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

HAL review

New implementation of HAL using sub state machines. The objective is to
facilitate the integration of the new feature "Low Phase Drift
Calibration" which needs two new state machines.
The HAL state machine is available by opening the hal.html file
parent 328b9f52
......@@ -6,12 +6,12 @@
#include <string.h>
/* Port state machine states */
#define HAL_PORT_STATE_DISABLED 0
#define HAL_PORT_STATE_LINK_DOWN 1
#define HAL_PORT_STATE_UP 2
#define HAL_PORT_STATE_CALIBRATION 3
#define HAL_PORT_STATE_LOCKING 4
#define HAL_PORT_STATE_RESET 5
typedef enum {
HAL_PORT_STATE_INIT=0,
HAL_PORT_STATE_DISABLED,
HAL_PORT_STATE_LINK_DOWN,
HAL_PORT_STATE_LINK_UP,
} halPortState_t;
/* Read temperature from SFPs */
#define READ_SFP_DIAG_ENABLE 1
......@@ -59,33 +59,36 @@ typedef struct hal_port_calibration {
struct shw_sfp_caldata sfp;
struct shw_sfp_header sfp_header_raw;
struct shw_sfp_dom sfp_dom_raw;
int sfpPresent;
} hal_port_calibration_t;
/* Internal port state structure */
struct hal_port_state {
/* non-zero: allocated */
int in_use;
/* linux i/f name */
char name[16];
typedef struct {
int state;
int nextState;
} halPortFsmState_t;
/* MAC addr */
uint8_t hw_addr[6];
typedef struct {
int isSupported; /* Set if Low Phase Drift Calibration is supported */
halPortFsmState_t txSetupStates;
halPortFsmState_t rxSetupStates;
}halPortLPDC_t; /* data for Low phase drift calibration */
/* ioctl() hw index */
int hw_index;
/* file descriptor for ioctls() */
int fd;
/* Internal port state structure */
struct hal_port_state {
int in_use; /* non-zero: allocated */
char name[16]; /* linux i/f name */
uint8_t hw_addr[6]; /* MAC addr */
int hw_index; /* ioctl() hw index : 0..n */
int fd; /* file descriptor for ioctls() */
int hw_addr_auto;
/* port FSM state (HAL_PORT_STATE_xxxx) */
int state;
halPortFsmState_t portStates;
/* fiber type, used to get alpha for SFP frequency */
int fiber_index;
/* 1: PLL is locked to this port */
int locked;
int fiber_index;/* fiber type, used to get alpha for SFP frequency */
int locked; /* 1: PLL is locked to this port */
/* calibration data */
hal_port_calibration_t calib;
......@@ -94,11 +97,10 @@ struct hal_port_state {
uint32_t phase_val;
int phase_val_valid;
int tx_cal_pending, rx_cal_pending;
/* locking FSM state */
int lock_state;
/*reference lock period in picoseconds*/
uint32_t clock_period;
int lock_state; /* locking FSM state */
uint32_t clock_period; /*reference lock period in picoseconds*/
/* approximate DMTD phase value (on slave port) at which RX timestamp
* (T2) counter transistion occurs (picoseconds) */
......@@ -108,8 +110,7 @@ struct hal_port_state {
* counter transistion occurs (picoseconds) */
uint32_t t4_phase_transition;
/* Endpoint's base address */
uint32_t ep_base;
uint32_t ep_base;/* Endpoint's base address */
/* whether SFP has diagnostic Monitoring capability */
int has_sfp_diag;
......@@ -122,6 +123,16 @@ struct hal_port_state {
int synchronized; // <>0 if port is synchronized
int portInfoUpdated; // Set to 1 when updated
/* Events to process */
int evt_reset; /* Set if a reset is requested */
int evt_lock; /* Set if the ptracker must be activated*/
int evt_linkUp; /* Set if link is up ( driver call */
/* Low phase drift calibration data */
halPortLPDC_t lpdc;
/* Pll FSM */
halPortFsmState_t pllStates;
};
struct hal_temp_sensors {
......@@ -132,8 +143,7 @@ struct hal_temp_sensors {
};
/* This is the overall structure stored in shared memory */
#define HAL_SHMEM_VERSION 12 /* Version 12, added monitor to
struct hal_port_state */
#define HAL_SHMEM_VERSION 13 /* Version 13, HAL code review */
struct hal_shmem_header {
int nports;
......@@ -143,10 +153,14 @@ struct hal_shmem_header {
int read_sfp_diag;
};
static inline int state_up(int state)
static inline int get_port_state(struct hal_port_state *ps)
{
return ps->portStates.state;
}
static inline int state_up(struct hal_port_state *ps)
{
return (state != HAL_PORT_STATE_LINK_DOWN
&& state != HAL_PORT_STATE_DISABLED);
return get_port_state(ps) == HAL_PORT_STATE_LINK_UP;
}
static inline struct hal_port_state *hal_lookup_port(
......
Subproject commit 135c480e387345315ed3d205342629fea45a1ca3
Subproject commit 5285a9abcd9b2c30c914129e05831e0eeccac0fc
......@@ -98,8 +98,8 @@ time_t wrsPortStatusTable_data_fill(unsigned int *n_rows)
* values defined as WRS_PORT_STATUS_LINK_*
*/
wrsPortStatusTable_array[i].wrsPortStatusLink =
1 + state_up(port_state->state);
if (port_state->state == HAL_PORT_STATE_DISABLED) {
1 + state_up(&port_state);
if (get_port_state(port_state) == HAL_PORT_STATE_DISABLED) {
wrsPortStatusTable_array[i].wrsPortStatusSfpError =
WRS_PORT_STATUS_SFP_ERROR_PORT_DOWN;
/* if port is disabled don't fill
......
......@@ -666,7 +666,7 @@ void show_ports(int hal_alive, int ppsi_alive)
if (mode == SHOW_GUI) {
/* check if link is up */
if (state_up(port_state->state))
if (state_up(port_state))
term_cprintf(C_GREEN, " %-5s", if_name);
else
term_cprintf(C_RED, "*%-5s", if_name);
......@@ -816,7 +816,7 @@ void show_ports(int hal_alive, int ppsi_alive)
}
term_cprintf(C_WHITE, "\n");
} else if (mode & WEB_INTERFACE) {
printf("%s ", state_up(port_state->state)
printf("%s ", state_up(port_state)
? "up" : "down");
printf("%s ", port_state->locked
? "Locked" : "NoLock");
......@@ -825,7 +825,7 @@ void show_ports(int hal_alive, int ppsi_alive)
? "Calibrated" : "Uncalibrated");
} else if (print_port) {
printf("port:%s ", if_name);
printf("lnk:%d ", state_up(port_state->state));
printf("lnk:%d ", state_up(port_state));
printf("lock:%d ", port_state->locked);
print_port = 0;
}
......
......@@ -401,7 +401,11 @@ struct dump_info hal_port_info [] = {
DUMP_FIELD(int, hw_index),
DUMP_FIELD(int, fd),
DUMP_FIELD(int, hw_addr_auto),
DUMP_FIELD(int, state),
DUMP_FIELD(int, portStates.state),
DUMP_FIELD(int, pllStates.state),
DUMP_FIELD(int, lpdc.isSupported),
DUMP_FIELD(int, lpdc.txSetupStates.state),
DUMP_FIELD(int, lpdc.rxSetupStates.state),
DUMP_FIELD(int, fiber_index),
DUMP_FIELD(int, locked),
/* these fields are defined as uint32_t but we prefer %i to %x */
......
......@@ -2,7 +2,9 @@
# We are now Kconfig-based
-include ../../.config
OBJS = hal_exports.o hal_main.o hal_ports.o hal_timing.o
OBJS = hal_exports.o hal_main.o hal_ports.o hal_timing.o \
hal_port_gen_fsm.o hal_port_fsm.o hal_port_fsm_tx.o hal_port_fsm_rx.o hal_port_fsm_pll.o\
hal_port_leds.o hal_timer.o
BINARY = wrsw_hal
......
......@@ -77,7 +77,7 @@ int halexp_lock_cmd(const char *port_name, int command, int priority)
* both the PLLs and the PPS Generator. */
int halexp_pps_cmd(int cmd, hexp_pps_params_t * params)
{
int busy,ret;
int ret;
pr_debug("halexp_pps_cmd: cmd=%d\n", cmd);
switch (cmd) {
......@@ -142,9 +142,7 @@ int halexp_pps_cmd(int cmd, hexp_pps_params_t * params)
return shw_pps_gen_enable_output(params->pps_valid);
case HEXP_PPSG_CMD_SET_TIMING_MODE:
ret=shw_pps_set_timing_mode(params->timing_mode);
hal_update_timing_mode();
return ret;
return hal_set_timing_mode(params->timing_mode);
case HEXP_PPSG_CMD_GET_TIMING_MODE:{
ret=hal_get_timing_mode();
......
......@@ -22,11 +22,38 @@
#include <libwr/timeout.h>
#include "wrsw_hal.h"
#include "hal_timer.h"
#include <rt_ipc.h>
#define MAX_CLEANUP_CALLBACKS 16
#define UPDATE_FAN_PERIOD 500
#define UPDATE_ALL_PERIOD 100
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_all(int timerId);
/* Polling timeouts (RT Subsystem & SFP detection) */
static timer_parameter_t _timerParameters[] = {
{
.id=TMO_UPDATE_ALL,
.tmoMs=100, // 100ms
.repeat=1,
.cb=cb_timer_update_all
},
{
.id=TMO_UPDATE_FAN,
.tmoMs=500, // 500ms
.repeat=1,
.cb=cb_timer_update_fan
},
};
#define MAIN_TIMER_COUNT (sizeof(_timerParameters)/sizeof(timer_parameter_t))
static int daemon_mode = 0;
static hal_cleanup_callback_t cleanup_cb[MAX_CLEANUP_CALLBACKS];
......@@ -223,11 +250,25 @@ static void hal_parse_cmdline(int argc, char *argv[])
}
}
static void cb_timer_update_fan(int timerId) {
struct hal_temp_sensors temp_sensors; /* local copy of temperatures */
/* Update fans and get temperatures values. Don't write
* temperatures directly to the shmem to reduce the
* critical section of shmem */
shw_update_fans(&temp_sensors);
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_BEGIN);
memcpy(&hal_shmem->temp, &temp_sensors,
sizeof(temp_sensors));
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_END);
}
static void cb_timer_update_all(int timerId) {
hal_port_update_all();
}
int main(int argc, char *argv[])
{
struct hal_temp_sensors temp_sensors; /* local copy of temperatures */
static timeout_t update_fan_tmo;
static timeout_t update_all_tmo;
wrs_msg_init(argc, argv, LOG_DAEMON);
......@@ -246,8 +287,7 @@ int main(int argc, char *argv[])
if (hal_init())
exit(1);
libwr_tmo_init(&update_fan_tmo, UPDATE_FAN_PERIOD, 1);
libwr_tmo_init(&update_all_tmo, UPDATE_ALL_PERIOD, 1);
timerInit(_timerParameters,MAIN_TIMER_COUNT);
/*
* Main loop update - polls for WRIPC requests and rolls the port
......@@ -263,19 +303,8 @@ int main(int argc, char *argv[])
for (;;) {
hal_update_wripc(25 /* max ms delay */);
if (libwr_tmo_expired(&update_all_tmo))
hal_port_update_all();
if (libwr_tmo_expired(&update_fan_tmo)) {
/* Update fans and get temperatures values. Don't write
* temperatures directly to the shmem to reduce the
* critical section of shmem */
shw_update_fans(&temp_sensors);
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_BEGIN);
memcpy(&hal_shmem->temp, &temp_sensors,
sizeof(temp_sensors));
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_END);
}
// Check main timers and call callback if timeout expires
timerScan(_timerParameters,MAIN_TIMER_COUNT);
}
hal_shutdown();
......
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Jean-Claude BAU - CERN
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <linux/if.h>
#include <rt_ipc.h>
#include <hal_exports.h>
#include <libwr/hal_shmem.h>
#include <libwr/switch_hw.h>
#include "hal_ports.h"
#include "hal_port_leds.h"
#include "hal_port_gen_fsm.h"
#include "hal_port_fsmP.h"
#include "hal_port_fsm_rx.h"
#include "hal_port_fsm_tx.h"
#include "hal_port_fsm_pll.h"
#include "wrsw_hal.h"
/**
* State machine
* States :
* - HAL_PORT_STATE_INIT:
* Inital state
* - HAL_PORT_STATE_DISABLED:
* The port is disabled and waiting for a SFP insertion
* - HAL_PORT_STATE_LINK_DOWN:
* A Sfp is inserted but the port is waiting for being up
* - HAL_PORT_STATE_LINK_UP:
* The port is UP and operational
* Events :
* - timer : triggered regularly to execute background work
* - sfpInserted: A Sfp has been inserted
* - sfpRemoved : A Sfp has been removed
* - linkUp : A link up has been detected (driver ioctl)
* - Link down : Port is going down
* - reset : Reset of the port is requested
*
*/
/* external prototypes */
static int _builPortEvents(void * vpfg);
static int _hal_port_state_init(void *vpfg, int eventMsk, int isNewState);
static int _hal_port_state_disabled(void *vpfg, int eventMsk, int isNewState);
static int _hal_port_state_link_down(void *vpfg, int eventMsk, int isNewState);
static int _hal_port_state_link_up(void *vpfg, int eventMsk, int isNewState);
static void _init_port(struct hal_port_state * ps);
static void _reset_port(struct hal_port_state * ps);
static void _unlock_port( struct hal_port_state * ps);
static int _get_port_link_state(struct hal_port_state * ps,int *linkUp);
static halPortStateTable_t _fsmStateTable[] =
{
{ .state=HAL_PORT_STATE_INIT,
.stateName="INIT",
FSM_SET_FCT_NAME(_hal_port_state_init)
},
{ .state=HAL_PORT_STATE_DISABLED,
.stateName="DISABLED",
FSM_SET_FCT_NAME(_hal_port_state_disabled)
},
{ .state=HAL_PORT_STATE_LINK_DOWN,
.stateName="LINK_DOWN",
FSM_SET_FCT_NAME(_hal_port_state_link_down)
},
{ .state=HAL_PORT_STATE_LINK_UP,
.stateName="LINK_UP",
FSM_SET_FCT_NAME(_hal_port_state_link_up)
},
{.state=1}
};
static halPortEventTable_t _fsmEvtTable[] = {
{
.evtMask = HAL_PORT_EVENT_TIMER,
.evtName="TIMER"
},
{
.evtMask =HAL_PORT_EVENT_SFP_INSERTED,
.evtName = "SFP_INS"
},
{
.evtMask =HAL_PORT_EVENT_SFP_REMOVED,
.evtName = "SFP_REM"
},
{
.evtMask =HAL_PORT_EVENT_LINK_UP,
.evtName = "LINK_UP"
},
{ .evtMask =HAL_PORT_EVENT_LINK_DOWN,
.evtName = "LINK_DOWN"
},
{ .evtMask =HAL_PORT_EVENT_RESET,
.evtName = "REET"
},
{ .evtMask = -1 } };
static halPortFsmGen_t _portFsm = {
.fsm_name="PortFsm",
.fctBuilEvents=_builPortEvents,
.pt=_fsmStateTable,
.pe=_fsmEvtTable
};
/* INIT state
*
* if entering in state then
* init port
* init TX SETUP FSM
* fi
* run TX SETUP FSM
* if final state reached (TX SETUP FSM) then state = DISABLED
*
*/
static int _hal_port_state_init(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
if ( isNewState ) {
_init_port(ps);
/* Init the tx state machine */
hal_port_tx_setup_init_fsm(ps);
}
/* if final state reached for tx setup state machine
* then we can go to DISABLED state
*/
if (hal_port_tx_setup_state_fsm(ps)==1 )
_fireState(vpfg,HAL_PORT_STATE_DISABLED);
return 0;
}
/*
* DISABLED state
*
* if entering in state then reset port
* if SFP inserted the state=LINK_DOWN
*/
static int _hal_port_state_disabled(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
if ( isNewState ) {
_reset_port(ps);
}
if ( _isHalEventSfpInserted(eventMsk) )
_fireState(vpfg,HAL_PORT_STATE_LINK_DOWN);
return 0;
}
/* LINK_DOWN state
*
* if SFP removed event then state= DISABLED
* if entering in state then
* reset port
* init RX_SETUP FSM
* fi
* run RX_SETUP FSM
* if final state (RX_SETUP FSM ) reached then state=LINK_UP
*/
static int _hal_port_state_link_down(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
// High priority event received
if ( _isHalEventSfpRemoved(eventMsk) ) {
_fireState(vpfg,HAL_PORT_STATE_DISABLED);
return 0;
}
if ( isNewState ) {
_reset_port(ps);
/* Init the rx state machine */
hal_port_rx_setup_init_fsm(ps);
}
/* if final state reached for tx setup state machine then
* we can go LINK_UP state
*/
if (hal_port_rx_setup_state_fsm(ps)==1 ) {
_fireState(vpfg,HAL_PORT_STATE_LINK_UP);
return 0;
}
return 0;
}
/* LINK_UP state :
*
* if SFP removed event then state= DISABLED
* if reset or link down events then state= LINK_DOWN
* if entering in state then inititialize PLL FSM
* Run PLL FSM
* Update Leds
*/
static int _hal_port_state_link_up(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
if ( _isHalEventSfpRemoved(eventMsk) ) {
_unlock_port(ps);
_fireState(vpfg,HAL_PORT_STATE_DISABLED);
return 0;
}
if ( _isHalEventReset(eventMsk) || _isHalEventLinkDown(eventMsk)) {
_unlock_port(ps);
_fireState(vpfg,HAL_PORT_STATE_LINK_DOWN);
return 0;
}
if ( isNewState ) {
// Init PLL FSM
hal_port_pll_init_fsm(ps);
}
// Run PLL state machine
hal_port_pll_state_fsm(ps);
// Update leds
{
// Update synced led
int ledValue= ps->synchronized
&& (ps->portInfoUpdated--) > -50 // 50 * 100ms (FSM call rate) = 5seconds
? 1 : 0;
led_set_synched(ps->hw_index, ledValue);
// Update link led
if (ps->portMode == PORT_MODE_SLAVE)
ledValue=SFP_LED_WRMODE_SLAVE;
else if (ps->portMode == PORT_MODE_MASTER)
ledValue=SFP_LED_WRMODE_MASTER;
else
ledValue=SFP_LED_WRMODE_OTHER;
led_set_wrmode(ps->hw_index,ledValue);
}
return 0;
}
/*
* Build all events
*/
static int _builPortEvents(void * vpfg) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
int portEventMask=HAL_PORT_EVENT_TIMER;
if ( ps->evt_linkUp != -1 ) {
portEventMask |= ps->evt_linkUp ?
HAL_PORT_EVENT_LINK_UP : HAL_PORT_EVENT_LINK_DOWN;
}
if ( ps->evt_reset ) {
portEventMask |= HAL_PORT_EVENT_RESET;
ps->evt_reset=0;
}
portEventMask |= ps->calib.sfpPresent ?
HAL_PORT_EVENT_SFP_INSERTED : HAL_PORT_EVENT_SFP_REMOVED;
return portEventMask;
}
/* Init the FSM on all ports. Called one time at startup */
void hal_port_state_fsm_init( struct hal_port_state * ps ) {
int portIndex;
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 */
}
}
/* Call FSM for on all ports */
void hal_port_state_fsm( struct hal_port_state * ps ) {
int portIndex;
hal_port_poll_rts_state(); // Update rts state on all ports
/* Call state machine for all ports */
for (portIndex = 0; portIndex < HAL_MAX_PORTS; portIndex++) {
if ( ps->in_use) {
_portFsm.ps=ps;
_portFsm.st=&ps->portStates;
/* Update evt_linkUp */
if ( _get_port_link_state(ps,&ps->evt_linkUp)==-1 ) {
// IOTCL error : We put -1 in the link state. It will be considered as invalid
ps->evt_linkUp=-1;
}
hal_port_generic_fsm(&_portFsm);
}
ps++; /* Next port */
}
}
/* Reset port
* Called when entering in states DISABLED and LINK_DOWN and when the port is initialized the first time
*/
static void _reset_port(struct hal_port_state * ps)
{
// Disable ptracker : Needed if we were in state LINK_UP with a timing mode set to BC
rts_enable_ptracker(ps->hw_index, 0);
// Clear data
ps->calib.rx_calibrated =
ps->calib.tx_calibrated =
ps->locked = 0;
ps->lock_state =
ps->tx_cal_pending =
ps->rx_cal_pending = 0;
ps->portMode= PORT_MODE_OTHER;
ps->synchronized=ps->portInfoUpdated=0;
ps->locked=0;
ps->calib.phy_tx_min = ps->calib.phy_rx_min = 0; // No longer used
ps->calib.delta_tx_board = 0; /* never set */
ps->calib.delta_rx_board = 0; /* never set */
ps->tx_cal_pending = 0;
ps->rx_cal_pending = 0;
/* Set link/wrmode LEDs to other. Master/slave
* color is set in the different place */
led_set_wrmode(ps->hw_index,SFP_LED_WRMODE_OTHER);
/* turn off synced LED */
led_set_synched(ps->hw_index, 0);
}
/* 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 _unlock_port( struct hal_port_state * ps)
{
if ( hal_get_timing_mode()==HAL_TIMING_MODE_BC ) {
hal_set_timing_mode(HAL_TIMING_MODE_FREE_MASTER);
}
// 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)
{
struct ifreq ifr;
strncpy(ifr.ifr_name, ps->name, sizeof(ifr.ifr_name));
if (ioctl(halPorts.hal_port_fd, SIOCGIFFLAGS, &ifr) < 0 ) {
pr_error("%s: IOCTL error detected : Cannot check link up on %s",__func__,ps->name);
return -1;
}
*linkUp=(ifr.ifr_flags & IFF_UP && ifr.ifr_flags & IFF_RUNNING);
return 0;
}
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Jean-Claude BAU - CERN
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*
*
*/
#ifndef HAL_PORT_FSM_H
#define HAL_PORT_FSM_H
/* Prototypes */
void fsm_state_machine( struct hal_port_state * ps );
void hal_port_state_fsm( struct hal_port_state * ps );
void hal_port_state_fsm_init( struct hal_port_state * ps );
#endif
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Jean-Claude BAU - CERN
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*
*
*/
#ifndef HAL_PORT_FSMP_H
#define HAL_PORT_FSMP_H
#include "hal_port_fsm.h"
typedef enum
{
HAL_PORT_EVENT_TIMER=(1<<0),
HAL_PORT_EVENT_SFP_INSERTED=(1<<1),
HAL_PORT_EVENT_SFP_REMOVED=(1<<3),
HAL_PORT_EVENT_LINK_UP=(1<<4),
HAL_PORT_EVENT_LINK_DOWN=(1<<5),
HAL_PORT_EVENT_RESET=(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 _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;
}
#endif
#include <hal_exports.h>
#include <libwr/hal_shmem.h>
#include "hal_ports.h"
#include "hal_port_fsm_pllP.h"
/**
* State machine
* States :
* - HAL_PORT_PLL_STATE_UNLOCKED: Inital state
* - HAL_PORT_PLL_STATE_LOCKING : Waiting PLL locking
* - HAL_PORT_PLL_STATE_LOCKED : Final state. Pll locked
* Events :
* - HAL_PORT_PLL_EVENT_TIMER : Use to do background stuff
* - HAL_PORT_PLL_EVENT_LOCK : Lock is requested (timing mode=BC)
* - HAL_PORT_PLL_EVENT_LOCKED : Port is locked
* - HAL_PORT_PLL_EVENT_UNLOCK : Pll is unlocked
* - HAL_PORT_PLL_EVENT_DISABLED : PLL lock is not requested
*
*
*/
/* external prototypes */
static int _buildEvents(void * vpfg);
static int _hal_port_pll_state_unlocked(void *vpfg, int eventMsk, int isNewState);
static int _hal_port_pll_state_locked(void *vpfg, int eventMsk, int isNewState);
static int _hal_port_pll_state_locking(void *vpfg, int eventMsk, int isNewState);
static int _check_pll_lock(struct hal_port_state *ps);
static halPortStateTable_t _fsmStateTable[] =
{
{
.state=HAL_PORT_PLL_STATE_UNLOCKED,
.stateName="UNLOCKED",
FSM_SET_FCT_NAME(_hal_port_pll_state_unlocked)
},
{
.state=HAL_PORT_PLL_STATE_LOCKING,
.stateName="LOCKING",
FSM_SET_FCT_NAME(_hal_port_pll_state_locking)
},
{
.state=HAL_PORT_PLL_STATE_LOCKED,
.stateName="LOCKED",
FSM_SET_FCT_NAME(_hal_port_pll_state_locked)
},
{.state=1}
};
static halPortEventTable_t _fsmEvtTable[] = {
{
.evtMask = HAL_PORT_PLL_EVENT_TIMER,
.evtName="TIMER"
},
{
.evtMask = HAL_PORT_PLL_EVENT_LOCK,
.evtName="LOCK"
},
{
.evtMask = HAL_PORT_PLL_EVENT_UNLOCKED,
.evtName="UNLOCKED"
},
{
.evtMask = HAL_PORT_PLL_EVENT_LOCKED,
.evtName="LOCKED"
},
{
.evtMask = HAL_PORT_PLL_EVENT_DISABLE,
.evtName="DISABLE"
},
{ .evtMask = -1 } };
static halPortFsmGen_t _portFsm = {
.fsm_name="PortFsmPll",
.fctBuilEvents=_buildEvents,
.pt=_fsmStateTable,
.pe=_fsmEvtTable
};
/* UNLOCKED state
*
* if locked event then
* state=LOCKED (should not happen )
* else
* if lock event then
* lock channel
* state=LOCKING
* fi
* fi
*
*/
static int _hal_port_pll_state_unlocked(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
if ( _isHalPllEventLocked(eventMsk) ) {
_fireState(vpfg,HAL_PORT_PLL_STATE_LOCKED);
return 0;
}
if ( _isHalPllEventLock(eventMsk) ) {
if ( rts_lock_channel(ps->hw_index, 0)>=0 ) {
_fireState(vpfg,HAL_PORT_PLL_STATE_LOCKING);
return 0;
}
}
return 0;
}
/*
* LOCKING state
*
* if locked event then state=LOCKED
* else if unlock event then state=UNLOCKED
*/
static int _hal_port_pll_state_locking(void *vpfg, int eventMsk, int isNewState) {
if ( _isHalPllEventLocked(eventMsk) ) {
_fireState(vpfg,HAL_PORT_PLL_STATE_LOCKED);
return 0;
}
if ( _isHalPllEventDisable(eventMsk) ) {
_fireState(vpfg,HAL_PORT_PLL_STATE_UNLOCKED);
return 0;
}
return 0;
}
/*
* LOCKED state
*
* if unlock event then
* state = LOCKING
* else if disabled event then state=UNLOCK
* else return final state machine reached
* fi
*/
static int _hal_port_pll_state_locked(void *vpfg, int eventMsk, int isNewState) {
if ( _isHalPllEventUnlock(eventMsk) ) {
_fireState(vpfg,HAL_PORT_PLL_STATE_LOCKING);
return 0;
}
if ( _isHalPllEventDisable(eventMsk) ) {
_fireState(vpfg,HAL_PORT_PLL_STATE_UNLOCKED);
return 0;
}
return 1; /* final state */
}
/*
* Build FSM events
*
* Lock & Locked events are generated only if the timing mode is BC
*/
static int _buildEvents(void * vpfg) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
int portEventMask=HAL_PORT_PLL_EVENT_TIMER;
int tm;
tm= hal_get_timing_mode();
ps->locked=0;
if ( tm == HAL_TIMING_MODE_BC) {
int locked=_check_pll_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;
}
/* Init PLL FSM */
void hal_port_pll_init_fsm(struct hal_port_state * ps ) {
_portFsm.ps=ps;
_portFsm.st=&ps->pllStates;
ps->pllStates.state=-1;
_fireState(&_portFsm,HAL_PORT_PLL_STATE_UNLOCKED);
}
/* FSM state machine for TX setup on a given port
* Returned value:
* 1: when final state has been reached
* 0: when final state has not been reached
* -1: error detected
*/
int hal_port_pll_state_fsm( struct hal_port_state * ps ) {
_portFsm.ps=ps;
_portFsm.st=&ps->pllStates;
return hal_port_generic_fsm(&_portFsm);
}
extern struct rts_pll_state hal_port_rts_state;
extern int hal_port_rts_state_valid;
/* Returns 1 if the port is locked, 0 if unlocked, -1 in case of error */
static int _check_pll_lock(struct hal_port_state *ps)
{
struct rts_pll_state *hs = getRtsStatePtr();
if (!ps)
return -1;
if (!isRtsStateValid())
return -1;
if (hs->delock_count > 0)
return -1;
return ( hs->mode==RTS_MODE_BC &&
hs->current_ref == ps->hw_index &&
(hs->flags & RTS_DMTD_LOCKED) &&
(hs->flags & RTS_REF_LOCKED));
}
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Jean-Claude BAU - CERN
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*
*
*/
#ifndef HAL_PORT_FSM_PLL_H
#define HAL_PORT_FSM_PLL_H
/* prototypes */
void hal_port_pll_init_fsm(struct hal_port_state * ps );
int hal_port_pll_state_fsm( struct hal_port_state * ps );
#endif
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Jean-Claude BAU - CERN
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*
*
*/
#ifndef HAL_PORT_FSM_PLLP_H
#define HAL_PORT_FSM_PLLP_H
#include <libwr/wrs-msg.h>
#include "hal_port_gen_fsm.h"
#include "hal_port_fsm_pll.h"
typedef enum {
HAL_PORT_PLL_STATE_UNLOCKED=0,
HAL_PORT_PLL_STATE_LOCKING,
HAL_PORT_PLL_STATE_LOCKED
} halPortPllState_t;
typedef enum
{
HAL_PORT_PLL_EVENT_TIMER=(1<<0),
HAL_PORT_PLL_EVENT_UNLOCKED=(1<<1),
HAL_PORT_PLL_EVENT_LOCK=(1<<2),
HAL_PORT_PLL_EVENT_LOCKED=(1<<3),
HAL_PORT_PLL_EVENT_DISABLE=(1<<4),
}halPortPllEventMask_t ;
static __inline__ int _isHalPllEventLock(halPortPllEventMask_t eventMsk) {
return eventMsk & HAL_PORT_PLL_EVENT_LOCK;
}
static __inline__ int _isHalPllEventLocked(halPortPllEventMask_t eventMsk) {
return eventMsk & HAL_PORT_PLL_EVENT_LOCKED;
}
static __inline__ int _isHalPllEventUnlock(halPortPllEventMask_t eventMsk) {
return eventMsk & HAL_PORT_PLL_EVENT_UNLOCKED;
}
static __inline__ int _isHalPllEventDisable(halPortPllEventMask_t eventMsk) {
return eventMsk & HAL_PORT_PLL_EVENT_DISABLE;
}
#endif
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Jean-Claude BAU - CERN
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*
*
*/
#include <sys/ioctl.h>
#include <net/if.h>
#include <stdint.h>
#include <libwr/wrs-msg.h>
#include <libwr/hal_shmem.h>
#include <hal_exports.h>
#include "driver_stuff.h"
#include "hal_ports.h"
#include "hal_port_leds.h"
#include "hal_port_fsm_rxP.h"
/**
* State machine
* States :
* - HAL_PORT_RX_SETUP_STATE_START:
* Inital state
* - HAL_PORT_RX_SETUP_STATE_CALIB_NO_LPDC :
* Calibration when LPDC is not supported
* - HAL_PORT_RX_SETUP_STATE_DONE:
* RX setup terminated
* Events :
* - timer : triggered regularly to execute background work
* - linkUp : A link up has been detected (driver ioctl)
* - Link down : Port is going down
*/
/* external prototypes */
static int _buildEvents(void * vpfg);
static int _hal_port_rx_setup_state_start(void *vpfg, int eventMsk, int isNewState);
static int _hal_port_rx_setup_state_calib_no_lpdc(void *vpfg, int ventMsk, int isNewState);
static int _hal_port_rx_setup_state_done(void *vpfg, int ventMsk, int isNewState);
static uint32_t _pcs_readl(struct hal_port_state * ps, int reg);
static halPortStateTable_t _fsmStateTable[] =
{
{ .state=HAL_PORT_RX_SETUP_STATE_START,
.stateName="START",
FSM_SET_FCT_NAME(_hal_port_rx_setup_state_start)
},
{ .state=HAL_PORT_RX_SETUP_STATE_CALIB_NO_LPDC,
.stateName="CALIB_NO_LPDC",
FSM_SET_FCT_NAME(_hal_port_rx_setup_state_calib_no_lpdc)
},
{ .state=HAL_PORT_RX_SETUP_STATE_DONE,
.stateName="DONE",
FSM_SET_FCT_NAME(_hal_port_rx_setup_state_done)
},
{.state=1}
};
static halPortEventTable_t _fsmEvtTable[] = {
{
.evtMask = HAL_PORT_RX_SETUP_EVENT_TIMER,
.evtName="TIMER"
},
{
.evtMask = HAL_PORT_RX_SETUP_EVENT_LINK_UP,
.evtName="LINK_UP"
},
{
.evtMask = HAL_PORT_RX_SETUP_EVENT_LINK_DOWN,
.evtName="LINK_DOWN"
},
{ .evtMask = -1 } };
static halPortFsmGen_t _portFsm = {
.fsm_name="PortFsmRxSetup",
.fctBuilEvents=_buildEvents,
.pt=_fsmStateTable,
.pe=_fsmEvtTable
};
/* START state
* (Hypothesis: LPDC support has already been determined before )
*
* if link up event then
* if LPDC is not supported then state = CALIB_NO_LPDC
* else state = DONE
* fi
*/
static int _hal_port_rx_setup_state_start(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
if ( _isHalRxSetupEventLinkUp(eventMsk) ) {
_fireState(vpfg,ps->lpdc.isSupported ?
HAL_PORT_RX_SETUP_STATE_DONE : // Not yet implemented
HAL_PORT_RX_SETUP_STATE_CALIB_NO_LPDC);
}
return 0;
}
/* CALIB_NO_LPDC state
*
* if link down event then state = START
* if link up state then
* Calculate the bit slide.
* if bit slide successfully calculated then state=DONE
* fi
*/
static int _hal_port_rx_setup_state_calib_no_lpdc(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
int32_t bit_slide_steps=(_pcs_readl(ps, 16) >> 4) & 0x1f;
if ( _isHalRxSetupEventLinkDown(eventMsk) ) {
_fireState(vpfg,HAL_PORT_RX_SETUP_STATE_START);
return 0;
}
if ( _isHalRxSetupEventLinkUp(eventMsk) ) {
if ( bit_slide_steps !=-1 ) {
ps->calib.tx_calibrated = 1;
ps->calib.rx_calibrated = 1;
/* FIXME: use proper register names */
ps->calib.bitslide_ps=(uint32_t)bit_slide_steps*(uint32_t)800; /* 1 step = 800ps */
pr_info("%s:%s: bitslide= %d\n",__func__,ps->name,bit_slide_steps);
ps->calib.delta_rx_phy = ps->calib.phy_rx_min;
ps->calib.delta_tx_phy = ps->calib.phy_tx_min;
ps->tx_cal_pending = 0;
ps->rx_cal_pending = 0;
_fireState(vpfg,HAL_PORT_RX_SETUP_STATE_DONE);
}
}
return 0;
}
/*
* DONE state
*
* if 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) {
if ( _isHalRxSetupEventLinkDown(eventMsk) ) {
_fireState(vpfg,HAL_PORT_RX_SETUP_STATE_START);
return 0;
}
if ( _isHalRxSetupEventLinkUp(eventMsk) ) {
return 1; /* Final state reached */;
}
return 0;
}
/* Build FSM events */
static int _buildEvents(void *vpfg) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
int portEventMask=HAL_PORT_RX_SETUP_EVENT_TIMER;
if ( ps->evt_linkUp != -1 ) {
portEventMask |= ps->evt_linkUp ?
HAL_PORT_RX_SETUP_EVENT_LINK_UP : HAL_PORT_RX_SETUP_EVENT_LINK_DOWN;
}
return portEventMask;
}
/*
* Init RX SETUP FSM
*/
void hal_port_rx_setup_init_fsm(struct hal_port_state * ps ) {
_portFsm.ps=ps;
_portFsm.st=&ps->lpdc.rxSetupStates;
ps->lpdc.rxSetupStates.state=-1;
_fireState(&_portFsm,HAL_PORT_RX_SETUP_STATE_START);
}
/* FSM state machine for RX setup on a given port
* Returned value:
* 1: when final state has been reached
* 0: when final state has not been reached
* -1: error detected
*/
int hal_port_rx_setup_state_fsm( struct hal_port_state * ps ) {
_portFsm.ps=ps;
_portFsm.st=&ps->lpdc.rxSetupStates;
return hal_port_generic_fsm(&_portFsm);
}
static uint32_t _pcs_readl(struct hal_port_state * p, int reg)
{
struct ifreq ifr;
uint32_t rv;
strncpy(ifr.ifr_name, p->name, sizeof(ifr.ifr_name));
rv = NIC_READ_PHY_CMD(reg);
ifr.ifr_data = (void *)&rv;
if (ioctl(halPorts.hal_port_fd, PRIV_IOCPHYREG, &ifr) < 0) {
pr_error("%s: ioctl error: Cannot read bitslide \n",__func__);
return -1;
}
return NIC_RESULT_DATA(rv);
}
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Jean-Claude BAU - CERN
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*
*
*/
#ifndef HAL_PORT_FSM_RX_H
#define HAL_PORT_FSM_RX_H
/* prototypes */
void hal_port_rx_setup_init_fsm(struct hal_port_state * ps );
int hal_port_rx_setup_state_fsm( struct hal_port_state * ps );
#endif
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Jean-Claude BAU - CERN
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*
*
*/
#ifndef HAL_PORT_FSM_RXP_H
#define HAL_PORT_FSM_RXP_H
#include <libwr/wrs-msg.h>
#include "hal_port_gen_fsm.h"
typedef enum {
HAL_PORT_RX_SETUP_STATE_START=0,
HAL_PORT_RX_SETUP_STATE_CALIB_NO_LPDC,
HAL_PORT_RX_SETUP_STATE_DONE
} hapPortRxSetupState_t;
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)
}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;
}
#endif
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Jean-Claude BAU - CERN
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*
*
*/
#include <hal_exports.h>
#include <libwr/hal_shmem.h>
#include "hal_port_gen_fsm.h"
#include "hal_port_fsm_txP.h"
/**
* State machine
* States :
* - HAL_PORT_TX_SETUP_STATE_START:
* Inital state
* - HAL_PORT_TX_SETUP_STATE_DONE:
* TX setup terminated
* Events :
* - timer : triggered regularly to execute background work
*/
/* external prototypes */
static int _buildEvents(void * vpfg);
static int _hal_port_tx_setup_state_start(void *vpfg, int eventMsk, int isNewState);
static int _hal_port_tx_setup_state_done(void *vpfg, int eventMsk, int isNewState);
static halPortStateTable_t _fsmStateTable[] =
{
{ .state=HAL_PORT_TX_SETUP_STATE_START,
.stateName="START",
FSM_SET_FCT_NAME(_hal_port_tx_setup_state_start)
},
{ .state=HAL_PORT_TX_SETUP_STATE_DONE,
.stateName="DONE",
FSM_SET_FCT_NAME(_hal_port_tx_setup_state_done)
},
{.state=1}
};
static halPortEventTable_t _fsmEvtTable[] = {
{
.evtMask = HAL_PORT_TX_SETUP_EVENT_TIMER,
.evtName="TIMER"
},
{ .evtMask = -1 } };
static halPortFsmGen_t _portFsm = {
.fsm_name="PortFsmTxSetup",
.fctBuilEvents=_buildEvents,
.pt=_fsmStateTable,
.pe=_fsmEvtTable
};
/*
* START state
*
* If entering in state then
* Set LPDC supported accordingly to the hardware
* fi
* if LPDC is not supported then state=DONE
*
*/
static int _hal_port_tx_setup_state_start(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
if ( isNewState ) {
ps->lpdc.isSupported=0; // Not yet supported
}
if ( !ps->lpdc.isSupported ) {
// NO LPDC support
_fireState(vpfg,HAL_PORT_TX_SETUP_STATE_DONE);
return 0;
}
return 0;
}
/*
* DONE state
*
* Return final state machine reached
*/
static int _hal_port_tx_setup_state_done(void *vpfg, int eventMsk, int isNewState) {
return 1; /* Final state reached */
}
/* Build events mask */
static int _buildEvents(void *vpfg) {
return HAL_PORT_TX_SETUP_EVENT_TIMER;
}
/* Init the TX SETUP FSM on a given port */
void hal_port_tx_setup_init_fsm(struct hal_port_state * ps ) {
_portFsm.ps=ps;
_portFsm.st=&ps->lpdc.txSetupStates;
ps->lpdc.txSetupStates.state=-1;
_fireState(&_portFsm,HAL_PORT_TX_SETUP_STATE_START);
}
/* FSM state machine for TX setup on a given port
* Returned value:
* 1: when final state has been reached
* 0: when final state has not been reached
* -1: error detected
*/
int hal_port_tx_setup_state_fsm( struct hal_port_state * ps ) {
_portFsm.ps=ps;
_portFsm.st=&ps->lpdc.txSetupStates;
return hal_port_generic_fsm(&_portFsm);
}
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Jean-Claude BAU - CERN
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*
*
*/
#ifndef HAL_PORT_FSM_TX_H
#define HAL_PORT_FSM_TX_H
/* prototypes */
void hal_port_tx_setup_init_fsm(struct hal_port_state * ps );
int hal_port_tx_setup_state_fsm( struct hal_port_state * ps );
#endif
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Jean-Claude BAU - CERN
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*
*
*/
#ifndef HAL_PORT_FSM_TXP_H
#define HAL_PORT_FSM_TXP_H
#include <libwr/wrs-msg.h>
#include "hal_port_gen_fsm.h"
typedef enum {
HAL_PORT_TX_SETUP_STATE_START=0,
HAL_PORT_TX_SETUP_STATE_DONE
} hapPortTxSetupState_t;
typedef enum
{
HAL_PORT_TX_SETUP_EVENT_TIMER=(1<<0),
}halPortTxSetupEventMask_t ;
static __inline__ int _isHalTxSetupEventTimer(halPortTxSetupEventMask_t eventMsk) {
return eventMsk & HAL_PORT_TX_SETUP_EVENT_TIMER;
}
#endif
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Jean-Claude BAU - CERN
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*
*/
#include "hal_port_gen_fsm.h"
static char * _generic_build_events( halPortFsmGen_t *pfg, int *portEventMask);
/* Generic engine used by all ports states machine */
int hal_port_generic_fsm( halPortFsmGen_t *pfg) {
int ret=0;
if ( pfg->ps->in_use ) {
int portEventMask,isNewState;
char *evtStr=_generic_build_events(pfg, &portEventMask);
/* Check if state has changed */
if ( (isNewState=_isPendingState(pfg))==1 ) {
_consumeState(pfg);
}
/* Call state entry */
if (portEventMask || isNewState) {
halPortStateTable_t *pt=pfg->pt;
while (pt->state!=-1 ) {
if (pt->state==_getState(pfg) ) {
if ( FSM_GEN_DEBUG && pt->fctName!=NULL)
printf("%s.%s: Calling %s (newState=%d, evts=%s),\n",
pfg->ps->name,pfg->fsm_name,
pt->fctName, isNewState,evtStr);
ret=(*pt->fct)(pfg,portEventMask,isNewState);
if ( _isPendingState(pfg) ) {
/* Consume state immediately */
return hal_port_generic_fsm(pfg);
}
break;
}
pt++;
}
}
}
return ret;
}
static char * _generic_build_events( halPortFsmGen_t *pfg, int *portEventMask) {
*portEventMask=0;
if ( pfg->fctBuilEvents )
*portEventMask=(*pfg->fctBuilEvents)(pfg);
if ( FSM_GEN_DEBUG ) {
static char str[128];
int copy=*portEventMask;
halPortEventTable_t *pe=pfg->pe;
str[0]=0;
while (pe->evtMask!=-1 ) {
if (copy==0) break;
if ( (pe->evtMask & copy) !=0 ) {
if ( str[0]!=0)
strcat(str,"+");
strcat(str,pe->evtName);
copy &=~pe->evtMask;
}
pe++;
}
return str;
} else {
static char str[1]="";
return str;
}
}
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Jean-Claude BAU - CERN
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*
*
*/
#ifndef HAL_PORT_GEN_FSM_H
#define HAL_PORT_GEN_FSM_H
#include <libwr/wrs-msg.h>
#include <libwr/hal_shmem.h>
#define FSM_GEN_DEBUG 1
#define FSM_SET_FCT_NAME(name) .fct=name, .fctName=#name
/*
* Used to define the callback to call for a givent state
*/
typedef struct {
int state;
char * stateName;
int (*fct)(void * vpfg/* struct halPortFsmGen_t *pfg*/, int eventMsk, int newState);
char *fctName;
}halPortStateTable_t;
typedef struct {
int evtMask;
char * evtName;
}halPortEventTable_t;
/*
* Structure containing all information needed by the state machine
*/
typedef struct {
char * fsm_name;
int (*fctBuilEvents)(void * vpfg/* struct halPortFsmGen_t *pfg*/);
halPortStateTable_t *pt;
halPortEventTable_t *pe;
struct hal_port_state *ps;
halPortFsmState_t *st;
}halPortFsmGen_t;
extern halPortFsmGen_t *pfg;
static __inline__ int _getState(halPortFsmGen_t *pfg) {
return pfg->st->state;
}
static __inline__ int _setState(halPortFsmGen_t *pfg, int newState) {
return pfg->st->state=newState;
}
static __inline__ int _getNextState(halPortFsmGen_t *pfg) {
return pfg->st->nextState;
}
static __inline__ char * _getStateName(halPortFsmGen_t *pfg) {
halPortStateTable_t *pt=pfg->pt+_getState(pfg);
return pt->stateName;
}
static __inline__ void _consumeState(halPortFsmGen_t *pfg) {
pfg->st->state=_getNextState(pfg);
if (FSM_GEN_DEBUG)
printf("%s.%s: Enter state %s\n",pfg->ps->name,pfg->fsm_name,_getStateName(pfg));
}
static __inline__ void _fireState(halPortFsmGen_t *pfg, int newState) {
pfg->st->nextState=newState;
}
static __inline__ int _isPendingState(halPortFsmGen_t *pfg) {
return _getState(pfg) != _getNextState(pfg);
}
/* prototypes */
int hal_port_generic_fsm( halPortFsmGen_t *pfg);
#endif
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Jean-Claude BAU - CERN
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*
*
*/
#include <hal_exports.h>
#include <libwr/hal_shmem.h>
#include "hal_ports.h"
#include "hal_port_leds.h"
static struct Leds {
unsigned char sync_leds_map_to_update[HAL_MAX_PORTS];
unsigned char link_leds_map_to_update[HAL_MAX_PORTS];
unsigned char sync_leds_map[HAL_MAX_PORTS];
unsigned char link_leds_map[HAL_MAX_PORTS];
} _leds;
void led_init_all_ports(struct hal_port_state *ps ) {
int i;
// Clear data
memset(&_leds,0,sizeof(_leds));
for (i = 0; i < HAL_MAX_PORTS; i++) {
shw_sfp_set_led_synced(i, 0);
shw_sfp_set_generic(i, 0, SFP_LED_WRMODE1 | SFP_LED_WRMODE2);
}
}
/* to avoid i2c transfers to set the link LEDs, cache their state */
void led_set_wrmode(int portIndex, int value)
{
if (portIndex >= HAL_MAX_PORTS)
return;
_leds.link_leds_map_to_update[portIndex]=value;
}
void led_link_update(struct hal_port_state *ps) {
int i;
for (i = 0; i < HAL_MAX_PORTS; i++) {
unsigned char value=_leds.link_leds_map_to_update[i];
if ( value != _leds.link_leds_map[i]) {
_leds.link_leds_map[i]=value;
/* update the LED, don't forget to turn off LEDs if needed */
switch (value) {
case SFP_LED_WRMODE_SLAVE :
/* cannot set and clear LED in the same call! */
shw_sfp_set_generic(i, 1, SFP_LED_WRMODE1);
shw_sfp_set_generic(i, 0, SFP_LED_WRMODE2);
break;
case SFP_LED_WRMODE_OTHER :
/* cannot set and clear LED in the same call! */
shw_sfp_set_generic(i, 0, SFP_LED_WRMODE1);
shw_sfp_set_generic(i, 1, SFP_LED_WRMODE2);
break;
case SFP_LED_WRMODE_MASTER:
shw_sfp_set_generic(i, 1,SFP_LED_WRMODE1 | SFP_LED_WRMODE2);
break;
case SFP_LED_WRMODE_OFF :
shw_sfp_set_generic(i, 0,
SFP_LED_WRMODE1 | SFP_LED_WRMODE2);
break;
}
}
#if 0
if (port->in_use && state_up(port->state)) {
if (port->portMode == PORT_MODE_SLAVE)
set_led_wrmode(i, SFP_LED_WRMODE_SLAVE);
else if (port->portMode == PORT_MODE_MASTER)
set_led_wrmode(i, SFP_LED_WRMODE_MASTER);
else
set_led_wrmode(i, SFP_LED_WRMODE_OTHER);
}
port++;
#endif
}
}
/* to avoid i2c transfers to set the synced LEDs, cache their state */
void led_set_synched(int portIndex, int value)
{
if (portIndex >= HAL_MAX_PORTS)
return;
_leds.sync_leds_map[portIndex] = value;
}
void led_sync_update(struct hal_port_state *ps )
{
int i;
for (i = 0; i < HAL_MAX_PORTS; i++) {
#if 0
/* Check:
* --port in use
* --link is up
*/
if ( ps->in_use
&& state_up(ps->state) ) {
int ledValue;
ledValue= ps->synchronized
&& (ps->portInfoUpdated--) > -10
? 1 : 0;
set_led_synced(i, ledValue);
}
#else
unsigned char value=_leds.sync_leds_map_to_update[i];
if ( value != _leds.sync_leds_map[i]) {
// Update led
shw_sfp_set_led_synced(i, (int)value);
_leds.sync_leds_map[i] = value;
}
ps++;
#endif
}
}
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Jean-Claude BAU - CERN
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*
*
*/
#ifndef HAL_PORT_LEDS_H
#define HAL_PORT_LEDS_H
/* Prototypes */
extern void led_init_all_ports(struct hal_port_state *ps );
extern void led_set_wrmode(int portIndex, int val);
extern void led_link_update(struct hal_port_state *port);
extern void led_set_synched(int portIndex, int val);
extern void led_sync_update(struct hal_port_state *port );
#endif
......@@ -30,12 +30,10 @@
#include <hal_exports.h>
#include <libwr/hal_shmem.h>
#include "driver_stuff.h"
#define UPDATE_RTS_PERIOD 250 /* ms */
#define UPDATE_SFP_PERIOD 1000 /* ms */
#define UPDATE_SYNC_LEDS_PERIOD 500 /* ms */
#define UPDATE_LINK_LEDS_PERIOD 500 /* ms */
#define UPDATE_SFP_DOM_PERIOD 1000 /* ms */
#include "hal_timer.h"
#include "hal_port_fsm.h"
#include "hal_port_leds.h"
#include "hal_ports.h"
typedef struct {
struct pp_instance * ppi; /* pointer to the ppi instance */
......@@ -45,52 +43,72 @@ typedef struct {
extern struct hal_shmem_header *hal_shmem;
extern struct wrs_shm_head *hal_shmem_hdr;
/* Port table: the only item which is not "hal_port_*", as it's much used */
static struct hal_port_state *ports;
hal_ports_t halPorts;
/**
* End new stuff
*/
/* An fd of always opened raw sockets for ioctl()-ing Ethernet devices */
static int hal_port_fd;
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;
/* RT subsystem PLL state, polled regularly via mini-ipc */
struct rts_pll_state hal_port_rts_state;
int hal_port_rts_state_valid = 0;
static void _cb_port_poll_rts_state(int timerId);
static void _cb_port_poll_sfp(int timerId);
static void _cb_port_poll_sfp_dom(int timerId);
static void _cb_port_update_sync_leds(int timerId);
static void _cb_port_update_link_leds(int timerId);
/* Polling timeouts (RT Subsystem & SFP detection) */
static timeout_t hal_port_tmo_rts, hal_port_tmo_sfp;
static timeout_t update_sync_leds_tmo, update_link_leds_tmo;
static timeout_t update_sfp_dom_tmo;
static int hal_port_nports;
static timer_parameter_t _timerParameters[] = {
{
.id=TMO_PORT_TMO_RTS,
.tmoMs=250, // 250 ms
.repeat=1,
.cb=_cb_port_poll_rts_state
},
{
.id=TMO_PORT_POLL_SFP,
.tmoMs=1000, // 1s
.repeat=1,
.cb=_cb_port_poll_sfp
},
{
.id=TMO_PORT_SFP_DOM,
.tmoMs=1000, // 1s
.repeat=1,
.cb=_cb_port_poll_sfp_dom
},
{
.id=TMO_UPDATE_SYNC_LEDs,
.tmoMs= 500, // 500ms
.repeat=1,
.cb=_cb_port_update_sync_leds
},
{
.id=TMO_UPDATE_LINK_LEDS,
.tmoMs=500, // 500ms
.repeat=1,
.cb=_cb_port_update_link_leds
},
};
#define PORT_TIMER_COUNT (sizeof(_timerParameters)/sizeof(timer_parameter_t))
int hal_port_check_lock(const char *port_name);
static void update_link_leds(void);
static void set_led_wrmode(int p_index, int val);
static void set_led_synced(int p_index, int val);
static void update_sync_leds(void);
int hal_port_any_locked(void)
{
if (!hal_port_rts_state_valid)
if (!isRtsStateValid())
return -1;
if (hal_port_rts_state.current_ref == REF_NONE)
if (getRtsState().current_ref == REF_NONE)
return -1;
return hal_port_rts_state.current_ref;
}
/* Resets the state variables of a port and re-starts its state machines */
static void hal_port_reset_state(struct hal_port_state * p)
{
p->state = HAL_PORT_STATE_LINK_DOWN;
p->calib.rx_calibrated =
p->calib.tx_calibrated =
p->locked = 0;
p->lock_state =
p->tx_cal_pending =
p->rx_cal_pending = 0;
p->portMode= PORT_MODE_OTHER;
p->synchronized=0;
return getRtsState().current_ref;
}
/* checks if the port is supported by the FPGA firmware */
......@@ -100,16 +118,15 @@ static int hal_port_check_presence(const char *if_name, unsigned char *mac)
strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
if (ioctl(hal_port_fd, SIOCGIFHWADDR, &ifr) < 0)
if (ioctl(halPorts.hal_port_fd, SIOCGIFHWADDR, &ifr) < 0)
return 0;
memcpy(mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
return 1;
}
/* Port initialization, from dot-config values */
static int hal_port_init(int index)
static int hal_port_init(struct hal_port_state *ps, int index)
{
struct hal_port_state *p = &ports[index];
char key[128];
int port_i;
char *retValue;
......@@ -118,52 +135,40 @@ static int hal_port_init(int index)
/* index is 0..17, port_i 1..18 */
port_i = index + 1;
/* make sure the states and other variables are in their init state */
hal_port_reset_state(p);
/* read dot-config values to get the interface name */
sprintf(key,"PORT%02i_IFACE",port_i);
if( (retValue=libwr_cfg_get(key))==NULL)
return -1;
strncpy(p->name, retValue, 16);
strncpy(ps->name, retValue, 16);
/* check if the port is built into the firmware, if not, we are done */
if (!hal_port_check_presence(p->name, p->hw_addr))
if (!hal_port_check_presence(ps->name, ps->hw_addr))
return -1;
p->state = HAL_PORT_STATE_DISABLED;
p->in_use = 1;
p->calib.phy_tx_min = p->calib.phy_rx_min = 0; // No longer used
ps->in_use = 1;
p->calib.delta_tx_board = 0; /* never set */
p->calib.delta_rx_board = 0; /* never set */
/* get the number of a port from notation wriX */
sscanf(p->name + 3, "%d", &p->hw_index);
sscanf(ps->name + 3, "%d", &ps->hw_index);
/* hw_index is 0..17, p->name wri1..18 */
p->hw_index--;
p->t2_phase_transition = DEFAULT_T2_PHASE_TRANS;
p->t4_phase_transition = DEFAULT_T4_PHASE_TRANS;
p->clock_period = REF_CLOCK_PERIOD_PS;
ps->hw_index--;
/* Get fiber type */
p->fiber_index = 0; /* Default fiber value */
ps->fiber_index = 0; /* Default fiber value */
sprintf(key,"PORT%02i_FIBER",port_i);
if( (retValue=libwr_cfg_get(key))==NULL ) {
pr_error("port %i (%s): no key \"%s\" specified. Default fiber 0\n",
port_i, p->name,key);
port_i, ps->name,key);
} else {
if (sscanf(retValue, "%i", &p->fiber_index) != 1) {
if (sscanf(retValue, "%i", &ps->fiber_index) != 1) {
pr_error("port %i (%s): Invalid key \"%s\" value (%d). Default fiber 0\n",
port_i, p->name, key,*retValue);
port_i, ps->name, key,*retValue);
}
}
/* read dot-config values to get the number of defined fibers */
strcpy(key,"N_FIBER_ENTRIES");
if( (retValue=libwr_cfg_get(key))==NULL) {
pr_error("port %i (%s): no key \"%s\" specified\n",
port_i, p->name,key);
port_i, ps->name,key);
maxFibers=-1;
} else
if (sscanf(retValue, "%i", &maxFibers) != 1) {
......@@ -171,41 +176,39 @@ static int hal_port_init(int index)
maxFibers=-1;
}
if (p->fiber_index > maxFibers) {
if (ps->fiber_index > maxFibers) {
pr_error("port %i (%s): "
"not supported fiber value (%d), default to 0\n",
port_i, p->name,p->fiber_index);
p->fiber_index = 0;
port_i, ps->name,ps->fiber_index);
ps->fiber_index = 0;
}
/* Enable port monitoring by default */
p->monitor = HAL_PORT_MONITOR_ENABLE;
ps->monitor = HAL_PORT_MONITOR_ENABLE;
sprintf(key,"PORT%02i_INST%02i_MONITOR",port_i,1);
if ((retValue = libwr_cfg_get(key)) == NULL ) {
pr_error("port %i (%s): no key \"%s\" specified. Default to"
" monitor=y.\n",
port_i, p->name,key);
port_i, ps->name,key);
} else {
if (!strcasecmp(retValue, "n")) {
p->monitor = HAL_PORT_MONITOR_DISABLE;
ps->monitor = HAL_PORT_MONITOR_DISABLE;
pr_info("port %i (%s): monitor=n (%i)\n", port_i,
p->name, p->monitor);
ps->name, ps->monitor);
} else if (!strcasecmp(retValue, "y")) {
p->monitor = HAL_PORT_MONITOR_ENABLE;
ps->monitor = HAL_PORT_MONITOR_ENABLE;
pr_info("port %i (%s): monitor=y (%i)\n", port_i,
p->name, p->monitor);
ps->name, ps->monitor);
} else {
/* error */
pr_error("port %i (%s): not supported \"monitor\" "
"value, default to y\n",
port_i, p->name);
port_i, ps->name);
}
}
/* Used to pre-calibrate the TX path for each port. No more in V3 */
/* FIXME: this address should come from the driver header */
p->ep_base = 0x30000 + 0x400 * p->hw_index;
ps->ep_base = 0x30000 + 0x400 * ps->hw_index;
return 0;
}
......@@ -219,15 +222,11 @@ int hal_port_init_shmem(char *logfilename)
pr_info("Initializing switch ports...\n");
/* default timeouts */
libwr_tmo_init(&hal_port_tmo_sfp, UPDATE_SFP_PERIOD, 1);
libwr_tmo_init(&hal_port_tmo_rts, UPDATE_RTS_PERIOD, 1);
libwr_tmo_init(&update_sync_leds_tmo, UPDATE_SYNC_LEDS_PERIOD, 1);
libwr_tmo_init(&update_link_leds_tmo, UPDATE_LINK_LEDS_PERIOD, 1);
libwr_tmo_init(&update_sfp_dom_tmo, UPDATE_SFP_DOM_PERIOD, 1);
timerInit(_timerParameters,PORT_TIMER_COUNT);
/* Open a single raw socket for accessing the MAC addresses, etc. */
hal_port_fd = socket(AF_PACKET, SOCK_DGRAM, 0);
if (hal_port_fd < 0) {
halPorts.hal_port_fd = socket(AF_PACKET, SOCK_DGRAM, 0);
if (halPorts.hal_port_fd < 0) {
pr_error("Can't create socket: %s\n", strerror(errno));
return -1;
}
......@@ -240,27 +239,28 @@ int hal_port_init_shmem(char *logfilename)
return -1;
}
hal_shmem = wrs_shm_alloc(hal_shmem_hdr, sizeof(*hal_shmem));
ports = wrs_shm_alloc(hal_shmem_hdr,
halPorts.ports = wrs_shm_alloc(hal_shmem_hdr,
sizeof(struct hal_port_state)
* HAL_MAX_PORTS);
if (!hal_shmem || !ports) {
if (!hal_shmem || !halPorts.ports) {
pr_error("Can't allocate in shmem\n");
return -1;
}
hal_shmem->ports = ports;
hal_shmem->ports = halPorts.ports;
for (index = 0; index < HAL_MAX_PORTS; index++)
if (hal_port_init(index) < 0)
if (hal_port_init(&halPorts.ports[index],index) < 0)
break;
hal_port_nports = index;
hal_port_state_fsm_init(halPorts.ports); // Init fsm
led_init_all_ports(halPorts.ports); // Reset all leds
halPorts.numberOfPorts = index;
pr_info("Number of physical ports supported in HW: %d\n",
hal_port_nports);
halPorts.numberOfPorts );
/* We are done, mark things as valid */
hal_shmem->nports = hal_port_nports;
hal_shmem->nports = halPorts.numberOfPorts ;
hal_shmem->hal_mode = hal_get_timing_mode();
ret = libwr_cfg_get("READ_SFP_DIAG_ENABLE");
......@@ -283,34 +283,15 @@ int hal_port_init_shmem(char *logfilename)
int hal_port_init_wripc(char *logfilename)
{
/* Create a WRIPC server for HAL public API */
return hal_init_wripc(ports, logfilename);
return hal_init_wripc(halPorts.ports, logfilename);
}
/* Checks if the link is up on inteface (if_name). Returns non-zero if yes. */
static int hal_port_check_link(const char *if_name)
{
struct ifreq ifr;
strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
if (ioctl(hal_port_fd, SIOCGIFFLAGS, &ifr) > 0)
return -1;
return (ifr.ifr_flags & IFF_UP && ifr.ifr_flags & IFF_RUNNING);
}
/* Port locking state machine - controls the HPLL/DMPLL. TODO (v3):
get rid of this code - this will all be moved to the realtime CPU
inside the FPGA and the softpll. */
static void hal_port_locking_fsm(struct hal_port_state * p)
{
}
int hal_port_pshifter_busy()
{
struct rts_pll_state *hs = &hal_port_rts_state;
struct rts_pll_state *hs = getRtsStatePtr();
if (!hal_port_rts_state_valid)
if (! isRtsStateValid() )
return 1;
if (hs->current_ref != REF_NONE) {
......@@ -331,163 +312,16 @@ int hal_port_pshifter_busy()
* port. Called by the main update function regularly. */
int hal_port_poll_rts_state(void)
{
struct rts_pll_state *hs = &hal_port_rts_state;
struct rts_pll_state *hs = getRtsStatePtr();
hal_port_rts_state_valid = rts_get_state(hs) < 0 ? 0 : 1;
if (!hal_port_rts_state_valid)
setRtsStateValidity( rts_get_state(hs) < 0 ? 0 : 1);
if (! isRtsStateValid() )
printf("rts_get_state failure, weird...\n");
return hal_port_rts_state_valid;
}
static uint32_t pcs_readl(struct hal_port_state * p, int reg)
{
struct ifreq ifr;
uint32_t rv;
strncpy(ifr.ifr_name, p->name, sizeof(ifr.ifr_name));
rv = NIC_READ_PHY_CMD(reg);
ifr.ifr_data = (void *)&rv;
// printf("raw fd %d name %s\n", hal_port_fd, ifr.ifr_name);
if (ioctl(hal_port_fd, PRIV_IOCPHYREG, &ifr) < 0) {
pr_error("ioctl failed\n");
};
// printf("PCS_readl: reg %d data %x\n", reg, NIC_RESULT_DATA(rv));
return NIC_RESULT_DATA(rv);
}
static int hal_port_link_down(struct hal_port_state * p, int link_up)
{
/* If, at any moment, the link goes down, reset the FSM and
* the port state structure. */
if (!link_up && p->state != HAL_PORT_STATE_LINK_DOWN
&& p->state != HAL_PORT_STATE_DISABLED) {
if (p->locked) {
pr_info("Switching RTS to use local reference\n");
if (hal_get_timing_mode()
!= HAL_TIMING_MODE_GRAND_MASTER) {
shw_pps_set_timing_mode(HAL_TIMING_MODE_FREE_MASTER);
hal_update_timing_mode();
}
}
/* turn off synced LED */
set_led_synced(p->hw_index, 0);
/* turn off link/wrmode LEDs */
set_led_wrmode(p->hw_index, SFP_LED_WRMODE_OFF);
p->state = HAL_PORT_STATE_LINK_DOWN;
hal_port_reset_state(p);
rts_enable_ptracker(p->hw_index, 0);
pr_info("%s: link down\n", p->name);
return 1;
}
return 0;
return isRtsStateValid();
}
/* Main port state machine */
static void hal_port_fsm(struct hal_port_state * p)
{
struct rts_pll_state *hs = &hal_port_rts_state;
int link_up = hal_port_check_link(p->name);
if (hal_port_link_down(p, link_up))
return;
/* handle the locking part */
hal_port_locking_fsm(p);
switch (p->state) {
case HAL_PORT_STATE_DISABLED:
p->calib.tx_calibrated = 0;
p->calib.rx_calibrated = 0;
break;
/* Default state - wait until the link goes up */
case HAL_PORT_STATE_LINK_DOWN:
case HAL_PORT_STATE_RESET:
{
if (link_up) {
uint32_t bit_slide_steps;
p->calib.tx_calibrated = 1;
p->calib.rx_calibrated = 1;
/* FIXME: use proper register names */
bit_slide_steps=(pcs_readl(p, 16) >> 4) & 0x1f;
p->calib.bitslide_ps=bit_slide_steps*800; /* 1 step = 800ps */
pr_info("Bitslide: %d\n",bit_slide_steps);
p->calib.delta_rx_phy =
p->calib.phy_rx_min;
p->calib.delta_tx_phy = p->calib.phy_tx_min;
if (0)
pr_info(
"Bypassing calibration for "
"downlink port %s [dTx %d, dRx %d]\n",
p->name, p->calib.delta_tx_phy,
p->calib.delta_rx_phy);
p->tx_cal_pending = 0;
p->rx_cal_pending = 0;
/* Set link/wrmode LEDs to other. Master/slave
* color is set in the different place */
set_led_wrmode(p->hw_index,
SFP_LED_WRMODE_OTHER);
pr_info("%s: link up\n", p->name);
p->state = HAL_PORT_STATE_UP;
}
break;
}
/* Default "on" state - just keep polling the phase value. */
case HAL_PORT_STATE_UP:
if (hal_port_rts_state_valid) {
p->phase_val =
hs->channels[p->hw_index].phase_loopback;
p->phase_val_valid =
hs->channels[p->hw_index].
flags & CHAN_PMEAS_READY ? 1 : 0;
//hal_port_check_lock(p->name);
//p->locked =
}
break;
/* Locking state (entered on calling hal_port_start_lock()). */
case HAL_PORT_STATE_LOCKING:
/* Once the locking FSM is done, go back to the "UP" state. */
p->locked = hal_port_check_lock(p->name);
if (p->locked) {
pr_info("[main-fsm] Port %s locked.\n",
p->name);
p->state = HAL_PORT_STATE_UP;
}
break;
/* Calibration state (entered by starting the
* calibration with halexp_calibration_cmd()) */
case HAL_PORT_STATE_CALIBRATION:
/* Calibration still pending - if not anymore, go back
* to the "UP" state */
if (p->rx_cal_pending || p->tx_cal_pending) {
} //calibration_fsm(p);
else
p->state = HAL_PORT_STATE_UP;
break;
}
}
static void hal_port_insert_sfp(struct hal_port_state * p)
static void hal_port_insert_sfp(struct hal_port_state * ps)
{
struct shw_sfp_header shdr;
struct shw_sfp_caldata *cdata;
......@@ -495,72 +329,72 @@ static void hal_port_insert_sfp(struct hal_port_state * p)
int err;
memset(&shdr, 0, sizeof(struct shw_sfp_header));
memset(&p->calib.sfp_dom_raw, 0, sizeof(struct shw_sfp_dom));
err = shw_sfp_read_verify_header(p->hw_index, &shdr);
memcpy(&p->calib.sfp_header_raw, &shdr, sizeof(struct shw_sfp_header));
memset(&ps->calib.sfp_dom_raw, 0, sizeof(struct shw_sfp_dom));
err = shw_sfp_read_verify_header(ps->hw_index, &shdr);
memcpy(&ps->calib.sfp_header_raw, &shdr, sizeof(struct shw_sfp_header));
if (err == -2) {
pr_error("%s SFP module not inserted. Failed to read SFP "
"configuration header\n", p->name);
"configuration header\n", ps->name);
return;
} else if (err < 0) {
pr_error("Failed to read SFP configuration header for %s\n",
p->name);
ps->name);
return;
}
if (hal_shmem->read_sfp_diag == READ_SFP_DIAG_ENABLE
&& shdr.diagnostic_monitoring_type & SFP_DIAGNOSTIC_IMPLEMENTED) {
pr_info("SFP Diagnostic Monitoring implemented in SFP plugged"
" to port %d (%s)\n", p->hw_index + 1, p->name);
" to port %d (%s)\n", ps->hw_index + 1, ps->name);
if (shdr.diagnostic_monitoring_type & SFP_ADDR_CHANGE_REQ) {
pr_warning("SFP in port %d (%s) requires special "
"address change before accessing Diagnostic"
" Monitoring, which is not implemented "
"right now\n", p->hw_index + 1, p->name);
"right now\n", ps->hw_index + 1, ps->name);
} else {
/* copy coontent of SFP's Diagnostic Monitoring */
shw_sfp_read_dom(p->hw_index, &p->calib.sfp_dom_raw);
shw_sfp_read_dom(ps->hw_index, &ps->calib.sfp_dom_raw);
if (err < 0) {
pr_error("Failed to read SFP Diagnostic "
"Monitoring for port %d (%s)\n",
p->hw_index + 1, p->name);
ps->hw_index + 1, ps->name);
}
p->has_sfp_diag = 1;
ps->has_sfp_diag = 1;
}
}
pr_info("SFP Info: Manufacturer: %.16s P/N: %.16s, S/N: %.16s\n",
shdr.vendor_name, shdr.vendor_pn, shdr.vendor_serial);
cdata = shw_sfp_get_cal_data(p->hw_index, &shdr);
cdata = shw_sfp_get_cal_data(ps->hw_index, &shdr);
if (cdata) {
/* Alpha is not known now. It is read later from the fibers'
* database. */
pr_info("%s SFP Info: (%s) delta Tx %d, delta Rx %d, "
"TX wl: %dnm, RX wl: %dnm\n", p->name,
"TX wl: %dnm, RX wl: %dnm\n", ps->name,
cdata->flags & SFP_FLAG_CLASS_DATA
? "class-specific" : "device-specific",
cdata->delta_tx_ps, cdata->delta_rx_ps, cdata->tx_wl,
cdata->rx_wl);
memcpy(&p->calib.sfp, cdata,
memcpy(&ps->calib.sfp, cdata,
sizeof(struct shw_sfp_caldata));
/* Mark SFP as found in data base */
p->calib.sfp.flags |= SFP_FLAG_IN_DB;
ps->calib.sfp.flags |= SFP_FLAG_IN_DB;
} else {
pr_error("Unknown SFP vn=\"%.16s\" pn=\"%.16s\" "
"vs=\"%.16s\" on port %s\n", shdr.vendor_name,
shdr.vendor_pn, shdr.vendor_serial, p->name);
memset(&p->calib.sfp, 0, sizeof(p->calib.sfp));
shdr.vendor_pn, shdr.vendor_serial, ps->name);
memset(&ps->calib.sfp, 0, sizeof(ps->calib.sfp));
}
p->state = HAL_PORT_STATE_LINK_DOWN;
shw_sfp_set_tx_disable(p->hw_index, 0);
ps->calib.sfpPresent=1;
shw_sfp_set_tx_disable(ps->hw_index, 0);
/* Copy the strings anyways, for informative value in shmem */
strncpy(p->calib.sfp.vendor_name, (void *)shdr.vendor_name, 16);
strncpy(p->calib.sfp.part_num, (void *)shdr.vendor_pn, 16);
strncpy(p->calib.sfp.vendor_serial, (void *)shdr.vendor_serial, 16);
strncpy(ps->calib.sfp.vendor_name, (void *)shdr.vendor_name, 16);
strncpy(ps->calib.sfp.part_num, (void *)shdr.vendor_pn, 16);
strncpy(ps->calib.sfp.vendor_serial, (void *)shdr.vendor_serial, 16);
/* check if SFP is 1GbE */
p->calib.sfp.flags |= shdr.br_nom == SFP_SPEED_1Gb ? SFP_FLAG_1GbE : 0;
p->calib.sfp.flags |= shdr.br_nom == SFP_SPEED_1Gb_10 ? SFP_FLAG_1GbE : 0;
ps->calib.sfp.flags |= shdr.br_nom == SFP_SPEED_1Gb ? SFP_FLAG_1GbE : 0;
ps->calib.sfp.flags |= shdr.br_nom == SFP_SPEED_1Gb_10 ? SFP_FLAG_1GbE : 0;
/*
* Now, we should fix the alpha value according to fiber
......@@ -568,166 +402,186 @@ static void hal_port_insert_sfp(struct hal_port_state * p)
* speed ratio of the SFP frequencies over the specific
* fiber. Thus, rely on the fiber type for this port.
*/
sprintf(subname, "alpha_%i_%i", p->calib.sfp.tx_wl, p->calib.sfp.rx_wl);
sprintf(subname, "alpha_%i_%i", ps->calib.sfp.tx_wl, ps->calib.sfp.rx_wl);
err = libwr_cfg_convert2("FIBER%02i_PARAMS", subname,
LIBWR_DOUBLE, &p->calib.sfp.alpha,
p->fiber_index);
LIBWR_DOUBLE, &ps->calib.sfp.alpha,
ps->fiber_index);
if (!err) {
/* Now we know alpha, so print it. */
pr_info("%s SFP Info: alpha %.3f (* 1e6) found for TX wl: %dnm,"
" RX wl: %dmn\n", p->name, p->calib.sfp.alpha * 1e6,
p->calib.sfp.tx_wl, p->calib.sfp.rx_wl);
" RX wl: %dmn\n", ps->name, ps->calib.sfp.alpha * 1e6,
ps->calib.sfp.tx_wl, ps->calib.sfp.rx_wl);
return;
}
/* Try again, with the opposite direction (rx/tx) */
sprintf(subname, "alpha_%i_%i", p->calib.sfp.rx_wl, p->calib.sfp.tx_wl);
sprintf(subname, "alpha_%i_%i", ps->calib.sfp.rx_wl, ps->calib.sfp.tx_wl);
err = libwr_cfg_convert2("FIBER%02i_PARAMS", subname,
LIBWR_DOUBLE, &p->calib.sfp.alpha,
p->fiber_index);
LIBWR_DOUBLE, &ps->calib.sfp.alpha,
ps->fiber_index);
if (!err) {
p->calib.sfp.alpha = (1.0 / (1.0 + p->calib.sfp.alpha)) - 1.0;
ps->calib.sfp.alpha = (1.0 / (1.0 + ps->calib.sfp.alpha)) - 1.0;
/* Now we know alpha, so print it. */
pr_info("%s SFP Info: alpha %.3f (* 1e6) found for TX wl: %dnm,"
" RX wl: %dmn\n", p->name, p->calib.sfp.alpha * 1e6,
p->calib.sfp.tx_wl, p->calib.sfp.rx_wl);
" RX wl: %dmn\n", ps->name, ps->calib.sfp.alpha * 1e6,
ps->calib.sfp.tx_wl, ps->calib.sfp.rx_wl);
return;
}
pr_error("Port %s, SFP vn=\"%.16s\" pn=\"%.16s\" vs=\"%.16s\", "
"fiber %i: no alpha known\n", p->name,
p->calib.sfp.vendor_name, p->calib.sfp.part_num,
p->calib.sfp.vendor_serial, p->fiber_index);
p->calib.sfp.alpha = 0;
"fiber %i: no alpha known\n", ps->name,
ps->calib.sfp.vendor_name, ps->calib.sfp.part_num,
ps->calib.sfp.vendor_serial, ps->fiber_index);
ps->calib.sfp.alpha = 0;
}
static void hal_port_remove_sfp(struct hal_port_state * p)
static void hal_port_remove_sfp(struct hal_port_state * ps)
{
hal_port_link_down(p, 0);
p->state = HAL_PORT_STATE_DISABLED;
// hal_port_link_down(p, 0);
/* clean SFP's details when removing SFP */
memset(&p->calib.sfp, 0, sizeof(p->calib.sfp));
memset(&p->calib.sfp_header_raw, 0, sizeof(struct shw_sfp_header));
memset(&p->calib.sfp_dom_raw, 0, sizeof(struct shw_sfp_dom));
p->has_sfp_diag = 0;
memset(&ps->calib.sfp, 0, sizeof(ps->calib.sfp));
memset(&ps->calib.sfp_header_raw, 0, sizeof(struct shw_sfp_header));
memset(&ps->calib.sfp_dom_raw, 0, sizeof(struct shw_sfp_dom));
ps->has_sfp_diag=ps->calib.sfpPresent=0;
}
/* detects insertion/removal of SFP transceivers */
static void hal_port_poll_sfp(void)
{
uint32_t mask = shw_sfp_module_scan();
static int old_mask = 0;
if (mask != old_mask) {
int i, hw_index;
for (i = 0; i < HAL_MAX_PORTS; i++) {
hw_index = ports[i].hw_index;
if (ports[i].in_use
&& (mask ^ old_mask) & (1 << hw_index)) {
int insert = mask & (1 << hw_index);
pr_info("SFP Info: Detected SFP %s "
"on port %s.\n",
insert ? "insertion" : "removal",
ports[i].name);
if (insert)
hal_port_insert_sfp(&ports[i]);
else
hal_port_remove_sfp(&ports[i]);
}
static int __old_mask = 0;
uint32_t mask = shw_sfp_module_scan();
if (mask != __old_mask) {
int i, hw_index;
/* lock shmem */
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_BEGIN);
for (i = 0; i < HAL_MAX_PORTS; i++) {
hw_index = halPorts.ports[i].hw_index;
if (halPorts.ports[i].in_use
&& (mask ^ __old_mask) & (1 << hw_index)) {
int insert = mask & (1 << hw_index);
pr_info("SFP Info: Detected SFP %s "
"on port %s.\n",
insert ? "insertion" : "removal",
halPorts.ports[i].name);
if (insert)
hal_port_insert_sfp(&halPorts.ports[i]);
else
hal_port_remove_sfp(&halPorts.ports[i]);
}
}
old_mask = mask;
}
/* Executes the port FSM for all ports. Called regularly by the main loop. */
void hal_port_update_all()
{
int i;
struct shw_sfp_dom sfp_dom_raw[HAL_MAX_PORTS];
/* unlock shmem */
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_END);
__old_mask = mask;
}
}
static void _cb_port_poll_rts_state(int timerId){
/* poll_rts_state does not write to shmem */
if (libwr_tmo_expired(&hal_port_tmo_rts))
hal_port_poll_rts_state();
/* lock shmem */
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_BEGIN);
if (libwr_tmo_expired(&hal_port_tmo_sfp))
hal_port_poll_sfp();
hal_port_poll_rts_state();
}
for (i = 0; i < HAL_MAX_PORTS; i++)
if (ports[i].in_use) {
hal_port_fsm(&ports[i]);
}
static void _cb_port_poll_sfp(int timerId){
hal_port_poll_sfp();
}
/* unlock shmem */
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_END);
static void _cb_port_poll_sfp_dom(int timerId){
if (hal_shmem->read_sfp_diag == READ_SFP_DIAG_ENABLE) {
struct shw_sfp_dom sfp_dom_raw[HAL_MAX_PORTS];
struct hal_port_state *ps;
int i;
if (hal_shmem->read_sfp_diag == READ_SFP_DIAG_ENABLE
&& libwr_tmo_expired(&update_sfp_dom_tmo)) {
/* get the DOM data to local memory */
ps=halPorts.ports;
for (i = 0; i < HAL_MAX_PORTS; i++) {
/* read DOM only for plugged ports with DOM
* capabilities */
if (ports[i].in_use
&& ports[i].state != HAL_PORT_STATE_DISABLED
&& (ports[i].has_sfp_diag)) {
shw_sfp_update_dom(ports[i].hw_index,
if (ps->in_use
&& ps->calib.sfpPresent
&& ps->has_sfp_diag) {
shw_sfp_update_dom(ps->hw_index,
&sfp_dom_raw[i]);
}
ps++;
}
/* lock shmem */
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_BEGIN);
/* copy the DOM from local memory to shmem */
ps=halPorts.ports;
for (i = 0; i < HAL_MAX_PORTS; i++) {
/* update DOM only for plugged ports with DOM
* capabilities */
if (ports[i].in_use
&& ports[i].state != HAL_PORT_STATE_DISABLED
&& (ports[i].has_sfp_diag)) {
memcpy(&ports[i].calib.sfp_dom_raw,
if (ps->in_use
&& ps->calib.sfpPresent
&& ps->has_sfp_diag) {
memcpy(&halPorts.ports[i].calib.sfp_dom_raw,
&sfp_dom_raw[i],
sizeof(struct shw_sfp_dom));
}
ps++;
}
/* unlock shmem */
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_END);
}
}
static void _cb_port_update_sync_leds(int timerId){
/* update LEDs of synced ports */
led_sync_update(halPorts.ports);
}
if (libwr_tmo_expired(&update_link_leds_tmo)) {
/* update color of the link LEDs */
update_link_leds();
}
static void _cb_port_update_link_leds(int timerId){
/* update color of the link LEDs */
led_link_update(halPorts.ports);
}
if (libwr_tmo_expired(&update_sync_leds_tmo)) {
/* update LEDs of synced ports */
update_sync_leds();
}
/* Executes the port FSM for all ports. Called regularly by the main loop. */
void hal_port_update_all()
{
timerScan(_timerParameters,PORT_TIMER_COUNT);
/* lock shmem */
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_BEGIN);
hal_port_state_fsm(halPorts.ports);
/* unlock shmem */
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_END);
}
int hal_port_enable_tracking(const char *port_name)
{
const struct hal_port_state *p = hal_lookup_port(ports,
hal_port_nports, port_name);
const struct hal_port_state *ps = hal_lookup_port(halPorts.ports,
halPorts.numberOfPorts, port_name);
if (!p)
if (!ps)
return -1;
return rts_enable_ptracker(p->hw_index, 1); /* 0 or -1 already */
return rts_enable_ptracker(ps->hw_index, 1); /* 0 or -1 already */
}
/* Triggers the locking state machine, called by the PTPd during the
* WR link setup phase. */
int hal_port_start_lock(const char *port_name, int priority)
{
struct hal_port_state *p = hal_lookup_port(ports, hal_port_nports,
port_name);
struct hal_port_state *ps = hal_lookup_port(halPorts.ports, halPorts.numberOfPorts, port_name);
if ( !ps )
return -1; /* unknown port */
ps->evt_lock=1;
return 0;
#if 0
int ret=-1;
if (!p && p->state != HAL_PORT_STATE_UP )
return -1; /* can't lock to a disconnected port */
......@@ -743,20 +597,20 @@ int hal_port_start_lock(const char *port_name, int priority)
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_END);
}
return ret;
#endif
}
/* Returns 1 if the port is locked */
int hal_port_check_lock(const char *port_name)
{
const struct hal_port_state *p = hal_lookup_port(ports,
hal_port_nports, port_name);
struct rts_pll_state *hs = &hal_port_rts_state;
const struct hal_port_state *p = hal_lookup_port(halPorts.ports,
halPorts.numberOfPorts, port_name);
struct rts_pll_state *hs = getRtsStatePtr();
if (!p)
return 0; /* was -1, but it would confuse the caller */
if (!hal_port_rts_state_valid)
if (! isRtsStateValid() )
return 0;
if (hs->delock_count > 0)
......@@ -770,20 +624,23 @@ int hal_port_check_lock(const char *port_name)
int hal_port_reset(const char *port_name)
{
struct hal_port_state *p = hal_lookup_port(ports,
hal_port_nports, port_name);
struct hal_port_state *ps = hal_lookup_port(halPorts.ports,
halPorts.numberOfPorts, port_name);
if (!p)
if (!ps)
return -1;
ps->evt_reset=1;
return 0;
#if 0
if (p->state != HAL_PORT_STATE_LINK_DOWN
&& p->state != HAL_PORT_STATE_DISABLED) {
/* turn off synced LED */
set_led_synced(p->hw_index, 0);
led_set_sync(p->hw_index, 0);
/* turn off link/wrmode LEDs */
set_led_wrmode(p->hw_index, SFP_LED_WRMODE_OFF);
led_set_wrmode(p->hw_index, SFP_LED_WRMODE_OFF);
hal_port_reset_state(p);
p->state = HAL_PORT_STATE_RESET;
......@@ -792,115 +649,15 @@ int hal_port_reset(const char *port_name)
return 1;
}
return 0;
}
/* to avoid i2c transfers to set the link LEDs, cache their state */
static void set_led_wrmode(int p_index, int val)
{
/* We assume that after the HAL is started all LEDs are off */
static int leds_map[HAL_MAX_PORTS];
if (p_index >= HAL_MAX_PORTS)
return;
if (leds_map[p_index] == val) {
/* value has not changed */
return;
}
/* update the LED, don't forget to turn off LEDs if needed */
if (val == SFP_LED_WRMODE_SLAVE) {
/* cannot set and clear LED in the same call! */
shw_sfp_set_generic(p_index, 1, SFP_LED_WRMODE1);
shw_sfp_set_generic(p_index, 0, SFP_LED_WRMODE2);
} else if (val == SFP_LED_WRMODE_OTHER) {
/* cannot set and clear LED in the same call! */
shw_sfp_set_generic(p_index, 0, SFP_LED_WRMODE1);
shw_sfp_set_generic(p_index, 1, SFP_LED_WRMODE2);
} else if (val == SFP_LED_WRMODE_MASTER) {
shw_sfp_set_generic(p_index, 1,
SFP_LED_WRMODE1 | SFP_LED_WRMODE2);
} else if (val == SFP_LED_WRMODE_OFF) {
shw_sfp_set_generic(p_index, 0,
SFP_LED_WRMODE1 | SFP_LED_WRMODE2);
}
leds_map[p_index] = val;
}
static void update_link_leds(void) {
int i;
struct hal_port_state *port = &ports[0];
for (i = 0; i < HAL_MAX_PORTS; i++) {
if (port->in_use && state_up(port->state)) {
if (port->portMode == PORT_MODE_SLAVE)
set_led_wrmode(i, SFP_LED_WRMODE_SLAVE);
else if (port->portMode == PORT_MODE_MASTER)
set_led_wrmode(i, SFP_LED_WRMODE_MASTER);
else
set_led_wrmode(i, SFP_LED_WRMODE_OTHER);
}
port++;
}
}
/* to avoid i2c transfers to set the synced LEDs, cache their state */
static void set_led_synced(int p_index, int val)
{
/* We assume that after the HAL is started all LEDs are off */
static int leds_map[HAL_MAX_PORTS];
if (p_index >= HAL_MAX_PORTS)
return;
if (leds_map[p_index] == val) {
/* value has not changed */
return;
}
/* update the LED */
shw_sfp_set_led_synced(p_index, val);
leds_map[p_index] = val;
}
static void update_sync_leds(void)
{
int i;
struct hal_port_state *port=&ports[0];
for (i = 0; i < HAL_MAX_PORTS; i++) {
/* Check:
* --port in use
* --link is up
*/
if ( port->in_use
&& state_up(port->state) ) {
int ledValue;
/* Check:
* --ppsi instance in slave state
* --servo is locked
* --WR of HA PTP servo
* --servo is updating
*/
ledValue= port->synchronized
&& (port->portInfoUpdated--) > -10
? 1 : 0;
set_led_synced(i, ledValue);
}
port++;
}
return 0;
#endif
}
void hal_update_port_info(char *iface_name, int mode, int synchronized){
int i;
struct hal_port_state *port=&ports[0];
struct hal_port_state *ps=halPorts.ports;
if ( iface_name==NULL ) {
pr_error("%s: Invalid iface_name parameter (NULL).\n",__func__);
......@@ -909,16 +666,15 @@ void hal_update_port_info(char *iface_name, int mode, int synchronized){
for (i = 0; i < HAL_MAX_PORTS; i++) {
if (port->in_use &&
state_up(port->state) &&
!strcmp(iface_name,port->name) ) {
if (ps->in_use &&
!strcmp(iface_name,ps->name) ) {
port->portMode=mode;
port->synchronized=synchronized;
port->portInfoUpdated=1;
ps->portMode=mode;
ps->synchronized=synchronized;
ps->portInfoUpdated=1;
break;
}
port++;
ps++;
}
}
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Jean-Claude BAU - CERN
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*
*
*/
#ifndef HAL_PORTS_H
#define HAL_PORTS_H
#include <rt_ipc.h>
typedef struct {
struct hal_port_state *ports;
int numberOfPorts;
int hal_port_fd; /* An fd of always opened raw sockets for ioctl()-ing Ethernet devices */
/* RT subsystem PLL state, polled regularly via mini-ipc */
struct rts_pll_state rts_state;
int rts_state_valid;
}hal_ports_t;
#define isRtsStateValid() halPorts.rts_state_valid
#define setRtsStateValidity(value) halPorts.rts_state_valid=(value)
#define getRtsState() (halPorts.rts_state)
#define getRtsStatePtr() (&getRtsState())
extern hal_ports_t halPorts;
extern int hal_port_poll_rts_state(void);
extern int hal_port_poll_rts_state(void);
extern int hal_get_timing_mode(void);
extern int rts_lock_channel(int channel, int priority);
#endif
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Jean-Claude BAU - CERN
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*
*/
#include "hal_timer.h"
void timerInit(timer_parameter_t *p,int nbTimers) {
int index;
for ( index=0; index < nbTimers; index++ ) {
libwr_tmo_init(&p->timer,p->tmoMs, p->repeat);
p++;
}
}
void timerScan(timer_parameter_t *p,int nbTimers) {
int index;
for ( index=0; index < nbTimers; index++ ) {
if (libwr_tmo_expired(&p->timer) && p->cb!=NULL) {
(*p->cb)(p->id);
}
p++;
}
}
/*
* Copyright (C) 2019 CERN (www.cern.ch)
* Author: Jean-Claude BAU - CERN
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*
*/
#ifndef HAL_TIMER_H
#define HAL_TIMER_H
#include <libwr/timeout.h>
typedef struct {
int id;
uint32_t tmoMs; // Time out value in ms
int repeat; // restart timeout automatically
timeout_t timer;
void (*cb)(int timerId);
}timer_parameter_t;
extern void timerInit(timer_parameter_t *p,int nbTimers);
extern void timerScan(timer_parameter_t *p,int nbTimers);
#endif
......@@ -11,12 +11,10 @@
#include <libwr/wrs-msg.h>
#include <libwr/timeout.h>
#include "wrsw_hal.h"
#include <rt_ipc.h>
#include <hal_exports.h>
#include "wrsw_hal.h"
#include "hal_ports.h"
extern struct rts_pll_state hal_port_rts_state;
extern int hal_port_rts_state_valid;
int hal_init_timing_mode(void)
{
......@@ -35,9 +33,9 @@ int hal_init_timing(char *filename)
int hal_get_timing_mode(void)
{
struct rts_pll_state *hs = &hal_port_rts_state;
struct rts_pll_state *hs = getRtsStatePtr();
if (hal_port_rts_state_valid)
if (isRtsStateValid())
switch (hs->mode) {
case RTS_MODE_GM_EXTERNAL:
return HAL_TIMING_MODE_GRAND_MASTER;
......@@ -51,8 +49,10 @@ int hal_get_timing_mode(void)
return -1;
}
int hal_update_timing_mode(void) {
return hal_port_poll_rts_state();
int hal_set_timing_mode(uint32_t tm) {
int ret=shw_pps_set_timing_mode(tm);
hal_port_poll_rts_state();
return ret;
}
......@@ -38,7 +38,7 @@ int hal_port_poll_rts_state(void);
int hal_init_timing_mode(void);
int hal_init_timing(char *filename);
int hal_get_timing_mode(void);
int hal_update_timing_mode(void);
int hal_set_timing_mode(uint32_t tm);
int hal_port_pshifter_busy(void);
#endif
<html>
<body>
<table border="0" cellspacing="0" cellpadding="0" align="LEFT">
<tr>
<td><img src="file:///opt/baujc/project/wr/wrs-proposed-master/wr-switch-sw-hal-review/userspace/wrsw_hal/yakindu/hal_0_0.png"/></td>
</tr>
</table>
</body>
</html>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:sgraph="http://www.yakindu.org/sct/sgraph/2.0.0">
<sgraph:Statechart xmi:id="_ufBzMLdfEemzI5ZuGbnP4A" specification="@EventDriven&#xA;// Use the event driven execution model.&#xA;// Runs a run-to-completion step&#xA;// each time an event is raised.&#xA;// Switch to cycle based behavior&#xA;// by specifying '@CycleBased(200)'&#xA;// instead.&#xA;&#xA;@ChildFirstExecution&#xA;// In composite states, execute&#xA;// child states first.&#xA;// @ParentFirstExecution does the opposite.&#xA;&#xA;&#xA;&#xA;interface port:&#xA;in event sfpInserted&#xA;in event sfpRemoved&#xA;in event linkUp&#xA;in event linkDown&#xA;in event timer&#xA;in event reset&#xA;var lpdcSupport : boolean = false&#xA;var rxCalibrationRunning: boolean = false&#xA;var calibrationDone:boolean&#xA;&#xA;interface pll:&#xA;&#x9;in event lock&#xA;&#x9;in event locked&#xA;&#x9;in event unlocked&#xA;&#x9;in event disable&#xA;&#xA;" name="hal">
<regions xmi:id="_ufftQLdfEemzI5ZuGbnP4A" name="main region">
<vertices xsi:type="sgraph:Entry" xmi:id="_uf588LdfEemzI5ZuGbnP4A">
<outgoingTransitions xmi:id="_ugB4wLdfEemzI5ZuGbnP4A" specification="" target="_uf8ZMLdfEemzI5ZuGbnP4A"/>
</vertices>
<vertices xsi:type="sgraph:State" xmi:id="_uf8ZMLdfEemzI5ZuGbnP4A" specification="entry / port.lpcSupport=false&#xA;&#xA;" name="HAL_PORT_STATE_INIT" incomingTransitions="_ugB4wLdfEemzI5ZuGbnP4A">
<regions xmi:id="_gj7iwLeKEemUVuDCbi9APQ" name="TX_SETUP">
<vertices xsi:type="sgraph:Entry" xmi:id="_sPl4oLeKEemUVuDCbi9APQ">
<outgoingTransitions xmi:id="_TqqU0LeLEemUVuDCbi9APQ" specification="" target="_tLh8cLeKEemUVuDCbi9APQ"/>
</vertices>
<vertices xsi:type="sgraph:State" xmi:id="_tLh8cLeKEemUVuDCbi9APQ" name="START" incomingTransitions="_TqqU0LeLEemUVuDCbi9APQ">
<outgoingTransitions xmi:id="_glqLoLeLEemUVuDCbi9APQ" specification="port.timer" target="_9Ue9ALeKEemUVuDCbi9APQ"/>
</vertices>
<vertices xsi:type="sgraph:State" xmi:id="_9Ue9ALeKEemUVuDCbi9APQ" specification="" name="DONE" incomingTransitions="_glqLoLeLEemUVuDCbi9APQ">
<outgoingTransitions xmi:id="_8monELdfEemzI5ZuGbnP4A" specification="port.timer" target="_4vYosLdfEemzI5ZuGbnP4A"/>
</vertices>
</regions>
</vertices>
<vertices xsi:type="sgraph:State" xmi:id="_4vYosLdfEemzI5ZuGbnP4A" name="HAL_PORT_STATE_DISABLED" incomingTransitions="_8monELdfEemzI5ZuGbnP4A _ChpIwLdnEemzI5ZuGbnP4A _GEngQLdnEemzI5ZuGbnP4A">
<outgoingTransitions xmi:id="_5j_jMLdkEemzI5ZuGbnP4A" specification="port.sfpInserted" target="_42BKcLeGEemyoZNNAM3ZMg"/>
</vertices>
<vertices xsi:type="sgraph:State" xmi:id="_aAs4YLdgEemzI5ZuGbnP4A" name="HAL_PORT_STATE_LINK_UP" incomingTransitions="_Uu-jcLeJEemUVuDCbi9APQ">
<outgoingTransitions xmi:id="_ChpIwLdnEemzI5ZuGbnP4A" specification="port.sfpRemoved" target="_4vYosLdfEemzI5ZuGbnP4A"/>
<outgoingTransitions xmi:id="_2gW5cLdsEemzI5ZuGbnP4A" specification="port.linkDown" target="_42BKcLeGEemyoZNNAM3ZMg"/>
<outgoingTransitions xmi:id="_Xrd6sLjyEemqMMLZEdLlPw" specification="port.reset" target="_42BKcLeGEemyoZNNAM3ZMg"/>
<regions xmi:id="_sitwMLkPEemqMMLZEdLlPw" name="PLL">
<vertices xsi:type="sgraph:State" xmi:id="_w_EmwLkPEemqMMLZEdLlPw" name="UNLOCKED" incomingTransitions="_zNXqULkPEemqMMLZEdLlPw _py7TsLkQEemqMMLZEdLlPw _sd8vgLkQEemqMMLZEdLlPw _lL8iUL3CEem_KcfQeEtgCA">
<outgoingTransitions xmi:id="_HnT-8LkQEemqMMLZEdLlPw" specification="pll.lock" target="_-j_kULkPEemqMMLZEdLlPw"/>
</vertices>
<vertices xsi:type="sgraph:Entry" xmi:id="_yXKbELkPEemqMMLZEdLlPw">
<outgoingTransitions xmi:id="_zNXqULkPEemqMMLZEdLlPw" specification="" target="_w_EmwLkPEemqMMLZEdLlPw"/>
</vertices>
<vertices xsi:type="sgraph:State" xmi:id="_-j_kULkPEemqMMLZEdLlPw" name="LOCKING" incomingTransitions="_HnT-8LkQEemqMMLZEdLlPw">
<outgoingTransitions xmi:id="_JnV9ALkQEemqMMLZEdLlPw" specification="pll.locked" target="_BhtSoLkQEemqMMLZEdLlPw"/>
<outgoingTransitions xmi:id="_sd8vgLkQEemqMMLZEdLlPw" specification="pll.disable" target="_w_EmwLkPEemqMMLZEdLlPw"/>
</vertices>
<vertices xsi:type="sgraph:State" xmi:id="_BhtSoLkQEemqMMLZEdLlPw" specification="" name="LOCKED" incomingTransitions="_JnV9ALkQEemqMMLZEdLlPw">
<outgoingTransitions xmi:id="_py7TsLkQEemqMMLZEdLlPw" specification="pll.unlocked" target="_w_EmwLkPEemqMMLZEdLlPw"/>
<outgoingTransitions xmi:id="_lL8iUL3CEem_KcfQeEtgCA" specification="pll.disable" target="_w_EmwLkPEemqMMLZEdLlPw"/>
</vertices>
</regions>
</vertices>
<vertices xsi:type="sgraph:State" xmi:id="_42BKcLeGEemyoZNNAM3ZMg" name="HAL_PORT_STATE_LINK_DOWN" incomingTransitions="_5j_jMLdkEemzI5ZuGbnP4A _2gW5cLdsEemzI5ZuGbnP4A _Xrd6sLjyEemqMMLZEdLlPw">
<outgoingTransitions xmi:id="_GEngQLdnEemzI5ZuGbnP4A" specification="port.sfpRemoved" target="_4vYosLdfEemzI5ZuGbnP4A"/>
<regions xmi:id="_42BxgLeGEemyoZNNAM3ZMg" name="RX_SETUP">
<vertices xsi:type="sgraph:Entry" xmi:id="_H57OgLeHEemyoZNNAM3ZMg">
<outgoingTransitions xmi:id="_GS6X8LeIEemyoZNNAM3ZMg" specification="&#xA;" target="_dI8J8LeHEemyoZNNAM3ZMg"/>
</vertices>
<vertices xsi:type="sgraph:State" xmi:id="_dI8J8LeHEemyoZNNAM3ZMg" name="START" incomingTransitions="_GS6X8LeIEemyoZNNAM3ZMg _97OqEL3DEem_KcfQeEtgCA">
<outgoingTransitions xmi:id="_FOusMLeKEemUVuDCbi9APQ" specification="port.timer[port.lpdcSupport==false]&#xA;" target="_x4lNAL3CEem_KcfQeEtgCA"/>
<outgoingTransitions xmi:id="_le6FIL3DEem_KcfQeEtgCA" specification="port.timer[port.lpdcSupport==true]" target="_Jj95ALeIEemyoZNNAM3ZMg"/>
</vertices>
<vertices xsi:type="sgraph:State" xmi:id="_Jj95ALeIEemyoZNNAM3ZMg" specification="" name="DONE" incomingTransitions="_le6FIL3DEem_KcfQeEtgCA _mY_HwL3DEem_KcfQeEtgCA">
<outgoingTransitions xmi:id="_Uu-jcLeJEemUVuDCbi9APQ" specification="port.linkUp" target="_aAs4YLdgEemzI5ZuGbnP4A"/>
</vertices>
<vertices xsi:type="sgraph:State" xmi:id="_x4lNAL3CEem_KcfQeEtgCA" name="CALIB_NO_SPDC" incomingTransitions="_FOusMLeKEemUVuDCbi9APQ">
<outgoingTransitions xmi:id="_mY_HwL3DEem_KcfQeEtgCA" specification="port.linkUp[port.calibrationDone==true]" target="_Jj95ALeIEemyoZNNAM3ZMg"/>
<outgoingTransitions xmi:id="_97OqEL3DEem_KcfQeEtgCA" specification="port.linkDown" target="_dI8J8LeHEemyoZNNAM3ZMg"/>
</vertices>
</regions>
</vertices>
</regions>
</sgraph:Statechart>
<notation:Diagram xmi:id="_uffGMLdfEemzI5ZuGbnP4A" type="org.yakindu.sct.ui.editor.editor.StatechartDiagramEditor" element="_ufBzMLdfEemzI5ZuGbnP4A" measurementUnit="Pixel">
<children xmi:id="_uflM0LdfEemzI5ZuGbnP4A" type="Region" element="_ufftQLdfEemzI5ZuGbnP4A">
<children xsi:type="notation:DecorationNode" xmi:id="_uf25oLdfEemzI5ZuGbnP4A" type="RegionName">
<styles xsi:type="notation:ShapeStyle" xmi:id="_uf25obdfEemzI5ZuGbnP4A"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_uf25ordfEemzI5ZuGbnP4A"/>
</children>
<children xsi:type="notation:Shape" xmi:id="_uf4u0LdfEemzI5ZuGbnP4A" type="RegionCompartment" fontName="Verdana" lineColor="4210752">
<children xmi:id="_uf6kALdfEemzI5ZuGbnP4A" type="Entry" element="_uf588LdfEemzI5ZuGbnP4A">
<children xmi:id="_uf7LELdfEemzI5ZuGbnP4A" type="BorderItemLabelContainer">
<children xsi:type="notation:DecorationNode" xmi:id="_uf7LE7dfEemzI5ZuGbnP4A" type="BorderItemLabel">
<styles xsi:type="notation:ShapeStyle" xmi:id="_uf7LFLdfEemzI5ZuGbnP4A"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_uf7LFbdfEemzI5ZuGbnP4A"/>
</children>
<styles xsi:type="notation:ShapeStyle" xmi:id="_uf7LEbdfEemzI5ZuGbnP4A" fontName="Verdana" lineColor="4210752"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_uf7LErdfEemzI5ZuGbnP4A"/>
</children>
<styles xsi:type="notation:ShapeStyle" xmi:id="_uf6kAbdfEemzI5ZuGbnP4A" fontName="Verdana" fillColor="0" lineColor="16777215"/>
<styles xsi:type="notation:NamedStyle" xmi:id="_uf6kArdfEemzI5ZuGbnP4A" name="allowColors"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_uf7yILdfEemzI5ZuGbnP4A" x="1109" width="26" height="28"/>
</children>
<children xmi:id="_uf-OYLdfEemzI5ZuGbnP4A" type="State" element="_uf8ZMLdfEemzI5ZuGbnP4A">
<children xsi:type="notation:DecorationNode" xmi:id="_uf-1cLdfEemzI5ZuGbnP4A" type="StateName">
<styles xsi:type="notation:ShapeStyle" xmi:id="_uf-1cbdfEemzI5ZuGbnP4A"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_uf-1crdfEemzI5ZuGbnP4A"/>
</children>
<children xsi:type="notation:Compartment" xmi:id="_ugADkLdfEemzI5ZuGbnP4A" type="StateTextCompartment">
<children xsi:type="notation:Shape" xmi:id="_ugAqoLdfEemzI5ZuGbnP4A" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_ugAqobdfEemzI5ZuGbnP4A"/>
</children>
</children>
<children xsi:type="notation:Compartment" xmi:id="_ugAqordfEemzI5ZuGbnP4A" type="StateFigureCompartment">
<children xmi:id="_qsgVQLeKEemUVuDCbi9APQ" type="Region" element="_gj7iwLeKEemUVuDCbi9APQ">
<children xsi:type="notation:DecorationNode" xmi:id="_qsgVQbeKEemUVuDCbi9APQ" type="RegionName">
<styles xsi:type="notation:ShapeStyle" xmi:id="_qsgVQreKEemUVuDCbi9APQ"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_qsgVQ7eKEemUVuDCbi9APQ"/>
</children>
<children xsi:type="notation:Shape" xmi:id="_qsgVRLeKEemUVuDCbi9APQ" type="RegionCompartment" fontName="Verdana" lineColor="4210752">
<children xmi:id="_sPnGwLeKEemUVuDCbi9APQ" type="Entry" element="_sPl4oLeKEemUVuDCbi9APQ">
<children xmi:id="_sPnt0LeKEemUVuDCbi9APQ" type="BorderItemLabelContainer">
<children xsi:type="notation:DecorationNode" xmi:id="_sPnt07eKEemUVuDCbi9APQ" type="BorderItemLabel">
<styles xsi:type="notation:ShapeStyle" xmi:id="_sPnt1LeKEemUVuDCbi9APQ"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_sPnt1beKEemUVuDCbi9APQ"/>
</children>
<styles xsi:type="notation:ShapeStyle" xmi:id="_sPnt0beKEemUVuDCbi9APQ" fontName="Verdana" lineColor="4210752"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_sPnt0reKEemUVuDCbi9APQ"/>
</children>
<styles xsi:type="notation:ShapeStyle" xmi:id="_sPnGwbeKEemUVuDCbi9APQ" fontName="Verdana" fillColor="0" lineColor="16777215"/>
<styles xsi:type="notation:NamedStyle" xmi:id="_sPnGwreKEemUVuDCbi9APQ" name="allowColors"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_sPnGw7eKEemUVuDCbi9APQ" x="7" y="-2"/>
</children>
<children xmi:id="_tLijgLeKEemUVuDCbi9APQ" type="State" element="_tLh8cLeKEemUVuDCbi9APQ">
<children xsi:type="notation:DecorationNode" xmi:id="_tLjKkLeKEemUVuDCbi9APQ" type="StateName">
<styles xsi:type="notation:ShapeStyle" xmi:id="_tLjKkbeKEemUVuDCbi9APQ" fillColor="10265827"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_tLjKkreKEemUVuDCbi9APQ"/>
</children>
<children xsi:type="notation:Compartment" xmi:id="_tLjKk7eKEemUVuDCbi9APQ" type="StateTextCompartment">
<children xsi:type="notation:Shape" xmi:id="_tLjKlLeKEemUVuDCbi9APQ" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_tLjKlbeKEemUVuDCbi9APQ"/>
</children>
</children>
<children xsi:type="notation:Compartment" xmi:id="_tLjxoLeKEemUVuDCbi9APQ" type="StateFigureCompartment"/>
<styles xsi:type="notation:ShapeStyle" xmi:id="_tLijgbeKEemUVuDCbi9APQ" fontName="Verdana" fillColor="10265827" lineColor="12632256"/>
<styles xsi:type="notation:FontStyle" xmi:id="_tLijgreKEemUVuDCbi9APQ"/>
<styles xsi:type="notation:BooleanValueStyle" xmi:id="_tLjxobeKEemUVuDCbi9APQ" name="isHorizontal" booleanValue="true"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_tLijg7eKEemUVuDCbi9APQ" x="91" y="-19" width="56" height="55"/>
</children>
<children xmi:id="_9UfkELeKEemUVuDCbi9APQ" type="State" element="_9Ue9ALeKEemUVuDCbi9APQ">
<children xsi:type="notation:DecorationNode" xmi:id="_9UfkFLeKEemUVuDCbi9APQ" type="StateName">
<styles xsi:type="notation:ShapeStyle" xmi:id="_9UfkFbeKEemUVuDCbi9APQ" fillColor="10265827"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_9UfkFreKEemUVuDCbi9APQ"/>
</children>
<children xsi:type="notation:Compartment" xmi:id="_9UgLILeKEemUVuDCbi9APQ" type="StateTextCompartment">
<children xsi:type="notation:Shape" xmi:id="_9UgyMLeKEemUVuDCbi9APQ" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_9UgyMbeKEemUVuDCbi9APQ"/>
</children>
</children>
<children xsi:type="notation:Compartment" xmi:id="_9UgyMreKEemUVuDCbi9APQ" type="StateFigureCompartment"/>
<styles xsi:type="notation:ShapeStyle" xmi:id="_9UfkEbeKEemUVuDCbi9APQ" fontName="Verdana" fillColor="10265827" lineColor="12632256"/>
<styles xsi:type="notation:FontStyle" xmi:id="_9UfkEreKEemUVuDCbi9APQ"/>
<styles xsi:type="notation:BooleanValueStyle" xmi:id="_9UgyM7eKEemUVuDCbi9APQ" name="isHorizontal" booleanValue="true"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_9UfkE7eKEemUVuDCbi9APQ" x="451" y="82" width="55" height="55"/>
</children>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_qsgVRbeKEemUVuDCbi9APQ"/>
</children>
<styles xsi:type="notation:ShapeStyle" xmi:id="_qsgVRreKEemUVuDCbi9APQ" fontName="Verdana" fillColor="15790320" lineColor="12632256"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_qsgVR7eKEemUVuDCbi9APQ"/>
</children>
</children>
<styles xsi:type="notation:ShapeStyle" xmi:id="_uf-OYbdfEemzI5ZuGbnP4A" fontName="Verdana" fillColor="15981773" lineColor="12632256"/>
<styles xsi:type="notation:FontStyle" xmi:id="_uf-OYrdfEemzI5ZuGbnP4A"/>
<styles xsi:type="notation:BooleanValueStyle" xmi:id="_ugAqo7dfEemzI5ZuGbnP4A" name="isHorizontal" booleanValue="true"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_ugBRsLdfEemzI5ZuGbnP4A" x="13" y="34" width="602" height="291"/>
</children>
<children xmi:id="_4vbE8LdfEemzI5ZuGbnP4A" type="State" element="_4vYosLdfEemzI5ZuGbnP4A">
<children xsi:type="notation:DecorationNode" xmi:id="_4vbsALdfEemzI5ZuGbnP4A" type="StateName">
<styles xsi:type="notation:ShapeStyle" xmi:id="_4vbsAbdfEemzI5ZuGbnP4A"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_4vbsArdfEemzI5ZuGbnP4A"/>
</children>
<children xsi:type="notation:Compartment" xmi:id="_4vbsA7dfEemzI5ZuGbnP4A" type="StateTextCompartment">
<children xsi:type="notation:Shape" xmi:id="_4vbsBLdfEemzI5ZuGbnP4A" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_4vbsBbdfEemzI5ZuGbnP4A"/>
</children>
</children>
<children xsi:type="notation:Compartment" xmi:id="_4vbsBrdfEemzI5ZuGbnP4A" type="StateFigureCompartment"/>
<styles xsi:type="notation:ShapeStyle" xmi:id="_4vbE8bdfEemzI5ZuGbnP4A" fontName="Verdana" fillColor="15981773" lineColor="12632256"/>
<styles xsi:type="notation:FontStyle" xmi:id="_4vbE8rdfEemzI5ZuGbnP4A"/>
<styles xsi:type="notation:BooleanValueStyle" xmi:id="_4vcTELdfEemzI5ZuGbnP4A" name="isHorizontal" booleanValue="true"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_4vbE87dfEemzI5ZuGbnP4A" x="893" y="164" width="294" height="191"/>
</children>
<children xmi:id="_aAuGgLdgEemzI5ZuGbnP4A" type="State" element="_aAs4YLdgEemzI5ZuGbnP4A">
<children xsi:type="notation:DecorationNode" xmi:id="_aAuGhLdgEemzI5ZuGbnP4A" type="StateName">
<styles xsi:type="notation:ShapeStyle" xmi:id="_aAuGhbdgEemzI5ZuGbnP4A"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_aAuGhrdgEemzI5ZuGbnP4A"/>
</children>
<children xsi:type="notation:Compartment" xmi:id="_aAutkLdgEemzI5ZuGbnP4A" type="StateTextCompartment">
<children xsi:type="notation:Shape" xmi:id="_aAutkbdgEemzI5ZuGbnP4A" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_aAutkrdgEemzI5ZuGbnP4A"/>
</children>
</children>
<children xsi:type="notation:Compartment" xmi:id="_aAutk7dgEemzI5ZuGbnP4A" type="StateFigureCompartment">
<children xmi:id="_ExvgALkQEemqMMLZEdLlPw" type="Region" element="_sitwMLkPEemqMMLZEdLlPw">
<children xsi:type="notation:DecorationNode" xmi:id="_ExvgAbkQEemqMMLZEdLlPw" type="RegionName">
<styles xsi:type="notation:ShapeStyle" xmi:id="_ExvgArkQEemqMMLZEdLlPw"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_ExvgA7kQEemqMMLZEdLlPw"/>
</children>
<children xsi:type="notation:Shape" xmi:id="_ExvgBLkQEemqMMLZEdLlPw" type="RegionCompartment" fontName="Verdana" lineColor="4210752">
<children xmi:id="_ExvgBbkQEemqMMLZEdLlPw" type="State" element="_w_EmwLkPEemqMMLZEdLlPw">
<children xsi:type="notation:DecorationNode" xmi:id="_ExvgBrkQEemqMMLZEdLlPw" type="StateName">
<styles xsi:type="notation:ShapeStyle" xmi:id="_ExvgB7kQEemqMMLZEdLlPw"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_ExvgCLkQEemqMMLZEdLlPw"/>
</children>
<children xsi:type="notation:Compartment" xmi:id="_ExvgCbkQEemqMMLZEdLlPw" type="StateTextCompartment">
<children xsi:type="notation:Shape" xmi:id="_ExvgCrkQEemqMMLZEdLlPw" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_ExvgC7kQEemqMMLZEdLlPw"/>
</children>
</children>
<children xsi:type="notation:Compartment" xmi:id="_ExvgDLkQEemqMMLZEdLlPw" type="StateFigureCompartment"/>
<styles xsi:type="notation:ShapeStyle" xmi:id="_ExvgDbkQEemqMMLZEdLlPw" fontName="Verdana" fillColor="10011046" lineColor="12632256"/>
<styles xsi:type="notation:FontStyle" xmi:id="_ExvgDrkQEemqMMLZEdLlPw"/>
<styles xsi:type="notation:BooleanValueStyle" xmi:id="_ExvgD7kQEemqMMLZEdLlPw" name="isHorizontal" booleanValue="true"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_ExvgELkQEemqMMLZEdLlPw" x="151" y="-10" width="234" height="68"/>
</children>
<children xmi:id="_ExvgEbkQEemqMMLZEdLlPw" type="Entry" element="_yXKbELkPEemqMMLZEdLlPw">
<children xmi:id="_ExvgErkQEemqMMLZEdLlPw" type="BorderItemLabelContainer">
<children xsi:type="notation:DecorationNode" xmi:id="_ExvgE7kQEemqMMLZEdLlPw" type="BorderItemLabel">
<styles xsi:type="notation:ShapeStyle" xmi:id="_ExvgFLkQEemqMMLZEdLlPw"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_ExvgFbkQEemqMMLZEdLlPw"/>
</children>
<styles xsi:type="notation:ShapeStyle" xmi:id="_ExvgFrkQEemqMMLZEdLlPw" fontName="Verdana" lineColor="4210752"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_ExvgF7kQEemqMMLZEdLlPw"/>
</children>
<styles xsi:type="notation:ShapeStyle" xmi:id="_ExvgGLkQEemqMMLZEdLlPw" fontName="Verdana" fillColor="0" lineColor="16777215"/>
<styles xsi:type="notation:NamedStyle" xmi:id="_ExvgGbkQEemqMMLZEdLlPw" name="allowColors"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_ExvgGrkQEemqMMLZEdLlPw" x="19" y="-10"/>
</children>
<children xmi:id="_ExvgG7kQEemqMMLZEdLlPw" type="State" element="_-j_kULkPEemqMMLZEdLlPw">
<children xsi:type="notation:DecorationNode" xmi:id="_ExvgHLkQEemqMMLZEdLlPw" type="StateName">
<styles xsi:type="notation:ShapeStyle" xmi:id="_ExvgHbkQEemqMMLZEdLlPw"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_ExvgHrkQEemqMMLZEdLlPw"/>
</children>
<children xsi:type="notation:Compartment" xmi:id="_ExvgH7kQEemqMMLZEdLlPw" type="StateTextCompartment">
<children xsi:type="notation:Shape" xmi:id="_ExvgILkQEemqMMLZEdLlPw" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_ExvgIbkQEemqMMLZEdLlPw"/>
</children>
</children>
<children xsi:type="notation:Compartment" xmi:id="_ExvgIrkQEemqMMLZEdLlPw" type="StateFigureCompartment"/>
<styles xsi:type="notation:ShapeStyle" xmi:id="_ExvgI7kQEemqMMLZEdLlPw" fontName="Verdana" fillColor="10011046" lineColor="12632256"/>
<styles xsi:type="notation:FontStyle" xmi:id="_ExvgJLkQEemqMMLZEdLlPw"/>
<styles xsi:type="notation:BooleanValueStyle" xmi:id="_ExvgJbkQEemqMMLZEdLlPw" name="isHorizontal" booleanValue="true"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_ExvgJrkQEemqMMLZEdLlPw" x="16" y="182" width="188" height="66"/>
</children>
<children xmi:id="_ExvgJ7kQEemqMMLZEdLlPw" type="State" element="_BhtSoLkQEemqMMLZEdLlPw">
<children xsi:type="notation:DecorationNode" xmi:id="_ExvgKLkQEemqMMLZEdLlPw" type="StateName">
<styles xsi:type="notation:ShapeStyle" xmi:id="_ExvgKbkQEemqMMLZEdLlPw"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_ExvgKrkQEemqMMLZEdLlPw"/>
</children>
<children xsi:type="notation:Compartment" xmi:id="_ExvgK7kQEemqMMLZEdLlPw" type="StateTextCompartment">
<children xsi:type="notation:Shape" xmi:id="_ExvgLLkQEemqMMLZEdLlPw" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_ExvgLbkQEemqMMLZEdLlPw"/>
</children>
</children>
<children xsi:type="notation:Compartment" xmi:id="_ExvgLrkQEemqMMLZEdLlPw" type="StateFigureCompartment"/>
<styles xsi:type="notation:ShapeStyle" xmi:id="_ExvgL7kQEemqMMLZEdLlPw" fontName="Verdana" fillColor="10011046" lineColor="12632256"/>
<styles xsi:type="notation:FontStyle" xmi:id="_ExvgMLkQEemqMMLZEdLlPw"/>
<styles xsi:type="notation:BooleanValueStyle" xmi:id="_ExvgMbkQEemqMMLZEdLlPw" name="isHorizontal" booleanValue="true"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_ExvgMrkQEemqMMLZEdLlPw" x="283" y="196" width="198" height="67"/>
</children>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_ExvgM7kQEemqMMLZEdLlPw"/>
</children>
<styles xsi:type="notation:ShapeStyle" xmi:id="_ExvgNLkQEemqMMLZEdLlPw" fontName="Verdana" fillColor="15790320" lineColor="12632256"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_ExvgNbkQEemqMMLZEdLlPw"/>
</children>
</children>
<styles xsi:type="notation:ShapeStyle" xmi:id="_aAuGgbdgEemzI5ZuGbnP4A" fontName="Verdana" fillColor="15981773" lineColor="12632256"/>
<styles xsi:type="notation:FontStyle" xmi:id="_aAuGgrdgEemzI5ZuGbnP4A"/>
<styles xsi:type="notation:BooleanValueStyle" xmi:id="_aAutlLdgEemzI5ZuGbnP4A" name="isHorizontal" booleanValue="true"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_aAuGg7dgEemzI5ZuGbnP4A" x="25" y="674" width="524" height="392"/>
</children>
<children xmi:id="_42DmsLeGEemyoZNNAM3ZMg" type="State" element="_42BKcLeGEemyoZNNAM3ZMg">
<children xsi:type="notation:DecorationNode" xmi:id="_42Fb4LeGEemyoZNNAM3ZMg" type="StateName">
<styles xsi:type="notation:ShapeStyle" xmi:id="_42Fb4beGEemyoZNNAM3ZMg"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_42Fb4reGEemyoZNNAM3ZMg"/>
</children>
<children xsi:type="notation:Compartment" xmi:id="_42GC8LeGEemyoZNNAM3ZMg" type="StateTextCompartment">
<children xsi:type="notation:Shape" xmi:id="_42GqALeGEemyoZNNAM3ZMg" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_42GqAbeGEemyoZNNAM3ZMg"/>
</children>
</children>
<children xsi:type="notation:Compartment" xmi:id="_42GqAreGEemyoZNNAM3ZMg" type="StateFigureCompartment">
<children xmi:id="_aVVIoL3DEem_KcfQeEtgCA" type="Region" element="_42BxgLeGEemyoZNNAM3ZMg">
<children xsi:type="notation:DecorationNode" xmi:id="_aVVIob3DEem_KcfQeEtgCA" type="RegionName">
<styles xsi:type="notation:ShapeStyle" xmi:id="_aVVIor3DEem_KcfQeEtgCA"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_aVVIo73DEem_KcfQeEtgCA"/>
</children>
<children xsi:type="notation:Shape" xmi:id="_aVVIpL3DEem_KcfQeEtgCA" type="RegionCompartment" fontName="Verdana" lineColor="4210752">
<children xmi:id="_aVVIpb3DEem_KcfQeEtgCA" type="Entry" element="_H57OgLeHEemyoZNNAM3ZMg">
<children xmi:id="_aVVIpr3DEem_KcfQeEtgCA" type="BorderItemLabelContainer">
<children xsi:type="notation:DecorationNode" xmi:id="_aVVIp73DEem_KcfQeEtgCA" type="BorderItemLabel">
<styles xsi:type="notation:ShapeStyle" xmi:id="_aVVIqL3DEem_KcfQeEtgCA"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_aVVIqb3DEem_KcfQeEtgCA"/>
</children>
<styles xsi:type="notation:ShapeStyle" xmi:id="_aVVIqr3DEem_KcfQeEtgCA" fontName="Verdana" lineColor="4210752"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_aVVIq73DEem_KcfQeEtgCA"/>
</children>
<styles xsi:type="notation:ShapeStyle" xmi:id="_aVVIrL3DEem_KcfQeEtgCA" fontName="Verdana" fillColor="0" lineColor="16777215"/>
<styles xsi:type="notation:NamedStyle" xmi:id="_aVVIrb3DEem_KcfQeEtgCA" name="allowColors"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_aVVIrr3DEem_KcfQeEtgCA" x="19" y="50"/>
</children>
<children xmi:id="_aVVIr73DEem_KcfQeEtgCA" type="State" element="_dI8J8LeHEemyoZNNAM3ZMg">
<children xsi:type="notation:DecorationNode" xmi:id="_aVVIsL3DEem_KcfQeEtgCA" type="StateName">
<styles xsi:type="notation:ShapeStyle" xmi:id="_aVVIsb3DEem_KcfQeEtgCA" fillColor="15053796" lineColor="0"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_aVVIsr3DEem_KcfQeEtgCA"/>
</children>
<children xsi:type="notation:Compartment" xmi:id="_aVVIs73DEem_KcfQeEtgCA" type="StateTextCompartment">
<children xsi:type="notation:Shape" xmi:id="_aVVItL3DEem_KcfQeEtgCA" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_aVVItb3DEem_KcfQeEtgCA"/>
</children>
</children>
<children xsi:type="notation:Compartment" xmi:id="_aVVItr3DEem_KcfQeEtgCA" type="StateFigureCompartment"/>
<styles xsi:type="notation:ShapeStyle" xmi:id="_aVVIt73DEem_KcfQeEtgCA" fontName="Verdana" fillColor="15053796" lineColor="0"/>
<styles xsi:type="notation:FontStyle" xmi:id="_aVVIuL3DEem_KcfQeEtgCA"/>
<styles xsi:type="notation:BooleanValueStyle" xmi:id="_aVVIub3DEem_KcfQeEtgCA" name="isHorizontal" booleanValue="true"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_aVVIur3DEem_KcfQeEtgCA" x="55" y="-23" width="56" height="55"/>
</children>
<children xmi:id="_aVVIu73DEem_KcfQeEtgCA" type="State" element="_Jj95ALeIEemyoZNNAM3ZMg">
<children xsi:type="notation:DecorationNode" xmi:id="_aVVIvL3DEem_KcfQeEtgCA" type="StateName">
<styles xsi:type="notation:ShapeStyle" xmi:id="_aVVIvb3DEem_KcfQeEtgCA" fillColor="15053796"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_aVVIvr3DEem_KcfQeEtgCA"/>
</children>
<children xsi:type="notation:Compartment" xmi:id="_aVVIv73DEem_KcfQeEtgCA" type="StateTextCompartment">
<children xsi:type="notation:Shape" xmi:id="_aVVIwL3DEem_KcfQeEtgCA" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_aVVIwb3DEem_KcfQeEtgCA"/>
</children>
</children>
<children xsi:type="notation:Compartment" xmi:id="_aVVIwr3DEem_KcfQeEtgCA" type="StateFigureCompartment"/>
<styles xsi:type="notation:ShapeStyle" xmi:id="_aVVIw73DEem_KcfQeEtgCA" fontName="Verdana" fillColor="15053796" lineColor="12632256"/>
<styles xsi:type="notation:FontStyle" xmi:id="_aVVIxL3DEem_KcfQeEtgCA"/>
<styles xsi:type="notation:BooleanValueStyle" xmi:id="_aVVIxb3DEem_KcfQeEtgCA" name="isHorizontal" booleanValue="true"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_aVVIxr3DEem_KcfQeEtgCA" x="139" y="170"/>
</children>
<children xmi:id="_aVVIx73DEem_KcfQeEtgCA" type="State" element="_x4lNAL3CEem_KcfQeEtgCA">
<children xsi:type="notation:DecorationNode" xmi:id="_aVVIyL3DEem_KcfQeEtgCA" type="StateName">
<styles xsi:type="notation:ShapeStyle" xmi:id="_aVVIyb3DEem_KcfQeEtgCA"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_aVVIyr3DEem_KcfQeEtgCA"/>
</children>
<children xsi:type="notation:Compartment" xmi:id="_aVVIy73DEem_KcfQeEtgCA" type="StateTextCompartment" collapsed="true">
<children xsi:type="notation:Shape" xmi:id="_aVVIzL3DEem_KcfQeEtgCA" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_aVVIzb3DEem_KcfQeEtgCA"/>
</children>
</children>
<children xsi:type="notation:Compartment" xmi:id="_aVVIzr3DEem_KcfQeEtgCA" type="StateFigureCompartment"/>
<styles xsi:type="notation:ShapeStyle" xmi:id="_aVVIz73DEem_KcfQeEtgCA" fontName="Verdana" fillColor="15053796" lineColor="12632256"/>
<styles xsi:type="notation:FontStyle" xmi:id="_aVVI0L3DEem_KcfQeEtgCA"/>
<styles xsi:type="notation:BooleanValueStyle" xmi:id="_aVVI0b3DEem_KcfQeEtgCA" name="isHorizontal" booleanValue="true"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_aVVI0r3DEem_KcfQeEtgCA" x="439" y="-23" width="117" height="55"/>
</children>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_aVVI073DEem_KcfQeEtgCA"/>
</children>
<styles xsi:type="notation:ShapeStyle" xmi:id="_aVVI1L3DEem_KcfQeEtgCA" fontName="Verdana" fillColor="15790320" lineColor="12632256"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_aVVI1b3DEem_KcfQeEtgCA"/>
</children>
</children>
<styles xsi:type="notation:ShapeStyle" xmi:id="_42ENwLeGEemyoZNNAM3ZMg" fontName="Verdana" fillColor="15981773" lineColor="12632256"/>
<styles xsi:type="notation:FontStyle" xmi:id="_42ENwbeGEemyoZNNAM3ZMg"/>
<styles xsi:type="notation:BooleanValueStyle" xmi:id="_42GqA7eGEemyoZNNAM3ZMg" name="isHorizontal" booleanValue="true"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_42ENwreGEemyoZNNAM3ZMg" x="709" y="427" width="619" height="390"/>
</children>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_uf4u0bdfEemzI5ZuGbnP4A"/>
</children>
<styles xsi:type="notation:ShapeStyle" xmi:id="_uflz4LdfEemzI5ZuGbnP4A" fontName="Verdana" fillColor="15790320" lineColor="12632256"/>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_uf5V4LdfEemzI5ZuGbnP4A" x="12" y="12" width="1640" height="1106"/>
</children>
<children xsi:type="notation:Shape" xmi:id="_ugImcLdfEemzI5ZuGbnP4A" type="StatechartText" fontName="Verdana" lineColor="4210752">
<children xsi:type="notation:DecorationNode" xmi:id="_ugJNgLdfEemzI5ZuGbnP4A" type="StatechartName">
<styles xsi:type="notation:ShapeStyle" xmi:id="_ugJNgbdfEemzI5ZuGbnP4A"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_ugJNgrdfEemzI5ZuGbnP4A"/>
</children>
<children xsi:type="notation:Shape" xmi:id="_ugJNg7dfEemzI5ZuGbnP4A" type="StatechartTextExpression" fontName="Verdana" lineColor="4210752">
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_ugJNhLdfEemzI5ZuGbnP4A"/>
</children>
<layoutConstraint xsi:type="notation:Bounds" xmi:id="_ugJNhbdfEemzI5ZuGbnP4A" x="10" y="10" width="200" height="400"/>
</children>
<styles xsi:type="notation:BooleanValueStyle" xmi:id="_uffGMbdfEemzI5ZuGbnP4A" name="inlineDefinitionSection"/>
<styles xsi:type="notation:DiagramStyle" xmi:id="_uffGMrdfEemzI5ZuGbnP4A"/>
<edges xmi:id="_ugHYULdfEemzI5ZuGbnP4A" type="Transition" element="_ugB4wLdfEemzI5ZuGbnP4A" source="_uf6kALdfEemzI5ZuGbnP4A" target="_uf-OYLdfEemzI5ZuGbnP4A">
<children xsi:type="notation:DecorationNode" xmi:id="_ugH_YbdfEemzI5ZuGbnP4A" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_ugH_YrdfEemzI5ZuGbnP4A"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_ugH_Y7dfEemzI5ZuGbnP4A" y="10"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_ugHYUbdfEemzI5ZuGbnP4A" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_ugH_YLdfEemzI5ZuGbnP4A" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_ugHYUrdfEemzI5ZuGbnP4A" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_TDgmULdsEemzI5ZuGbnP4A" id="(0.5,0.5)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_yFe8gLdfEemzI5ZuGbnP4A" id="(0.38358458961474035,0.003484320557491289)"/>
</edges>
<edges xmi:id="_8mqcQLdfEemzI5ZuGbnP4A" type="Transition" element="_8monELdfEemzI5ZuGbnP4A" source="_9UfkELeKEemUVuDCbi9APQ" target="_4vbE8LdfEemzI5ZuGbnP4A">
<children xsi:type="notation:DecorationNode" xmi:id="_8mqcRLdfEemzI5ZuGbnP4A" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_8mqcRbdfEemzI5ZuGbnP4A"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_8mrDULdfEemzI5ZuGbnP4A" x="-10" y="-10"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_8mqcQbdfEemzI5ZuGbnP4A" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_8mqcQ7dfEemzI5ZuGbnP4A" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_8mqcQrdfEemzI5ZuGbnP4A" points="[2, 10, -521, -40]$[306, 10, -217, -40]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_8ms4gLdfEemzI5ZuGbnP4A" id="(2.0408733624454145,0.3876923076923077)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_8mtfkLdfEemzI5ZuGbnP4A" id="(0.7513792978266273,0.7574062379668849)"/>
</edges>
<edges xmi:id="_5kAxULdkEemzI5ZuGbnP4A" type="Transition" element="_5j_jMLdkEemzI5ZuGbnP4A" source="_4vbE8LdfEemzI5ZuGbnP4A" target="_42DmsLeGEemyoZNNAM3ZMg">
<children xsi:type="notation:DecorationNode" xmi:id="_5kAxVLdkEemzI5ZuGbnP4A" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_5kAxVbdkEemzI5ZuGbnP4A"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_5kAxVrdkEemzI5ZuGbnP4A" y="10"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_5kAxUbdkEemzI5ZuGbnP4A" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_5kAxU7dkEemzI5ZuGbnP4A" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_5kAxUrdkEemzI5ZuGbnP4A" points="[5, 6, 3, -98]$[5, 102, 3, -2]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_5kDNkLdkEemzI5ZuGbnP4A" id="(0.5519987891859166,0.977766233766234)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_5kDNkbdkEemzI5ZuGbnP4A" id="(0.22220526308151572,0.010314595152140279)"/>
</edges>
<edges xmi:id="_ChqW4LdnEemzI5ZuGbnP4A" type="Transition" element="_ChpIwLdnEemzI5ZuGbnP4A" source="_aAuGgLdgEemzI5ZuGbnP4A" target="_4vbE8LdfEemzI5ZuGbnP4A">
<children xsi:type="notation:DecorationNode" xmi:id="_Chq98bdnEemzI5ZuGbnP4A" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_Chq98rdnEemzI5ZuGbnP4A"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_Chq987dnEemzI5ZuGbnP4A" x="121" y="18"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_ChqW4bdnEemzI5ZuGbnP4A" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_Chq98LdnEemzI5ZuGbnP4A" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_ChqW4rdnEemzI5ZuGbnP4A" points="[85, -12, -1039, 113]$[85, -120, -1039, 5]$[1021, -120, -103, 5]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_ChszILdnEemzI5ZuGbnP4A" id="(0.33178802572497273,0.0336986935952355)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_ChszIbdnEemzI5ZuGbnP4A" id="(0.36998914242024267,0.862881786676935)"/>
</edges>
<edges xmi:id="_GEoHULdnEemzI5ZuGbnP4A" type="Transition" element="_GEngQLdnEemzI5ZuGbnP4A" source="_42DmsLeGEemyoZNNAM3ZMg" target="_4vbE8LdfEemzI5ZuGbnP4A">
<children xsi:type="notation:DecorationNode" xmi:id="_GEouYbdnEemzI5ZuGbnP4A" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_GEouYrdnEemzI5ZuGbnP4A"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_GEouY7dnEemzI5ZuGbnP4A" x="2" y="59"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_GEoHUbdnEemzI5ZuGbnP4A" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_GEouYLdnEemzI5ZuGbnP4A" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_GEoHUrdnEemzI5ZuGbnP4A" points="[-12, -1, -40, 104]$[-12, -78, -40, 27]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_GEp8gLdnEemzI5ZuGbnP4A" id="(0.7124394184168013,0.005128205128205128)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_GEp8gbdnEemzI5ZuGbnP4A" id="(0.9753148019184494,0.8576080092414323)"/>
</edges>
<edges xmi:id="_2gZ8wLdsEemzI5ZuGbnP4A" type="Transition" element="_2gW5cLdsEemzI5ZuGbnP4A" source="_aAuGgLdgEemzI5ZuGbnP4A" target="_42DmsLeGEemyoZNNAM3ZMg">
<children xsi:type="notation:DecorationNode" xmi:id="_2gZ8xLdsEemzI5ZuGbnP4A" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_2gZ8xbdsEemzI5ZuGbnP4A"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_2gZ8xrdsEemzI5ZuGbnP4A" x="-51" y="-11"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_2gZ8wbdsEemzI5ZuGbnP4A" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_2gZ8w7dsEemzI5ZuGbnP4A" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_2gZ8wrdsEemzI5ZuGbnP4A" points="[74, -34, -435, 204]$[74, -147, -435, 91]$[508, -147, -1, 91]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_2gbx8LdsEemzI5ZuGbnP4A" id="(0.3395040263232279,0.08986318292062798)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_2gbx8bdsEemzI5ZuGbnP4A" id="(0.002093449858112687,0.10816614781505822)"/>
</edges>
<edges xmi:id="_GS-CULeIEemyoZNNAM3ZMg" type="Transition" element="_GS6X8LeIEemyoZNNAM3ZMg" source="_aVVIpb3DEem_KcfQeEtgCA" target="_aVVIr73DEem_KcfQeEtgCA">
<children xsi:type="notation:DecorationNode" xmi:id="_GS_QcLeIEemyoZNNAM3ZMg" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_GS_QcbeIEemyoZNNAM3ZMg"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_GS_QcreIEemyoZNNAM3ZMg" x="-17" y="-92"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_GS-pYLeIEemyoZNNAM3ZMg" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_GS-pYreIEemyoZNNAM3ZMg" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_GS-pYbeIEemyoZNNAM3ZMg" points="[5, 4, -38, -30]$[44, 58, 1, 24]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_YoaT0L3DEem_KcfQeEtgCA" id="(0.5,0.5)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_GTCTwLeIEemyoZNNAM3ZMg" id="(0.018931710615280588,0.5272727272727272)"/>
</edges>
<edges xmi:id="_UvBmwLeJEemUVuDCbi9APQ" type="Transition" element="_Uu-jcLeJEemUVuDCbi9APQ" source="_aVVIu73DEem_KcfQeEtgCA" target="_aAuGgLdgEemzI5ZuGbnP4A">
<children xsi:type="notation:DecorationNode" xmi:id="_UvC04LeJEemUVuDCbi9APQ" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_UvC04beJEemUVuDCbi9APQ"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_UvDb8LeJEemUVuDCbi9APQ" x="123" y="18"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_UvBmwbeJEemUVuDCbi9APQ" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_UvCN0LeJEemUVuDCbi9APQ" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_UvBmwreJEemUVuDCbi9APQ" points="[23, 20, 794, 14]$[23, 56, 794, 50]$[-321, 56, 450, 50]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_UvF4MLeJEemUVuDCbi9APQ" id="(0.005405405405405406,0.5849056603773585)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_UvF4MbeJEemUVuDCbi9APQ" id="(0.13310101031990185,0.134794774380942)"/>
</edges>
<edges xmi:id="_FOxvgLeKEemUVuDCbi9APQ" type="Transition" element="_FOusMLeKEemUVuDCbi9APQ" source="_aVVIr73DEem_KcfQeEtgCA" target="_aVVIx73DEem_KcfQeEtgCA">
<children xsi:type="notation:DecorationNode" xmi:id="_FOyWkbeKEemUVuDCbi9APQ" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_FOyWkreKEemUVuDCbi9APQ"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_FOyWk7eKEemUVuDCbi9APQ" x="2" y="-4"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_FOxvgbeKEemUVuDCbi9APQ" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_FOyWkLeKEemUVuDCbi9APQ" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_FOxvgreKEemUVuDCbi9APQ" points="[-68, -21, -269, -2]$[219, -21, 18, -2]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_FO0y0LeKEemUVuDCbi9APQ" id="(3.2543397287230307,0.8545454545454545)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_FO0y0beKEemUVuDCbi9APQ" id="(-0.15364992150706439,0.4709433962264151)"/>
</edges>
<edges xmi:id="_Tqq74LeLEemUVuDCbi9APQ" type="Transition" element="_TqqU0LeLEemUVuDCbi9APQ" source="_sPnGwLeKEemUVuDCbi9APQ" target="_tLijgLeKEemUVuDCbi9APQ">
<children xsi:type="notation:DecorationNode" xmi:id="_Tqri8beLEemUVuDCbi9APQ" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_Tqri8reLEemUVuDCbi9APQ"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_Tqri87eLEemUVuDCbi9APQ" x="-3" y="-35"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_Tqq74beLEemUVuDCbi9APQ" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_Tqri8LeLEemUVuDCbi9APQ" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_Tqq74reLEemUVuDCbi9APQ" points="[6, -2, -75, -20]$[41, -2, -40, -20]$[41, -10, -40, -28]$[77, -10, -4, -28]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_1LGdILkhEemqMMLZEdLlPw" id="(0.5,0.5)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_TqtYILeLEemUVuDCbi9APQ" id="(0.09626314293833475,0.8545454545454545)"/>
</edges>
<edges xmi:id="_glrZwLeLEemUVuDCbi9APQ" type="Transition" element="_glqLoLeLEemUVuDCbi9APQ" source="_tLijgLeKEemUVuDCbi9APQ" target="_9UfkELeKEemUVuDCbi9APQ">
<children xsi:type="notation:DecorationNode" xmi:id="_glrZxLeLEemUVuDCbi9APQ" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_glrZxbeLEemUVuDCbi9APQ"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_glrZxreLEemUVuDCbi9APQ" x="28" y="13"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_glrZwbeLEemUVuDCbi9APQ" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_glrZw7eLEemUVuDCbi9APQ" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_glrZwreLEemUVuDCbi9APQ" points="[2, 5, -120, -75]$[2, 72, -120, -8]$[122, 72, 0, -8]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_gltO8LeLEemUVuDCbi9APQ" id="(0.44281045751633985,0.9090909090909091)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_gltO8beLEemUVuDCbi9APQ" id="(-2.380436681222707,0.48)"/>
</edges>
<edges xmi:id="_XsDJgLjyEemqMMLZEdLlPw" type="Transition" element="_Xrd6sLjyEemqMMLZEdLlPw" source="_aAuGgLdgEemzI5ZuGbnP4A" target="_42DmsLeGEemyoZNNAM3ZMg">
<children xsi:type="notation:DecorationNode" xmi:id="_XsEXoLjyEemqMMLZEdLlPw" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_XsEXobjyEemqMMLZEdLlPw"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_XsEXorjyEemqMMLZEdLlPw" x="-3" y="10"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_XsDJgbjyEemqMMLZEdLlPw" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_XsDwkLjyEemqMMLZEdLlPw" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_XsDJgrjyEemqMMLZEdLlPw" points="[241, 31, -741, -8]$[981, 31, -1, -8]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_XsICALjyEemqMMLZEdLlPw" id="(0.2662020206398037,0.07863028505554949)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_XsIpELjyEemqMMLZEdLlPw" id="(0.0035167854383102944,0.18050541516245486)"/>
</edges>
<edges xmi:id="_zNY4cLkPEemqMMLZEdLlPw" type="Transition" element="_zNXqULkPEemqMMLZEdLlPw" source="_ExvgEbkQEemqMMLZEdLlPw" target="_ExvgBbkQEemqMMLZEdLlPw">
<children xsi:type="notation:DecorationNode" xmi:id="_zNY4dLkPEemqMMLZEdLlPw" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_zNY4dbkPEemqMMLZEdLlPw"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_zNY4drkPEemqMMLZEdLlPw" y="10"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_zNY4cbkPEemqMMLZEdLlPw" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_zNY4c7kPEemqMMLZEdLlPw" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_zNY4crkPEemqMMLZEdLlPw" points="[4, -1, -36, 2]$[40, -1, 0, 2]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_ep8-sLkREemqMMLZEdLlPw" id="(0.5,0.5)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_zNbUsLkPEemqMMLZEdLlPw" id="(0.0,0.24274986703206555)"/>
</edges>
<edges xmi:id="_HnVNELkQEemqMMLZEdLlPw" type="Transition" element="_HnT-8LkQEemqMMLZEdLlPw" source="_ExvgBbkQEemqMMLZEdLlPw" target="_ExvgG7kQEemqMMLZEdLlPw">
<children xsi:type="notation:DecorationNode" xmi:id="_HnVNFLkQEemqMMLZEdLlPw" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_HnVNFbkQEemqMMLZEdLlPw"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_HnVNFrkQEemqMMLZEdLlPw" x="-15" y="-34"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_HnVNEbkQEemqMMLZEdLlPw" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_HnVNE7kQEemqMMLZEdLlPw" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_HnVNErkQEemqMMLZEdLlPw" points="[-125, 30, 0, -137]$[-125, 159, 0, -8]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_HnXpULkQEemqMMLZEdLlPw" id="(0.6546214575353101,0.5293571163136382)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_HnXpUbkQEemqMMLZEdLlPw" id="(0.8725405696080978,0.13289581624282198)"/>
</edges>
<edges xmi:id="_JnWkELkQEemqMMLZEdLlPw" type="Transition" element="_JnV9ALkQEemqMMLZEdLlPw" source="_ExvgG7kQEemqMMLZEdLlPw" target="_ExvgJ7kQEemqMMLZEdLlPw">
<children xsi:type="notation:DecorationNode" xmi:id="_JnWkFLkQEemqMMLZEdLlPw" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_JnWkFbkQEemqMMLZEdLlPw"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_JnWkFrkQEemqMMLZEdLlPw" x="-1" y="-20"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_JnWkEbkQEemqMMLZEdLlPw" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_JnWkE7kQEemqMMLZEdLlPw" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_JnWkErkQEemqMMLZEdLlPw" points="[39, -10, -265, 14]$[171, -10, -133, 14]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_JnYZQLkQEemqMMLZEdLlPw" id="(0.7915189452873458,0.6349466776045939)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_JnYZQbkQEemqMMLZEdLlPw" id="(0.6900256732947393,0.0)"/>
</edges>
<edges xmi:id="_py9v8LkQEemqMMLZEdLlPw" type="Transition" element="_py7TsLkQEemqMMLZEdLlPw" source="_ExvgJ7kQEemqMMLZEdLlPw" target="_ExvgBbkQEemqMMLZEdLlPw">
<children xsi:type="notation:DecorationNode" xmi:id="_py9v9LkQEemqMMLZEdLlPw" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_py9v9bkQEemqMMLZEdLlPw"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_py9v9rkQEemqMMLZEdLlPw" x="9" y="40"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_py9v8bkQEemqMMLZEdLlPw" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_py9v87kQEemqMMLZEdLlPw" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_py9v8rkQEemqMMLZEdLlPw" points="[3, 0, 24, 166]$[3, -143, 24, 23]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_py_lILkQEemqMMLZEdLlPw" id="(0.11032387218375195,0.0)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_py_lIbkQEemqMMLZEdLlPw" id="(0.5786009011763706,0.6438127090301005)"/>
</edges>
<edges xmi:id="_sd9WkLkQEemqMMLZEdLlPw" type="Transition" element="_sd8vgLkQEemqMMLZEdLlPw" source="_ExvgG7kQEemqMMLZEdLlPw" target="_ExvgBbkQEemqMMLZEdLlPw">
<children xsi:type="notation:DecorationNode" xmi:id="_sd99obkQEemqMMLZEdLlPw" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_sd99orkQEemqMMLZEdLlPw"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_sd99o7kQEemqMMLZEdLlPw" y="10"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_sd9WkbkQEemqMMLZEdLlPw" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_sd99oLkQEemqMMLZEdLlPw" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_sd9WkrkQEemqMMLZEdLlPw" points="[0, 0, -109, 77]$[111, -64, 2, 13]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_sd_y0LkQEemqMMLZEdLlPw" id="(0.12147961925536468,0.0)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_sd_y0bkQEemqMMLZEdLlPw" id="(0.016893456968653162,0.672426607209216)"/>
</edges>
<edges xmi:id="_lL_loL3CEem_KcfQeEtgCA" type="Transition" element="_lL8iUL3CEem_KcfQeEtgCA" source="_ExvgJ7kQEemqMMLZEdLlPw" target="_ExvgBbkQEemqMMLZEdLlPw">
<children xsi:type="notation:DecorationNode" xmi:id="_lMAzwL3CEem_KcfQeEtgCA" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_lMAzwb3CEem_KcfQeEtgCA"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_lMBa0L3CEem_KcfQeEtgCA" x="68" y="-5"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_lL_lob3CEem_KcfQeEtgCA" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_lMAMsL3CEem_KcfQeEtgCA" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_lL_lor3CEem_KcfQeEtgCA" points="[111, 0, 104, 154]$[111, -172, 104, -18]$[52, -172, 45, -18]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_lMEeIL3CEem_KcfQeEtgCA" id="(0.23737373737373738,0.0)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_lMEeIb3CEem_KcfQeEtgCA" id="(0.8076923076923077,0.8382352941176471)"/>
</edges>
<edges xmi:id="_le7TQL3DEem_KcfQeEtgCA" type="Transition" element="_le6FIL3DEem_KcfQeEtgCA" source="_aVVIr73DEem_KcfQeEtgCA" target="_aVVIu73DEem_KcfQeEtgCA">
<children xsi:type="notation:DecorationNode" xmi:id="_le76Ub3DEem_KcfQeEtgCA" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_le76Ur3DEem_KcfQeEtgCA"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_le76U73DEem_KcfQeEtgCA" x="108" y="-15"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_le7TQb3DEem_KcfQeEtgCA" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_le76UL3DEem_KcfQeEtgCA" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_le7TQr3DEem_KcfQeEtgCA" points="[13, 50, -40, -147]$[54, 194, 1, -3]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_le-WkL3DEem_KcfQeEtgCA" id="(0.35714285714285715,0.9636363636363636)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_le-Wkb3DEem_KcfQeEtgCA" id="(0.08641975308641975,0.07547169811320754)"/>
</edges>
<edges xmi:id="_mY_u0L3DEem_KcfQeEtgCA" type="Transition" element="_mY_HwL3DEem_KcfQeEtgCA" source="_aVVIx73DEem_KcfQeEtgCA" target="_aVVIu73DEem_KcfQeEtgCA">
<children xsi:type="notation:DecorationNode" xmi:id="_mZAV4b3DEem_KcfQeEtgCA" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_mZAV4r3DEem_KcfQeEtgCA"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_mZAV473DEem_KcfQeEtgCA" x="40" y="-11"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_mY_u0b3DEem_KcfQeEtgCA" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_mZAV4L3DEem_KcfQeEtgCA" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_mY_u0r3DEem_KcfQeEtgCA" points="[-31, 50, 114, -171]$[-141, 224, 4, 3]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_mZCLEL3DEem_KcfQeEtgCA" id="(-0.11878881987577643,0.0)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_mZCLEb3DEem_KcfQeEtgCA" id="(0.9753086419753086,0.6037735849056604)"/>
</edges>
<edges xmi:id="_97QfQL3DEem_KcfQeEtgCA" type="Transition" element="_97OqEL3DEem_KcfQeEtgCA" source="_aVVIx73DEem_KcfQeEtgCA" target="_aVVIr73DEem_KcfQeEtgCA">
<children xsi:type="notation:DecorationNode" xmi:id="_97QfRL3DEem_KcfQeEtgCA" type="TransitionExpression">
<styles xsi:type="notation:ShapeStyle" xmi:id="_97QfRb3DEem_KcfQeEtgCA"/>
<layoutConstraint xsi:type="notation:Location" xmi:id="_97QfRr3DEem_KcfQeEtgCA" x="-7" y="14"/>
</children>
<styles xsi:type="notation:ConnectorStyle" xmi:id="_97QfQb3DEem_KcfQeEtgCA" routing="Rectilinear" lineColor="4210752"/>
<styles xsi:type="notation:FontStyle" xmi:id="_97QfQ73DEem_KcfQeEtgCA" fontName="Verdana"/>
<bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_97QfQr3DEem_KcfQeEtgCA" points="[16, 50, 257, 6]$[-271, 50, -30, 6]"/>
<sourceAnchor xsi:type="notation:IdentityAnchor" xmi:id="_97SUcL3DEem_KcfQeEtgCA" id="(-0.13616071428571427,0.0)"/>
<targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_97SUcb3DEem_KcfQeEtgCA" id="(2.4938460232577877,0.890909090909091)"/>
</edges>
</notation:Diagram>
</xmi:XMI>
......@@ -108,7 +108,7 @@ static int rtu_create_static_entries(void)
for (i = 0; i < hal_nports_local; i++) {
enabled_port_mask |= (1 << hal_ports_local_copy[i].hw_index);
port_was_up[i] = state_up(hal_ports_local_copy[i].state);
port_was_up[i] = state_up(&hal_ports_local_copy[i]);
}
// VLAN-aware Bridge reserved addresses (802.1Q-2005 Table 8.1)
......@@ -180,7 +180,7 @@ static void rtu_update_ports_state(void)
if (!hal_ports_local_copy[i].in_use)
continue;
link_up = state_up(hal_ports_local_copy[i].state);
link_up = state_up(&hal_ports_local_copy[i]);
if (port_was_up[i] && !link_up) {
pr_info(
"Port %s went down, removing corresponding entries...\n",
......@@ -253,7 +253,7 @@ static int rtu_daemon_learning_process(void)
for (port_down = i = 0; i <= MAX_PORT; i++) {
p = &hal_ports_local_copy[i];
if (p->in_use && p->hw_index == req.port_id
&& !state_up(p->state)) {
&& !state_up(p)) {
port_down = 1;
pr_debug("port down %s\n", p->name);
break;
......
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