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

HAL improvements and bug fixes.

parent eedbca03
......@@ -104,17 +104,23 @@ static inline const char *fsm_get_event_mask_as_string(fsm_t *fsm)
{
static char str[1024];
fsm_event_table_entry_t *evt;
int lastEventMask=fsm->lastEventMask;
strcpy(str, "");
str[0]=0;
for( evt = fsm->event_table; evt->evtMask > 0; evt++ )
{
if (fsm->lastEventMask & evt->evtMask)
if ( lastEventMask == 0 ) break;
if (lastEventMask & evt->evtMask)
{
if ( str[0]!=0 )
strcat(str," ");
strcat(str, evt->evtName);
strcat(str, " ");
lastEventMask &=~evt->evtMask;
}
}
if (lastEventMask!=0)
strcat(str," ???");
return str;
}
......
......@@ -90,7 +90,7 @@ typedef struct {
typedef struct {
int numberOfLpdcPorts;
uint32_t maskLpdcPorts;
uint32_t maskUsedPorts;
uint32_t maskTxSetupDonePorts;
int firstLpdcPort;
int lastLpdcPort;
......@@ -208,10 +208,14 @@ static inline struct hal_port_state *hal_lookup_port(
const char *name)
{
int i;
for (i = 0; i < nports; i++)
if (ports[i].in_use && (!strcmp(name, ports[i].name)))
return ports + i;
struct hal_port_state *p=ports;
for (i = 0; i < nports; i++) {
if (p->in_use && (!strcmp(name, p->name))) {
return p;
}
p++;
}
return NULL;
}
......
......@@ -145,7 +145,7 @@ int halexp_pps_cmd(int cmd, hexp_pps_params_t * params)
return hal_tmg_set_mode(params->timing_mode);
case HEXP_PPSG_CMD_GET_TIMING_MODE:{
ret=hal_tmg_get_mode();
ret=hal_tmg_get_mode(NULL);
return ret;
}
......
......@@ -10,7 +10,5 @@
#ifndef HAL_MAIN_H
#define HAL_MAIN_H
extern int hal_tmg_set_mode(uint32_t tm);
extern int hal_tmg_get_mode(void);
extern int hal_get_fpga_temperature(void);
#endif
......@@ -64,7 +64,6 @@ static int port_fsm_state_link_up(fsm_t *fsm, int eventMsk, int isNewState);
static void init_port(struct hal_port_state * ps);
static void reset_port(struct hal_port_state * ps);
static void shutdown_port( struct hal_port_state * ps);
static int get_port_link_state(struct hal_port_state * ps,int *linkUp);
static fsm_state_table_entry_t port_fsm_states[] =
......@@ -91,25 +90,27 @@ static fsm_state_table_entry_t port_fsm_states[] =
static fsm_event_table_entry_t port_fsm_events[] = {
{
.evtMask = HAL_PORT_EVENT_TIMER,
.evtName="TIMER"
.evtName="TIM"
},
{
.evtMask =HAL_PORT_EVENT_SFP_INSERTED,
.evtName = "SFP_INS"
},
{
.evtMask =HAL_PORT_EVENT_SFP_REMOVED,
.evtName = "SFP_REM"
.evtMask =HAL_PORT_EVENT_SFP_PRESENT,
.evtName = "SFP"
},
{
.evtMask =HAL_PORT_EVENT_LINK_UP,
.evtName = "LINK_UP"
},
{ .evtMask =HAL_PORT_EVENT_LINK_DOWN,
.evtName = "LINK_DOWN"
.evtName = "LKUP"
},
{ .evtMask =HAL_PORT_EVENT_RESET,
.evtName = "REET"
.evtName = "RST"
},
{ .evtMask =HAL_PORT_EVENT_POWER_DOWN,
.evtName = "PDOWN"
},
{ .evtMask =HAL_PORT_EVENT_EARLY_LINK_UP,
.evtName = "ELKUP"
},
{ .evtMask =HAL_PORT_EVENT_RX_ALIGNED,
.evtName = "RXALGN"
},
{ .evtMask = -1 } };
......@@ -148,10 +149,21 @@ static int port_fsm_state_init(fsm_t *fsm, int eventMsk, int isNewState) {
static int port_fsm_state_disabled(fsm_t *fsm, int eventMsk, int isNewState) {
struct hal_port_state * ps = (struct hal_port_state*) fsm->priv;
if ( isNewState )
if ( isNewState ) {
reset_port(ps);
if ( _isHalEventSfpInserted(eventMsk) && !_isHalEventPortPowerDown( eventMsk ))
// make sure the PHY calibration circuitry is put in a KNOWN state
if( ps->lpdc.isSupported ) {
pcs_writel(ps,
MDIO_LPC_CTRL_RESET_RX | MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK
| MDIO_LPC_CTRL_TX_ENABLE, MDIO_LPC_CTRL);
}
// Disable tracker
rts_enable_ptracker(ps->hw_index, 0);
}
if ( _isHalEventSfpPresent(eventMsk) && !_isHalEventPortPowerDown( eventMsk ))
fsm_fire_state(fsm,HAL_PORT_STATE_LINK_DOWN);
return 0;
}
......@@ -170,7 +182,15 @@ static int port_fsm_state_link_down(fsm_t *fsm, int eventMsk, int isNewState) {
struct hal_port_state * ps = (struct hal_port_state*) fsm->priv;
// High priority event received
if ( _isHalEventSfpRemoved(eventMsk) ) {
if ( !_isHalEventSfpPresent(eventMsk) ) {
fsm_fire_state(fsm,HAL_PORT_STATE_DISABLED);
return 0;
}
if( _isHalEventPortPowerDown( eventMsk ))
{
pr_info("%s: Port wri%d PDOWN detected\n" ,__func__,ps->hw_index + 1 );
// MII power down
fsm_fire_state(fsm,HAL_PORT_STATE_DISABLED);
return 0;
}
......@@ -227,27 +247,31 @@ static int port_fsm_state_link_up(fsm_t *fsm, int eventMsk, int isNewState) {
struct hal_port_state * ps = (struct hal_port_state*) fsm->priv;
if ( ps->lpdc.isSupported) {
if ( !_isHalEventPortRxAligned(eventMsk) || !_isHalEventPortEarlyLinkUp(eventMsk))
if ( /*!_isHalEventPortRxAligned(eventMsk) ||*/ !_isHalEventPortEarlyLinkUp(eventMsk)) {
// if ( !_isHalEventPortRxAligned(eventMsk) )
// printf("JCB:%s:wri%d RX not aligned\n",__func__, ps->hw_index+1);
if ( !_isHalEventPortEarlyLinkUp(eventMsk) )
printf("JCB:%s:wri%d No early link Up\n",__func__, ps->hw_index+1);
fsm_fire_state(fsm,HAL_PORT_STATE_LINK_DOWN);
}
}
if ( _isHalEventSfpRemoved(eventMsk) ) {
shutdown_port(ps);
if ( !_isHalEventSfpPresent(eventMsk) ) {
fsm_fire_state(fsm,HAL_PORT_STATE_DISABLED);
return 0;
}
if( _isHalEventPortPowerDown( eventMsk ))
{
pr_info("Port %d PDOWN detected\n" ,ps->hw_index + 1 );
pr_info("%s: Port wri%d PDOWN detected\n" ,__func__,ps->hw_index + 1 );
// MII power down
shutdown_port(ps);
fsm_fire_state(fsm,HAL_PORT_STATE_DISABLED);
return 0;
}
if ( _isHalEventReset(eventMsk) || _isHalEventLinkDown(eventMsk)) {
shutdown_port(ps);
if ( _isHalEventReset(eventMsk) || !_isHalEventLinkUp(eventMsk)) {
if ( !_isHalEventLinkUp(eventMsk) )
printf("JCB:%s:wri%d Link up lost\n",__func__, ps->hw_index+1);
fsm_fire_state(fsm,HAL_PORT_STATE_LINK_DOWN);
return 0;
}
......@@ -298,18 +322,18 @@ static int port_fsm_build_events(fsm_t *fsm) {
int portEventMask=HAL_PORT_EVENT_TIMER;
if ( ps->evt_linkUp >= 0 ) {
portEventMask |= ps->evt_linkUp ?
HAL_PORT_EVENT_LINK_UP : HAL_PORT_EVENT_LINK_DOWN;
if ( ps->evt_linkUp > 0 ) {
portEventMask |= HAL_PORT_EVENT_LINK_UP;
}
if ( ps->evt_reset ) {
portEventMask |= HAL_PORT_EVENT_RESET;
ps->evt_reset=0;
}
portEventMask |= ps->sfpPresent ?
HAL_PORT_EVENT_SFP_INSERTED : HAL_PORT_EVENT_SFP_REMOVED;
if (ps->sfpPresent)
portEventMask |= HAL_PORT_EVENT_SFP_PRESENT;
portEventMask |= ps->evt_powerDown ? HAL_PORT_EVENT_POWER_DOWN : 0;
if ( ps->evt_powerDown )
portEventMask |= HAL_PORT_EVENT_POWER_DOWN;
if ( ps->lpdc.isSupported ) {
uint32_t mioLpcStat;
......@@ -322,7 +346,6 @@ static int port_fsm_build_events(fsm_t *fsm) {
}
}
return portEventMask;
}
......@@ -417,35 +440,12 @@ static void reset_port(struct hal_port_state * ps)
/* Port initialization */
static void init_port(struct hal_port_state * ps)
{
reset_port(ps);
ps->t2_phase_transition = DEFAULT_T2_PHASE_TRANS;
ps->t4_phase_transition = DEFAULT_T4_PHASE_TRANS;
ps->clock_period = REF_CLOCK_PERIOD_PS;
}
/* Action done when leaving states locking/up */
static void shutdown_port( struct hal_port_state * ps)
{
if ( hal_tmg_get_mode()==HAL_TIMING_MODE_BC)
hal_tmg_set_mode(HAL_TIMING_MODE_FREE_MASTER);
// make sure the PHY calibration circuitry is put in a KNOWN state
if( ps->lpdc.isSupported )
{
hal_port_rx_setup_fsm_init( ps );
pcs_writel(ps,
MDIO_LPC_CTRL_RESET_RX | MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK
| MDIO_LPC_CTRL_TX_ENABLE, MDIO_LPC_CTRL);
}
// Disable tracker
rts_enable_ptracker(ps->hw_index, 0);
ps->locked=0;
}
/* Checks if the link is up on inteface (if_name). Returns non-zero if yes. */
static int get_port_link_state(struct hal_port_state * ps,int *linkUp)
......
......@@ -15,36 +15,26 @@
typedef enum
{
HAL_PORT_EVENT_TIMER = (1 << 0),
HAL_PORT_EVENT_SFP_INSERTED = (1 << 1),
HAL_PORT_EVENT_SFP_REMOVED = (1 << 2),
HAL_PORT_EVENT_LINK_UP = (1 << 3),
HAL_PORT_EVENT_LINK_DOWN = (1 << 4),
HAL_PORT_EVENT_RESET = (1 << 5),
HAL_PORT_EVENT_POWER_DOWN = (1 << 6),
HAL_PORT_EVENT_EARLY_LINK_UP = (1 << 7),
HAL_PORT_EVENT_RX_ALIGNED = (1 << 8)
HAL_PORT_EVENT_SFP_PRESENT = (1 << 1),
HAL_PORT_EVENT_LINK_UP = (1 << 2),
HAL_PORT_EVENT_RESET = (1 << 3),
HAL_PORT_EVENT_POWER_DOWN = (1 << 4),
HAL_PORT_EVENT_EARLY_LINK_UP = (1 << 5),
HAL_PORT_EVENT_RX_ALIGNED = (1 << 6)
} halPortEventMask_t;
static inline int _isHalEventInitialized(halPortEventMask_t eventMsk) {
return eventMsk & HAL_PORT_EVENT_TIMER;
}
static inline int _isHalEventSfpInserted(halPortEventMask_t eventMsk) {
return eventMsk & HAL_PORT_EVENT_SFP_INSERTED;
}
static inline int _isHalEventSfpRemoved(halPortEventMask_t eventMsk) {
return eventMsk & HAL_PORT_EVENT_SFP_REMOVED;
static inline int _isHalEventSfpPresent(halPortEventMask_t eventMsk) {
return eventMsk & HAL_PORT_EVENT_SFP_PRESENT;
}
static inline int _isHalEventLinkUp(halPortEventMask_t eventMsk) {
return eventMsk & HAL_PORT_EVENT_LINK_UP;
}
static inline int _isHalEventLinkDown(halPortEventMask_t eventMsk) {
return eventMsk & HAL_PORT_EVENT_LINK_DOWN;
}
static inline int _isHalEventReset(halPortEventMask_t eventMsk) {
return eventMsk & HAL_PORT_EVENT_RESET;
}
......
......@@ -53,7 +53,7 @@ static fsm_state_table_entry_t port_pll_fsm_states[] =
static fsm_event_table_entry_t port_pll_fsm_events[] = {
{
.evtMask = HAL_PORT_PLL_EVENT_TIMER,
.evtName="TIMER"
.evtName="TIM"
},
{
.evtMask = HAL_PORT_PLL_EVENT_LOCK,
......@@ -88,16 +88,16 @@ static fsm_event_table_entry_t port_pll_fsm_events[] = {
static int _hal_port_pll_state_unlocked(fsm_t *fsm, int eventMsk, int isNewState) {
struct hal_port_state * ps = (struct hal_port_state*) fsm->priv;
if ( isNewState ) {
ps->locked=0;
}
if ( _isHalPllEventLocked(eventMsk) ) {
fsm_fire_state(fsm, HAL_PORT_PLL_STATE_LOCKED);
return 0;
}
if ( _isHalPllEventLock(eventMsk) ) {
if ( rts_lock_channel(ps->hw_index, 0)>=0 ) {
} else
if ( _isHalPllEventLock(eventMsk) ) {
fsm_fire_state(fsm, HAL_PORT_PLL_STATE_LOCKING);
return 0;
}
}
return 0;
}
......@@ -108,7 +108,11 @@ static int _hal_port_pll_state_unlocked(fsm_t *fsm, int eventMsk, int isNewState
* else if unlock event then state=UNLOCKED
*/
static int _hal_port_pll_state_locking(fsm_t *fsm, int eventMsk, int isNewState) {
struct hal_port_state * ps = (struct hal_port_state*) fsm->priv;
if ( isNewState ) {
ps->locked=0;
}
if ( _isHalPllEventLocked(eventMsk) ) {
fsm_fire_state(fsm, HAL_PORT_PLL_STATE_LOCKED);
return 0;
......@@ -130,6 +134,11 @@ static int _hal_port_pll_state_locking(fsm_t *fsm, int eventMsk, int isNewState)
* fi
*/
static int _hal_port_pll_state_locked(fsm_t *fsm, int eventMsk, int isNewState) {
struct hal_port_state * ps = (struct hal_port_state*) fsm->priv;
if ( isNewState ) {
ps->locked=1;
}
if ( _isHalPllEventUnlock(eventMsk) ) {
fsm_fire_state(fsm, HAL_PORT_PLL_STATE_LOCKING);
return 0;
......@@ -150,23 +159,23 @@ static int port_pll_fsm_build_events(fsm_t *fsm) {
struct hal_port_state * ps = (struct hal_port_state*) fsm->priv;
int portEventMask=HAL_PORT_PLL_EVENT_TIMER;
int tm;
uint32_t hwIndex;
tm= hal_tmg_get_mode(&hwIndex);
tm= hal_tmg_get_mode();
ps->locked=0;
if ( tm == HAL_TIMING_MODE_BC) {
if ( tm == HAL_TIMING_MODE_BC && ps->evt_lock) {
portEventMask |= HAL_PORT_PLL_EVENT_LOCK;
ps->evt_lock=0; // Event consumed
return portEventMask;
}
if ( ps->hw_index==hwIndex && tm == HAL_TIMING_MODE_BC) {
int locked=hal_port_check_lock(ps);
if ( locked >=0 ) {
ps->locked = locked;
portEventMask|= locked ?
HAL_PORT_PLL_EVENT_LOCKED : HAL_PORT_PLL_EVENT_UNLOCKED;
}
if ( ps->evt_lock )
portEventMask |= HAL_PORT_PLL_EVENT_LOCK;
} else {
portEventMask |= HAL_PORT_PLL_EVENT_DISABLE;
}
ps->evt_lock=0;// Clear event
return portEventMask;
}
......
......@@ -83,23 +83,19 @@ static fsm_state_table_entry_t port_rx_setup_fsm_states[] =
static fsm_event_table_entry_t port_rx_setup_fsm_events[] = {
{
.evtMask = HAL_PORT_RX_SETUP_EVENT_TIMER,
.evtName="TIMER"
.evtName="TIM"
},
{
.evtMask = HAL_PORT_RX_SETUP_EVENT_LINK_UP,
.evtName="LINK_UP"
.evtName="LKUP"
},
{
.evtMask = HAL_PORT_RX_SETUP_EVENT_EARLY_LINK_UP,
.evtName="EARLY_LINK_UP"
},
{
.evtMask = HAL_PORT_RX_SETUP_EVENT_LINK_DOWN,
.evtName="LINK_DOWN"
.evtName="ELKUP"
},
{
.evtMask = HAL_PORT_RX_SETUP_EVENT_RX_ALIGNED,
.evtName="RX_ALIGNED"
.evtName="RX_ALGN"
},
{ .evtMask = -1 } };
......@@ -139,28 +135,31 @@ static int _hal_port_rx_setup_state_start(fsm_t *fsm, int eventMsk, int isNewSta
return 0;
}
if ( ps->lpdc.isSupported ) {
if ( isNewState )
if (ps->lpdc.isSupported) {
if (isNewState)
// Restart the time-out
libwr_tmo_restart(&rxSetup->earlyup_timeout);
/* Wait a bit to make sure early_link_up is reseted. This
timeout is initialized in hal_port_rx_setup_init_fsm(),
see detailed description there. */
if (! libwr_tmo_expired(&rxSetup->earlyup_timeout)) {
timeout is initialized in hal_port_rx_setup_init_fsm(),
see detailed description there. */
if (!libwr_tmo_expired(&rxSetup->earlyup_timeout)) {
return 0;
}
// LPDC support
pcs_writel(ps, MDIO_LPC_CTRL_TX_ENABLE |
MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK,
MDIO_LPC_CTRL);
MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK,
MDIO_LPC_CTRL);
if( _isHalRxSetupEventEarlyLinkUp(eventMsk)) {
halPortLpdcRx_t *rxSetup=ps->lpdc.rxSetup;
if (_isHalRxSetupEventEarlyLinkUp(eventMsk)) {
halPortLpdcRx_t *rxSetup = ps->lpdc.rxSetup;
rxSetup->attempts=0;
rxSetup->attempts = 0;
rts_enable_ptracker(ps->hw_index, 0);
fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_RESET_PCS);
} else {
// Restart the time-out
libwr_tmo_restart(&rxSetup->earlyup_timeout);
}
} else {
/* nothing to do, go waiting for link_up*/
......@@ -185,9 +184,6 @@ static int _hal_port_rx_setup_state_reset_pcs(fsm_t *fsm, int eventMsk, int isNe
if( _isHalRxSetupEventEarlyLinkUp(eventMsk)) {
halPortLpdcRx_t *rxSetup=ps->lpdc.rxSetup;
libwr_tmo_init(&rxSetup->link_timeout, 100, 1);
libwr_tmo_init(&rxSetup->align_timeout, 1, 1);
pcs_writel(ps, MDIO_LPC_CTRL_RESET_RX |
MDIO_LPC_CTRL_TX_ENABLE |
MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK,
......@@ -215,6 +211,10 @@ static int _hal_port_rx_setup_state_wait_lock(fsm_t *fsm, int eventMsk, int isNe
halPortLpdcRx_t *rxSetup=ps->lpdc.rxSetup;
if ( isNewState ) {
libwr_tmo_restart(&rxSetup->link_timeout);
libwr_tmo_restart(&rxSetup->align_timeout);
}
if ( _isHalRxSetupEventEarlyLinkUp(eventMsk)) {
// 1ms rx align detection window, described in previous state.
if(! libwr_tmo_expired(&rxSetup->align_timeout) )
......@@ -262,7 +262,6 @@ static int _hal_port_rx_setup_state_validate(fsm_t *fsm, int eventMsk, int isNew
phase, rxSetup->attempts);
rts_enable_ptracker(ps->hw_index, 0);
libwr_tmo_init( &rxSetup->align_to_link_timeout, 5000, 0 );
fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_DONE);
}
......@@ -280,6 +279,8 @@ static int _hal_port_rx_setup_state_restart(fsm_t *fsm, int eventMsk, int isNewS
if ( isNewState ) {
// This timer is used to leave enough time to the FSM in the other side to detect a link down
libwr_tmo_init(&ps->lpdc.rxSetup->restart_timeout, 100, 0);
pcs_writel(ps, MDIO_LPC_CTRL_DMTD_SOURCE_TXOUTCLK,
MDIO_LPC_CTRL);
} else {
if( libwr_tmo_expired( &ps->lpdc.rxSetup->restart_timeout ) ) {
fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_START);
......@@ -301,28 +302,26 @@ static int _hal_port_rx_setup_state_done(fsm_t *fsm, int eventMsk, int isNewStat
int early_up = _isHalRxSetupEventEarlyLinkUp(eventMsk);
int link_aligned = _isHalRxSetupEventRxAligned(eventMsk);
int link_up = _isHalRxSetupEventLinkUp(eventMsk);
/* earlyLinkUp detection only if LPDC support */
if ( ps->lpdc.isSupported ) {
if ( isNewState ) {
libwr_tmo_init( &ps->lpdc.rxSetup->align_to_link_timeout, 5000, 0 );
}
if ( !early_up) {
// Port went done
pr_info("rxcal: early link flag lost on port wri%d\n",
ps->hw_index + 1);
fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_START);
return 0;
}
if( libwr_tmo_expired( &ps->lpdc.rxSetup->align_to_link_timeout ) && !link_up && early_up && link_aligned)
if( libwr_tmo_expired( &ps->lpdc.rxSetup->align_to_link_timeout ) && !link_up)
{
pr_warning("rxcal: link is fucked up, early+align on, but no PCS link up. Retrying calibration on port %d\n",ps->hw_index + 1);
// pcs_writel(ps, MDIO_LPC_CTRL_TX_ENABLE|MDIO_LPC_CTRL_RESET_RX|MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK,
// MDIO_LPC_CTRL);
pcs_writel(ps, MDIO_LPC_CTRL_DMTD_SOURCE_TXOUTCLK,
MDIO_LPC_CTRL);
pr_warning("rxcal: link is fucked up. Retrying calibration on port %d\n",ps->hw_index + 1);
fsm_fire_state(fsm, HAL_PORT_RX_SETUP_STATE_RESTART);
return 0;
......@@ -338,12 +337,8 @@ static int port_rx_setup_fsm_build_events (fsm_t *fsm) {
int portEventMask=HAL_PORT_RX_SETUP_EVENT_TIMER;
//printf("rxBuildEvents port %d lup %d\n", ps->hw_index, ps->evt_linkUp );
if ( ps->evt_linkUp >= 0 ) {
portEventMask |= ps->evt_linkUp ?
HAL_PORT_RX_SETUP_EVENT_LINK_UP : HAL_PORT_RX_SETUP_EVENT_LINK_DOWN;
if ( ps->evt_linkUp > 0 ) {
portEventMask |= HAL_PORT_RX_SETUP_EVENT_LINK_UP;
}
if ( ps->lpdc.isSupported ) {
......
......@@ -26,19 +26,14 @@ typedef enum
{
HAL_PORT_RX_SETUP_EVENT_TIMER=(1<<0),
HAL_PORT_RX_SETUP_EVENT_LINK_UP=(1<<1),
HAL_PORT_RX_SETUP_EVENT_LINK_DOWN=(1<<2),
HAL_PORT_RX_SETUP_EVENT_EARLY_LINK_UP=(1<<3),
HAL_PORT_RX_SETUP_EVENT_RX_ALIGNED=(1<<4)
HAL_PORT_RX_SETUP_EVENT_EARLY_LINK_UP=(1<<2),
HAL_PORT_RX_SETUP_EVENT_RX_ALIGNED=(1<<3)
}halPortRxSetupEventMask_t ;
static inline int _isHalRxSetupEventTimer(halPortRxSetupEventMask_t eventMsk) {
return eventMsk & HAL_PORT_RX_SETUP_EVENT_TIMER;
}
static inline int _isHalRxSetupEventLinkDown(halPortRxSetupEventMask_t eventMsk) {
return eventMsk & HAL_PORT_RX_SETUP_EVENT_LINK_DOWN;
}
static inline int _isHalRxSetupEventLinkUp(halPortRxSetupEventMask_t eventMsk) {
return eventMsk & HAL_PORT_RX_SETUP_EVENT_LINK_UP;
}
......
......@@ -17,6 +17,7 @@
#include "hal_exports.h"
#include "driver_stuff.h"
#include "hal_port_leds.h"
#include "hal_timing.h"
#include "hal_main.h"
#include "hal_ports.h"
#include "hal_port_fsm_txP.h"
......@@ -80,7 +81,7 @@ static fsm_state_table_entry_t port_tx_setup_fsm_states[] =
static fsm_event_table_entry_t port_tx_setup_fsm_events[] = {
{
.evtMask = HAL_PORT_TX_SETUP_EVENT_TIMER,
.evtName="TIMER"
.evtName="TIM"
},
{ .evtMask = -1 } };
......@@ -108,7 +109,7 @@ static inline void txSetupNotDone(struct hal_port_state * ps) {
static inline int txSetupDoneOnAllPorts(struct hal_port_state * ps) {
halGlobalLPDC_t * gl = ps->lpdc.globalLpdc;
return gl->maskLpdcPorts==gl->maskTxSetupDonePorts;
return gl->maskUsedPorts==gl->maskTxSetupDonePorts;
}
/* prototypes */
......@@ -128,9 +129,15 @@ static int _within_range(int x, int minval, int maxval, int wrap);
static int port_tx_setup_fsm_state_start(fsm_t *fsm, int eventMsk, int isNewState) {
struct hal_port_state * ps = (struct hal_port_state*) fsm->priv;
// Force timing mode to FR
if ( hal_tmg_get_mode(NULL)==HAL_TIMING_MODE_BC)
hal_tmg_set_mode(HAL_TIMING_MODE_FREE_MASTER);
ps->locked=0;
txSetupNotDone(ps);
if ( !ps->lpdc.isSupported ) {
// NO LPDC support
fsm_fire_state(fsm,HAL_PORT_TX_SETUP_STATE_DONE);
fsm_fire_state(fsm,HAL_PORT_TX_SETUP_STATE_WAIT_OTHER_PORTS);
return 0;
} else {
// LPDC support
......@@ -152,7 +159,6 @@ static int port_tx_setup_fsm_state_start(fsm_t *fsm, int eventMsk, int isNewStat
MDIO_LPC_CTRL);
led_set_wrmode(ps->hw_index,SFP_LED_WRMODE_TX_CALIB);
txSetupNotDone(ps);
fsm_fire_state(fsm, HAL_PORT_TX_SETUP_STATE_RESET_PCS);
}
return 0;
......@@ -187,7 +193,6 @@ static int port_tx_setup_fsm_state_reset_pcs(fsm_t *fsm, int eventMsk, int isNew
*/
static int port_tx_setup_fsm_state_wait_lock(fsm_t *fsm, int eventMsk, int isNewState) {
struct hal_port_state * ps = (struct hal_port_state*) fsm->priv;
halPortLpdcTx_t *txSetup=ps->lpdc.txSetup;
uint32_t value;
if ( pcs_readl(ps, MDIO_LPC_STAT,&value)>=0 ) {
......@@ -197,8 +202,6 @@ static int port_tx_setup_fsm_state_wait_lock(fsm_t *fsm, int eventMsk, int isNew
rts_enable_ptracker(ps->hw_index, 1);
_pll_state.channels[ps->hw_index].flags = 0;
libwr_tmo_init(&txSetup->calib_timeout,
TX_CAL_PHASE_MEAS_TIMEOUT, 1);
fsm_fire_state(fsm, HAL_PORT_TX_SETUP_STATE_MEASURE_PHASE);
}
......@@ -216,6 +219,10 @@ static int port_tx_setup_fsm_state_measure_phase(fsm_t *fsm, int eventMsk, int i
halPortLpdcTx_t *txSetup=ps->lpdc.txSetup;
updatePllState(ps);
if ( isNewState ) {
libwr_tmo_init(&txSetup->calib_timeout, TX_CAL_PHASE_MEAS_TIMEOUT, 1);
}
if (!(_pll_state.channels[ps->hw_index].flags & CHAN_PMEAS_READY)) {
if (libwr_tmo_expired(&txSetup->calib_timeout) )
{
......@@ -299,8 +306,6 @@ static int port_tx_setup_fsm_state_validate(fsm_t *fsm, int eventMsk, int isNewS
led_set_wrmode(ps->hw_index,SFP_LED_WRMODE_OFF);
fsm_fire_state(fsm, HAL_PORT_TX_SETUP_STATE_WAIT_OTHER_PORTS);
txSetupDone(ps);
return 0;
}
/*
......@@ -311,8 +316,12 @@ static int port_tx_setup_fsm_state_wait_other_ports(fsm_t *fsm, int eventMsk, in
{
struct hal_port_state * ps = (struct hal_port_state*) fsm->priv;
if ( isNewState )
txSetupDone(ps);
if (txSetupDoneOnAllPorts(ps) ) {
_write_tx_calibration_file(ps);
if (ps->lpdc.globalLpdc->numberOfLpdcPorts )
_write_tx_calibration_file(ps);
fsm_fire_state(fsm,HAL_PORT_TX_SETUP_STATE_DONE);
}
return 0;
......@@ -342,7 +351,7 @@ static int port_tx_setup_fsm_build_events(fsm_t *fsm) {
void hal_port_tx_setup_init_all(struct hal_port_state * ports, halGlobalLPDC_t *globalLpdc) {
int index;
int numberOfLpdcPorts = 0;
uint32_t maskLpdcPorts=0;
uint32_t maskUsedPorts=0;
int firstLpdcPort = -1;
int lastLpdcPort = -1;
char name[64];
......@@ -360,6 +369,7 @@ void hal_port_tx_setup_init_all(struct hal_port_state * ports, halGlobalLPDC_t *
this global structure as they need to know whether all
the LPDC-supporting ports have been calibrated */
ps->lpdc.globalLpdc = globalLpdc;
maskUsedPorts|=((uint32_t)1)<<ps->hw_index;
/* Fill in global info needed for operation */
if (ps->lpdc.isSupported) {
......@@ -372,7 +382,7 @@ void hal_port_tx_setup_init_all(struct hal_port_state * ports, halGlobalLPDC_t *
/* count number of supported ports*/
numberOfLpdcPorts++;
maskLpdcPorts|=((uint32_t)1)<<ps->hw_index;
}
/* Fill txSetup fsm structure */
snprintf(name, sizeof(name), "PortTxSetupFSM.%d", ps->hw_index);
......@@ -386,12 +396,12 @@ void hal_port_tx_setup_init_all(struct hal_port_state * ports, halGlobalLPDC_t *
}
}
globalLpdc->maskUsedPorts=maskUsedPorts;
/* if there are any LPDC ports, do some preparation */
if(globalLpdc && numberOfLpdcPorts) {
/* fill in the global structure */
globalLpdc->numberOfLpdcPorts = numberOfLpdcPorts;
globalLpdc->maskLpdcPorts=maskLpdcPorts;
globalLpdc->maskTxSetupDonePorts = 0;
globalLpdc->calFileSynced = 0;
globalLpdc->firstLpdcPort = firstLpdcPort;
......@@ -406,11 +416,25 @@ void hal_port_tx_setup_init_all(struct hal_port_state * ports, halGlobalLPDC_t *
_load_tx_calibration_file(ports);
/* Force going to FREE running master for the calibration */
if ( hal_tmg_get_mode()!=HAL_TIMING_MODE_FREE_MASTER)
if ( hal_tmg_get_mode(NULL)!=HAL_TIMING_MODE_FREE_MASTER)
hal_tmg_set_mode(HAL_TIMING_MODE_FREE_MASTER);
}
}
//static void hal_port_tx_setup_fsm_reset(struct hal_port_state * ps )
//{
// fsm_set_state( &ps->lpdc.txSetupFSM, -1 ); // reset state
// fsm_fire_state( &ps->lpdc.txSetupFSM, HAL_PORT_TX_SETUP_STATE_START );
//
// if ( hal_tmg_get_mode(NULL)==HAL_TIMING_MODE_BC)
// hal_tmg_set_mode(HAL_TIMING_MODE_FREE_MASTER);
// ps->locked=0;
//
// pcs_writel(ps, MDIO_LPC_CTRL_RESET_RX |
// MDIO_LPC_CTRL_DMTD_SOURCE_TXOUTCLK,
// MDIO_LPC_CTRL);
//}
/* Init the TX SETUP FSM on a given port */
void hal_port_tx_setup_fsm_init(struct hal_port_state * ps ) {
fsm_init_state(&ps->lpdc.txSetupFSM);
......@@ -559,12 +583,3 @@ static int _within_range(int x, int minval, int maxval, int wrap)
}
void hal_port_tx_setup_fsm_reset(struct hal_port_state * ps )
{
fsm_set_state( &ps->lpdc.txSetupFSM, -1 ); // reset state
fsm_fire_state( &ps->lpdc.txSetupFSM, HAL_PORT_TX_SETUP_STATE_START );
pcs_writel(ps, MDIO_LPC_CTRL_RESET_RX |
MDIO_LPC_CTRL_DMTD_SOURCE_TXOUTCLK,
MDIO_LPC_CTRL);
}
......@@ -41,9 +41,6 @@ extern struct wrs_shm_head *hal_shmem_hdr;
#define FSM_DEBUG 1
#if FSM_DEBUG
static timeout_t debug_tmo;
#endif
hal_ports_t halPorts;
......@@ -263,9 +260,6 @@ int hal_port_shmem_init(char *logfilename)
hal_port_state_fsm_init_all(halPorts.ports, &halPorts.globalLpdc); // Init main port FSM for all ports
if ( FSM_DEBUG )
libwr_tmo_init( &debug_tmo, 1000, 1 );
led_init_all_ports(halPorts.ports); // Reset all leds
halPorts.numberOfPorts = index;
......@@ -274,7 +268,7 @@ int hal_port_shmem_init(char *logfilename)
/* We are done, mark things as valid */
hal_shmem->nports = halPorts.numberOfPorts ;
hal_shmem->hal_mode = hal_tmg_get_mode();
hal_shmem->hal_mode = hal_tmg_get_mode(NULL);
ret = libwr_cfg_get("READ_SFP_DIAG_ENABLE");
if (ret && !strcmp(ret, "y")) {
......@@ -576,7 +570,7 @@ static void _cb_port_poll_rts_state(int timerId){
/* poll_rts_state does not write to shmem */
hal_port_poll_rts_state();
// Update timing mode
hal_shmem->hal_mode = hal_tmg_get_mode();
hal_shmem->hal_mode = hal_tmg_get_mode(NULL);
}
static void _cb_port_poll_sfp(int timerId){
......@@ -636,21 +630,14 @@ static void _cb_port_update_link_leds(int timerId){
led_link_update(halPorts.ports);
}
/* Executes the port FSM for all ports. Called regularly by the main loop. */
void hal_port_update_all()
{
timer_scan(_timerParameters,PORT_TIMER_COUNT);
/* lock shmem */
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_BEGIN);
static void printFsmDebugInfo(void) {
static timeout_t _fsm_debug_tmo={.repeat=-1}; // Use -1 to know that the timer must be initialized
hal_port_state_fsm_run_all(halPorts.ports);
/* unlock shmem */
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_END);
if( FSM_DEBUG && libwr_tmo_expired( &debug_tmo ))
{
if ( _fsm_debug_tmo.repeat==-1) {
libwr_tmo_init( &_fsm_debug_tmo, 1000, 1 );
return;
}
if ( libwr_tmo_expired( &_fsm_debug_tmo ) ) {
int i;
printf("PortDBG: \n");
......@@ -659,26 +646,48 @@ void hal_port_update_all()
struct hal_port_state *ps = &halPorts.ports[i];
char txEventsStr[128];
char rxEventsStr[128];
char pllEventsStr[128];
char eventsStr[128];
if ( !ps->in_use || !ps->lpdc.isSupported )
if ( !ps->in_use )
continue;
strncpy( eventsStr, fsm_get_event_mask_as_string( &ps->fsm ), sizeof(txEventsStr) );
strncpy( txEventsStr, fsm_get_event_mask_as_string( &ps->lpdc.txSetupFSM ), sizeof(txEventsStr) );
strncpy( rxEventsStr, fsm_get_event_mask_as_string( &ps->lpdc.rxSetupFSM ), sizeof(rxEventsStr) );
strncpy( pllEventsStr, fsm_get_event_mask_as_string( &ps->pllFsm ), sizeof(rxEventsStr) );
printf(" - wri%02d: PORT:%-20s TX:%-21s (%-40s) RX:%-21s (%-40s) bslide=%d\n",
printf(" wri%02d: PORT:%-12s[%-36s] TX:%-16s[%-10s] RX:%-12s[%-25s] PLL:%-12s[%-25s] bs=%d\n",
ps->hw_index + 1,
fsm_get_state_name( &ps->fsm ),
eventsStr,
fsm_get_state_name( &ps->lpdc.txSetupFSM ),
txEventsStr,
fsm_get_state_name( &ps->lpdc.rxSetupFSM ),
rxEventsStr,
fsm_get_state_name( &ps->pllFsm ),
pllEventsStr,
ps->calib.bitslide_ps
);
}
}
}
/* Executes the port FSM for all ports. Called regularly by the main loop. */
void hal_port_update_all()
{
timer_scan(_timerParameters,PORT_TIMER_COUNT);
/* lock shmem */
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_BEGIN);
hal_port_state_fsm_run_all(halPorts.ports);
/* unlock shmem */
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_END);
if ( FSM_DEBUG )
printFsmDebugInfo();
}
int hal_port_enable_tracking(const char *port_name)
{
......@@ -699,6 +708,9 @@ int hal_port_start_lock(const char *port_name, int priority)
if ( !ps )
return -1; /* unknown port */
if ( rts_lock_channel(ps->hw_index, 0)<0 ) {
return -1;
}
ps->evt_lock=1;
return 0;
}
......
......@@ -33,11 +33,13 @@ int hal_tmg_init(const char * logfilename)
return 0;
}
int hal_tmg_get_mode(void)
int hal_tmg_get_mode(uint32_t *hwIndex)
{
struct rts_pll_state *hs = getRtsStatePtr();
if (isRtsStateValid())
if (isRtsStateValid()) {
if ( hwIndex!=NULL )
*hwIndex=hs->current_ref;
switch (hs->mode) {
case RTS_MODE_GM_EXTERNAL:
return HAL_TIMING_MODE_GRAND_MASTER;
......@@ -48,6 +50,7 @@ int hal_tmg_get_mode(void)
case RTS_MODE_DISABLED:
return HAL_TIMING_MODE_DISABLED;
}
}
return -1;
}
......
......@@ -11,7 +11,7 @@
#define HAL_TIMING_H
extern int hal_tmg_set_mode(uint32_t tm);
extern int hal_tmg_get_mode(void);
extern int hal_tmg_get_mode(uint32_t *hwIndex);
extern int hal_tmg_init(const char * logfilename);
#endif
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