Commit 6892422d authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

userspace: stripped wrsw_hal to a bare minimum

parent 55c40f75
......@@ -60,14 +60,14 @@ int hal_setup_fpga_images()
if( hal_config_get_string("global.hal_firmware_path", fpga_dir, sizeof(fpga_dir)) < 0)
return -1;
shw_set_fpga_firmware_path(fpga_dir);
// shw_set_fpga_firmware_path(fpga_dir);
/* check if the config demands a particular bitstream (otherwise libswitchhw will load the default ones) */
if( !hal_config_get_string("global.main_firmware", fw_name, sizeof(fw_name)))
/* if( !hal_config_get_string("global.main_firmware", fw_name, sizeof(fw_name)))
shw_request_fpga_firmware(FPGA_ID_MAIN, fw_name);
if( !hal_config_get_string("global.clkb_firmware", fw_name, sizeof(fw_name)))
shw_request_fpga_firmware(FPGA_ID_CLKB, fw_name);
shw_request_fpga_firmware(FPGA_ID_CLKB, fw_name);*/
return 0;
}
......@@ -171,23 +171,23 @@ int hal_init()
/* parse the configuration file and choose the bitstreams to load to the FPGAs */
assert_init(hal_parse_config());
assert_init(hal_setup_fpga_images());
// assert_init(hal_setup_fpga_images());
/* Check if the switch will operate as a grandmaster and eventually enable the ext clock input
prior to initializing libswitchhw. */
if(!hal_config_get_int("timing.use_external_clock", &enable))
shw_use_external_reference(enable);
// if(!hal_config_get_int("timing.use_external_clock", &enable))
// shw_use_external_reference(enable);
/* Perform a low-level hardware init, load bitstreams, initialize non-kernel drivers */
assert_init(shw_init());
/* If running in grandmaster mode, synchronize the internal PPS counter with the external source after
initializing the PPS generator. */
if(!hal_config_get_int("timing.use_external_clock", &enable))
shw_pps_gen_sync_external_pps();
// if(!hal_config_get_int("timing.use_external_clock", &enable))
// shw_pps_gen_sync_external_pps();
/* Load kernel drivers */
assert_init(hal_load_kernel_modules());
// assert_init(hal_load_kernel_modules());
/* Initialize port FSMs - see hal_ports.c */
assert_init(hal_init_ports());
......@@ -278,9 +278,9 @@ void hal_parse_cmdline(int argc, char *argv[])
hal_config_set_config_file(optarg);
break;
case 'f':
shw_fpga_force_firmware_reload();
break;
// case 'f':
// shw_fpga_force_firmware_reload();
// break;
case 'h':
show_help();
exit(0);
......
......@@ -94,17 +94,10 @@ typedef struct {
/* current DMTD loopback phase (picoseconds) and whether is it valid or not */
uint32_t phase_val;
int phase_val_valid;
int tx_cal_pending, rx_cal_pending;
/* locking FSM state */
int lock_state;
/* calibration FSM substates (RX/TX calibration in progress) */
int tx_cal_pending;
int rx_cal_pending;
/* Index of the activity/link LED */
int led_index;
/* Endpoint's base address */
uint32_t ep_base;
} hal_port_state_t;
......@@ -116,35 +109,6 @@ static hal_port_state_t ports[MAX_PORTS];
/* An fd of always opened raw sockets for ioctl()-ing Ethernet devices */
static int fd_raw;
/* computes an "unwrapped" PHY delay from the parameters from the configuration file (see wrsw_hal.h for
a detailed explanation) and the phase from the calibrator DMTD */
static uint32_t fix_phy_delay(int32_t delay, int32_t bias, int32_t min_val, int32_t range)
{
int32_t brange = (bias + range) % 8000;
TRACE(TRACE_INFO,"dly %d bias %d range %d brange %d", delay, bias, range,brange);
/* harder case: the range of calibrator measurements goes across the 0 - 8 ns "jump" - i.e.
the measured phase can be either in [bias, 8000ps] or in [0ps, bias + range - 8000ps] */
if(bias + range > 8000)
{
if(brange < 0) brange += 8000;
/* determine the subrange */
if(delay > bias || (delay < bias && delay > brange))
{
return delay - bias + min_val;
} {
return delay + (8000-bias) + min_val;
}
/* easy case - min and max delays fit as a single block inside the [0, 8000 ps] interval */
} else {
return delay - bias + min_val;
}
return delay; /* fixme: this is never reached */
}
/* generates a unique MAC address for port if_name (currently produced from the MAC of the
management port). */
/* FIXME: MAC addresses should be kept in some EEPROM */
......@@ -177,7 +141,6 @@ static int get_mac_address(const char *if_name, uint8_t *mac_addr)
/* Resets the state variables of a particular port and re-starts its state machines */
static void reset_port_state(hal_port_state_t *p)
{
p->calib.rx_calibrated = 0;
p->calib.tx_calibrated = 0;
p->locked = 0;
......@@ -185,7 +148,6 @@ static void reset_port_state(hal_port_state_t *p)
p->lock_state = LOCK_STATE_NONE;
p->tx_cal_pending = 0;
p->rx_cal_pending = 0;
}
#define AT_INT32 0
......@@ -280,12 +242,8 @@ int hal_init_port(const char *name, int index)
system(cmd);
/* read calibraton parameters (unwrapping and constant deltas) */
cfg_get_port_param(name, "phy_rx_bias", &p->calib.phy_rx_bias, AT_INT32, 7800);
cfg_get_port_param(name, "phy_rx_min", &p->calib.phy_rx_min, AT_INT32, 18*800);
cfg_get_port_param(name, "phy_rx_range", &p->calib.phy_rx_range, AT_INT32, 7*800);
cfg_get_port_param(name, "phy_tx_bias", &p->calib.phy_tx_bias, AT_INT32, 7800);
cfg_get_port_param(name, "phy_tx_min", &p->calib.phy_tx_min, AT_INT32, 18*800); cfg_get_port_param(name, "phy_tx_range", &p->calib.phy_tx_range, AT_INT32, 7*800);
cfg_get_port_param(name, "phy_tx_min", &p->calib.phy_tx_min, AT_INT32, 18*800);
cfg_get_port_param(name, "delta_tx_sfp", &p->calib.delta_tx_sfp, AT_INT32, 0);
cfg_get_port_param(name, "delta_rx_sfp", &p->calib.delta_rx_sfp, AT_INT32, 0);
......@@ -300,22 +258,13 @@ int hal_init_port(const char *name, int index)
p->calib.fiber_fix_alpha = (double)pow(2.0, 40.0) * ((p->calib.fiber_alpha + 1.0) / (p->calib.fiber_alpha + 2.0) - 0.5);
/* choose the LED (mini-backplane/front-panel). Not really implemented yet. In the V3 leds will be handled
from inside the FPGA */
p->led_index = (int) (p->name[3] - '0');
if(p->name[2] == 'u')
p->led_index |= LED_UP_MASK;
sscanf(p->name+2, "%d", &p->hw_index);
if(p->name[2] == 'd')
{
p->hw_index = 2+(p->name[3]-'0');
} else {
p->hw_index = 0+(p->name[3]-'0');
}
/* Set up the endpoint's base address (fixme: do this with the driver) */
p->ep_base = FPGA_BASE_EP_UP0 + 0x10000 * p->hw_index;
/* FIXME: this address should come from the driver header */
p->ep_base = 0x30000 + 0x400 * p->hw_index;
/* Configure the port's timing role depending on the contents of the config file */
snprintf(key_name, sizeof(key_name), "ports.%s.mode", p->name);
......@@ -388,35 +337,6 @@ static int check_link_up(const char *if_name)
and the softpll. */
static void port_locking_fsm(hal_port_state_t *p)
{
switch(p->lock_state)
{
/* locking disabled - do nothing */
case LOCK_STATE_NONE:
return;
/* Step 1: start locking by switching the helper PLL to use the newly designated uplink port as a reference */
/* ARub: removed for V3 as Tom commands */
case LOCK_STATE_START:
p->lock_state = LOCK_STATE_LOCKED;
break;
/* Step 2: wait until the HPLL has locked. fixme: timeout? */
/* ARub: removed for V3 as Tom commands */
/* Step 3: Wait until the DMPLL has locked */
/* ARub: removed for V3 as Tom commands */
/* Step 4: locking done. Just poll the PLL status regularly. */
case LOCK_STATE_LOCKED:
/* There were checks if hpll and dmpll. Removed now */
p->locked = 1;
break;
}
}
/* Updates the current value of the phase shift on a given port. Called by the main update function regularly. */
......@@ -426,6 +346,12 @@ static void poll_dmtd(hal_port_state_t *p)
}
static uint16_t pcs_readl(int endpoint, uint8_t reg)
{
}
/* Calibration state machine */
static void calibration_fsm(hal_port_state_t *p)
{
......@@ -436,8 +362,9 @@ static void calibration_fsm(hal_port_state_t *p)
TRACE(TRACE_INFO,"Bypassing calibration for downlink port %s", p->name);
p->calib.tx_calibrated = 1;
p->calib.rx_calibrated = 1;
p->calib.delta_rx_phy = 0;
p->calib.delta_tx_phy = 0;
/* FIXME: use proper register names */
p->calib.delta_rx_phy = p->calib.phy_rx_min + ((pcs_readl(p->hw_index, 16) >> 4) & 0x1f) * 800;
p->calib.delta_tx_phy = p->calib.phy_tx_min;
p->tx_cal_pending = 0;
p->rx_cal_pending = 0;
......@@ -446,35 +373,9 @@ static void calibration_fsm(hal_port_state_t *p)
/* Is there a calibration measurement in progress for this port? */
/* no, not in V3 */
/* no, not in V3 */
}
#if 0
/* Port LED update function. To be removed in V3. */
static int update_port_leds(hal_port_state_t *p)
{
uint32_t dsr = _fpga_readl(p->ep_base + EP_REG_DSR);
if(p->led_index & LED_UP_MASK)
{
int i = p->led_index & 0xf;
if(i==1)
shw_pio_set(&PIN_fled4[0], dsr & EP_DSR_LSTATUS ? 0 : 1);
else
shw_pio_set(&PIN_fled0[0], dsr & EP_DSR_LSTATUS ? 0 : 1);
// uplinks....
} else {
// printf("li %d\n", p->led_index);
shw_mbl_set_leds(p->led_index, 0, dsr & EP_DSR_LSTATUS ? MBL_LED_ON : MBL_LED_OFF);
}
return 0;
}
#endif
/* Main port state machine */
static void port_fsm(hal_port_state_t *p)
......@@ -617,9 +518,9 @@ int halexp_get_port_state(hexp_port_state_t *state, const char *port_name)
state->delta_tx = p->calib.delta_tx_phy + p->calib.delta_tx_sfp + p->calib.delta_tx_board;
state->delta_rx = p->calib.delta_rx_phy + p->calib.delta_rx_sfp + p->calib.delta_rx_board;
state->t2_phase_transition = 1400;
state->t4_phase_transition = 1400;
state->clock_period = 8000;
state->t2_phase_transition = 6000;
state->t4_phase_transition = 6000;
state->clock_period = 16000;
state->fiber_fix_alpha = p->calib.fiber_fix_alpha;
memcpy(state->hw_addr, p->hw_addr, 6);
......@@ -664,44 +565,6 @@ int halexp_query_ports(hexp_port_list_t *list)
/* Maciek's ptpx export for checking the presence of the external 10 MHz ref clock */
int hal_extsrc_check_lock()
{
char val[128];
FILE *fp;
if(!hal_config_get_string("extsrc.status", val, sizeof(val)))
{
printf("mlDGB_HAL: read value: %s\n",val);
if(!strcasecmp(val, "faked"))
{
return 1;
}
else if(!strcasecmp(val, "disabled"))
{
return -1;
}
else if(!strcasecmp(val, "enabled"))
{
//TODO: implement in HW, for the time being temprary solution
//#ifdef TMP
fp=fopen("/wr/etc/tmp_extsrc", "r");
if(!fp)
return 0;
if(fscanf(fp,"%s",val)>0)
{
if(!strcasecmp(val, "locked"))
return 1;
else if(!strcasecmp(val, "none"))
return -1;
else
return 0;
}
fclose(fp);
} else
//#endif
return 0;
}
return -1;
/*
return -1; //<0 - there is no external source lock
......
......@@ -22,25 +22,8 @@ typedef struct {
available at the parallel output of the PHY. */
uint32_t phy_rx_min;
/* RX delay range of the PHY, expressed as a difference (in picoseconds)
between the maximum and minimum possible RX delays. For example, a 1.25 Gbps
PHY with minimum delay of 8 UI and maximum delay of 12 UI will have
phy_rx_range equal to (12 - 8) * 800 ps = 3200 ps. Due to the nature of the
calibration method, the measurement range is limited to one parallel clock cycle,
i.e. 10 UIs, which is true for most 802.3z serdeses. PHYs which have bigger
delay variance can't be calibrated using this method. */
uint32_t phy_rx_range;
/* value of the phase shift (in picoseconds) measured by the calibrator DMTD
when the PHY has locked on the minimum possible delay. Used to "unwind" the phase
measurement into the PHY RX delay. This parameter must be determined experimentally. */
uint32_t phy_rx_bias;
/* the same set of parameters, but for the TX path of the PHY */
uint32_t phy_tx_bias;
uint32_t phy_tx_min;
uint32_t phy_tx_range;
/* Current PHY (clock-to-serial-symbol) TX and RX delays, in picoseconds */
uint32_t delta_tx_phy;
......@@ -55,9 +38,6 @@ typedef struct {
uint32_t delta_tx_board;
uint32_t delta_rx_board;
uint32_t raw_delta_rx_phy;
uint32_t raw_delta_tx_phy;
/* Fiber "alpha" asymmetry coefficient, as defined in the WRPTP Specification */
double fiber_alpha;
......
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