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

Add new timer facility

New facility added to control a timer used to schedule the different
action in HAL. This facility is used to accelerate the processing of the
FSM during the TX and RX calibrations.
parent fabd2de5
...@@ -29,12 +29,6 @@ ...@@ -29,12 +29,6 @@
#define MAX_CLEANUP_CALLBACKS 16 #define MAX_CLEANUP_CALLBACKS 16
typedef enum {
TMO_UPDATE_ALL=0,
TMO_UPDATE_FAN,
TMO_COUNT
}main_tmo_id_t;
static void cb_timer_update_fan(int timerId); static void cb_timer_update_fan(int timerId);
static void cb_timer_update_all(int timerId); static void cb_timer_update_all(int timerId);
...@@ -42,7 +36,7 @@ static void cb_timer_update_all(int timerId); ...@@ -42,7 +36,7 @@ static void cb_timer_update_all(int timerId);
static timer_parameter_t _timerParameters[] = { static timer_parameter_t _timerParameters[] = {
{ {
.id=TMO_UPDATE_ALL, .id=TMO_UPDATE_ALL,
.tmoMs=10, // 100ms .tmoMs=100,
.repeat=1, .repeat=1,
.cb=cb_timer_update_all .cb=cb_timer_update_all
}, },
...@@ -52,11 +46,11 @@ static timer_parameter_t _timerParameters[] = { ...@@ -52,11 +46,11 @@ static timer_parameter_t _timerParameters[] = {
.repeat=1, .repeat=1,
.cb=cb_timer_update_fan .cb=cb_timer_update_fan
}, },
{
.id=TMO_END_BLOCK
}
}; };
#define MAIN_TIMER_COUNT (sizeof(_timerParameters)/sizeof(timer_parameter_t))
static int daemon_mode = 0; static int daemon_mode = 0;
static hal_cleanup_callback_t cleanup_cb[MAX_CLEANUP_CALLBACKS]; static hal_cleanup_callback_t cleanup_cb[MAX_CLEANUP_CALLBACKS];
static char *logfilename; static char *logfilename;
...@@ -292,7 +286,7 @@ int main(int argc, char *argv[]) ...@@ -292,7 +286,7 @@ int main(int argc, char *argv[])
if (hal_init()) if (hal_init())
exit(1); exit(1);
timer_init(_timerParameters,MAIN_TIMER_COUNT); timer_init(_timerParameters);
/* /*
* Main loop update - polls for WRIPC requests and rolls the port * Main loop update - polls for WRIPC requests and rolls the port
...@@ -309,7 +303,7 @@ int main(int argc, char *argv[]) ...@@ -309,7 +303,7 @@ int main(int argc, char *argv[])
hal_wripc_update(25 /* max ms delay */); hal_wripc_update(25 /* max ms delay */);
// Check main timers and call callback if timeout expires // Check main timers and call callback if timeout expires
timer_scan(_timerParameters,MAIN_TIMER_COUNT); timer_scan(_timerParameters);
if ( hal_shmem->shmemState== HAL_SHMEM_STATE_INITITALIZING) { if ( hal_shmem->shmemState== HAL_SHMEM_STATE_INITITALIZING) {
// Check if all ports have been initialized // Check if all ports have been initialized
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <hal_exports.h> #include <hal_exports.h>
#include "driver_stuff.h" #include "driver_stuff.h"
#include "hal_timer.h"
#include "hal_ports.h" #include "hal_ports.h"
#include "hal_port_leds.h" #include "hal_port_leds.h"
...@@ -107,7 +108,7 @@ static halPortFsmGen_t _portFsm = { ...@@ -107,7 +108,7 @@ static halPortFsmGen_t _portFsm = {
//TODO-ML: the below structure is redundant, consider reogranization to use //TODO-ML: the below structure is redundant, consider reogranization to use
// hal_port_rts_state // hal_port_rts_state
static struct rts_pll_state _pll_state; static struct rts_pll_state _pll_state;
static uint32_t rxCalibInProgressMask=0;
static __inline__ void updatePllState(struct hal_port_state * ps) { static __inline__ void updatePllState(struct hal_port_state * ps) {
// update PLL state once for all ports // update PLL state once for all ports
...@@ -138,12 +139,14 @@ static int _hal_port_rx_setup_state_start(void *vpfg, int eventMsk, int isNewSta ...@@ -138,12 +139,14 @@ static int _hal_port_rx_setup_state_start(void *vpfg, int eventMsk, int isNewSta
} }
if ( ps->lpdc->isSupported ) { if ( ps->lpdc->isSupported ) {
/* Wait a bit to make sure early_link_up is resetted. This
/* Wait a bit to make sure early_link_up is reseted. This
timeout is initialized in hal_port_rx_setup_init_fsm(), timeout is initialized in hal_port_rx_setup_init_fsm(),
see detailed description there. */ see detailed description there. */
if (! libwr_tmo_expired(&rxSetup->earlyup_timeout)) { if (! libwr_tmo_expired(&rxSetup->earlyup_timeout)) {
return 0; return 0;
} }
// LPDC support // LPDC support
pcs_writel(ps, MDIO_LPC_CTRL_TX_ENABLE | pcs_writel(ps, MDIO_LPC_CTRL_TX_ENABLE |
MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK, MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK,
...@@ -167,6 +170,16 @@ static int _hal_port_rx_setup_state_start(void *vpfg, int eventMsk, int isNewSta ...@@ -167,6 +170,16 @@ static int _hal_port_rx_setup_state_start(void *vpfg, int eventMsk, int isNewSta
*/ */
static int _hal_port_rx_setup_state_reset_pcs(void *vpfg, int eventMsk, int isNewState) { static int _hal_port_rx_setup_state_reset_pcs(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps; struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
uint32_t lastMask=rxCalibInProgressMask;
// Accelerate the treatment of the FSM engine if needed
rxCalibInProgressMask|=1<<ps->hw_index;
if ( lastMask!=rxCalibInProgressMask )
pr_info("%s: port=%s rxCalibInProgressMask=0x%x\n",__func__,ps->name,rxCalibInProgressMask);
if ( lastMask!=rxCalibInProgressMask && rxCalibInProgressMask) {
timer_update_tmo(TMO_UPDATE_ALL,99 /*10*/);
}
if( _isHalRxSetupEventEarlyLinkUp(eventMsk)) { if( _isHalRxSetupEventEarlyLinkUp(eventMsk)) {
halPortLpdcRx_t *rxSetup=ps->lpdc->rxSetup; halPortLpdcRx_t *rxSetup=ps->lpdc->rxSetup;
...@@ -241,11 +254,12 @@ static int _hal_port_rx_setup_state_validate(void *vpfg, int eventMsk, int isNew ...@@ -241,11 +254,12 @@ static int _hal_port_rx_setup_state_validate(void *vpfg, int eventMsk, int isNew
MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK, MDIO_LPC_CTRL_DMTD_SOURCE_RXRECCLK,
MDIO_LPC_CTRL); MDIO_LPC_CTRL);
pcs_writel(ps, BMCR_ANENABLE | BMCR_ANRESTART, MII_BMCR); pcs_writel(ps, BMCR_ANENABLE | BMCR_ANRESTART, MII_BMCR);
rts_enable_ptracker(ps->hw_index, 0);
pr_info("wri%d: RX calibration complete at phase %d " pr_info("wri%d: RX calibration complete at phase %d "
"ps (after %d attempts).\n", ps->hw_index + 1, "ps (after %d attempts).\n", ps->hw_index + 1,
phase, rxSetup->attempts); phase, rxSetup->attempts);
rts_enable_ptracker(ps->hw_index, 0);
sleep(1); // fixme: really needed? sleep(1); // fixme: really needed?
_fireState(vpfg, HAL_PORT_RX_SETUP_STATE_DONE); _fireState(vpfg, HAL_PORT_RX_SETUP_STATE_DONE);
} }
...@@ -258,14 +272,24 @@ static int _hal_port_rx_setup_state_validate(void *vpfg, int eventMsk, int isNew ...@@ -258,14 +272,24 @@ static int _hal_port_rx_setup_state_validate(void *vpfg, int eventMsk, int isNew
* *
* if LPDC supported * if LPDC supported
* if early_link_down event then state=START * if early_link_down event then state=START
* if link up event then return final state machine reached
* *
*/ */
static int _hal_port_rx_setup_state_done(void *vpfg, int eventMsk, int isNewState) { static int _hal_port_rx_setup_state_done(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps; struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
uint32_t lastMask=rxCalibInProgressMask;
// restore original speed for the treatment of the FSM engine
rxCalibInProgressMask&=~(1<<ps->hw_index);
if ( lastMask!=rxCalibInProgressMask )
pr_info("%s: port=%s rxCalibInProgressMask=0x%x\n",__func__,ps->name,rxCalibInProgressMask);
if ( lastMask!=rxCalibInProgressMask && !rxCalibInProgressMask) {
timer_restore_tmo(TMO_UPDATE_ALL);
}
/* earlyLinkUp detection only if LPDC support */ /* earlyLinkUp detection only if LPDC support */
if ( ps->lpdc->isSupported ) { if ( ps->lpdc->isSupported ) {
if ( !_isHalRxSetupEventEarlyLinkUp(eventMsk)) { if ( !_isHalRxSetupEventEarlyLinkUp(eventMsk)) {
// Port went done // Port went done
pr_info("rxcal: early link flag lost on port wri%d\n", pr_info("rxcal: early link flag lost on port wri%d\n",
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "hal_port_gen_fsm.h" #include "hal_port_gen_fsm.h"
#include "driver_stuff.h" #include "driver_stuff.h"
#include "hal_port_leds.h" #include "hal_port_leds.h"
#include "hal_timer.h"
#include "hal_main.h" #include "hal_main.h"
#include "hal_ports.h" #include "hal_ports.h"
#include "hal_port_fsm_txP.h" #include "hal_port_fsm_txP.h"
...@@ -90,6 +91,7 @@ static halPortFsmGen_t _portFsm = { ...@@ -90,6 +91,7 @@ static halPortFsmGen_t _portFsm = {
.pe=_fsmEvtTable .pe=_fsmEvtTable
}; };
//TODO-ML: the below structure is redundant, consider reogranization to use //TODO-ML: the below structure is redundant, consider reogranization to use
// hal_port_rts_state // hal_port_rts_state
static struct rts_pll_state _pll_state; static struct rts_pll_state _pll_state;
...@@ -97,6 +99,8 @@ static struct rts_pll_state _pll_state; ...@@ -97,6 +99,8 @@ static struct rts_pll_state _pll_state;
static char *_calibrationFileName = "/update/tx_phase_cal.conf"; static char *_calibrationFileName = "/update/tx_phase_cal.conf";
struct config_file *_calibrationConfig; // Calibration config form file struct config_file *_calibrationConfig; // Calibration config form file
static uint32_t txCalibInProgressMask=0;
static __inline__ void updatePllState(struct hal_port_state * ps) { static __inline__ void updatePllState(struct hal_port_state * ps) {
// update PLL state once for all ports // update PLL state once for all ports
rts_get_state(&_pll_state); rts_get_state(&_pll_state);
...@@ -127,6 +131,17 @@ static int _within_range(int x, int minval, int maxval, int wrap); ...@@ -127,6 +131,17 @@ 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) { static int _hal_port_tx_setup_state_start(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps; struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
uint32_t lastMask=txCalibInProgressMask;
// Accelerate the treatment of the FSM engine if needed
txCalibInProgressMask|=1<<ps->hw_index;
if ( lastMask!=txCalibInProgressMask )
pr_info("%s: port=%s txCalibInProgressMask=0x%x\n",__func__,ps->name,txCalibInProgressMask);
if ( lastMask!=txCalibInProgressMask && txCalibInProgressMask) {
timer_update_tmo(TMO_UPDATE_ALL,99 /*10*/);
}
if ( !ps->lpdc->isSupported ) { if ( !ps->lpdc->isSupported ) {
// NO LPDC support // NO LPDC support
...@@ -306,6 +321,16 @@ static int _hal_port_tx_setup_state_validate(void *vpfg, int eventMsk, int isNew ...@@ -306,6 +321,16 @@ static int _hal_port_tx_setup_state_validate(void *vpfg, int eventMsk, int isNew
static int _hal_port_tx_setup_state_wait_other_ports(void *vpfg, int eventMsk, int isNewState) { 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; struct hal_port_state * ps = ((halPortFsmGen_t *) vpfg)->ps;
uint32_t lastMask=txCalibInProgressMask;
// restore original speed for the treatment of the FSM engine
txCalibInProgressMask&=~(1<<ps->hw_index);
if ( lastMask!=txCalibInProgressMask )
pr_info("%s: port=%s txCalibInProgressMask=0x%x\n",__func__,ps->name,txCalibInProgressMask);
if ( lastMask!=txCalibInProgressMask && txCalibInProgressMask==0) {
timer_restore_tmo(TMO_UPDATE_ALL);
}
if (txSetupDoneOnAllPorts(ps) ) { if (txSetupDoneOnAllPorts(ps) ) {
_write_tx_calibration_file(ps); _write_tx_calibration_file(ps);
......
...@@ -41,19 +41,6 @@ extern struct wrs_shm_head *hal_shmem_hdr; ...@@ -41,19 +41,6 @@ extern struct wrs_shm_head *hal_shmem_hdr;
hal_ports_t halPorts; hal_ports_t halPorts;
/**
* End new stuff
*/
typedef enum {
TMO_PORT_TMO_RTS=0,
TMO_PORT_POLL_SFP,
TMO_PORT_SFP_DOM,
TMO_UPDATE_SYNC_LEDs,
TMO_UPDATE_LINK_LEDS,
TMO_COUNT
}port_tmo_id_t;
static void _cb_port_poll_rts_state(int timerId); static void _cb_port_poll_rts_state(int timerId);
static void _cb_port_poll_sfp(int timerId); static void _cb_port_poll_sfp(int timerId);
static void _cb_port_poll_sfp_dom(int timerId); static void _cb_port_poll_sfp_dom(int timerId);
...@@ -93,10 +80,11 @@ static timer_parameter_t _timerParameters[] = { ...@@ -93,10 +80,11 @@ static timer_parameter_t _timerParameters[] = {
.repeat=1, .repeat=1,
.cb=_cb_port_update_link_leds .cb=_cb_port_update_link_leds
}, },
{
.id=TMO_END_BLOCK
}
}; };
#define PORT_TIMER_COUNT (sizeof(_timerParameters)/sizeof(timer_parameter_t))
/* prototypes */ /* prototypes */
static int hal_port_check_lpdc_support(struct hal_port_state * ps); static int hal_port_check_lpdc_support(struct hal_port_state * ps);
...@@ -227,7 +215,7 @@ int hal_port_shmem_init(char *logfilename) ...@@ -227,7 +215,7 @@ int hal_port_shmem_init(char *logfilename)
pr_info("Initializing switch ports...\n"); pr_info("Initializing switch ports...\n");
/* default timeouts */ /* default timeouts */
timer_init(_timerParameters,PORT_TIMER_COUNT); timer_init(_timerParameters);
/* Open a single raw socket for accessing the MAC addresses, etc. */ /* Open a single raw socket for accessing the MAC addresses, etc. */
halPorts.hal_port_fd = socket(AF_PACKET, SOCK_DGRAM, 0); halPorts.hal_port_fd = socket(AF_PACKET, SOCK_DGRAM, 0);
...@@ -634,7 +622,7 @@ static void _cb_port_update_link_leds(int timerId){ ...@@ -634,7 +622,7 @@ static void _cb_port_update_link_leds(int timerId){
/* Executes the port FSM for all ports. Called regularly by the main loop. */ /* Executes the port FSM for all ports. Called regularly by the main loop. */
void hal_port_update_all() void hal_port_update_all()
{ {
timer_scan(_timerParameters,PORT_TIMER_COUNT); timer_scan(_timerParameters);
/* lock shmem */ /* lock shmem */
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_BEGIN); wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_BEGIN);
......
...@@ -61,5 +61,4 @@ extern int hal_add_cleanup_callback(hal_cleanup_callback_t cb); ...@@ -61,5 +61,4 @@ extern int hal_add_cleanup_callback(hal_cleanup_callback_t cb);
extern int pcs_writel(struct hal_port_state *p, uint16_t value, int reg); extern int pcs_writel(struct hal_port_state *p, uint16_t value, int reg);
extern int pcs_readl(struct hal_port_state * p, int reg, uint32_t *value); extern int pcs_readl(struct hal_port_state * p, int reg, uint32_t *value);
#endif #endif
...@@ -6,27 +6,95 @@ ...@@ -6,27 +6,95 @@
* *
*/ */
#include <time.h>
#include <libwr/wrs-msg.h>
#include "hal_timer.h" #include "hal_timer.h"
void timer_init(timer_parameter_t *p,int nbTimers) { #define TIMER_MAX_BLOCKS 5
int index;
for ( index=0; index < nbTimers; index++ ) { static timer_parameter_t *blocks[TIMER_MAX_BLOCKS];
static time_t start, end;
static void _timer_register_block(timer_parameter_t *p) {
int i;
for (i=0; i<TIMER_MAX_BLOCKS; i++ ) {
if ( blocks[i]==p) {
// Already registered
return;
}
if ( blocks[i]==NULL) {
// Register the block
blocks[i]=p;
return;
}
}
}
void timer_init(timer_parameter_t *p) {
_timer_register_block(p);
while (p->id!=TMO_END_BLOCK) {
p->tmoMsRef=p->tmoMs; // Save the original value
libwr_tmo_init(&p->timer,p->tmoMs, p->repeat); libwr_tmo_init(&p->timer,p->tmoMs, p->repeat);
p++; p++;
} }
} }
void timer_scan(timer_parameter_t *p,int nbTimers) { void timer_scan(timer_parameter_t *p) {
int index;
for ( index=0; index < nbTimers; index++ ) { while (p->id!=TMO_END_BLOCK) {
if (libwr_tmo_expired(&p->timer) && p->cb!=NULL) { if (libwr_tmo_expired(&p->timer) && p->cb!=NULL) {
(*p->cb)(p->id); (*p->cb)(p->id);
} }
p++; p++;
} }
} }
void timer_update_tmo(tmo_id_t id,uint32_t tmoMs) {
int i;
for (i=0; i<TIMER_MAX_BLOCKS; i++ ) {
timer_parameter_t *p;
if ( (p=blocks[i])!=NULL ) {
while (p->id!=TMO_END_BLOCK) {
if (p->id==id) {
if ( p->tmoMs!=tmoMs ) {
p->tmoMs=tmoMs;
pr_info("%s: Timer %d set to %dms\n",__func__,id,p->tmoMs);
libwr_tmo_init(&p->timer,p->tmoMs, p->repeat);
time(&start);
}
}
p++;
}
}
}
}
void timer_restore_tmo(tmo_id_t id) {
int i;
for (i=0; i<TIMER_MAX_BLOCKS; i++ ) {
timer_parameter_t *p;
if ( (p=blocks[i])!=NULL ) {
while (p->id!=TMO_END_BLOCK) {
if (p->id==id) {
if ( p->tmoMs!=p->tmoMsRef) {
p->tmoMs=p->tmoMsRef;
pr_info("%s: Timer %d restored to %dms\n",__func__,id,p->tmoMs);
libwr_tmo_init(&p->timer,p->tmoMs, p->repeat);
time(&end);
pr_info("%s: Execution time %f seconds\n",__func__,difftime(end, start));
}
}
p++;
}
}
}
}
...@@ -11,16 +11,34 @@ ...@@ -11,16 +11,34 @@
#include <libwr/timeout.h> #include <libwr/timeout.h>
// List of all timer
typedef enum {
// RESERVED
TMO_END_BLOCK,
// MAIN
TMO_UPDATE_ALL=1,
TMO_UPDATE_FAN,
// PORTS
TMO_PORT_TMO_RTS,
TMO_PORT_POLL_SFP,
TMO_PORT_SFP_DOM,
TMO_UPDATE_SYNC_LEDs,
TMO_UPDATE_LINK_LEDS,
}tmo_id_t;
typedef struct { typedef struct {
int id; tmo_id_t id;
uint32_t tmoMs; // Time out value in ms uint32_t tmoMs; // Time out value in ms
uint32_t tmoMsRef; // Time out reference value in ms
int repeat; // restart timeout automatically int repeat; // restart timeout automatically
timeout_t timer; timeout_t timer;
void (*cb)(int timerId); void (*cb)(int timerId);
}timer_parameter_t; }timer_parameter_t;
extern void timer_update_tmo(tmo_id_t id,uint32_t tmoMs);
extern void timer_init(timer_parameter_t *p,int nbTimers); extern void timer_restore_tmo(tmo_id_t id);
extern void timer_scan(timer_parameter_t *p,int nbTimers); extern void timer_init(timer_parameter_t *p);
extern void timer_scan(timer_parameter_t *p);
#endif #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