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

HAL: Synchronize ports for RX calibration

A minimum delay of 20s is applied to all port for the the RX
calibration. After a reboot, all ports will be UP at the same time if
the RX  calibration time is less than 20s.
The same mechanism is applied all the time the link is going up.
parent 620a62ea
...@@ -101,7 +101,6 @@ typedef struct { ...@@ -101,7 +101,6 @@ typedef struct {
int isSupported; /* Set if Low Phase Drift Calibration is supported */ int isSupported; /* Set if Low Phase Drift Calibration is supported */
fsm_t txSetupFSM; fsm_t txSetupFSM;
fsm_t rxSetupFSM; fsm_t rxSetupFSM;
int rebootDone;
timeout_t minCalibRx_timeout; timeout_t minCalibRx_timeout;
halPortLpdcTx_t *txSetup; halPortLpdcTx_t *txSetup;
halPortLpdcRx_t *rxSetup; halPortLpdcRx_t *rxSetup;
......
...@@ -124,22 +124,17 @@ static int _hal_port_rx_setup_state_init(fsm_t *fsm, int eventMsk, int isNewStat ...@@ -124,22 +124,17 @@ static int _hal_port_rx_setup_state_init(fsm_t *fsm, int eventMsk, int isNewStat
struct hal_port_state * ps = (struct hal_port_state*) fsm->priv; struct hal_port_state * ps = (struct hal_port_state*) fsm->priv;
if ( ps->lpdc.globalLpdc->numberOfLpdcPorts ) { if ( ps->lpdc.globalLpdc->numberOfLpdcPorts ) {
if ( !ps->lpdc.rebootDone ) { if (ps->lpdc.isSupported) {
/** if ( _isHalRxSetupEventEarlyLinkUp(eventMsk) )
* This time-out is used to impose the same minimum of RX calibration time libwr_tmo_restart(&ps->lpdc.minCalibRx_timeout);
* on all ports (including port without LPDC. This is done to try to have fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_START);
* all ports going to state UP at the same time after a reboot. } else {
* It is is not done, PPSi (with BMCA) will take a long time to stabilize if ( _isHalRxSetupEventLinkUp(eventMsk))
* its port states libwr_tmo_restart(&ps->lpdc.minCalibRx_timeout);
*/ fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_START);
libwr_tmo_init(&ps->lpdc.minCalibRx_timeout,20000,0); // Timeout set to 20s
} }
} else { } else
/** No LCPD ports. We don't need to try synchronize the ports */ fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_START);
ps->lpdc.rebootDone=1;
}
fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_START);
return 0; return 0;
} }
...@@ -231,7 +226,7 @@ static int _hal_port_rx_setup_state_reset_pcs(fsm_t *fsm, int eventMsk, int isNe ...@@ -231,7 +226,7 @@ static int _hal_port_rx_setup_state_reset_pcs(fsm_t *fsm, int eventMsk, int isNe
fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_WAIT_LOCK); fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_WAIT_LOCK);
} else { } else {
if( libwr_tmo_expired( &rxSetup->link_timeout ) ) if( libwr_tmo_expired( &rxSetup->link_timeout ) )
fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_START); fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_INIT);
} }
return 0; return 0;
} }
...@@ -261,11 +256,15 @@ static int _hal_port_rx_setup_state_wait_lock(fsm_t *fsm, int eventMsk, int isNe ...@@ -261,11 +256,15 @@ static int _hal_port_rx_setup_state_wait_lock(fsm_t *fsm, int eventMsk, int isNe
_pll_state.channels[ps->hw_index].flags = 0; _pll_state.channels[ps->hw_index].flags = 0;
fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_VALIDATE); fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_VALIDATE);
} else { } else {
fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_RESET_PCS); if ( libwr_tmo_expired ( &ps->lpdc.minCalibRx_timeout))
// We are looping from WAIT_LOCK and RESET_PCS for too long
fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_INIT);
else
fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_RESET_PCS);
} }
} else { } else {
if( libwr_tmo_expired( &rxSetup->link_timeout ) ) if( libwr_tmo_expired( &rxSetup->link_timeout ) )
fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_START); fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_INIT);
} }
return 0; return 0;
...@@ -317,7 +316,7 @@ static int _hal_port_rx_setup_state_restart(fsm_t *fsm, int eventMsk, int isNewS ...@@ -317,7 +316,7 @@ static int _hal_port_rx_setup_state_restart(fsm_t *fsm, int eventMsk, int isNewS
MDIO_LPC_CTRL); MDIO_LPC_CTRL);
} else { } else {
if( libwr_tmo_expired( &ps->lpdc.rxSetup->restart_timeout ) ) { if( libwr_tmo_expired( &ps->lpdc.rxSetup->restart_timeout ) ) {
fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_START); fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_INIT);
} }
} }
return 0; return 0;
...@@ -347,7 +346,7 @@ static int _hal_port_rx_setup_state_done(fsm_t *fsm, int eventMsk, int isNewStat ...@@ -347,7 +346,7 @@ static int _hal_port_rx_setup_state_done(fsm_t *fsm, int eventMsk, int isNewStat
pr_info("rxcal: early link flag lost on port wri%d\n", pr_info("rxcal: early link flag lost on port wri%d\n",
ps->hw_index + 1); ps->hw_index + 1);
fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_START); fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_INIT);
return 0; return 0;
} }
...@@ -361,12 +360,10 @@ static int _hal_port_rx_setup_state_done(fsm_t *fsm, int eventMsk, int isNewStat ...@@ -361,12 +360,10 @@ static int _hal_port_rx_setup_state_done(fsm_t *fsm, int eventMsk, int isNewStat
} }
} }
if ( !ps->lpdc.rebootDone ) { if ( ps->lpdc.globalLpdc->numberOfLpdcPorts )
if ( libwr_tmo_expired(&ps->lpdc.minCalibRx_timeout) ) return link_up && libwr_tmo_expired(&ps->lpdc.minCalibRx_timeout) ? 1 : 0;
ps->lpdc.rebootDone=1; else
return link_up && ps->lpdc.rebootDone ? 1 : 0; return link_up ? 1 : 0;
}
return link_up ? 1 : 0;
} }
/* Build FSM events */ /* Build FSM events */
...@@ -445,6 +442,15 @@ void hal_port_rx_setup_fsm_init(struct hal_port_state * ps ) { ...@@ -445,6 +442,15 @@ void hal_port_rx_setup_fsm_init(struct hal_port_state * ps ) {
// the wait_lock state might detect the early link but never see it's aligned. // the wait_lock state might detect the early link but never see it's aligned.
libwr_tmo_init(&rxSetup->align_timeout, 1, 1); libwr_tmo_init(&rxSetup->align_timeout, 1, 1);
} }
/**
* This time-out is used to impose the same minimum of RX calibration time
* on all ports (including port without LPDC. This is done to try to have
* all ports going to state UP at the same time.
* It is is not done, PPSi (with BMCA) will take a long time to stabilize
* its port states
*/
libwr_tmo_init(&ps->lpdc.minCalibRx_timeout,20000,0); // Timeout set to 20s
fsm_fire_state( &ps->lpdc.rxSetupFSM, HAL_PORT_RX_SETUP_STATE_INIT ); fsm_fire_state( &ps->lpdc.rxSetupFSM, HAL_PORT_RX_SETUP_STATE_INIT );
} }
......
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