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
e78838e8
Commit
e78838e8
authored
Jan 04, 2015
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'new-config'
parents
57dbe28f
7b2f47f7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
1604 additions
and
641 deletions
+1604
-641
Kconfig
Kconfig
+221
-0
wrs_build_wraprootfs
build/scripts/wrs_build_wraprootfs
+1
-0
wrs-todo.in
doc/wrs-todo.in
+17
-16
wrs-user-manual.in
doc/wrs-user-manual.in
+153
-0
Makefile
userspace/libwr/Makefile
+2
-1
dot-config.c
userspace/libwr/dot-config.c
+252
-0
i2c_sfp.c
userspace/libwr/i2c_sfp.c
+52
-61
config.h
userspace/libwr/include/libwr/config.h
+36
-0
hal_shmem.h
userspace/libwr/include/libwr/hal_shmem.h
+3
-3
sfp_lib.h
userspace/libwr/include/libwr/sfp_lib.h
+12
-3
ppsi
userspace/ppsi
+1
-1
S20dot-config
userspace/rootfs_override/etc/init.d/S20dot-config
+6
-3
apply_dot-config
userspace/rootfs_override/wr/bin/apply_dot-config
+10
-0
NONWR_UDP_ALL
...ace/rootfs_override/wr/etc/ppsi-config-pool/NONWR_UDP_ALL
+126
-0
WR_AUTO
userspace/rootfs_override/wr/etc/ppsi-config-pool/WR_AUTO
+96
-0
WR_AUTO_UDP
...space/rootfs_override/wr/etc/ppsi-config-pool/WR_AUTO_UDP
+114
-0
WR_DEFAULT
userspace/rootfs_override/wr/etc/ppsi-config-pool/WR_DEFAULT
+96
-0
WR_MASTER
userspace/rootfs_override/wr/etc/ppsi-config-pool/WR_MASTER
+96
-0
ppsi-custom.conf
userspace/rootfs_override/wr/etc/ppsi-custom.conf
+96
-0
sfp_database.conf
userspace/rootfs_override/wr/etc/sfp_database.conf
+0
-22
wrsw_hal.conf
userspace/rootfs_override/wr/etc/wrsw_hal.conf
+0
-158
.gitignore
userspace/tools/.gitignore
+1
-0
Makefile
userspace/tools/Makefile
+2
-1
wrs_checkcfg.c
userspace/tools/wrs_checkcfg.c
+58
-0
wrs_dump_shmem.c
userspace/tools/wrs_dump_shmem.c
+4
-2
Makefile
userspace/wrsw_hal/Makefile
+2
-2
hal_config.c
userspace/wrsw_hal/hal_config.c
+0
-182
hal_main.c
userspace/wrsw_hal/hal_main.c
+6
-30
hal_ports.c
userspace/wrsw_hal/hal_ports.c
+124
-133
hal_timing.c
userspace/wrsw_hal/hal_timing.c
+17
-23
No files found.
Kconfig
View file @
e78838e8
...
...
@@ -145,3 +145,224 @@ config KEEP_ROOTFS
If unsusre, say N.
endmenu
menu "Port Timing Configuration"
config PORT00_PARAMS
string "Parameters for the first port"
default "name=wr0,tx=0,rx=160000,role=slave,fiber=0"
help
This item, and the following ones, are used to assign the
constant delays (likely from calibration), port roles and
type of fiber for each of the ports. Please refer to the
user manual for more information.
config PORT01_PARAMS
string "Parameters for the second port"
default "name=wr1,tx=0,rx=160000,role=slave,fiber=0"
config PORT02_PARAMS
string "Parameters for a further port"
default "name=wr2,tx=0,rx=160000,role=master,fiber=0"
config PORT03_PARAMS
string "Parameters for a further port"
default "name=wr3,tx=0,rx=160000,role=master,fiber=0"
config PORT04_PARAMS
string "Parameters for a further port"
default "name=wr4,tx=0,rx=161200,role=master,fiber=0"
config PORT05_PARAMS
string "Parameters for a further port"
default "name=wr5,tx=0,rx=161200,role=master,fiber=0"
config PORT06_PARAMS
string "Parameters for a further port"
default "name=wr6,tx=0,rx=161200,role=master,fiber=0"
config PORT07_PARAMS
string "Parameters for a further port"
default "name=wr7,tx=0,rx=161200,role=master,fiber=0"
config PORT08_PARAMS
string "Parameters for a further port"
default "name=wr8,tx=0,rx=161200,role=master,fiber=0"
config PORT09_PARAMS
string "Parameters for a further port"
default "name=wr9,tx=0,rx=161200,role=master,fiber=0"
config PORT10_PARAMS
string "Parameters for a further port"
default "name=wr10,tx=0,rx=161200,role=master,fiber=0"
config PORT11_PARAMS
string "Parameters for a further port"
default "name=wr11,tx=0,rx=161200,role=master,fiber=0"
config PORT12_PARAMS
string "Parameters for a further port"
default "name=wr12,tx=0,rx=161200,role=master,fiber=0"
config PORT13_PARAMS
string "Parameters for a further port"
default "name=wr13,tx=0,rx=161200,role=master,fiber=0"
config PORT14_PARAMS
string "Parameters for a further port"
default "name=wr14,tx=0,rx=161200,role=master,fiber=0"
config PORT15_PARAMS
string "Parameters for a further port"
default "name=wr15,tx=0,rx=161200,role=master,fiber=0"
config PORT16_PARAMS
string "Parameters for a further port"
default "name=wr16,tx=0,rx=161200,role=master,fiber=0"
config PORT17_PARAMS
string "Parameters for a further port"
default "name=wr17,tx=0,rx=161200,role=master,fiber=0"
endmenu
menu "SFP and Media Timing Configuration"
config SFP00_PARAMS
string "Parameters for one SFP device type"
default "name=AXGE-1254-0531,tx=10,rx=10,wl_txrx=1310+1490"
help
This parameter, and the following ones, are used to
configure the timing parameters of a specific SFP
tranceiver. The tranceiver name is autodected for each port
in the White Rabbit Switch, and you need one configuration
entry for each tranceiver type that is installed in your
device.
config SFP01_PARAMS
string "Parameters for one SFP device type"
default "name=AXGE-3454-0531,tx=10,rx=10,wl_txrx=1490+1310"
config SFP02_PARAMS
string "Parameters for one SFP device type"
config SFP03_PARAMS
string "Parameters for one SFP device type"
config SFP04_PARAMS
string "Parameters for one SFP device type"
config SFP05_PARAMS
string "Parameters for one SFP device type"
config SFP06_PARAMS
string "Parameters for one SFP device type"
config SFP07_PARAMS
string "Parameters for one SFP device type"
config SFP08_PARAMS
string "Parameters for one SFP device type"
config SFP09_PARAMS
string "Parameters for one SFP device type"
config FIBER00_PARAMS
string "Alpha parameters for fiber type 0"
default "alpha_1310_1490=2.6787e-04"
help
This parameter, and the following ones, specify the physical
features of your fiber type. You need to specify the alpha
value for each pair of wavelengths you are using. The index
("00" onwards) is used to match the port
(CONFIG_PORTxx_PARAMS) with one of several installed fiber
types.
config FIBER01_PARAMS
string "Alpha parameters for fiber type 1"
default "alpha_1310_1490=2.6787e-04"
config FIBER02_PARAMS
string "Alpha parameters for fiber type 2"
default "alpha_1310_1490=2.6787e-04"
config FIBER03_PARAMS
string "Alpha parameters for fiber type 3"
default "alpha_1310_1490=2.6787e-04"
endmenu
choice
prompt "Timing Mode"
default TIME_BC
config TIME_GM
bool "Grand-Master"
help
This options selects the White Rabbit Switch as a grandmaster,
i.e. it uses its input channels to track an Atomic or GPS and
claim to be a PTP authoritative source on the network.
config TIME_FM
bool "Free-Running Master"
help
The White Rabbit Switch pretends to be a master on his PTP
network, but it doesn't sync to an external source. Its own
internal clocks and counters are used to drive timing.
config TIME_BC
bool "Boundary Clock"
help
The White Rabbit Switch is a normal PTP Boundary Clock: it is
slave on one of its ports and master on the other ones, according
to the standard Best Master Clock algorithm.
endchoice
choice
prompt "PTP Port Assignment"
default PTP_WR_DEFAULT if TIME_BC
default PTP_WR_MASTER
config PTP_WR_DEFAULT
bool "Raw Ethernet, WR on, Slave on wr0/wr1, Master on other ports"
help
You can choose between one from a set of predefined
configuration files from your PTP server running in the
switch, or define your own custom configuration file.
The default setting for boundary clock forces ports wr0 and
wr1 to be PTP slaves and all other ports to be master, in
Ethernet mode and with full WR protocol extensions. The default
for a Grand-Master or Free-Running master has all ports as
master ports.
Other predefined choices select more flexible configuration used
mainly for test purposes. Any special need can be addressed by
providing your own ppsi.conf file, that you should copy
to your switch.
config PTP_WR_MASTER
bool "Raw Ethernet, WR on, Master on all ports"
config PTP_WR_AUTO
bool "Raw Ethernet, WR on, Auto master/slave on all ports"
config PTP_WR_AUTO_UDP
bool "UDP mode, WR on, Auto master/slave on all ports"
config PTP_NONWR_UDP_ALL
bool "UDP mode, No WR, all ports (including eth0)"
config PTP_CUSTOM
bool "Custom ppsi.conf"
endchoice
config PTP_CUSTOM_FILENAME
string "Pathname for your custom ppsi.conf"
depends on PTP_CUSTOM
default "/wr/etc/ppsi-custom.conf"
build/scripts/wrs_build_wraprootfs
View file @
e78838e8
...
...
@@ -34,6 +34,7 @@ cat > $TMPSCRIPT << EOF
.
$WRS_BASE_DIR
/../.config
mkdir -p
$TMPFS
/wr/etc
cp
$WRS_BASE_DIR
/../.config
$TMPFS
/wr/etc/dot-config
cp
$WRS_BASE_DIR
/../Kconfig
$TMPFS
/wr/etc/Kconfig
cp -r
$rootfs_vanilla
/*
$TMPFS
cp -r
$WRS_OUTPUT_DIR
/images/wr/*
$TMPFS
/wr
...
...
doc/wrs-todo.in
View file @
e78838e8
...
...
@@ -35,7 +35,7 @@
@setchapternewpage off
@set update-month
Nov
ember 2014
@set update-month
Dec
ember 2014
@c the release name below is substituted at build time
@set release
__
RELEASE
_
GIT
_
ID
__
...
...
@@ -210,14 +210,8 @@ public in an exported library. The library code rusted over the years,
and we can't trust it any more without some clean up. I'm personally
scared every time I look in that code base.
@item The @i
{
mini-ipc
}
mechanism is showing its limits. We are communicating
too much information, and the polling mechanism used in some processes
introduces significant delays. Most of the communication is just
about reporting status, so this should be brought to a shared-memory
area with a well-defined structure. Again, this allows simulation and
development off-switch, with fault injection.
@item Whenever @i
{
ipc
}
is used for actions, rather than just status passing,
which is now shmem-based,
we should audit the processes to ensure the are based on @i
{
select
}
rather than a timely poll. Actually, the HAL process is using quite
a lot of cpu time, and it could do much better.
...
...
@@ -227,14 +221,21 @@ interface with gateware is now simpler than it was, but software still
has remnants of old data structure. Also, the multi-threaded approach
is overkill, and the program could benefit from a simplification.
@item We need to sort out configuration files. I especially plan to
get rid of @i
{
lua
}
; it is only used to set internal variables in the @i
{
lua
}
data structures, that are then queried. This means if you set an unused
item (e.g. because of a typo or some old wishful-thinking documents) it won't
have any effect and it will report no error. The best action may be move
all configurations to the PPSi config file -- the delays and all the rest
are PTP-specific anyways, and PPSi supports per-architecture configuration
items.
@item The SFP code needs to be cleaned up. There is unsafe string
management in 16-wide non-terminated fields, and we don't really
report all the information we have (we should copy to shmem so to
get it out, at least). Also, using the device name without the vendor
name is unsafe: some vendors use generic device names.
@item The @t
{
TRACE
}
support it not really working. We have serious
warning messages that were never reported. We should really print
everything to stderr and let syslog manage it (according to user
configuration: this is already in dot-config).
@item Default values, when configuration is missing, are badly chosen.
For example, @i
{
alpha
}
is always positive for an unknown SFP, but we
should rather have zero (or a positive/negative thing according the
the wavelength, if known).
@end itemize
...
...
doc/wrs-user-manual.in
View file @
e78838e8
...
...
@@ -476,8 +476,161 @@ value is changed by the web interface, proper action is taken.
unknown facility names will generate a runtime error on the switch.
All three strings default to ``@t
{
daemon.info
}
''.
@item CONFIG
_
PORT00
_
PARAMS
@itemx CONFIG
_
PORT01
_
PARAMS
@itemx ...
@itemx CONFIG
_
PORT17
_
PARAMS
These configuration items are used to set up port parameters;
this includes the delays, the PTP role (not currently used,
though) and the fiber type as an integer index. Most likely
the default values work for you. See @ref
{
Timing Configuration
}
for details.
@item CONFIG
_
SFP00
_
PARAMS
@itemx ...
@itemx CONFIG
_
SFP09
_
PARAMS
Configuration for @sc
{
sfp
}
models. You should fill values for
all @sc
{
sfp
}
models you are using in your @sc
{
wrs
}
and all
wavelengths you are using. See @ref
{
Timing Configuration
}
for details.
@item CONFIG
_
FIBER00
_
PARAMS
@itemx ...
@itemx CONFIG
_
FIBER03
_
PARAMS
Configuration for fiber types. You are expected to have no more
than 4 fiber types installed in your deployment (if more, you need
to add items to the @i
{
dot-config
}
file). See @ref
{
Timing
Configuration
}
for details.
@item CONFIG
_
TIME
_
GM
@itemx CONFIG
_
TIME
_
FM
@itemx CONFIG
_
TIME
_
BC
The type of PTP clock this switch is. Only one of the three
items should be set (running ``@t
{
make menuconfig
}
'' offers
them as an exclusive choice). The options select a grand-master
with external reference, from GPS or Cesium or both; a free-running
master, used for isolated acquisition networks, withouth an
external reference; or a normal ``boundary-clock'' device that
is slave on some ports and master on other ports.
@item CONFIG
_
PTP
_
*
We support a set of PPSi configuration files, for different PTP
roles. The default option being selected by @i
{
Kconfig
}
is
@t
{
PTP
_
WR
_
DEFAULT
}
for @t
{
TIME
_
BC
}
devices and @t
{
PTP
_
WR
_
MASTER
}
for @t
{
GM
}
and @t
{
FM
}
devices. The former configuration selects
a mandated slave PTP role on ports @t
{
wr0
}
and @t
{
wr1
}
, and
mandated master on all other ports; the latter conifiguration
is master on all ports. Please see the help provided within
@i
{
Kconfig
}
for more details about the various options we support.
@item CONFIG
_
PTP
_
CUSTOM
_
FILENAME
If you chose @t
{
CONFIG
_
PTP
_
CUSTOM
}
in the choice above, you
can provide your own filename for the PPSi configuration file;
the chosen name is expected to be intalled in the @sc
{
wrs
}
filesystem.
@end table
@c ==========================================================================
@node Timing Configuration
@section Timing Configuration
This section describes how timing configuration works in the switch.
Please note that up to version 4.1 (included) of @t
{
wr-switch-sw
}
things
were different and not really documented.
Timing configuration now depends on three sets of @i
{
dot-config
}
variables: per-port information, per-sfp information and fiber
description.
This is, for explanation's sake, an example of such items:
@smallexample
CONFIG
_
PORT09
_
PARAMS="name=wr9,tx=226214,rx=226758,role=slave,fiber=2"
CONFIG
_
SFP00
_
PARAMS="name=AXGE-1254-0531,tx=0,rx=0,wl
_
txrx=1310+1490"
CONFIG
_
FIBER02
_
PARAMS="alpha
_
1310
_
1490=2.6787e-04"
@end smallexample
When making timing calculation for port @t
{
wr9
}
, assuming the
auto-detected @sc
{
sfp
}
model is``AXGE-1254-0531'', the software
uses configuration in the following way:
@itemize @bullet
@item The port has known tx and rx delays (around 226ns); the
values depend on trace length and other hardware-specific details
and are determined by a calibration procedure. These values are
used as constant delays in the @i
{
tx
}
and @i
{
rx
}
directions.
@item The port is also configured as slave (information not used
at this point) and is deployed using fiber type 2 -- this number
is just a local enumeration of fiber types; most likely you'll be
using type ``0'' in every port.
@item The transceiver installed uses 1310nm light for tx
and 1490nm light for rx (this is part of the specification of the
transceiver, but cannot be auto-detected). Moreover it has 0 constant
delay in both tx and rx, determined by calibration.
@item The fiber type being used (type 2 here), when driven
with 1310nm and 1490nm wavelengths, features an @i
{
alpha
}
parameter of
0.00026787 (i.e. a ratio of 1.00026787) between the speed of light in
the two directions. This value depends on both the fiber type and
wavelength, and is determined, again, by calibration.
@end itemize
Please note that only one alpha value is provided, because the
opposite one (@t
{
alpha
_
1490
_
1310
}
) is calculated by software.
@subheading Other Deployments
The example above matches the choices we make at CERN, where our
White Rabbit networks are all run with a single monomodal fiber
and 1310/1490 light.
If you are using dual-fiber transceivers, which is acceptable for
short links, you use the same wavelength in both direction, over two
fibers of the same length. In this case you may choose to avoid
writing the @t
{
wl
_
txrx
}
parameter in @sc
{
sfp
}
configuration and the
@t
{
alpha
_
XX
_
XX
}
parameter in fiber configuration. The missing
parameters will cause warning messages on the console, but are not
fatal, and a default alpha of 0 is used.
If you are using a pair of transceivers with different wavelengths,
and long fibers, you should provide an appropriate value of alpha,
according to laboratory measures on your fiber type. The
@t
{
CONFIG
_
FIBERxx
_
PARAMS
}
items are parsed as a list of
comma-separated assignments, so you can specify and number of
wavelength pairs. The accuracy of your value depends on the length
of the fiber link. For a 10km fiber (100us round-trip) you need to know
alpha up to 1e-7 if you want the related uncertainty to be
less than 10ps.
@subheading Calibration
Calibration of per-port and per-@sc
{
sfp
}
delays is described in the
White Rabbit wiki:
@url
{
http://www.ohwr.org/projects/white-rabbit/wiki/Calibration
}
. The
procedure can measure the total constant delays, but splitting between
the what depends on the port and what depends on the transceiver is
arbitrary (also, the split between the tx and rx paths is arbitrary).
The delays used in this example come from values listed in the above
web page, and you should not be surprised by the fact that the
transceiver specifies the delays as zero. By performing the
calibration procedure using this very transceiver type, the hardware
engineers decided to assign the whole of the delay to the port (any
split of the measured value is equally right). Other transceiver
types can be calibrated to either positive or negative values, to cope
with the @i
{
difference
}
between them and the @t
{
AXGE
}
devices.
@c ############################################################################
@node Booting with Barebox
@chapter Booting with Barebox
...
...
userspace/libwr/Makefile
View file @
e78838e8
OBJS
=
trace.o init.o fpga_io.o util.o pps_gen.o i2c.o shw_io.o i2c_bitbang.o
\
i2c_fpga_reg.o pio.o libshw_i2c.o i2c_sfp.o fan.o i2c_io.o hwiu.o
\
ptpd_netif.o hal_client.o
\
shmem.o hal_shmem.o rt_client.o
shmem.o hal_shmem.o rt_client.o
\
dot-config.o
LIB
=
libwr.a
...
...
userspace/libwr/dot-config.c
0 → 100644
View file @
e78838e8
/* Alessandro Rubini for CERN, 2014 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <libwr/config.h>
/* All strings here are strdup'd and then split; you can't free(3) them */
struct
cfg_item
{
char
*
name
;
char
*
value
;
struct
cfg_item
*
subcfg
;
struct
cfg_item
*
next
;
};
static
struct
cfg_item
*
libwr_cfg
;
static
int
libwr_subcfg
(
struct
cfg_item
*
c
)
{
struct
cfg_item
*
subc
;
c
->
subcfg
=
NULL
;
char
*
rest
,
*
s
;
if
(
!
strchr
(
c
->
value
,
'='
))
return
0
;
/* Very lazily, strdup this again, and then modify in place */
rest
=
strdup
(
c
->
value
);
if
(
!
rest
)
return
-
1
;
do
{
subc
=
calloc
(
1
,
sizeof
(
*
c
));
if
(
!
subc
)
return
-
1
;
subc
->
name
=
rest
;
/* Trim this and save trailing text */
s
=
strchr
(
rest
,
','
);
if
(
s
)
{
rest
=
s
+
1
;
*
s
=
'\0'
;
}
else
{
rest
=
NULL
;
}
/* split between name and value */
s
=
strchr
(
subc
->
name
,
'='
);
if
(
s
)
{
subc
->
value
=
s
+
1
;
*
s
=
'\0'
;
}
/* store and continue, if more is there */
subc
->
next
=
c
->
subcfg
;
c
->
subcfg
=
subc
;
}
while
(
rest
);
return
0
;
}
/* Parse a line into name=value and subcfg. Assume dot-config format */
static
int
libwr_cfg_line
(
char
*
line
)
{
struct
cfg_item
*
c
;
char
name
[
512
],
value
[
512
];
if
(
line
[
0
]
==
'#'
)
return
0
;
if
(
strlen
(
line
)
<
2
)
return
0
;
if
(
sscanf
(
line
,
"CONFIG_%[^=]=%[^
\n
]"
,
name
,
value
)
!=
2
)
{
errno
=
EINVAL
;
return
-
1
;
}
c
=
malloc
(
sizeof
(
*
c
));
if
(
!
c
)
return
-
1
;
c
->
subcfg
=
NULL
;
c
->
name
=
strdup
(
name
);
c
->
value
=
strdup
(
value
);
if
(
!
c
->
name
||
!
c
->
value
)
return
-
1
;
/* Strip quotes */
if
(
c
->
value
[
0
]
==
'"'
)
c
->
value
++
;
if
(
c
->
value
[
strlen
(
c
->
value
)
-
1
]
==
'"'
)
c
->
value
[
strlen
(
c
->
value
)
-
1
]
=
'\0'
;
libwr_subcfg
(
c
);
c
->
next
=
libwr_cfg
;
libwr_cfg
=
c
;
return
0
;
}
int
libwr_cfg_read_file
(
char
*
dotconfig
)
{
char
s
[
512
];
FILE
*
f
;
int
lineno
=
0
;
f
=
fopen
(
dotconfig
,
"r"
);
if
(
!
f
)
return
-
1
;
while
(
fgets
(
s
,
sizeof
(
s
),
f
))
{
lineno
++
;
if
(
libwr_cfg_line
(
s
)
<
0
)
return
-
lineno
;
}
fclose
(
f
);
return
0
;
}
int
libwr_cfg_dump
(
FILE
*
output
)
{
struct
cfg_item
*
c
=
libwr_cfg
;
struct
cfg_item
*
subc
=
libwr_cfg
;
while
(
c
)
{
fprintf
(
output
,
"name=
\"
%s
\"\n
value=
\"
%s
\"\n
"
,
c
->
name
,
c
->
value
);
subc
=
c
->
subcfg
;
while
(
subc
)
{
fprintf
(
output
,
" name=
\"
%s
\"\n
"
" value=
\"
%s
\"\n
"
,
subc
->
name
,
subc
->
value
);
subc
=
subc
->
next
;
}
c
=
c
->
next
;
}
return
0
;
}
int
libwr_cfg_read_verify_file
(
char
*
dotconfig
,
char
*
kconfig
)
{
FILE
*
f
;
int
errors
=
0
;
char
s
[
256
],
name
[
256
];
struct
cfg_item
*
c
;
struct
kc
{
char
*
name
;
struct
kc
*
next
;
}
*
all_configs
=
NULL
,
*
kc
,
*
next
;
if
(
libwr_cfg_read_file
(
dotconfig
))
return
-
1
;
/* Read Kconfig and store all config names */
f
=
fopen
(
kconfig
,
"r"
);
if
(
!
f
)
return
-
1
;
while
(
fgets
(
s
,
sizeof
(
s
),
f
))
{
if
(
sscanf
(
s
,
"config %s"
,
name
)
!=
1
)
continue
;
kc
=
malloc
(
sizeof
(
*
kc
));
if
(
!
kc
)
return
-
1
;
kc
->
name
=
strdup
(
name
);
kc
->
next
=
all_configs
;
all_configs
=
kc
;
}
fclose
(
f
);
/* Verify all configs, complain if missing */
for
(
c
=
libwr_cfg
;
c
;
c
=
c
->
next
)
{
for
(
kc
=
all_configs
;
kc
;
kc
=
kc
->
next
)
if
(
!
strcmp
(
c
->
name
,
kc
->
name
))
break
;
if
(
!
kc
)
{
fprintf
(
stderr
,
"Configuration
\"
%s
\"
not found
\n
"
,
c
->
name
);
errors
++
;
}
}
/* Free all kconfig allocs */
for
(
kc
=
all_configs
;
kc
;
kc
=
next
)
{
next
=
kc
->
next
;
free
(
kc
->
name
);
free
(
kc
);
}
if
(
errors
)
{
errno
=
EINVAL
;
return
-
1
;
}
return
0
;
}
char
*
libwr_cfg_get
(
char
*
cfgname
)
{
struct
cfg_item
*
c
;
for
(
c
=
libwr_cfg
;
c
;
c
=
c
->
next
)
if
(
!
strcmp
(
cfgname
,
c
->
name
))
return
c
->
value
;
return
NULL
;
}
char
*
libwr_cfg_get2
(
char
*
cfgname
,
char
*
subname
)
{
struct
cfg_item
*
c
,
*
subc
;
for
(
c
=
libwr_cfg
;
c
;
c
=
c
->
next
)
if
(
!
strcmp
(
cfgname
,
c
->
name
))
{
for
(
subc
=
c
->
subcfg
;
subc
;
subc
=
subc
->
next
)
if
(
!
strcmp
(
subname
,
subc
->
name
))
return
subc
->
value
;
}
return
NULL
;
}
int
libwr_cfg_convert2
(
char
*
cfgname
,
char
*
subname
,
enum
libwr_convert
conv
,
void
*
ret
,
...)
{
double
*
dptr
=
ret
;
int
*
iptr
=
ret
;
char
real_cfgname
[
128
];
char
*
value
;
va_list
args
;
char
ch
;
va_start
(
args
,
ret
);
vsprintf
(
real_cfgname
,
cfgname
,
args
);
va_end
(
args
);
value
=
libwr_cfg_get2
(
real_cfgname
,
subname
);
if
(
!
value
)
{
errno
=
ENOENT
;
return
-
1
;
}
errno
=
EINVAL
;
switch
(
conv
)
{
case
LIBWR_INT
:
if
(
sscanf
(
value
,
"%i%c"
,
iptr
,
&
ch
)
!=
1
)
return
-
1
;
return
0
;
case
LIBWR_STRING
:
strcpy
(
ret
,
value
);
return
0
;
case
LIBWR_DOUBLE
:
if
(
sscanf
(
value
,
"%lf%c"
,
dptr
,
&
ch
)
!=
1
)
return
-
1
;
return
0
;
}
return
-
1
;
/* never */
}
userspace/libwr/i2c_sfp.c
View file @
e78838e8
...
...
@@ -9,13 +9,10 @@
#include <unistd.h>
#include <errno.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <libwr/pio.h>
#include <libwr/trace.h>
#include <libwr/util.h>
#include <libwr/config.h>
#include "i2c.h"
#include "i2c_sfp.h"
...
...
@@ -547,70 +544,64 @@ int shw_sfp_read_verify_header(int num, struct shw_sfp_header *head)
static
struct
shw_sfp_caldata
*
shw_sfp_cal_list
=
NULL
;
int
shw_sfp_read_db
(
char
*
filename
)
/* local helper */
static
void
__err_msg
(
int
index
,
char
*
pname
,
char
*
pvalue
)
{
lua_State
*
L
=
luaL_newstate
();
struct
shw_sfp_caldata
*
sfp
;
luaL_openlibs
(
L
);
if
(
luaL_loadfile
(
L
,
filename
)
||
lua_pcall
(
L
,
0
,
0
,
0
))
{
printf
(
"cannot run configuration file: %s"
,
lua_tostring
(
L
,
-
1
));
return
-
1
;
}
fprintf
(
stderr
,
"Config item
\"
SFP%02i_PARAMS
\"
: parameter
\"
%s
\"
"
,
index
,
pname
);
if
(
pvalue
)
fprintf
(
stderr
,
"is wrong (
\"
%s
\"
)
\n
"
,
pvalue
);
else
fprintf
(
stderr
,
"is not specified
\n
"
);
}
lua_getglobal
(
L
,
"sfpdb"
);
if
(
!
lua_istable
(
L
,
-
1
))
{
printf
(
"`sfpdb' should be a table
\n
"
);
return
-
1
;
}
lua_pushnil
(
L
);
while
(
lua_next
(
L
,
-
2
))
{
if
(
!
lua_istable
(
L
,
-
1
))
{
lua_pop
(
L
,
1
);
continue
;
int
shw_sfp_read_db
(
void
)
{
struct
shw_sfp_caldata
*
sfp
;
char
s
[
128
];
int
error
,
val
,
index
;
for
(
index
=
0
;
;
index
++
)
{
error
=
libwr_cfg_convert2
(
"SFP%02i_PARAMS"
,
"name"
,
LIBWR_STRING
,
s
,
index
);
if
(
error
)
return
0
;
/* no more, no error */
sfp
=
calloc
(
1
,
sizeof
(
*
sfp
));
strncpy
(
sfp
->
part_num
,
s
,
sizeof
(
sfp
->
part_num
));
sfp
->
vendor_serial
[
0
]
=
0
;
sfp
->
flags
=
SFP_FLAG_CLASS_DATA
;
/* never used */
/* These are uint32_t as I write this. So use "int val" */
val
=
0
;
error
=
libwr_cfg_convert2
(
"SFP%02i_PARAMS"
,
"tx"
,
LIBWR_INT
,
&
val
,
index
);
if
(
error
)
__err_msg
(
index
,
"tx"
,
NULL
);
sfp
->
delta_tx
=
val
;
val
=
0
;
error
=
libwr_cfg_convert2
(
"SFP%02i_PARAMS"
,
"rx"
,
LIBWR_INT
,
&
val
,
index
);
if
(
error
)
__err_msg
(
index
,
"rx"
,
NULL
);
sfp
->
delta_rx
=
val
;
/* We also store the wavelength, used to get alpha */
error
=
libwr_cfg_convert2
(
"SFP%02i_PARAMS"
,
"wl_txrx"
,
LIBWR_STRING
,
&
s
,
index
);
if
(
error
)
__err_msg
(
index
,
"wl_txrx"
,
NULL
);
if
(
sscanf
(
s
,
"%i+%i"
,
&
sfp
->
tx_wl
,
&
sfp
->
rx_wl
)
!=
2
)
{
sfp
->
tx_wl
=
0
;
__err_msg
(
index
,
"wl_txrx"
,
s
);
}
const
char
*
sfp_pn
=
0
;
const
char
*
sfp_vs
=
0
;
int
vals
[
2
]
=
{
0
,
0
};
double
alpha
=
0
;
lua_pushnil
(
L
);
while
(
lua_next
(
L
,
-
2
))
{
const
char
*
key
=
lua_tostring
(
L
,
-
2
);
if
(
strcmp
(
key
,
"part_num"
)
==
0
)
sfp_pn
=
lua_tostring
(
L
,
-
1
);
else
if
(
strcmp
(
key
,
"part_serial"
)
==
0
)
sfp_vs
=
lua_tostring
(
L
,
-
1
);
else
if
(
strcmp
(
key
,
"alpha"
)
==
0
)
alpha
=
lua_tonumber
(
L
,
-
1
);
else
if
(
strcmp
(
key
,
"delta_tx"
)
==
0
)
vals
[
0
]
=
lua_tointeger
(
L
,
-
1
);
else
if
(
strcmp
(
key
,
"delta_rx"
)
==
0
)
vals
[
1
]
=
lua_tointeger
(
L
,
-
1
);
lua_pop
(
L
,
1
);
}
lua_pop
(
L
,
1
);
sfp
=
malloc
(
sizeof
(
struct
shw_sfp_caldata
));
strncpy
(
sfp
->
part_num
,
sfp_pn
,
sizeof
(
sfp
->
part_num
));
if
(
!
sfp_vs
||
strcmp
(
sfp_vs
,
""
)
==
0
)
{
sfp
->
vendor_serial
[
0
]
=
0
;
sfp
->
flags
|=
SFP_FLAG_CLASS_DATA
;
}
else
{
strcpy
(
sfp
->
vendor_serial
,
sfp_vs
);
sfp
->
flags
|=
SFP_FLAG_DEVICE_DATA
;
}
sfp
->
alpha
=
alpha
;
sfp
->
delta_tx
=
vals
[
0
];
sfp
->
delta_rx
=
vals
[
1
];
/* Alpha is filled later, per-port, in hal_port_insert_sfp() */
/* link and continue */
sfp
->
next
=
shw_sfp_cal_list
;
shw_sfp_cal_list
=
sfp
;
}
lua_pop
(
L
,
1
);
lua_close
(
L
);
return
0
;
}
...
...
userspace/libwr/include/libwr/config.h
0 → 100644
View file @
e78838e8
#ifndef __LIBWR_CONFIG_H__
#define __LIBWR_CONFIG_H__
/* Read a dot-config file, return 0 or -line, the unparsable line in file */
int
libwr_cfg_read_file
(
char
*
dotconfig
);
/* Diagnostic tool */
int
libwr_cfg_dump
(
FILE
*
output
);
/* Read a dot-config, verifying with Kconfig to complain for wrong names */
int
libwr_cfg_read_verify_file
(
char
*
dotconfig
,
char
*
kconfig
);
/* cfg_get() works for CONFIG_NTP_SERVER. Returns NULL or static storage. */
char
*
libwr_cfg_get
(
char
*
cfgname
);
/* cfg_get2(), as above but with suboptions like "name=AXGE-3454-0531". */
char
*
libwr_cfg_get2
(
char
*
cfgname
,
char
*
subname
);
/* We only convert the following types */
enum
libwr_convert
{
LIBWR_INT
,
LIBWR_STRING
,
LIBWR_DOUBLE
,
};
/*
* The following is the most flexible one: subname can be NULL,
* and the cfgname is a printf-format string (e.g. "PORT%02i_PARAMS");
* finally, the value is sscanf'd in the library, with error check.
* Returns 0 or -1 with errno set to EINVAL.
*/
int
libwr_cfg_convert2
(
char
*
cfgname
,
char
*
subname
,
enum
libwr_convert
,
void
*
ret
,
...)
__attribute__
((
format
(
printf
,
1
,
5
)));
#endif
/* __LIBWR_CONFIG_H__ */
userspace/libwr/include/libwr/hal_shmem.h
View file @
e78838e8
...
...
@@ -71,8 +71,8 @@ struct hal_port_state {
/* port FSM state (HAL_PORT_STATE_xxxx) */
int
state
;
/*
unused
*/
int
index
;
/*
fiber type, used to get alpha for SFP frequency
*/
int
fiber_
index
;
/* 1: PLL is locked to this port */
int
locked
;
...
...
@@ -92,7 +92,7 @@ struct hal_port_state {
};
/* This is the overall structure stored in shared memory */
#define HAL_SHMEM_VERSION
1
#define HAL_SHMEM_VERSION
2
/* Version 2 because sfp calib changed */
struct
hal_shmem_header
{
int
nports
;
struct
hal_port_state
*
ports
;
...
...
userspace/libwr/include/libwr/sfp_lib.h
View file @
e78838e8
...
...
@@ -23,12 +23,21 @@
struct
shw_sfp_caldata
{
int
flags
;
char
part_num
[
16
];
/* part number of device as found in DB */
/*
* Part number used to identify it. Serial number because we
* may specify per-specimen delays, but it is not used at this
* point in time
*/
char
part_num
[
16
];
char
vendor_serial
[
16
];
/* Callibration data */
double
alpha
;
uint32_t
delta_tx
;
uint32_t
delta_rx
;
/* wavelengths, used to get alpha from fiber type */
int
tx_wl
;
int
rx_wl
;
/* and link as a list */
struct
shw_sfp_caldata
*
next
;
};
...
...
@@ -87,8 +96,8 @@ static inline void shw_sfp_set_generic(int num, int status, int type)
shw_sfp_gpio_set
(
num
,
state
);
}
/* Load the db from
a file
*/
int
shw_sfp_read_db
(
char
*
filename
);
/* Load the db from
dot-config to internal structures
*/
int
shw_sfp_read_db
(
void
);
/* Read and verify the header all at once. returns -1 on failure */
int
shw_sfp_read_verify_header
(
int
num
,
struct
shw_sfp_header
*
head
);
...
...
ppsi
@
12bd4376
Subproject commit
f49685ec07132da80b8aec32a2d50d143d23e13d
Subproject commit
12bd4376a1eed963eed143cda3e140cc55cb7ccb
userspace/rootfs_override/etc/init.d/S20dot-config
View file @
e78838e8
...
...
@@ -45,12 +45,15 @@ if [ -n "$CONFIG_DOTCONF_URL" ]; then
echo
"Invalid URL for dot-config:
\"
$URL
\"
"
>
& 2
;;
esac
# If it exists
and it is not empty or awfully small, trust it
# If it exists
, it is not empty or too small, and the checker is happy..
if
[
-f
$tmpconfig
]
&&
[
$(
cat
$tmpconfig
|
wc
-c
)
-gt
200
]
;
then
[
$(
cat
$tmpconfig
|
wc
-c
)
-gt
200
]
&&
/wr/bin/wrs_checkcfg
$tmpconfig
/wr/etc/Kconfig
;
then
echo
"Using newly-downloaded dot-config from
$URL
"
# copy it in place to use the new file (unless it is identical)
cmp
-s
$tmpconfig
$dotconfig
||
cp
$tmpconfig
$dotconfig
fi
fi
# Finally, apply what we have, be it old or new
.
/wr/bin/apply_dot-config
/wr/bin/apply_dot-config
userspace/rootfs_override/wr/bin/apply_dot-config
View file @
e78838e8
...
...
@@ -75,3 +75,13 @@ set | tr -d \' | grep CONFIG_WRS_LOG | sed 's/=/ /' | while read varname value;
done
copy_conf /wr/sbin/start-daemons.sh
# Select a ppsi configuration file
for
n
in
/wr/etc/ppsi-conf-pool/
*
;
do
cfg
=
CONFIG_PTP_
$(
basename
$n
)
if
[
"
$cfg
"
=
"y"
]
;
then
cp
$n
/wr/etc/ppsi.conf
fi
done
if
[
"
$CONFIG_PTP_CUSTOM
"
=
"y"
]
;
then
cp
"
$CONFIG_PTP_CUSTOM_FILENAME
"
/wr/etc/ppsi.conf
fi
\ No newline at end of file
userspace/rootfs_override/wr/etc/ppsi-config-pool/NONWR_UDP_ALL
0 → 100644
View file @
e78838e8
# Autoselection of port mode, including eth0 (both raw and udp, for variety)
# Global settings
clock-class 187
clock-accuracy 254
port eth-udp
proto udp
iface eth0
role auto
extension none
port eth-raw
proto raw
iface eth0
role auto
extension none
port wr0
proto udp
iface wr0
role auto
extension none
port wr1
proto udp
iface wr1
role auto
extension none
port wr2
proto udp
iface wr2
role auto
extension none
port wr3
proto udp
iface wr3
role auto
extension none
port wr4
proto udp
iface wr4
role auto
extension none
port wr5
proto udp
iface wr5
role auto
extension none
port wr6
proto udp
iface wr6
role auto
extension none
port wr7
proto udp
iface wr7
role auto
extension none
port wr8
proto udp
iface wr8
role auto
extension none
port wr9
proto udp
iface wr9
role auto
extension none
port wr10
proto udp
iface wr10
role auto
extension none
port wr11
proto udp
iface wr11
role auto
extension none
port wr12
proto udp
iface wr12
role auto
extension none
port wr13
proto udp
iface wr13
role auto
extension none
port wr14
proto udp
iface wr14
role auto
extension none
port wr15
proto udp
iface wr15
role auto
extension none
port wr16
proto udp
iface wr16
role auto
extension none
port wr17
proto udp
iface wr17
role auto
extension none
userspace/rootfs_override/wr/etc/ppsi-config-pool/WR_AUTO
0 → 100644
View file @
e78838e8
# Autoselection of port modepgrandmasters
# Global settings
clock-class 187
clock-accuracy 254
port wr0
iface wr0
role auto
extension whiterabbit
port wr1
iface wr1
role auto
extension whiterabbit
port wr2
iface wr2
role auto
extension whiterabbit
port wr3
iface wr3
role auto
extension whiterabbit
port wr4
iface wr4
role auto
extension whiterabbit
port wr5
iface wr5
role auto
extension whiterabbit
port wr6
iface wr6
role auto
extension whiterabbit
port wr7
iface wr7
role auto
extension whiterabbit
port wr8
iface wr8
role auto
extension whiterabbit
port wr9
iface wr9
role auto
extension whiterabbit
port wr10
iface wr10
role auto
extension whiterabbit
port wr11
iface wr11
role auto
extension whiterabbit
port wr12
iface wr12
role auto
extension whiterabbit
port wr13
iface wr13
role auto
extension whiterabbit
port wr14
iface wr14
role auto
extension whiterabbit
port wr15
iface wr15
role auto
extension whiterabbit
port wr16
iface wr16
role auto
extension whiterabbit
port wr17
iface wr17
role auto
extension whiterabbit
userspace/rootfs_override/wr/etc/ppsi-config-pool/WR_AUTO_UDP
0 → 100644
View file @
e78838e8
# Autoselection of port mode
# Global settings
clock-class 187
clock-accuracy 254
port wr0
proto udp
iface wr0
role auto
extension whiterabbit
port wr1
proto udp
iface wr1
role auto
extension whiterabbit
port wr2
proto udp
iface wr2
role auto
extension whiterabbit
port wr3
proto udp
iface wr3
role auto
extension whiterabbit
port wr4
proto udp
iface wr4
role auto
extension whiterabbit
port wr5
proto udp
iface wr5
role auto
extension whiterabbit
port wr6
proto udp
iface wr6
role auto
extension whiterabbit
port wr7
proto udp
iface wr7
role auto
extension whiterabbit
port wr8
proto udp
iface wr8
role auto
extension whiterabbit
port wr9
proto udp
iface wr9
role auto
extension whiterabbit
port wr10
proto udp
iface wr10
role auto
extension whiterabbit
port wr11
proto udp
iface wr11
role auto
extension whiterabbit
port wr12
proto udp
iface wr12
role auto
extension whiterabbit
port wr13
proto udp
iface wr13
role auto
extension whiterabbit
port wr14
proto udp
iface wr14
role auto
extension whiterabbit
port wr15
proto udp
iface wr15
role auto
extension whiterabbit
port wr16
proto udp
iface wr16
role auto
extension whiterabbit
port wr17
proto udp
iface wr17
role auto
extension whiterabbit
userspace/rootfs_override/wr/etc/ppsi-config-pool/WR_DEFAULT
0 → 100644
View file @
e78838e8
# Default for boundary clocks
# Global settings
clock-class 187
clock-accuracy 254
port slave0
iface wr0
role slave
extension whiterabbit
port slave1
iface wr1
role slave
extension whiterabbit
port master2
iface wr2
role master
extension whiterabbit
port master3
iface wr3
role master
extension whiterabbit
port master4
iface wr4
role master
extension whiterabbit
port master5
iface wr5
role master
extension whiterabbit
port master6
iface wr6
role master
extension whiterabbit
port master7
iface wr7
role master
extension whiterabbit
port master8
iface wr8
role master
extension whiterabbit
port master9
iface wr9
role master
extension whiterabbit
port master10
iface wr10
role master
extension whiterabbit
port master11
iface wr11
role master
extension whiterabbit
port master12
iface wr12
role master
extension whiterabbit
port master13
iface wr13
role master
extension whiterabbit
port master14
iface wr14
role master
extension whiterabbit
port master15
iface wr15
role master
extension whiterabbit
port master16
iface wr16
role master
extension whiterabbit
port master17
iface wr17
role master
extension whiterabbit
userspace/rootfs_override/wr/etc/ppsi-config-pool/WR_MASTER
0 → 100644
View file @
e78838e8
# Default for grandmasters
# Global settings
clock-class 187
clock-accuracy 254
port master0
iface wr0
role master
extension whiterabbit
port master1
iface wr1
role master
extension whiterabbit
port master2
iface wr2
role master
extension whiterabbit
port master3
iface wr3
role master
extension whiterabbit
port master4
iface wr4
role master
extension whiterabbit
port master5
iface wr5
role master
extension whiterabbit
port master6
iface wr6
role master
extension whiterabbit
port master7
iface wr7
role master
extension whiterabbit
port master8
iface wr8
role master
extension whiterabbit
port master9
iface wr9
role master
extension whiterabbit
port master10
iface wr10
role master
extension whiterabbit
port master11
iface wr11
role master
extension whiterabbit
port master12
iface wr12
role master
extension whiterabbit
port master13
iface wr13
role master
extension whiterabbit
port master14
iface wr14
role master
extension whiterabbit
port master15
iface wr15
role master
extension whiterabbit
port master16
iface wr16
role master
extension whiterabbit
port master17
iface wr17
role master
extension whiterabbit
userspace/rootfs_override/wr/etc/ppsi-custom.conf
0 → 100644
View file @
e78838e8
# Autoselection of port modepgrandmasters
# Global settings
clock
-
class
187
clock
-
accuracy
254
port
wr0
iface
wr0
role
auto
extension
whiterabbit
port
wr1
iface
wr1
role
auto
extension
whiterabbit
port
wr2
iface
wr2
role
auto
extension
whiterabbit
port
wr3
iface
wr3
role
auto
extension
whiterabbit
port
wr4
iface
wr4
role
auto
extension
whiterabbit
port
wr5
iface
wr5
role
auto
extension
whiterabbit
port
wr6
iface
wr6
role
auto
extension
whiterabbit
port
wr7
iface
wr7
role
auto
extension
whiterabbit
port
wr8
iface
wr8
role
auto
extension
whiterabbit
port
wr9
iface
wr9
role
auto
extension
whiterabbit
port
wr10
iface
wr10
role
auto
extension
whiterabbit
port
wr11
iface
wr11
role
auto
extension
whiterabbit
port
wr12
iface
wr12
role
auto
extension
whiterabbit
port
wr13
iface
wr13
role
auto
extension
whiterabbit
port
wr14
iface
wr14
role
auto
extension
whiterabbit
port
wr15
iface
wr15
role
auto
extension
whiterabbit
port
wr16
iface
wr16
role
auto
extension
whiterabbit
port
wr17
iface
wr17
role
auto
extension
whiterabbit
userspace/rootfs_override/wr/etc/sfp_database.conf
deleted
100644 → 0
View file @
57dbe28f
--
The
VENDOR_SERIAL
field
can
be
set
to
an
empty
string
to
provide
class
-
level
--
information
as
opposed
to
device
-
level
information
.
sfpdb
= {
{
part_num
=
"AXGE-1254-0531"
,
alpha
=
2
.
67871791665542
e
-
04
,
delta_tx
=
10
,
delta_rx
=
10
},
{
part_num
=
"AXGE-3454-0531"
,
alpha
= -
2
.
67800055584799
e
-
04
,
delta_tx
=
10
,
delta_rx
=
10
},
}
userspace/rootfs_override/wr/etc/wrsw_hal.conf
deleted
100644 → 0
View file @
57dbe28f
global
= {
sfp_database_path
=
"/wr/etc/sfp_database.conf"
;
};
timing
= {
pps_width
=
100000
; --
PPS
pulse
width
--
use_nmea
=
1
; --
take
UTC
seconds
from
NMEA
GPS
clock
connected
to
/
dev
/
ttyS2
--
mode
=
"GrandMaster"
; --
grand
-
master
with
external
reference
};
ports
= {
wr0
= {
phy_rx_min
=
160000
; --
minimal
RX
latency
introduced
by
the
PHY
(
in
picoseconds
)
phy_tx_min
=
0
;
mac_addr
=
"auto"
;
mode
=
"wr_slave"
;
};
wr1
= {
phy_rx_min
=
160000
; --
minimal
RX
latency
introduced
by
the
PHY
(
in
picoseconds
)
phy_tx_min
=
0
;
mac_addr
=
"auto"
;
mode
=
"wr_master"
;
};
wr2
= {
phy_rx_min
=
160000
; --
minimal
RX
latency
introduced
by
the
PHY
(
in
picoseconds
)
phy_tx_min
=
0
;
mac_addr
=
"auto"
;
mode
=
"wr_master"
;
};
wr3
= {
phy_rx_min
=
160000
; --
minimal
RX
latency
introduced
by
the
PHY
(
in
picoseconds
)
phy_tx_min
=
0
;
mac_addr
=
"auto"
;
mode
=
"wr_master"
;
};
wr4
= {
phy_rx_min
=
161200
; --
minimal
RX
latency
introduced
by
the
PHY
(
in
picoseconds
)
phy_tx_min
=
0
;
mac_addr
=
"auto"
;
mode
=
"wr_master"
;
};
wr5
= {
phy_rx_min
=
161200
; --
minimal
RX
latency
introduced
by
the
PHY
(
in
picoseconds
)
phy_tx_min
=
0
;
mac_addr
=
"auto"
;
mode
=
"wr_master"
;
};
wr6
= {
phy_rx_min
=
161200
; --
minimal
RX
latency
introduced
by
the
PHY
(
in
picoseconds
)
phy_tx_min
=
0
;
mac_addr
=
"auto"
;
mode
=
"wr_master"
;
};
wr7
= {
phy_rx_min
=
161200
; --
minimal
RX
latency
introduced
by
the
PHY
(
in
picoseconds
)
phy_tx_min
=
0
;
mac_addr
=
"auto"
;
mode
=
"wr_master"
;
};
wr8
= {
phy_rx_min
=
161200
; --
minimal
RX
latency
introduced
by
the
PHY
(
in
picoseconds
)
phy_tx_min
=
0
;
mac_addr
=
"auto"
;
mode
=
"wr_master"
;
};
wr9
= {
phy_rx_min
=
161200
; --
minimal
RX
latency
introduced
by
the
PHY
(
in
picoseconds
)
phy_tx_min
=
0
;
mac_addr
=
"auto"
;
mode
=
"wr_master"
;
};
wr10
= {
phy_rx_min
=
161200
; --
minimal
RX
latency
introduced
by
the
PHY
(
in
picoseconds
)
phy_tx_min
=
0
;
mac_addr
=
"auto"
;
mode
=
"wr_master"
;
};
wr11
= {
phy_rx_min
=
161200
; --
minimal
RX
latency
introduced
by
the
PHY
(
in
picoseconds
)
phy_tx_min
=
0
;
mac_addr
=
"auto"
;
mode
=
"wr_master"
;
};
wr12
= {
phy_rx_min
=
161200
; --
minimal
RX
latency
introduced
by
the
PHY
(
in
picoseconds
)
phy_tx_min
=
0
;
mac_addr
=
"auto"
;
mode
=
"wr_master"
;
};
wr13
= {
phy_rx_min
=
161200
; --
minimal
RX
latency
introduced
by
the
PHY
(
in
picoseconds
)
phy_tx_min
=
0
;
mac_addr
=
"auto"
;
mode
=
"wr_master"
;
};
wr14
= {
phy_rx_min
=
161200
; --
minimal
RX
latency
introduced
by
the
PHY
(
in
picoseconds
)
phy_tx_min
=
0
;
mac_addr
=
"auto"
;
mode
=
"wr_master"
;
};
wr15
= {
phy_rx_min
=
161200
; --
minimal
RX
latency
introduced
by
the
PHY
(
in
picoseconds
)
phy_tx_min
=
0
;
mac_addr
=
"auto"
;
mode
=
"wr_master"
;
};
wr16
= {
phy_rx_min
=
161200
; --
minimal
RX
latency
introduced
by
the
PHY
(
in
picoseconds
)
phy_tx_min
=
0
;
mac_addr
=
"auto"
;
mode
=
"wr_master"
;
};
wr17
= {
phy_rx_min
=
161200
; --
minimal
RX
latency
introduced
by
the
PHY
(
in
picoseconds
)
phy_tx_min
=
0
;
mac_addr
=
"auto"
;
mode
=
"wr_master"
;
};
};
userspace/tools/.gitignore
View file @
e78838e8
...
...
@@ -19,3 +19,4 @@ wrs_dump_shmem
sdb-read
nbtee
wrs_auxclk
wrs_checkcfg
userspace/tools/Makefile
View file @
e78838e8
...
...
@@ -5,6 +5,7 @@ TOOLS += wrs_vlans wrs_dump_shmem
TOOLS
+=
sdb-read
TOOLS
+=
nbtee
TOOLS
+=
wrs_auxclk
TOOLS
+=
wrs_checkcfg
WR_INSTALL_ROOT
?=
/usr/lib/white-rabbit
...
...
@@ -44,7 +45,7 @@ endif
LDFLAGS
=
-L
../mini-rpc
\
-L
../libwr
\
-L
../libsdb
\
-lwr
-lminipc
-lsdbfs
-l
lua
-l
m
-ldl
-lwr
-lminipc
-lsdbfs
-lm
-ldl
all
:
$(TOOLS)
...
...
userspace/tools/wrs_checkcfg.c
0 → 100644
View file @
e78838e8
/* Alessandro Rubini for CERN, 2014 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <libwr/config.h>
int
main
(
int
argc
,
char
**
argv
)
{
int
err
,
verbose
=
0
;
me_lazy:
if
(
argc
<
2
||
!
strcmp
(
argv
[
1
],
"-h"
)
||
!
strcmp
(
argv
[
1
],
"--help"
))
{
fprintf
(
stderr
,
"%s: Use:
\"
%s [-v] <dotcfg> [<Kconfig>]
\"\n
"
,
argv
[
0
],
argv
[
0
]);
exit
(
1
);
}
if
(
!
strcmp
(
argv
[
1
],
"-v"
))
{
verbose
++
;
argv
++
;
argc
--
;
goto
me_lazy
;
}
if
(
access
(
argv
[
1
],
R_OK
)
<
0
)
{
fprintf
(
stderr
,
"%s: %s: %s
\n
"
,
argv
[
0
],
argv
[
1
],
strerror
(
errno
));
exit
(
1
);
}
if
(
argc
==
2
)
{
err
=
libwr_cfg_read_file
(
argv
[
1
]);
if
(
err
)
{
fprintf
(
stderr
,
"%s: Error in %s:%i: %s
\n
"
,
argv
[
0
],
argv
[
1
],
-
err
,
strerror
(
errno
));
exit
(
1
);
}
if
(
verbose
)
libwr_cfg_dump
(
stdout
);
exit
(
0
);
}
if
(
access
(
argv
[
2
],
R_OK
)
<
0
)
{
fprintf
(
stderr
,
"%s: %s: %s
\n
"
,
argv
[
0
],
argv
[
2
],
strerror
(
errno
));
exit
(
1
);
}
err
=
libwr_cfg_read_verify_file
(
argv
[
1
],
argv
[
2
]);
if
(
verbose
)
libwr_cfg_dump
(
stdout
);
if
(
err
)
exit
(
1
);
/* messages already printed */
exit
(
0
);
return
0
;
}
userspace/tools/wrs_dump_shmem.c
View file @
e78838e8
...
...
@@ -188,7 +188,7 @@ struct dump_info hal_port_info [] = {
DUMP_FIELD
(
int
,
hw_addr_auto
),
DUMP_FIELD
(
int
,
mode
),
DUMP_FIELD
(
int
,
state
),
DUMP_FIELD
(
int
,
index
),
DUMP_FIELD
(
int
,
fiber_
index
),
DUMP_FIELD
(
int
,
locked
),
/* these fields are defined as uint32_t but we prefer %i to %x */
DUMP_FIELD
(
int
,
calib
.
phy_rx_min
),
...
...
@@ -207,7 +207,9 @@ struct dump_info hal_port_info [] = {
DUMP_FIELD
(
double
,
calib
.
sfp
.
alpha
),
DUMP_FIELD
(
uint32_t
,
calib
.
sfp
.
delta_tx
),
DUMP_FIELD
(
uint32_t
,
calib
.
sfp
.
delta_rx
),
DUMP_FIELD
(
pointer
,
calib
.
sfp
.
next
),
DUMP_FIELD
(
int
,
calib
.
sfp
.
tx_wl
),
DUMP_FIELD
(
int
,
calib
.
sfp
.
rx_wl
),
DUMP_FIELD
(
pointer
,
calib
.
sfp
.
next
),
DUMP_FIELD
(
uint32_t
,
phase_val
),
DUMP_FIELD
(
int
,
phase_val_valid
),
...
...
userspace/wrsw_hal/Makefile
View file @
e78838e8
OBJS
=
hal_exports.o hal_main.o hal_ports.o hal_
config.o hal_
timing.o
OBJS
=
hal_exports.o hal_main.o hal_ports.o hal_timing.o
BINARY
=
wrsw_hal
...
...
@@ -27,7 +27,7 @@ ifdef WRS_HAL_DEBUG
endif
LDFLAGS
=
-L
../libwr
-L
../mini-rpc
\
-lminipc
-l
lua
-l
m
-ldl
-lwr
-lminipc
-lm
-ldl
-lwr
all
:
$(BINARY)
...
...
userspace/wrsw_hal/hal_config.c
deleted
100644 → 0
View file @
57dbe28f
/* Wrapper code for handling Lua configuration files */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <libwr/trace.h>
#define HAL_CONFIG_FILE "/wr/etc/wrsw_hal.conf"
static
lua_State
*
cfg_file
=
NULL
;
static
char
*
extra_cmdline
=
NULL
;
static
char
*
hal_config_file
=
HAL_CONFIG_FILE
;
/* Sets the path to the HAL config file */
void
hal_config_set_config_file
(
const
char
*
str
)
{
hal_config_file
=
strdup
(
str
);
}
/* Appends extra Lua code to the contents of the configuration file to
be parsed. Can be used to execute inline config given as a command
line parameter. */
int
hal_config_extra_cmdline
(
const
char
*
str
)
{
extra_cmdline
=
strdup
(
str
);
return
0
;
}
/* Parses the HAL configuration file */
int
hal_parse_config
()
{
int
ret
;
TRACE
(
TRACE_INFO
,
"Parsing wrsw_hal configuration file: %s"
,
HAL_CONFIG_FILE
);
cfg_file
=
lua_open
();
luaL_openlibs
(
cfg_file
);
/* Just execute the config file as a regular Lua script. The
contents of the file will be ordinary Lua variables
accessible via lua_State. */
ret
=
luaL_dofile
(
cfg_file
,
hal_config_file
);
/* Declare a Lua "helper" function for regexp searching global
variables - it's much easier to implement in Lua than in
plain C. */
ret
|=
luaL_dostring
(
cfg_file
,
"\
function get_var(name) \
local t = _G \
for w in name:gmatch(
\"
([%w_]+)
\\
.?
\"
) do \
t = t[w] \
end \
return t \
end"
);
/* Execute extra code from the command line */
if
(
extra_cmdline
)
ret
|=
luaL_dostring
(
cfg_file
,
extra_cmdline
);
if
(
ret
)
{
TRACE
(
TRACE_ERROR
,
"Error parsing the configuration file: %s"
,
lua_tostring
(
cfg_file
,
-
1
));
return
-
1
;
}
return
0
;
}
/* Looks up for a global variable (name). If it's found, it is pushed
on the Lua stack and the function returns 0, otherwise a negative
error code is returned. */
static
int
global_get_var
(
const
char
*
name
)
{
lua_getglobal
(
cfg_file
,
"get_var"
);
lua_pushstring
(
cfg_file
,
name
);
if
(
lua_pcall
(
cfg_file
,
1
,
1
,
0
)
!=
0
)
return
-
1
;
return
0
;
}
/* Retreives an integer variable (name) and stores it at
(value). Returns 0 on success, -1 if the variable was not found or
has invalid format. */
int
hal_config_get_int
(
const
char
*
name
,
int
*
value
)
{
if
(
global_get_var
(
name
)
<
0
)
return
-
1
;
if
(
!
lua_isnumber
(
cfg_file
,
-
1
))
return
-
1
;
*
value
=
(
int
)
lua_tonumber
(
cfg_file
,
-
1
);
return
0
;
}
/* Same as above, but for double floating point numbers. */
int
hal_config_get_double
(
const
char
*
name
,
double
*
value
)
{
if
(
global_get_var
(
name
)
<
0
)
return
-
1
;
if
(
!
lua_isnumber
(
cfg_file
,
-
1
))
return
-
1
;
*
value
=
(
double
)
lua_tonumber
(
cfg_file
,
-
1
);
return
0
;
}
/* Same as above, but for null-terminated strings */
int
hal_config_get_string
(
const
char
*
name
,
char
*
value
,
int
max_len
)
{
if
(
global_get_var
(
name
)
<
0
)
return
-
1
;
if
(
!
lua_isstring
(
cfg_file
,
-
1
))
return
-
1
;
strncpy
(
value
,
lua_tostring
(
cfg_file
,
-
1
),
max_len
);
return
0
;
}
/* Iterates a particular section (section) in the config file for its
* subsections. For a file containing:
ports = {
wru0 = {
...
};
wr1 = {
...
};
wr2 = {
...
};
};
calling hal_config_iterate("ports", 0, sub, strlen(sub)) will
return 1 and sub == "wr0",
calling hal_config_iterate("ports", 1, sub, strlen(sub)) will
return 1 and sub == "wr1",
hal_config_iterate("ports", 3, sub, strlen(sub)) will return 0, as
there will be no more subsections in the "ports" section.
*/
int
hal_config_iterate
(
const
char
*
section
,
int
index
,
char
*
subsection
,
int
max_len
)
{
int
i
=
0
;
if
(
global_get_var
(
section
)
<
0
)
return
-
1
;
lua_pushnil
(
cfg_file
);
/* first key */
while
(
lua_next
(
cfg_file
,
-
2
)
!=
0
)
{
/* uses 'key' (at index -2) and 'value' (at index -1) */
char
*
key_type
=
(
char
*
)
lua_typename
(
cfg_file
,
lua_type
(
cfg_file
,
-
1
));
if
(
!
strcmp
(
key_type
,
"table"
)
&&
i
==
index
)
{
strncpy
(
subsection
,
lua_tostring
(
cfg_file
,
-
2
),
max_len
);
return
1
;
}
else
if
(
!
strcmp
(
key_type
,
"string"
)
&&
i
==
index
)
{
strncpy
(
subsection
,
lua_tostring
(
cfg_file
,
-
1
),
max_len
);
return
1
;
}
i
++
;
/* removes 'value'; keeps 'key' for next iteration */
lua_pop
(
cfg_file
,
1
);
}
return
0
;
}
userspace/wrsw_hal/hal_main.c
View file @
e78838e8
...
...
@@ -14,6 +14,7 @@
#include <libwr/switch_hw.h>
#include <libwr/shw_io.h>
#include <libwr/sfp_lib.h>
#include <libwr/config.h>
#include "wrsw_hal.h"
#include <rt_ipc.h>
...
...
@@ -72,14 +73,15 @@ static void hal_deamonize();
/* Main initialization function */
static
int
hal_init
()
{
char
sfp_db_path
[
1024
];
//trace_log_stderr();
TRACE
(
TRACE_INFO
,
"HAL initializing..."
);
memset
(
cleanup_cb
,
0
,
sizeof
(
cleanup_cb
));
libwr_cfg_read_file
(
"/wr/etc/dot-config"
);
/* FIXME: accept -f */
shw_sfp_read_db
();
/* Set up trap for some signals - the main purpose is to
prevent the hardware from working when the HAL is shut down
- launching the HAL on already initialized HW will freeze
...
...
@@ -89,19 +91,6 @@ static int hal_init()
signal
(
SIGTERM
,
sighandler
);
signal
(
SIGILL
,
sighandler
);
assert_init
(
hal_parse_config
());
if
(
!
hal_config_get_string
(
"global.sfp_database_path"
,
sfp_db_path
,
sizeof
(
sfp_db_path
)))
{
if
(
shw_sfp_read_db
(
sfp_db_path
)
<
0
)
{
TRACE
(
TRACE_ERROR
,
"Can't read SFP database (%s)"
,
sfp_db_path
);
}
else
{
TRACE
(
TRACE_INFO
,
"Loaded SFP database (%s)"
,
sfp_db_path
);
}
}
/* Low-level hw init, init non-kernel drivers */
assert_init
(
shw_init
());
...
...
@@ -174,32 +163,19 @@ static void show_help()
{
printf
(
"WR Switch Hardware Abstraction Layer daemon (wrsw_hal)
\n
\
Usage: wrsw_hal [options], where [options] can be:
\n
\
-f : force FPGA firmware reload
\n
\
-d : fork into background (daemon mode)
\n
\
-x [code]: execute arbitrary Lua [code] before loading configuration file
\n
\
-c [file]: specify your own config file
\n\n
"
);
-d : fork into background (daemon mode)
\n
"
);
}
static
void
hal_parse_cmdline
(
int
argc
,
char
*
argv
[])
{
int
opt
;
while
((
opt
=
getopt
(
argc
,
argv
,
"d
fhx:c:
"
))
!=
-
1
)
{
while
((
opt
=
getopt
(
argc
,
argv
,
"d
h
"
))
!=
-
1
)
{
switch
(
opt
)
{
case
'd'
:
daemon_mode
=
1
;
break
;
case
'x'
:
hal_config_extra_cmdline
(
optarg
);
break
;
case
'c'
:
hal_config_set_config_file
(
optarg
);
break
;
// case 'f':
// shw_fpga_force_firmware_reload();
// break;
case
'h'
:
show_help
();
exit
(
0
);
...
...
userspace/wrsw_hal/hal_ports.c
View file @
e78838e8
This diff is collapsed.
Click to expand it.
userspace/wrsw_hal/hal_timing.c
View file @
e78838e8
...
...
@@ -7,6 +7,7 @@
#include <unistd.h>
#include <libwr/switch_hw.h>
#include <libwr/config.h>
#include "wrsw_hal.h"
#include "timeout.h"
...
...
@@ -20,8 +21,16 @@ static int timing_mode;
int
hal_init_timing
()
{
char
str
[
128
];
timeout_t
lock_tmo
;
static
struct
{
char
*
cfgname
;
int
modevalue
;
}
*
m
,
modes
[]
=
{
{
"TIME_GM"
,
HAL_TIMING_MODE_GRAND_MASTER
},
{
"TIME_FM"
,
HAL_TIMING_MODE_FREE_MASTER
},
{
"TIME_BC"
,
HAL_TIMING_MODE_BC
},
{
NULL
,
HAL_TIMING_MODE_BC
/* default */
},
};
if
(
rts_connect
()
<
0
)
{
TRACE
(
TRACE_ERROR
,
...
...
@@ -29,29 +38,14 @@ int hal_init_timing()
return
-
1
;
}
if
(
hal_config_get_string
(
"timing.mode"
,
str
,
sizeof
(
str
))
<
0
)
{
TRACE
(
TRACE_INFO
,
"Not timing mode specified in the config file. "
"Defaulting to Boundary Clock."
);
timing_mode
=
HAL_TIMING_MODE_BC
;
strcpy
(
str
,
"BoundaryClock"
);
}
else
{
if
(
!
strcasecmp
(
str
,
"GrandMaster"
)
||
!
strcasecmp
(
str
,
"GM"
))
timing_mode
=
HAL_TIMING_MODE_GRAND_MASTER
;
else
if
(
!
strcasecmp
(
str
,
"FreeMaster"
)
||
!
strcasecmp
(
str
,
"FM"
))
timing_mode
=
HAL_TIMING_MODE_FREE_MASTER
;
else
if
(
!
strcasecmp
(
str
,
"BoundaryClock"
)
||
!
strcasecmp
(
str
,
"BC"
))
timing_mode
=
HAL_TIMING_MODE_BC
;
else
{
TRACE
(
TRACE_ERROR
,
"Unrecognized timing mode '%s'"
,
str
);
return
-
1
;
}
}
for
(
m
=
modes
;
m
->
cfgname
;
m
++
)
if
(
libwr_cfg_get
(
m
->
cfgname
))
break
;
timing_mode
=
m
->
modevalue
;
TRACE
(
TRACE_INFO
,
"Timing mode: %s"
,
str
);
if
(
!
m
->
cfgname
)
fprintf
(
stderr
,
"%s: no config variable set, defaults used
\n
"
,
__func__
);
/* initialize the RT Subsys */
switch
(
timing_mode
)
{
...
...
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