Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
White Rabbit Switch - Software
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
86
Issues
86
List
Board
Labels
Milestones
Merge Requests
4
Merge Requests
4
CI / CD
CI / CD
Pipelines
Schedules
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
White Rabbit Switch - Software
Commits
6892422d
Commit
6892422d
authored
Jan 24, 2012
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
userspace: stripped wrsw_hal to a bare minimum
parent
55c40f75
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
31 additions
and
188 deletions
+31
-188
hal_main.c
userspace/wrsw_hal/hal_main.c
+12
-12
hal_ports.c
userspace/wrsw_hal/hal_ports.c
+19
-156
wrsw_hal.h
userspace/wrsw_hal/wrsw_hal.h
+0
-20
No files found.
userspace/wrsw_hal/hal_main.c
View file @
6892422d
...
...
@@ -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
);
...
...
userspace/wrsw_hal/hal_ports.c
View file @
6892422d
...
...
@@ -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
=
14
00
;
state
->
t4_phase_transition
=
14
00
;
state
->
clock_period
=
8
000
;
state
->
t2_phase_transition
=
60
00
;
state
->
t4_phase_transition
=
60
00
;
state
->
clock_period
=
16
000
;
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
...
...
userspace/wrsw_hal/wrsw_hal.h
View file @
6892422d
...
...
@@ -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
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment