Commit 55309172 authored by hongming's avatar hongming

Merge tag 'wrpc-v4.2' into cute-core-demo-etherbone

LM32 software for WRPC release v4.2
parents 62d60bf4 566f213f
......@@ -5,7 +5,6 @@ mainmenu "WR PTP Core software configuration"
config WR_SWITCH
bool "Build rt_cpu.bin, for the WR-Switch FPGA"
default n
select UART
config WR_NODE
bool
......@@ -30,6 +29,13 @@ config TEMP_POLL_INTERVAL
int
default 15
config TEMP_HIGH_THRESHOLD
int
default 70
config TEMP_HIGH_RAPPEL
int
default 60
config PLL_VERBOSE
boolean
default y if WR_SWITCH
......@@ -96,11 +102,6 @@ config PPSI
boolean
default y
config UART
boolean
default y if EMBEDDED_NODE
default n
config W1
depends on EMBEDDED_NODE
boolean
......@@ -150,8 +151,20 @@ config SYSLOG
The user (or init script) must use "syslog <ipaddr> <macaddr>"
to enable it. The special "off" ipaddr disables syslog.
config PUTS_SYSLOG
depends on SYSLOG
boolean "Sent puts (i.e. printf) to syslog too"
help
This allows logging the various warning and error messages
that normally go to the console alone, where nobody is looking
in a deployed system. Output from interactive commands is
not sent to syslog, but self-timed diagnostic (stat, gui, verbose)
will reach syslog anyways, if an interactive user enables them.
Unfortunately, "stat" will reach syslog as several short strings,
and "gui" is full of escape sequences.
config SNMP
depends on IP
depends on IP && !HOST_PROCESS
default y
boolean "Mini SNMP responder"
......@@ -170,11 +183,6 @@ config SNMP_AUX_DIAG
help
This option adds branch wrpcAuxDiag to the SNMP
config SNMP_HW_TYPE
depends on SNMP
default "spec"
string "Hardware type reported by SNMP"
config BUILD_INIT
depends on WR_NODE
default n
......@@ -206,6 +214,7 @@ config FLASH_INIT
default n
config AUX_DIAG
depends on WR_NODE
default n
boolean "Add support for auxiliary diagnostics registers"
help
......@@ -220,12 +229,21 @@ config SDB_STORAGE
Use SDB to manage flash and eeproms (both W1 and I2C). If not, legacy code
(eeprom only) will be selected.
config GENSDBFS
depends on SDB_STORAGE
default y
boolean "Shell command for SDBFS generation"
help
This option adds _sdb fs_ command to write empty SDBFS filesystem
image in Flash/EEPROM.
config LEGACY_EEPROM
depends on WR_NODE
boolean
default !SDB_STORAGE
config VLAN
depends on WR_NODE
boolean "Filter and rx/tx frames in a VLAN (as opposed to untagged)"
config VLAN_NR
......@@ -244,8 +262,22 @@ config VLAN_FOR_CLASS6
depends on VLAN
int "Route this VLAN too to fabric class 6 (Streamer/NIC)"
config WR_NODE_SIM
config WR_DIAG
depends on WR_NODE
boolean "Write of WRPC diagnostics to dedicated WB registers"
default n
help
This is a software part of new (additional) diagnostics for WR PTP
Core. It allows to access diagnostics values through WB registers
(e.g. PCI bus). It allows the host machine (of SPEC/SVEC/etc.) to
easily access information about the health of WR PTP Core.
Please note that other option to access the status of WRPC, which
is direct access to the WRPC's memory does not provide any mechanism
to ensure the data consistency.
config WR_NODE_SIM
depends on WR_NODE && !HOST_PROCESS
boolean "Build simple software for test of WR PTP Core in simulation"
default n
help
......@@ -256,12 +288,32 @@ config WR_NODE_SIM
MAC address destination and expects the simulation to return
these frames.
config ABSCAL
depends on WR_NODE
default y
boolean "Support absolute calibration"
help
If you select this, you'll be able to do absolute calibration
using a loop-back SFP adapter, according to the procedure
described and documented by Peter Jansweijer.
config LLDP
depends on WR_NODE
boolean "Include LLDP protocol transmit-only"
default n
help
This enable LLDP support. LLDP is a vendor-neutral link layer protocol
used by network devices for advertising their identity, capabilities,
and neighbors on local area network.
#
# This is a set of configuration options that should not be changed by
# normal users. If the "developer" menu is used, the binary is tainted.
comment "wrpc-sw is tainted if you change the following options"
config DEVELOPER
depends on WR_NODE
bool "Advanced configurations, only for developers"
help
The following options are new features under testing, or
......@@ -270,7 +322,7 @@ config DEVELOPER
you are a developer of wrpc-sw.
config PPSI_FORCE_CONFIG
depends on DEVELOPER && WR_NODE
depends on DEVELOPER
bool "Reconfigure ppsi from wrpc-sw at every build"
default y
help
......@@ -280,11 +332,11 @@ config PPSI_FORCE_CONFIG
peer-to-peer here, the change is propagated to the ppsi build.
config HOST_PROCESS
depends on DEVELOPER && WR_NODE
depends on DEVELOPER
boolean "Build as a host process, to develop/debug network"
config RAMSIZE
depends on DEVELOPER && EMBEDDED_NODE
depends on DEVELOPER && LM32
int "Size of the RAM in the FPGA for this program"
default 90112
help
......@@ -294,7 +346,7 @@ config RAMSIZE
choose your preferred value here.
config STACKSIZE
depends on DEVELOPER && EMBEDDED_NODE
depends on DEVELOPER && LM32
int "Size of the stack area needed by this program"
default 2048
help
......@@ -303,7 +355,7 @@ config STACKSIZE
at run time. (However, we have a detector for overflows).
config PRINT_BUFSIZE
depends on DEVELOPER && WR_NODE
depends on DEVELOPER
int "Size for the temporary output string of pp_printf"
default 128
help
......@@ -312,21 +364,19 @@ config PRINT_BUFSIZE
in a single call to printf.
config TEMP_POLL_INTERVAL
depends on DEVELOPER && WR_NODE
depends on DEVELOPER
int "Poll interval, in seconds, for temperature sensors"
config TEMP_HIGH_THRESHOLD
depends on DEVELOPER && WR_NODE && SYSLOG
default 70
depends on DEVELOPER && SYSLOG
int "Threshold for temperature: tell syslog if higher"
config TEMP_HIGH_RAPPEL
depends on DEVELOPER && WR_NODE && SYSLOG
default 60
depends on DEVELOPER && SYSLOG
int "Remember over-temperature every that many seconds"
config CMD_LL
depends on DEVELOPER && EMBEDDED_NODE
depends on DEVELOPER && LM32
bool "Build low-level commands for development/testing"
help
This enables low-level commands: "devmem" to read/write memory
......@@ -335,14 +385,22 @@ config CMD_LL
on the master, because they are just sent to the slave
during the initial handshake
config FLASH_INIT
config DAC_LOG
depends on DEVELOPER && EMBEDDED_NODE
bool "Be able send DAC values through UDP"
help
If you want to see the dac output, input to the VCXO main
oscillator, enable this. You'll have a "daclog" shell command
to set ipaddress and mac of the target host. UDP port is 1050.
config FLASH_INIT
depends on DEVELOPER && LM32
default y
boolean "Read init commands from flash storage"
# CHECK_RESET for switch and node
config CHECK_RESET
depends on DEVELOPER && !HOST_PROCESS
depends on DEVELOPER && LM32 || WR_SWITCH
bool "Print a stack trace if reset happens"
help
If the CPU is following a NULL pointer, the program will
......@@ -351,7 +409,7 @@ config CHECK_RESET
then clears the stack (for next time) and restarts again.
config SPLL_FIFO_LOG
depends on DEVELOPER && !HOST_PROCESS
depends on DEVELOPER && LM32
bool "Add a circular buffer for spll logging, used by tools/wrpc-dump"
help
This option addrs 256 bytes to the wrpc bynary, to log
......@@ -361,7 +419,7 @@ config SPLL_FIFO_LOG
choice
prompt "Implementation of pp_printf"
depends on DEVELOPER && WR_NODE
depends on DEVELOPER
config PRINTF_IS_XINT
bool "hex-and-int"
......@@ -406,7 +464,7 @@ config ASSERT
with no Kconfig -- and it does the same, unconditionally.
config DETERMINISTIC_BINARY
depends on DEVELOPER && EMBEDDED_NODE
depends on DEVELOPER || WR_SWITCH
boolean "Build a binary that is the same every time"
help
This option is used to #ifdef __DATE__ and __TIME__ strings
......@@ -418,27 +476,8 @@ config DETERMINISTIC_BINARY
If in doubt, say No.
config UART
boolean "Use hardware uart (and/or vuart if available)"
depends on (DEVELOPER && EMBEDDED_NODE) || WR_SWITCH
help
This option selects the serial driver, connected to either
the USB socket, or "vuart" (software fifo) or both, according
to how the gateware is built.
config UART_SW
depends on DEVELOPER && EMBEDDED_NODE
default !UART
boolean "Use software uart"
help
The software uart is made up of two circular buffers. It can
be used either as an alternative to the harwdare UART or as
an addition. If the option is turned on, ppsi log messages
are routed to the software uart. The interactive wrpc shell
and diagnostics run on the hardware UART if available.
config NET_VERBOSE
depends on DEVELOPER && WR_NODE
depends on DEVELOPER
boolean "Extra verbose messages for networking"
help
This is mainly a debug tool, to be left off unless you hack
......@@ -458,7 +497,7 @@ config PFILTER_VERBOSE
A debug tool for people changing the packet filter rules
config WRC_VERBOSE
depends on DEVELOPER
depends on DEVELOPER || WR_SWITCH
boolean "More verbose messages in wr core"
default y if WR_SWITCH
help
......@@ -501,6 +540,18 @@ config LATENCY_SYSLOG
bool "Report latency problems to syslog"
default y
config DEFAULT_PRINT_TASK_TIME_THRESHOLD
depends on DEVELOPER
default 0
int "Default threshold of printing task execution time"
help
If a task executes longer than a given number, its name and
an execution time will be printed to the console. Additionally,
setting this value triggers printing messages if particular task
runs longer than ever before. Setting to 0 disabled this
functionality. This value can be changed in run-time by the command
"ps max <msecs>".
# This is needed to size the pp_instance data strucuture. Instead of
# including the ppsi autoconf.h, with duplicate definitions, define it
......
......@@ -8,6 +8,7 @@ ifdef CONFIG_HOST_PROCESS
endif
export CROSS_COMPILE
export CONFIG_ABSCAL
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld
......@@ -75,6 +76,10 @@ pfilter-y := rules-novlan.bin
pfilter-$(CONFIG_VLAN) += rules-vlan.bin
export pfilter-y
# sdbfs image
sdbfsimg-y := sdbfs-default.bin
export sdbfsimg-y
all:
include shell/shell.mk
......@@ -129,7 +134,7 @@ endif
all: tools $(OUTPUT).elf $(arch-files-y)
.PRECIOUS: %.elf %.bin
.PHONY: all tools clean gitmodules $(PPSI)/ppsi.o
.PHONY: all tools clean gitmodules $(PPSI)/ppsi.o extest liblinux
# we need to remove "ptpdump" support for ppsi if RAM size is small and
# we include etherbone
......@@ -139,8 +144,6 @@ ifneq ($(CONFIG_RAMSIZE),131072)
endif
endif
PPSI_USER_CFLAGS += -DDIAG_PUTS=uart_sw_write_string
PPSI-CFG-y = wrpc_defconfig
PPSI-CFG-$(CONFIG_P2P) = wrpc_pdelay_defconfig
PPSI-CFG-$(CONFIG_HOST_PROCESS) = unix_defconfig
......@@ -209,6 +212,8 @@ clean:
$(MAKE) -C $(PPSI) clean
$(MAKE) -C sdb-lib clean
$(MAKE) -C tools clean
$(MAKE) -C liblinux clean
$(MAKE) -C liblinux/extest clean
distclean: clean
rm -rf include/config
......@@ -219,9 +224,18 @@ distclean: clean
%.o: %.c
${CC} $(CFLAGS) $(PTPD_CFLAGS) $(INCLUDE_DIR) $(LIB_DIR) -c $*.c -o $@
tools: .config gitmodules
liblinux:
$(MAKE) -C liblinux
extest:
$(MAKE) -C liblinux/extest
tools: .config gitmodules liblinux extest
$(MAKE) -C tools
tools-diag: liblinux extest
$(MAKE) -C tools wrpc-diags wrpc-vuart wr-streamers
# if needed, check out the submodules (first time only), so users
# who didn't read carefully the manual won't get confused
gitmodules:
......
......@@ -8,6 +8,8 @@ CONFIG_PPSI_FORCE_CONFIG=y
CONFIG_PRINT_BUFSIZE=128
CONFIG_RAMSIZE=131072
CONFIG_TEMP_POLL_INTERVAL=15
CONFIG_TEMP_HIGH_THRESHOLD=70
CONFIG_TEMP_HIGH_RAPPEL=60
CONFIG_PLL_VERBOSE=y
CONFIG_PFILTER_VERBOSE=y
CONFIG_WRC_VERBOSE=y
......@@ -22,7 +24,6 @@ CONFIG_EMBEDDED_NODE=y
# CONFIG_WR_NODE_PCS16 is not set
CONFIG_STACKSIZE=2048
CONFIG_PPSI=y
CONFIG_UART=y
CONFIG_W1=y
CONFIG_LATENCY_ETHTYPE=4455
CONFIG_LATENCY_SYSLOG=y
......@@ -30,9 +31,9 @@ CONFIG_P2P=y
CONFIG_IP=y
CONFIG_CMD_CONFIG=y
CONFIG_SYSLOG=y
# CONFIG_PUTS_SYSLOG is not set
CONFIG_SNMP=y
CONFIG_SNMP_SET=y
CONFIG_SNMP_HW_TYPE="spec"
CONFIG_BUILD_INIT=y
CONFIG_INIT_COMMAND="help"
CONFIG_HAS_BUILD_INIT=1
......@@ -40,16 +41,18 @@ CONFIG_HAS_FLASH_INIT=1
CONFIG_FLASH_INIT=y
# CONFIG_AUX_DIAG is not set
CONFIG_SDB_STORAGE=y
CONFIG_GENSDBFS=y
# CONFIG_LEGACY_EEPROM is not set
# CONFIG_WR_DIAG is not set
# CONFIG_WR_NODE_SIM is not set
CONFIG_ABSCAL=y
#
# wrpc-sw is tainted if you change the following options
#
CONFIG_DEVELOPER=y
CONFIG_TEMP_HIGH_THRESHOLD=70
CONFIG_TEMP_HIGH_RAPPEL=60
CONFIG_CMD_LL=y
# CONFIG_DAC_LOG is not set
CONFIG_CHECK_RESET=y
CONFIG_SPLL_FIFO_LOG=y
CONFIG_PRINTF_IS_XINT=y
......@@ -58,13 +61,14 @@ CONFIG_PRINTF_IS_XINT=y
# CONFIG_PRINTF_IS_NONE is not set
CONFIG_ASSERT=y
CONFIG_DETERMINISTIC_BINARY=y
CONFIG_UART_SW=y
CONFIG_NET_VERBOSE=y
# CONFIG_SNMP_VERBOSE is not set
CONFIG_FAKE_TEMPERATURES=y
CONFIG_LATENCY_PROBE=y
CONFIG_DEFAULT_PRINT_TASK_TIME_THRESHOLD=0
CONFIG_VLAN_ARRAY_SIZE=1
CONFIG_PRINTF_XINT=y
# CONFIG_PRINTF_FULL is not set
# CONFIG_PRINTF_MINI is not set
# CONFIG_PRINTF_NONE is not set
# CONFIG_LLDP is not set
......@@ -8,6 +8,8 @@ CONFIG_PPSI_FORCE_CONFIG=y
CONFIG_PRINT_BUFSIZE=128
CONFIG_RAMSIZE=131072
CONFIG_TEMP_POLL_INTERVAL=15
CONFIG_TEMP_HIGH_THRESHOLD=70
CONFIG_TEMP_HIGH_RAPPEL=60
# CONFIG_PLL_VERBOSE is not set
# CONFIG_PFILTER_VERBOSE is not set
# CONFIG_WRC_VERBOSE is not set
......@@ -22,7 +24,6 @@ CONFIG_EMBEDDED_NODE=y
# CONFIG_WR_NODE_PCS16 is not set
CONFIG_STACKSIZE=10240
CONFIG_PPSI=y
CONFIG_UART=y
CONFIG_W1=y
CONFIG_LATENCY_ETHTYPE=291
CONFIG_LATENCY_SYSLOG=y
......@@ -30,6 +31,7 @@ CONFIG_LATENCY_SYSLOG=y
CONFIG_IP=y
CONFIG_CMD_CONFIG=y
CONFIG_SYSLOG=y
# CONFIG_PUTS_SYSLOG is not set
# CONFIG_SNMP is not set
# CONFIG_BUILD_INIT is not set
CONFIG_INIT_COMMAND=""
......@@ -38,16 +40,18 @@ CONFIG_HAS_FLASH_INIT=1
CONFIG_FLASH_INIT=y
# CONFIG_AUX_DIAG is not set
CONFIG_SDB_STORAGE=y
CONFIG_GENSDBFS=y
# CONFIG_LEGACY_EEPROM is not set
# CONFIG_WR_DIAG is not set
# CONFIG_WR_NODE_SIM is not set
CONFIG_ABSCAL=y
#
# wrpc-sw is tainted if you change the following options
#
CONFIG_DEVELOPER=y
CONFIG_TEMP_HIGH_THRESHOLD=70
CONFIG_TEMP_HIGH_RAPPEL=60
CONFIG_CMD_LL=y
# CONFIG_DAC_LOG is not set
CONFIG_CHECK_RESET=y
# CONFIG_SPLL_FIFO_LOG is not set
CONFIG_PRINTF_IS_XINT=y
......@@ -56,12 +60,13 @@ CONFIG_PRINTF_IS_XINT=y
# CONFIG_PRINTF_IS_NONE is not set
# CONFIG_ASSERT is not set
# CONFIG_DETERMINISTIC_BINARY is not set
# CONFIG_UART_SW is not set
# CONFIG_NET_VERBOSE is not set
# CONFIG_FAKE_TEMPERATURES is not set
CONFIG_LATENCY_PROBE=y
CONFIG_DEFAULT_PRINT_TASK_TIME_THRESHOLD=0
CONFIG_VLAN_ARRAY_SIZE=1
CONFIG_PRINTF_XINT=y
# CONFIG_PRINTF_FULL is not set
# CONFIG_PRINTF_MINI is not set
# CONFIG_PRINTF_NONE is not set
# CONFIG_LLDP is not set
......@@ -8,6 +8,8 @@ CONFIG_PPSI_FORCE_CONFIG=y
CONFIG_PRINT_BUFSIZE=128
CONFIG_RAMSIZE=131072
CONFIG_TEMP_POLL_INTERVAL=15
CONFIG_TEMP_HIGH_THRESHOLD=70
CONFIG_TEMP_HIGH_RAPPEL=60
# CONFIG_PLL_VERBOSE is not set
# CONFIG_PFILTER_VERBOSE is not set
# CONFIG_WRC_VERBOSE is not set
......@@ -22,7 +24,6 @@ CONFIG_EMBEDDED_NODE=y
# CONFIG_WR_NODE_PCS16 is not set
CONFIG_STACKSIZE=10240
CONFIG_PPSI=y
CONFIG_UART=y
CONFIG_W1=y
CONFIG_LATENCY_ETHTYPE=291
CONFIG_LATENCY_SYSLOG=y
......@@ -30,6 +31,7 @@ CONFIG_P2P=y
CONFIG_IP=y
CONFIG_CMD_CONFIG=y
CONFIG_SYSLOG=y
# CONFIG_PUTS_SYSLOG is not set
# CONFIG_SNMP is not set
# CONFIG_BUILD_INIT is not set
CONFIG_INIT_COMMAND=""
......@@ -38,16 +40,18 @@ CONFIG_HAS_FLASH_INIT=1
CONFIG_FLASH_INIT=y
# CONFIG_AUX_DIAG is not set
CONFIG_SDB_STORAGE=y
CONFIG_GENSDBFS=y
# CONFIG_LEGACY_EEPROM is not set
# CONFIG_WR_DIAG is not set
# CONFIG_WR_NODE_SIM is not set
CONFIG_ABSCAL=y
#
# wrpc-sw is tainted if you change the following options
#
CONFIG_DEVELOPER=y
CONFIG_TEMP_HIGH_THRESHOLD=70
CONFIG_TEMP_HIGH_RAPPEL=60
CONFIG_CMD_LL=y
# CONFIG_DAC_LOG is not set
CONFIG_CHECK_RESET=y
# CONFIG_SPLL_FIFO_LOG is not set
CONFIG_PRINTF_IS_XINT=y
......@@ -56,12 +60,13 @@ CONFIG_PRINTF_IS_XINT=y
# CONFIG_PRINTF_IS_NONE is not set
# CONFIG_ASSERT is not set
# CONFIG_DETERMINISTIC_BINARY is not set
# CONFIG_UART_SW is not set
# CONFIG_NET_VERBOSE is not set
# CONFIG_FAKE_TEMPERATURES is not set
CONFIG_LATENCY_PROBE=y
CONFIG_DEFAULT_PRINT_TASK_TIME_THRESHOLD=0
CONFIG_VLAN_ARRAY_SIZE=1
CONFIG_PRINTF_XINT=y
# CONFIG_PRINTF_FULL is not set
# CONFIG_PRINTF_MINI is not set
# CONFIG_PRINTF_NONE is not set
# CONFIG_LLDP is not set
......@@ -39,6 +39,7 @@ CONFIG_FLASH_INIT=y
# CONFIG_AUX_DIAG is not set
CONFIG_SDB_STORAGE=y
# CONFIG_LEGACY_EEPROM is not set
# CONFIG_WR_DIAG is not set
# CONFIG_WR_NODE_SIM is not set
#
......
......@@ -8,18 +8,19 @@ CONFIG_PPSI_FORCE_CONFIG=y
CONFIG_PRINT_BUFSIZE=128
CONFIG_RAMSIZE=131072
CONFIG_TEMP_POLL_INTERVAL=15
# CONFIG_VLAN is not set
CONFIG_VLAN_NR=0
CONFIG_VLAN_1_FOR_CLASS7=0
CONFIG_VLAN_2_FOR_CLASS7=0
CONFIG_VLAN_FOR_CLASS6=0
CONFIG_TEMP_HIGH_THRESHOLD=70
CONFIG_TEMP_HIGH_RAPPEL=60
CONFIG_VLAN=y
CONFIG_VLAN_NR=1
CONFIG_VLAN_1_FOR_CLASS7=10
CONFIG_VLAN_2_FOR_CLASS7=11
CONFIG_VLAN_FOR_CLASS6=20
# CONFIG_HOST_PROCESS is not set
CONFIG_LM32=y
CONFIG_EMBEDDED_NODE=y
# CONFIG_WR_NODE_PCS16 is not set
CONFIG_STACKSIZE=2048
CONFIG_PPSI=y
CONFIG_UART=y
CONFIG_W1=y
CONFIG_LATENCY_ETHTYPE=291
# CONFIG_P2P is not set
......@@ -29,16 +30,19 @@ CONFIG_IP=y
CONFIG_SNMP=y
CONFIG_SNMP_SET=y
CONFIG_SNMP_AUX_DIAG=y
CONFIG_SNMP_HW_TYPE="spec"
# CONFIG_BUILD_INIT is not set
CONFIG_INIT_COMMAND=""
CONFIG_HAS_BUILD_INIT=0
CONFIG_BUILD_INIT=y
CONFIG_INIT_COMMAND="vlan off;ptp stop;sfp match;mode slave;ptp start"
CONFIG_HAS_BUILD_INIT=1
CONFIG_HAS_FLASH_INIT=1
CONFIG_FLASH_INIT=y
CONFIG_AUX_DIAG=y
CONFIG_SDB_STORAGE=y
CONFIG_GENSDBFS=y
# CONFIG_LEGACY_EEPROM is not set
CONFIG_WR_DIAG=y
# CONFIG_WR_NODE_SIM is not set
CONFIG_ABSCAL=y
CONFIG_LLDP=y
#
# wrpc-sw is tainted if you change the following options
......
......@@ -8,32 +8,41 @@ CONFIG_PPSI_FORCE_CONFIG=y
CONFIG_PRINT_BUFSIZE=128
CONFIG_RAMSIZE=131072
CONFIG_TEMP_POLL_INTERVAL=15
# CONFIG_VLAN is not set
CONFIG_VLAN_NR=0
CONFIG_VLAN_1_FOR_CLASS7=0
CONFIG_VLAN_2_FOR_CLASS7=0
CONFIG_VLAN_FOR_CLASS6=0
CONFIG_TEMP_HIGH_THRESHOLD=70
CONFIG_TEMP_HIGH_RAPPEL=60
CONFIG_VLAN=y
CONFIG_VLAN_NR=1
CONFIG_VLAN_1_FOR_CLASS7=10
CONFIG_VLAN_2_FOR_CLASS7=11
CONFIG_VLAN_FOR_CLASS6=20
# CONFIG_HOST_PROCESS is not set
CONFIG_LM32=y
CONFIG_EMBEDDED_NODE=y
# CONFIG_WR_NODE_PCS16 is not set
CONFIG_STACKSIZE=2048
CONFIG_PPSI=y
CONFIG_UART=y
CONFIG_W1=y
CONFIG_LATENCY_ETHTYPE=291
CONFIG_P2P=y
# CONFIG_IP is not set
CONFIG_IP=y
# CONFIG_CMD_CONFIG is not set
# CONFIG_BUILD_INIT is not set
CONFIG_INIT_COMMAND=""
CONFIG_HAS_BUILD_INIT=0
# CONFIG_SYSLOG is not set
CONFIG_SNMP=y
CONFIG_SNMP_SET=y
CONFIG_SNMP_AUX_DIAG=y
CONFIG_BUILD_INIT=y
CONFIG_INIT_COMMAND="vlan off;ptp stop;sfp match;mode slave;ptp start"
CONFIG_HAS_BUILD_INIT=1
CONFIG_HAS_FLASH_INIT=1
CONFIG_FLASH_INIT=y
# CONFIG_AUX_DIAG is not set
CONFIG_AUX_DIAG=y
CONFIG_SDB_STORAGE=y
CONFIG_GENSDBFS=y
# CONFIG_LEGACY_EEPROM is not set
CONFIG_WR_DIAG=y
# CONFIG_WR_NODE_SIM is not set
CONFIG_ABSCAL=y
CONFIG_LLDP=y
#
# wrpc-sw is tainted if you change the following options
......
......@@ -8,9 +8,10 @@ CONFIG_PPSI_FORCE_CONFIG=y
CONFIG_PRINT_BUFSIZE=128
CONFIG_RAMSIZE=65536
CONFIG_TEMP_POLL_INTERVAL=15
CONFIG_TEMP_HIGH_THRESHOLD=70
CONFIG_TEMP_HIGH_RAPPEL=60
CONFIG_PLL_VERBOSE=y
CONFIG_WRC_VERBOSE=y
# CONFIG_VLAN is not set
CONFIG_VLAN_NR=0
CONFIG_VLAN_1_FOR_CLASS7=0
CONFIG_VLAN_2_FOR_CLASS7=0
......@@ -18,18 +19,17 @@ CONFIG_VLAN_FOR_CLASS6=0
# CONFIG_HOST_PROCESS is not set
CONFIG_LM32=y
# CONFIG_EMBEDDED_NODE is not set
CONFIG_UART=y
CONFIG_LATENCY_ETHTYPE=291
CONFIG_INIT_COMMAND=""
CONFIG_HAS_BUILD_INIT=0
CONFIG_HAS_FLASH_INIT=0
# CONFIG_FLASH_INIT is not set
# CONFIG_AUX_DIAG is not set
#
# wrpc-sw is tainted if you change the following options
#
# CONFIG_DEVELOPER is not set
# CONFIG_CHECK_RESET is not set
# CONFIG_DETERMINISTIC_BINARY is not set
CONFIG_VLAN_ARRAY_SIZE=1
CONFIG_PRINTF_XINT=y
# CONFIG_PRINTF_FULL is not set
......
......@@ -8,34 +8,39 @@ CONFIG_PPSI_FORCE_CONFIG=y
CONFIG_PRINT_BUFSIZE=128
CONFIG_RAMSIZE=131072
CONFIG_TEMP_POLL_INTERVAL=15
# CONFIG_VLAN is not set
CONFIG_VLAN_NR=0
CONFIG_VLAN_1_FOR_CLASS7=0
CONFIG_VLAN_2_FOR_CLASS7=0
CONFIG_VLAN_FOR_CLASS6=0
CONFIG_TEMP_HIGH_THRESHOLD=70
CONFIG_TEMP_HIGH_RAPPEL=60
CONFIG_VLAN=y
CONFIG_VLAN_NR=1
CONFIG_VLAN_1_FOR_CLASS7=10
CONFIG_VLAN_2_FOR_CLASS7=11
CONFIG_VLAN_FOR_CLASS6=20
# CONFIG_HOST_PROCESS is not set
CONFIG_LM32=y
CONFIG_EMBEDDED_NODE=y
# CONFIG_WR_NODE_PCS16 is not set
CONFIG_STACKSIZE=2048
CONFIG_PPSI=y
CONFIG_UART=y
CONFIG_W1=y
CONFIG_LATENCY_ETHTYPE=291
# CONFIG_P2P is not set
CONFIG_IP=y
# CONFIG_CMD_CONFIG is not set
# CONFIG_SYSLOG is not set
# CONFIG_SNMP is not set
# CONFIG_BUILD_INIT is not set
CONFIG_INIT_COMMAND=""
CONFIG_HAS_BUILD_INIT=0
CONFIG_SNMP=y
CONFIG_SNMP_SET=y
CONFIG_BUILD_INIT=y
CONFIG_INIT_COMMAND="vlan off;ptp stop;sfp match;mode slave;ptp start"
CONFIG_HAS_BUILD_INIT=1
CONFIG_HAS_FLASH_INIT=1
CONFIG_FLASH_INIT=y
# CONFIG_AUX_DIAG is not set
CONFIG_SDB_STORAGE=y
CONFIG_GENSDBFS=y
# CONFIG_LEGACY_EEPROM is not set
# CONFIG_WR_DIAG is not set
# CONFIG_WR_NODE_SIM is not set
CONFIG_ABSCAL=y
#
# wrpc-sw is tainted if you change the following options
......
......@@ -8,6 +8,8 @@ CONFIG_PPSI_FORCE_CONFIG=y
CONFIG_PRINT_BUFSIZE=128
CONFIG_RAMSIZE=131072
CONFIG_TEMP_POLL_INTERVAL=15
CONFIG_TEMP_HIGH_THRESHOLD=70
CONFIG_TEMP_HIGH_RAPPEL=60
# CONFIG_PLL_VERBOSE is not set
# CONFIG_PFILTER_VERBOSE is not set
# CONFIG_WRC_VERBOSE is not set
......@@ -22,7 +24,6 @@ CONFIG_EMBEDDED_NODE=y
# CONFIG_WR_NODE_PCS16 is not set
CONFIG_STACKSIZE=2048
CONFIG_PPSI=y
CONFIG_UART=y
CONFIG_W1=y
CONFIG_LATENCY_ETHTYPE=291
# CONFIG_P2P is not set
......@@ -35,14 +36,18 @@ CONFIG_HAS_FLASH_INIT=1
CONFIG_FLASH_INIT=y
# CONFIG_AUX_DIAG is not set
CONFIG_SDB_STORAGE=y
CONFIG_GENSDBFS=y
# CONFIG_LEGACY_EEPROM is not set
# CONFIG_WR_DIAG is not set
CONFIG_WR_NODE_SIM=y
CONFIG_ABSCAL=y
#
# wrpc-sw is tainted if you change the following options
#
CONFIG_DEVELOPER=y
# CONFIG_CMD_LL is not set
# CONFIG_DAC_LOG is not set
# CONFIG_CHECK_RESET is not set
# CONFIG_SPLL_FIFO_LOG is not set
CONFIG_PRINTF_IS_XINT=y
......@@ -51,12 +56,13 @@ CONFIG_PRINTF_IS_XINT=y
# CONFIG_PRINTF_IS_NONE is not set
# CONFIG_ASSERT is not set
# CONFIG_DETERMINISTIC_BINARY is not set
# CONFIG_UART_SW is not set
# CONFIG_NET_VERBOSE is not set
# CONFIG_FAKE_TEMPERATURES is not set
# CONFIG_LATENCY_PROBE is not set
CONFIG_DEFAULT_PRINT_TASK_TIME_THRESHOLD=0
CONFIG_VLAN_ARRAY_SIZE=1
CONFIG_PRINTF_XINT=y
# CONFIG_PRINTF_FULL is not set
# CONFIG_PRINTF_MINI is not set
# CONFIG_PRINTF_NONE is not set
# CONFIG_LLDP is not set
#include <wrc.h>
#include <wrpc.h>
#include <string.h>
#include <shell.h>
#include <lib/ipv4.h>
/* a tx-only socket: no queue is there */
static struct wrpc_socket __static_daclog_socket = {
.queue.buff = NULL,
.queue.size = 0,
};
static struct wrpc_socket *daclog_socket;
static struct wr_udp_addr daclog_addr;
unsigned char daclog_mac[6];
/* alternate between two buffers */
#define BSIZE 512
struct daclog_buf {
unsigned char hdr[UDP_END];
uint16_t data[BSIZE];
};
static struct daclog_buf buffers[2];
static int ready[2];
void spll_log_dac(int y);
void spll_log_dac(int y)
{
static int bindex, bcount;
buffers[bindex].data[bcount++] = y;
if (bcount == BSIZE) {
ready[bindex] = 1;
bindex = !bindex;
bcount = 0;
}
}
static void daclog_init(void)
{
daclog_socket = ptpd_netif_create_socket(&__static_daclog_socket, NULL,
PTPD_SOCK_UDP, 1050);
daclog_addr.sport = daclog_addr.dport = htons(1050);
}
static int configured;
static int daclog_poll(void)
{
struct wr_sockaddr addr;
int len = sizeof(struct daclog_buf);
struct daclog_buf *b = NULL;
if (!configured)
return 0;
if (ready[0]) {
b = buffers + 0;
ready[0] = 0;
} else if (ready[1]) {
b = buffers + 1;
ready[1] = 0;
}
if (!b)
return 0;
/* format and send */
getIP((void *)&daclog_addr.saddr); /* if we have no ip yet, 0 is ok */
fill_udp((void *)b, len, &daclog_addr);
memcpy(&addr.mac, daclog_mac, 6);
ptpd_netif_sendto(daclog_socket, &addr, b, len, 0);
return 1;
}
DEFINE_WRC_TASK(daclog) = {
.name = "daclog",
.init = daclog_init,
.job = daclog_poll,
};
static int cmd_daclog(const char *args[])
{
char b1[32], b2[32];
if (args[0] && !strcmp(args[0], "off")) {
configured = 0;
return 0;
}
if (!args[1]) {
pp_printf("use: daclog <ipaddr> <macaddr> (or just \"off\"\n");
return -1;
}
decode_ip(args[0], (void *)&daclog_addr.daddr);
decode_mac(args[1], daclog_mac);
pp_printf("Dac logger parameters: %s, %s, port 1050\n",
format_ip(b1, (void *)&daclog_addr.daddr),
format_mac(b2, daclog_mac));
configured = 1;
ready[0] = ready[1] = 0; /* try to ensure data ordering */
return 0;
}
DEFINE_WRC_COMMAND(daclog) = {
.name = "daclog",
.exec = cmd_daclog,
};
# Those hardware-specific files should not be built for the host, even if
# most of them give no error no warning. The host has different implementations
obj-$(CONFIG_LM32) += dev/uart.o
obj-$(CONFIG_EMBEDDED_NODE) += \
dev/endpoint.o \
dev/ep_pfilter.o \
......@@ -18,15 +20,15 @@ obj-$(CONFIG_WR_NODE) += \
dev/pps_gen.o
obj-$(CONFIG_WR_SWITCH) += dev/timer-wrs.o dev/ad9516.o
obj-$(CONFIG_PUTS_SYSLOG) += dev/puts-syslog.o
obj-$(CONFIG_LEGACY_EEPROM) += dev/eeprom.o
obj-$(CONFIG_SDB_STORAGE) += dev/sdb-storage.o
obj-$(CONFIG_DAC_LOG) += dev/dac_log.o
obj-$(CONFIG_W1) += dev/w1.o dev/w1-hw.o dev/w1-shell.o
obj-$(CONFIG_W1) += dev/w1-temp.o dev/w1-eeprom.o
obj-$(CONFIG_W1) += dev/temp-w1.o
obj-$(CONFIG_UART) += dev/uart.o
obj-$(CONFIG_UART_SW) += dev/uart-sw.o
obj-$(CONFIG_FAKE_TEMPERATURES) += dev/fake-temp.o
......@@ -38,5 +40,11 @@ obj-y += $(pfilter-y:.bin=.o)
rules-%.o: rules-%.bin
$(OBJCOPY) -I binary $(OBJCOPY-TARGET-y) $< $@
# sdbfs image
obj-y += $(sdbfsimg-y:.bin=.o)
sdbfs-default.o: tools/sdbfs-default.bin
$(OBJCOPY) -I binary $(OBJCOPY-TARGET-y) $< $@
$(pfilter-y): tools
tools/pfilter-builder
......@@ -42,16 +42,14 @@ static int cmd_faketemp(const char *args[])
}
for (i = 0; i < 3 && args[i]; i++) {
int sign = 1, val;
int val;
/* accept negative, and at most one decimal */
if (args[i][0] == '-')
sign = -1, args[i]++;
/* accept at most one decimal */
dot = fromdec(args[i], &val);
val <<= 16;
if (dot[0] == '.' && dot[1] >= '0' && dot[1] <= '9')
val += 0x10000 / 10 * (dot[1] - '0');
temp_fake_data[i].t = val * sign;
temp_fake_data[i].t = val;
}
return 0;
}
......
......@@ -9,6 +9,7 @@
#include <wrc.h>
#include <flash.h>
#include <types.h>
#include <storage.h>
#define SDBFS_BIG_ENDIAN
#include <libsdbfs.h>
......@@ -19,6 +20,7 @@
static void delay(void)
{
int i;
for (i = 0; i < (int)(CPU_CLOCK/10000000); i++)
asm volatile ("nop");
}
......@@ -54,7 +56,7 @@ static uint8_t bbspi_transfer(int cspin, uint8_t val)
/*
* Init function (just set the SPI pins for idle)
*/
void flash_init()
void flash_init(void)
{
gpio_out(GPIO_SPI_NCS, 1);
gpio_out(GPIO_SPI_SCLK, 0);
......@@ -68,17 +70,17 @@ int flash_write(uint32_t addr, uint8_t *buf, int count)
{
int i;
bbspi_transfer(1,0);
bbspi_transfer(0,0x06);
bbspi_transfer(1,0);
bbspi_transfer(0,0x02);
bbspi_transfer(0,(addr & 0xFF0000) >> 16);
bbspi_transfer(0,(addr & 0xFF00) >> 8);
bbspi_transfer(0,(addr & 0xFF));
for ( i = 0; i < count; i++ ) {
bbspi_transfer(0,buf[i]);
bbspi_transfer(1, 0);
bbspi_transfer(0, 0x06);
bbspi_transfer(1, 0);
bbspi_transfer(0, 0x02);
bbspi_transfer(0, (addr & 0xFF0000) >> 16);
bbspi_transfer(0, (addr & 0xFF00) >> 8);
bbspi_transfer(0, (addr & 0xFF));
for (i = 0; i < count; i++) {
bbspi_transfer(0, buf[i]);
}
bbspi_transfer(1,0);
bbspi_transfer(1, 0);
/* make sure the write is complete */
while (flash_rsr() & 0x01) {
......@@ -94,16 +96,17 @@ int flash_write(uint32_t addr, uint8_t *buf, int count)
int flash_read(uint32_t addr, uint8_t *buf, int count)
{
int i;
bbspi_transfer(1,0);
bbspi_transfer(0,0x0b);
bbspi_transfer(0,(addr & 0xFF0000) >> 16);
bbspi_transfer(0,(addr & 0xFF00) >> 8);
bbspi_transfer(0,(addr & 0xFF));
bbspi_transfer(0,0);
for ( i = 0; i < count; i++ ) {
bbspi_transfer(1, 0);
bbspi_transfer(0, 0x0b);
bbspi_transfer(0, (addr & 0xFF0000) >> 16);
bbspi_transfer(0, (addr & 0xFF00) >> 8);
bbspi_transfer(0, (addr & 0xFF));
bbspi_transfer(0, 0);
for (i = 0; i < count; i++) {
buf[i] = bbspi_transfer(0, 0);
}
bbspi_transfer(1,0);
bbspi_transfer(1, 0);
return count;
}
......@@ -114,15 +117,16 @@ int flash_erase(uint32_t addr, int count)
int sectors;
/*calc number of sectors to be removed*/
if(count % FLASH_BLOCKSIZE > 0)
if (count % storage_cfg.blocksize > 0)
sectors = 1;
else
sectors = 0;
sectors += (count / FLASH_BLOCKSIZE);
sectors += (count / storage_cfg.blocksize);
for(i=0; i<sectors; ++i) {
flash_serase(addr + i*FLASH_BLOCKSIZE);
while(flash_rsr() & 0x01);
for (i = 0; i < sectors; ++i) {
flash_serase(addr + i*storage_cfg.blocksize);
while (flash_rsr() & 0x01)
;
}
return count;
......@@ -133,45 +137,46 @@ int flash_erase(uint32_t addr, int count)
*/
void flash_serase(uint32_t addr)
{
bbspi_transfer(1,0);
bbspi_transfer(0,0x06);
bbspi_transfer(1,0);
bbspi_transfer(0,0xD8);
bbspi_transfer(0,(addr & 0xFF0000) >> 16);
bbspi_transfer(0,(addr & 0xFF00) >> 8);
bbspi_transfer(0,(addr & 0xFF));
bbspi_transfer(1,0);
bbspi_transfer(1, 0);
bbspi_transfer(0, 0x06);
bbspi_transfer(1, 0);
bbspi_transfer(0, 0xD8);
bbspi_transfer(0, (addr & 0xFF0000) >> 16);
bbspi_transfer(0, (addr & 0xFF00) >> 8);
bbspi_transfer(0, (addr & 0xFF));
bbspi_transfer(1, 0);
}
/*
* Bulk erase
*/
void
flash_berase()
flash_berase(void)
{
bbspi_transfer(1,0);
bbspi_transfer(0,0x06);
bbspi_transfer(1,0);
bbspi_transfer(0,0xc7);
bbspi_transfer(1,0);
bbspi_transfer(1, 0);
bbspi_transfer(0, 0x06);
bbspi_transfer(1, 0);
bbspi_transfer(0, 0xc7);
bbspi_transfer(1, 0);
}
/*
* Read status register
*/
uint8_t flash_rsr()
uint8_t flash_rsr(void)
{
uint8_t retval;
bbspi_transfer(1,0);
bbspi_transfer(0,0x05);
retval = bbspi_transfer(0,0);
bbspi_transfer(1,0);
bbspi_transfer(1, 0);
bbspi_transfer(0, 0x05);
retval = bbspi_transfer(0, 0);
bbspi_transfer(1, 0);
return retval;
}
/*****************************************************************************/
/* SDB */
/* SDB */
/*****************************************************************************/
/* The sdb filesystem itself */
......@@ -202,7 +207,8 @@ static void flash_sdb_list(struct sdbfs *fs)
{
struct sdb_device *d;
int new = 1;
while ( (d = sdbfs_scan(fs, new)) != NULL) {
while ((d = sdbfs_scan(fs, new)) != NULL) {
d->sdb_component.product.record_type = '\0';
pp_printf("file 0x%08x @ %4i, name %19s\n",
(int)(d->sdb_component.product.device_id),
......@@ -215,19 +221,19 @@ static void flash_sdb_list(struct sdbfs *fs)
/*
* Check for SDB presence on flash
*/
int flash_sdb_check()
int flash_sdb_check(void)
{
uint32_t magic = 0;
int i;
uint32_t entry_point[] = {
0x000000, // flash base
0x100, // second page in flash
0x200, // IPMI with MultiRecord
0x300, // IPMI with larger MultiRecord
0x170000, // after first FPGA bitstream
0x2e0000 // after MultiBoot bitstream
};
0x000000, /* flash base */
0x100, /* second page in flash */
0x200, /* IPMI with MultiRecord */
0x300, /* IPMI with larger MultiRecord */
0x170000, /* after first FPGA bitstream */
0x2e0000 /* after MultiBoot bitstream */
};
for (i = 0; i < ARRAY_SIZE(entry_point); i++) {
flash_read(entry_point[i], (uint8_t *)&magic, 4);
......
......@@ -12,17 +12,15 @@
#include "syscon.h"
#include "i2c.h"
#define I2C_DELAY 300
void mi2c_delay(void)
void mi2c_delay(uint32_t delay)
{
int i;
for (i = 0; i < I2C_DELAY; i++)
for (i = 0; i < delay; i++)
asm volatile ("nop");
}
#define M_SDA_OUT(i, x) { gpio_out(i2c_if[i].sda, x); mi2c_delay(); }
#define M_SCL_OUT(i, x) { gpio_out(i2c_if[i].scl, x); mi2c_delay(); }
#define M_SDA_OUT(i, x) { gpio_out(i2c_if[i].sda, x); mi2c_delay(i2c_if[i].loop_delay); }
#define M_SCL_OUT(i, x) { gpio_out(i2c_if[i].scl, x); mi2c_delay(i2c_if[i].loop_delay); }
#define M_SDA_IN(i) gpio_in(i2c_if[i].sda)
void mi2c_start(uint8_t i2cif)
......
......@@ -31,8 +31,6 @@
#define RX_OOB_SIZE 3 /* as the number of FIFO data words */
#define ETH_HEADER_SIZE 14
// extracts the values of TS rising and falling edge counters from the descriptor header
#define EXPLODE_WR_TIMESTAMP(raw, rc, fc) \
......@@ -199,7 +197,7 @@ int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size,
&& counter_ppsg < 250000000)
sec--;
hwts->sec = sec & 0x7fffffff;
hwts->sec = sec;
cntr_diff = (counter_r & F_COUNTER_MASK) - counter_f;
......
#include <wrc.h>
#include <string.h>
#include <uart.h>
#include <shell.h>
#include <lib/ipv4.h>
int puts(const char *s)
{
char new_s[CONFIG_PRINT_BUFSIZE + 4];
int l, ret;
ret = uart_write_string(s);
l = strlen(s);
/* avoid shell-interation stuff */
if (shell_is_interacting)
return ret;
if (l < 2 || s[0] == '\e')
return ret;
if (!strncmp(s, "wrc#", 4))
return ret;
/* if not terminating with newline, add a trailing "...\n" */
strcpy(new_s, s);
if (s[l-1] != '\n') {
new_s[l++] = '.';
new_s[l++] = '.';
new_s[l++] = '.';
new_s[l++] = '\n';
new_s[l++] = '\0';
}
syslog_report(new_s);
return ret;
}
......@@ -7,6 +7,7 @@
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <errno.h>
#include <wrc.h>
#include <w1.h>
#include <storage.h>
......@@ -15,6 +16,7 @@
#include "i2c.h"
#include "onewire.h"
#include "endpoint.h"
#include "syscon.h"
#include <sdb.h>
#define SDBFS_BIG_ENDIAN
......@@ -35,6 +37,8 @@
#define EEPROM_START_ADR 0
#define EEPROM_STOP_ADR 127
struct storage_config storage_cfg;
/* Functions for Flash access */
static int sdb_flash_read(struct sdbfs *fs, int offset, void *buf, int count)
{
......@@ -169,6 +173,7 @@ static void storage_sdb_list(struct sdbfs *fs)
{
struct sdb_device *d;
int new = 1;
while ((d = sdbfs_scan(fs, new)) != NULL) {
d->sdb_component.product.record_type = '\0';
pp_printf("file 0x%08x @ %4i, name %s\n",
......@@ -220,7 +225,7 @@ void storage_init(int chosen_i2cif, int chosen_i2c_addr)
pp_printf("sdbfs: found at %i in Flash\n",
entry_points_flash[i]);
wrc_sdb.drvdata = NULL;
wrc_sdb.blocksize = FLASH_BLOCKSIZE;
wrc_sdb.blocksize = storage_cfg.blocksize;
wrc_sdb.entrypoint = entry_points_flash[i];
wrc_sdb.read = sdb_flash_read;
wrc_sdb.write = sdb_flash_write;
......@@ -259,7 +264,7 @@ void storage_init(int chosen_i2cif, int chosen_i2c_addr)
i2c_params.addr = EEPROM_START_ADR;
while (i2c_params.addr <= EEPROM_STOP_ADR) {
/* First, we check if I2C EEPROM is there */
if (!mi2c_devprobe(i2c_params.ifnum, i2c_params.addr)) {
if (!mi2c_devprobe(i2c_params.ifnum, i2c_params.addr)) {
i2c_params.addr++;
continue;
}
......@@ -694,6 +699,7 @@ int storage_init_show(void)
if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, SDB_DEV_INIT) < 0)
return -1;
pp_printf("-- user-defined script --\n");
used = 0;
do {
if (sdbfs_fread(&wrc_sdb, sizeof(used) + used, &byte, 1) != 1)
......@@ -705,7 +711,7 @@ int storage_init_show(void)
} while (byte != 0xff);
if (used == 0)
pp_printf("Empty init script...\n");
pp_printf("(empty)\n");
ret = 0;
out:
sdbfs_close(&wrc_sdb);
......@@ -737,3 +743,160 @@ out:
sdbfs_close(&wrc_sdb);
return ret;
}
int storage_read_hdl_cfg(void)
{
get_storage_info(&storage_cfg.memtype, &storage_cfg.baseadr,
&storage_cfg.blocksize);
if (storage_cfg.memtype == MEM_FLASH && storage_cfg.blocksize == 0) {
storage_cfg.valid = 0;
/* keep default blocksize for backwards compatibility */
storage_cfg.blocksize = FLASH_BLOCKSIZE;
} else
storage_cfg.valid = 1;
return 0;
}
extern uint32_t _binary_tools_sdbfs_default_bin_start[];
extern uint32_t _binary_tools_sdbfs_default_bin_end[];
static inline unsigned long SDB_ALIGN(unsigned long x, int blocksize)
{
return (x + (blocksize - 1)) & ~(blocksize - 1);
}
int storage_sdbfs_erase(int mem_type, uint32_t base_adr, uint32_t blocksize,
uint8_t i2c_adr)
{
if (!HAS_GENSDBFS || (mem_type == MEM_FLASH && blocksize == 0))
return -EINVAL;
if (mem_type == MEM_FLASH) {
pp_printf("Erasing Flash(0x%x)...\n", base_adr);
sdb_flash_erase(NULL, base_adr, SDBFS_REC * blocksize);
} else if (mem_type == MEM_EEPROM) {
pp_printf("Erasing EEPROM %d (0x%x)...\n", i2c_adr, base_adr);
i2c_params.ifnum = WRPC_FMC_I2C;
i2c_params.addr = i2c_adr;
wrc_sdb.drvdata = &i2c_params;
sdb_i2c_erase(&wrc_sdb, base_adr, SDBFS_REC *
sizeof(struct sdb_device));
} else if (mem_type == MEM_1W_EEPROM) {
pp_printf("Erasing 1-W EEPROM (0x%x)...\n", base_adr);
wrc_sdb.drvdata = &wrpc_w1_bus;
sdb_w1_erase(&wrc_sdb, base_adr, SDBFS_REC *
sizeof(struct sdb_device));
}
return 0;
}
int storage_gensdbfs(int mem_type, uint32_t base_adr, uint32_t blocksize,
uint8_t i2c_adr)
{
struct sdb_device *sdbfs =
(struct sdb_device *) _binary_tools_sdbfs_default_bin_start;
struct sdb_interconnect *sdbfs_dir = (struct sdb_interconnect *)
_binary_tools_sdbfs_default_bin_start;
/* struct sdb_device sdbfs_buf[SDBFS_REC]; */
int i;
char buf[19] = {0};
int cur_adr, size;
uint32_t val;
if (!HAS_GENSDBFS || (mem_type == MEM_FLASH && base_adr == 0))
return -EINVAL;
if (mem_type == MEM_FLASH && blocksize == 0)
return -EINVAL;
/* first file starts after the SDBFS description */
cur_adr = base_adr + SDB_ALIGN(SDBFS_REC*sizeof(struct sdb_device),
blocksize);
/* scan through files */
for (i = 1; i < SDBFS_REC; ++i) {
/* relocate each file depending on base address and block size*/
size = sdbfs[i].sdb_component.addr_last -
sdbfs[i].sdb_component.addr_first;
sdbfs[i].sdb_component.addr_first = cur_adr;
sdbfs[i].sdb_component.addr_last = cur_adr + size;
cur_adr = SDB_ALIGN(cur_adr + (size + 1), blocksize);
}
/* update the directory */
sdbfs_dir->sdb_component.addr_first = base_adr;
sdbfs_dir->sdb_component.addr_last =
sdbfs[SDBFS_REC-1].sdb_component.addr_last;
for (i = 0; i < SDBFS_REC; ++i) {
strncpy(buf, (char *)sdbfs[i].sdb_component.product.name, 18);
pp_printf("filename: %s; first: %x; last: %x\n", buf,
(int)sdbfs[i].sdb_component.addr_first,
(int)sdbfs[i].sdb_component.addr_last);
}
size = sizeof(struct sdb_device);
if (mem_type == MEM_FLASH) {
pp_printf("Formatting SDBFS in Flash(0x%x)...\n", base_adr);
/* each file is in a separate block, therefore erase SDBFS_REC
* number of blocks */
sdb_flash_erase(NULL, base_adr, SDBFS_REC * blocksize);
for (i = 0; i < SDBFS_REC; ++i) {
sdb_flash_write(NULL, base_adr + i*size, &sdbfs[i],
size);
}
/*
pp_printf("Verification...");
sdb_flash_read(NULL, base_adr, sdbfs_buf, SDBFS_REC *
sizeof(struct sdb_device));
if(memcmp(sdbfs, sdbfs_buf, SDBFS_REC *
sizeof(struct sdb_device)))
pp_printf("Error.\n");
else
pp_printf("OK.\n");
*/
} else if (mem_type == MEM_EEPROM) {
/* First, check if EEPROM is really there */
if (!mi2c_devprobe(WRPC_FMC_I2C, i2c_adr)) {
pp_printf("I2C EEPROM not found\n");
return -EINVAL;
}
i2c_params.ifnum = WRPC_FMC_I2C;
i2c_params.addr = i2c_adr;
pp_printf("Formatting SDBFS in I2C EEPROM %d (0x%x)...\n",
i2c_params.addr, base_adr);
wrc_sdb.drvdata = &i2c_params;
sdb_i2c_erase(&wrc_sdb, base_adr, SDBFS_REC * size);
for (i = 0; i < SDBFS_REC; ++i) {
sdb_i2c_write(&wrc_sdb, base_adr + i*size, &sdbfs[i],
size);
}
/*
pp_printf("Verification...");
sdb_i2c_read(&wrc_sdb, base_adr, sdbfs_buf, SDBFS_REC *
sizeof(struct sdb_device));
if(memcmp(sdbfs, sdbfs_buf, SDBFS_REC *
sizeof(struct sdb_device)))
pp_printf("Error.\n");
else
pp_printf("OK.\n");
*/
} else if (mem_type == MEM_1W_EEPROM) {
wrc_sdb.drvdata = &wrpc_w1_bus;
if (sdb_w1_read(&wrc_sdb, 0, &val, sizeof(val)) !=
sizeof(val)) {
pp_printf("1-Wire EEPROM not found\n");
return -EINVAL;
}
pp_printf("Formatting SDBFS in 1-W EEPROM (0x%x)...\n",
base_adr);
sdb_w1_erase(&wrc_sdb, base_adr, SDBFS_REC * size);
for (i = 0; i < SDBFS_REC; ++i) {
sdb_w1_write(&wrc_sdb, base_adr + i*size, &sdbfs[i],
size);
}
}
/* re-initialize storage after writing sdbfs image */
storage_init(WRPC_FMC_I2C, FMC_EEPROM_ADR);
return mem_type;
}
......@@ -26,12 +26,12 @@ int32_t sfp_in_db = 0;
char sfp_pn[SFP_PN_LEN];
int sfp_present(void)
static int sfp_present(void)
{
return !gpio_in(GPIO_SFP_DET);
}
int sfp_read_part_id(char *part_id)
static int sfp_read_part_id(char *part_id)
{
int i;
uint8_t data, sum;
......
......@@ -8,14 +8,37 @@
*/
#include "syscon.h"
#include <errno.h>
#include <string.h>
struct s_i2c_if i2c_if[2] = {
{SYSC_GPSR_FMC_SCL, SYSC_GPSR_FMC_SDA},
{SYSC_GPSR_SFP_SCL, SYSC_GPSR_SFP_SDA}
{SYSC_GPSR_FMC_SCL, SYSC_GPSR_FMC_SDA, FMC_I2C_DELAY},
{SYSC_GPSR_SFP_SCL, SYSC_GPSR_SFP_SDA, SFP_I2C_DELAY}
};
volatile struct SYSCON_WB *syscon;
/****************************
* BOARD NAME
***************************/
void get_hw_name(char *str)
{
uint32_t val;
val = syscon->HWIR;
memcpy(str, &val, HW_NAME_LENGTH-1);
}
/****************************
* Flash info
***************************/
void get_storage_info(int *memtype, uint32_t *sdbfs_baddr, uint32_t *blocksize)
{
/* convert sector size from KB to bytes */
*blocksize = SYSC_HWFR_STORAGE_SEC_R(syscon->HWFR) * 1024;
*sdbfs_baddr = syscon->SDBFS;
*memtype = SYSC_HWFR_STORAGE_TYPE_R(syscon->HWFR);
}
/****************************
* TIMER
***************************/
......@@ -38,7 +61,9 @@ void timer_delay(uint32_t tics)
{
uint32_t t_end;
// timer_init(1);
/*
timer_init(1);
*/
t_end = timer_get_tics() + tics;
while (time_before(timer_get_tics(), t_end))
......@@ -110,3 +135,80 @@ void net_rst(void)
syscon->GPSR |= SYSC_GPSR_NET_RST;
}
int wdiag_set_valid(int enable)
{
if (enable)
syscon->WDIAG_CTRL |= SYSC_WDIAG_CTRL_DATA_VALID;
if (!enable)
syscon->WDIAG_CTRL &= ~SYSC_WDIAG_CTRL_DATA_VALID;
return (int)(syscon->WDIAG_CTRL & SYSC_WDIAG_CTRL_DATA_VALID);
}
int wdiag_get_valid(void)
{
if (syscon->WDIAG_CTRL & SYSC_WDIAG_CTRL_DATA_VALID)
return 1;
else
return 0;
}
int wdiag_get_snapshot(void)
{
if (syscon->WDIAG_CTRL & SYSC_WDIAG_CTRL_DATA_SNAPSHOT)
return 1;
else
return 0;
}
void wdiags_write_servo_state(int wr_mode, uint8_t servostate, uint64_t mu,
uint64_t dms, int32_t asym, int32_t cko,
int32_t setp, int32_t ucnt)
{
syscon->WDIAG_SSTAT = wr_mode ? SYSC_WDIAG_SSTAT_WR_MODE:0;
syscon->WDIAG_SSTAT |= SYSC_WDIAG_SSTAT_SERVOSTATE_W(servostate);
syscon->WDIAG_MU_MSB = 0xFFFFFFFF & (mu>>32);
syscon->WDIAG_MU_LSB = 0xFFFFFFFF & mu;
syscon->WDIAG_DMS_MSB = 0xFFFFFFFF & (dms>>32);
syscon->WDIAG_DMS_LSB = 0xFFFFFFFF & dms;
syscon->WDIAG_ASYM = asym;
syscon->WDIAG_CKO = cko;
syscon->WDIAG_SETP = setp;
syscon->WDIAG_UCNT = ucnt;
}
void wdiags_write_port_state(int link, int locked)
{
uint32_t val = 0;
val = link ? SYSC_WDIAG_PSTAT_LINK : 0;
val |= locked ? SYSC_WDIAG_PSTAT_LOCKED : 0;
syscon->WDIAG_PSTAT = val;
}
void wdiags_write_ptp_state(uint8_t ptpstate)
{
syscon->WDIAG_PTPSTAT = SYSC_WDIAG_PTPSTAT_PTPSTATE_W(ptpstate);
}
void wdiags_write_aux_state(uint32_t aux_states)
{
syscon->WDIAG_ASTAT = SYSC_WDIAG_ASTAT_AUX_W(aux_states);
}
void wdiags_write_cnts(uint32_t tx, uint32_t rx)
{
syscon->WDIAG_TXFCNT = tx;
syscon->WDIAG_RXFCNT = rx;
}
void wdiags_write_time(uint64_t sec, uint32_t nsec)
{
syscon->WDIAG_SEC_MSB = 0xFFFFFFFF & (sec>>32);
syscon->WDIAG_SEC_LSB = 0xFFFFFFFF & sec;
syscon->WDIAG_NS = nsec;
}
void wdiags_write_temp(uint32_t temp)
{
syscon->WDIAG_TEMP = temp;
}
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2013 CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <wrc.h>
#include <uart-sw.h>
static struct wrc_uart_sw __attribute__((aligned(16))) uart_sw_dev = {
.magic = UART_SW_MAGIC,
.wsize = CONFIG_UART_SW_WSIZE,
.rsize = CONFIG_UART_SW_RSIZE,
};
static uint16_t nreturned;
void uart_init_sw(void)
{
/* zero fields, as we may be reloaded */
uart_sw_dev.nwritten = uart_sw_dev.nread = 0;
}
void __attribute__((weak)) uart_init_hw(void)
{}
static void uart_sw_write_byte(int b)
{
int index;
if (b == '\n')
uart_sw_write_byte('\r');
index = uart_sw_dev.nwritten % CONFIG_UART_SW_WSIZE;
uart_sw_dev.wbuffer[index] = b;
uart_sw_dev.nwritten++;
/* fake a real uart, so user-space can poll not-too-fast */
usleep(1000 * 1000 / 11520);
}
int uart_sw_write_string(const char *s)
{
const char *t = s;
while (*s)
uart_sw_write_byte(*(s++));
return s - t;
}
static int uart_sw_read_byte(void)
{
int index;
if (nreturned == uart_sw_dev.nread) /* nread == written by host */
return -1;
index = (nreturned++) % CONFIG_UART_SW_RSIZE;
return uart_sw_dev.rbuffer[index];
}
/* alias the "hw" names to these, so this applies if !CONFIG_UART */
int puts(const char *s)
__attribute__((alias("uart_sw_write_string"), weak));
void uart_write_byte(int b)
__attribute__((alias("uart_sw_write_byte"), weak));
int uart_write_string(const char *s)
__attribute__((alias("uart_sw_write_string"), weak));
int uart_read_byte(void)
__attribute__((alias("uart_sw_read_byte"), weak));
......@@ -11,7 +11,7 @@
#include "board.h"
#include "uart.h"
#include <hw/wb_vuart.h>
#include <hw/wb_uart.h>
#define CALC_BAUD(baudrate) \
( ((( (unsigned long long)baudrate * 8ULL) << (16 - 7)) + \
......@@ -25,10 +25,6 @@ void uart_init_hw()
uart->BCR = CALC_BAUD(UART_BAUDRATE);
}
void __attribute__((weak)) uart_init_sw(void)
{}
void uart_write_byte(int b)
{
if (b == '\n')
......@@ -60,8 +56,4 @@ int uart_read_byte(void)
}
int puts(const char *s)
__attribute__((alias("uart_write_string")));
/* The next alias is for ppsi log messages, that go to sw_uart if built */
int uart_sw_write_string(const char *s)
__attribute__((alias("uart_write_string"), weak));
__attribute__((weak,alias("uart_write_string")));
......@@ -2,6 +2,6 @@
\label{sec:wrpc_timecode}
Timecode interface provides current time to the other HDL modules in a form that
can be easily used. It consists of: a 1-PPS and a UTC timecode
can be easily used. It consists of: a 1-PPS and a TAI timecode
aligned to the time of WR Master.
......@@ -66,6 +66,12 @@ their own BSP, can find the board-common module under:
\cline{1-3}
g\_with\_external\_clock\_input & boolean & true & \\
\cline{1-3}
g\_board\_name & string & "NA " & \\
\cline{1-3}
g\_flash\_secsz\_kb & integer & 256 & \\
\cline{1-3}
g\_flash\_sdbfs\_baddr & integer & 0x600000 & \\
\cline{1-3}
g\_aux\_clks & integer & 0 & \\
\cline{1-3}
g\_dpram\_initf & string & "" & \\
......@@ -78,10 +84,17 @@ their own BSP, can find the board-common module under:
\cline{1-3}
g\_diag\_rw\_size & integer & 0 & \\
\hline
g\_tx\_streamer\_width & integer & 32 & \multirowpar{2}{TX/RX
data width when \tts{g\_fabric\_iface = STREAMERS} (otherwise ignored)}\\
g\_streamers\_op\_mode & enum & TX\_AND\_RX & Selects whether both TX and RX
streamer modules should be instantiated or only one of them when
\tts{g\_fabric\_iface = STREAMERS} (otherwise ignored)\\
\hline
g\_tx\_streamer\_params & record & default record & \multirowpar{2}{various TX/RX
streamers parameters when \tts{g\_fabric\_iface = STREAMERS} (otherwise
ignored)\footnote{See Streamers wiki page for detailed description of the
configuration records:
\url{http://www.ohwr.org/projects/wr-cores/wiki/TxRx_Streamers}}}\\
\cline{1-3}
g\_rx\_streamer\_width & integer & 32 & \\
g\_rx\_streamers\_params & record & default record & \\
\hline
g\_fabric\_iface & enum & PLAIN & optional module to be attached to the
fabric interface of WRPC \tts{[PLAIN/STREAMERS/ETHERBONE]}\\
......@@ -109,7 +122,7 @@ their own BSP, can find the board-common module under:
rst\_62m5\_n\_o & out & 1 & Active low reset output, synchronous to \tts{clk\_sys\_62m5\_o}\\
\hline
rst\_125m\_n\_o & out & 1 & Active low reset output, synchronous to \tts{clk\_ref\_125m\_o}\\
\hline\pagebreak
\hline
\hdltablesection{Interface with SFP}\\
\hline
sfp\_tx\_fault\_i & in & 1 & TX fault indicator\\
......@@ -142,6 +155,11 @@ their own BSP, can find the board-common module under:
\cline{1-3}
wb\_slave\_i & in & rec & \\
\hline
aux\_master\_o & out & rec & \multirowpar{2}{Mapped to WRPC auxiliary WB
master interface (see also Section~\ref{sec:wrpc_wb})}\\
\cline{1-3}
aux\_master\_i & in & rec & \\
\hline
\hdltablesection{WR fabric interface (when \tts{g\_fabric\_iface = plain})}\\
\hline
wrf\_src\_o & out & rec & \multirowpar{4}{Mapped to WRPC fabric interface
......@@ -168,6 +186,13 @@ their own BSP, can find the board-common module under:
wrs\_tx\_flush\_i & in & 1 & When asserted, the streamer will immediatly send
out all the data that is stored in its TX buffer\\
\hline
wrs\_tx\_cfg\_i & in & rec & \multirowpar{2}{Networking configuration of Tx/Rx
Streamers\footnote{See Streamers wiki page for detailed description of the
network configuration:
\url{http://www.ohwr.org/projects/wr-cores/wiki/TxRx_Streamers}}}\\
\cline{1-3}
wrs\_rx\_cfg\_i & in & rec & \\
\hline
wrs\_rx\_first\_o & out & 1 & Indicates the first word of the data block on \tts{wrs\_rx\_data\_o}\\
\hline
wrs\_rx\_last\_o & out & 1 & Indicates the last word of the data block on \tts{wrs\_rx\_data\_o}\\
......@@ -208,7 +233,7 @@ their own BSP, can find the board-common module under:
\hline
tm\_clk\_aux\_locked\_o & out & var & auxiliary clock locked to internal WR
clock. Size is equal to \tts{g\_aux\_clks}\\
\hline
\hline \pagebreak
\hdltablesection{External TX timestamp interface}\\
\hline
timestamps\_o & out & rec & Record-based output ports for
......@@ -217,6 +242,11 @@ their own BSP, can find the board-common module under:
txtsu\_ack\_i & in & 1 & acknowledge, indicating that user-defined module
has received the timestamp\\
\hline
abscal\_txts\_o & out & 1 & \multirowpar{2}{[optional] Endpoint timestamping
triggers used in the absolute calibration procedure} \\
\cline{1-3}
abscal\_rxts\_o & out & 1 & \\
\hline
\hdltablesection{Pause frame control}\\
\hline
fc\_tx\_pause\_req\_i & in & 1 & [optional] Ethernet flow control, request sending
......@@ -295,6 +325,10 @@ Section~\ref{sec:hdl_board_common_param} for a the list of common BSP parameters
\hline
areset\_n\_i & in & 1 & Reset input (active low, can be async)\\
\hline
areset\_edge\_n\_i & in & 1 & [optional] Reset input edge sensitive (active
rising-edge, can be async). Should be connected to PCIe reset if the board
should be able to operate both in hosted and standalone configuration.\\
\hline
clk\_20m\_vcxo\_i & in & 1 & 20MHz clock input from board VCXO\\
\hline
clk\_125m\_pllref\_p\_i & in & 1 & \multirowpar{2}{125MHz PLL reference
......@@ -389,6 +423,9 @@ Section~\ref{sec:hdl_board_common_param} for a the list of common BSP parameters
\hline
areset\_n\_i & in & 1 & Reset input (active low, can be async)\\
\hline
areset\_edge\_n\_i & in & 1 & [optional] Reset input edge sensitive (active
rising-edge, can be async).\\
\hline
clk\_20m\_vcxo\_i & in & 1 & 20MHz clock input from board VCXO\\
\hline
clk\_125m\_pllref\_p\_i & in & 1 & \multirowpar{2}{125MHz PLL reference
......@@ -490,6 +527,9 @@ Parameters and ports common to all BSPs are described in Section~\ref{sec:hdl_bo
\hline
areset\_n\_i & in & 1 & Reset input (active low, can be async)\\
\hline
areset\_edge\_n\_i & in & 1 & [optional] Reset input edge sensitive (active
rising-edge, can be async).\\
\hline
clk\_board\_20m\_i & in & 1 & 20MHz clock input from board\\
\hline
clk\_board\_125m\_i & in & 1 & 125MHz reference clock input from board\\
......
......@@ -8,6 +8,17 @@
g\_with\_external\_clock\_input & boolean & false &
enable external clock and 1-PPS inputs. The PLL inside WRPC will lock to
external 10 MHz and 1-PPS signal when operating in GrandMaster mode\\
\hline
g\_board\_name & string & "NA " & board name, exported by WRPC software as
SNMP object for diagnostics\\
\hline
g\_flash\_secsz\_kb & integer & 256 & Flash memory sector size in kilobytes.
Available through a Wishbone register, used by WRPC software to read/write
SDBFS image\\
\hline
g\_flash\_sdbfs\_baddr & integer & 0x600000 & Default base address in Flash
memory where \code{sdb fs} command should store an empty SDBFS image\\
\hline
g\_phys\_uart & boolean & true & enable physical UART interface\\
\hline
g\_virtual\_uart & boolean & false & enable virtual UART interface\\
......
......@@ -165,18 +165,19 @@ PSP. Parameters and ports common to all PSPs are described in Section~\ref{sec:h
\subsubsection{Xilinx}
\label{sec:hdl_platform_xilinx}
The Xilinx PSP currently supports the Spartan 6 family of FPGAs.
The Xilinx PSP currently supports the Spartan 6 and Kintex 7 (also inside Zynq) family of FPGAs.
The top-level VHDL module is located under:\\ \hrefwrpc{platform/xilinx/xwrc\_platform\_xilinx.vhd}
A VHDL package with the definition of the module can be found
under:\\ \hrefwrpc{platform/wr\_xilinx\_pkg.vhd}
Examples of (VHDL) instantiation of this module can be found in the SPEC and SVEC board support
packages (see also Sections~\ref{sec:hdl_board_spec}
Examples of (VHDL) instantiation of this module can be found in the SPEC, SVEC
and FASEC board support packages (see also Sections~\ref{sec:hdl_board_spec}
and~\ref{sec:hdl_board_svec}):\\
\hrefwrpc{board/spec/xwrc\_board\_spec.vhd}\\
\hrefwrpc{board/svec/xwrc\_board\_svec.vhd}
\hrefwrpc{board/svec/xwrc\_board\_svec.vhd}\\
\hrefwrpc{board/fasec/xwrc\_board\_fasec.vhd}\\
This section describes the generic parameters and ports which are
specific to the Xilinx PSP. Parameters and ports common to all PSPs
......
......@@ -29,7 +29,7 @@
\hline
rst\_n\_i & in & 1 & main reset input, active-low (hold for at least 5
\tts{clk\_sys\_i} cycles)\\
\hline
\hline\pagebreak
\hdltablesection{Timing system}\\
\hline
dac\_hpll\_load\_p1\_o & out & 1 & validates DAC value on data port \\
......@@ -89,7 +89,7 @@
when \tts{g\_pcs\_16bit = true}}\\
\cline{1-3}
phy16\_i & in & rec & \\
\hline
\hline\pagebreak
\hdltablesection{GPIO}\\
\hline
led\_act\_o & out & 1 & signal for driving Ethernet activity LED\\
......@@ -103,7 +103,7 @@
scl\_i & in & 1 & \\
\cline{1-3}
scl\_o & out & 1 & \\
\hline\pagebreak
\hline
sfp\_sda\_i & in & 1 & \multirowpar{4}{I2C interface for EEPROM inside SFP module}\\
\cline{1-3}
sfp\_sda\_o & out & 1 & \\
......
\subsection{WR Streamers, status and debug}
\label{subsec:wbgen:wr_streamers}
[version 0x00000001]\\
-----------------------------------------------------------------\\ This WB registers allow to diagnose transmission and reception of\\ data using WR streamers. \\ In particular, these registers provide access to streamer's \\ statistics that can be also access from SNMP, if supported. \\ -----------------------------------------------------------------\\ Copyright (c) 2016 CERN/BE-CO-HT and CERN/TE-MS-MM \\ \\ This source file is free software; you can redistribute it \\ and/or modify it under the terms of the GNU Lesser General \\ Public License as published by the Free Software Foundation; \\ either version 2.1 of the License, or (at your option) any \\ later version. \\ \\ This source is distributed in the hope that it will be \\ useful, but WITHOUT ANY WARRANTY; without even the implied \\ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR \\ PURPOSE. See the GNU Lesser General Public License for more \\ details \\ \\ You should have received a copy of the GNU Lesser General \\ Public License along with this source; if not, download it \\ from http://www.gnu.org/licenses/lgpl-2.1.html \\ -----------------------------------------------------------------
\subsubsection{Memory map summary}
\rowcolors{2}{gray!25}{white}
\resizebox{\textwidth}{!}{
\begin{tabular}{|l|l|l|l|l|}
\rowcolor{RoyalPurple}
\color{white} SW Offset & \color{white} Type & \color{white} Name &
\color{white} HW prefix & \color{white} C prefix\\
0x0& REG & Version register & wr\_streamers\_ver & VER\\
0x4& REG & Statistics status and ctrl register & wr\_streamers\_sscr1 & SSCR1\\
0x8& REG & Statistics status and ctrl register & wr\_streamers\_sscr2 & SSCR2\\
0xc& REG & Statistics status and ctrl register & wr\_streamers\_sscr3 & SSCR3\\
0x10& REG & Rx statistics & wr\_streamers\_rx\_stat0 & RX\_STAT0\\
0x14& REG & Rx statistics & wr\_streamers\_rx\_stat1 & RX\_STAT1\\
0x18& REG & Tx statistics & wr\_streamers\_tx\_stat2 & TX\_STAT2\\
0x1c& REG & Tx statistics & wr\_streamers\_tx\_stat3 & TX\_STAT3\\
0x20& REG & Rx statistics & wr\_streamers\_rx\_stat4 & RX\_STAT4\\
0x24& REG & Rx statistics & wr\_streamers\_rx\_stat5 & RX\_STAT5\\
0x28& REG & Rx statistics & wr\_streamers\_rx\_stat6 & RX\_STAT6\\
0x2c& REG & Rx statistics & wr\_streamers\_rx\_stat7 & RX\_STAT7\\
0x30& REG & Rx statistics & wr\_streamers\_rx\_stat8 & RX\_STAT8\\
0x34& REG & Rx statistics & wr\_streamers\_rx\_stat9 & RX\_STAT9\\
0x38& REG & Rx statistics & wr\_streamers\_rx\_stat10 & RX\_STAT10\\
0x3c& REG & Rx statistics & wr\_streamers\_rx\_stat11 & RX\_STAT11\\
0x40& REG & Rx statistics & wr\_streamers\_rx\_stat12 & RX\_STAT12\\
0x44& REG & Rx statistics & wr\_streamers\_rx\_stat13 & RX\_STAT13\\
0x48& REG & Tx Config Reg 0 & wr\_streamers\_tx\_cfg0 & TX\_CFG0\\
0x4c& REG & Tx Config Reg 1 & wr\_streamers\_tx\_cfg1 & TX\_CFG1\\
0x50& REG & Tx Config Reg 2 & wr\_streamers\_tx\_cfg2 & TX\_CFG2\\
0x54& REG & Tx Config Reg 3 & wr\_streamers\_tx\_cfg3 & TX\_CFG3\\
0x58& REG & Tx Config Reg 4 & wr\_streamers\_tx\_cfg4 & TX\_CFG4\\
0x5c& REG & Tx Config Reg 4 & wr\_streamers\_tx\_cfg5 & TX\_CFG5\\
0x60& REG & Rx Config Reg 0 & wr\_streamers\_rx\_cfg0 & RX\_CFG0\\
0x64& REG & Rx Config Reg 1 & wr\_streamers\_rx\_cfg1 & RX\_CFG1\\
0x68& REG & Rx Config Reg 2 & wr\_streamers\_rx\_cfg2 & RX\_CFG2\\
0x6c& REG & Rx Config Reg 3 & wr\_streamers\_rx\_cfg3 & RX\_CFG3\\
0x70& REG & Rx Config Reg 4 & wr\_streamers\_rx\_cfg4 & RX\_CFG4\\
0x74& REG & Rx Config Reg 5 & wr\_streamers\_rx\_cfg5 & RX\_CFG5\\
0x78& REG & TxRx Config Override & wr\_streamers\_cfg & CFG\\
0x7c& REG & DBG Control register & wr\_streamers\_dbg\_ctrl & DBG\_CTRL\\
0x80& REG & DBG Data & wr\_streamers\_dbg\_data & DBG\_DATA\\
0x84& REG & Test value & wr\_streamers\_dummy & DUMMY\\
\hline
\end{tabular}
}
\subsubsection{Register description}
\paragraph*{Version register}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_ver\\
{\bf HW address:} & 0x0\\
{\bf SW prefix:} & VER\\
{\bf SW offset:} & 0x0\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}ID[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}ID[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}ID[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}ID[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
ID
} [\emph{read/write}]: Version identifier
\\
Version identifier for the peripheral
\end{small}
\end{itemize}
\paragraph*{Statistics status and ctrl register}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_sscr1\\
{\bf HW address:} & 0x1\\
{\bf SW prefix:} & SSCR1\\
{\bf SW offset:} & 0x4\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RST\_TS\_CYC[27:20]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RST\_TS\_CYC[19:12]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RST\_TS\_CYC[11:4]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{4}{|c|}{\cellcolor{RoyalPurple!25}RST\_TS\_CYC[3:0]} & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_ACC\_OVERFLOW} & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}SNAPSHOT\_STATS} & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}RST\_SEQ\_ID} & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}RST\_STATS}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
RST\_STATS
} [\emph{write-only}]: Reset statistics
\\
Writing 1 reset counters, latency acc/max/min. This reset is timestamped
\end{small}
\item \begin{small}
{\bf
RST\_SEQ\_ID
} [\emph{write-only}]: Reset tx seq id
\\
Writing 1 reset sequence ID of transmitted frames
\end{small}
\item \begin{small}
{\bf
SNAPSHOT\_STATS
} [\emph{read/write}]: Snapshot statistics
\\
Writing 1 snapshots statistics for reading, it means that all the counters \\ are copied at the same instant to registers and this registers can be read\\ via wishbone/snmp while the counters are still running in the background. \\ this allows to read coherent data
\end{small}
\item \begin{small}
{\bf
RX\_LATENCY\_ACC\_OVERFLOW
} [\emph{read-only}]: Latency accumulator overflow
\\
Latency accumulator overflow - the lateny accumulator value is invalid
\end{small}
\item \begin{small}
{\bf
RST\_TS\_CYC
} [\emph{read-only}]: Reset timestamp cycles
\\
Timestamp of the last reset of stats (RST\_STAT) -- count of clock cycles
\end{small}
\end{itemize}
\paragraph*{Statistics status and ctrl register}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_sscr2\\
{\bf HW address:} & 0x2\\
{\bf SW prefix:} & SSCR2\\
{\bf SW offset:} & 0x8\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RST\_TS\_TAI\_LSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RST\_TS\_TAI\_LSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RST\_TS\_TAI\_LSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RST\_TS\_TAI\_LSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
RST\_TS\_TAI\_LSB
} [\emph{read-only}]: Reset timestamp 32 LSB of TAI
\\
Timestamp of the last reset of stats (RST\_STAT) -- LSB 32 bits of TAI
\end{small}
\end{itemize}
\paragraph*{Statistics status and ctrl register}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_sscr3\\
{\bf HW address:} & 0x3\\
{\bf SW prefix:} & SSCR3\\
{\bf SW offset:} & 0xc\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RST\_TS\_TAI\_MSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
RST\_TS\_TAI\_MSB
} [\emph{read-only}]: Reset timestamp 8 MSB of TAI
\\
Timestamp of the last reset of stats (RST\_STAT) -- MSB 8 bits of TAI
\end{small}
\end{itemize}
\paragraph*{Rx statistics}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_rx\_stat0\\
{\bf HW address:} & 0x4\\
{\bf SW prefix:} & RX\_STAT0\\
{\bf SW offset:} & 0x10\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & \multicolumn{4}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_MAX[27:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_MAX[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_MAX[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_MAX[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
RX\_LATENCY\_MAX
} [\emph{read-only}]: WR Streamer frame latency
\\
Maximum latency of received frames since reset
\end{small}
\end{itemize}
\paragraph*{Rx statistics}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_rx\_stat1\\
{\bf HW address:} & 0x5\\
{\bf SW prefix:} & RX\_STAT1\\
{\bf SW offset:} & 0x14\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & \multicolumn{4}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_MIN[27:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_MIN[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_MIN[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_MIN[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
RX\_LATENCY\_MIN
} [\emph{read-only}]: WR Streamer frame latency
\\
Minimum latency of received frames since reset
\end{small}
\end{itemize}
\paragraph*{Tx statistics}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_tx\_stat2\\
{\bf HW address:} & 0x6\\
{\bf SW prefix:} & TX\_STAT2\\
{\bf SW offset:} & 0x18\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}TX\_SENT\_CNT\_LSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}TX\_SENT\_CNT\_LSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}TX\_SENT\_CNT\_LSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}TX\_SENT\_CNT\_LSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
TX\_SENT\_CNT\_LSB
} [\emph{read-only}]: WR Streamer frame sent count (LSB)
\\
Number of sent wr streamer frames since reset
\end{small}
\end{itemize}
\paragraph*{Tx statistics}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_tx\_stat3\\
{\bf HW address:} & 0x7\\
{\bf SW prefix:} & TX\_STAT3\\
{\bf SW offset:} & 0x1c\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}TX\_SENT\_CNT\_MSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}TX\_SENT\_CNT\_MSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}TX\_SENT\_CNT\_MSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}TX\_SENT\_CNT\_MSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
TX\_SENT\_CNT\_MSB
} [\emph{read-only}]: WR Streamer frame sent count (MSB)
\\
Number of sent wr streamer frames since reset
\end{small}
\end{itemize}
\paragraph*{Rx statistics}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_rx\_stat4\\
{\bf HW address:} & 0x8\\
{\bf SW prefix:} & RX\_STAT4\\
{\bf SW offset:} & 0x20\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_RCVD\_CNT\_LSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_RCVD\_CNT\_LSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_RCVD\_CNT\_LSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_RCVD\_CNT\_LSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
RX\_RCVD\_CNT\_LSB
} [\emph{read-only}]: WR Streamer frame received count (LSB)
\\
Number of received wr streamer frames since reset
\end{small}
\end{itemize}
\paragraph*{Rx statistics}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_rx\_stat5\\
{\bf HW address:} & 0x9\\
{\bf SW prefix:} & RX\_STAT5\\
{\bf SW offset:} & 0x24\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_RCVD\_CNT\_MSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_RCVD\_CNT\_MSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_RCVD\_CNT\_MSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_RCVD\_CNT\_MSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
RX\_RCVD\_CNT\_MSB
} [\emph{read-only}]: WR Streamer frame received count (MSB)
\\
Number of received wr streamer frames since reset
\end{small}
\end{itemize}
\paragraph*{Rx statistics}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_rx\_stat6\\
{\bf HW address:} & 0xa\\
{\bf SW prefix:} & RX\_STAT6\\
{\bf SW offset:} & 0x28\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LOSS\_CNT\_LSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LOSS\_CNT\_LSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LOSS\_CNT\_LSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LOSS\_CNT\_LSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
RX\_LOSS\_CNT\_LSB
} [\emph{read-only}]: WR Streamer frame loss count (LSB)
\\
Number of lost wr streamer frames since reset
\end{small}
\end{itemize}
\paragraph*{Rx statistics}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_rx\_stat7\\
{\bf HW address:} & 0xb\\
{\bf SW prefix:} & RX\_STAT7\\
{\bf SW offset:} & 0x2c\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LOSS\_CNT\_MSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LOSS\_CNT\_MSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LOSS\_CNT\_MSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LOSS\_CNT\_MSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
RX\_LOSS\_CNT\_MSB
} [\emph{read-only}]: WR Streamer frame loss count (MSB)
\\
Number of lost wr streamer frames since reset
\end{small}
\end{itemize}
\paragraph*{Rx statistics}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_rx\_stat8\\
{\bf HW address:} & 0xc\\
{\bf SW prefix:} & RX\_STAT8\\
{\bf SW offset:} & 0x30\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LOST\_BLOCK\_CNT\_LSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LOST\_BLOCK\_CNT\_LSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LOST\_BLOCK\_CNT\_LSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LOST\_BLOCK\_CNT\_LSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
RX\_LOST\_BLOCK\_CNT\_LSB
} [\emph{read-only}]: WR Streamer block loss count (LSB)
\\
Number of indications that one or more blocks in a frame were lost (probably CRC\\ error) since reset
\end{small}
\end{itemize}
\paragraph*{Rx statistics}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_rx\_stat9\\
{\bf HW address:} & 0xd\\
{\bf SW prefix:} & RX\_STAT9\\
{\bf SW offset:} & 0x34\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LOST\_BLOCK\_CNT\_MSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LOST\_BLOCK\_CNT\_MSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LOST\_BLOCK\_CNT\_MSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LOST\_BLOCK\_CNT\_MSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
RX\_LOST\_BLOCK\_CNT\_MSB
} [\emph{read-only}]: WR Streamer block loss count (MSB)
\\
Number of indications that one or more blocks in a frame were lost (probably CRC\\ error) since reset
\end{small}
\end{itemize}
\paragraph*{Rx statistics}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_rx\_stat10\\
{\bf HW address:} & 0xe\\
{\bf SW prefix:} & RX\_STAT10\\
{\bf SW offset:} & 0x38\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_ACC\_LSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_ACC\_LSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_ACC\_LSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_ACC\_LSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
RX\_LATENCY\_ACC\_LSB
} [\emph{read-only}]: WR Streamer frame latency (LSB)
\\
Accumulated latency of received frames since reset
\end{small}
\end{itemize}
\paragraph*{Rx statistics}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_rx\_stat11\\
{\bf HW address:} & 0xf\\
{\bf SW prefix:} & RX\_STAT11\\
{\bf SW offset:} & 0x3c\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_ACC\_MSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_ACC\_MSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_ACC\_MSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_ACC\_MSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
RX\_LATENCY\_ACC\_MSB
} [\emph{read-only}]: WR Streamer frame latency (MSB)
\\
Accumulated latency of received frames since reset
\end{small}
\end{itemize}
\paragraph*{Rx statistics}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_rx\_stat12\\
{\bf HW address:} & 0x10\\
{\bf SW prefix:} & RX\_STAT12\\
{\bf SW offset:} & 0x40\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_ACC\_CNT\_LSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_ACC\_CNT\_LSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_ACC\_CNT\_LSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_ACC\_CNT\_LSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
RX\_LATENCY\_ACC\_CNT\_LSB
} [\emph{read-only}]: WR Streamer frame latency counter (LSB)
\\
Counter of the accumulated frequency (so avg can be calculated in SW) since reset
\end{small}
\end{itemize}
\paragraph*{Rx statistics}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_rx\_stat13\\
{\bf HW address:} & 0x11\\
{\bf SW prefix:} & RX\_STAT13\\
{\bf SW offset:} & 0x44\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_ACC\_CNT\_MSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_ACC\_CNT\_MSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_ACC\_CNT\_MSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}RX\_LATENCY\_ACC\_CNT\_MSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
RX\_LATENCY\_ACC\_CNT\_MSB
} [\emph{read-only}]: WR Streamer frame latency counter (MSB)
\\
Counter of the accumulated frequency (so avg can be calculated in SW) since reset
\end{small}
\end{itemize}
\paragraph*{Tx Config Reg 0}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_tx\_cfg0\\
{\bf HW address:} & 0x12\\
{\bf SW prefix:} & TX\_CFG0\\
{\bf SW offset:} & 0x48\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}ETHERTYPE[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}ETHERTYPE[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
ETHERTYPE
} [\emph{read/write}]: Ethertype
\end{small}
\end{itemize}
\paragraph*{Tx Config Reg 1}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_tx\_cfg1\\
{\bf HW address:} & 0x13\\
{\bf SW prefix:} & TX\_CFG1\\
{\bf SW offset:} & 0x4c\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_LOCAL\_LSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_LOCAL\_LSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_LOCAL\_LSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_LOCAL\_LSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
MAC\_LOCAL\_LSB
} [\emph{read/write}]: MAC Local LSB
\end{small}
\end{itemize}
\paragraph*{Tx Config Reg 2}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_tx\_cfg2\\
{\bf HW address:} & 0x14\\
{\bf SW prefix:} & TX\_CFG2\\
{\bf SW offset:} & 0x50\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_LOCAL\_MSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_LOCAL\_MSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
MAC\_LOCAL\_MSB
} [\emph{read/write}]: MAC Local MSB
\end{small}
\end{itemize}
\paragraph*{Tx Config Reg 3}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_tx\_cfg3\\
{\bf HW address:} & 0x15\\
{\bf SW prefix:} & TX\_CFG3\\
{\bf SW offset:} & 0x54\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_TARGET\_LSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_TARGET\_LSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_TARGET\_LSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_TARGET\_LSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
MAC\_TARGET\_LSB
} [\emph{read/write}]: MAC Target LSB
\end{small}
\end{itemize}
\paragraph*{Tx Config Reg 4}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_tx\_cfg4\\
{\bf HW address:} & 0x16\\
{\bf SW prefix:} & TX\_CFG4\\
{\bf SW offset:} & 0x58\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_TARGET\_MSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_TARGET\_MSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
MAC\_TARGET\_MSB
} [\emph{read/write}]: MAC Target MSB
\end{small}
\end{itemize}
\paragraph*{Tx Config Reg 4}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_tx\_cfg5\\
{\bf HW address:} & 0x17\\
{\bf SW prefix:} & TX\_CFG5\\
{\bf SW offset:} & 0x5c\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & \multicolumn{3}{|c|}{\cellcolor{RoyalPurple!25}QTAG\_PRIO[2:0]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & \multicolumn{4}{|c|}{\cellcolor{RoyalPurple!25}QTAG\_VID[11:8]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}QTAG\_VID[7:0]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}QTAG\_ENA}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
QTAG\_ENA
} [\emph{read/write}]: Enable tagging with Qtags
\end{small}
\item \begin{small}
{\bf
QTAG\_VID
} [\emph{read/write}]: VLAN ID
\end{small}
\item \begin{small}
{\bf
QTAG\_PRIO
} [\emph{read/write}]: Priority
\end{small}
\end{itemize}
\paragraph*{Rx Config Reg 0}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_rx\_cfg0\\
{\bf HW address:} & 0x18\\
{\bf SW prefix:} & RX\_CFG0\\
{\bf SW offset:} & 0x60\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}FILTER\_REMOTE} & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}ACCEPT\_BROADCAST}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}ETHERTYPE[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}ETHERTYPE[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
ETHERTYPE
} [\emph{read/write}]: Ethertype
\end{small}
\item \begin{small}
{\bf
ACCEPT\_BROADCAST
} [\emph{read/write}]: Accept Broadcast
\\
0: accept only unicasts; \\ 1: accept all broadcast packets
\end{small}
\item \begin{small}
{\bf
FILTER\_REMOTE
} [\emph{read/write}]: Filter Remote
\\
0: accept streamer frames with any source MAC address; \\ 1: accept streamer frames only with the source MAC address defined in mac\_remote
\end{small}
\end{itemize}
\paragraph*{Rx Config Reg 1}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_rx\_cfg1\\
{\bf HW address:} & 0x19\\
{\bf SW prefix:} & RX\_CFG1\\
{\bf SW offset:} & 0x64\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_LOCAL\_LSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_LOCAL\_LSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_LOCAL\_LSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_LOCAL\_LSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
MAC\_LOCAL\_LSB
} [\emph{read/write}]: MAC Local LSB
\end{small}
\end{itemize}
\paragraph*{Rx Config Reg 2}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_rx\_cfg2\\
{\bf HW address:} & 0x1a\\
{\bf SW prefix:} & RX\_CFG2\\
{\bf SW offset:} & 0x68\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_LOCAL\_MSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_LOCAL\_MSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
MAC\_LOCAL\_MSB
} [\emph{read/write}]: MAC Local MSB
\end{small}
\end{itemize}
\paragraph*{Rx Config Reg 3}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_rx\_cfg3\\
{\bf HW address:} & 0x1b\\
{\bf SW prefix:} & RX\_CFG3\\
{\bf SW offset:} & 0x6c\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_REMOTE\_LSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_REMOTE\_LSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_REMOTE\_LSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_REMOTE\_LSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
MAC\_REMOTE\_LSB
} [\emph{read/write}]: MAC Remote LSB
\end{small}
\end{itemize}
\paragraph*{Rx Config Reg 4}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_rx\_cfg4\\
{\bf HW address:} & 0x1c\\
{\bf SW prefix:} & RX\_CFG4\\
{\bf SW offset:} & 0x70\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_REMOTE\_MSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}MAC\_REMOTE\_MSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
MAC\_REMOTE\_MSB
} [\emph{read/write}]: MAC Remote MSB
\end{small}
\end{itemize}
\paragraph*{Rx Config Reg 5}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_rx\_cfg5\\
{\bf HW address:} & 0x1d\\
{\bf SW prefix:} & RX\_CFG5\\
{\bf SW offset:} & 0x74\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & \multicolumn{4}{|c|}{\cellcolor{RoyalPurple!25}FIXED\_LATENCY[27:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}FIXED\_LATENCY[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}FIXED\_LATENCY[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}FIXED\_LATENCY[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
FIXED\_LATENCY
} [\emph{read/write}]: Fixed Latency
\\
This register allows to configure fixed-latency. If the value is other than zero, the instant of outputing the received data from the rx streamer to the user application is delayed, so that the time-difference between the transmission fo the data and the output to the user matches the provided value. If the configured latency value is smaller than the network latency, the data is provided to the user instantly. The configuration value is expressed in clock cycles (16ns)
\end{small}
\end{itemize}
\paragraph*{TxRx Config Override}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_cfg\\
{\bf HW address:} & 0x1e\\
{\bf SW prefix:} & CFG\\
{\bf SW offset:} & 0x78\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{1}{|c}{-} & - & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}OR\_RX\_FIX\_LAT} & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}OR\_RX\_FTR\_REMOTE} & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}OR\_RX\_ACC\_BROADCAST} & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}OR\_RX\_MAC\_REM} & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}OR\_RX\_MAC\_LOC} & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}OR\_RX\_ETHERTYPE}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}OR\_TX\_QTAG} & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}OR\_TX\_MAC\_TAR} & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}OR\_TX\_MAC\_LOC} & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}OR\_TX\_ETHTYPE}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
OR\_TX\_ETHTYPE
} [\emph{read/write}]: Tx Ethertype
\\
Overrides default/application Tx Ethertype configuration with configuration in the proper register:\\ 0: Default/set by application; \\ 1: Value from WB register
\end{small}
\item \begin{small}
{\bf
OR\_TX\_MAC\_LOC
} [\emph{read/write}]: Tx MAC Local
\\
Overrides default/application Tx local MAC configuration with configuration in the proper register:\\ 0: Default/set by application; \\ 1: Value from WB register
\end{small}
\item \begin{small}
{\bf
OR\_TX\_MAC\_TAR
} [\emph{read/write}]: Tx MAC Target
\\
Overrides default/application Tx target MAC configuration with configuration in the proper register:\\ 0: Default/set by application; \\ 1: Value from WB register
\end{small}
\item \begin{small}
{\bf
OR\_TX\_QTAG
} [\emph{read/write}]: QTAG
\\
Overrides default/application QTAG values with configuration in the proper register:\\ 0: Default/set by application; \\ 1: Value from WB register
\end{small}
\item \begin{small}
{\bf
OR\_RX\_ETHERTYPE
} [\emph{read/write}]: Rx Ethertype
\\
Overrides default/application Rx Ethertype configuration with configuration in the proper register:\\ 0: Default/set by application; \\ 1: Value from WB register
\end{small}
\item \begin{small}
{\bf
OR\_RX\_MAC\_LOC
} [\emph{read/write}]: Rx MAC Local
\\
Overrides default/application Rx MAC Local configuration with configuration in the proper register:\\ 0: Default/set by application; \\ 1: Value from WB register
\end{small}
\item \begin{small}
{\bf
OR\_RX\_MAC\_REM
} [\emph{read/write}]: Rx MAC Remote
\\
Overrides default/application Rx MAC Remote configuration with configuration in the proper register:\\ 0: Default/set by application; \\ 1: Value from WB register
\end{small}
\item \begin{small}
{\bf
OR\_RX\_ACC\_BROADCAST
} [\emph{read/write}]: Rx Accept Broadcast
\\
Overrides default/application Rx Accept Broardcast configuration with configuration in the proper register:\\ 0: Default/set by application; \\ 1: Value from WB register
\end{small}
\item \begin{small}
{\bf
OR\_RX\_FTR\_REMOTE
} [\emph{read/write}]: Rx Filter Remote
\\
Overrides default/application Rx Filter Remote configuration with configuration in the proper register:\\ 0: Default/set by application; \\ 1: Value from WB register
\end{small}
\item \begin{small}
{\bf
OR\_RX\_FIX\_LAT
} [\emph{read/write}]: Rx Fixed Latency
\\
Overrides default/application Rx fixed latency configuration with configuration in the proper register:\\ 0: Default/set by application; \\ 1: Value from WB register
\end{small}
\end{itemize}
\paragraph*{DBG Control register}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_dbg\_ctrl\\
{\bf HW address:} & 0x1f\\
{\bf SW prefix:} & DBG\_CTRL\\
{\bf SW offset:} & 0x7c\\
\end{tabular}
\vspace{12pt}
This register is meant to control simple debugging of transmitted or received data.\\ It allows to sniff a 32-bit word at a configurable offset from received or transmitted data.
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}START\_BYTE[7:0]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}MUX}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
MUX
} [\emph{read/write}]: Debug Tx (0) or Rx (1)
\end{small}
\item \begin{small}
{\bf
START\_BYTE
} [\emph{read/write}]: Debug Start byte
\\
The offset, in bytes, from which the 32-bit word is read.
\end{small}
\end{itemize}
\paragraph*{DBG Data}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_dbg\_data\\
{\bf HW address:} & 0x20\\
{\bf SW prefix:} & DBG\_DATA\\
{\bf SW offset:} & 0x80\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}DBG\_DATA[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}DBG\_DATA[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}DBG\_DATA[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}DBG\_DATA[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
DBG\_DATA
} [\emph{read-only}]: Debug content
\end{small}
\end{itemize}
\paragraph*{Test value}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wr\_streamers\_dummy\\
{\bf HW address:} & 0x21\\
{\bf SW prefix:} & DUMMY\\
{\bf SW offset:} & 0x84\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}DUMMY[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}DUMMY[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}DUMMY[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}DUMMY[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
DUMMY
} [\emph{read-only}]: DUMMY value to read
\end{small}
\end{itemize}
\subsection{WR Core Diagnostics}
\label{subsec:wbgen:wrc_diags}
[version 0x00000001]\\
Diagnostics information accessible via WR
\subsubsection{Memory map summary}
\rowcolors{2}{gray!25}{white}
\resizebox{\textwidth}{!}{
\begin{tabular}{|l|l|l|l|l|}
\rowcolor{RoyalPurple}
\color{white} SW Offset & \color{white} Type & \color{white} Name &
\color{white} HW prefix & \color{white} C prefix\\
0x0& REG & Version register & wrc\_diags\_ver & VER\\
0x4& REG & Ctrl & wrc\_diags\_ctrl & CTRL\\
0x8& REG & WRPC Diag: servo status & wrc\_diags\_wdiag\_sstat & WDIAG\_SSTAT\\
0xc& REG & WRPC Diag: Port status & wrc\_diags\_wdiag\_pstat & WDIAG\_PSTAT\\
0x10& REG & WRPC Diag: PTP state & wrc\_diags\_wdiag\_ptpstat & WDIAG\_PTPSTAT\\
0x14& REG & WRPC Diag: AUX state & wrc\_diags\_wdiag\_astat & WDIAG\_ASTAT\\
0x18& REG & WRPC Diag: Tx PTP Frame cnts & wrc\_diags\_wdiag\_txfcnt & WDIAG\_TXFCNT\\
0x1c& REG & WRPC Diag: Rx PTP Frame cnts & wrc\_diags\_wdiag\_rxfcnt & WDIAG\_RXFCNT\\
0x20& REG & WRPC Diag:local time [msb of s] & wrc\_diags\_wdiag\_sec\_msb & WDIAG\_SEC\_MSB\\
0x24& REG & WRPC Diag: local time [lsb of s] & wrc\_diags\_wdiag\_sec\_lsb & WDIAG\_SEC\_LSB\\
0x28& REG & WRPC Diag: local time [ns] & wrc\_diags\_wdiag\_ns & WDIAG\_NS\\
0x2c& REG & WRPC Diag: Round trip (mu) [msb of ps] & wrc\_diags\_wdiag\_mu\_msb & WDIAG\_MU\_MSB\\
0x30& REG & WRPC Diag: Round trip (mu) [lsb of ps] & wrc\_diags\_wdiag\_mu\_lsb & WDIAG\_MU\_LSB\\
0x34& REG & WRPC Diag: Master-slave delay (dms) [msb of ps] & wrc\_diags\_wdiag\_dms\_msb & WDIAG\_DMS\_MSB\\
0x38& REG & WRPC Diag: Master-slave delay (dms) [lsb of ps] & wrc\_diags\_wdiag\_dms\_lsb & WDIAG\_DMS\_LSB\\
0x3c& REG & WRPC Diag: Total link asymmetry [ps] & wrc\_diags\_wdiag\_asym & WDIAG\_ASYM\\
0x40& REG & WRPC Diag: Clock offset (cko) [ps] & wrc\_diags\_wdiag\_cko & WDIAG\_CKO\\
0x44& REG & WRPC Diag: Phase setpoint (setp) [ps] & wrc\_diags\_wdiag\_setp & WDIAG\_SETP\\
0x48& REG & WRPC Diag: Update counter (ucnt) & wrc\_diags\_wdiag\_ucnt & WDIAG\_UCNT\\
0x4c& REG & WRPC Diag: Board temperature [C degree] & wrc\_diags\_wdiag\_temp & WDIAG\_TEMP\\
\hline
\end{tabular}
}
\subsubsection{Register description}
\paragraph*{Version register}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_ver\\
{\bf HW address:} & 0x0\\
{\bf SW prefix:} & VER\\
{\bf SW offset:} & 0x0\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}ID[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}ID[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}ID[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}ID[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
ID
} [\emph{read/write}]: Version identifier
\\
Version identifier for the peripheral
\end{small}
\end{itemize}
\paragraph*{Ctrl}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_ctrl\\
{\bf HW address:} & 0x1\\
{\bf SW prefix:} & CTRL\\
{\bf SW offset:} & 0x4\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}DATA\_SNAPSHOT}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}DATA\_VALID}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
DATA\_VALID
} [\emph{read-only}]: WR DIAG data valid
\\
0: valid\\ 1:transcient
\end{small}
\item \begin{small}
{\bf
DATA\_SNAPSHOT
} [\emph{read/write}]: WR DIAG data snapshot
\\
1: snapshot data (data in registers will not change aveter VALID becomes true)
\end{small}
\end{itemize}
\paragraph*{WRPC Diag: servo status}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_wdiag\_sstat\\
{\bf HW address:} & 0x2\\
{\bf SW prefix:} & WDIAG\_SSTAT\\
{\bf SW offset:} & 0x8\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & \multicolumn{4}{|c|}{\cellcolor{RoyalPurple!25}SERVOSTATE[3:0]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}WR\_MODE}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
WR\_MODE
} [\emph{read-only}]: WR valid
\\
0: not valid\\ 1:valid
\end{small}
\item \begin{small}
{\bf
SERVOSTATE
} [\emph{read-only}]: Servo State
\\
0: Uninitialized\\ 1: SYNC\_NSEC\\ 2: SYNC\_TAI\\ 3: SYNC\_PHASE\\ 4: TRACK\_PHASE\\ 5: WAIT\_OFFSET\_STABLE
\end{small}
\end{itemize}
\paragraph*{WRPC Diag: Port status}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_wdiag\_pstat\\
{\bf HW address:} & 0x3\\
{\bf SW prefix:} & WDIAG\_PSTAT\\
{\bf SW offset:} & 0xc\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}LOCKED} & \multicolumn{1}{|c|}{\cellcolor{RoyalPurple!25}LINK}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
LINK
} [\emph{read-only}]: Link Status
\\
0: link down\\ 1: link up
\end{small}
\item \begin{small}
{\bf
LOCKED
} [\emph{read-only}]: PLL Locked
\\
0: not locked\\ 1: locked
\end{small}
\end{itemize}
\paragraph*{WRPC Diag: PTP state}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_wdiag\_ptpstat\\
{\bf HW address:} & 0x4\\
{\bf SW prefix:} & WDIAG\_PTPSTAT\\
{\bf SW offset:} & 0x10\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}PTPSTATE[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
PTPSTATE
} [\emph{read-only}]: PTP State
\\
0: NONE\\ 1: PPS\_INITIALIZING\\ 2: PPS\_FAULTY\\ 3: disabled\\ 4: PPS\_LISTENING\\ 5: PPS\_PRE\_MASTER\\ 6: PPS\_MASTER\\ 7: PPS\_PASSIVE\\ 8: PPS\_UNCALIBRATED\\ 9: PPS\_SLAVE\\ 100-116: WR STATES\\ see: ppsi/proto-ext-whiterabbit/wr-constants.h\\ ppsi/include/ppsi/ieee1588\_types.h
\end{small}
\end{itemize}
\paragraph*{WRPC Diag: AUX state}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_wdiag\_astat\\
{\bf HW address:} & 0x5\\
{\bf SW prefix:} & WDIAG\_ASTAT\\
{\bf SW offset:} & 0x14\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{1}{|c}{-} & - & - & - & - & - & - & \multicolumn{1}{c|}{-}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}AUX[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
AUX
} [\emph{read-only}]: AUX channel
\\
A vector of bits, one bit per channel\\ 0: not valid\\ 1:valid
\end{small}
\end{itemize}
\paragraph*{WRPC Diag: Tx PTP Frame cnts}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_wdiag\_txfcnt\\
{\bf HW address:} & 0x6\\
{\bf SW prefix:} & WDIAG\_TXFCNT\\
{\bf SW offset:} & 0x18\\
\end{tabular}
\vspace{12pt}
Number of transmitted PTP Frames
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_TXFCNT[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_TXFCNT[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_TXFCNT[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_TXFCNT[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
WDIAG\_TXFCNT
} [\emph{read-only}]: Data
\end{small}
\end{itemize}
\paragraph*{WRPC Diag: Rx PTP Frame cnts}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_wdiag\_rxfcnt\\
{\bf HW address:} & 0x7\\
{\bf SW prefix:} & WDIAG\_RXFCNT\\
{\bf SW offset:} & 0x1c\\
\end{tabular}
\vspace{12pt}
Number of received PTP Frames
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_RXFCNT[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_RXFCNT[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_RXFCNT[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_RXFCNT[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
WDIAG\_RXFCNT
} [\emph{read-only}]: Data
\end{small}
\end{itemize}
\paragraph*{WRPC Diag:local time [msb of s]}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_wdiag\_sec\_msb\\
{\bf HW address:} & 0x8\\
{\bf SW prefix:} & WDIAG\_SEC\_MSB\\
{\bf SW offset:} & 0x20\\
\end{tabular}
\vspace{12pt}
Local Time expressed in seconds since epoch (TAI)
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_SEC\_MSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_SEC\_MSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_SEC\_MSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_SEC\_MSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
WDIAG\_SEC\_MSB
} [\emph{read-only}]: Data
\end{small}
\end{itemize}
\paragraph*{WRPC Diag: local time [lsb of s]}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_wdiag\_sec\_lsb\\
{\bf HW address:} & 0x9\\
{\bf SW prefix:} & WDIAG\_SEC\_LSB\\
{\bf SW offset:} & 0x24\\
\end{tabular}
\vspace{12pt}
Local Time expressed in seconds since epoch (TAI)
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_SEC\_LSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_SEC\_LSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_SEC\_LSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_SEC\_LSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
WDIAG\_SEC\_LSB
} [\emph{read-only}]: Data
\end{small}
\end{itemize}
\paragraph*{WRPC Diag: local time [ns]}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_wdiag\_ns\\
{\bf HW address:} & 0xa\\
{\bf SW prefix:} & WDIAG\_NS\\
{\bf SW offset:} & 0x28\\
\end{tabular}
\vspace{12pt}
Nanoseconds part of the Local Time expressed in seconds since epoch (TAI)
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_NS[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_NS[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_NS[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_NS[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
WDIAG\_NS
} [\emph{read-only}]: Data
\end{small}
\end{itemize}
\paragraph*{WRPC Diag: Round trip (mu) [msb of ps]}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_wdiag\_mu\_msb\\
{\bf HW address:} & 0xb\\
{\bf SW prefix:} & WDIAG\_MU\_MSB\\
{\bf SW offset:} & 0x2c\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_MU\_MSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_MU\_MSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_MU\_MSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_MU\_MSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
WDIAG\_MU\_MSB
} [\emph{read-only}]: Data
\end{small}
\end{itemize}
\paragraph*{WRPC Diag: Round trip (mu) [lsb of ps]}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_wdiag\_mu\_lsb\\
{\bf HW address:} & 0xc\\
{\bf SW prefix:} & WDIAG\_MU\_LSB\\
{\bf SW offset:} & 0x30\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_MU\_LSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_MU\_LSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_MU\_LSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_MU\_LSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
WDIAG\_MU\_LSB
} [\emph{read-only}]: Data
\end{small}
\end{itemize}
\paragraph*{WRPC Diag: Master-slave delay (dms) [msb of ps]}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_wdiag\_dms\_msb\\
{\bf HW address:} & 0xd\\
{\bf SW prefix:} & WDIAG\_DMS\_MSB\\
{\bf SW offset:} & 0x34\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_DMS\_MSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_DMS\_MSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_DMS\_MSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_DMS\_MSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
WDIAG\_DMS\_MSB
} [\emph{read-only}]: Data
\end{small}
\end{itemize}
\paragraph*{WRPC Diag: Master-slave delay (dms) [lsb of ps]}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_wdiag\_dms\_lsb\\
{\bf HW address:} & 0xe\\
{\bf SW prefix:} & WDIAG\_DMS\_LSB\\
{\bf SW offset:} & 0x38\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_DMS\_LSB[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_DMS\_LSB[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_DMS\_LSB[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_DMS\_LSB[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
WDIAG\_DMS\_LSB
} [\emph{read-only}]: Data
\end{small}
\end{itemize}
\paragraph*{WRPC Diag: Total link asymmetry [ps]}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_wdiag\_asym\\
{\bf HW address:} & 0xf\\
{\bf SW prefix:} & WDIAG\_ASYM\\
{\bf SW offset:} & 0x3c\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_ASYM[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_ASYM[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_ASYM[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_ASYM[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
WDIAG\_ASYM
} [\emph{read-only}]: Data
\end{small}
\end{itemize}
\paragraph*{WRPC Diag: Clock offset (cko) [ps]}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_wdiag\_cko\\
{\bf HW address:} & 0x10\\
{\bf SW prefix:} & WDIAG\_CKO\\
{\bf SW offset:} & 0x40\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_CKO[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_CKO[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_CKO[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_CKO[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
WDIAG\_CKO
} [\emph{read-only}]: Data
\end{small}
\end{itemize}
\paragraph*{WRPC Diag: Phase setpoint (setp) [ps]}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_wdiag\_setp\\
{\bf HW address:} & 0x11\\
{\bf SW prefix:} & WDIAG\_SETP\\
{\bf SW offset:} & 0x44\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_SETP[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_SETP[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_SETP[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_SETP[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
WDIAG\_SETP
} [\emph{read-only}]: Data
\end{small}
\end{itemize}
\paragraph*{WRPC Diag: Update counter (ucnt)}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_wdiag\_ucnt\\
{\bf HW address:} & 0x12\\
{\bf SW prefix:} & WDIAG\_UCNT\\
{\bf SW offset:} & 0x48\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_UCNT[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_UCNT[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_UCNT[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_UCNT[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
WDIAG\_UCNT
} [\emph{read-only}]: Data
\end{small}
\end{itemize}
\paragraph*{WRPC Diag: Board temperature [C degree]}\mbox{}\\\vskip 6pt
\rowcolors{1}{white}{white}
\begin{tabular}{l l }
{\bf HW prefix:} & wrc\_diags\_wdiag\_temp\\
{\bf HW address:} & 0x13\\
{\bf SW prefix:} & WDIAG\_TEMP\\
{\bf SW offset:} & 0x4c\\
\end{tabular}
\vspace{12pt}
\noindent
\resizebox{\textwidth}{!}{
\begin{tabular}{>{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} >{\centering\arraybackslash}p{1.5cm} }
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_TEMP[31:24]}\\
\hline
23 & 22 & 21 & 20 & 19 & 18 & 17 & 16\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_TEMP[23:16]}\\
\hline
15 & 14 & 13 & 12 & 11 & 10 & 9 & 8\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_TEMP[15:8]}\\
\hline
7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
\multicolumn{8}{|c|}{\cellcolor{RoyalPurple!25}WDIAG\_TEMP[7:0]}\\
\hline
\end{tabular}
}
\begin{itemize}
\item \begin{small}
{\bf
WDIAG\_TEMP
} [\emph{read-only}]: Data
\end{small}
\end{itemize}
\documentclass[a4paper, 12pt]{article}
\usepackage[english]{babel}
\usepackage{fullpage}
\usepackage[table,x11names,dvipsnames,table]{xcolor}
\usepackage{pgf}
\usepackage{tikz}
\usepackage[pdftex]{hyperref} % makes cross references and URLs clickable
......@@ -82,7 +83,7 @@ basicstyle=\footnotesize\ttfamily, backgroundcolor=\color{light-gray}, label=lst
\end{center}
}
\def \wrpcrelease {wrpc-v4.0}
\def \wrpcrelease {wrpc-v4.1}
\newcommand{\code}[1]{\texttt{#1}}
......@@ -187,7 +188,7 @@ following locations:
\end{itemize*}
Repositories containing the WRPC gateware and software (\textit{wr-cores},
\textit{wrpc-sw}) are tagged with \texttt{wrpc-v4.0} tag. Other tools used to
\textit{wrpc-sw}) are tagged with \texttt{wrpc-v4.1} tag. Other tools used to
build the core and load it into the FPGA should be used in their newest stable
releases, unless otherwise stated.
......@@ -208,6 +209,8 @@ can be chosen:
\item \href{http://www.ohwr.org/projects/vfc-hd}{VFC-HD VME board} +
\href{http://www.ohwr.org/projects/fmc-dio-5chttla}{FMC DIO card} +
VME crate with a single board computer running Linux\footref{note_a20}
\item \href{http://www.ohwr.org/projects/fasec}{FASEC board} +
\href{http://www.ohwr.org/projects/fmc-dio-5chttla}{FMC DIO card}
\end{itemize}
To be able to test White Rabbit synchronization you would also need
......@@ -277,7 +280,7 @@ following command should be executed:
$ export PATH=/opt/altera/16.0/quartus/bin:$PATH
\end{lstlisting}
\subsubsection{Downloading the sources and running the synthesis}
\subsubsection{Downloading the sources}
Thanks to the \textit{hdlmake} tool, the synthesis process for the reference
designs does not differ between Xilinx and Altera/Intel based boards. The tool creates
synthesis Makefile as well as ISE/Quartus project file based on a set of
......@@ -307,13 +310,13 @@ $ chmod a+x /usr/bin/hdlmake
\end{lstlisting}
Having all the tools in place, you can now clone the main WR PTP Core git
repository for the v4.0 release. The set of commands below clones the WR PTP Core
repository for the v4.1 release. The set of commands below clones the WR PTP Core
repository, checks out the release tag, and downloads other HDL repositories
(submodules) needed to synthesize the core:
\begin{lstlisting}
$ git clone git://ohwr.org/hdl-core-lib/wr-cores.git <your_location>/wr-cores
$ cd <your_location>/wr-cores
$ git checkout wrpc-v4.0
$ git checkout wrpc-v4.1
$ git submodule init
$ git submodule update
\end{lstlisting}
......@@ -328,7 +331,7 @@ The local copies of the submodules are stored to:
repository. Please refer to the project's documentation to find out which
version of this package you need to build.
\vspace{1em}
\subsubsection{Running the synthesis (ISE, Quartus)}
The subdirectory you should enter to run the synthesis depends on the hardware
platform you use:
\begin{itemize*}
......@@ -378,6 +381,41 @@ scratch you can use the following commands:
\texttt{*.sof} files;
\end{itemize*}
\subsubsection{Running the synthesis (Vivado)}
The workflow in Xilinx Vivado is different than for ISE and Quartus. It is
heavily based on packed IP cores and schematic entry. Therefore, if you would
like to synthesize the reference design for Zynq (FASEC board), you
need to go through two Vivado projects:
\begin{itemize*}
\item \texttt{<your\_location>/wr-cores/syn/wrc\_board\_fasec\_ip} - is a
project created with \textit{hdlmake} from all HDL files necessary to
synthesize the WR PTP Core with all its peripherals for Zynq (Kintex-7 FPGA).
The project contains also IP-XACT module description to generate Vivado IP
Core for further synthesis with a complete FASEC reference design.
\item \texttt{<your\_location>/wr-cores/syn/fasec\_ref\_design} - is a main
reference design project for FASEC board. It is made with the Vivado Block
Design instantiating Processing System, reset circuits, AXI interconnects
and WR PTP Core IP generated from \texttt{wrc\_board\_fasec\_ip} project.
\end{itemize*}
First, please execute the \texttt{build.tcl} script in Vivado batch mode
\footnote{You can also use Tools->Run Tcl Script... from Vivado gui} to create
WR PTP Core IP:
\begin{lstlisting}
$ cd <your_location>/wr-cores/syn/wrc_board_fasec_ip
$ vivado -mode batch -source build.tcl
\end{lstlisting}
After this step, you can generate the main reference design Vivado project,
using Tcl scripts in the repository:
\begin{lstlisting}
$ cd <your_location>/wr-cores/syn/fasec_ref_design
$ vivado -mode batch -source build.tcl
\end{lstlisting}
Open the project file \texttt{fasec\_ref\_design.xpr} and continue with regular
Vivado flow to synthesize the bitstream.
% ==========================================================================
\subsection{LM32 software compilation}
\label{LM32 software compilation}
......@@ -388,6 +426,11 @@ synthesized in section \ref{HDL synthesis}. You can skip this section, unless
you need to make some custom changes to the LM32 software and compile it
yourself.\\
\textbf{Note:} To compile also the host tools that come with this software
package you will need a \emph{readline-dev} library. In some Linux distributions
you would have to install it manually. E.g. in Ubuntu, please install
\emph{libreadline-dev} package.\\
First, you need to download and unpack the LM32 toolchain from the location
mentioned in section \ref{Repositories and Releases}. The following example
uses 32bit version of a toolchain. If you encounter problems running it, please
......@@ -404,13 +447,13 @@ $ export CROSS_COMPILE="<your_location>/lm32/bin/lm32-elf-"
\end{lstlisting}
To get the sources of the WRPC software, please clone the \textit{wrpc-sw} git
repository tagged with \texttt{wrpc-v4.0} tag. The commands in the listing below
repository tagged with \texttt{wrpc-v4.1} tag. The commands in the listing below
clone the \textit{wrpc-sw} repository together with submodules needed for this software.\\
\begin{lstlisting}
$ git clone git://ohwr.org/hdl-core-lib/wr-cores/wrpc-sw.git \
<your_location>/wrpc-sw
$ cd <your_location>/wrpc-sw
$ git checkout wrpc-v4.0
$ git checkout wrpc-v4.1
\end{lstlisting}
\textbf{Note:} If you use WRPC within another project, you may need to checkout
......@@ -423,7 +466,7 @@ run one of the following commands (the first two are text-mode, the third uses
a KDE GUI and the fourth uses a Gnome GUI):
\begin{lstlisting}
$ make menuconfig
$ make nonfig
$ make config
$ make xconfig
$ make gconfig
\end{lstlisting}
......@@ -481,7 +524,7 @@ slot.\\
\begin{lstlisting}
$ git clone git://ohwr.org/fmc-projects/spec/spec-sw.git <your_location>/spec-sw
$ cd <your_location>/spec-sw
$ git checkout aff79eb
$ git checkout 0745464
$ make
\end{lstlisting}
......@@ -512,35 +555,6 @@ Among plenty of messages you should be able to find something very similar to:
[1275527.296757] Product name: FmcDio5cha
\end{lstlisting}
By default, when loading the \textit{spec.ko} driver, FPGA gets programmed with
the "golden" bitstream. Starting from version 3.0, WR PTP Core uses a flash
memory chip on the carrier as a default place for storing the calibration
parameters and the init script. Also the storage format of this information is
now better organized in the files of the SDBFS filesystem. Therefore, starting
from v3.0 you have to write the SDBFS filesystem image to the flash
before running the WRPC. You can download the image from \textit{ohwr.org}:
\begin{lstlisting}
$ wget http://www.ohwr.org/attachments/download/4060/sdbfs-flash.bin
\end{lstlisting}
It contains all the files required by the core. They are empty, but have to
exist in the SDBFS structure to be written later as described in section
\ref{Writing configuration}. To write the filesystem image to flash, please
execute the following command:
\begin{lstlisting}
$ sudo tools/flash-write -c 0x0 0 1507712 < <your_location>/sdbfs-flash.bin
\end{lstlisting}
\noindent\textbf{Note:} If you have more than one SPEC board in your computer,
you can use \code{-b} parameter which takes the PCI bus address of the card you
want to program. This can be found in the list of the PCI devices installed in
the system (\code{lspci}).
\noindent\textbf{Note:} Please refer to section \ref{Writing SDBFS image in
standalone configuration} for instructions on how to write the SDBFS image to a
standalone SPEC or custom hardware.\\
Now, you are ready to program the FPGA with your synthesized bitstream from
\texttt{<your\_location>/wr-cores/syn/spec\_ref\_design/spec\_wr\_ref\_top.bin}
\begin{lstlisting}
......@@ -562,16 +576,39 @@ WRPC shell:
\begin{lstlisting}
$ sudo tools/spec-vuart
\end{lstlisting}
If you are able to see the shell prompt \textit{wrc\#} this means the Core
is up and running on your SPEC card. Congratulations !
is up and running on your SPEC card. Congratulations !\\
Starting from version 3.0, WR PTP Core uses a flash memory chip on the carrier
as a default place for storing calibration parameters and an init script.
The storage format of this information is organized in SDBFS filesystem.
Therefore, starting from v3.0 you have to write the empty
SDBFS filesystem image to the flash before running the WRPC. The simplest way of
doing this is by calling a WR PTP Core shell command:
\begin{lstlisting}
wrc# sdb fs 0
\end{lstlisting}
You should see the output similar to:
\begin{lstlisting}[basicstyle=\scriptsize\ttfamily]
filename: . ; first: 2e0000; last: 32007f
filename: wr-init ; first: 2f0000; last: 2f00ff
filename: calibration ; first: 300000; last: 30007f
filename: mac-address ; first: 310000; last: 310005
filename: sfp-database ; first: 320000; last: 32007f
Formatting SDBFS in Flash(0x2e0000)...
\end{lstlisting}
The other two methods: through the PCIe bus and using a Xilinx JTAG cable are
described in appendix \ref{appendix:writing_sdbfs}.
% ==========================================================================
\subsection{Programming FPGA on other boards}
Currently the driver packages for SVEC and VFC-HD boards depend on other CERN
drivers and front-end infrastructure. We are working to make them exportable. If
you are a CERN user of SVEC or VFC-HD board, please check
you are a CERN user of SVEC, VFC-HD board or SPEC in a Front-end computer,
please check
\url{https://wikis.cern.ch/display/HT/WR+Nodes} (accessible \textbf{only} from
CERN network) for more instructions. If you are outside CERN and would like to
use one of these boards, please contact us.
......@@ -626,15 +663,15 @@ $\Delta_{TX}$, $\Delta_{RX}$ and $\alpha$ parameters associated with them.
\begin{lstlisting}
wrc# sfp erase
wrc# sfp add AXGE-1254-0531 180667 148735 72169888
wrc# sfp add AXGE-3454-0531 180667 148735 -73685416
wrc# sfp add AXGE-1254-0531 180750 148326 72169888
wrc# sfp add AXGE-3454-0531 180750 148326 -73685416
\end{lstlisting}
To check the content of the SFP database you can execute the \textit{sfp show}
shell command.\\
\noindent\textbf{Note:} The $\Delta_{TX}$ and $\Delta_{RX}$ parameters above are
the defaults for wrpc-v4.0 release bitstream available on \textit{ohwr.org},
the defaults for wrpc-v4.1 release bitstream available on \textit{ohwr.org},
running on the SPEC v4 board and calibrated to port 1 of a~WR Switch
v3.3. These values as well as the default parameters for other boards are
available on the calibration wiki page
......@@ -671,33 +708,67 @@ Cesium clock). Depending on your board you should connect:
\end{itemize*}
\vspace{1em}
One option is to type by hand all the commands needed to initialize the WRPC software to
the required state every time the core starts. However, you can also write your
own initialization script and save it to the Flash/EEPROM. It will be executed every time
the WRPC software starts. A~simple script, that loads the calibration
parameters, configures the WR mode to Slave, starts the PTP daemon and sets
the IP address is presented below:
WRPC has a possibility to load user-defined intialization script on every
startup. If you run WRPC release v4.1 or higher, the default LM32 software
comes with a built-in init script. The default script disables VLAN support,
loads calibration values from the SFP database (provided that it was written
earlier by the user) and starts PTP in slave mode. Here are the actual WRPC
shell commands executed from the built-in init script:
\begin{lstlisting}
vlan off
ptp stop
sfp match
mode slave
ptp start
\end{lstlisting}
You can still define your own init script that will be saved in the
Flash/EEPROM memory attached to the WRPC. In that case, user-defined set of
commands is executed after the built-in script. For example, if you would
like to expand the default configuration by your own script that assigns an IP
address, you need to to execute the following WRPC shell commands:
\begin{lstlisting}
wrc# init erase
wrc# init add ip set 192.168.1.5
\end{lstlisting}
Another typical situation would be configuring the WRPC to run in GrandMaster or
Master mode. In this case, assuming you also want to configure the IP address
(like in the previous example) you would need to run the following WRPC shell
commands:
\begin{lstlisting}
wrc# init erase
wrc# init add ptp stop
wrc# init add sfp match
wrc# init add mode slave
wrc# init add mode master # for Free-running Master mode or
wrc# init add mode gm #for GrandMaster mode
wrc# init add ptp start
wrc# init add ip set 192.168.1.5
\end{lstlisting}
Almost exactly the same one can be used for running WRPC in the GrandMaster
or Master mode. The only difference would be changing the
\texttt{init add mode slave} line to \texttt{init add mode gm} or
\texttt{init add mode master}.
You can always check the content of the built-in and user-defined init scripts
by calling \texttt{init show} command:
\begin{lstlisting}
wrc# init show
-- built-in script --
vlan off
ptp stop
sfp match
mode slave
ptp start
-- user-defined script --
ip set 192.168.1.5
\end{lstlisting}
\noindent\textbf{Note:} This simple configuration disables VLANs configuration
in the WR PTP Core. If, for your network configuration you need to configure
VLANs, please check the instructions in section \ref{VLAN Support}.
% ==========================================================================
\subsection{Running the Core}
\label{Running the Core}
Having the SFP calibration database, and the init script created in \ref{Writing
configuration} you can now restart the WRPC by typing the shell command:
Having the SFP calibration database, and eventually a user-defined init script
created in \ref{Writing configuration} you can now restart the WRPC by typing
the shell command:
\begin{lstlisting}
wrc# init boot
......@@ -705,18 +776,19 @@ wrc# init boot
You should see log messages that confirm the execution of the initialization
script:
\begin{minipage}{\textwidth}
\begin{lstlisting}
executing: ptp stop
executing: vlan off
current vlan: 0 (0x0)
executing: ptp stop
PTP stop
executing: sfp match
AXGE-3454-0531
SFP matched, dTx=180707 dRx=148323 alpha=-73685416
executing: mode slave
executing: sfp match
AXGE-3454-0531
SFP matched, dTx=180750 dRx=148326 alpha=-73685416
executing: mode slave
PTP stop
Locking PLL
executing: ptp start
executing: ptp start
PTP start
Slave Only, clock class set to 255
executing: ip set 192.168.1.5
......@@ -724,7 +796,7 @@ IP-address: 192.168.1.5 (static assignment)
\end{lstlisting}
\end{minipage}
Now you should have the WR PTP Core running in WR Slave mode.\\
Now, your device runs as a WR Slave.\\
\textbf{Important!!!} WRPC needs to make a calibration of t24p phase transition
value. It has to be done only once for a new bitstream and is performed
......@@ -883,8 +955,8 @@ Part of the \texttt{snmpwalk}'s output:
WR-WRPC-MIB::wrpcPortInternalTx.0 = Counter32: 452
WR-WRPC-MIB::wrpcPortInternalRx.0 = Counter32: 869
WR-WRPC-MIB::wrpcSfpPn.1 = STRING: AXGE-1254-0531
WR-WRPC-MIB::wrpcSfpDeltaTx.1 = INTEGER: 180667
WR-WRPC-MIB::wrpcSfpDeltaRx.1 = INTEGER: 148735
WR-WRPC-MIB::wrpcSfpDeltaTx.1 = INTEGER: 180750
WR-WRPC-MIB::wrpcSfpDeltaRx.1 = INTEGER: 148326
WR-WRPC-MIB::wrpcSfpAlpha.1 = INTEGER: 72169888
End of MIB
\end{lstlisting}
......@@ -902,8 +974,8 @@ The SFPs database can be displayed using the \texttt{sfp show} command from
the WRPC's console:
\begin{lstlisting}
wrc# sfp show
1: PN:AXGE-1254-0531 dTx: 180667 dRx: 148735 alpha: 72169888
2: PN:AXGE-3454-0531 dTx: 180667 dRx: 148735 alpha: -73685416
1: PN:AXGE-1254-0531 dTx: 180750 dRx: 148326 alpha: 72169888
2: PN:AXGE-3454-0531 dTx: 180750 dRx: 148326 alpha: -73685416
\end{lstlisting}
The same data is exported by the \textit{Mini SNMP responder} via the table
\texttt{wrpcSfpTable}:
......@@ -912,10 +984,10 @@ The same data is exported by the \textit{Mini SNMP responder} via the table
$ snmpwalk $SNMP_OPT wrpcSfpTable
WR-WRPC-MIB::wrpcSfpPn.1 = STRING: AXGE-1254-0531
WR-WRPC-MIB::wrpcSfpPn.2 = STRING: AXGE-3454-0531
WR-WRPC-MIB::wrpcSfpDeltaTx.1 = INTEGER: 180667
WR-WRPC-MIB::wrpcSfpDeltaTx.2 = INTEGER: 180667
WR-WRPC-MIB::wrpcSfpDeltaRx.1 = INTEGER: 148735
WR-WRPC-MIB::wrpcSfpDeltaRx.2 = INTEGER: 148735
WR-WRPC-MIB::wrpcSfpDeltaTx.1 = INTEGER: 180750
WR-WRPC-MIB::wrpcSfpDeltaTx.2 = INTEGER: 180750
WR-WRPC-MIB::wrpcSfpDeltaRx.1 = INTEGER: 148326
WR-WRPC-MIB::wrpcSfpDeltaRx.2 = INTEGER: 148326
WR-WRPC-MIB::wrpcSfpAlpha.1 = INTEGER: 72169888
WR-WRPC-MIB::wrpcSfpAlpha.2 = INTEGER: -73685416
End of MIB
......@@ -983,8 +1055,8 @@ Simple verification of performed actions:\\
\begin{minipage}{\textwidth}
\begin{lstlisting}
wrc# sfp show
1: PN:AXGE-1254-0531 dTx: 180667 dRx: 148735 alpha: 72169888
2: PN:AXGE-3454-0531 dTx: 180667 dRx: 148735 alpha: -73685416
1: PN:AXGE-1254-0531 dTx: 180750 dRx: 148326 alpha: 72169888
2: PN:AXGE-3454-0531 dTx: 180750 dRx: 148326 alpha: -73685416
3: PN:NEW-SFP dTx: 1111 dRx: 2222 alpha: 3333
\end{lstlisting}
\end{minipage}
......@@ -1003,11 +1075,11 @@ Verify the result via SNMP:
WR-WRPC-MIB::wrpcSfpPn.1 = STRING: AXGE-1254-0531
WR-WRPC-MIB::wrpcSfpPn.2 = STRING: AXGE-3454-0531
WR-WRPC-MIB::wrpcSfpPn.3 = STRING: NEW-SFP
WR-WRPC-MIB::wrpcSfpDeltaTx.1 = INTEGER: 180667
WR-WRPC-MIB::wrpcSfpDeltaTx.2 = INTEGER: 180667
WR-WRPC-MIB::wrpcSfpDeltaTx.1 = INTEGER: 180750
WR-WRPC-MIB::wrpcSfpDeltaTx.2 = INTEGER: 180750
WR-WRPC-MIB::wrpcSfpDeltaTx.3 = INTEGER: 1111
WR-WRPC-MIB::wrpcSfpDeltaRx.1 = INTEGER: 148735
WR-WRPC-MIB::wrpcSfpDeltaRx.2 = INTEGER: 148735
WR-WRPC-MIB::wrpcSfpDeltaRx.1 = INTEGER: 148326
WR-WRPC-MIB::wrpcSfpDeltaRx.2 = INTEGER: 148326
WR-WRPC-MIB::wrpcSfpDeltaRx.3 = INTEGER: 2222
WR-WRPC-MIB::wrpcSfpAlpha.1 = INTEGER: 72169888
WR-WRPC-MIB::wrpcSfpAlpha.2 = INTEGER: -73685416
......@@ -1029,11 +1101,8 @@ To verify that database is empty:
\end{lstlisting}
% ==========================================================================
\subsection{Other Diagnostic Tools}
\label{Other Diagnostic Tools}
% --------------------------------------------------------------------------
\subsubsection{Syslog}
\newpage
\subsection{Syslog}
\label{Syslog}
\begin{sloppypar} % to prevent \texttt{} from going to the margine
......@@ -1112,9 +1181,215 @@ situations:\\
the current list of temperatures.\\
\end{longtable}
\end{sloppypar}
% --------------------------------------------------------------------------
% FIXME: syslog examples
% ==========================================================================
\newpage
\subsection{Diagnostic Tools}
\label{Diagnostic Tools}
This section describes various diagnostics tools that come with the WR PTP Core.
These tools are foreseen for the hosted environments as they access various WR
PTP Core registers over the External Wishbone interface\footnote{Please check
section \ref{sec:wrpc_hdl} for information about the WR PTP Core interfaces.}
(through PCIe or VME bridge).
% --------------------------------------------------------------------------
\subsubsection{wrpc-diags}
\label{wrpc-diags}
A direct access to synchronization status of the WR PTP Core is possible via WB registers.
Such access can be used by the application-specific logic or by any software running on the
host machine, provided the PCIe/VME bridge is instantiated in your design and
lets you access the WR PTP Core external Wishbone Slave interface (see
\ref{sec:hdl_wrpc}. Every reference design contains appropriate bridge, so you
can use one of them to access conveniently the Wishbone registers for WRPC
diagnostics using the \texttt{wrpc-diags} tool.
You will find \texttt{wrpc-diags} tool in the \textit{wrpc-sw} repository. If
you have not yet cloned it, please see section \ref{LM32 software compilation}
for more instructions how this should be done, as well as how to compile it.
The tool is self documented in the sense that a help \texttt{h} command lists
all the currently supported commands, and to get detailed information for a
given command, one can type \texttt{h cmd}.
To use the \texttt{wrpc-diags} tool interactively, call it with appropriate
parameters, depending on your hardware type. For example for a SPEC board at
address 01:00.0:
\begin{lstlisting}
$ sudo <your_wrpc-sw_location>/tools/wrpc-diags -o 0x20800 \
-f /sys/bus/pci/devices/0000:01:00.0/resource0
\end{lstlisting}
The prompt \texttt{wrcdiag[00] >} will appear and you will be able to input commands.
All the available commands are listed with \texttt{h}:
\begin{lstlisting}[basicstyle=\scriptsize\ttfamily]
cfv-774-cbt:wrcdiag[00] > h
Valid COMMANDS:
Idx Name Params Description
# 1: q [ ] -> Quit test program
# 2: h [ o c ] -> Help on commands
# 3: a [ ] -> Atom list commands
# 4: his [ ] -> History
# 5: s [ Seconds ] -> Sleep seconds
# 6: ms [ MilliSecs ] -> Sleep milliseconds
# 7: sh [ Unix Cmd ] -> Shell command
# 8: diags [ ] -> show all wrc diags
# 9: sstat [ ] -> get servo status
#10: ptpstat [ ] -> get PTP state
#11: pstat [ ] -> get port status
#12: astat [ ] -> get auxiliare state
#13: txfcnt [ ] -> get TX PTP frame count
#14: rxfcnt [ ] -> get RX frame count
#15: ltime [ ] -> Local Time expressed in sec since epoch
#16: rttime [ ] -> Round trip time in picoseconds
#17: msdelay [ ] -> Master slave link delay in picoseconds
#18: asym [ ] -> Total link asymmetry in picoseonds
#19: cko [ ] -> Clock offset in picoseonds
#20: setp [ ] -> Current slave's clock phase shift value
#21: ucnt [ ] -> Update counter
#22: temp [ ] -> get board temperature
Type "h name" to get complete command help
\end{lstlisting}
In order to see all the wrc diagnostics, the \texttt{diags} command inside the prompt should
be executed as follows:
\begin{lstlisting}
cfc-774-cbt:wrcdiag[00] > diags
servo status: Track phase
Port status: Link up, PLL locked,
PTP state: PPS slave
Aux state: ch0:enabled
TX frame count: 1593970
RX frame count: 6883447
TAI time: Wed May 31 15:31:56 2017
Round trip time: 848002 ps
Master slave delay: 417483 ps
Total Link asymmetry: 13036 ps
Clock offset: 2 ps
Phase setpoint: 7883 ps
Update counter: 812977
temp: 47.3750 C
\end{lstlisting}
Some advanced commands can be also executed. For example, one can call
\texttt{temp} command every 1 second for 5 times:
\begin{lstlisting}
cfc-774-cbt:wrcdiag[00] > 5(temp, s 1)
temp: 47.3750 C
temp: 47.3750 C
temp: 47.3750 C
temp: 47.3750 C
temp: 47.3750 C
\end{lstlisting}
The commands that are available from the interactive prompt can be also executed directly
from the host's shell prompt and via ssh. Both cases can be useful when writing shell
scripts using the tool. To call one of the commands from the host shell prompt,
use \texttt{echo cmd | wrpc-diags} format. For example, to execute
\texttt{diags} command for SPEC:
\begin{lstlisting}
echo 'diags' | sudo <your_wrpc-sw_location>/tools/wrpc-diags -o 0x20800 \
-f /sys/bus/pci/devices/0000:01:00.0/resource0
\end{lstlisting}
In order to call \texttt{temp} command every 1 second for 5 times:
\begin{lstlisting}
echo '5(temp, 1s)' | sudo <your_wrpc-sw_location>/tools/wrpc-diags -o 0x20800 \
-f /sys/bus/pci/devices/0000:01:00.0/resource0
\end{lstlisting}
% --------------------------------------------------------------------------
\subsubsection{wr-streamers}
\label{sec:wr-streamers-tool}
{\bf Note:} This tool can be used only if you've selected \tts{STREAMERS} mode
for the external WRPC fabric interface or if you have manually instantiated
WR Streamers module in your HDL design. See section \ref{sec:wrpc_hdl} for more
details on WR PTP Core and Board Support Packages interfaces.\\
The WR Streamers module provides information about transmitted and received
frames, which can be useful for diagnostics and debugging. One way of accessing
this information is by using the \texttt{diag} command of the WR PTP Core Shell.
An alternative is to use the \texttt{wr-streamers} tool described in this
section. You will find it in the \textit{wrpc-sw} repository. If
you have not yet cloned it, please see section \ref{LM32 software compilation}
for more instructions how this should be done, as well as how to compile it.\\
The available statistical information is identical to the one that can be
accessed via the \texttt{diag} command of WR PTP Core's Shell. It includes
statistics collected since the most recent reset: max/min latency, number of
transmitted/received frames, number of lost frames/blocks, number of latency
values accumulated, accumulated latency, and the time of the last reset. The
wishbone registers can also be used to override the default network
configuration of the WR Streamers.\\
The \texttt{wr-streamers} tool is self documented in the sense that a help
\texttt{h} command lists you all the currently supported commands, and to get
detailed information for a given command, one can type \texttt{h cmd}.
To use the \texttt{wr-streamers} tool interactively, call the tool with appropriate
parameters, depending on your hardware type. For example for a SPEC board at
address 01:00.0:
\begin{lstlisting}
$ sudo <your_wrpc-sw_location>/tools/wr-streamers -o 0x20700 \
-f /sys/bus/pci/devices/0000:01:00.0/resource0
\end{lstlisting}
The prompt \texttt{wrstm[00] >} will appear and you will be able to input commands.
All the available commands are listed with \texttt{h}:
\begin{lstlisting}[basicstyle=\scriptsize\ttfamily]
cfv-774-cbt:wrstm[00] > h
Valid COMMANDS:
Idx Name Params Description
# 1: q [ ] -> Quit test program
# 2: h [ o c ] -> Help on commands
# 3: a [ ] -> Atom list commands
# 4: his [ ] -> History
# 5: s [ Seconds ] -> Sleep seconds
# 6: ms [ MilliSecs ] -> Sleep milliseconds
# 7: sh [ Unix Cmd ] -> Shell command
# 8: stats [ [0/1/2/3/4/5/6/7] ] -> show streamers statistics
# 9: reset [ ] -> show time of the latest reset / time elapsed since then
#10: resetcnt [ ] -> reset tx/rx/lost counters and avg/min/max latency values
#11: resetseqid [ ] -> reset sequence ID of the tx streamer
#12: lat [ [latency] ] -> get/set config of fixed latency in integer [us] (-1 to disable)
#13: qtagf [ [0/1] ] -> QTags flag on off
#14: qtagvp [ [VID,prio] ] -> QTags Get/Set VLAN ID and priority
#15: qtagor [ [0/1] ] -> get/set overriding of default qtag config with WB config (set
using qtagf, qtagvp)
#16: ls [ [leapseconds] ] -> get/set leap seconds
Type "h name" to get complete command help
\end{lstlisting}
In order to see all the WR Streamers statistics, the \texttt{stats} command
inside the prompt should be executed as follows:
\begin{lstlisting}
cfc-774-cbt:wrstm[01] > stats
Latency [us] : min= 3.736 max= 8.216 avg = 3.88176
Frames [number]: tx =0 rx =61897834620 lost=0 (lost blocks =0)
\end{lstlisting}
The commands that are available from the interactive prompt can be also executed directly
from the host's shell prompt and via ssh. Both cases can be useful when writing shell
scripts using the tool. To call one of the commands from the host shell prompt, use
\texttt{echo cmd | wr-streamers}. For example, to execute \texttt{stats} command for SPEC:
\begin{lstlisting}
echo 'stats' | sudo <your_wrpc-sw_location>/tools/wr-streamers -o 0x20700 \
-f /sys/bus/pci/devices/0000:01:00.0/resource0
\end{lstlisting}
In order see the number of received frames every 1 second for 5 times, call:
\begin{lstlisting}
echo '5(stats 1, 1s)' | sudo <your_wrpc-sw_location/tools/wr-streamers -o 0x20700 \
-f /sys/bus/pci/devices/0000:01:00.0/resource0
\end{lstlisting}
% ==========================================================================
\newpage
\subsection{Other Diagnostic Methods}
\label{Other Diagnostic Tools}
% --------------------------------------------------------------------------
\subsubsection{Latency Test}
\label{Latency Test}
......@@ -1248,25 +1523,47 @@ The node now has a \textit{ps} command, that shows the number of iterations
and time spent in each \textit{task}. Each task reports when it did
something (as opposed to just polling the clock or network socket and
seeing that nothing is there to do); the \textit{iterations} count shows how many
times the task did something.
\begin{lstlisting}
wrc# ps
iterations seconds.micros name
44288501 4242.816329 idle
0 0.000000 spll-bh
37 0.016549 shell+gui
8992 1.158969 ptp
4252 0.037005 uptime
1 0.001035 check-link
0 0.000000 stats
0 0.000000 net-bh
568 5.068343 temperature
times the task did something. The \textit{max\_ms} show the longest execution
time of a particular task.
\begin{lstlisting}
wrc# ps
iterations seconds.micros max_ms name
145560 29.007144 75 idle
0 0.000000 0 spll-bh
6 0.001630 1 shell+gui
642 2.540416 8 ptp
31 0.000361 1 uptime
1 0.050424 51 check-link
32 0.011172 9 diags
0 0.000000 0 stats
235 0.023562 1 net-bh
32 0.029157 2 ipv4
0 0.000000 0 arp
0 0.000000 0 snmp
6 0.054566 12 temperature
\end{lstlisting}
By using ``\texttt{ps reset}'' you can zero all counters to start a new
test run.
It is possible to configure \texttt{ps} in such way that it prints information
when any task runs longer than any run before since reset
(or \texttt{ps reset}) and when it runs longer than a specified value
in miliseconds.
For this please use command ``\texttt{ps max <msecs>}'', where
\texttt{<msecs>} is a number of miliseconds triggering printouts.
\begin{lstlisting}
wrc# ps max 10
task temperature, run for 11 ms
task temperature, run for 12 ms
task temperature, run for 11 ms
wrc# ps
[...]
New max run time for a task shell+gui, old 1, new 75
task shell+gui, run for 75 ms
\end{lstlisting}
% --------------------------------------------------------------------------
\subsubsection{Pfilter rules}
\label{Pfilter rules}
......@@ -1316,43 +1613,42 @@ udp-based network services, in addition to \textit{ptp}:
\section{VLAN Support}
\label{VLAN Support}
The White Rabbit node can be configured to be vlan-aware, by setting
\texttt{CONFIG\_VLAN} in \textit{Kconfig}. The setting is disabled by default.
If configured for \textit{vlan} support, the node selects packet-filter rules
to receive frames in several \textit{vlan}s, all set at configuration time.
At run time you can use \texttt{vlan off} in the shell to turn off all \textit{vlan}
processing and get back to the ``standard'' packet-filter rules.
If you are using the White Rabbit PTP Core version 4.1 or later, it comes by
default with VLAN support enabled. You can always disable them in run time using
a WRPC shell command:
\begin{lstlisting}
wrc# vlan off
\end{lstlisting}
Current implementation allows to configure up to 4 VLAN IDs (VIDs) at build
time. The following Kconfig options are available in the LM32 software:
\begin{longtable}{ p{6.5cm} p{9cm} }
\small{\textit{CONFIG\_VLAN}} &
This is the top-level choice. It can be enabled or disabled.
If disabled, the following values default to 0 and the
packet filter will discard all tagged frames.\\
If VLANs are disabled, all incoming tagged frames will be discarded.\\
& \\
\small{\textit{CONFIG\_VLAN\_NR}} &
The default \textit{vlan} number for the CPU. All network traffic
directed to (and originating from) the \textit{lm32} processor will
belong to this \textit{vlan}. The~value can be changed at run time
using the \texttt{vlan} shell command.\\
The default \textit{vlan} number for the CPU (class 0). All network traffic
directed to (and originating from) the LM32 processor will
belong to this VLAN. The~value can be changed at run time
using the \texttt{vlan set} shell command.\\
& \\
\small{\textit{CONFIG\_VLAN\_1\_FOR\_CLASS7}} & \\
\small{\textit{CONFIG\_VLAN\_2\_FOR\_CLASS7}} &
The packet-filter rules are setup to deliver frames belonging
to two specific \textit{vlans} to class 7, usually \textit{etherbone}.
To deliver one \textit{vlan} only, set the two options to the same
number.\\
to two specific VLANs to class 7, usually Etherbone.
To deliver one VLAN only, set the two options to the same
number. These VIDs can be modified only at build time.\\
& \\
\small{\textit{CONFIG\_VLAN\_FOR\_CLASS6}} &
The packet-filter rules are setup to deliver frames belonging
to one specific \textit{vlan} to class 6, usually routed to the
\textit{streamer} or \textit{nic} logic blocks.\\
to one specific VLAN to class 6, usually routed to the
Streamer module. This VID can be modified only at build time.\\
\end{longtable}
......@@ -1364,6 +1660,25 @@ processed by the WRPC, class 6 is used for Streamers traffic, class 7 is used
for Etherbone traffic (see HDL documentation for boards HDL modules and
selection between Streamers, Etherbone and Plain modes).
The default WR PTP Core v4.1 release firmware comes with the following VIDs:
\begin{itemize}
\item \textbf{VID 1} - for class 0, traffic processed inside the WR PTP Core
\item \textbf{VID 10} and \textbf{VID 11} - for class 7, Etherbone traffic
\item \textbf{VID 20} - for class 6, Streamers traffic
\end{itemize}
This of course means that all the traffic from VIDs 10, 11, 20 is forwarded and
available on the WR PTP Core external fabric interface. The user is free to use
it for any other HDL module, not necessary Etherbone or Streamers.
Currently, only VID for the traffic processed by the WRPC (class 0) can be
modified in the run time. You can use the WRPC shell command
\texttt{vlan set <vid>} to modify it. If, for example, your WR node is supposed
to synchronize and respond to SNMP requests in VLAN 5, you should add this to
the user-defined init script:
\begin{lstlisting}
wrc# init add vlan set 5
\end{lstlisting}
% ##########################################################################
\newpage
......@@ -1520,12 +1835,18 @@ tools used to build and run it, you can write to our mailing list
\code{pll stop <channel>} & stops SoftPLL for the channel \\
\code{ps} & prints the list of running tasks (processes) in the CPU. For
each task you get the number of iterations and the CPU time consumed since
boot or last reset of values \\
each task you get the number of iterations, the maximum execution time
(measured with the monotonic clock) and the CPU time consumed (using
the RT clock) since boot or last reset of values \\
\code{ps reset} & zeroes the profiling information reported by the \code{ps}
command \\
\code{ps max <msecs>} & starts printing all tasks executing longer than
a given number of miliseconds. Additionally, it triggers printing messages
if particular task runs longer than ever before. Passing ``\code{0}'' as
a parameter stops the further printouts. \\
\code{ptp <e2e|p2p>} & selects PTP delay mechanism: end-to-end or peer-to-peer.
If configured, you can set \texttt{p2p} mode. Alternatively you can use also
aliases: \texttt{delay} (instead of \texttt{e2e}) or \texttt{pdelay}
......@@ -1549,6 +1870,34 @@ tools used to build and run it, you can write to our mailing list
\code{sdb} & prints devices connected to the Wishbone bus inside WRPC \\
\code{sdb fs <memtype> <baseadr> <param>} & creates SDBFS image under
specified \code{<baseadr>} in selected storage depending on \code{<memtype>}
({\bf 0} - Flash, {\bf 1} - I2C EEPROM, {\bf 2} - 1-Wire EEPROM). The meaning
of last parameter \code{<param>} depends on the type of selected storage. It
is either the sector size in kilobytes (for Flash) or I2C chip address (for
I2C EEPROM). Command \code{sdb} is available if \texttt{CONFIG\_GENSDBFS}
is set.\\
\code{sdb fs 0} & creates SDBFS image in Flash memory. Base address and sector
size are taken from HDL Syscon registers for SPEC/SVEC boards. If you want
to use it for custom board, base address and sector size must be specified
as VHDL generic parameters of the WR PTP Core. Command \code{sdb} is
available if \texttt{CONFIG\_GENSDBFS} is set.\\
\code{sdb fse <memtype> <baseadr> <param>} & erases SDBFS image under
specified \code{<baseadr>} from selected storage depending on
\code{<memtype>} ({\bf 0} - Flash, {\bf 1} - I2C EEPROM, {\bf 2} - 1-Wire
EEPROM). The meaning of last parameter \code{<param>} depends on the type
of selected storage. It is either the sector size in kilobytes (for Flash)
or I2C chip address (for I2C EEPROM). Command \code{sdb} is available
if \texttt{CONFIG\_GENSDBFS} is set.\\
\code{sdb fse 0} & erases SDBFS image from Flash memory. Base address and sector
size are taken from HDL Syscon registers for SPEC/SVEC boards. If you want
to use it for custom board, base address and sector size must be specified
as VHDL generic parameters of the WR PTP Core. Command \code{sdb} is
available if \texttt{CONFIG\_GENSDBFS} is set.\\
\code{sfp add <PN> <deltaTx> <deltaRx> <alpha>} & stores calibration
parameters for SFP to a file in Flash/EEPROM \\
......@@ -1682,8 +2031,41 @@ tools used to build and run it, you can write to our mailing list
% ##########################################################################
\clearpage
\section{Writing SDBFS image in standalone configuration}
\label{Writing SDBFS image in standalone configuration}
\section{Other ways to write SDBFS image to your Flash memory}
\label{appendix:writing_sdbfs}
\subsection{Writing SDBFS image through PCIe bus}
To write SDBFS filesystem image to the Flash memory of a hosted SPEC card, you
can use the \texttt{flash-write} tool available in the \emph{spec-sw} drivers
package.
First, please download the SDBFS image from \textit{ohwr.org}:
\begin{lstlisting}
$ wget http://www.ohwr.org/attachments/download/4060/sdbfs-flash.bin
\end{lstlisting}
It contains all the files required by the core. They are empty, but have to
exist in the SDBFS structure to be filled later from the WR PTP Core shell or
SNMP.\\
Before calling the tool, you need to have SPEC drivers loaded in your system:
\begin{lstlisting}
$ cd <your_location>/spec-sw
$ sudo insmod fmc-bus/kernel/fmc.ko
$ sudo insmod kernel/spec.ko
\end{lstlisting}
To write the filesystem image to flash, please execute the following
command:
\begin{lstlisting}
$ sudo tools/flash-write -c 0x0 0 1507712 < <your_location>/sdbfs-flash.bin
\end{lstlisting}
\noindent\textbf{Note:} If you have more than one SPEC board in your computer,
you can use \code{-b} parameter which takes the PCI bus address of the card you
want to program. This can be found in the list of the PCI devices installed in
the system (\code{lspci}).
\subsection{Writing SDBFS image in standalone configuration}
If you use SPEC board in a host-less environment, or you use custom
hardware and SPEC drivers/tools cannot be used, there is still a
......@@ -1938,4 +2320,29 @@ in file \texttt{snmp\_test\_config.bash}.
These tests have to be executed after any changes are made to the \textit{Mini SNMP
responder}.
% --------------------------------------------------------------------------
\newpage
\section{Wishbone Memory Maps}
\label{sec:wb_mem_maps}
This appendix provides a register map of Wishbone modules that are exposed to
external applications/HDL core. In the table below you can see the list of
modules available on the External Wishbone interface of the WR PTP Core. Please
bare in mind that WR Streamers Diagnostics module is available only when
\tts{STREAMERS} external fabric mode is selected.
\begin{center}
\begin{tabular}{|l|l|}
\hline
module name & base address\\
\hline \hline
WR Core Diagnostics & 0x20800\\
WR Streamers Diagnostics & 0x20700\\
\hline
\end{tabular}
\end{center}
\input{wbgen/wrc_diags.tex}
\newpage
\input{wbgen/wr_streamers_wb.tex}
\end{document}
revinfo.tex
wrpc_failures.pdf
all : wrpc_failures.pdf
.PHONY : all clean
RELEASE = $(shell git describe --always --dirty)
wrpc_failures.pdf : wrpc_failures.tex fail.tex intro.tex snmp_objects.tex snmp_exports.tex
@echo '\\newcommand{\\gitrevinfo}{'$(RELEASE)'}' > revinfo.tex
pdflatex wrpc_failures.tex
pdflatex wrpc_failures.tex
# To speed up generation of document for development, please comment out:
# % print alphabetical list
# \printnoidxglossary[type=snmp_all,style=tree,sort=letter]
# from doc/wrpc_failures/snmp_exports.tex file.
clean :
rm -f *.eps *.dat *.log *.out *.aux *.dvi *.ps *.toc *.pdf revinfo.tex
This section tries to identify all the possible ways the White Rabbit PTP Core can
fail. The structure of each error description is the following:
\begin{itemize}[leftmargin=0pt]
\item [] \underline{Severity}: describes how critical is the fault. Currently
we distinguish two severity levels:
\begin{packed_items}
\item WARNING - means that despite the fault the synchronization
functionality was not affected so the WRPC behaves correctly in the WR
network.
\item ERROR - means that the fault is critical and most probably WRPC
misbehaves.
\end{packed_items}
\item [] \underline{Mode}: for timing failures, it describes which modes are
affected. Possible values are:
\begin{packed_items}
\item \emph{Slave} - the WR Node (WR PTP Core) synchronizes to another WR
device.
\item \emph{Grand Master} - the WR Node (WR PTP Core) is at the top of the
synchronization hierarchy. It is synchronized to an external clock (e.g.
GPS, Cesium) and provides timing to other WR/PTP devices.
\item \emph{Master} - the WR Node (WR PTP Core) at the top of the
synchronization hierarchy. It provides timing to other WR/PTP devices
but runs from a local oscillator (not synchronized to an external
clock).
\item \emph{all} - any WR PTP Core can be affected regardless the timing
mode.
\end{packed_items}
\item [] \underline{Description}: What the problem is about, how important it
is and what are the effects if it occurs.
\item [] \underline{SNMP objects}: Which SNMP objects should be monitored to
detect the failure. These are objects from the \texttt{WR-WRPC-MIB}.
\item [] \underline{Error/Warning condition}: condition that should be checked
at the SNMP manager's side to detect given problem. Often you will see there
conditions like:\\
\texttt{[value] != [value]\_prev} or\\
\texttt{[value] - [value]\_prev > [threshold]}\\
where \text{[value]} and \text{[value]\_prev} are the current and previous
iteration readouts of an SNMP object. This way we check if the value of the
object has changed from the previous readout or if it has changed by more
than a safe threshold.
\item [] \underline{Action}: list of actions that should be performed in case
of an error/warning. Regardless of the detailed actions described for each
of the errors below, there are some common remarks that apply to all
situations:
\begin{itemize}
\item If a procedure given for a specific SNMP object does not solve the
problem, please contact WR experts to perform a more in-depth analysis of
the network. For this, you should provide a complete dump of the WRPC
status generated in the first step of each procedure.
\item The first action in most of the procedures, called \emph{Dump state}
requires simply calling a tool provided by WR developers that reads all
the detailed information from the node and writes it to a single file
that can be later analyzed by the experts.
\item If a problem solving procedure requires restarting or replacing a WR
Node working in the \emph{Grand Master} mode, please make sure that after
the repair, all other WR devices in the network are synchronized and do
not report any problems.
\item If a procedure requires replacing WR Node with a new unit, the
broken one should be handled to WR experts or the hardware manufacturer to
investigate the problem.
\end{itemize}
\end{itemize}
\newpage
\subsection{Timing error}
\label{sec:timing_fail}
As a timing error we define the WR PTP Core not being able to synchronize its
local time to the WR Master (if WRPC runs in the slave mode), or not being able
to provide correct WR time to the rest of the WR network (if WRPC runs in the
master mode). This section contains the list of faults leading to a timing error.
\subsubsection{\bf WR PTP Core operates in a wrong timing mode}
\label{fail:timing:ppsi_wrong_mode}
\begin{pck_descr}
\item [] \underline{Severity}: ERROR
\item [] \underline{Mode}: \emph{all}
\item [] \underline{Description}:\\
If the WRPC operates in a wrong timing mode (i.e. due to the
configuration error) it will be unable to provide a user application
with the correct WR time. For example, if the WRPC is supposed to
operate as Slave but is misconfigured to a Free-running Master mode, its
time would be different from other WR devices in the network, despite no
other errors being reported.\\
To be able to detect this problem, SNMP manager has to be fed with the
desired timing mode for the each monitored WR node.
\item [] \underline{SNMP objects}:\\
{\footnotesize
\snmpadd{WR-WRPC-MIB::wrpcSpllMode} }
\item [] \underline{Error condition}:\\
{\footnotesize
\texttt{wrpcSpllMode != <desired mode>}}
\item [] \underline{Action}:
\begin{pck_proc}
\item Modify the configuration of the WR PTP Core. Please check the
\emph{White Rabbit PTP Core User's Manual} for instructions how to
modify the init script to set the timing mode.
\end{pck_proc}
\end{pck_descr}
\subsubsection{\bf PTP/PPSi went out of \texttt{TRACK\_PHASE}}
\label{fail:timing:ppsi_track_phase}
\begin{pck_descr}
\item [] \underline{Severity}: ERROR
\item [] \underline{Mode}: \emph{Slave}
\item [] \underline{Description}:\\
If the \emph{PTP/PPSi} WR servo goes out of the \texttt{TRACK\_PHASE}
state, this means something bad has happened and the node lost
synchronization to its Master.
\item [] \underline{SNMP objects}:\\
{\footnotesize
\snmpadd{WR-WRPC-MIB::wrpcPtpServoStateN}\\
\snmpadd{WR-WRPC-MIB::wrpcPtpServoStateErrCnt} }
\item [] \underline{Error condition}:\\
{\footnotesize
\texttt{wrpcPtpServoStateErrCnt != wrpcPtpServoStateErrCnt\_prev} }
\item [] \underline{Action}:
\begin{pck_proc}
\item Check if the WR Master - timing source, was not restarted. If it
was, Slave leaving \texttt{TRACK\_PHASE} state is a normal behavior
and it should automatically re-synchronize.
\item Dump state
\item Check the status of the WR Master - timing source. In case it has
reported some problems, please follow the diagnostics document for the
WR Switch.
\item If the switch did not report any problems, restart the WR Node.
\item If the problem persists replace the WR Node hardware with a new
unit.
\item If the problem persists, please notify WR experts.
\end{pck_proc}
\end{pck_descr}
\subsubsection{\bf Offset jump not compensated by Slave}
\label{fail:timing:offset_jump}
\begin{pck_descr}
\item [] \underline{Severity}: ERROR
\item [] \underline{Mode}: \emph{Slave}
\item [] \underline{Description}:\\
This may happen if the Master resets its WR time counters (e.g. because
it lost the link to its Master higher in the hierarchy or to external
clock), but the WR Slave does not follow the jump.
\item [] \underline{SNMP objects}:\\
{\footnotesize
\snmpadd{WR-WRPC-MIB::wrpcPtpClockOffsetPsHR}\\
\snmpadd{WR-WRPC-MIB::wrpcPtpClockOffsetErrCnt} }
\item [] \underline{Error condition}:\\
{\footnotesize
\texttt{wrpcPtpClockOffsetErrCnt != wrpcPtpClockOffsetErrCnt\_prev} }
\item [] \underline{Action}:
\begin{pck_proc}
\item Dump state
\item Check the status of the WR Master - timing source. Normally, time
jumps should not happen and if they do, the problem should be
investigated on the WR Master side (e.g. \emph{Grand Master} unlocked
from the external reference).
\item Restart the WR Node and let it synchronize again.
\end{pck_proc}
\end{pck_descr}
\subsubsection{\bf Detected jump in the RTT value calculated by \emph{PTP/PPSi}}
\label{fail:timing:rtt_jump}
\begin{pck_descr}
\item [] \underline{Severity}: ERROR
\item [] \underline{Mode}: \emph{Slave}
\item [] \underline{Description}:\\
Once a WR link is established the round-trip delay (RTT) can change
smoothly due to the temperature variations. However, if a sudden jump is
detected, that means that an erroneous timestamp was generated either on
the Master or the Slave side.
One cause of that could be the wrong value of the t24p transition point.
\item [] \underline{SNMP objects}:\\
{\footnotesize
\snmpadd{WR-WRPC-MIB::wrpcPtpRTT}\\
\snmpadd{WR-WRPC-MIB::wrpcPtpRTTErrCnt} }
\item [] \underline{Error condition}:\\
{\footnotesize
\texttt{wrpcPtpRTTErrCnt != wrpcPtpRTTErrCnt\_prev} }
\item [] \underline{Action}:
\begin{pck_proc}
\item Dump state.
\item Check the status status of the WR Master - timing source.
Eventually proceed to investigate the problem on the WR Master side.
\item Restart the Node.
\item If the problem persists, replace the WR Node with a new unit.
\end{pck_proc}
\end{pck_descr}
\subsubsection{\bf Wrong $\Delta_{TXM}$, $\Delta_{RXM}$, $\Delta_{TXS}$,
$\Delta_{RXS}$, $\alpha$ values are reported to the \emph{PTP/PPSi} daemon}
\label{fail:timing:deltas_report}
\begin{pck_descr}
\item [] \underline{Severity}: ERROR
\item [] \underline{Mode}: \emph{Slave}
\item [] \underline{Description}:\\
If \emph{PTP/PPSi} doesn't get the correct values of fixed hardware delays,
it won't be able to calculate a proper Master-to-Slave delay. Although
the estimated offset in \emph{PTP/PPSi} is close to 0, the WRPC won't be
synchronized to the Master with sub-nanosecond accuracy.
\item [] \underline{SNMP objects}:\\
{\footnotesize
\snmpadd{WR-WRPC-MIB::wrpcPtpDeltaTxM}\\
\snmpadd{WR-WRPC-MIB::wrpcPtpDeltaRxM}\\
\snmpadd{WR-WRPC-MIB::wrpcPtpDeltaTxS}\\
\snmpadd{WR-WRPC-MIB::wrpcPtpDeltaRxS}\\
\snmpadd{WR-WRPC-MIB::wrpcPtpAlpha} }
\item [] \underline{Error condition}:\\
{\footnotesize
\texttt{wrpcPtpDeltaTxM == 0 || wrpcPtpDeltaRxM == 0 ||}\\
\texttt{wrpcPtpDeltaTxS == 0 || wrpcPtpDeltaRxS == 0 ||}\\
\texttt{wrpcPtpAlpha == 0} }
\item [] \underline{Action}:
\begin{pck_proc}
\item Check if the correct calibration values are entered both for the WR
Node and WR Master. WR Switch will report this in its own SNMP status
objects.
\item Check the White Rabbit PTP Core User Manual
\footnote{\url{http://www.ohwr.org/projects/wr-cores/wiki/Current\_release}}
for the instructions how the calibration values can be configured
locally or remotely using SET for SNMP objects.
\end{pck_proc}
\end{pck_descr}
\subsubsection{\bf PTP servo is not updating}
\label{fail:timing:servo_not_updating}
\begin{pck_descr}
\item [] \underline{Severity}: ERROR
\item [] \underline{Mode}: \emph{Slave}
\item [] \underline{Description}:\\
If PTP servo is not updating, we still increment the internal timing
counters, but don't have updated information on the Master time and link
delay. After some time the slave local time will drift away from the
master.
\item [] \underline{SNMP objects}:\\
{\footnotesize
\snmpadd{WR-WRPC-MIB::wrpcPtpServoUpdates}\\
\snmpadd{WR-WRPC-MIB::wrpcPtpServoUpdateTime} }
\item [] \underline{Error condition}:\\
{\footnotesize
\texttt{wrpcPtpServoUpdates == wrpcPtpServoUpdates\_prev} }
\item [] \underline{Action}:
\begin{pck_proc}
\item Dump state
\item Check if the PTP frames are flowing between the WR Node and its
timing master (error \ref{fail:timing:no_frames}).
\item Check the status of the WR Master - timing source.
\item Check if the SoftPLL did not unlock (error
\ref{fail:timing:spll_unlock}).
\item Restart the WR Node.
\item If the problem persists, replace the WR Node with a new unit.
\end{pck_proc}
\end{pck_descr}
\subsubsection{\bf \emph{SoftPLL} became unlocked}
\label{fail:timing:spll_unlock}
\begin{pck_descr}
\item [] \underline{Severity}: ERROR / WARNING
\item [] \underline{Mode}: \emph{all}
\item [] \underline{Description}:\\
If the \emph{SoftPLL} loses lock, for any reason, Slave, Master or Grand
Master node can no longer be syntonized and phase aligned with its time
source. WRPC in Master mode without properly locked Helper PLL is not
able to perform reliable phase measurements for enhancing Rx timestamps
resolution. For a Grand Master the reason of \emph{SoftPLL} going out of
lock might be disconnected 1-PPS/10MHz signals or that the external
clock is down.
\item [] \underline{SNMP objects}:\\
{\footnotesize
\snmpadd{WR-WRPC-MIB::wrpcSpllMode}\\
\snmpadd{WR-WRPC-MIB::wrpcSpllSeqState}\\
\snmpadd{WR-WRPC-MIB::wrpcSpllAlignState}\\
\snmpadd{WR-WRPC-MIB::wrpcSpllHlock}\\
\snmpadd{WR-WRPC-MIB::wrpcSpllMlock}\\
\snmpadd{WR-WRPC-MIB::wrpcSpllDelCnt} }
\item [] \underline{Error condition}:\\
{\footnotesize
\texttt{wrpcSpllSeqState != ready\emph{(3)} ||}\\
\texttt{[wrpcSpllMode == grandmaster\emph(1) \&\& wrpcAlignState != locked\emph{(6)}] ||}\\ % GrandMaster not locked
\texttt{[wrpcSpllMode == slave\emph{(3)} \&\& wrpcSpllHlock == 0] ||}\\ % Spll slave and Hpll unlocked
\texttt{[wrpcSpllMode == slave\emph{(3)} \&\& wrpcSpllMlock == 0] ||}\\ % Spll slave and Mpll unlocked
\texttt{[wrpcSpllMode != grandmaster\emph{(1)} \&\& wrpcSpllMode != master\emph{(2)} \&\& wrpcSpllMode != slave\emph{(3)}]}} % Spll in neither of the GM/Master/Slave modes
\item [] \underline{Warning condition}:\\
{\footnotesize
\texttt{[wrpcSpllMode == grandmaster\emph{(1)} \&\& wrpcSpllDelCnt > 0]}} % GrandMaster has unlocked from reference at some point
\item [] \underline{Action for \emph{Grand Master} WR Node}:
\begin{pck_proc}
\item Dump state
\item Check 1-PPS and 10MHz signals coming from an external source.
Verify if they are properly connected and, in case of a GPS receiver,
check if it is synchronized and locked.
\item Restart the WR Node
\item If the problem persists, replace the WR Node with a new unit
\end{pck_proc}
\item [] \underline{Action for \emph{Slave} WR Node}:
\begin{pck_proc}
\item Dump state
\item Check the status of the WR Master - timing source. Eventually
proceed to investigate the problem on the Master.
\item Verify if the WR link was not lost and re-initialized by checking
the SNMP manager software logs.
\item Restart the WR Node
\item If the problem persists, replace the WR Node with a new unit.
\end{pck_proc}
\end{pck_descr}
\subsubsection{\bf PTP frames don't reach LM32}
\label{fail:timing:no_frames}
\begin{pck_descr}
\item [] \underline{Severity}: ERROR
\item [] \underline{Mode}: \emph{all}
\item [] \underline{Description}:\\
In this case, \emph{PTP/PPSi} will fail to stay synchronized and provide
synchronization. Even if the WR servo is in the \texttt{TRACK\_PHASE}
state, it calculates a new phase shift based on the Master-to-Slave delay
variations. To calculate these variations, it still needs timestamped
PTP frames flowing. There could be several causes of such fault:
\begin{itemize}
\item WR Switch problem
\item wrong VLANs configuration
\item WR PTP Core HDL problem
\end{itemize}
\item [] \underline{SNMP objects}:\\
{\footnotesize
\snmpadd{WR-WRPC-MIB::wrpcPtpTx}\\
\snmpadd{WR-WRPC-MIB::wrpcPtpRx}\\
\snmpadd{WR-WRPC-MIB::wrpcPortInternalTx}\\
\snmpadd{WR-WRPC-MIB::wrpcPortInternalRx} }
\item [] \underline{Error condition}:\\
{\footnotesize
\texttt{wrpcPtpTx == wrpcPtpTx\_prev || wrpcPtpRx == wrpcPtpRx\_prev ||}\\
\texttt{wrpcPortInternalTx == wrpcPortInternalTx\_prev ||}\\
\texttt{wrpcPortInternalRx == wrpcPortInternalRx\_prev} }
\item [] \underline{Action}:
\begin{pck_proc}
\item Dump state.
\item Check the state of the WR Master - timing source. Especially, if
the PTP daemon is still running there.
\item Check if the VLANs configuration on the WR Node matches the
configuration of the WR Switch where this node is connected. Wrong
configuration (e.g. different VIDs) will cause the frames to be
dropped.
\item Restart the WR Node.
\item If possible, stop or reduce any additional (heavy) traffic that
might be sent through the WR network.
\item If the problem persists, please notify WR experts.
\end{pck_proc}
\end{pck_descr}
\subsubsection{\bf Detected SFP not supported for WR timing}
\label{fail:timing:wrong_sfp}
\begin{pck_descr}
\item [] \underline{Severity}: ERROR
\item [] \underline{Mode}: \emph{all}
\item [] \underline{Description}:\\
By not supported SFP for WR timing we mean a transceiver that doesn't
have the \emph{alpha} parameter and fixed hardware delays defined in the
SFP database. The consequence is \emph{PTP} not having the right
values to estimate the link asymmetry. Despite the \emph{PTP} offset
being close to \emph{0ps}, the device won't be properly synchronized.
\item [] \underline{SNMP objects}:\\
{\footnotesize
\snmpadd{WR-WRPC-MIB::wrpcPortSfpPn}\\
\snmpadd{WR-WRPC-MIB::wrpcPortSfpInDB}\\
\snmpadd{WR-WRPC-MIB::wrpcSfpPn.<n>} }
\item [] \underline{Error condition}:\\
{\footnotesize
\texttt{wrpcPortSfpInDB != inDataBase\emph{(2)}} }
\item [] \underline{Action}:
\begin{pck_proc}
\item Check if the SFP database is correctly defined by making sure the
error \ref{fail:timing:no_sfpdb} is not reported.
\item If you have written calibration data to the SFP database, check if
there is no typing error in the SFP part number. You can do this over
SNMP by reading \snmpadd{WR-WRPC-MIB::wrpcSfpPn.<n>} objects.
\item Change the optical SFP transceiver in the WR Node. Either it is
broken and should be replaced since its ID cannot be read correctly,
or a non-supported transceiver was plugged to the device.
\end{pck_proc}
\end{pck_descr}
\subsubsection{\bf SFP database not configured}
\label{fail:timing:no_sfpdb}
\begin{pck_descr}
\item [] \underline{Severity}: ERROR
\item [] \underline{Mode}: \emph{all}
\item [] \underline{Description}:\\
If there are no SFP entries in the database, any (even WR-supported) SFP
cannot be matched with the calibration values for a given hardware and
fiber. Despite \emph{PTP/PPSi} offset being close to 0 \emph{ps}, the
device won't be properly synchronized.
\item [] \underline{SNMP objects}:\\
{\footnotesize
\snmpadd{WR-WRPC-MIB::wrpcSfpPn.<n>}\\
\snmpadd{WR-WRPC-MIB::wrpcSfpDeltaTx.<n>}\\
\snmpadd{WR-WRPC-MIB::wrpcSfpDeltaRx.<n>}\\
\snmpadd{WR-WRPC-MIB::wrpcSfpAlpha.<n>} }
\item [] \underline{Note}: It's enough to try reading index 1 of the above
SNMP objects tables to make sure there is at least one entry in the
database.
\item [] \underline{Error condition}:\\
{\footnotesize
Error when trying to get any of the \texttt{wrpcSfpPn.1};
\texttt{wrpcSfpDeltaTx.1}; \texttt{wrpcSfpDeltaRx.1};
\texttt{wrpcSfpAlpha.1} SNMP objects}
\item [] \underline{Action}:
\begin{pck_proc}
\item Check the White Rabbit PTP Core User's
Manual\footnote{\url{http://www.ohwr.org/projects/wr-cores/wiki/Current\_release}}
for the instructions how the calibration values can be configured
locally or remotely using SET for SNMP objects.
\end{pck_proc}
\end{pck_descr}
\newpage
\subsection{Other errors}
\label{sec:other_fail}
\subsubsection{\bf WR link is down or FPGA not programmed or FPGA programmed with incorrect bitstream}
\label{fail:timing:master_down}
\begin{pck_descr}
\item [] \underline{Severity}: ERROR
\item [] \underline{Description}:\\
WRPC is monitored over the WR network. This means, to detect whether
the communication link is down we can either periodically ping the
device or monitor if there are no timeouts from SNMP requests.
\item [] \underline{SNMP objects}: \emph{(none)}
\item [] \underline{Error condition}:\\
{\footnotesize
SNMP request timeout or PING timeout}
\item [] \underline{Action}:
\begin{pck_proc}
\item Investigate on the computer/front-end where the WR Node card is
installed, if all the drivers are properly loaded and if the FPGA gets
programmed. You can take another WR Master device and connect it
locally to verify if the WR Node is programmed correctly.
\item If you have access to the physical UART connected to the WRPC or
you have a Virtual-UART for your hosted environment, you may try
accessing the WRPC shell to make sure the FPGA is programmed. Please
see the official \emph{White Rabbit PTP Core User's Manual} for more
information.
\item Check the fiber link e.g. by connecting another WR Node, with a
different SFP transceiver to the same fiber.
\item If there is still no link on the new WR Node, try connecting
fiber on the Master side to another port of the WR Switch (using
different SFP transceiver).
\item If there is still no link, the fiber connection is either dirty or
broken.
\end{pck_proc}
\end{pck_descr}
\subsubsection{\bf WR PTP Core reset}
\label{fail:other:reset}
\begin{pck_descr}
\item [] \underline{Severity}: ERROR
\item [] \underline{Description}:\\
If the WRPC was reset it might either mean that there was a power cut or
some not yet known bug caused the WRPC software to crash.
\item [] \underline{SNMP objects}:\\
{\footnotesize
\snmpadd{WR-WRPC-MIB::wrpcTimeSystemUptime} }
\item [] \underline{Error condition}:\\
{\footnotesize
\texttt{wrpcTimeSystemUptime < wrpcTimeSystemUptime\_prev} }
\item [] \underline{Action}:
\begin{pck_proc}
\item Dump state.
\item Check if there was a power cut e.g. by checking the uptime of the
computer/front-end where the WR Node card is installed.
\item If there was no power cut or intended machine restart, make a full
state dump and report problem to WR experts.
\end{pck_proc}
\end{pck_descr}
\subsubsection{\bf WR PTP Core time reset}
\label{fail:other:time_reset}
\begin{pck_descr}
\item [] \underline{Severity}: ERROR
\item [] \underline{Description}:\\
If the WRPC internal time counters are reset, this might mean the WR
Master in the network has some problems and WRPC has followed the time
reset. If that's not the case, this might mean some not yet known bug
caused the WRPC time reset.
\item [] \underline{SNMP objects}:\\
{\footnotesize
\snmpadd{WR-WRPC-MIB::wrpcTimeTAI}\\
\snmpadd{WR-WRPC-MIB::wrpcTimeTAIString} }
\item [] \underline{Error condition}:\\
{\footnotesize
\texttt{wrpcTimeTAI == 0} }
\item [] \underline{Action}:
\begin{pck_proc}
\item Dump state.
\item Check the status of the WR Master - timing source.
\item Check in the SNMP manager software logs, if there were no
\emph{link down} errors for the WR Node or the WR Master Switch. In
that case, the SFP optical transceivers should be changed or the fiber
link should be investigated.
\end{pck_proc}
\end{pck_descr}
\subsubsection{\bf Temperature of the node too high}
\label{fail:other:temp}
\begin{pck_descr}
\item [] \underline{Severity}: WARNING
\item [] \underline{Description}:\\
If the temperature raises too high we might break our electronics. It
also means that most probably something is wrong with the node cooling.
\item [] \underline{SNMP objects}:\\
{\footnotesize
\snmpadd{WR-WRPC-MIB::wrpcTemperatureName.<n>}\\
\snmpadd{WR-WRPC-MIB::wrpcTemperatureValue.<n>} }
\item [] \underline{Error condition}:\\
{\footnotesize
\texttt{wrpcTemperatureValue.<n> > THRESHOLD} }
\item [] \underline{Action}:
\begin{pck_proc}
\item Check the cooling for the computer/front-end/rack where the WR
Node is installed.
\end{pck_proc}
\end{pck_descr}
\section{Introduction}
This document provides information about the diagnostics of the White Rabbit
PTP Core (WRPC) - an HDL module present in every White Rabbit node. It is a
complementary documentation to the official \emph{White Rabbit PTP Core User's
Manual} published with every stable release. Please refer to this user manual
for the information about the WRPC, its interfaces and building instructions for
the official reference designs.\\
White Rabbit PTP Core starting from \emph{v4.0} provides diagnostic mechanisms
in the form of SNMP objects and optional Syslog messages (depending on the build
time LM32 software configuration). The implementation of an SNMP agent in the
WRPC is very basic comparing to the diagnostics offered by the White Rabbit
Switch. Since we are very constraint on the code size running inside the WR PTP
Core, almost all of the logic to detect and report errors has to be implemented
on the SNMP Manager's side.\\
This document has many internal hyperlinks that associate SNMP objects with
related problems description and the other way round. These links can be easily
used when reading the document on a computer.
\section{List of exported SNMP objects}
This section lists all the SNMP objects exported by the WR PTP Core. The objects
provide read-only values unless stated otherwise in their description.\\
\printnoidxglossary[type=snmp_status,title=,style=objtree,sort=def]
\snmpentrys{WR-WRPC-MIB}{}{wrpcVersionGroup}{
Group containing information about the WR PTP Core firmware version.}
\snmpentrys{WR-WRPC-MIB}{wrpcVersionGroup}{wrpcVersionHwType}{
\underline{Description:}
Type of the hardware of a given WR Node.}
\snmpentrys{WR-WRPC-MIB}{wrpcVersionGroup}{wrpcVersionSwVersion}{
\underline{Description:}
Version of the LM32 software running inside the WR PTP Core. }
\snmpentrys{WR-WRPC-MIB}{wrpcVersionGroup}{wrpcVersionSwBuildBy}{
\underline{Description:}
Information who has compiled the LM32 software running inside the WR PTP
Core. }
\snmpentrys{WR-WRPC-MIB}{wrpcVersionGroup}{wrpcVersionSwBuildDate}{
\underline{Description:}
Information when the LM32 software was compiled. }
\snmpentrys{WR-WRPC-MIB}{}{wrpcTimeGroup}{
Group containing system timers information}
\snmpentrys{WR-WRPC-MIB}{wrpcTimeGroup}{wrpcTimeTAI}{
\underline{Description:}
Current TAI time of the WR Node.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcTimeGroup}{wrpcTimeTAIString}{
\underline{Description:}
The current TAI time, printed as \%y-\%m-\%d-\%H:\%M:\%S (no time zone)
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcTimeGroup}{wrpcTimeSystemUptime}{
\underline{Description:}
System uptime in hundreds of second
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{}{wrpcTemperatureTable}{
Table of onboard thermometers measurements.}
\snmpentrys{WR-WRPC-MIB}{wrpcTemperatureTable}{wrpcTemperatureName.<n>}{
\underline{Description:}
Name of the temperature sensor \emph{n}.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcTemperatureTable}{wrpcTemperatureValue.<n>}{
\underline{Description:}
Temperature value of the sensor \emph{n}.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{}{wrpcSpllStatusGroup}{
Group containing White Rabbit PLLs status}
\snmpentrys{WR-WRPC-MIB}{wrpcSpllStatusGroup}{wrpcSpllMode}{
\underline{Description:}
Mode of operation of the Soft PLL inside WR PTP Core. Possible values:
\begin{packed_items_snmp_obj}
\item \texttt{grandmaster\emph{(1)}} -- Master synchronized to external reference (e.g. GPS or Cesium)
\item \texttt{master\emph{(2)}} -- Free-running Master
\item \texttt{slave\emph{(3)}}
\item \texttt{disabled\emph{(4)}}
\end{packed_items_snmp_obj}
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcSpllStatusGroup}{wrpcSpllIrqCnt}{
\underline{Description:}
Number of interrupts received by SoftPLL for DDMTD tags.}
\snmpentrys{WR-WRPC-MIB}{wrpcSpllStatusGroup}{wrpcSpllSeqState}{
\underline{Description:}
SoftPLL sequencer state. Possible values:
\begin{packed_items_snmp_obj}
\item \texttt{startExt\emph{(1)}}
\item \texttt{waitExt\emph{(2)}}
\item \texttt{startHelper\emph{(3)}}
\item \texttt{waitHelper\emph{(4)}}
\item \texttt{startMain\emph{(5)}}
\item \texttt{waitMain\emph{(6)}}
\item \texttt{disabled\emph{(7)}}
\item \texttt{ready\emph{(8)}}
\item \texttt{clearDacs\emph{(9)}}
\item \texttt{waitClearDacs\emph{(10)}}
\end{packed_items_snmp_obj}
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcSpllStatusGroup}{wrpcSpllAlignState}{
\underline{Description:}
SoftPLL aligner state. Possible values:
\begin{packed_items_snmp_obj}
\item \texttt{extOff\emph{(0)}}
\item \texttt{start\emph{(1)}}
\item \texttt{initCsync\emph{(2)}}
\item \texttt{waitCsync\emph{(3)}}
\item \texttt{waitSample\emph{(4)}}
\item \texttt{compensateDelay\emph{(5)}}
\item \texttt{locked\emph{(6)}}
\item \texttt{startAlignment\emph{(7)}}
\item \texttt{startMain\emph{(8)}}
\item \texttt{waitClkin\emph{(9)}}
\item \texttt{waitPlock\emph{(10)}}
\end{packed_items_snmp_obj}
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcSpllStatusGroup}{wrpcSpllHlock}{
\underline{Description:}
Helper PLL lock status.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcSpllStatusGroup}{wrpcSpllMlock}{
\underline{Description:}
Main PLL lock status.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcSpllStatusGroup}{wrpcSpllHY}{
\underline{Description:}
Helper PLL DAC value (range 0-65535).}
\snmpentrys{WR-WRPC-MIB}{wrpcSpllStatusGroup}{wrpcSpllMY}{
\underline{Description:}
Main PLL DAC value (range 0-65535).}
\snmpentrys{WR-WRPC-MIB}{wrpcSpllStatusGroup}{wrpcSpllDelCnt}{
\underline{Description:}
Delock counter - how many times either Helper of Main PLL lost lock since
the WRPC software has started.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{}{wrpcPtpGroup}{
Group with various information about PTP state}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpGroup}{wrpcPtpServoStateN}{
\underline{Description:}
Current state of WR synchronization servo running in the PTP. Possible
values:
\begin{packed_items_snmp_obj}
\item \texttt{uninitialized\emph{(0)}}
\item \texttt{syncNsec\emph{(1)}}
\item \texttt{syncSec\emph{(2)}}
\item \texttt{syncPhase\emph{(3)}}
\item \texttt{trackPhase\emph{(4)}}
\item \texttt{waitOffsetStable\emph{(5)}}
\end{packed_items_snmp_obj}
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpGroup}{wrpcPtpClockOffsetPsHR}{
\underline{Description:}
Current clock offset from master in picoseconds, calculated by PTP.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpGroup}{wrpcPtpSkew}{
\underline{Description:}
The estimated change of master-to-slave delay, in picoseconds.}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpGroup}{wrpcPtpRTT}{
\underline{Description:}
Round-trip-time in picoseconds calculated by PTP.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpGroup}{wrpcPtpServoUpdates}{
\underline{Description:}
Counter incremented each time the WR PTP servo calculates the offset value
from WR master and corrects the local clock.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpGroup}{wrpcPtpServoUpdateTime}{
\underline{Description:}
TAI nanoseconds when the WR PTP servo was last updated.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpGroup}{wrpcPtpDeltaTxM}{
\underline{Description:}
Fixed Tx latency of the WR master.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpGroup}{wrpcPtpDeltaRxM}{
\underline{Description:}
Fixed Rx latency of the WR master.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpGroup}{wrpcPtpDeltaTxS}{
\underline{Description:}
Fixed Tx latency of the WR slave.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpGroup}{wrpcPtpDeltaRxS}{
\underline{Description:}
Fixed Rx latency of the WR slave.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpGroup}{wrpcPtpServoStateErrCnt}{
\underline{Description:}
Number of times when WR PTP servo has lost the synchronization, i.e. went
ouf from the \texttt{TRACK\_PHASE} state.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpGroup}{wrpcPtpClockOffsetErrCnt}{
\underline{Description:}
Number of times when calculated offset to the Master was larger than
+/-500ps.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpGroup}{wrpcPtpRTTErrCnt}{
\underline{Description:}
Number of times when the jump was detected in the calculated round-trip-time
value. The jump is detected when rtt changes by more than 1ns comparing to the
previously calculated value.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpGroup}{wrpcPtpAsymmetry}{
\underline{Description:}
Link asymmetry calculated by PTP.}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpGroup}{wrpcPtpTx}{
\underline{Description:}
Number of transmitted PTP frames.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpGroup}{wrpcPtpRx}{
\underline{Description:}
Number of received PTP frames.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpGroup}{wrpcPtpAlpha}{
\underline{Description:}
Alpha value (fiber asymmetry coefficient) used for WR to estimate the
one-way link delay.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{}{wrpcPtpConfigGroup}{
The groups contains objects for configuring remotely the SFP database with
calibration parameters}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpConfigGroup}{wrpcPtpConfigRestart}{
\underline{Description:}
Read-write object to trigger the PTP restart to use the new settings.
Possible values:
\begin{packed_items_snmp_obj}
\item write: \texttt{restartPtp\emph{(1)}} -- triggers PTP restart
\item read: \texttt{restartPtpSuccessful\emph{(100)}} -- PTP restart triggered successfully
\item read: \texttt{restartPtpFailed\emph{(200)}} -- failed to trigger PTP restart
\end{packed_items_snmp_obj}
}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpConfigGroup}{wrpcPtpConfigApply}{
\underline{Description:}
Read-write object to validate and apply SFP settings. Possible values:
\begin{packed_items_snmp_obj}
\item write: \texttt{writeToFlashGivenSfp\emph{(1)}} -- write provided
\texttt{\glshyperlink{WR-WRPC-MIB::wrpcPtpConfigDeltaTx}},
\texttt{\glshyperlink{WR-WRPC-MIB::wrpcPtpConfigDeltaRx}},
\texttt{\glshyperlink{WR-WRPC-MIB::wrpcPtpConfigAlpha}} values to the SFP
database stored in the Flash for the SFP product number provided in
\texttt{\glshyperlink{WR-WRPC-MIB::wrpcPtpConfigSfpPn}}. The new values are
automatically loaded to the memory (\emph{sfp match} command is executed).
\item write: \texttt{writeToFlashCurrentSfp\emph{(2)}} -- write provided
\texttt{\glshyperlink{WR-WRPC-MIB::wrpcPtpConfigDeltaTx}},
\texttt{\glshyperlink{WR-WRPC-MIB::wrpcPtpConfigDeltaRx}},
\texttt{\glshyperlink{WR-WRPC-MIB::wrpcPtpConfigAlpha}} values to the SFP
database stored in the Flash for the SFP that is currently used. The new
values are automatically loaded to the memory (\emph{sfp match} command is
executed).
\item w: \texttt{writeToMemoryCurrentSfp\emph{(3)}} -- write provided
\texttt{\glshyperlink{WR-WRPC-MIB::wrpcPtpConfigDeltaTx}},
\texttt{\glshyperlink{WR-WRPC-MIB::wrpcPtpConfigDeltaRx}},
\texttt{\glshyperlink{WR-WRPC-MIB::wrpcPtpConfigAlpha}} values only to the
memory. The SFP database in the Flash is not modified.
\item write: \texttt{eraseFlash\emph{(50)}} -- erase SFP database stored in the Flash
\item read: \texttt{applySuccessful\emph{(100)}} -- required configuration applied successfully
\item read: \texttt{applySuccessfulMatchFailed\emph{(101)}} -- required values written to the database but
could not be matched with the currently used SFP
\item read: \texttt{applyFailed\emph{(200)}} -- failed to apply configuration
\item read: \texttt{applyFailedI2CError\emph{(201)}} -- failed to apply, communication error with the
flash memory
\item read: \texttt{applyFailedDBFull\emph{(202)}} -- failed to apply, SFP database is full
\item read: \texttt{applyFailedInvalidPN\emph{(203)}} -- failed to apply, invalid SFP product number
\end{packed_items_snmp_obj}
}
\snmpentrys{WR-WRPC-MIB}{wrpcPtpConfigGroup}{wrpcPtpConfigSfpPn}{
\underline{Description:}
Read-write object. SFP product number identifying which entry in the Flash
SFP database to
update. }
\snmpentrys{WR-WRPC-MIB}{wrpcPtpConfigGroup}{wrpcPtpConfigDeltaTx}{
\underline{Description:}
Read-write object. Fixed Tx delay value to be written, in picoseconds. }
\snmpentrys{WR-WRPC-MIB}{wrpcPtpConfigGroup}{wrpcPtpConfigDeltaRx}{
\underline{Description:}
Read-write object. Fixed Rx delay value to be written, in picoseconds. }
\snmpentrys{WR-WRPC-MIB}{wrpcPtpConfigGroup}{wrpcPtpConfigAlpha}{
\underline{Description:}
Read-write object. Alpha fiber asymmetry parameter to be written. }
\snmpentrys{WR-WRPC-MIB}{}{wrpcPortGroup}{
Group containing various information about the WR Ethernet port.}
\snmpentrys{WR-WRPC-MIB}{wrpcPortGroup}{wrpcPortLinkStatus}{
\underline{Description:}
Status of the link. Possible values:\\
\texttt{down\emph{(1)}} -- link is down\\
\texttt{up\emph{(2)}} -- link is up}
\snmpentrys{WR-WRPC-MIB}{wrpcPortGroup}{wrpcPortSfpPn}{
\underline{Description:}
Product number of the SFP currently plugged into the WR port.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcPortGroup}{wrpcPortSfpInDB}{
\underline{Description:}
Information whether the currently plugged SFP was matched with the
calibration values stored in the database. Possible values:
\begin{packed_items_snmp_obj}
\item \texttt{notInDataBase\emph{(1)}} -- currently plugged SFP could not be matched with any database entry
\item \texttt{inDataBase\emph{(2)}} -- currently plugged SFP was matched with database entry
\end{packed_items_snmp_obj}
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcPortGroup}{wrpcPortInternalTx}{
\underline{Description:}
Total number of Ethernet frames transmitted from LM32 processor.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcPortGroup}{wrpcPortInternalRx}{
\underline{Description:}
Total number of Ethernet frames received by LM32 processor.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{}{wrpcSfpTable}{
Table of the calibration values stored in the SFP database.}
\snmpentrys{WR-WRPC-MIB}{wrpcSfpTable}{wrpcSfpPn.<n>}{
\underline{Description:}
Product number for the SFP \emph{n} in the database.}
\snmpentrys{WR-WRPC-MIB}{wrpcSfpTable}{wrpcSfpDeltaTx.<n>}{
\underline{Description:}
Fixed Tx delay for the SFP \emph{n} in the database.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcSfpTable}{wrpcSfpDeltaRx.<n>}{
\underline{Description:}
Fixed Rx delay for the SFP \emph{n} in the database.
\glspar \underline{Related problems:}}
\snmpentrys{WR-WRPC-MIB}{wrpcSfpTable}{wrpcSfpAlpha.<n>}{
\underline{Description:}
Alpha fiber asymmetry coefficient for the SFP \emph{n} in the database.}
\def\us{\char`\_}
\documentclass[a4paper, 12pt]{article}
%\documentclass{article}
\usepackage{fullpage}
\usepackage{pgf}
\usepackage{tikz}
\usetikzlibrary{arrows,automata,shapes}
\usepackage{multirow}
\usepackage{color}
\usepackage[latin1]{inputenc}
\usepackage{verbatim}
\usepackage{amsmath}
\usepackage{textcomp}
\usepackage{times,mathptmx}
\usepackage{chngcntr}
\usepackage{hyperref}
\usepackage{enumitem}
\usepackage{scrextend}
%\usepackage[table]{xcolor}
\usepackage{listings}
\definecolor{light-gray}{gray}{0.95}
%\usepackage[firstpage]{draftwatermark}
% for glossary
% nopostdot - no dot at the end of index entires
\usepackage[nogroupskip,nopostdot,counter=subsubsection]{glossaries}
\renewcommand{\glossarysection}[2][]{}
\usepackage{listings}
\usepackage{cancel}
\graphicspath{ {../../../../figures/} }
\newenvironment{packed_enum}{
\begin{enumerate}[leftmargin=0pt,topsep=-12pt]
\setlength{\itemsep}{1pt}
\setlength{\parskip}{0pt}
\setlength{\parsep}{0pt}
}{\end{enumerate}}
\newenvironment{packed_items}{
\begin{itemize}[topsep=-12pt]
\setlength{\itemsep}{1pt}
\setlength{\parskip}{0pt}
\setlength{\parsep}{0pt}
}{\end{itemize}}
% \begin{itemize}[leftmargin=50pt] %,topsep=-12pt]
\newenvironment{packed_items_snmp_obj}{
\begin{itemize}[leftmargin=50pt]
\setlength{\itemsep}{1pt}
\setlength{\parskip}{0pt}
\setlength{\parsep}{0pt}
\renewcommand\labelitemi{--}
}{\end{itemize}}
\newenvironment{pck_descr}{
\begin{itemize}[leftmargin=0pt,topsep=-12pt]
\setlength{\itemsep}{1pt}
\setlength{\parskip}{0pt}
\setlength{\parsep}{0pt}
}{\end{itemize}}
\newenvironment{pck_proc}{
\begin{enumerate}[leftmargin=15pt,topsep=-12pt]
\setlength{\itemsep}{1pt}
\setlength{\parskip}{0pt}
\setlength{\parsep}{0pt}
}{\end{enumerate}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% creating subsubsubsection notation
% src: http://www.latex-community.org/forum/viewtopic.php?f=5&t=791
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\setcounter{secnumdepth}{6}
\renewcommand\theparagraph{\Alph{paragraph}}
\makeatletter
\renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}%
{-3.25ex\@plus -1ex \@minus -.2ex}%
{0.0001pt \@plus .2ex}%
{\normalfont\normalsize\bfseries}}
\renewcommand\subparagraph{\@startsection{subparagraph}{5}{\z@}%
{-3.25ex\@plus -1ex \@minus -.2ex}%
{0.0001pt \@plus .2ex}%
{\normalfont\normalsize\bfseries}}
\counterwithin{paragraph}{subsubsection}
\counterwithin{subparagraph}{paragraph}
\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\eqoffset}[1]{%
{\ensuremath{%
{\text{offset}}_{#1}}%
}%
}
\newcommand{\eqdelay}[1]{{\text{delay}}_{#1}}
\newcommand{\eqasymm}{{\text{asymmetry}}}
% for glossary, set way of sorting entries
\makenoidxglossaries
% don't bold entries, texttt them
\renewcommand*{\glsnamefont}[1]{\texttt{\textmd{#1}}}
\newglossary*{snmp_status}{SNMP's status objects}
\newglossary*{snmp_expert}{SNMP's expert objects}
\newglossary*{snmp_other}{Objects from other MIBs}
% alphabetical list of all entries
\newglossary*{snmp_all}{All SNMP objects}
\defglsentryfmt[snmp_status]{\texttt{\glsentryfmt}}
\defglsentryfmt[snmp_expert]{\texttt{\glsentryfmt}}
\defglsentryfmt[snmp_other]{\texttt{\glsentryfmt}}
% macro to add entires
\newcommand{\snmpadd}[1]{
\glspl{#1}\glsadd{x#1}%
}
% helpers to add glossary entries
% add newline to non empty strings. For descriptions.
\newcommand{\descr}[1]{
\ifx&#1&%
%
\else% put fixed space
\\#1
\fi
}
% {MIB}{parent}{object}{comment}{glossary_name}
\newcommand{\snmpentry}[5]{%
\ifx&#2&% if parameter 2 is empty don't add parent
\newglossaryentry{#1::#3}{%
type=#5,%
name={#3},%
plural={#1::#3},% used to display name not plural
user1={#1},% MIB
description={\descr{#4}}%
}%
\else
\newglossaryentry{#1::#3}{%
type=#5,%
name={#3},%
description={\descr{#4}},%
plural={#1::#3},% used to display name not plural
user1={#1},% MIB
parent={#1::#2}%
}%
\fi
% add entry to alphabetical list
\newglossaryentry{x#1::#3}{%
type=snmp_all,%
name={#1::#3},%
description={}
}%
}
% {MIB}{parent}{object}{comment}
\newcommand{\snmpentrye}[4]{%
\snmpentry{#1}{#2}{#3}{#4}{snmp_expert}
}
% {MIB}{parent}{object}{comment}
\newcommand{\snmpentrys}[4]{%
\snmpentry{#1}{#2}{#3}{#4}{snmp_status}
}
% command to add snmp objects from other MIBs
% {MIB}{parent}{object}{comment}
\newcommand{\snmpentryo}[4]{%
\snmpentry{#1}{#2}{#3}{#4}{snmp_other}
}
% extra indent for lists
\newlength{\paraaindent}
% indent for new paragraphs
\newlength{\snmpentryindent}
% load glossary definitions from snmp_objects.tex
\loadglsentries{snmp_objects}
% use \kern 0.33em instead of \space to have fixed width space
\newglossarystyle{objtree}{%
\renewenvironment{theglossary}%
{\setlength{\parindent}{0pt}%
\setlength{\parskip}{0pt plus 0.3pt}}%
{}%
\renewcommand*{\glossaryheader}{}%
\renewcommand*{\glsgroupheading}[1]{}%
\renewcommand{\glossentry}[2]{%
\hangindent30pt\relax
% save indent for other paragraphs
\setlength{\snmpentryindent}{\hangindent}
\parindent0pt\relax
% set indent for lists entries
\setlength{\paraaindent}{\hangindent}
\addtolength{\paraaindent}{14pt}
\setlist[enumerate]{leftmargin=\paraaindent}
$\bullet$\kern 0.33em\glsentryitem{##1}\glstreenamefmt{\glstarget{##1}{\texttt{\textmd{\glsentryuseri{##1}}::}\glossentryname{##1}}}%
\ifglshassymbol{##1}{\kern 0.33em(\glossentrysymbol{##1})}{}%
\glossentrydesc{##1}\glspostdescription\kern 0.33em##2\par\vspace{12pt}
}%
\renewcommand{\subglossentry}[3]{%
\hangindent##1\glstreeindent\relax
\addtolength{\hangindent}{30pt}
% save indent for other paragraphs
\setlength{\snmpentryindent}{\hangindent}
\parindent##1\glstreeindent\relax
% set indent for lists entries
\setlength{\paraaindent}{\hangindent}
\addtolength{\paraaindent}{14pt}
\setlist[enumerate]{leftmargin=\paraaindent}
\ifnum##1=1\relax
$\circ$%
\fi
\ifnum##1=2\relax
$\ast$%
\fi
\kern 0.33em%
\ifnum##1=1\relax
\glssubentryitem{##2}%
\fi
\glstreenamefmt{\glstarget{##2}{\glossentryname{##2}}}%
\ifglshassymbol{##2}{\kern 0.33em(\glossentrysymbol{##2})}{}%
\glossentrydesc{##2}\glspostdescription\kern 0.33em##3\par\vspace{12pt}
}%
%redefine \glspar to support indentation in many paragraphs
\renewcommand{\glspar}{%
\par
\parindent\snmpentryindent % restore first line in paragraph indent
\hangindent\snmpentryindent % restore other lines in paragraph indent
}%
}
\newcommand{\ignore}[1]{}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\setcounter{tocdepth}{2}
\input{revinfo.tex}
\title{White Rabbit PTP Core: Failures and Diagnostics}
\author{Grzegorz Daniluk\\[.5cm] CERN BE-CO-HT\\ \small{\gitrevinfo}}
\maketitle
\thispagestyle{empty}
\begin{figure}[ht!]
\centering
\vspace{1.3cm}
\includegraphics[width=0.50\textwidth]{img/WRlogo.pdf}
\end{figure}
\newpage
\newpage
\newpage
\tableofcontents
\newpage
\input{intro.tex}
\newpage
\section{Possible Errors}
\label{sec:failures}
\input{fail.tex}
\newpage
\input{snmp_exports.tex}
% add not used entries, but don't display their's section
% based on:
% http://tex.stackexchange.com/questions/115635/glossaries-suppress-pages-when-using-glsaddall
\forallglsentries{\thislabel}%
{%
\ifglsused{\thislabel}{}{\glsadd[format=ignore]{\thislabel}}%
}
\end{document}
......@@ -196,7 +196,6 @@ struct dump_info dump_info[] = {
DUMP_FIELD(int, mode),
DUMP_FIELD(int, seq_state),
DUMP_FIELD(int, dac_timeout),
DUMP_FIELD(int, default_dac_main),
DUMP_FIELD(int, delock_count),
DUMP_FIELD(uint32_t, irq_count),
DUMP_FIELD(int, mpll_shift_ps),
......@@ -205,7 +204,6 @@ struct dump_info dump_info[] = {
DUMP_FIELD(int, helper.tag_d0),
DUMP_FIELD(int, helper.ref_src),
DUMP_FIELD(int, helper.sample_n),
DUMP_FIELD(int, helper.delock_count),
/* FIXME: missing helper.pi etc.. */
DUMP_FIELD(int, ext.enabled),
DUMP_FIELD(int, ext.align_state),
......@@ -221,16 +219,11 @@ struct dump_info dump_info[] = {
DUMP_FIELD(int, mpll.tag_out),
DUMP_FIELD(int, mpll.tag_ref_d),
DUMP_FIELD(int, mpll.tag_out_d),
DUMP_FIELD(uint32_t, mpll.seq_ref),
DUMP_FIELD(int, mpll.seq_out),
DUMP_FIELD(int, mpll.match_state),
DUMP_FIELD(int, mpll.match_seq),
DUMP_FIELD(int, mpll.phase_shift_target),
DUMP_FIELD(int, mpll.phase_shift_current),
DUMP_FIELD(int, mpll.id_ref),
DUMP_FIELD(int, mpll.id_out),
DUMP_FIELD(int, mpll.sample_n),
DUMP_FIELD(int, mpll.delock_count),
DUMP_FIELD(int, mpll.dac_index),
DUMP_FIELD(int, mpll.enabled),
......
......@@ -73,10 +73,6 @@ void uart_init_hw(void)
}
void uart_init_sw(void)
{ printf("%s\n", __func__); }
void uart_exit(int i)
{
system("stty sane");
......
......@@ -6,9 +6,6 @@
#ifndef __ENDPOINT_H
#define __ENDPOINT_H
#define DMTD_AVG_SAMPLES 256
#define DMTD_MAX_PHASE 16384
#include <stdint.h>
typedef enum {
......
/*
Register definitions for slave core: Simple Wishbone UART
* File : ../../../../software/include/hw/wb_uart.h
* Author : auto-generated by wbgen2 from uart.wb
* Created : Mon Feb 21 22:25:02 2011
* File : wb_uart.h
* Author : auto-generated by wbgen2 from simple_uart_wb.wb
* Created : Wed Mar 1 17:29:58 2017
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE uart.wb
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE simple_uart_wb.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_UART_WB
#define __WBGEN2_REGDEFS_UART_WB
#ifndef __WBGEN2_REGDEFS_SIMPLE_UART_WB_WB
#define __WBGEN2_REGDEFS_SIMPLE_UART_WB_WB
#include <inttypes.h>
......@@ -30,6 +30,7 @@
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: Status Register */
/* definitions for field: TX busy in reg: Status Register */
......@@ -55,24 +56,48 @@
#define UART_RDR_RX_DATA_SHIFT 0
#define UART_RDR_RX_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_RDR_RX_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* [0x0]: REG Status Register */
#define UART_REG_SR 0x00000000
/* [0x4]: REG Baudrate control register */
#define UART_REG_BCR 0x00000004
/* [0x8]: REG Transmit data regsiter */
#define UART_REG_TDR 0x00000008
/* [0xc]: REG Receive data regsiter */
#define UART_REG_RDR 0x0000000c
/* definitions for register: Host VUART Tx register */
/* definitions for field: TX Data in reg: Host VUART Tx register */
#define UART_HOST_TDR_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_HOST_TDR_DATA_SHIFT 0
#define UART_HOST_TDR_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_HOST_TDR_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for field: TX Ready in reg: Host VUART Tx register */
#define UART_HOST_TDR_RDY WBGEN2_GEN_MASK(8, 1)
/* definitions for register: Host VUART Rx register */
/* definitions for field: RX Data in reg: Host VUART Rx register */
#define UART_HOST_RDR_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_HOST_RDR_DATA_SHIFT 0
#define UART_HOST_RDR_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_HOST_RDR_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for field: RX Ready in reg: Host VUART Rx register */
#define UART_HOST_RDR_RDY WBGEN2_GEN_MASK(8, 1)
/* definitions for field: RX FIFO Count in reg: Host VUART Rx register */
#define UART_HOST_RDR_COUNT_MASK WBGEN2_GEN_MASK(9, 16)
#define UART_HOST_RDR_COUNT_SHIFT 9
#define UART_HOST_RDR_COUNT_W(value) WBGEN2_GEN_WRITE(value, 9, 16)
#define UART_HOST_RDR_COUNT_R(reg) WBGEN2_GEN_READ(reg, 9, 16)
PACKED struct UART_WB {
/* [0x0]: REG Status Register */
uint32_t SR;
/* [0x4]: REG Baudrate control register */
uint32_t BCR;
/* [0x8]: REG Transmit data regsiter */
uint32_t TDR;
/* [0xc]: REG Receive data regsiter */
uint32_t RDR;
/* [0x0]: REG Status Register */
uint32_t SR;
/* [0x4]: REG Baudrate control register */
uint32_t BCR;
/* [0x8]: REG Transmit data regsiter */
uint32_t TDR;
/* [0xc]: REG Receive data regsiter */
uint32_t RDR;
/* [0x10]: REG Host VUART Tx register */
uint32_t HOST_TDR;
/* [0x14]: REG Host VUART Rx register */
uint32_t HOST_RDR;
};
#endif
/*
Register definitions for slave core: Virtual UART
* File : wb_vuart.h
* Author : auto-generated by wbgen2 from wb_virtual_uart.wb
* Created : Wed Apr 6 23:02:01 2011
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wb_virtual_uart.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_WB_VIRTUAL_UART_WB
#define __WBGEN2_REGDEFS_WB_VIRTUAL_UART_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: Status Register */
/* definitions for field: TX busy in reg: Status Register */
#define UART_SR_TX_BUSY WBGEN2_GEN_MASK(0, 1)
/* definitions for field: RX ready in reg: Status Register */
#define UART_SR_RX_RDY WBGEN2_GEN_MASK(1, 1)
/* definitions for register: Baudrate control register */
/* definitions for register: Transmit data regsiter */
/* definitions for field: Transmit data in reg: Transmit data regsiter */
#define UART_TDR_TX_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_TDR_TX_DATA_SHIFT 0
#define UART_TDR_TX_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_TDR_TX_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: Receive data regsiter */
/* definitions for field: Received data in reg: Receive data regsiter */
#define UART_RDR_RX_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_RDR_RX_DATA_SHIFT 0
#define UART_RDR_RX_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_RDR_RX_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: FIFO 'UART TX FIFO' data output register 0 */
/* definitions for field: Char sent by UART to TX in reg: FIFO 'UART TX FIFO' data output register 0 */
#define UART_DEBUG_R0_TX_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_DEBUG_R0_TX_SHIFT 0
#define UART_DEBUG_R0_TX_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_DEBUG_R0_TX_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: FIFO 'UART TX FIFO' control/status register */
/* definitions for field: FIFO full flag in reg: FIFO 'UART TX FIFO' control/status register */
#define UART_DEBUG_CSR_FULL WBGEN2_GEN_MASK(16, 1)
/* definitions for field: FIFO empty flag in reg: FIFO 'UART TX FIFO' control/status register */
#define UART_DEBUG_CSR_EMPTY WBGEN2_GEN_MASK(17, 1)
/* definitions for field: FIFO counter in reg: FIFO 'UART TX FIFO' control/status register */
#define UART_DEBUG_CSR_USEDW_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_DEBUG_CSR_USEDW_SHIFT 0
#define UART_DEBUG_CSR_USEDW_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_DEBUG_CSR_USEDW_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
PACKED struct UART_WB {
/* [0x0]: REG Status Register */
uint32_t SR;
/* [0x4]: REG Baudrate control register */
uint32_t BCR;
/* [0x8]: REG Transmit data regsiter */
uint32_t TDR;
/* [0xc]: REG Receive data regsiter */
uint32_t RDR;
/* [0x10]: REG FIFO 'UART TX FIFO' data output register 0 */
uint32_t DEBUG_R0;
/* [0x14]: REG FIFO 'UART TX FIFO' control/status register */
uint32_t DEBUG_CSR;
};
#endif
/*
Register definitions for slave core: WR Transmission control, status and debug
* File : ./doc/wr_streamers.h
* Author : auto-generated by wbgen2 from wr_streamers_wb.wb
* Created : Tue Jun 20 08:53:54 2017
* Version : 0x00000001
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wr_streamers_wb.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_WR_STREAMERS_WB_WB
#define __WBGEN2_REGDEFS_WR_STREAMERS_WB_WB
#ifdef __KERNEL__
#include <linux/types.h>
#else
#include <inttypes.h>
#endif
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* version definition */
#define WBGEN2_WR_STREAMERS_VERSION 0x00000001
/* definitions for register: Version register */
/* definitions for field: Version identifier in reg: Version register */
#define WR_STREAMERS_VER_ID_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_VER_ID_SHIFT 0
#define WR_STREAMERS_VER_ID_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_VER_ID_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Statistics status and ctrl register */
/* definitions for field: Reset statistics in reg: Statistics status and ctrl register */
#define WR_STREAMERS_SSCR1_RST_STATS WBGEN2_GEN_MASK(0, 1)
/* definitions for field: Reset tx seq id in reg: Statistics status and ctrl register */
#define WR_STREAMERS_SSCR1_RST_SEQ_ID WBGEN2_GEN_MASK(1, 1)
/* definitions for field: Snapshot statistics in reg: Statistics status and ctrl register */
#define WR_STREAMERS_SSCR1_SNAPSHOT_STATS WBGEN2_GEN_MASK(2, 1)
/* definitions for field: Latency accumulator overflow in reg: Statistics status and ctrl register */
#define WR_STREAMERS_SSCR1_RX_LATENCY_ACC_OVERFLOW WBGEN2_GEN_MASK(3, 1)
/* definitions for field: Reset timestamp cycles in reg: Statistics status and ctrl register */
#define WR_STREAMERS_SSCR1_RST_TS_CYC_MASK WBGEN2_GEN_MASK(4, 28)
#define WR_STREAMERS_SSCR1_RST_TS_CYC_SHIFT 4
#define WR_STREAMERS_SSCR1_RST_TS_CYC_W(value) WBGEN2_GEN_WRITE(value, 4, 28)
#define WR_STREAMERS_SSCR1_RST_TS_CYC_R(reg) WBGEN2_GEN_READ(reg, 4, 28)
/* definitions for register: Statistics status and ctrl register */
/* definitions for field: Reset timestamp 32 LSB of TAI in reg: Statistics status and ctrl register */
#define WR_STREAMERS_SSCR2_RST_TS_TAI_LSB_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_SSCR2_RST_TS_TAI_LSB_SHIFT 0
#define WR_STREAMERS_SSCR2_RST_TS_TAI_LSB_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_SSCR2_RST_TS_TAI_LSB_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Statistics status and ctrl register */
/* definitions for field: Reset timestamp 8 MSB of TAI in reg: Statistics status and ctrl register */
#define WR_STREAMERS_SSCR3_RST_TS_TAI_MSB_MASK WBGEN2_GEN_MASK(0, 8)
#define WR_STREAMERS_SSCR3_RST_TS_TAI_MSB_SHIFT 0
#define WR_STREAMERS_SSCR3_RST_TS_TAI_MSB_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define WR_STREAMERS_SSCR3_RST_TS_TAI_MSB_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: Rx statistics */
/* definitions for field: WR Streamer frame latency in reg: Rx statistics */
#define WR_STREAMERS_RX_STAT0_RX_LATENCY_MAX_MASK WBGEN2_GEN_MASK(0, 28)
#define WR_STREAMERS_RX_STAT0_RX_LATENCY_MAX_SHIFT 0
#define WR_STREAMERS_RX_STAT0_RX_LATENCY_MAX_W(value) WBGEN2_GEN_WRITE(value, 0, 28)
#define WR_STREAMERS_RX_STAT0_RX_LATENCY_MAX_R(reg) WBGEN2_GEN_READ(reg, 0, 28)
/* definitions for register: Rx statistics */
/* definitions for field: WR Streamer frame latency in reg: Rx statistics */
#define WR_STREAMERS_RX_STAT1_RX_LATENCY_MIN_MASK WBGEN2_GEN_MASK(0, 28)
#define WR_STREAMERS_RX_STAT1_RX_LATENCY_MIN_SHIFT 0
#define WR_STREAMERS_RX_STAT1_RX_LATENCY_MIN_W(value) WBGEN2_GEN_WRITE(value, 0, 28)
#define WR_STREAMERS_RX_STAT1_RX_LATENCY_MIN_R(reg) WBGEN2_GEN_READ(reg, 0, 28)
/* definitions for register: Tx statistics */
/* definitions for field: WR Streamer frame sent count (LSB) in reg: Tx statistics */
#define WR_STREAMERS_TX_STAT2_TX_SENT_CNT_LSB_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_TX_STAT2_TX_SENT_CNT_LSB_SHIFT 0
#define WR_STREAMERS_TX_STAT2_TX_SENT_CNT_LSB_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_TX_STAT2_TX_SENT_CNT_LSB_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Tx statistics */
/* definitions for field: WR Streamer frame sent count (MSB) in reg: Tx statistics */
#define WR_STREAMERS_TX_STAT3_TX_SENT_CNT_MSB_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_TX_STAT3_TX_SENT_CNT_MSB_SHIFT 0
#define WR_STREAMERS_TX_STAT3_TX_SENT_CNT_MSB_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_TX_STAT3_TX_SENT_CNT_MSB_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Rx statistics */
/* definitions for field: WR Streamer frame received count (LSB) in reg: Rx statistics */
#define WR_STREAMERS_RX_STAT4_RX_RCVD_CNT_LSB_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_RX_STAT4_RX_RCVD_CNT_LSB_SHIFT 0
#define WR_STREAMERS_RX_STAT4_RX_RCVD_CNT_LSB_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_RX_STAT4_RX_RCVD_CNT_LSB_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Rx statistics */
/* definitions for field: WR Streamer frame received count (MSB) in reg: Rx statistics */
#define WR_STREAMERS_RX_STAT5_RX_RCVD_CNT_MSB_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_RX_STAT5_RX_RCVD_CNT_MSB_SHIFT 0
#define WR_STREAMERS_RX_STAT5_RX_RCVD_CNT_MSB_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_RX_STAT5_RX_RCVD_CNT_MSB_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Rx statistics */
/* definitions for field: WR Streamer frame loss count (LSB) in reg: Rx statistics */
#define WR_STREAMERS_RX_STAT6_RX_LOSS_CNT_LSB_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_RX_STAT6_RX_LOSS_CNT_LSB_SHIFT 0
#define WR_STREAMERS_RX_STAT6_RX_LOSS_CNT_LSB_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_RX_STAT6_RX_LOSS_CNT_LSB_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Rx statistics */
/* definitions for field: WR Streamer frame loss count (MSB) in reg: Rx statistics */
#define WR_STREAMERS_RX_STAT7_RX_LOSS_CNT_MSB_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_RX_STAT7_RX_LOSS_CNT_MSB_SHIFT 0
#define WR_STREAMERS_RX_STAT7_RX_LOSS_CNT_MSB_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_RX_STAT7_RX_LOSS_CNT_MSB_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Rx statistics */
/* definitions for field: WR Streamer block loss count (LSB) in reg: Rx statistics */
#define WR_STREAMERS_RX_STAT8_RX_LOST_BLOCK_CNT_LSB_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_RX_STAT8_RX_LOST_BLOCK_CNT_LSB_SHIFT 0
#define WR_STREAMERS_RX_STAT8_RX_LOST_BLOCK_CNT_LSB_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_RX_STAT8_RX_LOST_BLOCK_CNT_LSB_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Rx statistics */
/* definitions for field: WR Streamer block loss count (MSB) in reg: Rx statistics */
#define WR_STREAMERS_RX_STAT9_RX_LOST_BLOCK_CNT_MSB_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_RX_STAT9_RX_LOST_BLOCK_CNT_MSB_SHIFT 0
#define WR_STREAMERS_RX_STAT9_RX_LOST_BLOCK_CNT_MSB_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_RX_STAT9_RX_LOST_BLOCK_CNT_MSB_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Rx statistics */
/* definitions for field: WR Streamer frame latency (LSB) in reg: Rx statistics */
#define WR_STREAMERS_RX_STAT10_RX_LATENCY_ACC_LSB_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_RX_STAT10_RX_LATENCY_ACC_LSB_SHIFT 0
#define WR_STREAMERS_RX_STAT10_RX_LATENCY_ACC_LSB_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_RX_STAT10_RX_LATENCY_ACC_LSB_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Rx statistics */
/* definitions for field: WR Streamer frame latency (MSB) in reg: Rx statistics */
#define WR_STREAMERS_RX_STAT11_RX_LATENCY_ACC_MSB_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_RX_STAT11_RX_LATENCY_ACC_MSB_SHIFT 0
#define WR_STREAMERS_RX_STAT11_RX_LATENCY_ACC_MSB_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_RX_STAT11_RX_LATENCY_ACC_MSB_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Rx statistics */
/* definitions for field: WR Streamer frame latency counter (LSB) in reg: Rx statistics */
#define WR_STREAMERS_RX_STAT12_RX_LATENCY_ACC_CNT_LSB_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_RX_STAT12_RX_LATENCY_ACC_CNT_LSB_SHIFT 0
#define WR_STREAMERS_RX_STAT12_RX_LATENCY_ACC_CNT_LSB_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_RX_STAT12_RX_LATENCY_ACC_CNT_LSB_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Rx statistics */
/* definitions for field: WR Streamer frame latency counter (MSB) in reg: Rx statistics */
#define WR_STREAMERS_RX_STAT13_RX_LATENCY_ACC_CNT_MSB_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_RX_STAT13_RX_LATENCY_ACC_CNT_MSB_SHIFT 0
#define WR_STREAMERS_RX_STAT13_RX_LATENCY_ACC_CNT_MSB_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_RX_STAT13_RX_LATENCY_ACC_CNT_MSB_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Tx Config Reg 0 */
/* definitions for field: Ethertype in reg: Tx Config Reg 0 */
#define WR_STREAMERS_TX_CFG0_ETHERTYPE_MASK WBGEN2_GEN_MASK(0, 16)
#define WR_STREAMERS_TX_CFG0_ETHERTYPE_SHIFT 0
#define WR_STREAMERS_TX_CFG0_ETHERTYPE_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define WR_STREAMERS_TX_CFG0_ETHERTYPE_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for register: Tx Config Reg 1 */
/* definitions for field: MAC Local LSB in reg: Tx Config Reg 1 */
#define WR_STREAMERS_TX_CFG1_MAC_LOCAL_LSB_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_TX_CFG1_MAC_LOCAL_LSB_SHIFT 0
#define WR_STREAMERS_TX_CFG1_MAC_LOCAL_LSB_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_TX_CFG1_MAC_LOCAL_LSB_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Tx Config Reg 2 */
/* definitions for field: MAC Local MSB in reg: Tx Config Reg 2 */
#define WR_STREAMERS_TX_CFG2_MAC_LOCAL_MSB_MASK WBGEN2_GEN_MASK(0, 16)
#define WR_STREAMERS_TX_CFG2_MAC_LOCAL_MSB_SHIFT 0
#define WR_STREAMERS_TX_CFG2_MAC_LOCAL_MSB_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define WR_STREAMERS_TX_CFG2_MAC_LOCAL_MSB_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for register: Tx Config Reg 3 */
/* definitions for field: MAC Target LSB in reg: Tx Config Reg 3 */
#define WR_STREAMERS_TX_CFG3_MAC_TARGET_LSB_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_TX_CFG3_MAC_TARGET_LSB_SHIFT 0
#define WR_STREAMERS_TX_CFG3_MAC_TARGET_LSB_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_TX_CFG3_MAC_TARGET_LSB_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Tx Config Reg 4 */
/* definitions for field: MAC Target MSB in reg: Tx Config Reg 4 */
#define WR_STREAMERS_TX_CFG4_MAC_TARGET_MSB_MASK WBGEN2_GEN_MASK(0, 16)
#define WR_STREAMERS_TX_CFG4_MAC_TARGET_MSB_SHIFT 0
#define WR_STREAMERS_TX_CFG4_MAC_TARGET_MSB_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define WR_STREAMERS_TX_CFG4_MAC_TARGET_MSB_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for register: Tx Config Reg 4 */
/* definitions for field: Enable tagging with Qtags in reg: Tx Config Reg 4 */
#define WR_STREAMERS_TX_CFG5_QTAG_ENA WBGEN2_GEN_MASK(0, 1)
/* definitions for field: VLAN ID in reg: Tx Config Reg 4 */
#define WR_STREAMERS_TX_CFG5_QTAG_VID_MASK WBGEN2_GEN_MASK(8, 12)
#define WR_STREAMERS_TX_CFG5_QTAG_VID_SHIFT 8
#define WR_STREAMERS_TX_CFG5_QTAG_VID_W(value) WBGEN2_GEN_WRITE(value, 8, 12)
#define WR_STREAMERS_TX_CFG5_QTAG_VID_R(reg) WBGEN2_GEN_READ(reg, 8, 12)
/* definitions for field: Priority in reg: Tx Config Reg 4 */
#define WR_STREAMERS_TX_CFG5_QTAG_PRIO_MASK WBGEN2_GEN_MASK(24, 3)
#define WR_STREAMERS_TX_CFG5_QTAG_PRIO_SHIFT 24
#define WR_STREAMERS_TX_CFG5_QTAG_PRIO_W(value) WBGEN2_GEN_WRITE(value, 24, 3)
#define WR_STREAMERS_TX_CFG5_QTAG_PRIO_R(reg) WBGEN2_GEN_READ(reg, 24, 3)
/* definitions for register: Rx Config Reg 0 */
/* definitions for field: Ethertype in reg: Rx Config Reg 0 */
#define WR_STREAMERS_RX_CFG0_ETHERTYPE_MASK WBGEN2_GEN_MASK(0, 16)
#define WR_STREAMERS_RX_CFG0_ETHERTYPE_SHIFT 0
#define WR_STREAMERS_RX_CFG0_ETHERTYPE_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define WR_STREAMERS_RX_CFG0_ETHERTYPE_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for field: Accept Broadcast in reg: Rx Config Reg 0 */
#define WR_STREAMERS_RX_CFG0_ACCEPT_BROADCAST WBGEN2_GEN_MASK(16, 1)
/* definitions for field: Filter Remote in reg: Rx Config Reg 0 */
#define WR_STREAMERS_RX_CFG0_FILTER_REMOTE WBGEN2_GEN_MASK(17, 1)
/* definitions for register: Rx Config Reg 1 */
/* definitions for field: MAC Local LSB in reg: Rx Config Reg 1 */
#define WR_STREAMERS_RX_CFG1_MAC_LOCAL_LSB_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_RX_CFG1_MAC_LOCAL_LSB_SHIFT 0
#define WR_STREAMERS_RX_CFG1_MAC_LOCAL_LSB_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_RX_CFG1_MAC_LOCAL_LSB_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Rx Config Reg 2 */
/* definitions for field: MAC Local MSB in reg: Rx Config Reg 2 */
#define WR_STREAMERS_RX_CFG2_MAC_LOCAL_MSB_MASK WBGEN2_GEN_MASK(0, 16)
#define WR_STREAMERS_RX_CFG2_MAC_LOCAL_MSB_SHIFT 0
#define WR_STREAMERS_RX_CFG2_MAC_LOCAL_MSB_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define WR_STREAMERS_RX_CFG2_MAC_LOCAL_MSB_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for register: Rx Config Reg 3 */
/* definitions for field: MAC Remote LSB in reg: Rx Config Reg 3 */
#define WR_STREAMERS_RX_CFG3_MAC_REMOTE_LSB_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_RX_CFG3_MAC_REMOTE_LSB_SHIFT 0
#define WR_STREAMERS_RX_CFG3_MAC_REMOTE_LSB_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_RX_CFG3_MAC_REMOTE_LSB_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Rx Config Reg 4 */
/* definitions for field: MAC Remote MSB in reg: Rx Config Reg 4 */
#define WR_STREAMERS_RX_CFG4_MAC_REMOTE_MSB_MASK WBGEN2_GEN_MASK(0, 16)
#define WR_STREAMERS_RX_CFG4_MAC_REMOTE_MSB_SHIFT 0
#define WR_STREAMERS_RX_CFG4_MAC_REMOTE_MSB_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define WR_STREAMERS_RX_CFG4_MAC_REMOTE_MSB_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for register: Rx Config Reg 5 */
/* definitions for field: Fixed Latency in reg: Rx Config Reg 5 */
#define WR_STREAMERS_RX_CFG5_FIXED_LATENCY_MASK WBGEN2_GEN_MASK(0, 28)
#define WR_STREAMERS_RX_CFG5_FIXED_LATENCY_SHIFT 0
#define WR_STREAMERS_RX_CFG5_FIXED_LATENCY_W(value) WBGEN2_GEN_WRITE(value, 0, 28)
#define WR_STREAMERS_RX_CFG5_FIXED_LATENCY_R(reg) WBGEN2_GEN_READ(reg, 0, 28)
/* definitions for register: TxRx Config Override */
/* definitions for field: Tx Ethertype in reg: TxRx Config Override */
#define WR_STREAMERS_CFG_OR_TX_ETHTYPE WBGEN2_GEN_MASK(0, 1)
/* definitions for field: Tx MAC Local in reg: TxRx Config Override */
#define WR_STREAMERS_CFG_OR_TX_MAC_LOC WBGEN2_GEN_MASK(1, 1)
/* definitions for field: Tx MAC Target in reg: TxRx Config Override */
#define WR_STREAMERS_CFG_OR_TX_MAC_TAR WBGEN2_GEN_MASK(2, 1)
/* definitions for field: QTAG in reg: TxRx Config Override */
#define WR_STREAMERS_CFG_OR_TX_QTAG WBGEN2_GEN_MASK(3, 1)
/* definitions for field: Rx Ethertype in reg: TxRx Config Override */
#define WR_STREAMERS_CFG_OR_RX_ETHERTYPE WBGEN2_GEN_MASK(16, 1)
/* definitions for field: Rx MAC Local in reg: TxRx Config Override */
#define WR_STREAMERS_CFG_OR_RX_MAC_LOC WBGEN2_GEN_MASK(17, 1)
/* definitions for field: Rx MAC Remote in reg: TxRx Config Override */
#define WR_STREAMERS_CFG_OR_RX_MAC_REM WBGEN2_GEN_MASK(18, 1)
/* definitions for field: Rx Accept Broadcast in reg: TxRx Config Override */
#define WR_STREAMERS_CFG_OR_RX_ACC_BROADCAST WBGEN2_GEN_MASK(19, 1)
/* definitions for field: Rx Filter Remote in reg: TxRx Config Override */
#define WR_STREAMERS_CFG_OR_RX_FTR_REMOTE WBGEN2_GEN_MASK(20, 1)
/* definitions for field: Rx Fixed Latency in reg: TxRx Config Override */
#define WR_STREAMERS_CFG_OR_RX_FIX_LAT WBGEN2_GEN_MASK(21, 1)
/* definitions for register: DBG Control register */
/* definitions for field: Debug Tx (0) or Rx (1) in reg: DBG Control register */
#define WR_STREAMERS_DBG_CTRL_MUX WBGEN2_GEN_MASK(0, 1)
/* definitions for field: Debug Start byte in reg: DBG Control register */
#define WR_STREAMERS_DBG_CTRL_START_BYTE_MASK WBGEN2_GEN_MASK(8, 8)
#define WR_STREAMERS_DBG_CTRL_START_BYTE_SHIFT 8
#define WR_STREAMERS_DBG_CTRL_START_BYTE_W(value) WBGEN2_GEN_WRITE(value, 8, 8)
#define WR_STREAMERS_DBG_CTRL_START_BYTE_R(reg) WBGEN2_GEN_READ(reg, 8, 8)
/* definitions for register: DBG Data */
/* definitions for register: Test value */
/* definitions for field: DUMMY value to read in reg: Test value */
#define WR_STREAMERS_DUMMY_DUMMY_MASK WBGEN2_GEN_MASK(0, 32)
#define WR_STREAMERS_DUMMY_DUMMY_SHIFT 0
#define WR_STREAMERS_DUMMY_DUMMY_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WR_STREAMERS_DUMMY_DUMMY_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
PACKED struct WR_STREAMERS_WB {
/* [0x0]: REG Version register */
uint32_t VER;
/* [0x4]: REG Statistics status and ctrl register */
uint32_t SSCR1;
/* [0x8]: REG Statistics status and ctrl register */
uint32_t SSCR2;
/* [0xc]: REG Statistics status and ctrl register */
uint32_t SSCR3;
/* [0x10]: REG Rx statistics */
uint32_t RX_STAT0;
/* [0x14]: REG Rx statistics */
uint32_t RX_STAT1;
/* [0x18]: REG Tx statistics */
uint32_t TX_STAT2;
/* [0x1c]: REG Tx statistics */
uint32_t TX_STAT3;
/* [0x20]: REG Rx statistics */
uint32_t RX_STAT4;
/* [0x24]: REG Rx statistics */
uint32_t RX_STAT5;
/* [0x28]: REG Rx statistics */
uint32_t RX_STAT6;
/* [0x2c]: REG Rx statistics */
uint32_t RX_STAT7;
/* [0x30]: REG Rx statistics */
uint32_t RX_STAT8;
/* [0x34]: REG Rx statistics */
uint32_t RX_STAT9;
/* [0x38]: REG Rx statistics */
uint32_t RX_STAT10;
/* [0x3c]: REG Rx statistics */
uint32_t RX_STAT11;
/* [0x40]: REG Rx statistics */
uint32_t RX_STAT12;
/* [0x44]: REG Rx statistics */
uint32_t RX_STAT13;
/* [0x48]: REG Tx Config Reg 0 */
uint32_t TX_CFG0;
/* [0x4c]: REG Tx Config Reg 1 */
uint32_t TX_CFG1;
/* [0x50]: REG Tx Config Reg 2 */
uint32_t TX_CFG2;
/* [0x54]: REG Tx Config Reg 3 */
uint32_t TX_CFG3;
/* [0x58]: REG Tx Config Reg 4 */
uint32_t TX_CFG4;
/* [0x5c]: REG Tx Config Reg 4 */
uint32_t TX_CFG5;
/* [0x60]: REG Rx Config Reg 0 */
uint32_t RX_CFG0;
/* [0x64]: REG Rx Config Reg 1 */
uint32_t RX_CFG1;
/* [0x68]: REG Rx Config Reg 2 */
uint32_t RX_CFG2;
/* [0x6c]: REG Rx Config Reg 3 */
uint32_t RX_CFG3;
/* [0x70]: REG Rx Config Reg 4 */
uint32_t RX_CFG4;
/* [0x74]: REG Rx Config Reg 5 */
uint32_t RX_CFG5;
/* [0x78]: REG TxRx Config Override */
uint32_t CFG;
/* [0x7c]: REG DBG Control register */
uint32_t DBG_CTRL;
/* [0x80]: REG DBG Data */
uint32_t DBG_DATA;
/* [0x84]: REG Test value */
uint32_t DUMMY;
};
#endif
/*
Register definitions for slave core: WR Core Diagnostics
* File : wrc_diags_regs.h
* Author : auto-generated by wbgen2 from wrc_diags_wb.wb
* Created : Tue Jun 20 09:59:03 2017
* Version : 0x00000001
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wrc_diags_wb.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_WRC_DIAGS_WB_WB
#define __WBGEN2_REGDEFS_WRC_DIAGS_WB_WB
#ifdef __KERNEL__
#include <linux/types.h>
#else
#include <inttypes.h>
#endif
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* version definition */
#define WBGEN2_WRC_DIAGS_VERSION 0x00000001
/* definitions for register: Version register */
/* definitions for field: Version identifier in reg: Version register */
#define WRC_DIAGS_VER_ID_MASK WBGEN2_GEN_MASK(0, 32)
#define WRC_DIAGS_VER_ID_SHIFT 0
#define WRC_DIAGS_VER_ID_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define WRC_DIAGS_VER_ID_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Ctrl */
/* definitions for field: WR DIAG data valid in reg: Ctrl */
#define WRC_DIAGS_CTRL_DATA_VALID WBGEN2_GEN_MASK(0, 1)
/* definitions for field: WR DIAG data snapshot in reg: Ctrl */
#define WRC_DIAGS_CTRL_DATA_SNAPSHOT WBGEN2_GEN_MASK(8, 1)
/* definitions for register: WRPC Diag: servo status */
/* definitions for field: WR valid in reg: WRPC Diag: servo status */
#define WRC_DIAGS_WDIAG_SSTAT_WR_MODE WBGEN2_GEN_MASK(0, 1)
/* definitions for field: Servo State in reg: WRPC Diag: servo status */
#define WRC_DIAGS_WDIAG_SSTAT_SERVOSTATE_MASK WBGEN2_GEN_MASK(8, 4)
#define WRC_DIAGS_WDIAG_SSTAT_SERVOSTATE_SHIFT 8
#define WRC_DIAGS_WDIAG_SSTAT_SERVOSTATE_W(value) WBGEN2_GEN_WRITE(value, 8, 4)
#define WRC_DIAGS_WDIAG_SSTAT_SERVOSTATE_R(reg) WBGEN2_GEN_READ(reg, 8, 4)
/* definitions for register: WRPC Diag: Port status */
/* definitions for field: Link Status in reg: WRPC Diag: Port status */
#define WRC_DIAGS_WDIAG_PSTAT_LINK WBGEN2_GEN_MASK(0, 1)
/* definitions for field: PLL Locked in reg: WRPC Diag: Port status */
#define WRC_DIAGS_WDIAG_PSTAT_LOCKED WBGEN2_GEN_MASK(1, 1)
/* definitions for register: WRPC Diag: PTP state */
/* definitions for field: PTP State in reg: WRPC Diag: PTP state */
#define WRC_DIAGS_WDIAG_PTPSTAT_PTPSTATE_MASK WBGEN2_GEN_MASK(0, 8)
#define WRC_DIAGS_WDIAG_PTPSTAT_PTPSTATE_SHIFT 0
#define WRC_DIAGS_WDIAG_PTPSTAT_PTPSTATE_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define WRC_DIAGS_WDIAG_PTPSTAT_PTPSTATE_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: WRPC Diag: AUX state */
/* definitions for field: AUX channel in reg: WRPC Diag: AUX state */
#define WRC_DIAGS_WDIAG_ASTAT_AUX_MASK WBGEN2_GEN_MASK(0, 8)
#define WRC_DIAGS_WDIAG_ASTAT_AUX_SHIFT 0
#define WRC_DIAGS_WDIAG_ASTAT_AUX_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define WRC_DIAGS_WDIAG_ASTAT_AUX_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: WRPC Diag: Tx PTP Frame cnts */
/* definitions for register: WRPC Diag: Rx PTP Frame cnts */
/* definitions for register: WRPC Diag:local time [msb of s] */
/* definitions for register: WRPC Diag: local time [lsb of s] */
/* definitions for register: WRPC Diag: local time [ns] */
/* definitions for register: WRPC Diag: Round trip (mu) [msb of ps] */
/* definitions for register: WRPC Diag: Round trip (mu) [lsb of ps] */
/* definitions for register: WRPC Diag: Master-slave delay (dms) [msb of ps] */
/* definitions for register: WRPC Diag: Master-slave delay (dms) [lsb of ps] */
/* definitions for register: WRPC Diag: Total link asymmetry [ps] */
/* definitions for register: WRPC Diag: Clock offset (cko) [ps] */
/* definitions for register: WRPC Diag: Phase setpoint (setp) [ps] */
/* definitions for register: WRPC Diag: Update counter (ucnt) */
/* definitions for register: WRPC Diag: Board temperature [C degree] */
PACKED struct WRC_DIAGS_WB {
/* [0x0]: REG Version register */
uint32_t VER;
/* [0x4]: REG Ctrl */
uint32_t CTRL;
/* [0x8]: REG WRPC Diag: servo status */
uint32_t WDIAG_SSTAT;
/* [0xc]: REG WRPC Diag: Port status */
uint32_t WDIAG_PSTAT;
/* [0x10]: REG WRPC Diag: PTP state */
uint32_t WDIAG_PTPSTAT;
/* [0x14]: REG WRPC Diag: AUX state */
uint32_t WDIAG_ASTAT;
/* [0x18]: REG WRPC Diag: Tx PTP Frame cnts */
uint32_t WDIAG_TXFCNT;
/* [0x1c]: REG WRPC Diag: Rx PTP Frame cnts */
uint32_t WDIAG_RXFCNT;
/* [0x20]: REG WRPC Diag:local time [msb of s] */
uint32_t WDIAG_SEC_MSB;
/* [0x24]: REG WRPC Diag: local time [lsb of s] */
uint32_t WDIAG_SEC_LSB;
/* [0x28]: REG WRPC Diag: local time [ns] */
uint32_t WDIAG_NS;
/* [0x2c]: REG WRPC Diag: Round trip (mu) [msb of ps] */
uint32_t WDIAG_MU_MSB;
/* [0x30]: REG WRPC Diag: Round trip (mu) [lsb of ps] */
uint32_t WDIAG_MU_LSB;
/* [0x34]: REG WRPC Diag: Master-slave delay (dms) [msb of ps] */
uint32_t WDIAG_DMS_MSB;
/* [0x38]: REG WRPC Diag: Master-slave delay (dms) [lsb of ps] */
uint32_t WDIAG_DMS_LSB;
/* [0x3c]: REG WRPC Diag: Total link asymmetry [ps] */
uint32_t WDIAG_ASYM;
/* [0x40]: REG WRPC Diag: Clock offset (cko) [ps] */
uint32_t WDIAG_CKO;
/* [0x44]: REG WRPC Diag: Phase setpoint (setp) [ps] */
uint32_t WDIAG_SETP;
/* [0x48]: REG WRPC Diag: Update counter (ucnt) */
uint32_t WDIAG_UCNT;
/* [0x4c]: REG WRPC Diag: Board temperature [C degree] */
uint32_t WDIAG_TEMP;
};
#endif
......@@ -3,7 +3,7 @@
* File : wrc_syscon_regs.h
* Author : auto-generated by wbgen2 from wrc_syscon_wb.wb
* Created : Mon Jul 11 14:59:51 2016
* Created : Mon Nov 27 13:37:56 2017
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wrc_syscon_wb.wb
......@@ -14,7 +14,11 @@
#ifndef __WBGEN2_REGDEFS_WRC_SYSCON_WB_WB
#define __WBGEN2_REGDEFS_WRC_SYSCON_WB_WB
#ifdef __KERNEL__
#include <linux/types.h>
#else
#include <inttypes.h>
#endif
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
......@@ -123,6 +127,34 @@
#define SYSC_HWFR_MEMSIZE_W(value) WBGEN2_GEN_WRITE(value, 0, 4)
#define SYSC_HWFR_MEMSIZE_R(reg) WBGEN2_GEN_READ(reg, 0, 4)
/* definitions for field: Storage type in reg: Hardware Feature Register */
#define SYSC_HWFR_STORAGE_TYPE_MASK WBGEN2_GEN_MASK(8, 2)
#define SYSC_HWFR_STORAGE_TYPE_SHIFT 8
#define SYSC_HWFR_STORAGE_TYPE_W(value) WBGEN2_GEN_WRITE(value, 8, 2)
#define SYSC_HWFR_STORAGE_TYPE_R(reg) WBGEN2_GEN_READ(reg, 8, 2)
/* definitions for field: Storage sector size in reg: Hardware Feature Register */
#define SYSC_HWFR_STORAGE_SEC_MASK WBGEN2_GEN_MASK(16, 16)
#define SYSC_HWFR_STORAGE_SEC_SHIFT 16
#define SYSC_HWFR_STORAGE_SEC_W(value) WBGEN2_GEN_WRITE(value, 16, 16)
#define SYSC_HWFR_STORAGE_SEC_R(reg) WBGEN2_GEN_READ(reg, 16, 16)
/* definitions for register: Hardware Info Register */
/* definitions for field: Board name in reg: Hardware Info Register */
#define SYSC_HWIR_NAME_MASK WBGEN2_GEN_MASK(0, 32)
#define SYSC_HWIR_NAME_SHIFT 0
#define SYSC_HWIR_NAME_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define SYSC_HWIR_NAME_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Storage SDBFS info */
/* definitions for field: Base address in reg: Storage SDBFS info */
#define SYSC_SDBFS_BADDR_MASK WBGEN2_GEN_MASK(0, 32)
#define SYSC_SDBFS_BADDR_SHIFT 0
#define SYSC_SDBFS_BADDR_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define SYSC_SDBFS_BADDR_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: Timer Control Register */
/* definitions for field: Timer Divider in reg: Timer Control Register */
......@@ -176,6 +208,77 @@
#define SYSC_DIAG_CR_RW WBGEN2_GEN_MASK(31, 1)
/* definitions for register: User Diag: data to read/write */
/* definitions for register: WRPC Diag: ctrl */
/* definitions for field: WR DIAG data valid in reg: WRPC Diag: ctrl */
#define SYSC_WDIAG_CTRL_DATA_VALID WBGEN2_GEN_MASK(0, 1)
/* definitions for field: WR DIAG data snapshot in reg: WRPC Diag: ctrl */
#define SYSC_WDIAG_CTRL_DATA_SNAPSHOT WBGEN2_GEN_MASK(8, 1)
/* definitions for register: WRPC Diag: servo status */
/* definitions for field: WR valid in reg: WRPC Diag: servo status */
#define SYSC_WDIAG_SSTAT_WR_MODE WBGEN2_GEN_MASK(0, 1)
/* definitions for field: Servo State in reg: WRPC Diag: servo status */
#define SYSC_WDIAG_SSTAT_SERVOSTATE_MASK WBGEN2_GEN_MASK(8, 4)
#define SYSC_WDIAG_SSTAT_SERVOSTATE_SHIFT 8
#define SYSC_WDIAG_SSTAT_SERVOSTATE_W(value) WBGEN2_GEN_WRITE(value, 8, 4)
#define SYSC_WDIAG_SSTAT_SERVOSTATE_R(reg) WBGEN2_GEN_READ(reg, 8, 4)
/* definitions for register: WRPC Diag: Port status */
/* definitions for field: Link Status in reg: WRPC Diag: Port status */
#define SYSC_WDIAG_PSTAT_LINK WBGEN2_GEN_MASK(0, 1)
/* definitions for field: PLL Locked in reg: WRPC Diag: Port status */
#define SYSC_WDIAG_PSTAT_LOCKED WBGEN2_GEN_MASK(1, 1)
/* definitions for register: WRPC Diag: PTP state */
/* definitions for field: PTP State in reg: WRPC Diag: PTP state */
#define SYSC_WDIAG_PTPSTAT_PTPSTATE_MASK WBGEN2_GEN_MASK(0, 8)
#define SYSC_WDIAG_PTPSTAT_PTPSTATE_SHIFT 0
#define SYSC_WDIAG_PTPSTAT_PTPSTATE_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define SYSC_WDIAG_PTPSTAT_PTPSTATE_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: WRPC Diag: AUX state */
/* definitions for field: AUX channel in reg: WRPC Diag: AUX state */
#define SYSC_WDIAG_ASTAT_AUX_MASK WBGEN2_GEN_MASK(0, 8)
#define SYSC_WDIAG_ASTAT_AUX_SHIFT 0
#define SYSC_WDIAG_ASTAT_AUX_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define SYSC_WDIAG_ASTAT_AUX_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: WRPC Diag: Tx PTP Frame cnts */
/* definitions for register: WRPC Diag: Rx PTP Frame cnts */
/* definitions for register: WRPC Diag:local time [msb of s] */
/* definitions for register: WRPC Diag: local time [lsb of s] */
/* definitions for register: WRPC Diag: local time [ns] */
/* definitions for register: WRPC Diag: Round trip (mu) [msb of ps] */
/* definitions for register: WRPC Diag: Round trip (mu) [lsb of ps] */
/* definitions for register: WRPC Diag: Master-slave delay (dms) [msb of ps] */
/* definitions for register: WRPC Diag: Master-slave delay (dms) [lsb of ps] */
/* definitions for register: WRPC Diag: Total link asymmetry [ps] */
/* definitions for register: WRPC Diag: Clock offset (cko) [ps] */
/* definitions for register: WRPC Diag: Phase setpoint (setp) [ps] */
/* definitions for register: WRPC Diag: Update counter (ucnt) */
/* definitions for register: WRPC Diag: Board temperature [C degree] */
/* [0x0]: REG Syscon reset register */
#define SYSC_REG_RSTR 0x00000000
/* [0x4]: REG GPIO Set/Readback Register */
......@@ -184,16 +287,58 @@
#define SYSC_REG_GPCR 0x00000008
/* [0xc]: REG Hardware Feature Register */
#define SYSC_REG_HWFR 0x0000000c
/* [0x10]: REG Timer Control Register */
#define SYSC_REG_TCR 0x00000010
/* [0x14]: REG Timer Counter Value Register */
#define SYSC_REG_TVR 0x00000014
/* [0x18]: REG User Diag: version register */
#define SYSC_REG_DIAG_INFO 0x00000018
/* [0x1c]: REG User Diag: number of words */
#define SYSC_REG_DIAG_NW 0x0000001c
/* [0x20]: REG User Diag: Control Register */
#define SYSC_REG_DIAG_CR 0x00000020
/* [0x24]: REG User Diag: data to read/write */
#define SYSC_REG_DIAG_DAT 0x00000024
/* [0x10]: REG Hardware Info Register */
#define SYSC_REG_HWIR 0x00000010
/* [0x14]: REG Storage SDBFS info */
#define SYSC_REG_SDBFS 0x00000014
/* [0x18]: REG Timer Control Register */
#define SYSC_REG_TCR 0x00000018
/* [0x1c]: REG Timer Counter Value Register */
#define SYSC_REG_TVR 0x0000001c
/* [0x20]: REG User Diag: version register */
#define SYSC_REG_DIAG_INFO 0x00000020
/* [0x24]: REG User Diag: number of words */
#define SYSC_REG_DIAG_NW 0x00000024
/* [0x28]: REG User Diag: Control Register */
#define SYSC_REG_DIAG_CR 0x00000028
/* [0x2c]: REG User Diag: data to read/write */
#define SYSC_REG_DIAG_DAT 0x0000002c
/* [0x30]: REG WRPC Diag: ctrl */
#define SYSC_REG_WDIAG_CTRL 0x00000030
/* [0x34]: REG WRPC Diag: servo status */
#define SYSC_REG_WDIAG_SSTAT 0x00000034
/* [0x38]: REG WRPC Diag: Port status */
#define SYSC_REG_WDIAG_PSTAT 0x00000038
/* [0x3c]: REG WRPC Diag: PTP state */
#define SYSC_REG_WDIAG_PTPSTAT 0x0000003c
/* [0x40]: REG WRPC Diag: AUX state */
#define SYSC_REG_WDIAG_ASTAT 0x00000040
/* [0x44]: REG WRPC Diag: Tx PTP Frame cnts */
#define SYSC_REG_WDIAG_TXFCNT 0x00000044
/* [0x48]: REG WRPC Diag: Rx PTP Frame cnts */
#define SYSC_REG_WDIAG_RXFCNT 0x00000048
/* [0x4c]: REG WRPC Diag:local time [msb of s] */
#define SYSC_REG_WDIAG_SEC_MSB 0x0000004c
/* [0x50]: REG WRPC Diag: local time [lsb of s] */
#define SYSC_REG_WDIAG_SEC_LSB 0x00000050
/* [0x54]: REG WRPC Diag: local time [ns] */
#define SYSC_REG_WDIAG_NS 0x00000054
/* [0x58]: REG WRPC Diag: Round trip (mu) [msb of ps] */
#define SYSC_REG_WDIAG_MU_MSB 0x00000058
/* [0x5c]: REG WRPC Diag: Round trip (mu) [lsb of ps] */
#define SYSC_REG_WDIAG_MU_LSB 0x0000005c
/* [0x60]: REG WRPC Diag: Master-slave delay (dms) [msb of ps] */
#define SYSC_REG_WDIAG_DMS_MSB 0x00000060
/* [0x64]: REG WRPC Diag: Master-slave delay (dms) [lsb of ps] */
#define SYSC_REG_WDIAG_DMS_LSB 0x00000064
/* [0x68]: REG WRPC Diag: Total link asymmetry [ps] */
#define SYSC_REG_WDIAG_ASYM 0x00000068
/* [0x6c]: REG WRPC Diag: Clock offset (cko) [ps] */
#define SYSC_REG_WDIAG_CKO 0x0000006c
/* [0x70]: REG WRPC Diag: Phase setpoint (setp) [ps] */
#define SYSC_REG_WDIAG_SETP 0x00000070
/* [0x74]: REG WRPC Diag: Update counter (ucnt) */
#define SYSC_REG_WDIAG_UCNT 0x00000074
/* [0x78]: REG WRPC Diag: Board temperature [C degree] */
#define SYSC_REG_WDIAG_TEMP 0x00000078
#endif
......@@ -14,7 +14,7 @@ void mi2c_stop(uint8_t i2cif);
void mi2c_get_byte(uint8_t i2cif, unsigned char *data, uint8_t last);
unsigned char mi2c_put_byte(uint8_t i2cif, unsigned char data);
void mi2c_delay(void);
void mi2c_delay(uint32_t delay);
//void mi2c_scan(uint8_t i2cif);
#endif
......@@ -11,7 +11,7 @@
/* Please increment WRPC_SHMEM_VERSION if you change any exported data
* structure */
#define WRPC_SHMEM_VERSION 1 /* first version */
#define WRPC_SHMEM_VERSION 2 /* removed some unused fields */
#ifndef __ASSEMBLY__
extern const char *build_revision;
......
......@@ -23,12 +23,6 @@ extern int32_t sfp_alpha;
extern int32_t sfp_deltaTx;
extern int32_t sfp_deltaRx;
/* Returns 1 if there's a SFP transceiver inserted in the socket. */
int sfp_present(void);
/* Reads the part ID of the SFP from its configuration EEPROM */
int sfp_read_part_id(char *part_id);
/* Match plugged SFP with a DB entry */
int sfp_match(void);
......
......@@ -13,6 +13,7 @@ extern int wrc_ui_mode;
extern int wrc_stat_running;
const char *fromhex(const char *hex, int *v);
const char *fromhex64(const char *hex, int64_t *v);
const char *fromdec(const char *dec, int *v);
void decode_mac(const char *str, unsigned char *mac);
char *format_mac(char *s, const unsigned char *mac);
......@@ -36,7 +37,9 @@ void env_init(void);
int shell_exec(const char *buf);
int shell_interactive(void);
extern int shell_is_interacting;
void shell_boot_script(void);
void shell_show_build_init(void);
#endif
......@@ -46,6 +46,12 @@
#define EE_RET_CORRPT -3
#define EE_RET_POSERR -4
#ifdef CONFIG_GENSDBFS
#define HAS_GENSDBFS 1
#else
#define HAS_GENSDBFS 0
#endif
extern uint32_t cal_phase_transition;
extern uint8_t has_eeprom;
......@@ -61,15 +67,34 @@ void storage_init(int i2cif, int i2c_addr);
int storage_sfpdb_erase(void);
int storage_match_sfp(struct s_sfpinfo *sfp);
int storage_get_sfp(struct s_sfpinfo * sfp,
uint8_t add, uint8_t pos);
int storage_get_sfp(struct s_sfpinfo *sfp, uint8_t add, uint8_t pos);
int storage_phtrans(uint32_t * val,
uint8_t write);
int storage_phtrans(uint32_t *val, uint8_t write);
int storage_init_erase(void);
int storage_init_add(const char *args[]);
int storage_init_show(void);
int storage_init_readcmd(uint8_t *buf, uint8_t bufsize, uint8_t next);
struct storage_config {
int memtype;
int valid;
uint32_t blocksize;
uint32_t baseadr;
};
extern struct storage_config storage_cfg;
#define MEM_FLASH 0
#define MEM_EEPROM 1
#define MEM_1W_EEPROM 2
#define SDBFS_REC 5
int storage_read_hdl_cfg(void);
int storage_sdbfs_erase(int mem_type, uint32_t base_adr, uint32_t blocksize,
uint8_t i2c_adr);
int storage_gensdbfs(int mem_type, uint32_t base_adr, uint32_t blocksize,
uint8_t i2c_adr);
#endif
......@@ -49,12 +49,33 @@ struct SYSCON_WB {
uint32_t GPSR; /*GPIO Set/Readback Register */
uint32_t GPCR; /*GPIO Clear Register */
uint32_t HWFR; /*Hardware Feature Register */
uint32_t HWIR; /*Hardware Info Register */
uint32_t SDBFS; /*Flash SDBFS Info Register */
uint32_t TCR; /*Timer Control Register */
uint32_t TVR; /*Timer Counter Value Register */
uint32_t DIAG_INFO;
uint32_t DIAG_NW;
uint32_t DIAG_CR;
uint32_t DIAG_DAT;
uint32_t WDIAG_CTRL;
uint32_t WDIAG_SSTAT;
uint32_t WDIAG_PSTAT;
uint32_t WDIAG_PTPSTAT;
uint32_t WDIAG_ASTAT;
uint32_t WDIAG_TXFCNT;
uint32_t WDIAG_RXFCNT;
uint32_t WDIAG_SEC_MSB;
uint32_t WDIAG_SEC_LSB;
uint32_t WDIAG_NS;
uint32_t WDIAG_MU_MSB;
uint32_t WDIAG_MU_LSB;
uint32_t WDIAG_DMS_MSB;
uint32_t WDIAG_DMS_LSB;
uint32_t WDIAG_ASYM;
uint32_t WDIAG_CKO;
uint32_t WDIAG_SETP;
uint32_t WDIAG_UCNT;
uint32_t WDIAG_TEMP;
};
/*GPIO pins*/
......@@ -70,10 +91,13 @@ struct SYSCON_WB {
#define WRPC_FMC_I2C 0
#define WRPC_SFP_I2C 1
#define FMC_I2C_DELAY 15
#define SFP_I2C_DELAY 300
struct s_i2c_if {
uint32_t scl;
uint32_t sda;
uint32_t loop_delay;
};
extern struct s_i2c_if i2c_if[2];
......@@ -105,6 +129,10 @@ static inline int sysc_get_memsize(void)
return (SYSC_HWFR_MEMSIZE_R(syscon->HWFR) + 1) * 16;
}
#define HW_NAME_LENGTH 5 /* 4 letters + '\0' */
void get_hw_name(char *str);
void get_storage_info(int *memtype, uint32_t *sdbfs_baddr, uint32_t *blocksize);
#define DIAG_RW_BANK 0
#define DIAG_RO_BANK 1
void diag_read_info(uint32_t *id, uint32_t *ver, uint32_t *nrw, uint32_t *nro);
......@@ -113,5 +141,18 @@ int diag_write_word(uint32_t adr, uint32_t val);
void net_rst(void);
int wdiag_set_valid(int enable);
int wdiag_get_valid(void);
int wdiag_get_snapshot(void);
void wdiags_write_servo_state(int wr_mode, uint8_t servostate, uint64_t mu,
uint64_t dms, int32_t asym, int32_t cko,
int32_t setp, int32_t ucnt);
void wdiags_write_port_state(int link, int locked);
void wdiags_write_ptp_state(uint8_t ptpstate);
void wdiags_write_aux_state(uint32_t aux_states);
void wdiags_write_cnts(uint32_t tx, uint32_t rx);
void wdiags_write_time(uint64_t sec, uint32_t nsec);
void wdiags_write_temp(uint32_t temp);
#endif /* CONFIG_WR_NODE */
#endif
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2013 CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#ifndef __UART_SW_H
#define __UART_SW_H
/* The host code (tools/wrpc-uart-sw) must include this too, for the struct */
#ifdef __lm32__
#include "uart.h" /* we need to offer the same prototypes */
#endif
/* These are currently static but can become Kconfig items */
#define CONFIG_UART_SW_WSIZE 256
#define CONFIG_UART_SW_RSIZE 32
#define UART_SW_MAGIC 0x752d7377 /* "u-sw" */
struct wrc_uart_sw {
uint32_t magic;
uint16_t wsize, nwritten;
uint16_t rsize, nread;
unsigned char wbuffer[CONFIG_UART_SW_WSIZE];
unsigned char rbuffer[CONFIG_UART_SW_RSIZE];
};
#endif /* __UART_SW_H */
......@@ -6,15 +6,10 @@
#ifndef __UART_H
#define __UART_H
void uart_init_sw(void);
void uart_init_hw(void);
void uart_write_byte(int b);
int uart_write_string(const char *s);
int puts(const char *s);
int uart_read_byte(void);
/* uart-sw is used by ppsi (but may be wrapped to normal uart) */
int uart_sw_write_string(const char *s);
#endif
......@@ -21,6 +21,7 @@ struct wrc_task {
unsigned long nrun;
unsigned long seconds;
unsigned long nanos;
unsigned long max_run_ticks; /* in ticks */
};
/* An helper for periodic tasks, relying on a static varible */
......
......@@ -5,6 +5,7 @@
#define WRC_MODE_GM 1
#define WRC_MODE_MASTER 2
#define WRC_MODE_SLAVE 3
#define WRC_MODE_ABSCAL 4
extern int ptp_mode;
int wrc_ptp_init(void);
......
WR-WRPC-AUX-STREAMERS-MIB DEFINITIONS ::= BEGIN
-- Based on the WR-WRPC-MIB
-- Adam Wujek & Maciej Lipinski, BE-CO-HT, CERN
-- IMPORTS: Include definitions from other mibs here
IMPORTS
OBJECT-TYPE, Unsigned32, MODULE-IDENTITY FROM SNMPv2-SMI
wrWrpcMIB FROM WR-WRPC-MIB;
wrpcAuxDiag MODULE-IDENTITY
LAST-UPDATED "201706081000Z"
ORGANIZATION "CERN"
CONTACT-INFO "postal: BE-CO-HT, CERN, Geneva
email: ht-drivers@cern.ch
"
DESCRIPTION "White Rabbit WRPC aux registers for WR Streamers
"
REVISION "201706081000Z"
DESCRIPTION
"Second revision."
::= { wrWrpcMIB 2 }
wrpcAuxDiagId1 OBJECT IDENTIFIER ::= { wrpcAuxDiag 1 }
wrpcAuxDiagVersion102 OBJECT IDENTIFIER ::= { wrpcAuxDiagId1 2 }
-- ****************************************************************************
wrpcAuxDiag102RoTable OBJECT-TYPE
SYNTAX SEQUENCE OF WrpcAuxDiag102RoEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"Table with read only registers"
::= { wrpcAuxDiagVersion102 1 }
wrpcAuxDiag102RoEntry OBJECT-TYPE
SYNTAX WrpcAuxDiag102RoEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"An entry for read only registers"
INDEX { wrpcAuxDiag102RoIndex }
::= { wrpcAuxDiag102RoTable 1 }
WrpcAuxDiag102RoEntry ::=
SEQUENCE {
wrpcAuxDiag102RoIndex Unsigned32,
wrpcAuxDiag102RoRegCount Unsigned32,
wrpcAuxDiag102RoStatus Unsigned32,
wrpcAuxDiag102RoResetTimeCycles Unsigned32,
wrpcAuxDiag102RoResetTimeTaiLsb Unsigned32,
wrpcAuxDiag102RoResetTimeTaiMsb Unsigned32,
wrpcAuxDiag102RoLatencyMax Unsigned32,
wrpcAuxDiag102RoLatencyMin Unsigned32,
wrpcAuxDiag102RoSentFrameCntLsb Unsigned32,
wrpcAuxDiag102RoSentFrameCntMsb Unsigned32,
wrpcAuxDiag102RoRcvdFrameCntLsb Unsigned32,
wrpcAuxDiag102RoRcvdFrameCntMsb Unsigned32,
wrpcAuxDiag102RoLostFrameCntLsb Unsigned32,
wrpcAuxDiag102RoLostFrameCntMsb Unsigned32,
wrpcAuxDiag102RoLostBlockCntLsb Unsigned32,
wrpcAuxDiag102RoLostBlockCntMsb Unsigned32,
wrpcAuxDiag102RoLatencyCntLsb Unsigned32,
wrpcAuxDiag102RoLatencyCntMsb Unsigned32,
wrpcAuxDiag102RoLatencyAccLsb Unsigned32,
wrpcAuxDiag102RoLatencyAccMsb Unsigned32,
wrpcAuxDiag102RoDbgWord Unsigned32,
wrpcAuxDiag102RoMagicNumber Unsigned32
}
wrpcAuxDiag102RoIndex OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"Index for wrpcAuxDiag102RoTable"
::= { wrpcAuxDiag102RoEntry 1 }
wrpcAuxDiag102RoRegCount OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of registers available in the wrpcAuxDiag102RoTable"
::= { wrpcAuxDiag102RoEntry 2 }
wrpcAuxDiag102RoStatus OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"bit 0: HIGH indicates that statistics are being reseted
bit 1: HIGH indicates that latency accumulator has overflown since
last reset. Snapshot-able by setting bit 1 in
wrpcAuxDiag102RwControlRegister."
::= { wrpcAuxDiag102RoEntry 3 }
wrpcAuxDiag102RoResetTimeCycles OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Cycle part of reset timestamp: number of cycles of the 125MHz
clock in the since the TAI second started;
Timestamp is taken at the rising and falling edge of the input
reset value. This allows to:
1. read the timestamp of the start of statistics acquisition
(generated before)
2. set HIGH reset (this can be combine with snapshotting
the statistics at the same time)
3. read the timestamp of the end of statistics acquisition and
the stats values for as long as it takes
4. set LOW reset, this restart acquisition (a new timestamp will
indicate the start of the acquisition (you can restart before
point 3)"
::= { wrpcAuxDiag102RoEntry 4 }
wrpcAuxDiag102RoResetTimeTaiLsb OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"LSB part of reset timestamp: number: TAI time - indicates
number of seconds since epoch
Timestamp is taken at the rising and falling edge of the input
reset value. This allows to:
1. read the timestamp of the start of statistics acquisition
(generated before)
2. set HIGH reset (this can be combine with snapshotting
the statistics at the same time)
3. read the timestamp of the end of statistics acquisition and
the stats values for as long as it takes
4. set LOW reset, this restart acquisition (a new timestamp will
indicate the start of the acquisition (you can restart before
point 3)"
::= { wrpcAuxDiag102RoEntry 5 }
wrpcAuxDiag102RoResetTimeTaiMsb OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"MSB part of reset timestamp
Timestamp is taken at the rising and falling edge of the input
reset value. This allows to:
1. read the timestamp of the start of statistics acquisition
(generated before)
2. set HIGH reset (this can be combine with snapshotting
the statistics at the same time)
3. read the timestamp of the end of statistics acquisition and
the stats values for as long as it takes
4. set LOW reset, this restart acquisition (a new timestamp will
indicate the start of the acquisition (you can restart before
point 3)"
::= { wrpcAuxDiag102RoEntry 6 }
wrpcAuxDiag102RoLatencyMax OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Maximum latency since reset. Snapshot-able by setting bit 1 in
wrpcAuxDiag102RwControlRegister."
::= { wrpcAuxDiag102RoEntry 7 }
wrpcAuxDiag102RoLatencyMin OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Minimum latency since reset. Snapshot-able by setting bit 1 in
wrpcAuxDiag102RwControlRegister."
::= { wrpcAuxDiag102RoEntry 8 }
wrpcAuxDiag102RoSentFrameCntLsb OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"LSB of the number of sent streamer frames since reset. Snapshot-able by
setting bit 1 in wrpcAuxDiag102RwControlRegister."
::= { wrpcAuxDiag102RoEntry 9 }
wrpcAuxDiag102RoSentFrameCntMsb OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"MSB of the number of sent streamer frames since reset. Snapshot-able by
setting bit 1 in wrpcAuxDiag102RwControlRegister."
::= { wrpcAuxDiag102RoEntry 10 }
wrpcAuxDiag102RoRcvdFrameCntLsb OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"LSB of the number of received streamers frames since reset. Snapshot-able by
setting bit 1 in wrpcAuxDiag102RwControlRegister."
::= { wrpcAuxDiag102RoEntry 11 }
wrpcAuxDiag102RoRcvdFrameCntMsb OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"MSB of the number of received streamers frames since reset. Snapshot-able by
setting bit 1 in wrpcAuxDiag102RwControlRegister."
::= { wrpcAuxDiag102RoEntry 12 }
wrpcAuxDiag102RoLostFrameCntLsb OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"LSB of the number of lost streamer frames since reset. Snapshot-able by
setting bit 1 in wrpcAuxDiag102RwControlRegister."
::= { wrpcAuxDiag102RoEntry 13 }
wrpcAuxDiag102RoLostFrameCntMsb OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"MSB of the number of lost streamer frames since reset. Snapshot-able by
setting bit 1 in wrpcAuxDiag102RwControlRegister."
::= { wrpcAuxDiag102RoEntry 14 }
wrpcAuxDiag102RoLostBlockCntLsb OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"LSB of the number or lost streamer blocks since reset. Snapshot-able by
setting bit 1 in wrpcAuxDiag102RwControlRegister.
Each streamer frame can have a number of blocks, each has its own
CRC, this blocks are counted separately (in the improbable case
that there is one block in the frame that is corrupted but
the frame's CRC is OK."
::= { wrpcAuxDiag102RoEntry 15 }
wrpcAuxDiag102RoLostBlockCntMsb OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"MSB of the number or lost streamer blocks since reset. Snapshot-able by
setting bit 1 in wrpcAuxDiag102RwControlRegister.
Each streamer frame can have a number of blocks, each has its own
CRC, this blocks are counted separately (in the improbable case
that there is one block in the frame that is corrupted but
the frame's CRC is OK."
::= { wrpcAuxDiag102RoEntry 16 }
wrpcAuxDiag102RoLatencyCntLsb OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"LSB of the number of latency values accumulated in the accumulator since
reset (avg_latency = latency_acc/latency_cnt). Snapshot-able by
setting bit 1 in wrpcAuxDiag102RwControlRegister."
::= { wrpcAuxDiag102RoEntry 17 }
wrpcAuxDiag102RoLatencyCntMsb OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"LSB of the number of latency values accumulated in the accumulator since
reset (avg_latency = latency_acc/latency_cnt). Snapshot-able by
setting bit 1 in wrpcAuxDiag102RwControlRegister."
::= { wrpcAuxDiag102RoEntry 18 }
wrpcAuxDiag102RoLatencyAccLsb OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"LSB of accumulated latency value. Snapshot-able by setting bit 1
in wrpcAuxDiag102RwControlRegister."
::= { wrpcAuxDiag102RoEntry 19 }
wrpcAuxDiag102RoLatencyAccMsb OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"MSB of accumulated latency value. Snapshot-able by setting bit 1
in wrpcAuxDiag102RwControlRegister."
::= { wrpcAuxDiag102RoEntry 20 }
wrpcAuxDiag102RoInputWord OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"DBG: one can read the input word to verify the operation
(i.e. the read-write register at address 0). Snapshot-able by
setting bit 1 in wrpcAuxDiag102RwControlRegister."
::= { wrpcAuxDiag102RoEntry 21 }
wrpcAuxDiag102RoMagicNumber OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"DBG: Magic number to for sanity checks, should read in hex
0xDEADBEEF and in decimal 3735928559."
::= { wrpcAuxDiag102RoEntry 22 }
-- ****************************************************************************
wrpcAuxDiag102RwTable OBJECT-TYPE
SYNTAX SEQUENCE OF WrpcAuxDiag102RwEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"Table with read-write registers"
::= { wrpcAuxDiagVersion102 2 }
wrpcAuxDiag102RwEntry OBJECT-TYPE
SYNTAX WrpcAuxDiag102RwEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"An entry for read-write registers"
INDEX { wrpcAuxDiag102RwIndex }
::= { wrpcAuxDiag102RwTable 1 }
WrpcAuxDiag102RwEntry ::=
SEQUENCE {
wrpcAuxDiag102RwIndex Unsigned32,
wrpcAuxDiag102RwRegCount Unsigned32,
wrpcAuxDiag102RwControlRegister Unsigned32
}
wrpcAuxDiag102RwIndex OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"Index for wrpcAuxDiag102RwTable"
::= { wrpcAuxDiag102RwEntry 1 }
wrpcAuxDiag102RwRegCount OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of registers available in the wrpcAuxDiag102RwTable"
::= { wrpcAuxDiag102RwEntry 2 }
wrpcAuxDiag102RwControlRegister OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"bit 0: setting to HIGH resets the counters
bit 1: setting to HIGH snapshots the statistics value
Timestamp is taken at the rising and falling edge of the input
reset value. This allows to:
1. read the timestamp of the start of statistics acquisition
(generated before)
2. set HIGH reset (this can be combine with snapshotting
the statistics at the same time)
3. read the timestamp of the end of statistics acquisition and
the stats values for as long as it takes
4. set LOW reset, this restart acquisition (a new timestamp will
indicate the start of the acquisition (you can restart before
point 3)
Snapshot allows to read coherent data, i.e. the values of the
counters are stored in separate registers at the same instant.
Even if reading is slow, they will not change, so one can read
coherent value of accumulator and the count of accumulated values,
and therefore calculate precise average. Note, the statistics are
still taken in the background. The snapshotted values are kept
coherent as long as snapshot value is HIGH"
::= { wrpcAuxDiag102RwEntry 3 }
-- ****************************************************************************
END
......@@ -262,7 +262,9 @@ wrpcSpllAlignState OBJECT-TYPE
compensateDelay(5),
locked(6),
startAlignment(7),
startMain(8)
startMain(8),
waitClkin(9),
waitPlock(10)
}
MAX-ACCESS read-only
STATUS current
......
......@@ -6,16 +6,14 @@
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <wrc.h>
#include <wrpc.h>
#include <string.h>
#include "endpoint.h"
#include "ipv4.h"
#include "ptpd_netif.h"
#ifndef htons
#define htons(x) x
#endif
static uint8_t __arp_queue[128];
static struct wrpc_socket __static_arp_socket = {
.queue.buff = __arp_queue,
......
......@@ -6,8 +6,9 @@
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <string.h>
#include <wrc.h>
#include <wrpc.h>
#include <string.h>
#include "endpoint.h"
#include "ipv4.h"
......@@ -17,10 +18,6 @@
#include "hw/etherbone-config.h"
#include "ext_config.h"
#ifndef htons
#define htons(x) x
#endif
enum ip_status ip_status = IP_TRAINING;
static uint8_t myIP[4];
......@@ -111,7 +108,7 @@ static int bootp_poll(void)
ret = process_bootp(buf, len);
if (task_not_yet(&bootp_tics, TICS_PER_SECOND))
return 0;
return ret;
len = prepare_bootp(&addr, buf, ++bootp_retry);
ptpd_netif_sendto(bootp_socket, &addr, buf, len, 0);
......
......@@ -65,6 +65,6 @@ int check_dest_ip(unsigned char *buf);
void syslog_init(void);
int syslog_poll(void);
void syslog_report(char *buf);
void syslog_report(const char *buf);
#endif
obj-y += lib/util.o
obj-y += lib/assert.o
obj-$(CONFIG_LM32) += \
lib/atoi.o \
lib/assert.o \
lib/usleep.o
obj-$(CONFIG_WR_NODE) += lib/net.o
......@@ -11,3 +11,4 @@ obj-$(CONFIG_IP) += lib/ipv4.o lib/arp.o lib/icmp.o lib/udp.o lib/bootp.o
obj-$(CONFIG_SYSLOG) += lib/syslog.o
obj-$(CONFIG_LATENCY_PROBE) += lib/latency.o
obj-$(CONFIG_SNMP) += lib/snmp.o
obj-$(CONFIG_LLDP) += lib/lldp.o
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2011 GSI (www.gsi.de)
* Copyright (C) 2017 CERN
*
* Author: Cesar Prados <c.prados@gsi.de>
* Author: Adam Wujek <adam.wujek@cern.ch>
*
* LLDP transmit-only station
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <string.h>
#include "revision.h"
#include "ptpd_netif.h"
#include "lldp.h"
#include "endpoint.h"
#include "ipv4.h"
#include "shell.h"
#include "syscon.h"
#include <wrpc.h> /*needed for htons()*/
static uint8_t lldpdu[LLDP_MAX_PKT_LEN];
static uint16_t lldpdu_len;
/* tx-only socket */
static struct wrpc_socket __static_lldp_socket = {
.queue.buff = NULL,
.queue.size = 0,
};
static struct wrpc_socket *lldp_socket;
static struct wr_sockaddr addr;
extern char wrc_hw_name[HW_NAME_LENGTH];
static void lldp_header_tlv(uint8_t tlv_type, uint8_t tlv_len)
{
lldpdu[lldpdu_len] = tlv_type << 1;
lldpdu[lldpdu_len + LLDP_SUBTYPE] = tlv_len;
lldpdu_len += LLDP_HEADER;
}
static void fill_mac(uint8_t *tlv, uint8_t type)
{
*tlv = type;
/* write MAC after subtype byte */
get_mac_addr(tlv + LLDP_SUBTYPE);
}
static void lldp_add_tlv(int tlv_type) {
uint8_t mac[6];
unsigned char ipWR[4];
int tlv_len = 0;
switch (tlv_type) {
case END_LLDP:
/* End TLV */
/* header */
lldp_header_tlv(tlv_type, tlv_len);
break;
case CHASSIS_ID:
tlv_len = CHASSIS_ID_TLV_LEN;
/* header */
lldp_header_tlv(tlv_type, tlv_len);
/* TLV Chassis Component */
fill_mac(&lldpdu[lldpdu_len], CHASSIS_ID_TYPE_MAC);
break;
case PORT_ID:
tlv_len = PORT_ID_TLV_LEN;
/* header */
lldp_header_tlv(tlv_type, tlv_len);
/* TLV portID */
fill_mac(&lldpdu[lldpdu_len], PORT_ID_SUBTYPE_MAC);
break;
case TTL:
tlv_len = TTL_ID_TLV_LEN;
/* header */
lldp_header_tlv(tlv_type, tlv_len);
/* TLV Time to Live */
/* use LLDP_TX_TICK_INTERVAL in seconds times 4 */
lldpdu[lldpdu_len + TTL_BYTE_MSB] =
(((LLDP_TX_TICK_INTERVAL / 1000) * 4) >> 8) & 0xff;
lldpdu[lldpdu_len + TTL_BYTE_LSB] =
((LLDP_TX_TICK_INTERVAL / 1000) * 4) & 0xff;
break;
case PORT:
tlv_len = strlen(PORT_NAME) + 1;
/* header */
lldp_header_tlv(tlv_type, tlv_len);
strcpy((char *)lldpdu + lldpdu_len, PORT_NAME);
break;
case SYS_NAME:
{
/* TODO get host system name from wr-core outer world */
/* NOTE: according to 802.1AB-2005 9.5.6.2 and then
* IETF RFC 3418:
* "If the name is unknown, the value is the zero-length
* string."
* However, we put the IP, if not set MAC to be able to
* identify a system */
char buf[32];
getIP(ipWR);
if (HAS_IP && memcmp(ipWR, "\0\0\0\0", 4)) {
/* NOTE: no subtype */
format_ip(buf, ipWR);
tlv_len = strlen((char *)buf);
strcpy((char *)(lldpdu + lldpdu_len + LLDP_HEADER),
(char *)buf);
} else {
/* NOTE: no subtype */
get_mac_addr(mac);
pp_sprintf(buf,
"%02x:%02x:%02x:%02x:%02x:%02x",
mac[0], mac[1], mac[2], mac[3],
mac[4], mac[5]);
tlv_len = 17;
strncpy((char *)(lldpdu + lldpdu_len + LLDP_HEADER),
(char *)buf, tlv_len);
}
/* header */
lldp_header_tlv(tlv_type, tlv_len);
break;
}
case SYS_DESCR:
tlv_len = 0; /* will be calculated later */
uint8_t *pdu_p;
/* set the pointer after TLV's header */
pdu_p = &lldpdu[lldpdu_len + LLDP_HEADER];
/* TLV Info srting */
strncpy((char *)(pdu_p), wrc_hw_name, HW_NAME_LENGTH - 1);
pdu_p += strnlen(wrc_hw_name, HW_NAME_LENGTH - 1);
strcpy((char *)(pdu_p), ": ");
pdu_p += 2; /* length of ": " */
strncpy((char *)(pdu_p), build_revision, 32);
pdu_p += strnlen(build_revision, 32);
tlv_len = (uint8_t)(pdu_p - &lldpdu[lldpdu_len + LLDP_HEADER]);
lldp_header_tlv(tlv_type, tlv_len);
break;
case SYS_CAPLTY:
/* don't implement this, this TLV is optional */
break;
tlv_len = 4;
/* header */
lldp_header_tlv(tlv_type, tlv_len);
/* TLV Info string */
memset(lldpdu + lldpdu_len, 0x0, tlv_len);
break;
case MNG_ADD:
/* TODO: fill with MAC if no IP present */
if (!HAS_IP || !memcmp(ipWR, "\0\0\0\0", 4)) {
/* if no IP present skip this field */
break;
}
/* TODO: dynamic len */
tlv_len = 0xc;
/* header */
lldp_header_tlv(tlv_type, tlv_len);
/* TLV Info string */
lldpdu[lldpdu_len] = MNG_ADDR_LEN; /* len */
/* mngt add subtype */
lldpdu[lldpdu_len + LLDP_SUBTYPE] = MNG_ADDR_SUBTYPE_IPv4;
/* if subtype (ifIndex)*/
lldpdu[lldpdu_len + MNT_IF_SUBTYPE] =
MNG_IF_NUM_SUBTYPE_IFINDEX;
/* if number */
lldpdu[lldpdu_len + MNT_IF_NUM] = 0x1;
/* TLV Info srting */
if (HAS_IP) {
getIP(ipWR);
char buf[32];
format_ip(buf, ipWR);
memcpy(&lldpdu[lldpdu_len + LLDP_SUBTYPE + 1],
ipWR, 4);
}
/* TODO: add info about VLAN 9.5.9.9g */
break;
case USER_DEF:
/* TODO define WR TLV */
return;
break;
default:
return;
break;
}
lldpdu_len += tlv_len;
}
static void lldp_update(void)
{
int i;
/* add mandatory LLDP TLVs */
memset(lldpdu, 0x0, LLDP_MAX_PKT_LEN);
lldpdu_len = 0;
pp_printf("lldp update\n");
/* add all TLV's */
for (i = CHASSIS_ID; i <= MNG_ADD; i++)
lldp_add_tlv(i);
/* end TLVs */
lldp_add_tlv(END_LLDP);
}
static void lldp_init(void)
{
struct wr_sockaddr saddr;
/* LLDP: raw ethernet*/
memset(&saddr, 0x0, sizeof(saddr));
saddr.ethertype = htons(LLDP_ETH_TYP);
lldp_socket = ptpd_netif_create_socket(&__static_lldp_socket, &saddr,
PTPD_SOCK_RAW_ETHERNET, 0);
memset(&addr, 0x0, sizeof(struct wr_sockaddr));
memcpy(addr.mac, LLDP_MCAST_MAC, 6);
lldp_update();
}
static int lldp_poll(void)
{
static int ticks;
unsigned char new_ipWR;
static unsigned char old_ipWR;
uint8_t new_mac[ETH_ALEN];
static uint8_t old_mac[ETH_ALEN];
/* periodic tasks */
if (ticks > LLDP_TX_TICK_INTERVAL) {
get_mac_addr(new_mac);
if (HAS_IP) {
getIP(&new_ipWR);
}
/* Update only when IP or MAC changed */
/* TODO: or VLAN changed */
if (memcmp(&new_mac, &old_mac, ETH_ALEN)
|| (HAS_IP && (ip_status != IP_TRAINING)
&& memcmp(&new_ipWR, &old_ipWR, IPLEN))
) {
/* update LLDP info */
lldp_update();
/* copy new MAC nad IP */
memcpy(&old_mac, &new_mac, ETH_ALEN);
memcpy(&old_ipWR, &new_ipWR, IPLEN);
}
ptpd_netif_sendto(lldp_socket, &addr, lldpdu, lldpdu_len, 0);
ticks = 0;
return 1;
} else {
ticks += 1;
return 0;
}
}
DEFINE_WRC_TASK(lldp) = {
.name = "lldp",
.init = lldp_init,
.job = lldp_poll,
};
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2011 GSI (www.gsi.de)
* Author: Cesar Prados <c.prados@gsi.de>
*
* LLDP transmit-only station
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#ifndef __LLDP_H
#define __LLDP_H
#include "minic.h"
#define LLDP_MCAST_MAC "\x01\x80\xC2\x00\x00\x0E" /* 802.1AB-2005,
Table 8-1 */
#define LLDP_ETH_TYP 0x88CC /* 802.1AB-2005, Table 8-2 */
#define LLDP_MAX_PKT_LEN 0x9E /* 158 bytes */
#define TLV_MAX 0xA
#define LLDP_HEADER 0x2
#define LLDP_SUBTYPE 0x1
#define MNT_IF_SUBTYPE 0x6
#define MNT_IF_NUM 10
#define LLDP_TX_TICK_INTERVAL 10000
#define CHASSIS_ID_TLV_LEN (1 + ETH_ALEN) /* chassis ID subtype byte
* + MAC Len */
#define CHASSIS_ID_TYPE_MAC 4 /* 802.1AB-2005, table 9-2 */
#define PORT_ID_TLV_LEN (1 + ETH_ALEN) /* port ID subtype byte
* + MAC Len */
#define PORT_ID_SUBTYPE_MAC 3 /* 802.1AB-2005, table 9-3 */
#define TTL_ID_TLV_LEN 2 /* 802.1AB-2005, Figure 9-6 */
#define TTL_BYTE_MSB 0
#define TTL_BYTE_LSB 1
#define PORT_NAME "wr0"
#define IPLEN 4 /* len of IP address in bytes */
#define MNG_ADDR_LEN (1 + IPLEN) /* MNT addr subtype + IPLEN */
#define MNG_ADDR_SUBTYPE_IPv4 1 /* ianaAddressFamilyNumbers MIB */
#define MNG_ADDR_SUBTYPE_MAC 6 /* ianaAddressFamilyNumbers MIB */
#define MNG_IF_NUM_SUBTYPE_IFINDEX 2 /* 802.1AB-2005, 9.5.9.5 */
enum TLV_TYPE {
END_LLDP = 0, /* mandatory TLVs */
CHASSIS_ID,
PORT_ID,
TTL,
PORT, /* optional TLVs */
SYS_NAME,
SYS_DESCR,
SYS_CAPLTY,
MNG_ADD,
USER_DEF
};
#endif /* __LLDP_H */
......@@ -252,7 +252,7 @@ int ptpd_netif_recvfrom(struct wrpc_socket *s, struct wr_sockaddr *from, void *d
rx_timestamp->sec = hwts.sec;
rx_timestamp->nsec = hwts.nsec;
rx_timestamp->phase = 0;
rx_timestamp->correct = hwts.valid & (!spll_busy);
rx_timestamp->correct = hwts.valid && (!spll_busy);
ptpd_netif_linearize_rx_timestamp(rx_timestamp,
rx_timestamp->raw_phase,
......
......@@ -12,8 +12,9 @@
* Each OID is divided into the limb and twig part.
* The twig part can be handled as a group or a table
*/
#include <string.h>
#include <wrc.h>
#include <wrpc.h>
#include <string.h>
#include <minic.h>
#include <limits.h>
......@@ -27,13 +28,10 @@
#include "softpll_ng.h"
#include "temperature.h"
#include "sfp.h"
#include "syscon.h"
#include "storage.h"
#ifndef htons
#define htons(x) x
#endif
#define ASN_BOOLEAN ((u_char)0x01)
#define ASN_INTEGER ((u_char)0x02)
#define ASN_OCTET_STR ((u_char)0x04)
......@@ -223,8 +221,7 @@ static uint32_t aux_diag_reg_rw_num;
extern struct pp_instance ppi_static;
static struct wr_servo_state *wr_s_state;
#define SNMP_HW_TYPE_LEN 32
char snmp_hw_type[SNMP_HW_TYPE_LEN] = CONFIG_SNMP_HW_TYPE;
extern char wrc_hw_name[HW_NAME_LENGTH];
/* __DATE__ and __TIME__ is already stored in struct spll_stats stats, but
* redefining it here makes code smaller than concatenate existing one */
static char *snmp_build_date = __DATE__ " " __TIME__;
......@@ -354,7 +351,7 @@ static uint8_t oid_wrpcSfpAlpha[] = {5};
OIDs */
/* wrpcVersionGroup */
static struct snmp_oid oid_array_wrpcVersionGroup[] = {
OID_FIELD_VAR( oid_wrpcVersionHwType, get_p, NO_SET, ASN_OCTET_STR, &snmp_hw_type),
OID_FIELD_VAR( oid_wrpcVersionHwType, get_p, NO_SET, ASN_OCTET_STR, &wrc_hw_name),
OID_FIELD_VAR( oid_wrpcVersionSwVersion, get_pp, NO_SET, ASN_OCTET_STR, &build_revision),
OID_FIELD_VAR( oid_wrpcVersionSwBuildBy, get_pp, NO_SET, ASN_OCTET_STR, &build_by),
OID_FIELD_VAR( oid_wrpcVersionSwBuildDate, get_pp, NO_SET, ASN_OCTET_STR, &snmp_build_date),
......
......@@ -32,6 +32,8 @@ void syslog_init(void)
static int cmd_syslog(const char *args[])
{
char b1[32], b2[32];
char *p;
int i;
if (args[0] && !strcmp(args[0], "off")) {
syslog_addr.daddr = 0;
......@@ -39,8 +41,19 @@ static int cmd_syslog(const char *args[])
}
if (!args[1]) {
pp_printf("use: syslog <ipaddr> <macaddr> (or just \"off\"\n");
pp_printf(" or syslog msg ....\n");
return -1;
}
if (!strcmp(args[0], "msg")) {
for (i = 0; args[i+1]; i++)
;
/* now, args[i] is the last argument; undo previous nulls */
for (p = (void *)args[i]; p > args[1]; p--) /* not "const"! */
if (*p == '\0')
*p = ' ';
syslog_report(args[1]);
return 0;
}
decode_ip(args[0], (void *)&syslog_addr.daddr);
decode_mac(args[1], syslog_mac);
pp_printf("Syslog parameters: %s, %s\n",
......@@ -99,6 +112,7 @@ int syslog_poll(void)
extern struct pp_instance *ppi;
struct wr_servo_state *s;
static uint32_t prev_tics;
static int last_setp, worst_delta, bad_track_lost;
static int track_ok_count, prev_servo_state = -1;
if (IS_HOST_PROCESS)
......@@ -135,10 +149,15 @@ int syslog_poll(void)
goto send;
}
/*
* The following section is all about track-lost events
*/
if (!prev_tics)
prev_tics = now;
if (s && s->state == WR_TRACK_PHASE) /* monitor setpoint while ok */
last_setp = s->cur_setpoint;
if (s && s->state == WR_TRACK_PHASE &&
prev_servo_state != WR_TRACK_PHASE) {
/* we reached sync: log it */
......@@ -158,8 +177,33 @@ int syslog_poll(void)
"%i-th re-rtrack after %i.%03i s",
track_ok_count,
prev_tics / 1000, prev_tics % 1000);
/* Report if we didn't really loose time */
if (!bad_track_lost)
len += pp_sprintf(buf + len, " (max delta %i ps)",
worst_delta);
bad_track_lost = worst_delta = 0;
goto send;
}
if (s && s->state == WR_SYNC_PHASE && (s->flags & WR_FLAG_WAIT_HW)) {
/*
* Passing through SYNC_NSEC is a glimpse, and we won't notice.
* Check, rather if we are waiting beofre sync_phase.
*/
bad_track_lost = 1;
}
if (s && s->state != WR_TRACK_PHASE) {
int delta = s->cur_setpoint - last_setp;
/* "abs(x - y)" is not working, unexpectedly) */
if (delta < 0)
delta = - delta;
if (delta > worst_delta)
worst_delta = delta;
}
if (s && s->state != WR_TRACK_PHASE &&
prev_servo_state == WR_TRACK_PHASE) {
prev_servo_state = s->state;
......@@ -169,6 +213,9 @@ int syslog_poll(void)
goto send;
}
/*
* A section about temperature monitoring
*/
if (!next_temp_check) {
next_temp_check = now + 1000;
......@@ -207,7 +254,7 @@ send:
}
/* A report tool for others to call (used by ltest at least) */
void syslog_report(char *msg)
void syslog_report(const char *msg)
{
char buf[256];
unsigned char ip[4];
......
......@@ -15,6 +15,7 @@ void fill_udp(uint8_t * buf, int len, struct wr_udp_addr *uaddr)
{
unsigned short sum;
struct wr_udp_addr addr;
uint8_t oddb;
/* if there is no user-provided uaddr, we are replying */
if (!uaddr) {
......@@ -40,9 +41,12 @@ void fill_udp(uint8_t * buf, int len, struct wr_udp_addr *uaddr)
buf[UDP_CHECKSUM] = 0;
buf[UDP_CHECKSUM + 1] = 0;
buf[len] = '\0'; /* pad, in case the payload is odd */
/* pad, in case the payload is odd, but we can avoid the if */
oddb = buf[len];
buf[len] = '\0';
sum = ipv4_checksum((unsigned short *)(buf + UDP_VIRT_SADDR),
(len + 1 - UDP_VIRT_SADDR) / 2);
buf[len] = oddb;
if (sum == 0)
sum = 0xFFFF;
......
.depend
\ No newline at end of file
# If it exists includes Makefile.specific. In this Makefile, you should put
# specific Makefile code that you want to run before this. For example,
# build a particular environment.
-include Makefile.specific
SUPPORT_CERN_VMEBRIDGE ?= n
LIB = libdevmap.a
LOBJ := devmap.o
GIT_VER ?= $(shell git describe --always --dirty)
GIT_USR ?= $(shell git config --get-all user.name)
CFLAGS = -Wall -ggdb -fPIC -Werror -I./ -I../include
CFLAGS += -D__GIT_VER__="\"$(GIT_VER)\"" -D__GIT_USR__="\"$(GIT_USR)\""
LDFLAGS = -L.
ARFLAGS = rc
ifeq ($(SUPPORT_CERN_VMEBRIDGE), y)
LIBVME_A = $(VMEBRIDGE)/lib
LIBVME_H = $(VMEBRIDGE)/include
CFLAGS += -I$(LIBVME_H) -I$(LIBVME_A)
CFLAGS += -DSUPPORT_CERN_VMEBRIDGE
LDFLAGS += -L$(LIBVME_A) -lvmebus
LIB_DEP += $(LIBVME_A)/libvmebus.a
endif
%: %.c $(LIB)
$(CC) $(CFLAGS) $*.c $(LDFLAGS) -o $@
$(LIB): $(LOBJ) $(LIB_DEP)
ifeq ($(SUPPORT_CERN_VMEBRIDGE), y)
$(AR) $(ARFLAGS) tmp$@ $(LOBJ)
# transform a thin library into a normal one
echo -e "create $@\naddlib tmp$@\naddlib $(LIBVME_A)/libvmebus.a\nsave\nend" | $(AR) -M
$(RM) tmp$@
else
$(AR) $(ARFLAGS) $@ $^
endif
clean:
rm -f $(LIB) .depend *.o *~
.depend: Makefile $(wildcard *.c *.h ../*.h)
$(CC) $(CFLAGS) -M $(LOBJ:.o=.c) -o $@
-include .depend
/**
* Author: Federico Vaga <federico.vaga@cern.ch>
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <inttypes.h>
#include "libdevmap.h"
static const char * const libdevmap_version_s = "libdevmap version: "
__GIT_VER__ ", by " __GIT_USR__ " " __TIME__ " " __DATE__;
#ifdef SUPPORT_CERN_VMEBRIDGE
#include <libvmebus.h>
struct vmebridge_map_args {
/**
* VME memory map arguments
*/
uint32_t data_width; /**< default register size in bytes */
uint32_t am; /**< VME address modifier to use */
uint64_t addr; /**< physical base address */
};
#endif
#ifdef SUPPORT_CERN_VMEBRIDGE
static struct mapping_desc *cern_vmebridge_dev_map(
struct mapping_args *map_args, int mapping_length)
{
struct mapping_desc *desc;
struct vme_mapping *vme_mapping;
volatile void *ptr_map;
struct vmebridge_map_args *vme_args =
(struct vmebridge_map_args *)map_args->vme_extra_args;
vme_mapping = malloc(sizeof(struct vme_mapping));
if (!vme_mapping)
return NULL;
/* Prepare mmap description */
memset(vme_mapping, 0, sizeof(struct vme_mapping));
vme_mapping->am = vme_args->am;
vme_mapping->data_width = vme_args->data_width;
vme_mapping->sizel = map_args->offset + mapping_length;
vme_mapping->vme_addrl = vme_args->addr;
/* Do mmap */
ptr_map = vme_map(vme_mapping, 1);
if (!ptr_map)
goto out_alloc;
desc = malloc(sizeof(struct mapping_desc));
if (!desc)
goto out_map;
desc->base = ptr_map + map_args->offset;
desc->mmap = (void *)vme_mapping;
return desc;
out_map:
vme_unmap(vme_mapping, 1);
out_alloc:
free(vme_mapping);
return NULL;
}
#endif
/**
* It maps into memory the given device resource
* @parma[in] resource_path path to the resource file which can be mmapped
* @param[in] offset virtual address of the device memory region of interest
* within the resource
*
* @todo make the open more user friendly
*
* @return NULL on error and errno is approproately set.
* On success a mapping descriptor.
*/
struct mapping_desc *dev_map(struct mapping_args *map_args, uint32_t map_length)
{
struct mapping_desc *desc;
off_t pa_offset /*page aligned offset */;
#ifdef SUPPORT_CERN_VMEBRIDGE
if (map_args->vme_extra_args) { //map device through CERN VME_BRIDGE
desc = cern_vmebridge_dev_map(map_args, map_length);
if (!desc) {
return NULL;
}
desc->is_be = 1; /* VME Bus is big endian */
desc->args = map_args;
return desc;
}
#endif
desc = malloc(sizeof(struct mapping_desc));
if (!desc)
goto out_alloc;
desc->fd = open(map_args->resource_file, O_RDWR | O_SYNC);
if (desc->fd <= 0)
goto out_open;
/* offset is page aligned */
pa_offset = map_args->offset & ~(getpagesize() - 1);
desc->map_pa_length = map_length + map_args->offset - pa_offset;
desc->mmap = mmap(NULL, desc->map_pa_length,
PROT_READ | PROT_WRITE,
MAP_SHARED, desc->fd, pa_offset);
if ((long)desc->mmap == -1)
goto out_mmap;
desc->base = desc->mmap + map_args->offset - pa_offset;
/*
* @todo for future VME devices handled via a resource file,
* exposed in standard place (/sys/bus/vme/device/xxx/resource-file)
* the bus type (pci or vme) should be checked to set properly
* the endianess (could be get from the path's resource)
*/
desc->is_be = 0; /* default set to little endian */
return desc;
out_mmap:
close(desc->fd);
out_open:
free(desc);
out_alloc:
return NULL;
}
/**
* It releases the resources allocated by dev_map(). The mapping will
* not be available anymore and the descriptor will be invalidated
* @param[in,out] descriptor token from dev_map()
*/
void dev_unmap(struct mapping_desc *desc)
{
#ifdef SUPPORT_CERN_VMEBRIDGE
if (!desc->fd) { /* cern vmebridge resource */
vme_unmap((struct vme_mapping *)desc->mmap, 1);
free(desc->args->vme_extra_args);
free(desc->args);
free(desc);
return;
}
#endif
munmap(desc->mmap, desc->map_pa_length);
close(desc->fd);
free(desc->args);
free(desc);
}
#ifdef SUPPORT_CERN_VMEBRIDGE
#define CERN_VMEBRIDGE_REQUIRED_ARG_NB 2
#define CERN_VMEBRIDGE 1
static struct option long_options[] = {
{"cern-vmebridge", no_argument, 0, CERN_VMEBRIDGE},
{"address", required_argument, 0, 'a'},
{"offset", required_argument, 0, 'o'},
{"data-width", required_argument, 0, 'w'},
{"am", required_argument, 0, 'm'},
{0, 0, 0, 0}
};
/*
* looks for vme-compat option
* returns 1 if vme-compat is matched, otherwhise 0.
*/
static int cern_vmebridge_match(int argc, char *argv[])
{
int i;
for (i = 0; i < argc; ++i) {
if (!strcmp(argv[i], "--cern-vmebridge")) {
return 1;
}
}
return 0;
}
/*
* Parse mandatory arguments to mmap VME physical address space
* return 0 on sucess, -1 in case of error
*/
static int cern_vmebridge_parse_args(int argc, char *argv[],
struct mapping_args *map_args)
{
struct vmebridge_map_args *vme_args;
int ret, arg_count = 0, c, option_index = 0;
vme_args = calloc(1, sizeof(struct vmebridge_map_args));
if (!vme_args)
return -1;
map_args->vme_extra_args = vme_args;
/* set default values in case they are not provided*/
vme_args->data_width = 32;
vme_args->am = 0x39;
while ((c = getopt_long(argc, argv, "w:o:m:a:CERN_VMEBRIDGE", long_options,
&option_index)) != -1) {
switch(c) {
case CERN_VMEBRIDGE:
// nothing to do
break;
case 'w': /* optional arg */
ret = sscanf(optarg, "%u",
&vme_args->data_width);
if (ret != 1)
return -1;
if ( !(vme_args->data_width == 8 ||
vme_args->data_width == 16 ||
vme_args->data_width == 32 ||
vme_args->data_width == 64) )
return -1;
break;
case 'o': /* mandatory arg */
ret = sscanf(optarg, "0x%"SCNx64, &map_args->offset);
if (ret != 1)
return -1;
++arg_count;
break;
case 'm': /* optional arg */
ret = sscanf(optarg, "0x%x",
&vme_args->am);
if (ret != 1)
return -1;
break;
case 'a': /* mandatory arg */
ret = sscanf(optarg, "0x%"SCNx64,
&vme_args->addr);
if (ret != 1)
return -1;
++arg_count;
break;
case '?':
/* ignore unknown arguments */
break;
}
}
return (arg_count == CERN_VMEBRIDGE_REQUIRED_ARG_NB) ? 0 : -1;
}
#endif
#define REQUIRED_ARG_NB 2
struct mapping_args *dev_parse_mapping_args(int argc, char *argv[])
{
struct mapping_args *map_args;
char c;
int ret, arg_count = 0;
map_args = calloc(1, sizeof(struct mapping_args));
if (!map_args)
return NULL;
/*
* getopt variable: cancel error message printing because we look for
* only mapping options among other options
*/
opterr = 0;
#ifdef SUPPORT_CERN_VMEBRIDGE
if (cern_vmebridge_match(argc, argv)) {
ret = cern_vmebridge_parse_args(argc, argv, map_args);
if (ret < 0) {
goto out;
}
/*
* getopts variable: reset argument index in case application
* needs to parse arguments lokkink for specific args.
*/
optind = 1;
return map_args;
}
#endif
while ((c = getopt (argc, argv, "o:f:")) != -1)
{
switch (c)
{
case 'o':
ret = sscanf(optarg, "0x%x",
(unsigned int *)&map_args->offset);
if (ret != 1) {
goto out;
}
++arg_count;
break;
case 'f':
map_args->resource_file = optarg;
++arg_count;
break;
case '?':
/* ignore unknown arguments */
break;
}
}
if (arg_count != REQUIRED_ARG_NB) {
goto out;
}
/*
* getopts variable: reset argument index in case application needs to
* parse arguments lokkink for specific args.
*/
optind = 1;
return map_args;
out:
free(map_args);
return NULL;
}
const char * const dev_mapping_help()
{
static char help_msg[] =
"Device mapping options: \n"
"\t-f <file resource path> -o 0x<address offset> \n"
#ifdef SUPPORT_CERN_VMEBRIDGE
"Device mapping options for CERN vmebus driver: \n"
"\t--cern-vmebridge -a 0x<VME base address> \n"
"\t-o 0x<address offset> [-w <data-width[8,16,32] default=32>\n"
"\t-m 0x<address modifier default=0x39>]\n"
#endif
;
return help_msg;
}
const char * const dev_get_version()
{
return libdevmap_version_s;
}
# If it exists includes Makefile.specific. In this Makefile, you should put
# specific Makefile code that you want to run before this. For example,
# build a particular environment.
-include Makefile.specific
GIT_VER =? $(shell git describe --always --dirty)
GIT_USR =? $(shell git config --get-all user.name)
LIB = libextest.a
LOBJ := extest.o
CFLAGS = -Wall -ggdb -fPIC -Werror -I./
CFLAGS += -D__GIT_VER__="\"$(GIT_VER)\"" -D__GIT_USR__="\"$(GIT_USR)\""
LDFLAGS = -L. -lextest
ARFLAGS = rc
%: %.c $(LIB)
$(CC) $(CFLAGS) $*.c $(LDFLAGS) -o $@
$(LIB): $(LOBJ) $(LIB_DEP)
$(AR) $(ARFLAGS) $@ $^
clean:
rm -f $(LIB) .depend *.o *~
.depend: Makefile $(wildcard *.c *.h ../*.h)
$(CC) $(CFLAGS) -M $(LOBJ:.o=.c) -o $@
-include .depend
/**
* @file extest.c
*
* @brief Extensible Test program
*
* Copyright (C) CERN (www.cern.ch)
* Author: Julian Lewis
* Michel Arruat
*/
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <extest.h>
//!< Description of each operator.
static struct operator oprs[OprOPRS] = {
{
.id = OprNOOP,
.name = "?",
.help = "??? Not an operator"
},
{ OprNE, "#" , "Test: Not equal" },
{ OprEQ, "=" , "Test: Equal" },
{ OprGT, ">" , "Test: Greater than" },
{ OprGE, ">=", "Test: Greater than or equal" },
{ OprLT, "<" , "Test: Less than" },
{ OprLE, "<=", "Test: Less than or equal" },
{ OprAS, ":=", "Assign: Becomes equal" },
{ OprPL, "+" , "Arith: Add" },
{ OprMI, "-" , "Arith: Subtract" },
{ OprTI, "*" , "Arith: Multiply" },
{ OprDI, "/" , "Arith: Divide" },
{ OprAND, "&" , "Bits: AND" },
{ OprOR, "!" , "Bits: OR" },
{ OprXOR, "!!", "Bits: XOR" },
{ OprNOT, "##", "Bits: One's Complement" },
{ OprNEG, "#-", "Bits: Two's complement" },
{ OprLSH, "<<", "Bits: Left shift" },
{ OprRSH, ">>", "Bits: Right shift" },
{ OprINC, "++", "Arith: Increment" },
{ OprDECR, "--", "Arith: Decrement" },
{ OprPOP, ";" , "Stack: POP" },
{ OprSTM, "->", "Stack: PUSH" }
};
//! We divide the extended ASCII table in subsets of atom types (atom_t)
static char atomhash[256] = {
10,9,9,9,9,9,9,9,9,0,0,9,9,0,9 ,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
0,1,12,1,9,4,1,9,2,3,1,1,0,1,11,1,5,5,5,5,5,5,5,5,5,5,1,1,1,1,1,1,
10,6,6,6,6,6,6,6,6,6,6,6,6,6,6 ,6,6,6,6,6,6,6,6,6,6,6,6,7,9,8,9,6,
9 ,6,6,6,6,6,6,6,6,6,6,6,6,6,6 ,6,6,6,6,6,6,6,6,6,6,6,6,9,9,9,9,9,
9 ,9,9,9,9,9,9,9,9,9,9,9,9,9,9 ,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
9 ,9,9,9,9,9,9,9,9,9,9,9,9,9,9 ,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
9 ,9,9,9,9,9,9,9,9,9,9,9,9,9,9 ,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
9 ,9,9,9,9,9,9,9,9,9,9,9,9,9,9 ,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
};
static struct cmd_desc *_cmdlist = NULL;
static int _cmdlist_size = 0;
static struct atom _args_copy[MAX_ARG_COUNT + 1]; /* +1 for the terminator */
static void (*user_sig_hndl)() = NULL; // user sig handler
static const char * const libextest_version_s = "libextest version: "
__GIT_VER__ ", by " __GIT_USR__ " " __TIME__ " " __DATE__;
/**
* sighandler - SIGNAL handler
*
* @param sig: SIGNAL number
*
* We catch signals so that we can properly clean-up the session and exit
*/
static void sighandler(int sig)
{
/*
* we use sys_siglist[] instead of strsignal() to stay compatible
* with old versions of glibc
*/
printf("\nEXIT: Signal %s received\n", sys_siglist[sig]);
free(_cmdlist);
if (user_sig_hndl)
user_sig_hndl();
exit(1);
}
/**
* sighandler_init - register and configure the SIGNAL handler
*/
static void sighandler_init()
{
struct sigaction act;
act.sa_handler = sighandler;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(SIGFPE, &act, 0);
sigaction(SIGINT, &act, 0);
sigaction(SIGILL, &act, 0);
sigaction(SIGKILL, &act, 0);
sigaction(SIGQUIT, &act, 0);
sigaction(SIGSEGV, &act, 0);
sigaction(SIGTERM, &act, 0);
}
static int check_named_parameter(char *buf)
{
/*
* we are here because *buf = '-'
* check if next char is a letter or another '-' followed by many
* letters like:
* -[a-zA-Z]{1}
* --[a-zA-Z]*
*/
if ( (atomhash[(int)*(buf + 1)] == Alpha) ||
( (*(buf + 1) == '-') &&
(atomhash[(int)*(buf + 2)] == Alpha) ) )
return 1;
return 0;
}
static char *get_named_parameter(char *input, char *buf, struct atom *atom)
{
atom_t atype; /* atom type */
int i;
/*
* parameter name and value can be 'Separator' separated or not.
* A named parameter with its value can be specified in several ways:
* "--arg1-1" or "--arg1 -1" or "-a-1" or "-a -1":
* Too face this issue, named parameter is copied using two loops.
* First loop copy '-' character(s)
* Second loop copy the parameter name itself
*/
atom->pos = (unsigned int)(buf - input);
i = 0;
atype = atomhash[(int)(*buf)];
while (atype == Operator) {
atom->text[i++] = *buf++;
atype = atomhash[(int)*buf];
}
atype = atomhash[(int)(*buf)];
while (atype == Alpha) {
atom->text[i++] = *buf++;
if (i >= MAX_ARG_LENGTH)
break;
atype = atomhash[(int)*buf];
}
atom->text[i] = '\0';
atom->type = String;
return buf;
}
/**
* get_atoms - Split the command and its arguments into atoms
*
* @param input - command to split
* @param atoms - buffer to store atoms. [max: @ref MAX_ARG_COUNT elements]
*
* @return number of atoms processed
*/
static int get_atoms(char *input, struct atom *atoms)
{
char *buf; /* goes through input */
char *endptr; /* marks the end within input of an atom */
atom_t atype; /* atom type */
int cnt = 0; /* keeps track of @atoms entries */
int i, j;
if ( input == NULL || *input == '.')
return cnt; /* repeat last command */
bzero((void*)atoms, MAX_ARG_COUNT * sizeof(struct atom));
buf = input;
while (1) {
if (cnt >= MAX_ARG_COUNT - 1) { /* avoid overflow */
atoms[cnt].type = Terminator;
break;
}
atype = atomhash[(int)*buf];
reeval:
switch (atype) {
case Numeric:
atoms[cnt].val = (int)strtol(buf, &endptr, 0);
snprintf(atoms[cnt].text, MAX_ARG_LENGTH, "%d",
atoms[cnt].val);
atoms[cnt].type = Numeric;
buf = endptr;
cnt++;
break;
case Alpha:
atoms[cnt].pos = (unsigned int)(buf - input);
j = 0;
while (atype == Alpha) {
atoms[cnt].text[j++] = *buf++;
if (j >= MAX_ARG_LENGTH)
break;
atype = atomhash[(int)*buf];
}
atoms[cnt].text[j] = '\0';
atoms[cnt].type = Alpha;
atoms[cnt].cmd_id = CMD_NOCM;
for (i = 0; i < _cmdlist_size; ++i) {
if (!strcmp(_cmdlist[i].name, atoms[cnt].text))
atoms[cnt].cmd_id = _cmdlist[i].id;
}
cnt++;
break;
case Quotes:
/* Strings are "enclosed between quotes" */
atoms[cnt].pos = (unsigned int)(buf - input);
j = 0;
atype = atomhash[(int)(*(++buf))];
while (atype != Quotes && atype != Terminator) {
atoms[cnt].text[j++] = *buf++;
if (j >= MAX_ARG_LENGTH)
break;
atype = atomhash[(int)*buf];
}
atoms[cnt].text[j] = '\0';
atoms[cnt].type = String;
buf++; /* discard ending quotes */
cnt++;
break;
case Separator:
while (atype == Separator)
atype = atomhash[(int)(*(++buf))];
break;
case Comment:
/* Comments are %enclosed between percent marks% */
atype = atomhash[(int)(*(++buf))];
while (atype != Comment) {
atype = atomhash[(int)(*(buf++))];
if (atype == Terminator) /* no ending % */
return cnt;
}
break;
case Operator:
/*
* Two cases:
* pick up negative Numerics
* or named parameters of the command
*/
if (*buf == '-') {
/*
* Check if it is a named parameter
* Two syntaxes are supported:
* short one -[a-zA-Z]{1}
* long one --[a-zA-Z]*
*/
if (check_named_parameter(buf)) {
buf = get_named_parameter(input, buf,
&(atoms[cnt]));
cnt++;
break;
}
/* It's negative Numerics */
char *c = buf + 1;
if (*c && isdigit(*c)) {
atype = Numeric;
goto reeval;
}
}
atoms[cnt].pos = (unsigned int)(buf - input);
j = 0;
while (atype == Operator) {
atoms[cnt].text[j++] = *buf++;
if (j >= MAX_ARG_LENGTH)
break;
atype = atomhash[(int)*buf];
}
atoms[cnt].text[j] = '\0';
atoms[cnt].type = Operator;
for (i = 0; i < OprOPRS; i++) {
if (!strcmp(oprs[i].name, atoms[cnt].text)) {
atoms[cnt].oid = oprs[i].id;
break;
}
}
cnt++;
break;
case Open:
case Close:
case Open_index:
case Close_index:
case Bit:
atoms[cnt].type = atype;
buf++;
cnt++;
break;
case Illegal_char:
case Terminator:
default:
atoms[cnt].type = atype;
return cnt;
}
}
return cnt;
}
/**
* clone_args - clones @ref nr arguments from a group of atoms w/ termination
*
* @param to - address to copy to
* @param from - address to copy from
* @param nr - number of atoms to copy
*/
void clone_args(struct atom *to, struct atom *from, int nr)
{
int i = 0;
for (i = 0; i <= nr; i++) /* #0 is the cmd itself */
memcpy(to + i, from + i, sizeof(struct atom));
(to + i)->type = Terminator;
}
/**
* get_cmd_by_id - get command using its id
*
* @param cmd_id - command id (from the command enum list)
*
* @return pointer to cmd descriptor on success
* @return NULL if there is no command with id @ref cmd_id
*/
struct cmd_desc *get_cmd_by_id(int cmd_id)
{
int i;
for (i = 0; i < _cmdlist_size; ++i) {
if (_cmdlist[i].id == cmd_id)
return &_cmdlist[i];
}
return NULL;
}
struct cmd_desc *get_cmd_by_name(char *cmd_name)
{
int i;
for (i = 0; i < _cmdlist_size; ++i) {
if (!strcmp(_cmdlist[i].name, cmd_name))
return &_cmdlist[i];
}
return NULL;
}
static void atoms_init(struct atom *atoms, unsigned int elems)
{
int i;
bzero((void *)atoms, elems * sizeof(struct atom));
for (i = 0; i < elems; i++) {
atoms[i].type = Terminator;
}
}
/**
* param_amount - catch the amount of parameters for this command
*
* @param atoms - stream of atoms (user's command-line input, split into atoms)
*
* This function takes a stream of atoms, starting with a particular command.
* It identifies the number of subsequent atoms that this first atom should
* be fed with.
*
* @return number of parameters @b excluding the command itself
*/
static int param_amount(struct atom *atoms)
{
int i = 1; /* don't count the command itself */
/* "help" command is special */
if (atoms[0].cmd_id == CMD_HELP &&
atoms[1].type == Alpha && atoms[1].cmd_id != CMD_NOCM) {
i++;
goto out;
}
/* "atom list" command is special */
if (atoms[0].cmd_id == CMD_ATOMS) {
while (atoms[i].type != Terminator &&
atoms[i].type != Illegal_char)
i++;
goto out;
}
while (atoms[i].type == Numeric ||
atoms[i].type == Operator ||
atoms[i].type == String) {
if (atoms[i].type == Numeric && atoms[i + 1].type == Open)
break;
i++;
}
out:
return i - 1;
}
/**
* do_cmd - Execute command described in @atoms
*
* @param idx - index in command atom list to start execution from
* @param atoms - command atoms list
*
* @return end arg index - if OK
* @return one of @ref tst_prg_err_t - in case of error
*/
static int do_cmd(int idx, struct atom *atoms)
{
struct atom *ap; /* atom pointer */
struct cmd_desc *cdp; /* command's description */
int ret; /* stores what the handler returns */
int count = 1; /* stores the Numeric before brackets (Open) */
int rec; /* for recursive do_cmd() in Open */
int i;
/*
* @todo
* test what happens when inside a (loop), there is an error.
* Would it catch it or not? Would it break badly?
*/
atoms_init(_args_copy, MAX_ARG_COUNT + 1);
while (1) {
ap = &atoms[idx];
if (ap->type != Numeric && ap->type != Open)
count = 1; /* set count to default */
switch (ap->type) {
case Numeric:
count = ap->val;
idx++;
break;
case String:
idx++;
break;
case Open:
idx++;
for (i = 0; i < count; i++)
rec = do_cmd(idx, atoms);
idx = rec;
count = 1;
break;
case Alpha:
cdp = get_cmd_by_id(ap->cmd_id);
cdp->pa = param_amount(ap);
clone_args(_args_copy, ap, cdp->pa);
/*
* We don't do anything (yet) with ret.
* It could be used to implement a richer interface,
* but for the time being we'll leave it like that.
*/
ret = (*cdp->handle)(cdp, _args_copy);
/* keep compiler silent */
(void) ret;
idx += cdp->pa + 1;
break;
case Close:
idx++;
return idx;
case Terminator:
return idx;
default:
idx++;
return idx;
}
}
}
static void set_prompt(char *buf, size_t len, char *prg_name, char *host,
int cmd_index)
{
// snprintf(buf, len, WHITE_ON_BLACK "%s:%s[%02d] > "
// DEFAULT_COLOR, host, prg_name, cmd_index);
snprintf(buf, len, "%s:%s[%02d] > ", host, prg_name, cmd_index);
buf[len - 1] = '\0';
}
/* add a line to the history if it's not a duplicate of the previous */
static void extest_add_history(char *line)
{
HIST_ENTRY *prev;
int save_it;
if (!line[0])
return;
using_history();
prev = previous_history();
/* save it if there's no previous line or if they're different */
save_it = !prev || strcmp(line, prev->line);
using_history();
if (save_it)
add_history(line);
}
/****************************
* built-in command handlers
****************************/
/**
* hndl_illegal - Illegal command handler
*
* @param cmdd - command description
* @param atoms - command atoms list
*
* @return >= 0 - on success
* @return tst_prg_err_t - on failure
*/
static int hndl_illegal(struct cmd_desc* cmdd, struct atom *atoms)
{
printf("%s --> %s\n", atoms->text, cmdd->help);
return 1;
}
/**
* hndl_quit - Quit test program
*
* @param cmdd - command description
* @param atoms - command atoms list
*
* @return nothing; it just cleans up and exits
*/
static int hndl_quit(struct cmd_desc* cmdd, struct atom *atoms)
{
if (atoms == (struct atom*)VERBOSE_HELP) {
printf("\nexit the test program\n");
return 1;
}
exit(EXIT_SUCCESS);
}
/**
* cmd_lnm - command's longest name
*
* @return strlen of the longest command
*/
static int cmd_lnm(void)
{
static int len = 0, i;
if (len)
return len;
for (i = 0; i < _cmdlist_size; ++i) {
if (strlen(_cmdlist[i].name) > len)
len = strlen(_cmdlist[i].name);
}
return len;
}
/**
* cmd_lopt - command's longest option
*
* @return strlen of the longest command option
*/
static int cmd_lopt(void)
{
static int len = 0, i;
if (len)
return len;
for (i = 0; i < _cmdlist_size; ++i) {
if (strlen(_cmdlist[i].opt) > len)
len = strlen(_cmdlist[i].opt);
}
return len;
}
/**
* hndl_help - User help
*
* @param cmdd - command description
* @param atoms - command atoms list
*
* @return >= 0 - on success
* @return tst_prg_err_t - on failure
*/
static int hndl_help(struct cmd_desc* cmdd, struct atom *atoms)
{
struct cmd_desc *cdp = NULL; /* command description ptr */
int i, j;
if (atoms == (struct atom*)VERBOSE_HELP) {
printf("%s - display full command list\n"
"%s o - help on the operators\n"
"%s cmd - help on the command 'cmd'\n",
cmdd->name, cmdd->name, cmdd->name);
goto out;
}
if (atoms[1].type == Alpha && !strcmp(atoms[1].text, "o")) {
printf("\nOPERATORS:\n\n");
for (i = 1; i < OprOPRS; i++)
printf("Id: %2d Opr: %s \t--> %s\n",
oprs[i].id, oprs[i].name, oprs[i].help);
} else if (atoms[1].type == Alpha &&
(cdp = get_cmd_by_name(atoms[1].text))) {
(*cdp->handle)(cdp, (struct atom *)VERBOSE_HELP);
} else {
printf("Valid COMMANDS:\n%-*s %-*s %-*s %-s\n",
(int)strlen("#xx:"), "Idx", cmd_lnm(), "Name",
(int)strlen("[ ] ->") + cmd_lopt(), "Params",
"Description");
for (i = 0, j = 0; i < _cmdlist_size; ++i) {
if (_cmdlist[i].valid)
printf("#%2d: %-*s [ %-*s ] -> %s\n", ++j,
cmd_lnm(), _cmdlist[i].name, cmd_lopt(),
_cmdlist[i].opt, _cmdlist[i].help);
}
printf("\nType \"h name\" to get complete command help\n");
}
out:
return 1;
}
/**
* hndl_history - Command history print-out
*
* @param cmdd - command description
* @param atoms - command atoms list
*
* @return >= 0 - on success
* @return tst_prg_err_t - on failure
*/
static int hndl_history(struct cmd_desc* cmdd, struct atom *atoms)
{
HIST_ENTRY **list;
int i;
if (atoms == (struct atom*)VERBOSE_HELP) {
printf("%s - display command history\n", cmdd->name);
goto out;
}
list = history_list();
if (list) {
for (i = 0; list[i]; i++)
printf("Cmd[%02d] %s\n", i, list[i]->line);
}
out:
return 1;
}
/**
* hndl_atoms - Print out the command line split into atoms
*
* @param cmdd - command description
* @param atoms - command atoms list
*
* Useful for debugging
*
* @return >= 0 - on success
* @return tst_prg_err_t - on failure
*/
static int hndl_atoms(struct cmd_desc* cmdd, struct atom *atoms)
{
struct cmd_desc *dp;
struct atom *ap;
int i = 0;
if (atoms == (struct atom*)VERBOSE_HELP) {
printf("%s - split the command line input into atoms\n",
cmdd->name);
goto out;
}
printf("Arg list: Consists of %d atoms.\n", cmdd->pa);
for (i = 0; i < cmdd->pa; i++) {
ap = &atoms[i + 1]; /* skip command itself */
switch (ap->type) {
case Numeric:
printf("Arg[%02d] Num: %d\n", i + 1, ap->val);
break;
case Alpha:
if (ap->cmd_id) {
dp = get_cmd_by_id(ap->cmd_id);
printf("Arg[%02d] Cmd: %d Name: %s Help: %s\n",
i + 1, ap->cmd_id, dp->name, dp->help);
} else /* illegal command, i.e. 'CMD_NOCM' case */
printf("Arg[%02d] Unknown Command: %s\n",
i + 1, ap->text);
break;
case Operator:
if (ap->oid) {
int id = ap->oid;
printf("Arg[%02d] Operator: %s Help: %s\n",
i + 1, oprs[id].name, oprs[id].help);
}
else
printf("Arg[%02d] Unknown Operator: %s\n",
i + 1, ap->text);
break;
case String:
printf("Arg[%02d] String: \"%s\"\n", i + 1, ap->text);
break;
case Open:
printf("Arg[%02d] Opn: (\n", i + 1);
break;
case Close:
printf("Arg[%02d] Cls: )\n", i + 1);
break;
case Open_index:
printf("Arg[%02d] Opn: [\n", i + 1);
break;
case Close_index:
printf("Arg[%02d] Cls: ]\n", i + 1);
break;
case Bit:
printf("Arg[%02d] Bit: .\n", i + 1);
break;
case Terminator:
printf("Arg[%02d] End: @\n", i + 1);
break;
default:
printf("Arg[%02d] ???\n", i + 1);
}
}
out:
return 1;
}
/**
* hndl_sleep - sleep for a few seconds
*
* @param cmdd - command description
* @param atoms - command atoms list
*
* @return >= 0 - on success
* @return tst_prg_err_t - on failure
*/
static int hndl_sleep(struct cmd_desc* cmdd, struct atom *atoms)
{
int seconds;
if (atoms == (struct atom*)VERBOSE_HELP) {
printf("%s [n] - put the process to sleep for 'n' seconds\n"
"\tNote that n=1s is the default value.\n",
cmdd->name);
goto out;
}
atoms++;
if (atoms->type == Numeric)
seconds = atoms->val;
else
seconds = 1;
sleep(seconds);
out:
return 1;
}
/**
* hndl_msleep - sleep for a few milliseconds
*
* @param cmdd - command description
* @param atoms - command atoms list
*
* @return >= 0 - on success
* @return tst_prg_err_t - on failure
*/
static int hndl_msleep(struct cmd_desc* cmdd, struct atom *atoms)
{
int usec = 1000; /*default */
if (atoms == (struct atom*)VERBOSE_HELP) {
printf("%s [n] - put the process to sleep for 'n' milliseconds\n"
"\tNote that n=1ms is the default value.\n",
cmdd->name);
goto out;
}
atoms++;
if (atoms->type == Numeric)
usec = atoms->val * 1000;
usleep(usec);
out:
return 1;
}
/**
* hndl_shell - execute a shell command
*
* @param cmdd - command description
* @param atoms - command atoms list
*
* @return >= 0 - on success
* @return tst_prg_err_t - on failure
*/
static int hndl_shell(struct cmd_desc* cmdd, struct atom *atoms)
{
if (atoms == (struct atom*)VERBOSE_HELP) {
printf("%s \"shellcmd args\" - execute a shell command.\n"
"Note that shellcmd and its arguments need to be "
"enclosed in double quotes. These can't be escaped "
"so use single quotes (if needed) inside args.\n",
cmdd->name);
goto out;
}
if ((++atoms)->type != String)
return -TST_ERR_WRONG_ARG;
system(atoms->text);
out:
return 1;
}
//!< Standard commands definitions
static struct cmd_desc _built_in_cmdlist[CMD_USR] = {
[CMD_NOCM]
{
.valid = 0,
.id = CMD_NOCM,
.name = "???",
.help = "Illegal command",
.opt = "",
.comp = 0,
.handle = hndl_illegal,
},
[CMD_QUIT]
{
1, CMD_QUIT, "q", "Quit test program", "", 0, hndl_quit,
},
[CMD_HELP]
{
1, CMD_HELP, "h", "Help on commands", "o c", 0, hndl_help,
},
[CMD_ATOMS]
{
1, CMD_ATOMS, "a", "Atom list commands", "", 0, hndl_atoms,
},
[CMD_HIST]
{
1, CMD_HIST, "his", "History", "", 0, hndl_history,
},
[CMD_SLEEP]
{
1, CMD_SLEEP, "s", "Sleep seconds", "Seconds", 0, hndl_sleep,
},
[CMD_MSLEEP]
{
1, CMD_MSLEEP, "ms", "Sleep milliseconds", "MilliSecs", 0, hndl_msleep,
},
[CMD_SHELL]
{
1, CMD_SHELL, "sh", "Shell command", "Unix Cmd", 1, hndl_shell,
},
};
/********************************************
* extest's User's API
*******************************************/
const char * const extest_get_version()
{
return libextest_version_s;
}
/**
* do_yes_no - Get user answer (y/n)
*
* @param question - prompt the user with it
* @param extra - extra argument to the question (can be NULL)
*
* @return 1 - user replied 'yes'
* @return 0 - user replied 'no'
*/
int extest_do_yes_no(char *question, char *extra)
{
int reply;
ask:
printf("%s", question);
if (extra)
printf(" %s", extra);
printf("? (y/n) > ");
reply = getchar();
if (reply == EOF)
return 0;
else if (reply != '\n') {
/* escape subsequent characters and the ending '\n' */
while (getchar() != '\n')
;
}
if (reply != 'y' && reply != 'n' && /* accept y/n & Y/N */
reply != 'Y' && reply != 'N') {
printf("answer y/n only\n");
goto ask;
}
return reply == 'y';
}
/**
* compulsory_ok - checks that compulsory parameters are passed
*
* @param cmdd - command description
* @param atoms - command atoms list
*
* @return 1 - ok
* @return 0 - not ok
*/
int extest_compulsory_ok(struct cmd_desc *cmdd)
{
return cmdd->pa == cmdd->comp;
}
/**
* is_last_atom - checks if @ref atom is the last in the list to be processed
*
* @param atom - command atoms list
*
* An atom is considered to be the last one of a list if it is either
* the terminator or the atom preceding the terminator
*
* @return 1 - if it's the last one
* @return 0 - if it isn't
*/
int extest_is_last_atom(struct atom *atom)
{
if (atom->type == Terminator)
return 1;
if ((atom + 1)->type == Terminator)
return 1;
return 0;
}
/*********************************************************************/
/**
* extest_register_user_cmd - Register user commands
*
* @param user_cmds - user commands list
* @param user_cmds_nb - user commands count
*
* This function it is meant to register the list of specific user commands
* which will be added to the built-in ones.
* Note: user command's id should be greater than CMD_USR otherwise commands are
* not registered.
*
* @return 0 on success or -1 on failure
*/
int extest_register_user_cmd(struct cmd_desc user_cmdlist[], int user_cmd_nb)
{
int i;
/*
* check that none of the user command got an id in conflict with the
* built-in commands id.
*/
for (i = 0; i < user_cmd_nb; ++i) {
if (user_cmdlist[i].id < CMD_USR) {
fprintf(stderr,
"User cmd'id should be greater than CMD_USR.\n");
return -1;
}
}
/*
* build cmdlist grouping built-in and user commands
*/
_cmdlist = calloc(user_cmd_nb + CMD_USR, sizeof(struct cmd_desc));
if (_cmdlist == NULL) {
fprintf(stderr, "Allocating cmdlist failed: %s\n",
strerror(errno));
return -1;
}
memcpy(_cmdlist, _built_in_cmdlist, sizeof(struct cmd_desc) * CMD_USR);
memcpy(&_cmdlist[CMD_USR], user_cmdlist,
sizeof(struct cmd_desc) * user_cmd_nb);
_cmdlist_size = CMD_USR + user_cmd_nb;
return 0;
}
/**
* extest_init - Initialise extest
*
* @param argc - argument counter
* @param char *argv[] - argument values
*
* This function it is meant to run as long as the test program process runs.
* It will only return when there is a severe failure -- such as a signal.
*
* @return EXIT_FAILURE - on failure
*/
int extest_run(char *prg_name, void (*user_sighandler)())
{
struct atom cmd_atoms[MAX_ARG_COUNT];
char host[32] = { 0 };
char prompt[128]; /* prompt string */
char *cmd; /* command pointer */
int cmdindx = 0;
sighandler_init();
user_sig_hndl = user_sighandler; // store user signal handler
gethostname(host, 32);
using_history();
while(1) {
bzero(prompt, sizeof(prompt));
if (isatty(fileno(stdin)))
set_prompt(prompt, sizeof(prompt), prg_name, host,
cmdindx++);
cmd = readline(prompt);
if (!cmd) {
free(_cmdlist);
break; //leave infinite loop
}
extest_add_history(cmd);
atoms_init(cmd_atoms, MAX_ARG_COUNT);
get_atoms(cmd, cmd_atoms); /* split cmd into atoms */
do_cmd(0, cmd_atoms); /* execute atoms */
free(cmd);
}
return 0;
}
/**
* @file extest.h
*
* @brief Common header file for extest's programs
*
* Copyright (C) CERN (www.cern.ch)
* Author: Julian Lewis
* Michel Arruat
*/
#ifndef _EXTEST_H_
#define _EXTEST_H_
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#define MAX_ARG_COUNT 256 //!< maximum command line arguments
#define MAX_ARG_LENGTH 128 //!< max characters per argument
#define F_CLOSED (-1) //!< file closed
#define WHITE_ON_BLACK "\033[40m\033[1;37m"
#define DEFAULT_COLOR "\033[m"
//! Operator ID's
typedef enum {
OprNOOP,
OprNE,
OprEQ,
OprGT,
OprGE,
OprLT,
OprLE,
OprAS,
OprPL,
OprMI,
OprTI,
OprDI,
OprAND,
OprOR,
OprXOR,
OprNOT,
OprNEG,
OprLSH,
OprRSH,
OprINC,
OprDECR,
OprPOP,
OprSTM,
OprOPRS
} oprid_t;
struct operator {
oprid_t id; //!< operator ID (one of @ref oprid_t)
char name[16]; //!< Human form
char help[32]; //!< help string
};
//!< atom types
typedef enum {
Separator = 0, //!< [\t\n\r ,]
Operator = 1, //!< [!#&*+-/:;<=>?]
Open = 2, //!< [(]
Close = 3, //!< [)]
Comment = 4, //!< [%]
Numeric = 5, //!< [0-9]
Alpha = 6, //!< [a-zA-Z_]
Open_index = 7, //!< [\[]
Close_index = 8, //!< [\]]
Illegal_char = 9, //!< all the rest in the ASCII table
Terminator = 10, //!< [@\0]
Bit = 11, //!< [.]
String = 12 //!< ["]
} atom_t;
#define Quotes String
/*! atom container
* Example: 'oprd min 5 0x400' is formed by 4 atoms
*/
struct atom {
unsigned int pos; //!< position if @av_type is @Alpha or @Operator
int val; //!< value if @av_type is @Numeric
atom_t type; //!< atom type
char text[MAX_ARG_LENGTH]; //!< string representation
unsigned int cmd_id; //!< command id (might be built-in or user-defined)
oprid_t oid; //!< operator id (if any)
};
/*! @name Default commands for every test program
*
* Some default commands use ioctl calls to access the driver.
* The user should provide these ioctl numbers to use these commands.
* If a particular ioctl number is not provided, its command won't be issued.
* IOCTL numbers can be obtained using @b debugfs
*/
enum built_in_cmd_id {
CMD_NOCM = 0, //!< llegal command
CMD_QUIT, //!< Quit test program
CMD_HELP, //!< Help on commands
CMD_ATOMS, //!< Atom list commands
CMD_HIST, //!< History
CMD_SLEEP, //!< Sleep sec
CMD_MSLEEP, //!< Sleep millisec
CMD_SHELL, //!< Shell command
CMD_USR //!< first available command for the user
};
//!< Command description
struct cmd_desc {
int valid; //!< show command to the user? (1 - yes, 0 - no)
int id; //!< id (user-defined && @def_cmd_id)
char *name; //!< spelling
char *help; //!< short help string
char *opt; //!< options (if any)
int comp; //!< amount of compulsory options
int (*handle)(struct cmd_desc *, struct atom *); //!< handler
int pa; //!< number of arguments to be passed to the handler
};
/*! @name extest's public API
*/
//@{
//!< User wants verbose command help
#define VERBOSE_HELP (-1)
//! Test program Error return codes
enum extest_error {
TST_NO_ERR, //!< cool
TST_ERR_NOT_IMPL, //!< function not implemented
TST_ERR_NO_PARAM, //!< compulsory parameter is not provided
TST_ERR_WRONG_ARG, //!< wrong command argument
TST_ERR_SYSCALL, //!< system call fails
TST_ERR_LAST //!< error idx
};
int extest_do_yes_no(char *question, char *extra);
int extest_compulsory_ok(struct cmd_desc *cmdd);
int extest_register_user_cmd(struct cmd_desc user_cmdlist[],
int user_cmd_nb);
int extest_run(char* prg_name, void (*user_sighndl)());
int extest_is_last_atom(struct atom *atom);
const char * const extest_get_version();
//@}
#endif /* _EXTEST_H_ */
/**
* Author: Federico Vaga <federico.vaga@cern.ch>
*/
#ifndef __LIBDEVMAP_H__
#define __LIBDEVMAP_H__
#include <stdint.h>
#include <arpa/inet.h>
#define iomemr32(is_be, val) ((is_be) ? ntohl(val) : val)
#define iomemw32(is_be, val) ((is_be) ? htonl(val) : val)
struct mapping_args {
char *resource_file;
uint64_t offset;
void *vme_extra_args;
};
/* device resource mapped into memory */
struct mapping_desc {
int fd;
void *mmap;
int map_pa_length; /* mapped length is page aligned */
volatile void *base; /* address of the concerned memory region */
int is_be; /* tells the device endianess */
struct mapping_args *args;
};
/**
* @defgroup device resource mapping
*@{
*/
extern struct mapping_desc *dev_map(struct mapping_args *map_args,
uint32_t map_length);
extern void dev_unmap(struct mapping_desc *dev);
extern struct mapping_args *dev_parse_mapping_args(int argc, char *argv[]);
extern const char * const dev_mapping_help();
extern const char * const dev_get_version();
/** @}*/
#endif //__LIBDEVMAP_H__
......@@ -25,12 +25,15 @@
#include "shell.h"
#include "revision.h"
#define WRC_DIAG_REFRESH_PERIOD (1 * TICS_PER_SECOND)
extern struct pp_servo servo;
extern struct pp_instance ppi_static;
struct pp_instance *ppi = &ppi_static;
const char *ptp_unknown_str= "unknown";
static void wrc_mon_std_servo(void);
int wrc_wr_diags(void);
#define PRINT64_FACTOR 1000000000LL
static char* print64(uint64_t x, int align)
......@@ -383,7 +386,120 @@ static int wrc_log_stats(void)
return 1;
}
DEFINE_WRC_TASK(stats) = {
.name = "stats",
.job = wrc_log_stats,
};
int wrc_wr_diags(void)
{
struct hal_port_state ps;
static uint32_t last_jiffies;
int tx, rx;
uint64_t sec;
uint32_t nsec;
int n_out;
uint32_t aux_stat=0;
int temp=0, valid=0, snapshot=0,i;
valid = wdiag_get_valid();
snapshot = wdiag_get_snapshot();
/* if the data is snapshot and there is already valid data, do not
* refresh */
if(valid & snapshot)
return 0;
/* ***************** lock data from reading by user **************** */
if (!last_jiffies)
last_jiffies = timer_get_tics() - 1 - WRC_DIAG_REFRESH_PERIOD;
/* stats update condition */
if (time_before(timer_get_tics(), last_jiffies + WRC_DIAG_REFRESH_PERIOD))
return 0;
last_jiffies = timer_get_tics();
/* ***************** lock data from reading by user **************** */
wdiag_set_valid(0);
/* frame statistics */
minic_get_stats(&tx, &rx);
wdiags_write_cnts(tx,rx);
/* local time */
shw_pps_gen_get_time(&sec, &nsec);
wdiags_write_time(sec, nsec);
/* port state (from hal) */
wrpc_get_port_state(&ps, NULL);
wdiags_write_port_state((ps.state ? 1 : 0), (ps.locked ? 1 : 0));
/* port PTP State (from ppsi)
* see:
ppsi/proto-ext-whiterabbit/wr-constants.h
ppsi/include/ppsi/ieee1588_types.h
0 : none
1 : PPS_INITIALIZING
2 : PPS_FAULTY
3 : PPS_DISABLED
4 : PPS_LISTENING
5 : PPS_PRE_MASTER
6 : PPS_MASTER
7 : PPS_PASSIVE
8 : PPS_UNCALIBRATED
9 : PPS_SLAVE
100: WRS_PRESENT
101: WRS_S_LOCK
102: WRS_M_LOCK
103: WRS_LOCKED
104, 108-116:WRS_CALIBRATION
105: WRS_CALIBRATED
106: WRS_RESP_CALIB_REQ
107: WRS_WR_LINK_ON
*/
wdiags_write_ptp_state((uint8_t )ppi->state);
/* servo state (if slave)s */
if(ptp_mode == WRC_MODE_SLAVE){
struct wr_servo_state *ss =
&((struct wr_data *)ppi->ext_data)->servo_state;
int32_t asym = (int32_t)(ss->picos_mu-2LL * ss->delta_ms);
int wr_mode = (ss->flags & WR_FLAG_VALID) ? 1 : 0;
int servostate = ss->state;
/* see ppsi/proto-ext-whiterabbit/wr-constants.c:
0: WR_UNINITIALIZED = 0,
1: WR_SYNC_NSEC,
2: WR_SYNC_TAI,
3: WR_SYNC_PHASE,
4: WR_TRACK_PHASE,
5: WR_WAIT_OFFSET_STABLE */
wdiags_write_servo_state(wr_mode, servostate, ss->picos_mu,
ss->delta_ms, asym, ss->offset,
ss->cur_setpoint,ss->update_count);
}
/* auxiliar channels (if any) */
spll_get_num_channels(NULL, &n_out);
if (n_out > 8) n_out = 8; /* hardware limit. */
for(i = 0; i < n_out; i++) {
aux_stat |= (0x1 & spll_get_aux_status(i)) << i;
}
wdiags_write_aux_state(aux_stat);
/* temperature */
temp = wrc_temp_get("pcb");
wdiags_write_temp(temp);
/* **************** unlock data from reading by user ************** */
wdiag_set_valid(1);
return 1;
}
#ifdef CONFIG_WR_DIAG
DEFINE_WRC_TASK(diags) = {
.name = "diags",
.job = wrc_wr_diags,
};
#endif
ppsi @ cb5934e8
Subproject commit 325a277479110cde0e99edfd62f7c99a778be21d
Subproject commit cb5934e8dac07c21572d335a5691ea714eeebf57
......@@ -25,6 +25,7 @@ static int cmd_init(const char *args[])
else
pp_printf("OK.\n");
} else if (args[0] && !strcasecmp(args[0], "show")) {
shell_show_build_init();
storage_init_show();
} else if (args[0] && !strcasecmp(args[0], "boot")) {
spll_very_init();
......
......@@ -12,20 +12,29 @@
extern struct wrc_task wrc_tasks[];
extern int wrc_n_tasks;
extern uint32_t print_task_time_threshold;
static int cmd_ps(const char *args[])
{
struct wrc_task *t;
if (args[0] && !strcasecmp(args[0], "reset")) {
for_each_task(t)
t->nrun = t->seconds = t->nanos = 0;
return 0;
if (args[0]) {
if(!strcasecmp(args[0], "reset")) {
for_each_task(t)
t->nrun = t->seconds = t->nanos = t->max_run_ticks = 0;
return 0;
} else if (!strcasecmp(args[0], "max")) {
if (args[1])
print_task_time_threshold = atoi(args[1]);
pp_printf("print_task_time_threshold %d\n",
print_task_time_threshold);
return 0;
}
}
pp_printf(" iterations seconds.micros name\n");
pp_printf(" iterations seconds.micros max_ms name\n");
for_each_task(t)
pp_printf(" %9li %9li.%06li %s\n", t->nrun,
t->seconds, t->nanos/1000, t->name);
pp_printf(" %9li %9li.%06li %9ld %s\n", t->nrun,
t->seconds, t->nanos/1000, t->max_run_ticks, t->name);
return 0;
}
......
......@@ -26,12 +26,19 @@ struct subcmd {
{"gm", wrc_ptp_set_mode, WRC_MODE_GM},
{"master", wrc_ptp_set_mode, WRC_MODE_MASTER},
{"slave", wrc_ptp_set_mode, WRC_MODE_SLAVE},
#ifdef CONFIG_ABSCAL
{"abscal", wrc_ptp_set_mode, WRC_MODE_ABSCAL},
#endif
};
static char *is_run[] = {"stopped", "running"};
static char *is_mech[] = {[PP_E2E_MECH] = "e2e", [PP_P2P_MECH] = "p2p"};
static char *is_mode[] = {[WRC_MODE_GM] = "gm", [WRC_MODE_MASTER] = "master",
[WRC_MODE_SLAVE] = "slave"};
[WRC_MODE_SLAVE] = "slave"
#ifdef CONFIG_ABSCAL
, [WRC_MODE_ABSCAL] = "abscal"
#endif
};
static int cmd_ptp(const char *args[])
{
......
......@@ -3,14 +3,69 @@
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <string.h>
#include <errno.h>
#include "shell.h"
#include "syscon.h"
#include "hw/memlayout.h"
#include "storage.h"
/*
* args[1] - where to write sdbfs image (0 - Flash, 1 - I2C EEPROM,
* 2 - 1Wire EEPROM)
* args[2] - base address for sdbfs image in Flash/EEPROM
* args[3] - i2c address of EEPROM or blocksize of Flash
*/
static int cmd_sdb(const char *args[])
{
sdb_print_devices();
return 0;
uint8_t i2c_adr = FMC_EEPROM_ADR;
int blocksize = 1;
if (!args[0]) {
sdb_print_devices();
return 0;
}
if (!args[1] || !HAS_GENSDBFS)
return -EINVAL;
/* interpret args[3] as i2c adr or blocksize depending on memory type */
if (args[3] && atoi(args[1]) == MEM_FLASH)
blocksize = atoi(args[3])*1024;
else if (args[3])
i2c_adr = atoi(args[3]);
/* Writing SDBFS image */
if (!strcasecmp(args[0], "fs") && args[2]) {
/* if all the parameters were specified from the cmd line, we
* use these */
storage_gensdbfs(atoi(args[1]), atoi(args[2]), blocksize,
i2c_adr);
return 0;
}
if (!strcasecmp(args[0], "fs") && storage_cfg.valid &&
atoi(args[1]) == MEM_FLASH) {
/* if available, we can also use Flash parameters specified with
* HDL generics */
storage_gensdbfs(MEM_FLASH, storage_cfg.baseadr,
storage_cfg.blocksize, 0);
return 0;
}
/* Erasing SDBFS image */
if (!strcasecmp(args[0], "fse") && args[2]) {
storage_sdbfs_erase(atoi(args[1]), atoi(args[2]), blocksize,
i2c_adr);
return 0;
}
if (!strcasecmp(args[0], "fse") && storage_cfg.valid &&
atoi(args[1]) == MEM_FLASH) {
storage_sdbfs_erase(MEM_FLASH, storage_cfg.baseadr,
storage_cfg.blocksize, 0);
return 0;
}
return -EINVAL;
}
DEFINE_WRC_COMMAND(sdb) = {
......
#include <wrc.h>
#include "shell.h"
static int cmd_uptime(const char *args[])
{
extern uint32_t uptime_sec;
pp_printf("%u\n", uptime_sec);
return 0;
}
DEFINE_WRC_COMMAND(uptime) = {
.name = "uptime",
.exec = cmd_uptime,
};
......@@ -21,7 +21,6 @@
#define SH_MAX_LINE_LEN 80
#define SH_MAX_ARGS 8
#define SH_ENVIRON_SIZE 256
/* interactive shell state definitions */
......@@ -43,6 +42,8 @@ static int cmd_pos = 0, cmd_len = 0;
static int state = SH_PROMPT;
static int current_key = 0;
int shell_is_interacting;
static int insert(char c)
{
if (cmd_len >= SH_MAX_LINE_LEN)
......@@ -117,9 +118,15 @@ static int _shell_exec(void)
int shell_exec(const char *cmd)
{
strncpy(cmd_buf, cmd, SH_MAX_LINE_LEN);
int i;
if (cmd != cmd_buf)
strncpy(cmd_buf, cmd, SH_MAX_LINE_LEN);
cmd_len = strlen(cmd_buf);
return _shell_exec();
shell_is_interacting = 1;
i = _shell_exec();
shell_is_interacting = 0;
return i;
}
void shell_init()
......@@ -131,6 +138,7 @@ void shell_init()
int shell_interactive()
{
int c;
switch (state) {
case SH_PROMPT:
pp_printf("wrc# ");
......@@ -212,10 +220,16 @@ int shell_interactive()
return 0;
}
const char *fromhex(const char *hex, int *v)
const char *fromhex64(const char *hex, int64_t *v)
{
int o = 0;
int64_t o = 0;
int sign = 1;
if (hex && *hex == '-') {
sign = -1;
hex++;
}
for (; hex && *hex; ++hex) {
if (*hex >= '0' && *hex <= '9') {
o = (o << 4) + (*hex - '0');
......@@ -228,14 +242,28 @@ const char *fromhex(const char *hex, int *v)
}
}
*v = o;
*v = o * sign;
return hex;
}
const char *fromhex(const char *hex, int *v)
{
const char *ret;
int64_t v64;
ret = fromhex64(hex, &v64);
*v = (int)v64;
return ret;
}
const char *fromdec(const char *dec, int *v)
{
int o = 0;
int o = 0, sign = 1;
if (dec && *dec == '-') {
sign = -1;
dec++;
}
for (; dec && *dec; ++dec) {
if (*dec >= '0' && *dec <= '9') {
o = (o * 10) + (*dec - '0');
......@@ -244,7 +272,7 @@ const char *fromdec(const char *dec, int *v)
}
}
*v = o;
*v = o * sign;
return dec;
}
......@@ -262,6 +290,11 @@ static int build_init_readcmd(uint8_t *cmd, int maxlen)
p += i;
if (*p == ';')
p++;
if (i == 0) {
/* it's the last call, roll-back *p to be ready for the next
* call */
p = shell_init_cmd;
}
return i;
}
......@@ -278,7 +311,7 @@ void shell_boot_script(void)
if (!cmd_len)
break;
pp_printf("executing: %s\n", cmd_buf);
_shell_exec();
shell_exec(cmd_buf);
}
while (CONFIG_HAS_FLASH_INIT) {
......@@ -292,9 +325,26 @@ void shell_boot_script(void)
cmd_buf[cmd_len - 1] = 0;
pp_printf("executing: %s\n", cmd_buf);
_shell_exec();
shell_exec(cmd_buf);
next = 1;
}
return;
}
void shell_show_build_init(void)
{
uint8_t i = 0;
pp_printf("-- built-in script --\n");
while (CONFIG_HAS_BUILD_INIT) {
cmd_len = build_init_readcmd((uint8_t *)cmd_buf,
SH_MAX_LINE_LEN);
if (!cmd_len)
break;
pp_printf("%s\n", cmd_buf);
++i;
}
if (!i)
pp_printf("(empty)\n");
}
......@@ -5,6 +5,7 @@ obj-$(CONFIG_WR_NODE) += \
shell/cmd_help.o \
shell/cmd_mac.o \
shell/cmd_ps.o \
shell/cmd_uptime.o \
shell/cmd_refresh.o
obj-$(CONFIG_EMBEDDED_NODE) += \
......
......@@ -37,20 +37,20 @@ int spll_n_chan_ref, spll_n_chan_out;
#define MAIN_CHANNEL (spll_n_chan_ref)
static const struct stringlist_entry seq_states [] =
{
{ SEQ_START_EXT, "start-ext" },
{ SEQ_WAIT_EXT, "wait-ext" },
{ SEQ_START_HELPER, "start-helper" },
{ SEQ_WAIT_HELPER, "wait-helper" },
{ SEQ_START_MAIN, "start-main" },
{ SEQ_WAIT_MAIN, "wait-main" },
{ SEQ_DISABLED, "disabled" },
{ SEQ_READY, "ready" },
{ SEQ_CLEAR_DACS, "clear-dacs" },
{ SEQ_WAIT_CLEAR_DACS, "wait-clear-dacs" },
{ 0, NULL }
static const char *seq_states[] =
{
[SEQ_START_EXT] = "start-ext",
[SEQ_WAIT_EXT] = "wait-ext",
[SEQ_START_HELPER] = "start-helper",
[SEQ_WAIT_HELPER] = "wait-helper",
[SEQ_START_MAIN] = "start-main",
[SEQ_WAIT_MAIN] = "wait-main",
[SEQ_DISABLED] = "disabled",
[SEQ_READY] = "ready",
[SEQ_CLEAR_DACS] = "clear-dacs",
[SEQ_WAIT_CLEAR_DACS] = "wait-clear-dacs",
};
#define SEQ_STATES_NR ARRAY_SIZE(seq_states)
volatile struct softpll_state softpll;
......@@ -481,11 +481,15 @@ void spll_get_num_channels(int *n_ref, int *n_out)
void spll_show_stats()
{
struct softpll_state *s = (struct softpll_state *)&softpll;
const char *statename = seq_states[s->seq_state];
if (s->seq_state >= SEQ_STATES_NR)
statename = "<Unknown>";
if (softpll.mode > 0)
pp_printf("softpll: irqs %d seq %s mode %d "
"alignment_state %d HL%d ML%d HY=%d MY=%d DelCnt=%d\n",
s->irq_count, stringlist_lookup(seq_states, s->seq_state),
s->irq_count, statename,
s->mode, s->ext.align_state,
s->helper.ld.locked, s->mpll.ld.locked,
s->helper.pi.y, s->mpll.pi.y,
......
......@@ -31,10 +31,6 @@
#define SPLL_AUX_ENABLED (1<<0) /* Locking the particular aux channel to the WR reference is enabled */
#define SPLL_AUX_LOCKED (1<<1) /* The particular aux clock is already locked to WR reference */
/* Phase detector types */
#define SPLL_PD_DDMTD 0
#define SPLL_PD_BANGBANG 1
/* Channels for spll_measure_frequency() */
#define SPLL_OSC_REF 0
#define SPLL_OSC_DMTD 1
......@@ -131,7 +127,6 @@ struct softpll_state {
int mode;
int seq_state;
int dac_timeout;
int default_dac_main;
int delock_count;
unsigned irq_count;
int32_t mpll_shift_ps;
......
......@@ -93,24 +93,6 @@ void ld_init(spll_lock_det_t *ld)
ld->lock_changed = 0;
}
void lowpass_init(spll_lowpass_t *lp, int alpha)
{
lp->y_d = 0x80000000;
lp->alpha = alpha;
}
int lowpass_update(spll_lowpass_t *lp, int x)
{
if (lp->y_d == 0x80000000) {
lp->y_d = x;
return x;
} else {
int scaled = (lp->alpha * (x - lp->y_d)) >> 15;
lp->y_d = lp->y_d + (scaled >> 1) + (scaled & 1);
return lp->y_d;
}
}
/* Enables/disables DDMTD tag generation on a given (channel).
Channels (0 ... splL_n_chan_ref - 1) are the reference channels
......@@ -142,40 +124,3 @@ void spll_enable_tagger(int channel, int enable)
pll_verbose("%s: ch %d, OCER 0x%x, RCER 0x%x\n", __FUNCTION__, channel, SPLL->OCER, SPLL->RCER);
}
void biquad_init(spll_biquad_t *bq, const int *coefs, int shift)
{
memset(bq, 0, sizeof(spll_biquad_t));
memcpy(bq->coefs, coefs, 5 * sizeof(int));
bq->shift = shift;
}
int biquad_update(spll_biquad_t *bq, int x)
{
register int y = 0;
y += bq->coefs[0] * x;
y += bq->coefs[1] * bq->xd[0];
y += bq->coefs[2] * bq->xd[1];
y -= bq->coefs[3] * bq->yd[0];
y -= bq->coefs[4] * bq->yd[1];
y >>= bq->shift;
bq->xd[1] = bq->xd[0];
bq->xd[0] = x;
bq->yd[1] = bq->yd[0];
bq->yd[0] = y;
return y;
}
const char *stringlist_lookup(const struct stringlist_entry *slist, int id)
{
int i;
for(i=0; slist[i].str; i++) {
if(slist[i].id == id)
return slist[i].str;
}
return "<unknown>";
}
......@@ -50,33 +50,6 @@ typedef struct {
int lock_changed;
} spll_lock_det_t;
/* simple, 1st-order lowpass filter */
typedef struct {
int alpha;
int y_d;
} spll_lowpass_t;
typedef struct {
int coefs[5]; /* Biquad coefficients: b0 b1 b2 a1 a2 */
int shift; /* bit shift for the coeffs / output */
int yd[2], xd[2]; /* I/O delay lines */
} spll_biquad_t;
/* long-term-average filter */
typedef struct {
int acc;
int n;
int window;
int pos;
int size;
int log[16];
} spll_lta_t;
struct stringlist_entry {
int id;
const char *str;
};
/* initializes the PI controller state. Currently almost a stub. */
void pi_init(spll_pi_t *pi);
......@@ -86,14 +59,7 @@ int pi_update(spll_pi_t *pi, int x);
void ld_init(spll_lock_det_t *ld);
int ld_update(spll_lock_det_t *ld, int y);
void lowpass_init(spll_lowpass_t *lp, int alpha);
int lowpass_update(spll_lowpass_t *lp, int x);
void spll_enable_tagger(int channel, int enable);
void biquad_init(spll_biquad_t *bq, const int *coefs, int shift);
int biquad_update(spll_biquad_t *bq, int x);
const char *stringlist_lookup(const struct stringlist_entry *slist, int id);
#endif // __SPLL_COMMON_H
......@@ -11,13 +11,6 @@
#include "softpll_ng.h"
const int helper_precomp_coefs [] =
{ /*b0*/ 60648,
/*b1*/ 60648,
/*b2*/ 0,
/*a1*/ 55760,
/*a2*/ 0};
void helper_init(struct spll_helper_state *s, int ref_channel)
{
......@@ -33,7 +26,6 @@ void helper_init(struct spll_helper_state *s, int ref_channel)
s->ld.lock_samples = 10000;
s->ld.delock_samples = 100;
s->ref_src = ref_channel;
s->delock_count = 0;
}
int helper_update(struct spll_helper_state *s, int tag,
......@@ -101,8 +93,6 @@ void helper_start(struct spll_helper_state *s)
pi_init((spll_pi_t *)&s->pi);
ld_init((spll_lock_det_t *)&s->ld);
biquad_init(&s->precomp, helper_precomp_coefs, 16);
spll_enable_tagger(s->ref_src, 1);
spll_debug(DBG_EVENT | DBG_HELPER, DBG_EVT_START, 1);
}
......
......@@ -31,10 +31,8 @@ struct spll_helper_state {
int p_setpoint, tag_d0;
int ref_src;
int sample_n;
int delock_count;
spll_pi_t pi;
spll_lock_det_t ld;
spll_biquad_t precomp;
};
void helper_init(struct spll_helper_state *s, int ref_channel);
......
......@@ -14,12 +14,14 @@
#define MPLL_TAG_WRAPAROUND 100000000
#define MATCH_NEXT_TAG 0
#define MATCH_WAIT_REF 1
#define MATCH_WAIT_OUT 2
#undef WITH_SEQUENCING
#ifdef CONFIG_DAC_LOG
extern void spll_log_dac(int y);
#else
static inline void spll_log_dac(int y) {}
#endif
void mpll_init(struct spll_main_state *s, int id_ref,
int id_out)
{
......@@ -37,7 +39,6 @@ void mpll_init(struct spll_main_state *s, int id_ref,
#else
#error "Please set CONFIG for wr switch or wr node"
#endif
s->delock_count = 0;
s->enabled = 0;
/* Freqency branch lock detection */
......@@ -63,9 +64,6 @@ void mpll_start(struct spll_main_state *s)
s->tag_out = -1;
s->tag_ref_d = -1;
s->tag_out_d = -1;
s->seq_ref = 0;
s->seq_out = 0;
s->match_state = MATCH_NEXT_TAG;
s->phase_shift_target = 0;
s->phase_shift_current = 0;
......@@ -138,6 +136,8 @@ int mpll_update(struct spll_main_state *s, int tag, int source)
y = pi_update((spll_pi_t *)&s->pi, err);
SPLL->DAC_MAIN = SPLL_DAC_MAIN_VALUE_W(y)
| SPLL_DAC_MAIN_DAC_SEL_W(s->dac_index);
if (s->dac_index == 0)
spll_log_dac(y);
spll_debug(DBG_MAIN | DBG_REF, s->tag_ref + s->adder_ref, 0);
spll_debug(DBG_MAIN | DBG_TAG, s->tag_out + s->adder_out, 0);
......
......@@ -23,16 +23,10 @@ struct spll_main_state {
int adder_ref, adder_out, tag_ref, tag_out, tag_ref_d, tag_out_d;
// tag sequencing stuff
uint32_t seq_ref, seq_out;
int match_state;
int match_seq;
int phase_shift_target;
int phase_shift_current;
int id_ref, id_out; /* IDs of the reference and the output channel */
int sample_n;
int delock_count;
int dac_index;
int enabled;
};
......
......@@ -31,7 +31,6 @@ CONFIG_CMD_CONFIG=y
CONFIG_SYSLOG=y
CONFIG_SNMP=y
CONFIG_SNMP_SET=y
CONFIG_SNMP_HW_TYPE="spec"
CONFIG_BUILD_INIT=y
CONFIG_INIT_COMMAND="ptp stop"
CONFIG_HAS_BUILD_INIT=1
......
......@@ -11,3 +11,6 @@ flash-write
pfilter-builder
wrpc-dump
mapper
wrpc-vuart
wr-streamers
wrpc-diags
EB ?= no
SDBFS ?= no
CFLAGS = -Wall -ggdb -I../include
LDFLAGS = -lutil
ALL = genraminit genramvhd genrammif wrpc-uart-sw
CFLAGS = -Wall -ggdb -I../include -I../liblinux -I../liblinux/extest
CFLAGS += -D__GIT_VER__="\"$(GIT_VER)\"" -D__GIT_USR__="\"$(GIT_USR)\""
LDFLAGS = -lutil -L../liblinux -ldevmap -L../liblinux/extest -lextest
LDFLAGS += -lreadline
ALL = genraminit genramvhd genrammif
ALL += wrpc-w1-read wrpc-w1-write
ALL += pfilter-builder
ALL += wrpc-dump mapper
ALL += wrpc-vuart
ALL += wr-streamers
ALL += wrpc-diags
ifneq ($(EB),no)
ALL += eb-w1-write
......@@ -46,7 +51,15 @@ wrpc-dump: wrpc-dump.c dump-info-host.o
$(CC) $(CFLAGS) -I../ppsi/include -I../ppsi/arch-wrpc/include -I.. \
-I ../softpll \
$^ -o $@ \
-D__GIT_VER__="\"$(GIT_VER)\"" -D__GIT_USR__="\"$(GIT_USR)\""
wr-streamers: wr-streamers.c
$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@
wrpc-diags: wrpc-diags.c
$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@
wrpc-vuart: wrpc-vuart.c
$(CC) $(CFLAGS) -Werror $^ $(LDFLAGS) -o $@
pfilter-builder: pfilter-builder.c
$(CC) $(CFLAGS) -include ../include/generated/autoconf.h \
......
#!/bin/bash
mkdir -p ok-configs
declare -A ok
touch ok-configs/empty
for n in ok-configs/*; do
S=$(md5sum $n | awk '{print $1}')
ok[$S]=y
done
rm ok-configs/empty
while true; do
D=$(mktemp build.XXXXXX); rm $D; mkdir $D
make randconfig 2>&1 | grep KCONFIG_SEED | tee /dev/tty > $D/seed
S=$(md5sum .config | awk '{print $1}')
if [ "${ok[$S]}" = y ]; then
echo "duplicate; skipping"
rm -rf $D
continue
fi
cp .config $D/config
make -s clean> $D/clean 2>&1
rm ppsi/.config
make -j8 > $D/build 2>&1
if [ $? -eq 0 ]; then
if grep -q warning: $D/build; then
echo "Warning"
make -s savedefconfig
mv defconfig $D
mv $D warn-$D
else
echo "Ok"
cp $D/config ok-configs/$D
S=$(md5sum ok-configs/$D | awk '{print $1}')
ok[$S]=y
rm -rf $D
fi
else
echo "Failed"
make -s savedefconfig
mv defconfig $D
mv $D ko-$D
echo ko-$D
fi
sleep .5
echo ""
done
#!/bin/bash
declare -A err
HOW="grep -wi error $file"
for n in ko-build*; do
test -d $n || continue
file=$n/build
S=$($HOW | sort | md5sum | awk '{print $1}')
err[$S]=$n
done
for n in ${err[*]}; do
echo "############################ $n"
file=$n/build
$HOW
done
#!/bin/bash
declare -A warn
HOW="grep -wi warning $file"
for n in warn-build*; do
test -d $n || continue
file=$n/build
S=$($HOW | sort | md5sum | awk '{print $1}')
warn[$S]=$n
done
for n in ${warn[*]}; do
echo "############################ $n"
file=$n/build
$HOW
done
......@@ -112,4 +112,4 @@ main()
for(;;);
}
\ No newline at end of file
}
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>
#include <time.h>
#include <libdevmap.h>
#include <extest.h>
#include <hw/wr_streamers.h>
static struct mapping_desc *wrstm = NULL;
#define LEAP_SECONDS_DEFAULT 37
static int leap_seconds = LEAP_SECONDS_DEFAULT;
static char *stats_mesg[][2] = {
{"Number of sent wr streamer frames since reset", "tx_cnt"},
{"Number of received wr streamer frames since reset", "rx_cnt"},
{"Number of lost wr streamer frames since reset", "rx_cnt_lost_fr"},
{"Maximum latency [ref clk period] of received frames since reset",
"max_lat_raw"},
{"Minimum latency [ref clk period] of received frames since reset",
"min_lat_raw"},
{"Accumulated latency [ref clk period] of received frames since reset",
"acc_lat"},
{"Counter of the accumulated frequency", "acc_freq_cnt"},
{"Number of indications that one or more blocks in a"
"frame were lost (probably CRC error) since reset", "rx_cnt_lost_blk"},
};
int read_stats(struct cmd_desc *cmdd, struct atom *atoms)
{
volatile struct WR_STREAMERS_WB *ptr =
(volatile struct WR_STREAMERS_WB *)wrstm->base;
int val, overflow;
double max_lat, min_lat, avg_lat;
uint64_t acc_lat, cnt_lat;
if (atoms == (struct atom *)VERBOSE_HELP) {
printf("%s - options\n"
"\t0: %s\n\t1: %s\n\t2: %s\n\t3: %s\n\t4: %s\n\t5: %s\n"
"\t6: %s\n\t7: %s\n", cmdd->name, stats_mesg[0][0],
stats_mesg[1][0], stats_mesg[2][0], stats_mesg[3][0],
stats_mesg[4][0], stats_mesg[5][0], stats_mesg[6][0],
stats_mesg[7][0]);
return 1;
}
++atoms;
if (atoms->type != Terminator && atoms->type != Numeric)
return -TST_ERR_WRONG_ARG;
val = -1; // all stats
if (atoms->type == Numeric)
val = atoms->val; // specific stats
//snapshot stats
ptr->SSCR1 = iomemw32(wrstm->is_be, WR_STREAMERS_SSCR1_SNAPSHOT_STATS);
switch(val) {
case -1: //all stats
max_lat = WR_STREAMERS_RX_STAT0_RX_LATENCY_MAX_R(
iomemr32(wrstm->is_be, ptr->RX_STAT0));
max_lat = (max_lat * 8) / 1000.0;
min_lat = WR_STREAMERS_RX_STAT1_RX_LATENCY_MIN_R(
iomemr32(wrstm->is_be, ptr->RX_STAT1));
min_lat = (min_lat * 8) / 1000.0;
overflow = WR_STREAMERS_SSCR1_RX_LATENCY_ACC_OVERFLOW &
iomemr32(wrstm->is_be, ptr->SSCR1);
//put it all together
acc_lat = ((uint64_t)iomemr32(wrstm->is_be, ptr->RX_STAT11)
<< 32) |iomemr32(wrstm->is_be, ptr->RX_STAT10);
cnt_lat = ((uint64_t)iomemr32(wrstm->is_be, ptr->RX_STAT13)
<< 32) | iomemr32(wrstm->is_be, ptr->RX_STAT12);
avg_lat = (((double)acc_lat) * 8 / 1000) / (double)cnt_lat;
fprintf(stderr, "Latency [us] : min=%10g max=%10g avg =%10g "
"(0x%x, 0x%x, %lu=%u << 32 | %u)*8/1000 us, "
"cnt =%lu overflow =%d)\n",
min_lat, max_lat, avg_lat,
iomemr32(wrstm->is_be, ptr->RX_STAT1),
iomemr32(wrstm->is_be, ptr->RX_STAT0),
acc_lat, iomemr32(wrstm->is_be, ptr->RX_STAT11),
iomemr32(wrstm->is_be, ptr->RX_STAT10),
cnt_lat, overflow);
fprintf(stderr, "Frames [number]: tx =%lu rx =%lu lost=%lu "
"(lost blocks =%lu)\n",
((uint64_t)iomemr32(wrstm->is_be, ptr->TX_STAT3)
<< 32) | iomemr32(wrstm->is_be, ptr->TX_STAT2),
((uint64_t)iomemr32(wrstm->is_be, ptr->RX_STAT5)
<< 32) | iomemr32(wrstm->is_be, ptr->RX_STAT4),
((uint64_t)iomemr32(wrstm->is_be, ptr->RX_STAT7)
<< 32) | iomemr32(wrstm->is_be, ptr->RX_STAT6),
((uint64_t)iomemr32(wrstm->is_be, ptr->RX_STAT9)
<< 32) | iomemr32(wrstm->is_be, ptr->RX_STAT8));
break;
case 0:
fprintf(stderr, "%s:%lu\n", stats_mesg[0][1],
((uint64_t)iomemr32(wrstm->is_be, ptr->TX_STAT3)
<< 32) | iomemr32(wrstm->is_be, ptr->TX_STAT2));
break;
case 1:
fprintf(stderr, "%s:%lu\n", stats_mesg[1][1],
((uint64_t)iomemr32(wrstm->is_be, ptr->RX_STAT5)
<< 32) | iomemr32(wrstm->is_be, ptr->RX_STAT4));
break;
case 2:
fprintf(stderr, "%s:%lu\n", stats_mesg[2][1],
((uint64_t)iomemr32(wrstm->is_be, ptr->RX_STAT7)
<< 32) | iomemr32(wrstm->is_be, ptr->RX_STAT6));
break;
case 3:
fprintf(stderr, "%s: 0x%x\n", stats_mesg[3][1],
WR_STREAMERS_RX_STAT0_RX_LATENCY_MAX_R(
iomemr32(wrstm->is_be, ptr->RX_STAT0)));
break;
case 4:
fprintf(stderr, "%s: 0x%x\n", stats_mesg[4][1],
WR_STREAMERS_RX_STAT1_RX_LATENCY_MIN_R(
iomemr32(wrstm->is_be, ptr->RX_STAT1)));
break;
case 5:
fprintf(stderr, "%s:%lu\n", stats_mesg[5][1],
((uint64_t)iomemr32(wrstm->is_be, ptr->RX_STAT11)
<< 32) | iomemr32(wrstm->is_be, ptr->RX_STAT10));
break;
case 6:
fprintf(stderr, "%s:%lu\n", stats_mesg[6][1],
((uint64_t)iomemr32(wrstm->is_be, ptr->RX_STAT13)
<< 32) | iomemr32(wrstm->is_be, ptr->RX_STAT12));
break;
case 7:
fprintf(stderr, "%s:%lu\n", stats_mesg[7][1],
((uint64_t)iomemr32(wrstm->is_be, ptr->RX_STAT9)
<< 32) | iomemr32(wrstm->is_be, ptr->RX_STAT8));
break;
}
//release snapshot
ptr->SSCR1 = 0;
return 1;
}
int read_reset_time(struct cmd_desc *cmdd, struct atom *atoms)
{
uint64_t tai, tai_msw;
uint32_t tai_lsw;
int days=0, hours=0, minutes=0, seconds;
double reset_time_elapsed=0;
time_t cur_time;
time_t res_time_sec;
volatile struct WR_STREAMERS_WB *ptr =
(volatile struct WR_STREAMERS_WB *)wrstm->base;
if (atoms == (struct atom *)VERBOSE_HELP) {
printf("%s - %s\n", cmdd->name, cmdd->help);
return 1;
}
tai_lsw = iomemr32(wrstm->is_be, ptr->SSCR2);
tai_msw = iomemr32(wrstm->is_be, ptr->SSCR3) & WR_STREAMERS_SSCR3_RST_TS_TAI_MSB_MASK;
tai = (tai_msw << 32) | tai_lsw;
res_time_sec = (time_t)(tai + leap_seconds);//to UTC
cur_time = time(NULL);
reset_time_elapsed = difftime(cur_time,res_time_sec);
days = reset_time_elapsed/(60*60*24);
hours = (reset_time_elapsed-days*60*60*24)/(60*60);
minutes = (reset_time_elapsed-days*60*60*24-hours*60*60)/(60);
seconds = (reset_time_elapsed-days*60*60*24-hours*60*60-minutes*60);
fprintf(stderr, "Time elapsed from reset (computed with %d leap seconds): "
"%d days, %d h, %d m, %d s; Reseted on %s\n",
leap_seconds, days, hours, minutes, seconds,
asctime(localtime(&res_time_sec)));
return 1;
}
int reset_counters(struct cmd_desc *cmdd, struct atom *atoms)
{
volatile struct WR_STREAMERS_WB *ptr =
(volatile struct WR_STREAMERS_WB *)wrstm->base;
if (atoms == (struct atom *)VERBOSE_HELP) {
printf("%s - %s\n", cmdd->name, cmdd->help);
return 1;
}
ptr->SSCR1 = iomemw32(wrstm->is_be, WR_STREAMERS_SSCR1_RST_STATS);
fprintf(stderr, "Reseted statistics counters\n");
return 1;
}
int reset_seqid(struct cmd_desc *cmdd, struct atom *atoms)
{
volatile struct WR_STREAMERS_WB *ptr =
(volatile struct WR_STREAMERS_WB *)wrstm->base;
if (atoms == (struct atom *)VERBOSE_HELP) {
printf("%s - %s\n", cmdd->name, cmdd->help);
return 1;
}
ptr->SSCR1 = iomemw32(wrstm->is_be, WR_STREAMERS_SSCR1_RST_SEQ_ID);
return 1;
}
int get_set_tx_ethertype(struct cmd_desc *cmdd, struct atom *atoms)
{
volatile struct WR_STREAMERS_WB *ptr =
(volatile struct WR_STREAMERS_WB *)wrstm->base;
uint32_t val;
if (atoms == (struct atom *)VERBOSE_HELP) {
printf("%s - %s\n", cmdd->name, cmdd->help);
return 1;
}
++atoms;
if (atoms->type != Terminator) {
if (atoms->type != Numeric)
return -TST_ERR_WRONG_ARG;
val = atoms->val & WR_STREAMERS_TX_CFG0_ETHERTYPE_MASK;
ptr->TX_CFG0 = iomemw32(wrstm->is_be, val);
}
val = WR_STREAMERS_TX_CFG0_ETHERTYPE_R(iomemr32(wrstm->is_be,
ptr->TX_CFG0));
fprintf(stderr, "TX ethertype 0x%x\n", val);
return 1;
}
int get_set_tx_local_mac(struct cmd_desc *cmdd, struct atom *atoms)
{
volatile struct WR_STREAMERS_WB *ptr =
(volatile struct WR_STREAMERS_WB *)wrstm->base;
uint32_t lsw;
uint64_t val, msw;
if (atoms == (struct atom *)VERBOSE_HELP) {
printf("%s - %s\n", cmdd->name, cmdd->help);
return 1;
}
++atoms;
if (atoms->type != Terminator) {
if (atoms->type != Numeric)
return -TST_ERR_WRONG_ARG;
val = atoms->val & 0xFFFFFFFFFFFF;
lsw = val & 0xFFFFFFFF;
msw = (val >> 32) & WR_STREAMERS_TX_CFG2_MAC_LOCAL_MSB_MASK;
ptr->TX_CFG1 = iomemw32(wrstm->is_be, lsw);
ptr->TX_CFG2 = iomemw32(wrstm->is_be, msw);
}
lsw = iomemr32(wrstm->is_be, ptr->TX_CFG1);
msw = iomemr32(wrstm->is_be, ptr->TX_CFG2);
val = lsw | (msw << 32);
fprintf(stderr, "TX Local MAC address 0x%lx\n", val);
return 1;
}
int get_set_tx_remote_mac(struct cmd_desc *cmdd, struct atom *atoms)
{
volatile struct WR_STREAMERS_WB *ptr =
(volatile struct WR_STREAMERS_WB *)wrstm->base;
uint32_t lsw;
uint64_t val, msw;
if (atoms == (struct atom *)VERBOSE_HELP) {
printf("%s - %s\n", cmdd->name, cmdd->help);
return 1;
}
++atoms;
if (atoms->type != Terminator) {
if (atoms->type != Numeric)
return -TST_ERR_WRONG_ARG;
val = atoms->val & 0xFFFFFFFFFFFF;
lsw = val & 0xFFFFFFFF;
msw = (val >> 32) & WR_STREAMERS_TX_CFG4_MAC_TARGET_MSB_MASK;
ptr->TX_CFG3 = iomemw32(wrstm->is_be, lsw);
ptr->TX_CFG4 = iomemw32(wrstm->is_be, msw);
}
lsw = iomemr32(wrstm->is_be, ptr->TX_CFG3);
msw = iomemr32(wrstm->is_be, ptr->TX_CFG4);
val = lsw | (msw << 32);
fprintf(stderr, "TX Target MAC address 0x%lx\n", val);
return 1;
}
int get_set_rx_ethertype(struct cmd_desc *cmdd, struct atom *atoms)
{
volatile struct WR_STREAMERS_WB *ptr =
(volatile struct WR_STREAMERS_WB *)wrstm->base;
uint32_t val;
if (atoms == (struct atom *)VERBOSE_HELP) {
printf("%s - %s\n", cmdd->name, cmdd->help);
return 1;
}
++atoms;
if (atoms->type != Terminator) {
if (atoms->type != Numeric)
return -TST_ERR_WRONG_ARG;
val = iomemr32(wrstm->is_be, ptr->RX_CFG0);
val &= ~WR_STREAMERS_RX_CFG0_ETHERTYPE_MASK;
val |= WR_STREAMERS_RX_CFG0_ETHERTYPE_W(atoms->val);
ptr->RX_CFG0 = iomemw32(wrstm->is_be, val);
}
val = WR_STREAMERS_RX_CFG0_ETHERTYPE_R(iomemr32(wrstm->is_be,
ptr->RX_CFG0));
fprintf(stderr, "RX ethertype 0x%x\n", val);
return 1;
}
int get_set_rx_local_mac(struct cmd_desc *cmdd, struct atom *atoms)
{
volatile struct WR_STREAMERS_WB *ptr =
(volatile struct WR_STREAMERS_WB *)wrstm->base;
uint32_t lsw;
uint64_t val, msw;
if (atoms == (struct atom *)VERBOSE_HELP) {
printf("%s - %s\n", cmdd->name, cmdd->help);
return 1;
}
++atoms;
if (atoms->type != Terminator) {
if (atoms->type != Numeric)
return -TST_ERR_WRONG_ARG;
val = atoms->val & 0xFFFFFFFFFFFF;
lsw = val & 0xFFFFFFFF;
msw = (val >> 32) & WR_STREAMERS_RX_CFG2_MAC_LOCAL_MSB_MASK;
ptr->RX_CFG1 = iomemw32(wrstm->is_be, lsw);
ptr->RX_CFG2 = iomemw32(wrstm->is_be, msw);
}
lsw = iomemr32(wrstm->is_be, ptr->RX_CFG1);
msw = iomemr32(wrstm->is_be, ptr->RX_CFG2);
val = lsw | (msw << 32);
fprintf(stderr, "RX Local MAC address 0x%lx\n", val);
return 1;
}
int get_set_rx_remote_mac(struct cmd_desc *cmdd, struct atom *atoms)
{
volatile struct WR_STREAMERS_WB *ptr =
(volatile struct WR_STREAMERS_WB *)wrstm->base;
uint32_t lsw;
uint64_t val, msw;
if (atoms == (struct atom *)VERBOSE_HELP) {
printf("%s - %s\n", cmdd->name, cmdd->help);
return 1;
}
++atoms;
if (atoms->type != Terminator) {
if (atoms->type != Numeric)
return -TST_ERR_WRONG_ARG;
val = atoms->val & 0xFFFFFFFFFFFF;
lsw = val & 0xFFFFFFFF;
msw = (val >> 32) & WR_STREAMERS_RX_CFG4_MAC_REMOTE_MSB_MASK;
ptr->RX_CFG3 = iomemw32(wrstm->is_be, lsw);
ptr->RX_CFG4 = iomemw32(wrstm->is_be, msw);
}
lsw = iomemr32(wrstm->is_be, ptr->RX_CFG3);
msw = iomemr32(wrstm->is_be, ptr->RX_CFG4);
val = lsw | (msw << 32);
fprintf(stderr, "RX Target MAC address 0x%lx\n", val);
return 1;
}
int get_set_latency(struct cmd_desc *cmdd, struct atom *atoms)
{
volatile struct WR_STREAMERS_WB *ptr =
(volatile struct WR_STREAMERS_WB *)wrstm->base;
int lat;
uint32_t val;
if (atoms == (struct atom *)VERBOSE_HELP) {
printf("%s - %s\n", cmdd->name, cmdd->help);
return 1;
}
++atoms;
if (atoms->type == Terminator) {
// Get Latency
fprintf(stderr, "Fixed latency configured: %d [us]\n",
(iomemr32(wrstm->is_be, ptr->RX_CFG5) * 8) / 1000);
}
else {
if (atoms->type != Numeric)
return -TST_ERR_WRONG_ARG;
lat = atoms->val;
if (lat < 0) {
val = ~WR_STREAMERS_CFG_OR_RX_FIX_LAT &
iomemr32(wrstm->is_be, ptr->CFG);
ptr->CFG = iomemw32(wrstm->is_be, val);
fprintf(stderr, "Disabled overriding of default fixed "
"latency value (it is now the default/set "
"by application)\n");
}
else {
val = (lat * 1000) / 8;
ptr->RX_CFG5 = iomemw32(wrstm->is_be,
WR_STREAMERS_RX_CFG5_FIXED_LATENCY_W(val));
val = iomemr32(wrstm->is_be, ptr->CFG);
val |= WR_STREAMERS_CFG_OR_RX_FIX_LAT;
ptr->CFG = iomemw32(wrstm->is_be, val);
val = WR_STREAMERS_RX_CFG5_FIXED_LATENCY_R(
iomemr32(wrstm->is_be, ptr->RX_CFG5));
fprintf(stderr, "Fixed latency set: %d [us] "
"(set %d | read : %d [cycles])\n",
lat, ((lat * 1000) / 8), val);
}
}
return 1;
}
int get_set_qtags_flag(struct cmd_desc *cmdd, struct atom *atoms)
{
volatile struct WR_STREAMERS_WB *ptr =
(volatile struct WR_STREAMERS_WB *)wrstm->base;
uint32_t val, txcfg5;
if (atoms == (struct atom *)VERBOSE_HELP) {
printf("%s - %s\n", cmdd->name, cmdd->help);
return 1;
}
++atoms;
txcfg5 = iomemr32(wrstm->is_be, ptr->TX_CFG5);
if (atoms->type == Terminator) { //read current flag
// Check enable/disable QTag flag
val = txcfg5 & WR_STREAMERS_TX_CFG5_QTAG_ENA;
}
else { // set QTag flag
if (atoms->type != Numeric)
return -TST_ERR_WRONG_ARG;
val = (atoms->val) ? 1 : 0; /* convert input into 0 or 1 */
if (val)
txcfg5 |= WR_STREAMERS_TX_CFG5_QTAG_ENA;
else
txcfg5 &= ~WR_STREAMERS_TX_CFG5_QTAG_ENA;
ptr->TX_CFG5 = iomemw32(wrstm->is_be, txcfg5);
}
fprintf(stderr, "Tagging with QTag is %s\n",
(val) ? "Enabled" : "Disabled");
return 1;
}
int get_set_qtags_param(struct cmd_desc *cmdd, struct atom *atoms)
{
volatile struct WR_STREAMERS_WB *ptr =
(volatile struct WR_STREAMERS_WB *)wrstm->base;
int argc;
uint32_t vid, prio, txcfg5, cfg;
if (atoms == (struct atom *)VERBOSE_HELP) {
printf("%s - %s\n", cmdd->name, cmdd->help);
return 1;
}
++atoms;
txcfg5 = iomemr32(wrstm->is_be, ptr->TX_CFG5);
if (atoms->type == Terminator) { //read current flag
vid = (txcfg5 & WR_STREAMERS_TX_CFG5_QTAG_VID_MASK) >>
WR_STREAMERS_TX_CFG5_QTAG_VID_SHIFT;
prio = (txcfg5 & WR_STREAMERS_TX_CFG5_QTAG_PRIO_MASK) >>
WR_STREAMERS_TX_CFG5_QTAG_PRIO_SHIFT;
}
else { // writing new QTag settings
argc = 0; //count provided arguments
if (atoms->type != Numeric)
return -TST_ERR_WRONG_ARG;
/* first parameter is vid */
argc++;
vid = atoms->val;
++atoms;
if (atoms->type == Numeric) { // new prio is provided
prio = atoms->val;
argc++;
}
txcfg5 &= ~WR_STREAMERS_TX_CFG5_QTAG_VID_MASK; //reset vid bit field
txcfg5 |= (vid << WR_STREAMERS_TX_CFG5_QTAG_VID_SHIFT); // set new vid
if (argc == 2) {
txcfg5 &= ~WR_STREAMERS_TX_CFG5_QTAG_PRIO_MASK; // reset prio bit field
txcfg5 |= (prio << WR_STREAMERS_TX_CFG5_QTAG_PRIO_SHIFT); // set new prio
}
// enable QTag just in case it's not yet enabled
txcfg5 |= 0x1;
ptr->TX_CFG5 = iomemw32(wrstm->is_be, txcfg5);
/* read the override register and enable overriding of the
default configuration (set with generics) with the WB
configuration (written above) */
cfg = iomemr32(wrstm->is_be, ptr->CFG);
cfg |= WR_STREAMERS_CFG_OR_TX_QTAG;
ptr->CFG = iomemw32(wrstm->is_be, cfg);
}
fprintf(stderr, "Tagging with QTag: VLAN ID: %d prio: %d\n",
vid, prio);
return 1;
}
int get_set_qtags_or(struct cmd_desc *cmdd, struct atom *atoms)
{
volatile struct WR_STREAMERS_WB *ptr =
(volatile struct WR_STREAMERS_WB *)wrstm->base;
uint32_t cfg, val;
if (atoms == (struct atom *)VERBOSE_HELP) {
printf("%s - %s\n", cmdd->name, cmdd->help);
return 1;
}
++atoms;
cfg = iomemr32(wrstm->is_be, ptr->CFG);
if (atoms->type == Terminator) { //read current flag
// Check enable/disable QTag flag
val = cfg & WR_STREAMERS_CFG_OR_TX_QTAG;
}
else { // set QTag flag
if (atoms->type != Numeric)
return -TST_ERR_WRONG_ARG;
val = (atoms->val) ? 1 : 0; /* convert input into 0 or 1 */
if (val)
cfg |= WR_STREAMERS_CFG_OR_TX_QTAG;
else
cfg &= ~WR_STREAMERS_CFG_OR_TX_QTAG;
ptr->CFG = iomemw32(wrstm->is_be, cfg);
}
fprintf(stderr, "Overriding of the default QTag config with WB config is %s\n",
(val) ? "Enabled" : "Disabled");
return 1;
}
int get_set_leap_seconds(struct cmd_desc *cmdd, struct atom *atoms)
{
if (atoms == (struct atom *)VERBOSE_HELP) {
printf("%s - %s\n", cmdd->name, cmdd->help);
return 1;
}
++atoms;
if (atoms->type != Terminator) {
if (atoms->type != Numeric)
return -TST_ERR_WRONG_ARG;
leap_seconds = atoms->val;
}
fprintf(stderr, "leap seconds: %d\n", leap_seconds);
return 1;
}
enum wrstm_cmd_id{
WRSTM_CMD_STATS = CMD_USR,
WRSTM_CMD_RESET,
WRSTM_CMD_RESET_CNTS,
WRSTM_CMD_RESET_SEQID,
/* FIXME: see below
WRSTM_CMD_TX_ETHERTYPE,
WRSTM_CMD_TX_LOC_MAC,
WRSTM_CMD_TX_REM_MAC,
WRSTM_CMD_RX_ETHERTYPE,
WRSTM_CMD_RX_LOC_MAC,
WRSTM_CMD_RX_REM_MAC,
*/
WRSTM_CMD_LATENCY,
WRSTM_CMD_QTAG_ENB,
WRSTM_CMD_QTAG_VP,
WRSTM_CMD_QTAG_OR,
WRSTM_CMD_LEAP_SEC,
// WRSTM_CMD_DBG_BYTE,
// WRSTM_CMD_DBG_MUX,
// WRSTM_CMD_DBG_VAL,
WRSTM_CMD_LAST,
};
#define WRSTM_CMD_NB WRSTM_CMD_LAST - CMD_USR
struct cmd_desc wrstm_cmd[WRSTM_CMD_NB + 1] = {
{ 1, WRSTM_CMD_STATS, "stats", "show streamers statistics",
"[0/1/2/3/4/5/6/7]", 0, read_stats},
{ 1, WRSTM_CMD_RESET, "reset",
"show time of the latest reset / time elapsed since then", "", 0,
read_reset_time},
{ 1, WRSTM_CMD_RESET_CNTS, "resetcnt",
"reset tx/rx/lost counters and avg/min/max latency values", "", 0,
reset_counters},
{ 1, WRSTM_CMD_RESET_SEQID, "resetseqid",
"reset sequence ID of the tx streamer", "", 0, reset_seqid},
/** ****************************************************************
* FIXME: 1: MAC address is a long number and such a long number
* needs special handling, now when I write 0x28d2444c0e17,
* I read 0x444c0e17. indeed only the LSB is written to
* the proper register.
* 2: all this values require additional setting of correspinding
* override bits in CFG register
* 3: all these values require enable/disable override (maybe
* with 0x0 value?
*
{ 1, WRSTM_CMD_TX_LOC_MAC, "txlocmac",
"get/set TX Local MAC addres", "mac", 0, get_set_tx_local_mac},
{ 1, WRSTM_CMD_TX_REM_MAC, "txremmac",
"get/set TX Target MAC address", "mac", 0, get_set_tx_remote_mac},
{ 1, WRSTM_CMD_RX_ETHERTYPE, "rxether",
"get/set RX ethertype", "ethertype", 0, get_set_rx_ethertype},
{ 1, WRSTM_CMD_RX_LOC_MAC, "rxlocmac",
"get/set RX Local MAC addres", "mac", 0, get_set_rx_local_mac},
{ 1, WRSTM_CMD_RX_REM_MAC, "rxremmac",
"get/set RX Remote MAC address", "mac", 0, get_set_rx_remote_mac},
{ 1, WRSTM_CMD_TX_ETHERTYPE, "txether",
"get/set TX ethertype", "ethertype", 0, get_set_tx_ethertype},
**************************************************************** */
{ 1, WRSTM_CMD_LATENCY, "lat",
"get/set config of fixed latency in integer [us] (-1 to disable)",
"[latency]", 0, get_set_latency},
{ 1, WRSTM_CMD_QTAG_ENB, "qtagf",
"QTags flag on off",
"[0/1]", 0, get_set_qtags_flag},
{ 1, WRSTM_CMD_QTAG_VP, "qtagvp",
"QTags Get/Set VLAN ID and priority",
"[VID,prio]", 0, get_set_qtags_param},
{ 1, WRSTM_CMD_QTAG_OR, "qtagor",
"get/set overriding of default qtag config with WB config (set "
"using qtagf, qtagvp)",
"[0/1]", 0, get_set_qtags_or},
{ 1, WRSTM_CMD_LEAP_SEC, "ls",
"get/set leap seconds",
"[leapseconds]", 0, get_set_leap_seconds},
// { 1, WRSTM_CMD_DBG_BYTE, "dbgbyte",
// "set which byte of the rx or tx frame should be snooped", "byte", 1,},
// { 1, WRSTM_CMD_DBG_MUX, "dbgdir",
// "set whether tx or rx frames should be snooped", "dir", 1,},
// { 1, WRSTM_CMD_DBG_VAL, "dbgword",
// "read the snooped 32-bit value", "", 0,},
{0, },
};
void print_version(void)
{
fprintf(stderr, "Built in wrpc-sw repo ver:%s, by %s on %s %s\n",
__GIT_VER__, __GIT_USR__, __TIME__, __DATE__);
}
static void wrstm_help(char *prog)
{
fprintf(stderr, "%s [options]\n", prog);
fprintf(stderr, "%s\n", dev_mapping_help());
print_version();
}
static void sig_hndl()
{
// Signal occured: free resource and exit
fprintf(stderr, "Handle signal: free resource and exit.\n");
dev_unmap(wrstm);
exit(1);
}
static int verify_reg_version()
{
volatile struct WR_STREAMERS_WB *ptr =
(volatile struct WR_STREAMERS_WB *)wrstm->base;
uint32_t ver = 0;
ver = iomemr32(wrstm->is_be, ptr->VER);
fprintf(stderr, "Wishbone register version: in FPGA = 0x%x |"
" in SW = 0x%x\n", ver, WBGEN2_WR_STREAMERS_VERSION);
if(ver != WBGEN2_WR_STREAMERS_VERSION)
return -1;
else
return 0;
}
int main(int argc, char *argv[])
{
int ret;
struct mapping_args *map_args;
map_args = dev_parse_mapping_args(argc, argv);
if (!map_args) {
wrstm_help(argv[0]);
return -1;
}
wrstm = dev_map(map_args, sizeof(struct WR_STREAMERS_WB));
if (!wrstm) {
fprintf(stderr, "%s: wrstm mmap() failed: %s\n", argv[0],
strerror(errno));
free(map_args);
return -1;
}
ret = verify_reg_version();
if (ret) {
fprintf(stderr, "Register version in FPGA and SW does not match\n");
dev_unmap(wrstm);
return -1;
}
ret = extest_register_user_cmd(wrstm_cmd, WRSTM_CMD_NB);
if (ret) {
dev_unmap(wrstm);
return -1;
}
/* execute command loop */
ret = extest_run("wrstm", sig_hndl);
dev_unmap(wrstm);
return (ret) ? -1 : 0;
}
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>
#include <time.h>
#include <libdevmap.h>
#include <extest.h>
#include <hw/wrc_diags_regs.h>
static struct mapping_desc *wrcdiag = NULL;
static void unlock_diag(volatile struct WRC_DIAGS_WB *ptr)
{
//reset snapshot bit & keep valid bit as it is
ptr->CTRL &= iomemw32(wrcdiag->is_be, 0x1);
}
static int lock_diag(volatile struct WRC_DIAGS_WB *ptr)
{
int loop = 10;
//snapshot diag ( just raise snapshot bit)
ptr->CTRL |= iomemw32(wrcdiag->is_be, WRC_DIAGS_CTRL_DATA_SNAPSHOT);
//wait max 10ms that valid bit becomes true.
do {
if (ptr->CTRL & iomemw32(wrcdiag->is_be,
WRC_DIAGS_CTRL_DATA_VALID))
return 0;
usleep(1000);
--loop;
} while(loop);
fprintf(stderr, "timeout(10ms) expired while waiting for the valid bit "
"for snapshot\n");
return 1;
}
static void print_servo_status(uint32_t val)
{
static char *sstat_str[] = {
"Not initialized",
"Sync ns",
"Sync TAI",
"Sync phase",
"Track phase",
"Wait offset stable",
};
fprintf(stderr, "servo status:\t\t%s\n",
sstat_str[val >> WRC_DIAGS_WDIAG_SSTAT_SERVOSTATE_SHIFT]);
}
static void print_port_status(uint32_t val)
{
static int nbits = 2;
static char *pstat_str[][2] = {
//bit = 0 bit = 1
{"Link down", "Link up",},
{"PLL not locked", "PLL locked",},
};
int i, idx;
fprintf(stderr, "Port status:\t\t");
for (i = 0; i < nbits; ++i) {
idx = (val & (1 << i)) ? 1 : 0;
fprintf(stderr, "%s, ", pstat_str[i][idx]);
}
fprintf(stderr, "\n");
}
static void print_ptp_state(uint32_t val)
{
static char *ptpstat_str[] = {
"None",
"PPS initializing",
"PPS faulty",
"disabled",
"PPS listening",
"PPS pre-master",
"PPS master",
"PPS passive",
"PPS uncalibrated",
"PPS slave",
};
fprintf(stderr, "PTP state:\t\t");
if (val <= 9)
fprintf(stderr, "%s", ptpstat_str[val]);
else if (val >= 100 && val <= 116)
fprintf(stderr, "WR STATES(see ppsi/ieee1588_types.h): %d", val);
else
fprintf(stderr, "Unknown");
fprintf(stderr, "\n");
}
static void print_aux_state(uint32_t val)
{
int nch = 8; //should be retrieved from a register
int i;
fprintf(stderr, "Aux state:\t\t");
for (i = 0; i < nch; i++) {
if (val & (1 << i))
fprintf(stderr, "ch%d:enabled ", i);
}
fprintf(stderr, "\n");
}
static void print_tx_frame_count(uint32_t val)
{
fprintf(stderr, "TX frame count:\t\t%d\n", val);
}
static void print_rx_frame_count(uint32_t val)
{
fprintf(stderr, "RX frame count:\t\t%d\n", val);
}
static void print_local_time(uint32_t sec_msw, uint32_t sec_lsw, uint32_t ns)
{
uint64_t sec = (uint64_t)(sec_msw) << 32 | sec_lsw;
// fprintf(stderr, "TAI time:\t\t %" PRIu64 "sec %d nsec\n",
// sec, ns);
fprintf(stderr, "TAI time:\t\t%s", ctime((time_t *)&sec));
}
static void print_roundtrip_time(uint32_t msw, uint32_t lsw)
{
uint64_t val = (uint64_t)(msw) << 32 | lsw;
fprintf(stderr, "Round trip time:\t%" PRIu64 " ps\n", val);
}
static void print_master_slave_delay(uint32_t msw, uint32_t lsw)
{
uint64_t val = (uint64_t)(msw) << 32 | lsw;
fprintf(stderr, "Master slave delay:\t%" PRIu64 " ps\n", val);
}
static void print_link_asym(uint32_t val)
{
fprintf(stderr, "Total Link asymmetry:\t%d ps\n", val);
}
static void print_clock_offset(uint32_t val)
{
fprintf(stderr, "Clock offset:\t\t%d ps\n", val);
}
static void print_phase_setpoint(uint32_t val)
{
fprintf(stderr, "Phase setpoint:\t\t%d ps\n", val);
}
static void print_update_counter(uint32_t val)
{
fprintf(stderr, "Update counter:\t\t%d\n", val);
}
static void print_board_temp(uint32_t val)
{
fprintf(stderr, "temp:\t\t\t%d.%04d C\n", val >> 16,
(int)((val & 0xffff) * 10 * 1000 >> 16));
}
enum wrcdiag_cmd_id{
WRCDIAG_CMD_DIAGS = CMD_USR,
WRCDIAG_CMD_SSTAT,
WRCDIAG_CMD_PTPSTAT,
WRCDIAG_CMD_PSTAT,
WRCDIAG_CMD_ASTAT,
WRCDIAG_CMD_TXFCNT,
WRCDIAG_CMD_RXFCNT,
WRCDIAG_CMD_LTIME,
WRCDIAG_CMD_RTTIME,
WRCDIAG_CMD_MSTRSLAVEDELAY,
WRCDIAG_CMD_LINKASYM,
WRCDIAG_CMD_CKOFFSET,
WRCDIAG_CMD_PHASESETPOINT,
WRCDIAG_CMD_UPDATECNT,
WRCDIAG_CMD_TEMP,
WRCDIAG_CMD_LAST,
};
static int read_diags(struct cmd_desc *cmdd, struct atom *atoms)
{
volatile struct WRC_DIAGS_WB *ptr =
(volatile struct WRC_DIAGS_WB *)wrcdiag->base;
int res;
if (atoms == (struct atom *)VERBOSE_HELP) {
printf("%s - %s\n", cmdd->name, cmdd->help);
return 1;
}
res = lock_diag(ptr);
if (res) {
fprintf(stderr, "Cmd is not executed\n");
return 1;
}
switch (cmdd->id) {
case WRCDIAG_CMD_DIAGS:
print_servo_status(iomemr32(wrcdiag->is_be, ptr->WDIAG_SSTAT));
print_port_status(iomemr32(wrcdiag->is_be, ptr->WDIAG_PSTAT));
print_ptp_state(iomemr32(wrcdiag->is_be, ptr->WDIAG_PTPSTAT));
print_aux_state(iomemr32(wrcdiag->is_be, ptr->WDIAG_ASTAT));
print_tx_frame_count(iomemr32(wrcdiag->is_be, ptr->WDIAG_TXFCNT));
print_rx_frame_count(iomemr32(wrcdiag->is_be, ptr->WDIAG_RXFCNT));
print_local_time(iomemr32(wrcdiag->is_be, ptr->WDIAG_SEC_MSB),
iomemr32(wrcdiag->is_be, ptr->WDIAG_SEC_LSB),
iomemr32(wrcdiag->is_be, ptr->WDIAG_NS));
print_roundtrip_time(iomemr32(wrcdiag->is_be, ptr->WDIAG_MU_MSB),
iomemr32(wrcdiag->is_be, ptr->WDIAG_MU_LSB));
print_master_slave_delay(iomemr32(wrcdiag->is_be,
ptr->WDIAG_DMS_MSB),
iomemr32(wrcdiag->is_be,
ptr->WDIAG_DMS_LSB));
print_link_asym(iomemr32(wrcdiag->is_be, ptr->WDIAG_ASYM));
print_clock_offset(iomemr32(wrcdiag->is_be, ptr->WDIAG_CKO));
print_phase_setpoint(iomemr32(wrcdiag->is_be, ptr->WDIAG_SETP));
print_update_counter(iomemr32(wrcdiag->is_be, ptr->WDIAG_UCNT));
print_board_temp(iomemr32(wrcdiag->is_be, ptr->WDIAG_TEMP));
break;
case WRCDIAG_CMD_SSTAT:
print_servo_status(iomemr32(wrcdiag->is_be, ptr->WDIAG_SSTAT));
break;
case WRCDIAG_CMD_PSTAT:
print_port_status(iomemr32(wrcdiag->is_be, ptr->WDIAG_PSTAT));
break;
case WRCDIAG_CMD_PTPSTAT:
print_ptp_state(iomemr32(wrcdiag->is_be, ptr->WDIAG_PTPSTAT));
break;
case WRCDIAG_CMD_ASTAT:
print_aux_state(iomemr32(wrcdiag->is_be, ptr->WDIAG_ASTAT));
break;
case WRCDIAG_CMD_TXFCNT:
print_tx_frame_count(iomemr32(wrcdiag->is_be,
ptr->WDIAG_TXFCNT));
break;
case WRCDIAG_CMD_RXFCNT:
print_rx_frame_count(iomemr32(wrcdiag->is_be,
ptr->WDIAG_RXFCNT));
break;
case WRCDIAG_CMD_LTIME:
print_local_time(iomemr32(wrcdiag->is_be, ptr->WDIAG_SEC_MSB),
iomemr32(wrcdiag->is_be, ptr->WDIAG_SEC_LSB),
iomemr32(wrcdiag->is_be, ptr->WDIAG_NS));
break;
case WRCDIAG_CMD_RTTIME:
print_roundtrip_time(iomemr32(wrcdiag->is_be,
ptr->WDIAG_MU_MSB),
iomemr32(wrcdiag->is_be,
ptr->WDIAG_MU_LSB));
break;
case WRCDIAG_CMD_MSTRSLAVEDELAY:
print_master_slave_delay(iomemr32(wrcdiag->is_be,
ptr->WDIAG_DMS_MSB),
iomemr32(wrcdiag->is_be,
ptr->WDIAG_DMS_LSB));
break;
case WRCDIAG_CMD_LINKASYM:
print_link_asym(iomemr32(wrcdiag->is_be, ptr->WDIAG_ASYM));
break;
case WRCDIAG_CMD_CKOFFSET:
print_clock_offset(iomemr32(wrcdiag->is_be, ptr->WDIAG_CKO));
break;
case WRCDIAG_CMD_PHASESETPOINT:
print_phase_setpoint(iomemr32(wrcdiag->is_be, ptr->WDIAG_SETP));
break;
case WRCDIAG_CMD_UPDATECNT:
print_update_counter(iomemr32(wrcdiag->is_be, ptr->WDIAG_UCNT));
break;
case WRCDIAG_CMD_TEMP:
print_board_temp(iomemr32(wrcdiag->is_be, ptr->WDIAG_TEMP));
break;
}
unlock_diag(ptr);
return 1;
}
void print_version(void)
{
fprintf(stderr, "Built in wrpc-sw repo ver:%s, by %s on %s %s\n",
__GIT_VER__, __GIT_USR__, __TIME__, __DATE__);
}
static void wrcdiag_help(char *prog)
{
fprintf(stderr, "%s [options]\n", prog);
fprintf(stderr, "%s\n", dev_mapping_help());
print_version();
}
static void sig_hndl()
{
volatile struct WRC_DIAGS_WB *ptr =
(volatile struct WRC_DIAGS_WB *)wrcdiag->base;
// Signal occured: free resource and exit
fprintf(stderr, "Handle signal: free resource and exit.\n");
unlock_diag(ptr); // clean snapshot
dev_unmap(wrcdiag);
exit(1);
}
#define WRCDIAG_CMD_NB WRCDIAG_CMD_LAST - CMD_USR
struct cmd_desc wrcdiag_cmd[WRCDIAG_CMD_NB + 1] = {
{ 1, WRCDIAG_CMD_DIAGS, "diags", "show all wrc diags",
"", 0, read_diags},
{ 1, WRCDIAG_CMD_SSTAT, "sstat",
"get servo status", "", 0, read_diags},
{ 1, WRCDIAG_CMD_PTPSTAT, "ptpstat",
"get PTP state", "", 0, read_diags},
{ 1, WRCDIAG_CMD_PSTAT, "pstat",
"get port status", "", 0, read_diags},
{ 1, WRCDIAG_CMD_ASTAT, "astat",
"get auxiliare state", "", 1, read_diags},
{ 1, WRCDIAG_CMD_TXFCNT, "txfcnt",
"get TX PTP frame count", "", 1, read_diags},
{ 1, WRCDIAG_CMD_RXFCNT, "rxfcnt",
"get RX frame count", "", 1, read_diags},
{ 1, WRCDIAG_CMD_LTIME, "ltime",
"Local Time expressed in sec since epoch", "", 1, read_diags},
{ 1, WRCDIAG_CMD_RTTIME, "rttime",
"Round trip time in picoseconds", "", 1, read_diags},
{ 1, WRCDIAG_CMD_MSTRSLAVEDELAY, "msdelay",
"Master slave link delay in picoseconds", "", 1, read_diags},
{ 1, WRCDIAG_CMD_LINKASYM, "asym",
"Total link asymmetry in picoseonds", "", 1, read_diags},
{ 1, WRCDIAG_CMD_CKOFFSET, "cko",
"Clock offset in picoseonds", "", 1, read_diags},
{ 1, WRCDIAG_CMD_PHASESETPOINT, "setp",
"Current slave's clock phase shift value", "", 1, read_diags},
{ 1, WRCDIAG_CMD_UPDATECNT, "ucnt",
"Update counter", "", 1, read_diags},
{ 1, WRCDIAG_CMD_TEMP, "temp",
"get board temperature", "", 1, read_diags},
{0, },
};
static int verify_reg_version()
{
volatile struct WRC_DIAGS_WB *ptr =
(volatile struct WRC_DIAGS_WB *)wrcdiag->base;
uint32_t ver = 0;
ver = iomemr32(wrcdiag->is_be, ptr->VER);
fprintf(stderr, "Wishbone register version: in FPGA = 0x%x |"
" in SW = 0x%x\n", ver, WBGEN2_WRC_DIAGS_VERSION);
if(ver != WBGEN2_WRC_DIAGS_VERSION)
return -1;
else
return 0;
}
int main(int argc, char *argv[])
{
int ret;
struct mapping_args *map_args;
map_args = dev_parse_mapping_args(argc, argv);
if (!map_args) {
wrcdiag_help(argv[0]);
return -1;
}
wrcdiag = dev_map(map_args, sizeof(struct WRC_DIAGS_WB));
if (!wrcdiag) {
fprintf(stderr, "%s: wrcdiag mmap() failed: %s\n", argv[0],
strerror(errno));
free(map_args);
return -1;
}
ret = verify_reg_version();
if (ret) {
fprintf(stderr, "Register version in FPGA and SW does not match\n");
dev_unmap(wrcdiag);
return -1;
}
ret = extest_register_user_cmd(wrcdiag_cmd, WRCDIAG_CMD_NB);
if (ret) {
dev_unmap(wrcdiag);
return -1;
}
/* execute command loop */
ret = extest_run("wrcdiag", sig_hndl);
dev_unmap(wrcdiag);
return (ret) ? -1 : 0;
}
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2013 CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <pty.h>
#include <arpa/inet.h> /* ntohl etc */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/select.h>
#include "../include/uart-sw.h"
/*
* The following parameters match the spec, but can be changed on env/cmdline
*/
#define DEFAULT_BUS -1 /* all */
#define DEFAULT_BAR 0 /* first bar */
#define DEFAULT_RAMADDR 0 /* beginning */
#define DEFAULT_RAMSIZE 0x16000 /* 88k, default in spec */
#define MAX_DEVICES 8 /* no alloc, me lazy */
static struct usw_pci_id {
unsigned pci_v;
unsigned pci_d;
} spec_devices[] = {
{ 0x10dc /* CERN */, 0x018d /* SPEC */ },
{ 0x1a39 /* Gennum */, 0x0004 /* GN4124 */ },
{ 0, },
};
struct usw_device {
void *mapaddr;
int mapsize;
struct wrc_uart_sw *p;
uint16_t nreturned;
int fd;
};
static struct usw_device devs[MAX_DEVICES];
char *prgname;
/* Prepare communication according to user settings (currently pty only) */
static int usw_prepare_io(struct usw_device *dev)
{
char path[PATH_MAX];
int fdm, fds;
if (openpty(&fdm, &fds, path, NULL, NULL) < 0) {
fprintf(stderr, "%s: openpty(): %s\n", prgname,
strerror(errno));
return -1;
}
dev->fd = fdm;
close(fds);
printf("Opened \"%s\"; use screen or minicom\n", path);
return 0;
}
/* Open a uart-sw device, with an already-prepared mmap */
static int usw_open_device(char *name, struct usw_device *dev)
{
int i;
uint32_t *ptr;
for (i = 0; i < dev->mapsize; i += 16) {
ptr = dev->mapaddr + i;
if (*ptr == UART_SW_MAGIC)
break;
}
if (i == dev->mapsize) {
fprintf(stderr, "%s: no uart-sw in device %s\n", prgname,
name);
return -1;
}
fprintf(stderr, "%s: %s: found uart-sw at 0x%x\n", prgname, name, i);
dev->p = dev->mapaddr + i;
return usw_prepare_io(dev);
}
/* Access a PCI device, mmap and so on */
static int usw_access_pci(char *name, int index)
{
struct usw_device *dev = devs + index;
char path[PATH_MAX];
struct stat stbuf;
int fd;
memset(dev, 0, sizeof(*dev));
sprintf(path, "/sys/bus/pci/devices/%s/resource0", name);
if ((fd = open(path, O_RDWR | O_SYNC)) < 0) {
fprintf(stderr, "%s: %s: %s\n", prgname, path,
strerror(errno));
return -1;
}
fstat(fd, &stbuf);
dev->mapsize = stbuf.st_size;
dev->mapaddr = mmap(0, stbuf.st_size,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (dev->mapaddr == MAP_FAILED) {
fprintf(stderr, "%s: mmap(%s): %s\n", prgname, path,
strerror(errno));
return -1;
}
return usw_open_device(name, dev);
}
/* Scan PCI space for vendor and device; return number of successes */
static int usw_scan_pci(struct usw_pci_id *id, struct usw_device *arr,
int alen)
{
char path[PATH_MAX];
FILE *f;
struct dirent **namelist;
int i, j, n, ndevs;
unsigned v, d;
n = scandir("/sys/bus/pci/devices", &namelist, 0, 0);
if (n < 0) {
fprintf(stderr, "%s: /sys/bus/pci/devices: %s\n", prgname,
strerror(errno));
return -1;
}
for (i = ndevs = 0; i < n; i++) {
if (namelist[i]->d_name[0] == '.')
continue;
/* check vendor */
sprintf(path, "/sys/bus/pci/devices/%s/vendor",
namelist[i]->d_name);
f = fopen(path, "r");
if (!f) {
fprintf(stderr, "%s: %s: %s\n", prgname, path,
strerror(errno));
continue;
}
if (fscanf(f, "%i", &v) != 1)
continue;
fclose(f);
/* check device */
sprintf(path, "/sys/bus/pci/devices/%s/device",
namelist[i]->d_name);
f = fopen(path, "r");
if (!f) {
fprintf(stderr, "%s: %s: %s\n", prgname, path,
strerror(errno));
continue;
}
if (fscanf(f, "%i", &d) != 1)
continue;
fclose(f);
for (j = 0; id[j].pci_v; j++)
if (id[j].pci_v == v && id[j].pci_d == d)
break;
if (!spec_devices[j].pci_v)
continue; /* not found in whole array */
/* Ok, so this is ours. Celebrate, and open it */
fprintf(stderr, "%s: found device %04x:%04x: %s\n", prgname,
v, d, namelist[i]->d_name);
if (ndevs == alen) {
fprintf(stderr, "%s: array overflow, ignoring card\n",
prgname);
continue;
}
if (usw_access_pci(namelist[i]->d_name, ndevs))
continue;
ndevs++;
}
return ndevs;
}
/* Low-level shmem uart: output if outc >= 0; return -1 or input char */
static int usw_ll(struct usw_device *dev, int outc)
{
struct wrc_uart_sw local_uart;
uint32_t *ptr = (void *)&local_uart;
uint32_t *hwptr = (void *)dev->p;
int i, n, pos;
if (outc >= 0) {
/* FIXME: output */
}
/* The shmem is word-mapped but big-endian. So convert (inefficient) */
for (i = 0; i < sizeof(local_uart) / sizeof(*ptr); i++)
ptr[i] = ntohl(hwptr[i]);
if (outc >= 0) {
/* This is horrible, because of dual endian conversions */
n = ntohs(local_uart.nread) % CONFIG_UART_SW_RSIZE;
local_uart.rbuffer[n] = outc;
pos = (offsetof(struct wrc_uart_sw, rbuffer) + n) / 4;
hwptr[pos] = htonl(ptr[pos]);
local_uart.nread = htons(ntohs(local_uart.nread) + 1);
pos = offsetof(struct wrc_uart_sw, nread) / 4;
hwptr[pos] = htonl(ptr[pos]);
}
if (ntohs(local_uart.nwritten) < dev->nreturned)
dev->nreturned = 0; /* reloaded */
if (ntohs(local_uart.nwritten) > dev->nreturned) {
i = dev->nreturned % CONFIG_UART_SW_WSIZE;
i = local_uart.wbuffer[i];
dev->nreturned++;
return i;
}
return -1;
}
/* read/write the file descriptor, polling the low-level uart */
static int usw_do_io(struct usw_device *dev, int ready)
{
unsigned char buf[1]; /* oh so tiny */
int char_i, char_o;
char_o = -1;
if (ready) {
if (read(dev->fd, buf, 1) != 1)
/* error */;
char_o = buf[0];
}
while ((char_i = usw_ll(dev, char_o)) >= 0) {
buf[0] = char_i;
write(dev->fd, buf, 1);
char_o = -1;
}
return 0;
}
int main(int argc, char **argv)
{
int maxfd, ndev, i;
struct timeval tv = {0,};
fd_set set, fullset;
prgname = argv[0];
/* FIXME: parse commandline arguments */
ndev = usw_scan_pci(spec_devices, devs, MAX_DEVICES);
if (ndev < 1) {
fprintf(stderr, "%s: no suitable PCI devices\n", argv[0]);
exit(1);
}
FD_ZERO(&fullset);
maxfd = 0;
for (i = 0; i < ndev; i++) {
FD_SET(devs[i].fd, &fullset);
if (devs[i].fd > maxfd)
maxfd = devs[i].fd;
}
while (1) {
set = fullset;
tv.tv_usec = 50 * 1000;
i = select(maxfd + 1, &set, NULL, NULL, &tv);
if (i < 0)
continue;
for (i = 0; i < ndev; i++)
usw_do_io(devs + i, FD_ISSET(devs[i].fd, &set));
}
}
/**
* Author: Federico Vaga <federico.vaga@cern.ch>
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <unistd.h>
#include <termios.h>
#include <getopt.h>
#include <errno.h>
#include <hw/wb_uart.h>
#include <libdevmap.h>
static void wrpc_vuart_help(char *prog)
{
const char *mapping_help_str;
mapping_help_str = dev_mapping_help();
fprintf(stderr, "%s [options]\n", prog);
fprintf(stderr, "%s\n", mapping_help_str);
fprintf(stderr, "Vuart specific option: [-k(keep terminal)]\n");
}
/**
* It receives a single byte
* @param[in] vuart token from dev_map()
*
*
*/
static int8_t wr_vuart_rx(struct mapping_desc *vuart)
{
int rdr = ((volatile struct UART_WB *)vuart->base)->HOST_RDR;
if (vuart->is_be)
rdr = ntohl(rdr);
return (rdr & UART_HOST_RDR_RDY) ? UART_HOST_RDR_DATA_R(rdr) : -1;
}
/**
* It transmits a single byte
* @param[in] vuart token from dev_map()
*/
static void wr_vuart_tx(struct mapping_desc *vuart, char data)
{
volatile struct UART_WB *ptr = (volatile struct UART_WB *)vuart->base;
int sr = (vuart->is_be) ? ntohl(ptr->SR) : ptr->SR;
uint32_t val;
while(sr & UART_SR_RX_RDY)
sr = (vuart->is_be) ? ntohl(ptr->SR) : ptr->SR;
val = (vuart->is_be) ? htonl(UART_HOST_TDR_DATA_W(data)) :
UART_HOST_TDR_DATA_W(data);
ptr->HOST_TDR = val;
}
/**
* It reads a number of bytes and it stores them in a given buffer
* @param[in] vuart token from dev_map()
* @param[out] buf destination for read bytes
* @param[in] size numeber of bytes to read
*
* @return the number of read bytes
*/
static size_t wr_vuart_read(struct mapping_desc *vuart, char *buf, size_t size)
{
size_t s = size, n_rx = 0;
int8_t c;
while(s--) {
c = wr_vuart_rx(vuart);
if(c < 0)
return n_rx;
*buf++ = c;
n_rx ++;
}
return n_rx;
}
/**
* It writes a number of bytes from a given buffer
* @param[in] vuart token from dev_map()
* @param[in] buf buffer to write
* @param[in] size numeber of bytes to write
*
* @return the number of written bytes
*/
static size_t wr_vuart_write(struct mapping_desc *vuart, char *buf, size_t size)
{
size_t s = size;
while(s--)
wr_vuart_tx(vuart, *buf++);
return size;
}
static void wrpc_vuart_term_main(struct mapping_desc *vuart, int keep_term)
{
struct termios oldkey, newkey;
//above is place for old and new port settings for keyboard teletype
int need_exit = 0;
fd_set fds;
int ret;
char rx, tx;
fprintf(stderr, "[press C-a to exit]\n");
if(!keep_term) {
tcgetattr(STDIN_FILENO,&oldkey);
newkey.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
newkey.c_iflag = IGNPAR;
newkey.c_oflag = 0;
newkey.c_lflag = 0;
newkey.c_cc[VMIN]=1;
newkey.c_cc[VTIME]=0;
tcflush(STDIN_FILENO, TCIFLUSH);
tcsetattr(STDIN_FILENO,TCSANOW,&newkey);
}
while(!need_exit) {
struct timeval tv = {0, 10000};
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
/*
* Check if the STDIN has characters to read
* (what the user writes)
*/
ret = select(STDIN_FILENO + 1, &fds, NULL, NULL, &tv);
switch (ret) {
case -1:
perror("select");
break;
case 0: /* timeout */
break;
default:
if(!FD_ISSET(STDIN_FILENO, &fds))
break;
/* The user wrote something */
do {
ret = read(STDIN_FILENO, &tx, 1);
} while (ret < 0 && errno == EINTR);
if (ret != 1) {
fprintf(stderr, "nothing to read. Port disconnected?\n");
need_exit = 1; /* kill */
}
/* If the user character is C-a, then kill */
if(tx == '\x01')
need_exit = 1;
ret = wr_vuart_write(vuart, &tx, 1);
if (ret != 1) {
fprintf(stderr, "Unable to write (errno: %d)\n", errno);
need_exit = 1;
}
break;
}
/* Print all the incoming charactes */
while((wr_vuart_read(vuart, &rx, 1)) == 1)
fprintf(stderr,"%c", rx);
}
if(!keep_term)
tcsetattr(STDIN_FILENO, TCSANOW, &oldkey);
}
int main(int argc, char *argv[])
{
char c;
int keep_term = 0;
struct mapping_args *map_args;
struct mapping_desc *vuart = NULL;
map_args = dev_parse_mapping_args(argc, argv);
if (!map_args) {
wrpc_vuart_help(argv[0]);
goto out;
}
/* Parse specific args */
while ((c = getopt (argc, argv, "k")) != -1) {
switch (c) {
case 'k':
keep_term = 1;
break;
case 'h':
wrpc_vuart_help(argv[0]);
break;
case '?':
break;
}
}
vuart = dev_map(map_args, sizeof(struct UART_WB));
if (!vuart) {
fprintf(stderr, "%s: vuart_open() failed: %s\n", argv[0],
strerror(errno));
goto out;
}
wrpc_vuart_term_main(vuart, keep_term);
dev_unmap(vuart);
return 0;
out:
return -1;
}
......@@ -35,27 +35,35 @@
#include "wrc_ptp.h"
#include "system_checks.h"
#ifndef CONFIG_DEFAULT_PRINT_TASK_TIME_THRESHOLD
#define CONFIG_DEFAULT_PRINT_TASK_TIME_THRESHOLD 0
#endif
int wrc_ui_mode = UI_SHELL_MODE;
int wrc_ui_refperiod = TICS_PER_SECOND; /* 1 sec */
int wrc_phase_tracking = 1;
char wrc_hw_name[HW_NAME_LENGTH];
uint32_t cal_phase_transition = 2389;
int wrc_vlan_number = CONFIG_VLAN_NR;
static uint32_t prev_nanos_for_profile;
static uint32_t prev_ticks_for_profile;
uint32_t print_task_time_threshold = CONFIG_DEFAULT_PRINT_TASK_TIME_THRESHOLD;
static void wrc_initialize(void)
{
uint8_t mac_addr[6];
sdb_find_devices();
uart_init_sw();
uart_init_hw();
pp_printf("WR Core: starting up...\n");
timer_init(1);
get_hw_name(wrc_hw_name);
storage_read_hdl_cfg();
wrpc_w1_init();
wrpc_w1_bus.detail = ONEWIRE_PORT;
w1_scan_bus(&wrpc_w1_bus);
......@@ -69,12 +77,12 @@ static void wrc_initialize(void)
if (get_persistent_mac(ONEWIRE_PORT, mac_addr) == -1) {
pp_printf("Unable to determine MAC address\n");
mac_addr[0] = 0x22; //
mac_addr[1] = 0x33; //
mac_addr[2] = 0x44; // fallback MAC if get_persistent_mac fails
mac_addr[3] = 0x55; //
mac_addr[4] = 0x66; //
mac_addr[5] = 0x77; //
mac_addr[0] = 0x22; /*
mac_addr[1] = 0x33; *
mac_addr[2] = 0x44; * fallback MAC if get_persistent_mac fails
mac_addr[3] = 0x55; *
mac_addr[4] = 0x66; *
mac_addr[5] = 0x77; */
}
pp_printf("Local MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
......@@ -92,7 +100,7 @@ static void wrc_initialize(void)
minic_init();
shw_pps_gen_init();
wrc_ptp_init();
//try reading t24 phase transition from EEPROM
/* try reading t24 phase transition from EEPROM */
calib_t24p(WRC_MODE_MASTER, &cal_phase_transition);
spll_very_init();
usleep_init();
......@@ -104,6 +112,8 @@ static void wrc_initialize(void)
wrc_ptp_set_mode(WRC_MODE_SLAVE);
wrc_ptp_start();
shw_pps_gen_get_time(NULL, &prev_nanos_for_profile);
/* get tics */
prev_ticks_for_profile = timer_get_tics();
}
DEFINE_WRC_TASK0(idle) = {
......@@ -168,7 +178,6 @@ void init_hw_after_reset(void)
{
/* Ok, now init the devices so we can printf and delay */
sdb_find_devices();
uart_init_sw();
uart_init_hw();
timer_init(1);
}
......@@ -215,25 +224,54 @@ DEFINE_WRC_TASK(spll) = {
.job = spll_update,
};
static void task_time_normalize(struct wrc_task *t)
{
if (t->nanos > 1000 * 1000 * 1000) {
t->nanos -= 1000 * 1000 * 1000;
t->seconds++;
}
}
/* Account the time to either this task or task 0 */
static void account_task(struct wrc_task *t, int done_sth)
{
uint32_t nanos;
signed int delta;
uint32_t ticks;
signed int delta_ticks;
if (!done_sth)
t = __task_begin; /* task 0 is special */
shw_pps_gen_get_time(NULL, &nanos);
/* get monotonic number of ticks */
ticks = timer_get_tics();
delta = nanos - prev_nanos_for_profile;
if (delta < 0)
delta += 1000 * 1000 * 1000;
t->nanos += delta;
if (t-> nanos > 1000 * 1000 * 1000) {
t->nanos -= 1000 * 1000 * 1000;
t->seconds++;
}
task_time_normalize(t);
prev_nanos_for_profile = nanos;
delta_ticks = ticks - prev_ticks_for_profile;
if (delta_ticks < 0)
delta_ticks += TICS_PER_SECOND;
if (t->max_run_ticks < delta_ticks) {/* update max_run_ticks */
if (print_task_time_threshold) {
/* Print only if threshold is set */
pp_printf("New max run time for a task %s, old %ld, "
"new %d\n",
t->name, t->max_run_ticks, delta_ticks);
}
t->max_run_ticks = delta_ticks;
}
if (print_task_time_threshold
&& delta_ticks > print_task_time_threshold)
pp_printf("task %s, run for %d ms\n", t->name, delta_ticks);
prev_ticks_for_profile = ticks;
}
/* Run a task with profiling */
......
......@@ -77,7 +77,22 @@ static void wrc_sim_initialize(void)
{
uint8_t mac_addr[6];
sdb_find_devices();
// Search SDB for devices takes too long, hard-coded offsets
// should work for most WR-PTP core implementations
// (unless you add/remove/move peripherals), in which case
// you should comment out all the hard-coded offsets and
// uncomment the following line to perform a dynamic search
// at runtime.
//sdb_find_devices();
BASE_MINIC = (void *)0x20000;
BASE_EP = (void *)0x20100;
BASE_SOFTPLL = (void *)0x20200;
BASE_PPS_GEN = (void *)0x20300;
BASE_SYSCON = (void *)0x20400;
BASE_UART = (void *)0x20500;
BASE_ONEWIRE = (void *)0x20600;
BASE_ETHERBONE_CFG = (void *)0x20700;
timer_init(1);
/* Source MAC used by WRPC's Endpoint */
......
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