Commit c622140d authored by Tomasz Wlostowski's avatar Tomasz Wlostowski Committed by Maciej Lipinski

hal: fixed RX alignment detection (and some other suspicious code in the FSMs too - see comments)

parent 589d3c1f
......@@ -85,6 +85,7 @@ typedef struct {
/* Low Phase Drift Calibration for rx */
typedef struct {
timeout_t link_timeout;
timeout_t align_timeout;
int attempts;
}halPortLpdcRx_t;
......
......@@ -134,6 +134,7 @@ static int _hal_port_state_init(void *vpfg, int eventMsk, int isNewState) {
_init_port(ps);
/* Init the tx state machine */
hal_port_tx_setup_init_fsm(ps);
hal_port_rx_setup_init_fsm(ps);
}
/* if final state reached for tx setup state machine
* then we can go to DISABLED state
......@@ -310,10 +311,12 @@ void hal_port_state_fsm_init( struct hal_port_state * ps ) {
for (portIndex = 0; portIndex < HAL_MAX_PORTS; portIndex++) {
if ( ps->in_use)
{
_portFsm.ps=ps;
_portFsm.st=&ps->portStates;
ps->portStates.state=-1;
_fireState(&_portFsm,HAL_PORT_STATE_INIT);
}
ps++; /* Next port */
}
......
......@@ -23,6 +23,7 @@
#include "hal_port_leds.h"
#include "hal_port_fsm_rxP.h"
#include "hal_port_fsm_txP.h"
/**
* State machine
......@@ -125,6 +126,12 @@ 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;
// 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)
return 0;
if ( ps->lpdc.isSupported ) {
// LPDC support
pcs_writel(ps, MDIO_LPC_CTRL_TX_ENABLE |
......@@ -157,6 +164,11 @@ static int _hal_port_rx_setup_state_reset_pcs(void *vpfg, int eventMsk, int isNe
halPortLpdcRx_t *rxSetup=ps->lpdc.rxSetup;
libwr_tmo_init(&rxSetup->link_timeout, 100, 1);
// establish a 1ms wait for the LINK_ALIGNED flag -
// alignment detection takes a little bit more time than early
// link detect. Without the wait (depending on execution timing of the HAL code)
// the wait_lock state might detect the early link but never see it's aligned.
libwr_tmo_init(&rxSetup->align_timeout, 1, 1);
pcs_writel(ps, MDIO_LPC_CTRL_RESET_RX |
MDIO_LPC_CTRL_TX_ENABLE |
......@@ -169,7 +181,6 @@ static int _hal_port_rx_setup_state_reset_pcs(void *vpfg, int eventMsk, int isNe
rxSetup->attempts++;
_fireState(vpfg,HAL_PORT_RX_SETUP_STATE_WAIT_LOCK);
}
return 0;
}
......@@ -183,6 +194,10 @@ static int _hal_port_rx_setup_state_wait_lock(void *vpfg, int eventMsk, int isNe
halPortLpdcRx_t *rxSetup=ps->lpdc.rxSetup;
if ( _isHalRxSetupEventEarlyLinkUp(eventMsk)) {
// 1ms rx align detection window, described in previous state.
if(! libwr_tmo_expired(&rxSetup->align_timeout) )
return 0; // call me again 1ms later...
if ( _isHalRxSetupEventRxAligned(eventMsk)) {
rts_enable_ptracker(ps->hw_index, 0);
......@@ -209,7 +224,7 @@ static int _hal_port_rx_setup_state_validate(void *vpfg, int eventMsk, int isNew
updatePllState(ps);
if (_pll_state.channels[ps->hw_index].flags & CHAN_PMEAS_READY) {
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;
......
......@@ -129,7 +129,6 @@ static int _hal_port_tx_setup_state_start(void *vpfg, int eventMsk, int isNewSta
} else {
// LPDC support
halPortLpdcTx_t *txSetup=ps->lpdc.txSetup;
struct halGlobalLPDC * gl = ps->lpdc.globalLpdc;
txSetup->attempts=0;
txSetup->expected_phase = 0;
......@@ -249,9 +248,7 @@ static int _hal_port_tx_setup_state_measure_phase(void *vpfg, int eventMsk, int
txSetup->attempts, txSetup->expected_phase, txSetup->tollerance,
hal_get_fpga_temperature() / 256.0);
if (_within_range(phase, phase_min, phase_max, 16000)) {
int i;
if(_within_range(phase, phase_min, phase_max, 16000)) {
pr_info("FIX port %d phase %d after %d attempts "
"(temp = %.3f degC)\n", ps->hw_index, txSetup->measured_phase,
txSetup->attempts, hal_get_fpga_temperature() / 256.0);
......
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