Commit b6fd5c20 authored by Maciej Lipinski's avatar Maciej Lipinski

[HAL] Fix waiting of ports in init state for all LPDC ports to finish calibration

- point on all ports (with and without LPDC support) to the global
  LPDC structure, this is so that all ports can see whether the LPDC
  ports were all calibrated
- add new state to tx_setup FSM in which ports wait for all the
  LPDC-supported ports to finish calibration

All ports (with and without support) need to wait for LPDC calibartion
to finish because otherwise one of them could become slave and
change the timing_mode while LPDC requires the switch to be in
free-running master mode
parent 0abd4c2b
......@@ -138,13 +138,10 @@ static int _hal_port_state_init(void *vpfg, int eventMsk, int isNewState) {
hal_port_tx_setup_init_fsm(ps);
hal_port_rx_setup_init_fsm(ps);
}
/* if final state reached for tx setup state machine
/* if final state reached for tx setup state machine ON ALL PORTS
* then we can go to DISABLED state
*/
hal_port_tx_setup_state_fsm( ps );
if ( txSetupDoneOnAllPorts(ps) )
if (hal_port_tx_setup_state_fsm( ps ) == 1 )
_fireState(vpfg,HAL_PORT_STATE_DISABLED);
return 0;
......
......@@ -40,6 +40,7 @@ static int _hal_port_tx_setup_state_validate(void *vpfg, int eventMsk, int isNew
static int _hal_port_tx_setup_state_reset_pcs(void *vpfg, int eventMsk, int isNewState);
static int _hal_port_tx_setup_state_wait_lock(void *vpfg, int eventMsk, int isNewState);
static int _hal_port_tx_setup_state_measure_phase(void *vpfg, int eventMsk, int isNewState);
static int _hal_port_tx_setup_state_wait_other_ports(void *vpfg, int eventMsk, int isNewState);
static int _hal_port_tx_setup_state_done(void *vpfg, int eventMsk, int isNewState);
static halPortStateTable_t _fsmStateTable[] =
......@@ -64,6 +65,10 @@ static halPortStateTable_t _fsmStateTable[] =
.stateName="VALIDATE",
FSM_SET_FCT_NAME(_hal_port_tx_setup_state_validate)
},
{ .state=HAL_PORT_TX_SETUP_STATE_WAIT_OTHER_PORTS,
.stateName="WAIT OTHER PORTS",
FSM_SET_FCT_NAME(_hal_port_tx_setup_state_wait_other_ports)
},
{ .state=HAL_PORT_TX_SETUP_STATE_DONE,
.stateName="DONE",
FSM_SET_FCT_NAME(_hal_port_tx_setup_state_done)
......@@ -104,8 +109,6 @@ static __inline__ void txSetupDone(struct hal_port_state * ps) {
int txSetupDoneOnAllPorts(struct hal_port_state * ps) {
struct halGlobalLPDC * gl = ps->lpdc.globalLpdc;
if( !gl )
return 0;
return gl->numberOfTxSetupDonePorts == gl->numberOfLpdcPorts;
}
......@@ -127,7 +130,7 @@ static int _hal_port_tx_setup_state_start(void *vpfg, int eventMsk, int isNewSta
if ( !ps->lpdc.isSupported ) {
// NO LPDC support
_fireState(vpfg,HAL_PORT_TX_SETUP_STATE_DONE);
_fireState(vpfg,HAL_PORT_TX_SETUP_STATE_WAIT_OTHER_PORTS);
return 0;
} else {
// LPDC support
......@@ -293,13 +296,24 @@ static int _hal_port_tx_setup_state_validate(void *vpfg, int eventMsk, int isNew
led_set_wrmode(ps->hw_index,SFP_LED_WRMODE_OFF);
_fireState(vpfg,HAL_PORT_TX_SETUP_STATE_DONE);
_fireState(vpfg,HAL_PORT_TX_SETUP_STATE_WAIT_OTHER_PORTS);
txSetupDone(ps);
if(txSetupDoneOnAllPorts(ps))
_write_tx_calibration_file(ps);
return 0;
}
/*
* Wait for all LPDC-supporting ports to be calibrated
*/
static int _hal_port_tx_setup_state_wait_other_ports(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps = ((halPortFsmGen_t *) vpfg)->ps;
if (txSetupDoneOnAllPorts(ps) )
_fireState(vpfg,HAL_PORT_TX_SETUP_STATE_DONE);
}
/*
* DONE state
......@@ -328,19 +342,22 @@ void hal_port_tx_setup_init(struct hal_port_state * ps, struct halGlobalLPDC *g
int firstLpdcPort = -1;
int lastLpdcPort = -1;
/* check whether there is any port that supports LPDC,
if there is such port, load the tx calibration file.*/
/* 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 && _ps->lpdc.isSupported){
/* 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
the LPDC-supporting ports have been calibrated */
_ps->lpdc.globalLpdc = globalLpdc;
/* if this is the first port with LPDC support,
allocate memory for the global struct */
if( !globalLpdc )
globalLpdc = malloc(sizeof(struct halGlobalLPDC));
/* link the global structure from each port*/
_ps->lpdc.globalLpdc = globalLpdc;
/* Fill in global info needed for operation */
if(_ps->in_use && _ps->lpdc.isSupported){
/* if this ist he first supporetd port, save its index*/
if (firstLpdcPort < 0)
firstLpdcPort = index;
......
......@@ -26,6 +26,7 @@ HAL_PORT_TX_SETUP_STATE_RESET_PCS,
HAL_PORT_TX_SETUP_STATE_WAIT_LOCK,
HAL_PORT_TX_SETUP_STATE_MEASURE_PHASE,
HAL_PORT_TX_SETUP_STATE_VALIDATE,
HAL_PORT_TX_SETUP_STATE_WAIT_OTHER_PORTS,
HAL_PORT_TX_SETUP_STATE_DONE
} hapPortTxSetupState_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