Commit c41e1cd5 authored by Jean-Claude BAU's avatar Jean-Claude BAU

Initialization corrections and HAL share memory changes

- HAL shared memory modified to hide and remove some dependencies not
needed by PPSi
- LPDC structures are now stored in HAL shared memory. They are then
accessible by the share memory dump tool
- Improve the initialization procedure
parent c0be77c7
......@@ -76,7 +76,7 @@ typedef struct {
int cal_saved_phase_valid;
int measured_phase;
int expected_phase;
int tollerance;
int tolerance;
int update_cnt;
int expected_phase_valid;
timeout_t calib_timeout;
......@@ -90,13 +90,13 @@ typedef struct {
int attempts;
}halPortLpdcRx_t;
struct halGlobalLPDC {
typedef struct {
int numberOfLpdcPorts;
int numberOfTxSetupDonePorts;
int firstLpdcPort;
int lastLpdcPort;
int calFileSynced;
}; /* Global data for Low phase drift calibration */
}halGlobalLPDC_t; /* Global data for Low phase drift calibration */
typedef struct {
int isSupported; /* Set if Low Phase Drift Calibration is supported */
......@@ -104,7 +104,7 @@ typedef struct {
halPortFsmState_t rxSetupStates;
halPortLpdcTx_t *txSetup;
halPortLpdcRx_t *rxSetup;
struct halGlobalLPDC *globalLpdc;
halGlobalLPDC_t *globalLpdc;
}halPortLPDC_t; /* per-port data for Low phase drift calibration */
/* Internal port state structure */
......@@ -161,10 +161,10 @@ struct hal_port_state {
/* Events to process */
int evt_reset; /* Set if a reset is requested */
int evt_lock; /* Set if the ptracker must be activated*/
int evt_linkUp; /* Set if link is up ( driver call */
int evt_linkUp; /* Set if link is up ( driver call )*/
/* Low phase drift calibration data */
halPortLPDC_t lpdc;
halPortLPDC_t *lpdc; /* Use a pointer to avoid to export this structure to PPSi */
/* Pll FSM */
halPortFsmState_t pllStates;
......
......@@ -309,20 +309,21 @@ static int _builPortEvents(void * vpfg) {
/* Init the FSM on all ports. Called one time at startup */
void hal_port_state_fsm_init( struct hal_port_state * ps ) {
void hal_port_state_fsm_init( struct hal_port_state * ps, halGlobalLPDC_t *globalLpdc) {
int portIndex;
struct hal_port_state * _ps=ps;
for (portIndex = 0; portIndex < HAL_MAX_PORTS; portIndex++) {
if ( ps->in_use)
if ( _ps->in_use)
{
_portFsm.ps=ps;
_portFsm.st=&ps->portStates;
ps->portStates.state=-1;
_portFsm.ps=_ps;
_portFsm.st=&_ps->portStates;
_ps->portStates.state=-1;
_fireState(&_portFsm,HAL_PORT_STATE_INIT);
}
ps++; /* Next port */
_ps++; /* Next port */
}
hal_port_tx_setup_init(ps, globalLpdc); // Global init for tx_setup
}
/* Call FSM for on all ports */
......
......@@ -16,6 +16,6 @@
/* Prototypes */
void fsm_state_machine( struct hal_port_state * ps );
void hal_port_state_fsm( struct hal_port_state * ps );
void hal_port_state_fsm_init( struct hal_port_state * ps );
void hal_port_state_fsm_init( struct hal_port_state * ps,halGlobalLPDC_t *globalLpdc);
#endif
......@@ -125,19 +125,19 @@ static __inline__ void updatePllState(struct hal_port_state * ps) {
*/
static int _hal_port_rx_setup_state_start(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
halPortLpdcRx_t *rxSetup=ps->lpdc.rxSetup;
halPortLpdcRx_t *rxSetup=ps->lpdc->rxSetup;
// prevent RX FSM from starting up when the TX path calibration of the port is
// not completed.
if( ps->lpdc.txSetupStates.state != HAL_PORT_TX_SETUP_STATE_DONE) {
if( ps->lpdc->txSetupStates.state != HAL_PORT_TX_SETUP_STATE_DONE) {
pr_warning("rx_setup FSM is attempted to be started before the"
"tx_setup FSM has finished (in state %d) - this should"
"never happen, in theory.\n",
ps->lpdc.txSetupStates.state);
ps->lpdc->txSetupStates.state);
return 0;
}
if ( ps->lpdc.isSupported ) {
if ( ps->lpdc->isSupported ) {
/* Wait a bit to make sure early_link_up is resetted. This
timeout is initialized in hal_port_rx_setup_init_fsm(),
see detailed description there. */
......@@ -169,7 +169,7 @@ static int _hal_port_rx_setup_state_reset_pcs(void *vpfg, int eventMsk, int isNe
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
if( _isHalRxSetupEventEarlyLinkUp(eventMsk)) {
halPortLpdcRx_t *rxSetup=ps->lpdc.rxSetup;
halPortLpdcRx_t *rxSetup=ps->lpdc->rxSetup;
libwr_tmo_init(&rxSetup->link_timeout, 100, 1);
// establish a 1ms wait for the LINK_ALIGNED flag -
......@@ -199,7 +199,7 @@ static int _hal_port_rx_setup_state_reset_pcs(void *vpfg, int eventMsk, int isNe
*/
static int _hal_port_rx_setup_state_wait_lock(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
halPortLpdcRx_t *rxSetup=ps->lpdc.rxSetup;
halPortLpdcRx_t *rxSetup=ps->lpdc->rxSetup;
if ( _isHalRxSetupEventEarlyLinkUp(eventMsk)) {
// 1ms rx align detection window, described in previous state.
......@@ -234,8 +234,7 @@ static int _hal_port_rx_setup_state_validate(void *vpfg, int eventMsk, int isNew
if (_pll_state.channels[ps->hw_index].flags & CHAN_PMEAS_READY) {
int phase = _pll_state.channels[ps->hw_index].phase_loopback;
halPortLpdcRx_t *rxSetup=ps->lpdc.rxSetup;
uint32_t value;
halPortLpdcRx_t *rxSetup=ps->lpdc->rxSetup;
pcs_writel(ps, MDIO_LPC_CTRL_RX_ENABLE |
MDIO_LPC_CTRL_TX_ENABLE |
......@@ -266,7 +265,7 @@ static int _hal_port_rx_setup_state_done(void *vpfg, int eventMsk, int isNewStat
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
/* earlyLinkUp detection only if LPDC support */
if ( ps->lpdc.isSupported ) {
if ( ps->lpdc->isSupported ) {
if ( !_isHalRxSetupEventEarlyLinkUp(eventMsk)) {
// Port went done
pr_info("rxcal: early link flag lost on port wri%d\n",
......@@ -292,7 +291,7 @@ static int _buildEvents(void *vpfg) {
HAL_PORT_RX_SETUP_EVENT_LINK_UP : HAL_PORT_RX_SETUP_EVENT_LINK_DOWN;
}
if ( ps->lpdc.isSupported ) {
if ( ps->lpdc->isSupported ) {
uint32_t mioLpcStat;
if ( pcs_readl(ps, MDIO_LPC_STAT,&mioLpcStat) >= 0 ) {
......@@ -311,9 +310,9 @@ static int _buildEvents(void *vpfg) {
*/
void hal_port_rx_setup_init_fsm(struct hal_port_state * ps ) {
_portFsm.ps=ps;
_portFsm.st=&ps->lpdc.rxSetupStates;
ps->lpdc.rxSetupStates.state=-1;
if ( ps->lpdc.isSupported ) {
_portFsm.st=&ps->lpdc->rxSetupStates;
ps->lpdc->rxSetupStates.state=-1;
if ( ps->lpdc->isSupported ) {
/* This timeout is needed when link goes down. In such case
the link_down flag is set earlier than the early_link_up
flag is reseted. So, after the link goes down, we need to
......@@ -326,7 +325,7 @@ void hal_port_rx_setup_init_fsm(struct hal_port_state * ps ) {
a reason. If it was done in _hal_port_rx_setup_state_start(),
the timeout would also kick in when the START state is
entered from WAIT_LOCK*/
halPortLpdcRx_t *rxSetup=ps->lpdc.rxSetup;
halPortLpdcRx_t *rxSetup=ps->lpdc->rxSetup;
libwr_tmo_init(&rxSetup->earlyup_timeout, 10, 1);
}
_fireState(&_portFsm,HAL_PORT_RX_SETUP_STATE_START);
......@@ -341,7 +340,7 @@ void hal_port_rx_setup_init_fsm(struct hal_port_state * ps ) {
int hal_port_rx_setup_state_fsm( struct hal_port_state * ps ) {
_portFsm.ps=ps;
_portFsm.st=&ps->lpdc.rxSetupStates;
_portFsm.st=&ps->lpdc->rxSetupStates;
return hal_port_generic_fsm(&_portFsm);
}
......@@ -103,12 +103,12 @@ static __inline__ void updatePllState(struct hal_port_state * ps) {
}
static __inline__ void txSetupDone(struct hal_port_state * ps) {
struct halGlobalLPDC * gl = ps->lpdc.globalLpdc;
halGlobalLPDC_t * gl = ps->lpdc->globalLpdc;
gl->numberOfTxSetupDonePorts++;
}
int txSetupDoneOnAllPorts(struct hal_port_state * ps) {
struct halGlobalLPDC * gl = ps->lpdc.globalLpdc;
halGlobalLPDC_t * gl = ps->lpdc->globalLpdc;
return gl->numberOfTxSetupDonePorts == gl->numberOfLpdcPorts;
}
......@@ -128,18 +128,18 @@ static int _within_range(int x, int minval, int maxval, int wrap);
static int _hal_port_tx_setup_state_start(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
if ( !ps->lpdc.isSupported ) {
if ( !ps->lpdc->isSupported ) {
// NO LPDC support
_fireState(vpfg,HAL_PORT_TX_SETUP_STATE_WAIT_OTHER_PORTS);
return 0;
} else {
// LPDC support
halPortLpdcTx_t *txSetup=ps->lpdc.txSetup;
halPortLpdcTx_t *txSetup=ps->lpdc->txSetup;
txSetup->attempts=0;
txSetup->expected_phase = 0;
txSetup->expected_phase_valid = 0;
txSetup->tollerance = TX_CAL_TOLLERANCE;
txSetup->tolerance = TX_CAL_TOLLERANCE;
txSetup->update_cnt = 0;
_pll_state.channels[ps->hw_index].flags = 0;
......@@ -186,12 +186,12 @@ static int _hal_port_tx_setup_state_reset_pcs(void *vpfg, int eventMsk, int isNe
*/
static int _hal_port_tx_setup_state_wait_lock(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
halPortLpdcTx_t *txSetup=ps->lpdc.txSetup;
halPortLpdcTx_t *txSetup=ps->lpdc->txSetup;
uint32_t value;
if ( pcs_readl(ps, MDIO_LPC_STAT,&value)>=0 ) {
if ( (value & MDIO_LPC_STAT_RESET_TX_DONE)!=0 ) {
ps->lpdc.txSetup->attempts++;
ps->lpdc->txSetup->attempts++;
rts_enable_ptracker(ps->hw_index, 1);
_pll_state.channels[ps->hw_index].flags = 0;
libwr_tmo_init(&txSetup->calib_timeout,
......@@ -210,7 +210,7 @@ static int _hal_port_tx_setup_state_wait_lock(void *vpfg, int eventMsk, int isNe
*/
static int _hal_port_tx_setup_state_measure_phase(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps = ((halPortFsmGen_t *) vpfg)->ps;
halPortLpdcTx_t *txSetup=ps->lpdc.txSetup;
halPortLpdcTx_t *txSetup=ps->lpdc->txSetup;
updatePllState(ps);
if (!(_pll_state.channels[ps->hw_index].flags & CHAN_PMEAS_READY)) {
......@@ -224,7 +224,7 @@ static int _hal_port_tx_setup_state_measure_phase(void *vpfg, int eventMsk, int
return 0; // keep waiting
}
txSetup = ps->lpdc.txSetup;
txSetup = ps->lpdc->txSetup;
int phase = _pll_state.channels[ps->hw_index].phase_loopback;
txSetup->measured_phase = phase;
......@@ -239,19 +239,19 @@ static int _hal_port_tx_setup_state_measure_phase(void *vpfg, int eventMsk, int
// let's say the first 1.5 ns of the 16 ns ref clock
// cycle, so that we have enough setup time
txSetup->tollerance = TX_CAL_FIRST_CAL_TOLLERANCE;
txSetup->tolerance = TX_CAL_FIRST_CAL_TOLLERANCE;
txSetup->expected_phase = TX_CAL_FIRST_CAL_EXPECTED_PHASE;
}
txSetup->expected_phase_valid = 1;
}
int phase_min = txSetup->expected_phase - txSetup->tollerance;
int phase_max = txSetup->expected_phase + txSetup->tollerance;
int phase_min = txSetup->expected_phase - txSetup->tolerance;
int phase_max = txSetup->expected_phase + txSetup->tolerance;
pr_info("TX Calibration: upd wri%d phase %d after %d "
"attempts target %d tollerance %d\n",
"attempts target %d tolerance %d\n",
ps->hw_index+1, txSetup->measured_phase,
txSetup->attempts, txSetup->expected_phase, txSetup->tollerance);
txSetup->attempts, txSetup->expected_phase, txSetup->tolerance);
if(_within_range(phase, phase_min, phase_max, 16000)) {
pr_info("FIX port %d phase %d after %d attempts "
......@@ -282,7 +282,7 @@ static int _hal_port_tx_setup_state_validate(void *vpfg, int eventMsk, int isNew
if (!(_pll_state.channels[ps->hw_index].flags & CHAN_PMEAS_READY))
return 0; // keep waiting
txSetup = ps->lpdc.txSetup;
txSetup = ps->lpdc->txSetup;
txSetup->measured_phase = _pll_state.channels[ps->hw_index].phase_loopback;
pr_info("Port %d: TX calibration complete\n", ps->hw_index + 1);
rts_enable_ptracker(ps->hw_index, 0);
......@@ -335,29 +335,27 @@ static int _buildEvents(void *vpfg) {
- initializing a global structure and filling it in - this structure is
needed by tx calibration only (so far)
*/
void hal_port_tx_setup_init(struct hal_port_state * ps, struct halGlobalLPDC *globalLpdc) {
void hal_port_tx_setup_init(struct hal_port_state * ps, halGlobalLPDC_t *globalLpdc) {
int index;
struct hal_port_state * _ps = ps;
int numberOfLpdcPorts = 0;
int firstLpdcPort = -1;
int lastLpdcPort = -1;
/* Allocate memory for the global struct */
globalLpdc = malloc(sizeof(struct halGlobalLPDC));
/* Initialize pointer to the global structure for each port.
Check whether there is any port that supports LPDC,
if there is/are such port(s), remember index of the first/last and
their number. We need this info in operation.*/
for (index = 0; index < HAL_MAX_PORTS; index++){
if (_ps->in_use ) {
/* Link the global structure from each port.
NOTE: Even ports that do not support LPDC require access to
this global structre as they need to know whether all
this global structure as they need to know whether all
the LPDC-supporting ports have been calibrated */
_ps->lpdc.globalLpdc = globalLpdc;
_ps->lpdc->globalLpdc = globalLpdc;
/* Fill in global info needed for operation */
if(_ps->in_use && _ps->lpdc.isSupported){
if (_ps->lpdc->isSupported) {
/* if this ist he first supporetd port, save its index*/
if (firstLpdcPort < 0)
firstLpdcPort = index;
......@@ -368,6 +366,7 @@ void hal_port_tx_setup_init(struct hal_port_state * ps, struct halGlobalLPDC *g
/* count number of supported ports*/
numberOfLpdcPorts++;
}
}
_ps++;
}
......@@ -394,8 +393,8 @@ void hal_port_tx_setup_init(struct hal_port_state * ps, struct halGlobalLPDC *g
/* Init the TX SETUP FSM on a given port */
void hal_port_tx_setup_init_fsm(struct hal_port_state * ps ) {
_portFsm.ps=ps;
_portFsm.st=&ps->lpdc.txSetupStates;
ps->lpdc.txSetupStates.state=-1;
_portFsm.st=&ps->lpdc->txSetupStates;
ps->lpdc->txSetupStates.state=-1;
_fireState(&_portFsm,HAL_PORT_TX_SETUP_STATE_START);
}
......@@ -408,14 +407,14 @@ void hal_port_tx_setup_init_fsm(struct hal_port_state * ps ) {
int hal_port_tx_setup_state_fsm( struct hal_port_state * ps ) {
_portFsm.ps=ps;
_portFsm.st=&ps->lpdc.txSetupStates;
_portFsm.st=&ps->lpdc->txSetupStates;
return hal_port_generic_fsm(&_portFsm);
}
/* if config is present then update the calibration data */
static void _load_tx_calibration_file(struct hal_port_state * ps) {
int i = 0;
struct halGlobalLPDC * gl = ps->lpdc.globalLpdc;
halGlobalLPDC_t * gl = ps->lpdc->globalLpdc;
// Read calibration file, if it exists
_calibrationConfig = cfg_load(_calibrationFileName, 0);
......@@ -431,7 +430,7 @@ static void _load_tx_calibration_file(struct hal_port_state * ps) {
pr_info("Loading LPCD config data from %s\n", _calibrationFileName);
for (i = 0; i < HAL_MAX_PORTS; i++){
if (ps->in_use && ps->lpdc.isSupported)
if (ps->in_use && ps->lpdc->isSupported)
{
char key_name[80];
int value;
......@@ -441,8 +440,8 @@ static void _load_tx_calibration_file(struct hal_port_state * ps) {
if(cfg_get_int( _calibrationConfig, key_name, &value) )
{
pr_info("cal: wri%d %d\n", ps->hw_index+1, value);
ps->lpdc.txSetup->cal_saved_phase = value;
ps->lpdc.txSetup->cal_saved_phase_valid = 1;
ps->lpdc->txSetup->cal_saved_phase = value;
ps->lpdc->txSetup->cal_saved_phase_valid = 1;
}
}
ps++;
......@@ -468,7 +467,7 @@ static void _write_tx_calibration_file(struct hal_port_state * _ps)
{
int i;
struct hal_port_state * ps=_ps;
struct halGlobalLPDC * gl = ps->lpdc.globalLpdc;
halGlobalLPDC_t * gl = ps->lpdc->globalLpdc;
/* Only the first LPDC-supporting port writes the file. Otherwise,
there is problem with pointers when looping through port structures
......@@ -490,11 +489,11 @@ static void _write_tx_calibration_file(struct hal_port_state * _ps)
ps=_ps;
for (i = gl->firstLpdcPort; i <= gl->lastLpdcPort; i++) {
if (ps->in_use && ps->lpdc.isSupported)
if (ps->in_use && ps->lpdc->isSupported)
{
char key_name[80];
snprintf(key_name, sizeof(key_name), "TX_PHASE_PORT%d", ps->hw_index);
cfg_set_int(cfg, key_name, ps->lpdc.txSetup->measured_phase);
cfg_set_int(cfg, key_name, ps->lpdc->txSetup->measured_phase);
}
ps++;
}
......
......@@ -12,7 +12,7 @@
/* prototypes */
void hal_port_tx_setup_init_fsm(struct hal_port_state * ps );
void hal_port_tx_setup_init(struct hal_port_state * ps, struct halGlobalLPDC *globalLpdc );
void hal_port_tx_setup_init(struct hal_port_state * ps, halGlobalLPDC_t *globalLpdc );
int hal_port_tx_setup_state_fsm( struct hal_port_state * ps);
#endif
......@@ -134,13 +134,23 @@ static int hal_port_init(struct hal_port_state *ps, int index)
if (!hal_port_check_presence(ps->name, ps->hw_addr))
return -1;
/* Allocate LPDC structure */
if ( (ps->lpdc = wrs_shm_alloc(hal_shmem_hdr, sizeof(halPortLPDC_t)))==NULL ) {
pr_error("Can't allocate LPDC structure in shmem\n");
return -1;
}
ps->in_use = 1;
ps->lpdc.isSupported = hal_port_check_lpdc_support(ps);
ps->lpdc->isSupported = hal_port_check_lpdc_support(ps);
if ( ps->lpdc.isSupported ) {
if ( ps->lpdc->isSupported ) {
// Allocate memory for tx/rx setup
ps->lpdc.txSetup = malloc(sizeof(halPortLpdcTx_t));
ps->lpdc.rxSetup = malloc(sizeof(halPortLpdcRx_t));
ps->lpdc->txSetup = wrs_shm_alloc(hal_shmem_hdr,sizeof(halPortLpdcTx_t));
ps->lpdc->rxSetup = wrs_shm_alloc(hal_shmem_hdr,sizeof(halPortLpdcRx_t));
if ( ps->lpdc->rxSetup==NULL || ps->lpdc->txSetup==NULL) {
pr_error("Can't allocate LPDC (rx/tx) structures in shmem\n");
return -1;
}
}
/* get the number of a port from notation wriX */
sscanf(ps->name + 3, "%d", &ps->hw_index);
......@@ -247,8 +257,8 @@ int hal_port_shmem_init(char *logfilename)
for (index = 0; index < HAL_MAX_PORTS; index++)
if (hal_port_init(&halPorts.ports[index],index) < 0)
break;
hal_port_state_fsm_init(halPorts.ports); // Init fsm
hal_port_tx_setup_init(halPorts.ports, halPorts.globalLpdc); // Global init for tx_setup
hal_port_state_fsm_init(halPorts.ports,&halPorts.globalLpdc); // Init fsm
led_init_all_ports(halPorts.ports); // Reset all leds
halPorts.numberOfPorts = index;
......@@ -342,11 +352,11 @@ static int hal_port_check_lpdc_support(struct hal_port_state * ps)
return 0;
} else {
if (rv & EP_ECR_FEAT_LPC) {
pr_info("Supports for Low Phase Drift Calibration detected"
pr_info("Supports for Low Phase Drift Calibration detected "
"at port %s\n", ps->name);
return 1;
} else {
pr_info("NO supports for Low Phase Drift Calibration detected"
pr_info("NO supports for Low Phase Drift Calibration detected "
"at port %s\n", ps->name);
return 0;
}
......
......@@ -11,6 +11,7 @@
#define HAL_PORTS_H
#include <rt_ipc.h>
#include <libwr/hal_shmem.h>
typedef struct {
struct hal_port_state *ports;
......@@ -22,7 +23,7 @@ typedef struct {
int rts_state_valid;
/* Global information needed by LPDC (tx setup) */
struct halGlobalLPDC *globalLpdc;
halGlobalLPDC_t globalLpdc;
}hal_ports_t;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment