Commit 0f601eff authored by hongming's avatar hongming

Merge branch 'master' into cute-core-thu

Conflicts:
	lib/ipv4.c
	tools/pfilter-builder.c
	wrc_main.c
parents eaaa9943 b5e318d8
......@@ -16,4 +16,3 @@
.config.old
include/config
include/generated
.depend
......@@ -26,6 +26,56 @@ config RAMSIZE
default 65536 if WR_SWITCH
default 131072
config TEMP_POLL_INTERVAL
int
default 15
config PLL_VERBOSE
boolean
default y if WR_SWITCH
config PFILTER_VERBOSE
boolean
config WRC_VERBOSE
boolean
default y if WR_SWITCH
config VLAN
boolean
config VLAN_NR
int
default 10 if VLAN
default 0
config VLAN_1_FOR_CLASS7
int
default 20 if VLAN
default 0
config VLAN_2_FOR_CLASS7
int
default 30 if VLAN
default 0
config VLAN_FOR_CLASS6
int
default 100 if VLAN
default 0
config HOST_PROCESS
boolean
default n
config LM32
boolean
default !HOST_PROCESS
config EMBEDDED_NODE
boolean
default LM32 && WR_NODE
# CONFIG_WR_SWITCH has no further options at all at this point
config WR_NODE_PCS16
......@@ -47,33 +97,28 @@ config PPSI
default y
config UART
depends on WR_NODE
boolean
default y
default y if EMBEDDED_NODE
default n
config W1
depends on WR_NODE
depends on EMBEDDED_NODE
boolean
default y
config LATENCY_ETHTYPE
int
default 0
# The other ones can be set by non-developers
config ETHERBONE
config IP
depends on WR_NODE
boolean "Compile Etherbone support in wrpc-sw"
boolean "Compile minimal IP support in wrpc-sw"
help
This allows to run LM32 code that is aware of Etherbone.
You need to run a gateware file that includes Etherbone support.
If in doubt, say No.
config WRNIC
depends on WR_NODE
boolean "Compile White Rabbit NIC support in wrpc-sw"
help
This allows to run LM32 code that is aware of Etherbone and
NIC. You need to run a gateware file that includes Etherbone
and NIC support. This option needs ETHERBONE enabled.
If in doubt, say No.
This allows to run LM32 code that is aware of IP. The feature is
needed to run Etherbone in your gateware, because Etherbone
is UDP-based and thus the CPU needs to run DHCP.
config CMD_CONFIG
depends on WR_NODE
......@@ -83,16 +128,60 @@ config CMD_CONFIG
reports the current configuration. This adds half a kilobyte
to the binary size (100b for the code plus the .config file).
config NIC_PFILTER
depends on WR_NODE
depends on ETHERBONE
bool "Add packet filter rules for wr-nic"
config SYSLOG
depends on IP
boolean "Include syslog client support"
help
When using wr-nic, the host must receive frames that are not
ptp nor etherbone ones. This adds the needed filter rules
to that effect. Such rules are not needed when no Etherbone
is there, because in that case all non-ptp frames reach the
host.
This enable a UDP syslog client, configured by a shell command.
The user (or init script) must use "syslog <ipaddr> <macaddr>"
to enable it. The special "off" ipaddr disables syslog.
config SNMP
depends on IP
default y
boolean "Mini SNMP responder"
config SNMP_SET
depends on SNMP
default y
boolean "Add SET support to the Mini SNMP responder"
help
This option enables support for SET requests for Mini SNMP responder
config SNMP_HW_TYPE
depends on SNMP
default "spec"
string "Hardware type reported by SNMP"
config BUILD_INIT
depends on WR_NODE
default n
boolean "Include an init command in the binary (build-time)"
config INIT_COMMAND
depends on BUILD_INIT
string "Enter the init command, use ';' as command separator"
default ""
config INIT_COMMAND
string
default ""
# The following two integer values are derived, and used in if() (shell.c)
config HAS_BUILD_INIT
int
default 1 if BUILD_INIT
default 0
config HAS_FLASH_INIT
int
default 1 if FLASH_INIT
default 0
config FLASH_INIT
boolean
default y if EMBEDDED_NODE
default n
#
# This is a set of configuration options that should not be changed by
......@@ -107,8 +196,12 @@ config DEVELOPER
directly working on this package. Please don't use unless
you are a developer of wrpc-sw.
config RAMSIZE
config HOST_PROCESS
depends on DEVELOPER && WR_NODE
boolean "Build as a host process, to develop/debug network"
config RAMSIZE
depends on DEVELOPER && EMBEDDED_NODE
int "Size of the RAM in the FPGA for this program"
default 90112
help
......@@ -118,7 +211,7 @@ config RAMSIZE
choose your preferred value here.
config STACKSIZE
depends on DEVELOPER && WR_NODE
depends on DEVELOPER && EMBEDDED_NODE
int "Size of the stack area needed by this program"
default 2048
help
......@@ -135,8 +228,22 @@ config PRINT_BUFSIZE
also constraints the maximum lenght of text that can be written
in a single call to printf.
config CMD_LL
config TEMP_POLL_INTERVAL
depends on DEVELOPER && WR_NODE
int "Poll interval, in seconds, for temperature sensors"
config TEMP_HIGH_THRESHOLD
depends on DEVELOPER && WR_NODE && SYSLOG
default 70
int "Threshold for temperature: tell syslog if higher"
config TEMP_HIGH_RAPPEL
depends on DEVELOPER && WR_NODE && SYSLOG
default 60
int "Remember over-temperature every that many seconds"
config CMD_LL
depends on DEVELOPER && EMBEDDED_NODE
bool "Build low-level commands for development/testing"
help
This enables low-level commands: "devmem" to read/write memory
......@@ -145,9 +252,14 @@ config CMD_LL
on the master, because they are just sent to the slave
during the initial handshake
config FLASH_INIT
depends on DEVELOPER && EMBEDDED_NODE
default y
boolean "Read init commands from flash storage"
# CHECK_RESET for switch and node
config CHECK_RESET
depends on DEVELOPER
depends on DEVELOPER && !HOST_PROCESS
bool "Print a stack trace if reset happens"
help
If the CPU is following a NULL pointer, the program will
......@@ -155,6 +267,15 @@ config CHECK_RESET
detects that it is re-executed and dumps a stack trace; it
then clears the stack (for next time) and restarts again.
config SPLL_FIFO_LOG
depends on DEVELOPER && !HOST_PROCESS
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
the DDMTD tags read from the fifos, the interrupts and the
related timing. The information is shown by tools/wrpc-dump
if present, no change/rebuild of the tool is needed.
choice
prompt "Implementation of pp_printf"
depends on DEVELOPER && WR_NODE
......@@ -198,7 +319,7 @@ config PPSI
Select this option for the ppsi engine (now only option)
config DETERMINISTIC_BINARY
depends on DEVELOPER && WR_NODE
depends on DEVELOPER && EMBEDDED_NODE
boolean "Build a binary that is the same every time"
help
This option is used to #ifdef __DATE__ and __TIME__ strings
......@@ -212,15 +333,14 @@ config DETERMINISTIC_BINARY
config UART
boolean "Use hardware uart (and/or vuart if available)"
depends on DEVELOPER && WR_NODE
default y
depends on DEVELOPER && EMBEDDED_NODE
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 && WR_NODE
depends on DEVELOPER && EMBEDDED_NODE
default !UART
boolean "Use software uart"
help
......@@ -230,6 +350,66 @@ config UART_SW
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
boolean "Extra verbose messages for networking"
help
This is mainly a debug tool, to be left off unless you hack
in the network subsystem.
config PLL_VERBOSE
depends on DEVELOPER
boolean "Verbose messages in softpll"
help
The softpll is usually silent in WR node and verbose in WR
switch. You can enable pll messages in WR node for debugging.
config PFILTER_VERBOSE
depends on DEVELOPER
boolean "Verbose messages in packet filter setup"
help
A debug tool for people changing the packet filter rules
config WRC_VERBOSE
depends on DEVELOPER
boolean "More verbose messages in wr core"
default y if WR_SWITCH
help
This enables some more diagnostic messages. Normally off.
config SNMP_VERBOSE
depends on DEVELOPER && SNMP
boolean "More verbose messages in SNMP"
help
This enables some more diagnostic messages. Normally off.
config FAKE_TEMPERATURES
depends on DEVELOPER
boolean "Offer an array of 3 fake temperatures, for testing"
help
The option adds also a "faketemp" command, used to set
the fake temperatures: e.g. "faketemp 120 -10 50"
config VLAN
depends on DEVELOPER
boolean "Filter and rx/tx frames in a VLAN (as opposed to untagged)"
config VLAN_NR
depends on VLAN
int "Use this VLAN number for filter/tx/rx"
config VLAN_1_FOR_CLASS7
depends on VLAN
int "Route this VLAN to fabric class 7 (Etherbone)"
config VLAN_2_FOR_CLASS7
depends on VLAN
int "Route this VLAN too to fabric class 7 (Etherbone)"
config VLAN_FOR_CLASS6
depends on VLAN
int "Route this VLAN too to fabric class 6 (Streamer/NIC)"
config SDB_STORAGE
depends on WR_NODE
default y
......@@ -243,6 +423,21 @@ config LEGACY_EEPROM
boolean
default !SDB_STORAGE
config LATENCY_PROBE
depends on DEVELOPER
bool "Build the latency probe mechanism (send/recv)"
help
The latency prober sends two frames to broadcast and
then the timestamp of their departure time. The receiver
measures the network latency and reports it.
If this option is set, the receiver is always running. The
sender is built but must be activated by the latency shell cmd.
config LATENCY_ETHTYPE
depends on LATENCY_PROBE
int "Ethtype to use for latency probing"
# This is needed to size the pp_instance data strucuture. Instead of
# including the ppsi autoconf.h, with duplicate definitions, define it
# here, as we know what the value is
......
......@@ -4,7 +4,7 @@
T=$(mktemp /tmp/wrpc-config.XXXXXX)
configs=$(ls configs)
configs=$(cd configs; echo *_defconfig)
if [ $# -ne 0 ]; then
configs="$*"
fi
......
# Tomasz Wlostowski for CERN, 2011,2012
-include $(CURDIR)/.config
CROSS_COMPILE ?= lm32-elf-
ifdef CONFIG_HOST_PROCESS
CROSS_COMPILE =
endif
export CROSS_COMPILE
CC = $(CROSS_COMPILE)gcc
......@@ -9,56 +15,60 @@ OBJDUMP = $(CROSS_COMPILE)objdump
OBJCOPY = $(CROSS_COMPILE)objcopy
SIZE = $(CROSS_COMPILE)size
-include $(CURDIR)/.config
AUTOCONF = $(CURDIR)/include/generated/autoconf.h
PPSI = ppsi
# we miss CONFIG_ARCH_LM32 as we have no other archs by now
obj-y = arch/lm32/crt0.o arch/lm32/irq.o
obj-$(CONFIG_LM32) = arch/lm32/crt0.o arch/lm32/irq.o
LDS-$(CONFIG_WR_NODE) = arch/lm32/ram.ld
LDS-$(CONFIG_WR_SWITCH) = arch/lm32/ram-wrs.ld
LDS-$(CONFIG_HOST_PROCESS) =
obj-$(CONFIG_WR_NODE) += wrc_main.o
obj-$(CONFIG_WR_SWITCH) += wrs_main.o
obj-$(CONFIG_WR_SWITCH) += ipc/minipc-mem-server.o ipc/rt_ipc.o
obj-y += dump-info.o
# our linker script is preprocessed, so have a rule here
%.ld: %.ld.S $(AUTOCONF) .config
$(CC) -include $(AUTOCONF) -E -P $*.ld.S -o $@
cflags-y = -ffreestanding -include $(AUTOCONF) -Iinclude/std -Iinclude \
cflags-y = -ffreestanding -include $(AUTOCONF) -Iinclude \
-I. -Isoftpll -Iipc
cflags-y += -I$(CURDIR)/pp_printf
cflags-$(CONFIG_LM32) += -Iinclude/std
cflags-$(CONFIG_PPSI) += \
-ffreestanding \
-include include/ppsi-wrappers.h \
-Iinclude \
-I$(PPSI)/include \
-I$(PPSI)/arch-wrpc \
-I$(PPSI)/arch-wrpc/include \
-I$(PPSI)/proto-ext-whiterabbit \
-Iboards/spec
obj-ppsi = \
$(PPSI)/ppsi.o
# in order to build tools/wrpc-dump, we need these flags, even for wrs builds
cflags-y += \
-I$(PPSI)/arch-wrpc/include \
-I$(PPSI)/include
obj-ppsi = $(PPSI)/ppsi.o
obj-$(CONFIG_PPSI) += $(obj-ppsi)
obj-$(CONFIG_PPSI) += \
# Below, CONFIG_PPSI is wrong, as we can't build these for the host
obj-$(CONFIG_EMBEDDED_NODE) += \
monitor/monitor_ppsi.o \
lib/ppsi-wrappers.o \
$(obj-ppsi)
lib/ppsi-wrappers.o
CFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled
LDFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled \
cflags-$(CONFIG_LM32) += -mmultiply-enabled -mbarrel-shift-enabled
ldflags-$(CONFIG_LM32) = -mmultiply-enabled -mbarrel-shift-enabled \
-nostdlib -T $(LDS-y)
arch-files-$(CONFIG_LM32) = $(OUTPUT).ram $(OUTPUT).vhd $(OUTPUT).mif
# packet-filter rules depend on configuration; default is rules-plain
pfilter-y := rules-plain.bin
pfilter-$(CONFIG_ETHERBONE) := rules-ebone.bin
pfilter-$(CONFIG_NIC_PFILTER) := rules-e+nic.bin
# packet-filter rules: for CONFIG_VLAN we use both sets
pfilter-y := rules-novlan.bin
pfilter-$(CONFIG_VLAN) += rules-vlan.bin
export pfilter-y
all:
......@@ -68,15 +78,14 @@ include lib/lib.mk
include pp_printf/printf.mk
include dev/dev.mk
include softpll/softpll.mk
include host/host.mk
# ppsi already has div64 (the same one), so only pick it if not using ppsi.
ifndef CONFIG_PPSI
obj-y += pp_printf/div64.o
# unfortunately, we need a prototype therex
cflags-y += -include include/wrc.h
endif
# And always complain if we pick the libgcc division: 64/32 = 32 is enough here.
obj-y += check-error.o
obj-$(CONFIG_LM32) += check-error.o
# add system check functions like stack overflow and check reset
obj-y += system_checks.o
......@@ -85,13 +94,15 @@ obj-y += system_checks.o
obj-$(CONFIG_WR_NODE) += sdb-lib/libsdbfs.a
cflags-$(CONFIG_WR_NODE) += -Isdb-lib
CFLAGS = $(CFLAGS_PLATFORM) $(cflags-y) -Wall -Wstrict-prototypes \
CFLAGS = $(cflags-y) -Wall -Wstrict-prototypes \
-ffunction-sections -fdata-sections -Os -Wmissing-prototypes \
-include include/trace.h -ggdb
-include include/wrc.h -ggdb
LDFLAGS = $(LDFLAGS_PLATFORM) \
LDFLAGS = $(ldflags-y) \
-Wl,--gc-sections -Os -lgcc -lc
WRC-O-FLAGS-$(CONFIG_LM32) = --gc-sections -e _start
OBJS = $(obj-y)
OUTPUT-$(CONFIG_WR_NODE) = wrc
......@@ -99,8 +110,14 @@ OUTPUT-$(CONFIG_WR_SWITCH) = rt_cpu
OUTPUT := $(OUTPUT-y)
GIT_VER = $(shell git describe --always --dirty | sed 's;^wr-switch-sw-;;')
GIT_USR = $(shell git config --get-all user.name)
# if user.name is not available from git use user@hostname
ifeq ($(GIT_USR),)
GIT_USR = $(shell whoami)@$(shell hostname)
endif
all: tools $(OUTPUT).ram $(OUTPUT).vhd $(OUTPUT).mif
all: tools $(OUTPUT).elf $(arch-files-y)
.PRECIOUS: %.elf %.bin
.PHONY: all tools clean gitmodules $(PPSI)/ppsi.o
......@@ -108,35 +125,42 @@ all: tools $(OUTPUT).ram $(OUTPUT).vhd $(OUTPUT).mif
# we need to remove "ptpdump" support for ppsi if RAM size is small and
# we include etherbone
ifneq ($(CONFIG_RAMSIZE),131072)
ifdef CONFIG_ETHERBONE
ifdef CONFIG_IP
PPSI_USER_CFLAGS = -DCONFIG_NO_PTPDUMP
endif
endif
PPSI_USER_CFLAGS += -DDIAG_PUTS=uart_sw_write_string
PPSI-CFG-y = wrpc_defconfig
PPSI-CFG-$(CONFIG_HOST_PROCESS) = unix_defconfig
PPSI-FLAGS-$(CONFIG_LM32) = CONFIG_NO_PRINTF=y
$(obj-ppsi):
test -f $(PPSI)/.config || $(MAKE) -C $(PPSI) wrpc_defconfig
$(MAKE) -C $(PPSI) WRPCSW_ROOT=.. \
CROSS_COMPILE=$(CROSS_COMPILE) CONFIG_NO_PRINTF=y \
test -f $(PPSI)/.config || $(MAKE) -C $(PPSI) $(PPSI-CFG-y)
$(MAKE) -C $(PPSI) ppsi.o WRPCSW_ROOT=.. \
CROSS_COMPILE=$(CROSS_COMPILE) CONFIG_NO_PRINTF=y
USER_CFLAGS="$(PPSI_USER_CFLAGS)"
sdb-lib/libsdbfs.a:
$(MAKE) -C sdb-lib
$(OUTPUT).elf: $(LDS-y) $(AUTOCONF) gitmodules $(OUTPUT).o config.o
$(CC) $(CFLAGS) -D__GIT_VER__="\"$(GIT_VER)\"" -c revision.c
$(CC) $(CFLAGS) -D__GIT_VER__="\"$(GIT_VER)\"" -D__GIT_USR__="\"$(GIT_USR)\"" -c revision.c
${CC} -o $@ revision.o config.o $(OUTPUT).o $(LDFLAGS)
${OBJDUMP} -d $(OUTPUT).elf > $(OUTPUT)_disasm.S
$(SIZE) $@
$(OUTPUT).o: $(OBJS)
$(LD) --gc-sections -e _start -r $(OBJS) -T bigobj.lds -o $@
$(LD) $(WRC-O-FLAGS-y) -r $(OBJS) -T bigobj.lds -o $@
OBJCOPY-TARGET-$(CONFIG_LM32) = -O elf32-lm32 -B lm32
OBJCOPY-TARGET-$(CONFIG_HOST_PROCESS) = -O elf64-x86-64 -B i386
config.o: .config
sed '1,3d' .config > .config.bin
dd bs=1 count=1 if=/dev/zero 2> /dev/null >> .config.bin
$(OBJCOPY) -I binary -O elf32-lm32 -B lm32 \
$(OBJCOPY) -I binary $(OBJCOPY-TARGET-y) \
--rename-section .data=.data.config .config.bin $@
rm -f .config.bin
......@@ -156,7 +180,7 @@ $(AUTOCONF): silentoldconfig
clean:
rm -f $(OBJS) $(OUTPUT).elf $(OUTPUT).bin $(OUTPUT).ram \
$(LDS) rules-*.bin .depend
$(LDS) rules-*.bin
$(MAKE) -C $(PPSI) clean
$(MAKE) -C sdb-lib clean
$(MAKE) -C tools clean
......@@ -164,7 +188,7 @@ clean:
%.o: %.c
${CC} $(CFLAGS) $(PTPD_CFLAGS) $(INCLUDE_DIR) $(LIB_DIR) -c $*.c -o $@
tools:
tools: .config
$(MAKE) -C tools
# if needed, check out the submodules (first time only), so users
......@@ -177,22 +201,20 @@ gitmodules:
# following targets from Makefile.kconfig
silentoldconfig:
@mkdir -p include/config
$(MAKE) -f Makefile.kconfig $@
$(MAKE) quiet=quiet_ -f Makefile.kconfig $@
scripts_basic config:
$(MAKE) -f Makefile.kconfig $@
$(MAKE) quiet=quiet_ -f Makefile.kconfig $@
%config:
$(MAKE) -f Makefile.kconfig $@
$(MAKE) quiet=quiet_ -f Makefile.kconfig $@
defconfig:
$(MAKE) -f Makefile.kconfig spec_defconfig
$(MAKE) quiet=quiet_ -f Makefile.kconfig spec_defconfig
.config: silentoldconfig
# Trivial depend rule. We can't $(obj-y:.o=.c) because some objects come from
# assembly source. In glob avoid the toold directory, and ppsi/pp-printf
.depend: $(wildcard *.c [^pt]/*.c)
$(CC) $(CFLAGS) -DSDBFS_BIG_ENDIAN -MM $^ > $@
-include .depend
# This forces more compilations than needed, but it's useful
# (we depend on .config and not on include/generated/autoconf.h
# because the latter is touched by silentoldconfig at each build)
$(obj-y): .config $(wildcard include/*.h)
This diff is collapsed.
......@@ -84,5 +84,9 @@ SECTIONS
/* First location in stack is highest address in RAM (stack area) */
PROVIDE(_fstack = ORIGIN(stack) + LENGTH(stack) - 4);
/* We have no ppi_static nor fifo_log in wrs builds */
PROVIDE(ppi_static = 0);
PROVIDE(fifo_log = 0);
}
......@@ -64,4 +64,11 @@ SECTIONS
/* First location in stack is highest address in STACK */
PROVIDE(_fstack = ORIGIN(stack) + LENGTH(stack) - 4);
/* This may be missing, according to .config */
PROVIDE(fifo_log = 0);
/* A vlan rule-set may be missing (if no CONFIG_VLAN) */
PROVIDE(_binary_rules_vlan_bin_start = 0);
PROVIDE(_binary_rules_vlan_bin_end = 0);
}
......@@ -10,4 +10,15 @@ SECTIONS
KEEP(*(.cmd))
__cmd_end = .;
}
.temp : {
__temp_begin = .;
KEEP(*(.temp))
__temp_end = .;
}
.task : {
__task_begin = .;
KEEP(*(.task0))
KEEP(*(.task))
__task_end = .;
}
}
/*
* This work is part of the White Rabbit project
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#ifndef __BOARD_H
#define __BOARD_H
#include <hw/memlayout.h>
/* Board-specific parameters */
/* WR Core system/CPU clock frequency in Hz */
#define CPU_CLOCK 62500000ULL
/* WR Reference clock period (picoseconds) and frequency (Hz) */
#define REF_CLOCK_PERIOD_PS 8000
#define REF_CLOCK_FREQ_HZ 125000000
/* Baud rate of the builtin UART (does not apply to the VUART) */
#define UART_BAUDRATE 115200ULL
/* Maximum number of simultaneously created sockets */
#define NET_MAX_SOCKETS 4
/* Socket buffer size, determines the max. RX packet size */
#define NET_SKBUF_SIZE 512
/* Number of auxillary clock channels - usually equal to the number of FMCs */
#define NUM_AUX_CLOCKS 1
int board_init();
int board_update();
#endif
#
# Automatically generated make config: don't edit
#
# CONFIG_WR_SWITCH is not set
CONFIG_WR_NODE=y
CONFIG_PRINT_BUFSIZE=128
# CONFIG_PRINTF_XINT is not set
CONFIG_RAMSIZE=131072
CONFIG_TEMP_POLL_INTERVAL=15
CONFIG_PLL_VERBOSE=y
CONFIG_PFILTER_VERBOSE=y
CONFIG_WRC_VERBOSE=y
CONFIG_VLAN=y
CONFIG_VLAN_NR=10
CONFIG_VLAN_1_FOR_CLASS7=20
CONFIG_VLAN_2_FOR_CLASS7=30
CONFIG_VLAN_FOR_CLASS6=100
# 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=4455
CONFIG_IP=y
CONFIG_CMD_CONFIG=y
CONFIG_SYSLOG=y
CONFIG_BUILD_INIT=y
CONFIG_INIT_COMMAND="help"
CONFIG_HAS_BUILD_INIT=1
CONFIG_HAS_FLASH_INIT=1
CONFIG_FLASH_INIT=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_CHECK_RESET=y
CONFIG_SPLL_FIFO_LOG=y
CONFIG_PRINTF_FULL=y
# CONFIG_PRINTF_MINI is not set
# CONFIG_PRINTF_NONE is not set
CONFIG_DETERMINISTIC_BINARY=y
CONFIG_UART_SW=y
CONFIG_NET_VERBOSE=y
CONFIG_FAKE_TEMPERATURES=y
CONFIG_SDB_STORAGE=y
# CONFIG_LEGACY_EEPROM is not set
CONFIG_LATENCY_PROBE=y
CONFIG_VLAN_ARRAY_SIZE=1
......@@ -6,24 +6,50 @@ CONFIG_WR_NODE=y
CONFIG_PRINT_BUFSIZE=128
CONFIG_PRINTF_XINT=y
CONFIG_RAMSIZE=131072
CONFIG_TEMP_POLL_INTERVAL=15
# CONFIG_PLL_VERBOSE is not set
# CONFIG_PFILTER_VERBOSE is not set
# CONFIG_WRC_VERBOSE is not set
# 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_HOST_PROCESS is not set
CONFIG_LM32=y
CONFIG_EMBEDDED_NODE=y
# CONFIG_WR_NODE_PCS16 is not set
CONFIG_STACKSIZE=10240
CONFIG_PPSI=y
CONFIG_UART=y
CONFIG_W1=y
CONFIG_ETHERBONE=y
CONFIG_WRNIC=y
CONFIG_LATENCY_ETHTYPE=0
CONFIG_IP=y
CONFIG_CMD_CONFIG=y
CONFIG_NIC_PFILTER=y
CONFIG_SYSLOG=y
# CONFIG_BUILD_INIT is not set
CONFIG_INIT_COMMAND=""
CONFIG_HAS_BUILD_INIT=0
CONFIG_HAS_FLASH_INIT=1
CONFIG_FLASH_INIT=y
#
# wrpc-sw is tainted if you change the following options
#
CONFIG_DEVELOPER=y
# CONFIG_CHECK_RESET is not set
CONFIG_TEMP_HIGH_THRESHOLD=70
CONFIG_TEMP_HIGH_RAPPEL=60
CONFIG_CMD_LL=y
CONFIG_CHECK_RESET=y
# CONFIG_SPLL_FIFO_LOG is not set
# CONFIG_PRINTF_FULL is not set
# CONFIG_PRINTF_MINI is not set
# CONFIG_PRINTF_NONE 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_SDB_STORAGE=y
# CONFIG_LEGACY_EEPROM is not set
CONFIG_LATENCY_PROBE=y
CONFIG_VLAN_ARRAY_SIZE=1
......@@ -4,24 +4,28 @@
# CONFIG_WR_SWITCH is not set
CONFIG_WR_NODE=y
CONFIG_PRINT_BUFSIZE=128
CONFIG_PRINTF_XINT=y
# CONFIG_PRINTF_XINT is not set
CONFIG_RAMSIZE=131072
CONFIG_PLL_VERBOSE=y
CONFIG_WRC_VERBOSE=y
CONFIG_HOST_PROCESS=y
# CONFIG_EMBEDDED_CODE is not set
# CONFIG_EMBEDDED_NODE is not set
# CONFIG_WR_NODE_PCS16 is not set
CONFIG_STACKSIZE=2048
CONFIG_PPSI=y
CONFIG_UART=y
CONFIG_W1=y
# CONFIG_ETHERBONE is not set
# CONFIG_UART is not set
CONFIG_IP=y
CONFIG_CMD_CONFIG=y
#
# wrpc-sw is tainted if you change the following options
#
CONFIG_DEVELOPER=y
# CONFIG_CHECK_RESET is not set
# CONFIG_PRINTF_FULL is not set
CONFIG_PRINTF_FULL=y
# CONFIG_PRINTF_MINI is not set
# CONFIG_PRINTF_NONE is not set
# CONFIG_PTP_NOPOSIX is not set
# CONFIG_DETERMINISTIC_BINARY is not set
CONFIG_UART_SW=y
# CONFIG_SDB_STORAGE is not set
CONFIG_LEGACY_EEPROM=y
CONFIG_NET_VERBOSE=y
CONFIG_SDB_STORAGE=y
# CONFIG_LEGACY_EEPROM is not set
CONFIG_VLAN_ARRAY_SIZE=1
......@@ -9,7 +9,7 @@ CONFIG_STACKSIZE=2048
CONFIG_PPSI=y
CONFIG_UART=y
CONFIG_W1=y
# CONFIG_ETHERBONE is not set
# CONFIG_IP is not set
# CONFIG_CMD_CONFIG is not set
#
......
......@@ -5,15 +5,37 @@
CONFIG_WR_NODE=y
CONFIG_PRINT_BUFSIZE=128
CONFIG_PRINTF_XINT=y
CONFIG_RAMSIZE=131072
CONFIG_TEMP_POLL_INTERVAL=15
CONFIG_VLAN_NR=0
CONFIG_VLAN_1_FOR_CLASS7=0
CONFIG_VLAN_2_FOR_CLASS7=0
CONFIG_VLAN_FOR_CLASS6=0
# 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_ETHERBONE=y
CONFIG_LATENCY_ETHTYPE=0
CONFIG_IP=y
# CONFIG_CMD_CONFIG is not set
# CONFIG_SYSLOG is not set
CONFIG_SNMP=y
# CONFIG_SNMP_SET is not set
CONFIG_SNMP_HW_TYPE="spec"
# CONFIG_BUILD_INIT is not set
CONFIG_INIT_COMMAND=""
CONFIG_HAS_BUILD_INIT=0
CONFIG_HAS_FLASH_INIT=1
CONFIG_FLASH_INIT=y
#
# wrpc-sw is tainted if you change the following options
#
# CONFIG_DEVELOPER is not set
CONFIG_LEGACY_EEPROM=y
CONFIG_SDB_STORAGE=y
# CONFIG_LEGACY_EEPROM is not set
CONFIG_VLAN_ARRAY_SIZE=1
......@@ -5,23 +5,53 @@
CONFIG_WR_NODE=y
CONFIG_PRINT_BUFSIZE=128
CONFIG_PRINTF_XINT=y
CONFIG_RAMSIZE=131072
CONFIG_TEMP_POLL_INTERVAL=15
# CONFIG_PLL_VERBOSE is not set
# CONFIG_PFILTER_VERBOSE is not set
# CONFIG_WRC_VERBOSE is not set
# 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_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_ETHERBONE is not set
CONFIG_LATENCY_ETHTYPE=0
CONFIG_IP=y
# CONFIG_CMD_CONFIG is not set
# CONFIG_SYSLOG is not set
CONFIG_SNMP=y
CONFIG_SNMP_SET=y
CONFIG_SNMP_HW_TYPE="spec"
# CONFIG_BUILD_INIT is not set
CONFIG_INIT_COMMAND=""
CONFIG_HAS_BUILD_INIT=0
CONFIG_HAS_FLASH_INIT=1
CONFIG_FLASH_INIT=y
#
# wrpc-sw is tainted if you change the following options
#
CONFIG_DEVELOPER=y
# CONFIG_CMD_LL is not set
# CONFIG_CHECK_RESET is not set
# CONFIG_SPLL_FIFO_LOG is not set
# CONFIG_PRINTF_FULL is not set
# CONFIG_PRINTF_MINI is not set
# CONFIG_PRINTF_NONE is not set
# CONFIG_PTP_NOPOSIX is not set
# CONFIG_DETERMINISTIC_BINARY is not set
# CONFIG_UART_SW is not set
# CONFIG_SDB_STORAGE is not set
CONFIG_LEGACY_EEPROM=y
# CONFIG_NET_VERBOSE is not set
CONFIG_SNMP_VERBOSE=y
CONFIG_FAKE_TEMPERATURES=y
CONFIG_SDB_STORAGE=y
# CONFIG_LEGACY_EEPROM is not set
# CONFIG_LATENCY_PROBE is not set
CONFIG_VLAN_ARRAY_SIZE=1
......@@ -9,8 +9,7 @@ CONFIG_STACKSIZE=2048
CONFIG_PPSI=y
CONFIG_UART=y
CONFIG_W1=y
CONFIG_ETHERBONE=y
CONFIG_NIC_PFILTER=y
CONFIG_IP=y
# CONFIG_CMD_CONFIG is not set
#
......
......@@ -169,7 +169,7 @@ static int ad9516_set_output_divider(int output, int ratio, int phase_offset)
uint16_t base = ((output - 6) / 2) * 0x5 + 0x199;
TRACE("Output [divider %d]: %d ratio: %d base %x lc %d hc %d\n", secondary, output, ratio, base, lcycles ,hcycles);
pp_printf("Output [divider %d]: %d ratio: %d base %x lc %d hc %d\n", secondary, output, ratio, base, lcycles ,hcycles);
if(!secondary)
{
......@@ -222,7 +222,7 @@ static void ad9516_sync_outputs(void)
int ad9516_init(int scb_version)
{
TRACE("Initializing AD9516 PLL...\n");
pp_printf("Initializing AD9516 PLL...\n");
oc_spi_init((void *)BASE_SPI);
......@@ -239,7 +239,7 @@ int ad9516_init(int scb_version)
/* Check the presence of the chip */
if (ad9516_read_reg(0x3) != 0xc3) {
TRACE("Error: AD9516 PLL not responding.\n");
pp_printf("Error: AD9516 PLL not responding.\n");
return -1;
}
......@@ -279,7 +279,7 @@ int ad9516_init(int scb_version)
ad9516_sync_outputs();
ad9516_set_vco_divider(3);
TRACE("AD9516 locked.\n");
pp_printf("AD9516 locked.\n");
gpio_out(GPIO_SYS_CLK_SEL, 1); /* switch the system clock to the PLL reference */
gpio_out(GPIO_PERIPH_RESET_N, 0); /* reset all peripherals which use AD9516-provided clocks */
......
obj-$(CONFIG_WR_NODE) += \
# 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_EMBEDDED_NODE) += \
dev/endpoint.o \
dev/ep_pfilter.o \
dev/pfilter-rules.o \
dev/i2c.o \
dev/minic.o \
dev/pps_gen.o \
dev/syscon.o \
dev/sfp.o \
dev/devicelist.o \
......@@ -12,6 +13,10 @@ obj-$(CONFIG_WR_NODE) += \
dev/flash.o\
dev/ext_config.o
obj-$(CONFIG_WR_NODE) += \
dev/temperature.o \
dev/pps_gen.o
obj-$(CONFIG_WR_SWITCH) += dev/timer-wrs.o dev/ad9516.o
obj-$(CONFIG_LEGACY_EEPROM) += dev/eeprom.o
......@@ -19,14 +24,19 @@ obj-$(CONFIG_SDB_STORAGE) += dev/sdb-storage.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
# Filter rules are selected according to configuration, see toplevel Makefile,
# but the filename is reflected in symbol names, so use a symlink here.
dev/pfilter-rules.o: $(pfilter-y)
ln -sf $(pfilter-y) rules-pfilter.bin
$(OBJCOPY) -I binary -O elf32-lm32 -B lm32 rules-pfilter.bin $@
obj-$(CONFIG_FAKE_TEMPERATURES) += dev/fake-temp.o
# Filter rules are selected according to configuration, but we may
# have more than one. Note: the filename is reflected in symbol names,
# so they are hardwired in ../Makefile (and ../tools/pfilter-builder too)
obj-y += $(pfilter-y:.bin=.o)
rules-%.o: rules-%.bin
$(OBJCOPY) -I binary $(OBJCOPY-TARGET-y) $< $@
$(pfilter-y): tools/pfilter-builder
$^
......
......@@ -57,6 +57,10 @@
* ------------------------------------------------
*/
#define SFP_DB_EMPTY 0xff
static uint8_t sfpcount = SFP_DB_EMPTY;
uint8_t has_eeprom = 0;
static int i2cif, i2c_addr; /* globals, using the names we always used */
......@@ -137,7 +141,7 @@ static int eeprom_write(uint8_t i2cif, uint8_t i2c_addr, uint32_t offset,
int32_t storage_sfpdb_erase(void)
{
uint8_t sfpcount = 0;
sfpcount = 0;
//just a dummy function that writes '0' to sfp count field of the SFP DB
if (eeprom_write(i2cif, i2c_addr, EE_BASE_SFP, &sfpcount,
......@@ -147,28 +151,44 @@ int32_t storage_sfpdb_erase(void)
return sfpcount;
}
int storage_get_sfp(struct s_sfpinfo * sfp,
uint8_t add, uint8_t pos)
static uint8_t sfp_chksum(uint8_t *ptr)
{
int i;
uint8_t chksum = 0;
/* '-1' because we do not include chksum in computation */
for (i = 0; i < sizeof(struct s_sfpinfo) - 1; ++i)
chksum = (uint8_t) ((uint16_t) chksum + *(ptr++)) & 0xff;
return chksum;
}
int storage_get_sfp(struct s_sfpinfo *sfp, uint8_t oper, uint8_t pos)
{
static uint8_t sfpcount = 0;
uint8_t i, chksum = 0;
uint8_t *ptr;
uint8_t i;
struct s_sfpinfo dbsfp;
if (pos >= SFPS_MAX)
return EE_RET_POSERR; //position in database outside the range
if (pos >= SFPS_MAX) {
/* position in database outside the range */
return EE_RET_POSERR;
}
//read how many SFPs are in the database, but only in the first call (pos==0)
if (!pos
/* Read how many SFPs are in the database, but only in the first call
*/
if (sfpcount == SFP_DB_EMPTY
&& eeprom_read(i2cif, i2c_addr, EE_BASE_SFP, &sfpcount,
sizeof(sfpcount)) != sizeof(sfpcount))
return EE_RET_I2CERR;
if (add && sfpcount == SFPS_MAX) //no more space in the database to add new SFPs
return EE_RET_DBFULL;
else if (!pos && !add && sfpcount == 0) //there are no SFPs in the database to read
return sfpcount;
/* for not written flash set sfpcount to 0 */
if (sfpcount == SFP_DB_EMPTY)
sfpcount = 0;
if (oper == SFP_GET) {
if (sfpcount == 0) {
/* There are no SFPs in the database to read */
return 0;
}
if (!add) {
if (eeprom_read(i2cif, i2c_addr,
EE_BASE_SFP + sizeof(sfpcount)
+ pos * sizeof(struct s_sfpinfo),
......@@ -176,27 +196,42 @@ int storage_get_sfp(struct s_sfpinfo * sfp,
!= sizeof(struct s_sfpinfo) )
return EE_RET_I2CERR;
ptr = (uint8_t *) sfp;
for (i = 0; i < sizeof(struct s_sfpinfo) - 1; ++i) //'-1' because we do not include chksum in computation
chksum =
(uint8_t) ((uint16_t) chksum + *(ptr++)) & 0xff;
if (chksum != sfp->chksum)
if (sfp_chksum((uint8_t *)sfp) != sfp->chksum)
return EE_RET_CORRPT;
} else {
/*count checksum */
ptr = (uint8_t *) sfp;
for (i = 0; i < sizeof(struct s_sfpinfo) - 1; ++i) //'-1' because we do not include chksum in computation
chksum =
(uint8_t) ((uint16_t) chksum + *(ptr++)) & 0xff;
sfp->chksum = chksum;
/*add SFP at the end of DB */
}
if (oper == SFP_ADD) {
for (i = 0; i < sfpcount; i++) {
if (eeprom_read(i2cif, i2c_addr,
EE_BASE_SFP + sizeof(sfpcount)
+ i * sizeof(struct s_sfpinfo),
(uint8_t *)&dbsfp, sizeof(struct s_sfpinfo))
!= sizeof(struct s_sfpinfo))
return EE_RET_I2CERR;
if (!strncmp(dbsfp.pn, sfp->pn, 16)) { /* sfp matched */
pp_printf("Update existing SFP entry\n");
break;
}
}
if (i >= SFPS_MAX) { /* database is full */
return EE_RET_DBFULL;
}
/* Count checksum */
sfp->chksum = sfp_chksum((uint8_t *)sfp);
/* Add an entry at the given pos in the DB */
eeprom_write(i2cif, i2c_addr,
EE_BASE_SFP + sizeof(sfpcount)
+ sfpcount * sizeof(struct s_sfpinfo),
+ i * sizeof(struct s_sfpinfo),
(uint8_t *) sfp, sizeof(struct s_sfpinfo));
sfpcount++;
eeprom_write(i2cif, i2c_addr, EE_BASE_SFP, &sfpcount,
sizeof(sfpcount));
if (i >= sfpcount) {
pp_printf("Adding new SFP entry\n");
/* We're adding a new entry, update sfpcount */
sfpcount++;
eeprom_write(i2cif, i2c_addr, EE_BASE_SFP, &sfpcount,
sizeof(sfpcount));
}
}
return sfpcount;
......@@ -204,19 +239,15 @@ int storage_get_sfp(struct s_sfpinfo * sfp,
int storage_match_sfp(struct s_sfpinfo * sfp)
{
uint8_t sfpcount = 1;
int8_t i, temp;
int8_t i;
int sfp_cnt = 1;
struct s_sfpinfo dbsfp;
for (i = 0; i < sfpcount; ++i) {
temp = storage_get_sfp(&dbsfp, 0, i);
if (!i) {
sfpcount = temp; //only in first round valid sfpcount is returned from eeprom_get_sfp
if (sfpcount == 0 || sfpcount == 0xFF)
return 0;
else if (sfpcount < 0)
return sfpcount;
}
for (i = 0; i < sfp_cnt; ++i) {
sfp_cnt = storage_get_sfp(&dbsfp, SFP_GET, i);
if (sfp_cnt <= 0)
return sfp_cnt;
if (!strncmp(dbsfp.pn, sfp->pn, 16)) {
sfp->dTx = dbsfp.dTx;
sfp->dRx = dbsfp.dRx;
......
......@@ -15,15 +15,29 @@
* the actual packet filter rules are created
*/
#include <stdio.h>
#include <wrc.h>
#include <shell.h>
#include <endpoint.h>
#include <hw/endpoint_regs.h>
extern uint32_t _binary_rules_pfilter_bin_start[];
extern uint32_t _binary_rules_pfilter_bin_end[];
extern uint32_t _binary_rules_novlan_bin_start[];
extern uint32_t _binary_rules_novlan_bin_end[];
extern uint32_t _binary_rules_vlan_bin_start[];
extern uint32_t _binary_rules_vlan_bin_end[];
struct rule_set {
uint32_t *ini;
uint32_t *end;
} rule_sets[2] = {
{
_binary_rules_novlan_bin_start,
_binary_rules_novlan_bin_end,
}, {
_binary_rules_vlan_bin_start,
_binary_rules_vlan_bin_end,
}
};
#define pfilter_dbg(fmt, ...) /* nothing */
extern volatile struct EP_WB *EP;
......@@ -40,13 +54,23 @@ static uint32_t swap32(uint32_t v)
void pfilter_init_default(void)
{
/* Use shorter names to avoid getting mad */
uint32_t *vini = _binary_rules_pfilter_bin_start;
uint32_t *vend = _binary_rules_pfilter_bin_end;
uint32_t m, *v;
struct rule_set *s;
uint8_t mac[6];
char buf[20];
uint32_t m, *vini, *vend, *v, *v_vlan = NULL;
uint64_t cmd_word;
int i;
static int inited;
uint32_t latency_ethtype = CONFIG_LATENCY_ETHTYPE;
/* If vlan, use rule-set 1, else rule-set 0 */
s = rule_sets + (wrc_vlan_number != 0);
if (!s->ini) {
pp_printf("no pfilter rule-set!\n");
return;
}
vini = s->ini;
vend = s->end;
/*
* The array of words starts with 0x11223344 so we
......@@ -79,21 +103,55 @@ void pfilter_init_default(void)
}
/*
* Patch the local MAC address in place,
* in the first three instructions after NOP */
* in the first three instructions after NOP
*/
get_mac_addr(mac);
v[2] &= ~(0xffff << 13);
v[4] &= ~(0xffff << 13);
v[6] &= ~(0xffff << 13);
v[2] |= ((EP->MACH >> 0) & 0xffff) << 13;
v[4] |= ((EP->MACL >> 16) & 0xffff) << 13;
v[6] |= ((EP->MACL >> 0) & 0xffff) << 13;
v[2] |= ((mac[0] << 8) | mac[1]) << 13;
v[4] |= ((mac[2] << 8) | mac[3]) << 13;
v[6] |= ((mac[4] << 8) | mac[5]) << 13;
pfilter_verbose("fixing MAC adress in rule: use %s\n",
format_mac(buf, mac));
/*
* Patch in the "latency" ethtype too. This is set at build time
* so there's not need to remember the place or the value.
*/
if (latency_ethtype == 0)
latency_ethtype = 0x88f7; /* reuse PTPv2 type: turn into NOP */
for (v = vini + 1; v < vend; v += 2) {
if (((*v >> 13) & 0xffff) == 0xcafe
&& (*v & 0x7) == OR) {
pfilter_verbose("fixing latency eth_type: use 0x%x\n",
latency_ethtype);
*v &= ~(0xffff << 13);
*v |= latency_ethtype << 13;
}
}
/* If this is the VLAN rule-set, patch the vlan number too */
for (v = vini + 1; v < vend; v += 2) {
if (((*v >> 13) & 0xffff) == 0x0aaa
&& ((*v >> 7) & 0x1f) == 7) {
pfilter_verbose("fixing VLAN number in rule: use %i\n",
wrc_vlan_number);
v_vlan = v;
*v &= ~(0xffff << 13);
*v |= wrc_vlan_number << 13;
}
}
EP->PFCR0 = 0; // disable pfilter
for (i = 0;v < vend; v += 2, i++) {
for (i = 0, v = vini + 1; v < vend; v += 2, i++) {
uint32_t cr0, cr1;
cmd_word = v[0] | ((uint64_t)v[1] << 32);
pfilter_dbg("pos %02i: %x.%08x\n", i, (uint32_t)(cmd_word >> 32), (uint32_t)(cmd_word));
pfilter_verbose("pfilter rule %02i: %x.%08x\n", i,
(uint32_t)(cmd_word >> 32),
(uint32_t)(cmd_word));
cr1 = EP_PFCR1_MM_DATA_LSB_W(cmd_word & 0xfff);
cr0 = EP_PFCR0_MM_ADDR_W(i) | EP_PFCR0_MM_DATA_MSB_W(cmd_word >> 12) |
......@@ -103,5 +161,11 @@ void pfilter_init_default(void)
EP->PFCR0 = cr0;
}
/* Restore the 0xaaa vlan number, so we can re-patch next time */
if (v_vlan) {
*v_vlan &= ~(0xffff << 13);
*v_vlan |= 0x0aaa << 13;
}
EP->PFCR0 = EP_PFCR0_ENABLE;
}
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2016 GSI (www.gsi.de)
* Author: Alessandro rubini
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <wrc.h>
#include <temperature.h>
#include <shell.h>
static struct wrc_onetemp temp_fake_data[] = {
{"roof", TEMP_INVALID},
{"core", TEMP_INVALID},
{"case", TEMP_INVALID},
{NULL,}
};
static int temp_fake_refresh(struct wrc_temp *t)
{
/* nothing to do */
return 0;
}
/* not static at this point, because it's the only one */
DEFINE_TEMPERATURE(w1) = {
.read = temp_fake_refresh,
.t = temp_fake_data,
};
static int cmd_faketemp(const char *args[])
{
int i;
const char *dot;
if (!args[0]) {
pp_printf("%08x %08x %08x\n", temp_fake_data[0].t,
temp_fake_data[1].t, temp_fake_data[2].t);
return 0;
}
for (i = 0; i < 3 && args[i]; i++) {
int sign = 1, val;
/* accept negative, and at most one decimal */
if (args[i][0] == '-')
sign = -1, args[i]++;
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;
}
return 0;
}
DEFINE_WRC_COMMAND(faketemp) = {
.name = "faketemp",
.exec = cmd_faketemp,
};
......@@ -80,6 +80,11 @@ int flash_write(uint32_t addr, uint8_t *buf, int count)
}
bbspi_transfer(1,0);
/* make sure the write is complete */
while (flash_rsr() & 0x01) {
/* do nothing */
}
return count;
}
......
......@@ -10,6 +10,7 @@
#include <stdio.h>
#include <string.h>
#include <wrc.h>
#include <wrpc.h>
#include "types.h"
#include "board.h"
......@@ -51,16 +52,7 @@
static volatile uint32_t dma_tx_buf[MINIC_DMA_TX_BUF_SIZE / 4];
static volatile uint32_t dma_rx_buf[MINIC_DMA_RX_BUF_SIZE / 4];
struct wr_minic {
volatile uint32_t *rx_head, *rx_base;
uint32_t rx_avail, rx_size;
volatile uint32_t *tx_head, *tx_base;
uint32_t tx_avail, tx_size;
int tx_count, rx_count;
};
static struct wr_minic minic;
struct wr_minic minic;
static inline void minic_writel(uint32_t reg, uint32_t data)
{
......@@ -191,10 +183,10 @@ int minic_poll_rx()
return (isr & MINIC_EIC_ISR_RX) ? 1 : 0;
}
int minic_rx_frame(uint8_t * hdr, uint8_t * payload, uint32_t buf_size,
int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size,
struct hw_timestamp *hwts)
{
uint32_t payload_size, num_words;
uint32_t frame_size, payload_size, num_words;
uint32_t desc_hdr;
uint32_t raw_ts;
uint32_t cur_avail;
......@@ -217,8 +209,8 @@ int minic_rx_frame(uint8_t * hdr, uint8_t * payload, uint32_t buf_size,
}
return 0;
}
payload_size = RX_DESC_SIZE(desc_hdr);
num_words = ((payload_size + 3) >> 2) + 1;
frame_size = RX_DESC_SIZE(desc_hdr);
num_words = ((frame_size + 3) >> 2) + 1;
/* valid packet */
if (!RX_DESC_ERROR(desc_hdr)) {
......@@ -229,15 +221,15 @@ int minic_rx_frame(uint8_t * hdr, uint8_t * payload, uint32_t buf_size,
int cntr_diff;
uint16_t dhdr;
payload_size -= RX_OOB_SIZE;
frame_size -= RX_OOB_SIZE;
/* fixme: ugly way of doing unaligned read */
minic_rx_memcpy((uint8_t *) & raw_ts,
(uint8_t *) minic.rx_head
+ payload_size + 6, 4);
+ frame_size + 6, 4);
minic_rx_memcpy((uint8_t *) & dhdr,
(uint8_t *) minic.rx_head +
payload_size + 4, 2);
frame_size + 4, 2);
EXPLODE_WR_TIMESTAMP(raw_ts, counter_r, counter_f);
shw_pps_gen_get_time(&sec, &counter_ppsg);
......@@ -258,14 +250,14 @@ int minic_rx_frame(uint8_t * hdr, uint8_t * payload, uint32_t buf_size,
hwts->nsec = counter_r * (REF_CLOCK_PERIOD_PS / 1000);
hwts->valid = (dhdr & RXOOB_TS_INCORRECT) ? 0 : 1;
}
payload_size = frame_size - ETH_HEADER_SIZE;
n_recvd = (buf_size < payload_size ? buf_size : payload_size);
minic.rx_count++;
minic_rx_memcpy(hdr, (void *)minic.rx_head + 4,
minic_rx_memcpy((void *)hdr, (void *)minic.rx_head + 4,
ETH_HEADER_SIZE);
minic_rx_memcpy(payload, (void *)minic.rx_head + 4
+ ETH_HEADER_SIZE, n_recvd - ETH_HEADER_SIZE);
+ ETH_HEADER_SIZE, n_recvd);
} else {
n_recvd = -1;
}
......@@ -288,19 +280,24 @@ int minic_rx_frame(uint8_t * hdr, uint8_t * payload, uint32_t buf_size,
return n_recvd;
}
int minic_tx_frame(uint8_t * hdr, uint8_t * payload, uint32_t size,
int minic_tx_frame(struct wr_ethhdr_vlan *hdr, uint8_t *payload, uint32_t size,
struct hw_timestamp *hwts)
{
uint32_t d_hdr, mcr, nwords;
uint8_t ts_valid;
int i;
int i, hsize;
minic_new_tx_buffer();
memset((void *)minic.tx_head, 0x0, size + 16);
memset((void *)minic.tx_head + 4, 0, size < 60 ? 60 : size);
memcpy((void *)minic.tx_head + 4, hdr, ETH_HEADER_SIZE);
memcpy((void *)minic.tx_head + 4 + ETH_HEADER_SIZE, payload,
size - ETH_HEADER_SIZE);
if (hdr->ethtype == htons(0x8100))
hsize = sizeof(struct wr_ethhdr_vlan);
else
hsize = sizeof(struct wr_ethhdr);
memset((void *)minic.tx_head, 0x0, size + hsize + 4);
memcpy((void *)minic.tx_head + 4, hdr, hsize);
memcpy((void *)minic.tx_head + 4 + hsize, payload, size);
size += hsize;
if (size < 60)
size = 60;
......@@ -361,7 +358,7 @@ int minic_tx_frame(uint8_t * hdr, uint8_t * payload, uint32_t size,
fid = MINIC_TSR0_FID_R(minic_readl(MINIC_REG_TSR0));
if (fid != WRPC_FID) {
TRACE_DEV("minic_tx_frame: unmatched fid %d vs %d\n",
wrc_verbose("minic_tx_frame: unmatched fid %d vs %d\n",
fid, WRPC_FID);
}
......@@ -376,7 +373,7 @@ int minic_tx_frame(uint8_t * hdr, uint8_t * payload, uint32_t size,
hwts->ahead = 0;
hwts->nsec = counter_r * (REF_CLOCK_PERIOD_PS / 1000);
// TRACE_DEV("minic_tx_frame [%d bytes] TS: %d.%d valid %d\n", size, hwts->utc, hwts->nsec, hwts->valid);
// wrc_verbose("minic_tx_frame [%d bytes] TS: %d.%d valid %d\n", size, hwts->utc, hwts->nsec, hwts->valid);
minic.tx_count++;
}
......
......@@ -45,7 +45,7 @@ void shw_pps_gen_init()
/* Adjusts the nanosecond (refclk cycle) counter by atomically adding (how_much) cycles. */
int shw_pps_gen_adjust(int counter, int64_t how_much)
{
TRACE_DEV("Adjust: counter = %s [%c%d]\n",
wrc_verbose("Adjust: counter = %s [%c%d]\n",
counter == PPSG_ADJUST_SEC ? "seconds" : "nanoseconds",
how_much < 0 ? '-' : '+', (int32_t) abs(how_much));
......@@ -96,7 +96,8 @@ static uint64_t pps_get_utc(void)
return out;
}
void shw_pps_gen_get_time(uint64_t * seconds, uint32_t * nanoseconds)
void __attribute__((weak)) shw_pps_gen_get_time(uint64_t * seconds,
uint32_t * nanoseconds)
{
uint32_t ns_cnt;
uint64_t sec1, sec2;
......@@ -110,9 +111,7 @@ void shw_pps_gen_get_time(uint64_t * seconds, uint32_t * nanoseconds)
if (seconds)
*seconds = sec2;
if (nanoseconds)
*nanoseconds =
(uint32_t) ((int64_t) ns_cnt *
(int64_t) REF_CLOCK_PERIOD_PS / 1000LL);
*nanoseconds = ns_cnt * NS_PER_CLOCK;
}
/* Returns 1 when the adjustment operation is not yet finished */
......
......@@ -12,7 +12,6 @@
#include <wrc.h>
#include "board.h"
#include "trace.h"
#include "syscon.h"
#include "endpoint.h"
#include "softpll_ng.h"
......@@ -150,7 +149,7 @@ int rxts_calibration_update(uint32_t *t24p_value)
if (cal_cur_phase >= CAL_SCAN_RANGE) {
if (det_rising.state != TD_DONE || det_falling.state != TD_DONE)
{
TRACE_DEV("RXTS calibration error.\n");
wrc_verbose("RXTS calibration error.\n");
return -1;
}
......@@ -173,7 +172,7 @@ int rxts_calibration_update(uint32_t *t24p_value)
if(ttrans >= REF_CLOCK_PERIOD_PS) ttrans -= REF_CLOCK_PERIOD_PS;
TRACE_DEV("RXTS calibration: R@%dps, F@%dps, transition@%dps\n",
wrc_verbose("RXTS calibration: R@%dps, F@%dps, transition@%dps\n",
det_rising.trans_phase, det_falling.trans_phase,
ttrans);
......
......@@ -7,7 +7,6 @@
*
* Released according to the GNU GPL, version 2 or any later version.
*/
//#include <string.h>
#include <wrc.h>
#include <w1.h>
#include <storage.h>
......@@ -15,6 +14,7 @@
#include "types.h"
#include "i2c.h"
#include "onewire.h"
#include "endpoint.h"
#include <sdb.h>
#define SDBFS_BIG_ENDIAN
......@@ -165,7 +165,7 @@ static void storage_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 %s\n",
(int)(d->sdb_component.product.device_id),
......@@ -195,12 +195,13 @@ void storage_init(int chosen_i2cif, int chosen_i2c_addr)
uint32_t magic = 0;
static unsigned entry_points_eeprom[] = {0, 64, 128, 256, 512, 1024};
static unsigned entry_points_flash[] = {
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 */
0x600000}; /* after SVEC AFPGA bitstream */
int i, ret;
/*
......@@ -208,7 +209,7 @@ void storage_init(int chosen_i2cif, int chosen_i2c_addr)
*/
for (i = 0; i < ARRAY_SIZE(entry_points_flash); i++) {
flash_read(entry_points_flash[i], (void *)&magic, sizeof(magic));
if(magic == SDB_MAGIC)
if (magic == SDB_MAGIC)
break;
}
if (magic == SDB_MAGIC) {
......@@ -291,19 +292,25 @@ found_exit:
* setting if no sdbfs is there, but CONFIG_SDB_STORAGE depends on
* CONFIG_W1 anyways.
*/
int get_persistent_mac(uint8_t portnum, uint8_t * mac)
int get_persistent_mac(uint8_t portnum, uint8_t *mac)
{
int ret;
int i, class;
uint64_t rom;
if (IS_HOST_PROCESS) {
/* we don't have sdb working, so get the real eth address */
get_mac_addr(mac);
return 0;
}
if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, SDB_DEV_MAC) < 0)
return -1;
ret = sdbfs_fread(&wrc_sdb, 0, mac, 6);
sdbfs_close(&wrc_sdb);
if(ret < 0)
if (ret < 0)
pp_printf("%s: SDB error\n", __func__);
if (mac[0] == 0xff ||
(mac[0] | mac[1] | mac[2] | mac[3] | mac[4] | mac[5]) == 0) {
......@@ -333,7 +340,7 @@ int get_persistent_mac(uint8_t portnum, uint8_t * mac)
return 0;
}
int set_persistent_mac(uint8_t portnum, uint8_t * mac)
int set_persistent_mac(uint8_t portnum, uint8_t *mac)
{
int ret;
......@@ -376,7 +383,7 @@ int32_t storage_sfpdb_erase(void)
if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, SDB_DEV_SFP) < 0)
return -1;
ret = sdbfs_ferase(&wrc_sdb, 0, wrc_sdb.f_len);
if(ret == wrc_sdb.f_len)
if (ret == wrc_sdb.f_len)
ret = 1;
sdbfs_close(&wrc_sdb);
return ret == 1 ? 0 : -1;
......@@ -387,51 +394,59 @@ int32_t storage_sfpdb_erase(void)
static int sfp_valid(struct s_sfpinfo *sfp)
{
int i;
for(i=0; i<SFP_PN_LEN; ++i) {
if(sfp->pn[i] == 0xff)
for (i = 0; i < SFP_PN_LEN; ++i) {
if (sfp->pn[i] == 0xff)
return 0;
}
return 1;
}
int storage_get_sfp(struct s_sfpinfo * sfp,
uint8_t add, uint8_t pos)
static int sfp_entry(struct s_sfpinfo *sfp, uint8_t oper, uint8_t pos)
{
static uint8_t sfpcount = 0;
struct s_sfpinfo tempsfp;
int ret = -1;
uint8_t i, chksum = 0;
uint8_t *ptr;
int sdb_offset;
if (pos >= SFPS_MAX)
return EE_RET_POSERR; //position outside the range
return EE_RET_POSERR; /* position outside the range */
if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, SDB_DEV_SFP) < 0)
return -1;
//read how many SFPs are in the database, but only in the first call
if(!pos) {
/* Read how many SFPs are in the database, but only in the first
* call */
if (!pos) {
sfpcount = 0;
while (sdbfs_fread(&wrc_sdb, sizeof(sfpcount) +
sfpcount*sizeof(tempsfp), &tempsfp,
sdb_offset = sizeof(sfpcount);
while (sdbfs_fread(&wrc_sdb, sdb_offset, &tempsfp,
sizeof(tempsfp)) == sizeof(tempsfp)) {
if(!sfp_valid(&tempsfp))
if (!sfp_valid(&tempsfp))
break;
sfpcount++;
sdb_offset = sizeof(sfpcount) + sfpcount * sizeof(tempsfp);
}
}
if (add && sfpcount == SFPS_MAX) //no more space to add new SFPs
return EE_RET_DBFULL;
if (!pos && !add && sfpcount == 0) // no SFPs in the database
return 0;
if ((oper == SFP_ADD) && (sfpcount == SFPS_MAX)) {
/* no more space to add new SFPs */
ret = EE_RET_DBFULL;
goto out;
}
if (!add) {
if (sdbfs_fread(&wrc_sdb, sizeof(sfpcount) + pos * sizeof(*sfp),
sfp, sizeof(*sfp))
!= sizeof(*sfp))
if (!pos && (oper == SFP_GET) && sfpcount == 0) {
/* no SFPs in the database */
ret = 0;
goto out;
}
if (oper == SFP_GET) {
sdb_offset = sizeof(sfpcount) + pos * sizeof(*sfp);
if (sdbfs_fread(&wrc_sdb, sdb_offset, sfp, sizeof(*sfp))
!= sizeof(*sfp))
goto out;
ptr = (uint8_t *)sfp;
......@@ -442,46 +457,99 @@ int storage_get_sfp(struct s_sfpinfo * sfp,
pp_printf("sfp: corrupted checksum\n");
goto out;
}
} else {
/*count checksum */
}
if (oper == SFP_ADD) {
/* count checksum */
ptr = (uint8_t *)sfp;
/* use sizeof() - 1 because we don't include checksum */
for (i = 0; i < sizeof(struct s_sfpinfo) - 1; ++i)
chksum = chksum + *(ptr++);
sfp->chksum = chksum;
/* add SFP at the end of DB */
if (sdbfs_fwrite(&wrc_sdb, sizeof(sfpcount)
+ sfpcount * sizeof(*sfp), sfp, sizeof(*sfp))
!= sizeof(*sfp))
sdb_offset = sizeof(sfpcount) + sfpcount * sizeof(*sfp);
if (sdbfs_fwrite(&wrc_sdb, sdb_offset, sfp, sizeof(*sfp))
!= sizeof(*sfp)) {
goto out;
}
sfpcount++;
if (sdbfs_fwrite(&wrc_sdb, 0, &sfpcount, sizeof(sfpcount))
!= sizeof(sfpcount))
goto out;
}
ret = sfpcount;
out:
sdbfs_close(&wrc_sdb);
return ret;
return 0;
}
int storage_match_sfp(struct s_sfpinfo * sfp)
static int storage_update_sfp(struct s_sfpinfo *sfp)
{
int sfpcount = 1;
int temp;
int8_t i;
struct s_sfpinfo sfp_db[SFPS_MAX];
struct s_sfpinfo *dbsfp;
/* copy entries from flash to the memory, update entry if matched */
for (i = 0; i < sfpcount; ++i) {
dbsfp = &sfp_db[i];
sfpcount = sfp_entry(dbsfp, SFP_GET, i);
if (sfpcount <= 0)
return sfpcount;
if (!strncmp(dbsfp->pn, sfp->pn, 16)) {
/* update matched entry */
dbsfp->dTx = sfp->dTx;
dbsfp->dRx = sfp->dRx;
dbsfp->alpha = sfp->alpha;
}
}
/* erase entire database */
if (storage_sfpdb_erase() == EE_RET_I2CERR) {
pp_printf("Could not erase DB\n");
return -1;
}
/* add all SFPs */
for (i = 0; i < sfpcount; ++i) {
dbsfp = &sfp_db[i];
temp = sfp_entry(dbsfp, SFP_ADD, 0);
if (temp < 0) {
/* if error, return it */
return temp;
}
}
return i;
}
int storage_get_sfp(struct s_sfpinfo *sfp, uint8_t oper, uint8_t pos)
{
struct s_sfpinfo tmp_sfp;
if (oper == SFP_GET) {
/* Get SFP entry */
return sfp_entry(sfp, SFP_GET, pos);
}
/* storage_match_sfp replaces content of parameter, so do the copy
* first */
tmp_sfp = *sfp;
if (!storage_match_sfp(&tmp_sfp)) { /* add a new sfp entry */
pp_printf("Adding new SFP entry\n");
return sfp_entry(sfp, SFP_ADD, 0);
}
pp_printf("Update existing SFP entry\n");
return storage_update_sfp(sfp);
}
int storage_match_sfp(struct s_sfpinfo *sfp)
{
uint8_t sfpcount = 1;
int8_t i, temp;
int8_t i;
struct s_sfpinfo dbsfp;
for (i = 0; i < sfpcount; ++i) {
temp = storage_get_sfp(&dbsfp, 0, i);
if (!i) {
// first round: valid sfpcount is returned
sfpcount = temp;
if (sfpcount == 0 || sfpcount == 0xFF)
return 0;
else if (sfpcount < 0)
return sfpcount;
}
sfpcount = sfp_entry(&dbsfp, SFP_GET, i);
if (sfpcount <= 0)
return sfpcount;
if (!strncmp(dbsfp.pn, sfp->pn, 16)) {
sfp->dTx = dbsfp.dTx;
sfp->dRx = dbsfp.dRx;
......@@ -497,8 +565,7 @@ int storage_match_sfp(struct s_sfpinfo * sfp)
* Phase transition ("calibration" file)
*/
#define VALIDITY_BIT 0x80000000
int storage_phtrans(uint32_t * valp,
uint8_t write)
int storage_phtrans(uint32_t *valp, uint8_t write)
{
int ret = -1;
uint32_t value;
......@@ -544,7 +611,7 @@ int storage_init_erase(void)
if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, SDB_DEV_INIT) < 0)
return -1;
ret = sdbfs_ferase(&wrc_sdb, 0, wrc_sdb.f_len);
if(ret == wrc_sdb.f_len)
if (ret == wrc_sdb.f_len)
ret = 1;
sdbfs_close(&wrc_sdb);
return ret == 1 ? 0 : -1;
......@@ -569,7 +636,7 @@ int storage_init_add(const char *args[])
while (sdbfs_fread(&wrc_sdb, sizeof(used)+used, &byte, 1) == 1) {
if (byte == 0xff)
break;
used ++;
used++;
}
if (used > 256 /* 0xffff or wrong */)
......@@ -582,7 +649,7 @@ int storage_init_add(const char *args[])
(void *)args[i], len) != len)
goto out;
used += len;
if(args[i+1] != NULL) /* next one is another word of the same command */
if (args[i+1] != NULL) /* next one is another word of the same command */
separator = ' ';
else /* no more words, end command with '\n' */
separator = '\n';
......@@ -615,18 +682,18 @@ int storage_init_show(void)
if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, SDB_DEV_INIT) < 0)
return -1;
used = 0;
do {
if (sdbfs_fread(&wrc_sdb, sizeof(used) + used, &byte, 1) != 1)
goto out;
if(byte != 0xff) {
if (byte != 0xff) {
pp_printf("%c", byte);
used++;
}
} while(byte != 0xff);
} while (byte != 0xff);
if(used == 0)
if (used == 0)
pp_printf("Empty init script...\n");
ret = 0;
out:
......
......@@ -10,10 +10,21 @@
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include <errno.h>
#include "syscon.h"
#include "i2c.h"
#include "sfp.h"
#include "storage.h"
/* Calibration data (from EEPROM if available) */
int32_t sfp_alpha = 73622176; /* default values if could not read EEPROM */
int32_t sfp_deltaTx = 0;
int32_t sfp_deltaRx = 0;
int32_t sfp_in_db = 0;
char sfp_pn[SFP_PN_LEN];
int sfp_present(void)
{
......@@ -52,3 +63,27 @@ int sfp_read_part_id(char *part_id)
return -1;
}
int sfp_match(void)
{
struct s_sfpinfo sfp;
sfp_pn[0] = '\0';
if (!sfp_present()) {
return -ENODEV;
}
if (sfp_read_part_id(sfp_pn)) {
return -EIO;
}
strncpy(sfp.pn, sfp_pn, SFP_PN_LEN);
if (storage_match_sfp(&sfp) == 0) {
sfp_in_db = SFP_NOT_MATCHED;
return -ENXIO;
}
sfp_deltaTx = sfp.dTx;
sfp_deltaRx = sfp.dRx;
sfp_alpha = sfp.alpha;
sfp_in_db = SFP_MATCHED;
return 0;
}
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2016 GSI (www.gsi.de)
* Author: Alessandro rubini
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <wrc.h>
#include <w1.h>
#include <temperature.h>
static struct wrc_onetemp temp_w1_data[] = {
{"pcb", TEMP_INVALID},
{NULL,}
};
static unsigned long nextt;
static int niterations;
/* Returns 1 if it did something */
static int temp_w1_refresh(struct wrc_temp *t)
{
static int done;
if (!done) {
nextt = timer_get_tics() + 1000;
done++;
}
/* Odd iterations: send the command, even iterations: read back */
int phase = niterations & 1;
static int intervals[] = {
200, (1000 * CONFIG_TEMP_POLL_INTERVAL) - 200
};
if (time_before(timer_get_tics(), nextt))
return 0;
nextt += intervals[phase];
niterations++;
switch(phase) {
case 0:
w1_read_temp_bus(&wrpc_w1_bus, W1_FLAG_NOWAIT);
break;
case 1:
temp_w1_data[0].t =
w1_read_temp_bus(&wrpc_w1_bus, W1_FLAG_COLLECT);
break;
}
return 1;
}
/* not static at this point, because it's the only one */
DEFINE_TEMPERATURE(w1) = {
.read = temp_w1_refresh,
.t = temp_w1_data,
};
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2016 GSI (www.gsi.de)
* Author: Alessandro rubini
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <wrc.h>
#include <string.h>
#include <temperature.h>
#include <shell.h>
extern struct wrc_temp __temp_begin[], __temp_end[];
/*
* Library functions
*/
uint32_t wrc_temp_get(char *name)
{
struct wrc_temp *ta;
struct wrc_onetemp *wt;
for (ta = __temp_begin; ta < __temp_end; ta++)
for (wt = ta->t; wt->name; wt++) {
if (!strcmp(wt->name, name))
return wt->t;
}
return TEMP_INVALID;
}
struct wrc_onetemp *wrc_temp_getnext(struct wrc_onetemp *pt)
{
struct wrc_temp *ta;
struct wrc_onetemp *wt;
if (!pt) { /* first one */
if (__temp_begin != __temp_end)
return __temp_begin->t;
}
if (pt[1].name)
return pt + 1;
/* get next array, if any */
for (ta = __temp_begin; ta < __temp_end; ta++) {
for (wt = ta->t; wt->name; wt++) {
if (wt == pt) {
ta++;
if (ta >= __temp_end)
return NULL;
return ta->t;
}
}
}
return NULL;
}
extern int wrc_temp_format(char *buffer, int len)
{
struct wrc_onetemp *p;
int l = 0, i = 0;
int32_t t;
for (p = wrc_temp_getnext(NULL); p; p = wrc_temp_getnext(p), i++) {
if (l + 16 > len) {
l += sprintf(buffer + l, " ENOSPC");
return l;
}
t = p->t;
l += sprintf(buffer + l, "%s%s:", i ? " " : "", p->name);
if (t == TEMP_INVALID) {
l += sprintf(buffer + l, "INVALID");
continue;
}
if (t < 0) {
t = -(signed)t;
l += sprintf(buffer + l, "-");
}
l += sprintf(buffer + l,"%d.%04d", t >> 16,
((t & 0xffff) * 10 * 1000 >> 16));
}
return l;
}
/*
* The task
*/
static void wrc_temp_init(void)
{
struct wrc_temp *ta;
/* Call all actors, so they can init themselves (using ->data) */
for (ta = __temp_begin; ta < __temp_end; ta++)
ta->read(ta);
}
static int wrc_temp_refresh(void)
{
struct wrc_temp *ta;
int ret = 0;
for (ta = __temp_begin; ta < __temp_end; ta++)
ret += ta->read(ta);
return (ret > 0);
}
DEFINE_WRC_TASK(temp) = {
.name = "temperature",
.init = wrc_temp_init,
.job = wrc_temp_refresh,
};
/*
* The shell command
*/
static int cmd_temp(const char *args[])
{
char buffer[80];
wrc_temp_format(buffer, sizeof(buffer));
pp_printf("%s\n", buffer);
return 0;
}
DEFINE_WRC_COMMAND(temp) = {
.name = "temp",
.exec = cmd_temp,
};
This diff is collapsed.
#include <sys/types.h>
#include <ppsi/ppsi.h>
#include <softpll_ng.h>
#include "dump-info.h"
struct dump_info dump_info[] = {
/* map for fields of ppsi structures */
#undef DUMP_STRUCT
#define DUMP_STRUCT struct pp_globals
DUMP_HEADER("pp_globals"),
DUMP_FIELD(pointer, pp_instances), /* FIXME: follow this */
DUMP_FIELD(pointer, servo), /* FIXME: follow this */
DUMP_FIELD(pointer, rt_opts),
DUMP_FIELD(pointer, defaultDS),
DUMP_FIELD(pointer, currentDS),
DUMP_FIELD(pointer, parentDS),
DUMP_FIELD(pointer, timePropertiesDS),
DUMP_FIELD(int, ebest_idx),
DUMP_FIELD(int, ebest_updated),
DUMP_FIELD(int, nlinks),
DUMP_FIELD(int, max_links),
//DUMP_FIELD(struct pp_globals_cfg cfg),
DUMP_FIELD(int, rxdrop),
DUMP_FIELD(int, txdrop),
DUMP_FIELD(pointer, arch_data),
DUMP_FIELD(pointer, global_ext_data),
#undef DUMP_STRUCT
#define DUMP_STRUCT DSDefault /* Horrible typedef */
DUMP_HEADER("DSDefault"),
DUMP_FIELD(Boolean, twoStepFlag),
DUMP_FIELD(ClockIdentity, clockIdentity),
DUMP_FIELD(UInteger16, numberPorts),
DUMP_FIELD(ClockQuality, clockQuality),
DUMP_FIELD(UInteger8, priority1),
DUMP_FIELD(UInteger8, priority2),
DUMP_FIELD(UInteger8, domainNumber),
DUMP_FIELD(Boolean, slaveOnly),
#undef DUMP_STRUCT
#define DUMP_STRUCT DSCurrent /* Horrible typedef */
DUMP_HEADER("DSCurrent"),
DUMP_FIELD(UInteger16, stepsRemoved),
DUMP_FIELD(TimeInternal, offsetFromMaster),
DUMP_FIELD(TimeInternal, meanPathDelay), /* oneWayDelay */
DUMP_FIELD(UInteger16, primarySlavePortNumber),
#undef DUMP_STRUCT
#define DUMP_STRUCT DSParent /* Horrible typedef */
DUMP_HEADER("DSParent"),
DUMP_FIELD(PortIdentity, parentPortIdentity),
DUMP_FIELD(UInteger16, observedParentOffsetScaledLogVariance),
DUMP_FIELD(Integer32, observedParentClockPhaseChangeRate),
DUMP_FIELD(ClockIdentity, grandmasterIdentity),
DUMP_FIELD(ClockQuality, grandmasterClockQuality),
DUMP_FIELD(UInteger8, grandmasterPriority1),
DUMP_FIELD(UInteger8, grandmasterPriority2),
#undef DUMP_STRUCT
#define DUMP_STRUCT DSTimeProperties /* Horrible typedef */
DUMP_HEADER("DSTimeProperties"),
DUMP_FIELD(Integer16, currentUtcOffset),
DUMP_FIELD(Boolean, currentUtcOffsetValid),
DUMP_FIELD(Boolean, leap59),
DUMP_FIELD(Boolean, leap61),
DUMP_FIELD(Boolean, timeTraceable),
DUMP_FIELD(Boolean, frequencyTraceable),
DUMP_FIELD(Boolean, ptpTimescale),
DUMP_FIELD(Enumeration8, timeSource),
#undef DUMP_STRUCT
#define DUMP_STRUCT struct wr_servo_state
DUMP_HEADER("servo_state"),
DUMP_FIELD_SIZE(char, if_name, 16),
DUMP_FIELD(unsigned_long, flags),
DUMP_FIELD(int, state),
DUMP_FIELD(Integer32, delta_tx_m),
DUMP_FIELD(Integer32, delta_rx_m),
DUMP_FIELD(Integer32, delta_tx_s),
DUMP_FIELD(Integer32, delta_rx_s),
DUMP_FIELD(Integer32, fiber_fix_alpha),
DUMP_FIELD(Integer32, clock_period_ps),
DUMP_FIELD(TimeInternal, t1),
DUMP_FIELD(TimeInternal, t2),
DUMP_FIELD(TimeInternal, t3),
DUMP_FIELD(TimeInternal, t4),
DUMP_FIELD(Integer32, delta_ms_prev),
DUMP_FIELD(int, missed_iters),
DUMP_FIELD(TimeInternal, mu), /* half of the RTT */
DUMP_FIELD(Integer64, picos_mu),
DUMP_FIELD(Integer32, cur_setpoint),
DUMP_FIELD(Integer32, delta_ms),
DUMP_FIELD(UInteger32, update_count),
DUMP_FIELD(int, tracking_enabled),
DUMP_FIELD_SIZE(char, servo_state_name, 32),
DUMP_FIELD(Integer64, skew),
DUMP_FIELD(Integer64, offset),
DUMP_FIELD(UInteger32, n_err_state),
DUMP_FIELD(UInteger32, n_err_offset),
DUMP_FIELD(UInteger32, n_err_delta_rtt),
#undef DUMP_STRUCT
#define DUMP_STRUCT struct pp_instance
DUMP_HEADER("pp_instance"),
DUMP_FIELD(int, state),
DUMP_FIELD(int, next_state),
DUMP_FIELD(int, next_delay),
DUMP_FIELD(int, is_new_state),
DUMP_FIELD(pointer, arch_data),
DUMP_FIELD(pointer, ext_data),
DUMP_FIELD(unsigned_long, d_flags),
DUMP_FIELD(unsigned_char, flags),
DUMP_FIELD(unsigned_char, role),
DUMP_FIELD(unsigned_char, proto),
DUMP_FIELD(pointer, glbs),
DUMP_FIELD(pointer, n_ops),
DUMP_FIELD(pointer, t_ops),
DUMP_FIELD(pointer, __tx_buffer),
DUMP_FIELD(pointer, __rx_buffer),
DUMP_FIELD(pointer, tx_frame),
DUMP_FIELD(pointer, rx_frame),
DUMP_FIELD(pointer, tx_ptp),
DUMP_FIELD(pointer, rx_ptp),
/* This is a sub-structure */
DUMP_FIELD(int, ch[0].fd),
DUMP_FIELD(pointer, ch[0].custom),
DUMP_FIELD(pointer, ch[0].arch_data),
DUMP_FIELD_SIZE(bina, ch[0].addr, 6),
DUMP_FIELD(int, ch[0].pkt_present),
DUMP_FIELD(int, ch[1].fd),
DUMP_FIELD(pointer, ch[1].custom),
DUMP_FIELD(pointer, ch[1].arch_data),
DUMP_FIELD_SIZE(bina, ch[1].addr, 6),
DUMP_FIELD(int, ch[1].pkt_present),
DUMP_FIELD(ip_address, mcast_addr),
DUMP_FIELD(int, tx_offset),
DUMP_FIELD(int, rx_offset),
DUMP_FIELD_SIZE(bina, peer, 6),
DUMP_FIELD(uint16_t, peer_vid),
DUMP_FIELD(TimeInternal, t1),
DUMP_FIELD(TimeInternal, t2),
DUMP_FIELD(TimeInternal, t3),
DUMP_FIELD(TimeInternal, t4),
DUMP_FIELD(TimeInternal, cField),
DUMP_FIELD(TimeInternal, last_rcv_time),
DUMP_FIELD(TimeInternal, last_snt_time),
DUMP_FIELD(UInteger16, frgn_rec_num),
DUMP_FIELD(Integer16, frgn_rec_best),
//DUMP_FIELD(struct pp_frgn_master frgn_master[PP_NR_FOREIGN_RECORDS]),
DUMP_FIELD(pointer, portDS),
//DUMP_FIELD(unsigned long timeouts[__PP_TO_ARRAY_SIZE]),
DUMP_FIELD(UInteger16, recv_sync_sequence_id),
DUMP_FIELD(Integer8, log_min_delay_req_interval),
//DUMP_FIELD(UInteger16 sent_seq[__PP_NR_MESSAGES_TYPES]),
DUMP_FIELD_SIZE(bina, received_ptp_header, sizeof(MsgHeader)),
//DUMP_FIELD(pointer, iface_name),
//DUMP_FIELD(pointer, port_name),
DUMP_FIELD(int, port_idx),
DUMP_FIELD(int, vlans_array_len),
/* FIXME: array */
DUMP_FIELD(int, nvlans),
/* sub structure */
DUMP_FIELD_SIZE(char, cfg.port_name, 16),
DUMP_FIELD_SIZE(char, cfg.iface_name, 16),
DUMP_FIELD(int, cfg.ext),
DUMP_FIELD(int, cfg.ext),
DUMP_FIELD(unsigned_long, ptp_tx_count),
DUMP_FIELD(unsigned_long, ptp_rx_count),
#undef DUMP_STRUCT
#define DUMP_STRUCT struct softpll_state
DUMP_HEADER("softpll"),
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),
DUMP_FIELD(int, helper.p_adder),
DUMP_FIELD(int, helper.p_setpoint),
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),
DUMP_FIELD(int, ext.align_timer),
DUMP_FIELD(int, ext.align_target),
DUMP_FIELD(int, ext.align_step),
DUMP_FIELD(int, ext.align_shift),
DUMP_FIELD(int, mpll.state),
/* FIXME: mpll.pi etc */
DUMP_FIELD(int, mpll.adder_ref),
DUMP_FIELD(int, mpll.adder_out),
DUMP_FIELD(int, mpll.tag_ref),
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),
#undef DUMP_STRUCT
#define DUMP_STRUCT struct spll_fifo_log
DUMP_HEADER("pll_fifo"),
DUMP_FIELD(uint32_t, trr),
DUMP_FIELD(uint32_t, tstamp),
DUMP_FIELD(uint32_t, duration),
DUMP_FIELD(uint16_t, irq_count),
DUMP_FIELD(uint16_t, tag_count),
/* FIXME: aux_state and ptracker_state -- variable-len arrays */
DUMP_HEADER("end"),
};
#include "flash.h"
void flash_init(void)
{}
int flash_write(uint32_t addr, uint8_t *buf, int count)
{ return 0; }
int flash_read(uint32_t addr, uint8_t *buf, int count)
{ return 0; }
int flash_erase(uint32_t addr, int count)
{ return 0; }
#include "syscon.h"
#include "spll_common.h"
#include "hw/etherbone-config.h"
static struct SYSCON_WB _syscon;
volatile struct SYSCON_WB *syscon = &_syscon;
static unsigned char _pps[sizeof(struct PPSG_WB)];
unsigned char *BASE_PPS_GEN = (void *)&_pps;
static unsigned char _pll[sizeof(struct SPLL_WB)];
unsigned char *BASE_SOFTPLL = (void *)&_pll;
static unsigned char _ebone[EB_IPV4 + 4];
unsigned char *BASE_ETHERBONE_CFG = (void *)&_ebone;
#include "i2c.h"
void mi2c_init(uint8_t i2cif)
{}
uint8_t mi2c_devprobe(uint8_t i2cif, uint8_t i2c_addr)
{ return 0; }
void mi2c_start(uint8_t i2cif)
{}
void mi2c_repeat_start(uint8_t i2cif)
{}
void mi2c_stop(uint8_t i2cif)
{}
unsigned char mi2c_put_byte(uint8_t i2cif, unsigned char data)
{ return 1; }
void mi2c_get_byte(uint8_t i2cif, unsigned char *data, uint8_t last)
{ *data = 0; }
#include <stdio.h>
#include <w1.h>
struct w1_bus wrpc_w1_bus;
void wrpc_w1_init(void)
{ printf("%s\n", __func__); }
int w1_scan_bus(struct w1_bus *bus)
{ printf("%s\n", __func__); return 0; }
int w1_read_eeprom_bus(struct w1_bus *bus,
int offset, uint8_t *buffer, int blen)
{ return -1; }
int w1_write_eeprom_bus(struct w1_bus *bus,
int offset, const uint8_t *buffer, int blen)
{ return -1; }
int w1_erase_eeprom_bus(struct w1_bus *bus, int offset, int blen)
{ return -1; }
void uart_exit(int i);
obj-$(CONFIG_HOST_PROCESS) += \
host/misc.o \
host/fake-i2c.o \
host/fake-w1.o \
host/fake-flash.o \
host/fake-hw.o \
host/ptp.o \
host/spll.o \
host/socket.o
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>
#include <termios.h>
#include <sys/select.h>
#include <sys/time.h>
#include "irq.h"
#include "uart.h"
#include "endpoint.h"
#include "pps_gen.h"
#include "rxts_calibrator.h"
#include "host.h"
uint32_t _endram;
int wrc_stat_running;
/* timer */
void usleep_init(void)
{ printf("%s\n", __func__); }
void timer_init(uint32_t enable)
{ printf("%s\n", __func__); }
void timer_delay(uint32_t tics)
{
usleep(tics * 1000);
}
uint32_t uptime_sec;
uint32_t timer_get_tics(void)
{
struct timeval tv;
uint64_t msecs;
gettimeofday(&tv, NULL);
msecs = tv.tv_sec * 1000 + tv.tv_usec / 1000;
return msecs;
}
void shw_pps_gen_get_time(uint64_t * seconds, uint32_t * nanoseconds)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
if (seconds)
*seconds = ts.tv_sec;
if (nanoseconds)
*nanoseconds = ts.tv_nsec / NS_PER_CLOCK;
}
/* uart */
void uart_init_hw(void)
{
struct termios t;
printf("%s\n", __func__);
tcgetattr(STDIN_FILENO, &t);
cfmakeraw(&t);
t.c_oflag |= ONLCR | OPOST;
tcsetattr(STDIN_FILENO, 0, &t);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stdin, NULL, _IONBF, 0);
printf("UART simulator on the host: use ctrl-C or ctrl-D to exit\n");
}
void uart_init_sw(void)
{ printf("%s\n", __func__); }
void uart_exit(int i)
{
system("stty sane");
exit(i);
}
int uart_read_byte(void)
{
fd_set set;
int ret = -1;
struct timeval tv = {0, 0};
FD_ZERO(&set);
FD_SET(STDIN_FILENO, & set);
if (select(STDIN_FILENO + 1, &set, NULL, NULL, &tv) > 0)
ret = getchar();
/* Use ctrl-C and ctrl-D specially (hack!) */
if (ret == 3 || ret == 4) {
uart_exit(0);
}
return ret;
}
/* unused stuff */
void disable_irq(void)
{ printf("%s\n", __func__); }
void enable_irq(void)
{ printf("%s\n", __func__); }
int wrc_mon_gui(void)
{ printf("%s\n", __func__); return 0;}
void sdb_find_devices(void)
{ printf("%s\n", __func__); }
int calib_t24p(int mode, uint32_t *value)
{ return 0; }
int ep_get_bitslide(void)
{ return 0; }
int ep_enable(int enabled, int autoneg)
{ return 0; }
void ep_init(uint8_t mac_addr[])
{ printf("%s\n", __func__); }
void pfilter_init_default(void)
{}
static int task_relax(void)
{
usleep(1000);
return 1; /* we did something */
}
DEFINE_WRC_TASK(relax) = {
.name = "relax",
.job = task_relax,
};
#include "wrc_ptp.h"
int wrc_ptp_init(void)
{ return 0; }
int wrc_ptp_set_mode(int mode)
{ return 0; }
int wrc_ptp_get_mode(void)
{ return 0; }
int wrc_ptp_start(void)
{ return 0; }
int wrc_ptp_stop(void)
{ return 0; }
int wrc_ptp_update(void)
{ return 0; }
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <net/if_arp.h>
#include "include/types.h" /* with "types.h" I might get the standard one... */
#include "endpoint.h"
#include "ptpd_netif.h"
#include "minic.h"
#include "hw/pps_gen_regs.h"
#include "host.h"
static int dumpstruct(FILE *dest, char *name, void *ptr, int size)
{
int ret, i;
unsigned char *p = ptr;
if (!NET_IS_VERBOSE)
return 0;
ret = fprintf(dest, "dump %s at %p (size 0x%x)\n", name, ptr, size);
for (i = 0; i < size; ) {
ret += fprintf(dest, "%02x", p[i]);
i++;
ret += fprintf(dest, i & 3 ? " " : i & 0xf ? " " : "\n");
}
if (i & 0xf)
ret += fprintf(dest, "\n");
return ret;
}
static char ifname[16];
static char ethaddr[ETH_ALEN];
static int ethaddr_ok;
int sock;
void minic_init(void)
{
char *name = getenv("WRPC_MINIC");
struct ifreq ifr;
struct packet_mreq req;
struct sockaddr_ll addr;
int ethindex;
if (!name)
name = "eth0";
strcpy(ifname, name);
printf("%s: using %s as interface\n", __func__, ifname);
sock = socket(PF_PACKET, SOCK_RAW | SOCK_NONBLOCK, ETH_P_1588);
if (sock < 0) {
printf("%s: can`t open raw socket: %s\n",
__func__, strerror(errno));
}
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, ifname);
if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) {
printf("%s: can`t get hw address of \"%s\": %s\n",
__func__, ifname, strerror(errno));
}
memcpy(ethaddr, &ifr.ifr_ifru.ifru_hwaddr.sa_data, ETH_ALEN);
ethaddr_ok = 1;
strcpy(ifr.ifr_name, ifname);
if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) {
printf("%s: can`t get index of \"%s\": %s\n",
__func__, ifname, strerror(errno));
}
ethindex = ifr.ifr_ifindex;
memset(&req, 0, sizeof(req));
req.mr_ifindex = ethindex;
req.mr_type = PACKET_MR_PROMISC;
if (setsockopt(sock, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
&req, sizeof(req)) < 0) {
printf("%s: can`t set \"%s\" to promiscuous mode: %s\n",
__func__, ifname, strerror(errno));
}
addr.sll_family = AF_PACKET;
addr.sll_protocol = htons(ETH_P_ALL);
addr.sll_ifindex = ifr.ifr_ifindex;
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
fprintf(stderr, "%s: can't bind to \"%s\": %s\n",
__func__, ifname, strerror(errno));
}
/* Finally, put the current date into the SEC counter of ppsg */
{
uint64_t utc = time(NULL);
uint32_t *ptr;
ptr = (void *)BASE_PPS_GEN
+ offsetof(struct PPSG_WB, CNTR_UTCLO);
*ptr = utc;
ptr = (void *)BASE_PPS_GEN
+ offsetof(struct PPSG_WB, CNTR_UTCHI);
*ptr = utc >> 32;
}
}
/* We have a problem: this is called before minic_init(), so we dup code */
void get_mac_addr(uint8_t dev_addr[])
{
char *name = getenv("WRPC_MINIC");
struct ifreq ifr;
int sock;
if (ethaddr_ok) {
memcpy(dev_addr, ethaddr, ETH_ALEN);
return;
}
if (!name)
name = "eth0";
sock = socket(PF_PACKET, SOCK_RAW | SOCK_NONBLOCK, ETH_P_1588);
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, name);
ioctl(sock, SIOCGIFHWADDR, &ifr);
memcpy(dev_addr, &ifr.ifr_ifru.ifru_hwaddr.sa_data, ETH_ALEN);
close(sock);
}
void set_mac_addr(uint8_t dev_addr[])
{
printf("%s: no implemented yet\n", __func__);
}
int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size,
struct hw_timestamp *hwts)
{
unsigned char frame[1500];
struct timespec ts;
int ret;
ret = recv(sock, frame, sizeof(frame), MSG_DONTWAIT);
clock_gettime(CLOCK_REALTIME, &ts);
if (ret < 0 && errno == EAGAIN)
return 0;
if (ret < 0) {
printf("recv(): %s\n", strerror(errno));
uart_exit(1);
}
memcpy(hdr, frame, 14);
dumpstruct(stdout, "rx header", hdr, 14);
ret -= 14;
dumpstruct(stdout, "rx payload", frame + 14, ret);
if (ret > buf_size) {
printf("warning: truncating frame to %i\n", buf_size);
ret = buf_size;
}
memcpy(payload, frame + 14, ret);
hwts->sec = ts.tv_sec;
hwts->nsec = ts.tv_nsec;
hwts->phase = 0;
net_verbose("%s: %9li.%09i.%03i\n", __func__, (long)hwts->sec,
hwts->nsec, hwts->phase);
return ret;
}
int minic_tx_frame(struct wr_ethhdr_vlan *hdr, uint8_t * payload, uint32_t size,
struct hw_timestamp *hwts)
{
unsigned char frame[1500];
struct timespec ts;
int hsize, len;
if (hdr->ethtype == htons(0x8100))
hsize = sizeof(struct wr_ethhdr_vlan);
else
hsize = sizeof(struct wr_ethhdr);
dumpstruct(stdout, "tx header", hdr, hsize);
dumpstruct(stdout, "tx payload", payload, size);
memcpy(frame, hdr, hsize);
memcpy(frame + hsize, payload, size);
clock_gettime(CLOCK_REALTIME, &ts);
len = send(sock, frame, size + hsize, 0);
hwts->sec = ts.tv_sec;
hwts->nsec = ts.tv_nsec;
hwts->phase = 0;
net_verbose("%s: %9li.%09i.%03i\n", __func__, (long)hwts->sec,
hwts->nsec, hwts->phase);
return len;
}
int wrpc_get_port_state(struct hal_port_state *port, const char *port_name)
{
return 0;
}
int ep_link_up(uint16_t * lpa)
{
struct ifreq ifr;
strcpy(ifr.ifr_name, ifname);
if ( ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
ifr.ifr_flags = ~0; /* assume up, don't be messy */
}
if (ifr.ifr_flags & IFF_UP
&& ifr.ifr_flags & IFF_RUNNING)
return 1;
return 0;
}
#include "softpll_ng.h"
void spll_very_init(void)
{}
void spll_init(int mode, int ref_channel, int align_pps)
{}
void spll_enable_ptracker(int ref_channel, int enable)
{}
void spll_set_phase_shift(int out_channel, int32_t value_picoseconds)
{}
int spll_shifter_busy(int out_channel)
{ return 1; }
int spll_check_lock(int out_channel)
{ return 0; }
int spll_update(void)
{ return 0; }
int spll_read_ptracker(int ref_channel, int32_t *phase_ps, int *enabled)
{ return 0; }
......@@ -31,10 +31,10 @@
#define UART_BAUDRATE 115200ULL
/* Maximum number of simultaneously created sockets */
#define NET_MAX_SOCKETS 4
#define NET_MAX_SOCKETS 12
/* Socket buffer size, determines the max. RX packet size */
#define NET_SKBUF_SIZE 512
#define NET_MAX_SKBUF_SIZE 512
/* Number of auxillary clock channels - usually equal to the number of FMCs */
#define NUM_AUX_CLOCKS 1
......@@ -52,5 +52,10 @@ int board_update(void);
#define BOARD_MAX_CHAN_AUX 2
#define BOARD_MAX_PTRACKERS 1
#ifdef CONFIG_IP
#define HAS_IP 1
#else
#define HAS_IP 0
#endif
#endif /* __BOARD_WRC_H */
/*
* This header defines structures for dumping other structures from
* binary files. Every arch has a different endianness and alignment/size,
* so we can't just use the structures from the host compiler. It used to
* work for lm32/i386, but it fails with x86-64, so let's change attitude.
*/
#include <stdint.h>
/*
* To ease copying from header files, allow int, char and other known types.
* Please add more type as more structures are included here
*/
enum dump_type {
dump_type_char, /* for zero-terminated strings */
dump_type_bina, /* for binary stull in MAC format */
/* normal types follow */
dump_type_uint32_t,
dump_type_uint16_t,
dump_type_int,
dump_type_unsigned_long,
dump_type_unsigned_char,
dump_type_unsigned_short,
dump_type_double,
dump_type_float,
dump_type_pointer,
/* and strange ones, from IEEE */
dump_type_UInteger64,
dump_type_Integer64,
dump_type_UInteger32,
dump_type_Integer32,
dump_type_UInteger16,
dump_type_Integer16,
dump_type_UInteger8,
dump_type_Integer8,
dump_type_Enumeration8,
dump_type_Boolean,
dump_type_ClockIdentity,
dump_type_PortIdentity,
dump_type_ClockQuality,
/* and this is ours */
dump_type_TimeInternal,
dump_type_ip_address,
};
/* because of the sizeof later on, we need these typedefs */
typedef void * pointer;
typedef unsigned long unsigned_long;
typedef unsigned char unsigned_char;
typedef unsigned short unsigned_short;
typedef struct {unsigned char addr[4];} ip_address;
/*
* This is generated with the target compiler, and then linked
* by the host compiler, so size and alignment must be safe. Then, the
* first structure in each group has the endian flag and the structure name.
* Following ones have zero in endian flag and field name.
*/
#define DUMP_ENDIAN_FLAG 0x12345678
struct dump_info {
uint32_t endian_flag;
uint32_t type;
uint32_t offset;
uint32_t size;
char name[48];
};
extern struct dump_info dump_info[]; /* wrpc-sw/dump-info.c -> bina -> elf */
#define DUMP_HEADER(_struct) { \
.endian_flag = DUMP_ENDIAN_FLAG, \
.name = _struct, \
}
/* The macros below rely on DUMP_STRUCT that must be externally defined */
#define DUMP_FIELD(_type, _fname) { \
.endian_flag = 0, \
.type = dump_type_ ## _type, \
.offset = offsetof(DUMP_STRUCT, _fname),\
.size = sizeof(_type), \
.name = #_fname, \
}
#define DUMP_FIELD_SIZE(_type, _fname, _size) { \
.endian_flag = 0, \
.type = dump_type_ ## _type, \
.offset = offsetof(DUMP_STRUCT, _fname),\
.size = _size, \
.name = #_fname, \
}
......@@ -6,12 +6,17 @@
#ifndef __IRQ_H
#define __IRQ_H
#ifdef unix
static inline void clear_irq(void) {}
#else
static inline void clear_irq(void)
{
unsigned int val = 1;
asm volatile ("wcsr ip, %0"::"r" (val));
}
#endif
void disable_irq(void);
void enable_irq(void);
void _irq_entry(void);
......
......@@ -19,9 +19,34 @@ void minic_disable(void);
int minic_poll_rx(void);
void minic_get_stats(int *tx_frames, int *rx_frames);
int minic_rx_frame(uint8_t * hdr, uint8_t * payload, uint32_t buf_size,
struct wr_ethhdr {
uint8_t dstmac[6];
uint8_t srcmac[6];
uint16_t ethtype;
};
struct wr_ethhdr_vlan {
uint8_t dstmac[6];
uint8_t srcmac[6];
uint16_t ethtype;
uint16_t tag;
uint16_t ethtype_2;
};
struct wr_minic {
volatile uint32_t *rx_head, *rx_base;
uint32_t rx_avail, rx_size;
volatile uint32_t *tx_head, *tx_base;
uint32_t tx_avail, tx_size;
int tx_count, rx_count;
};
extern struct wr_minic minic;
int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size,
struct hw_timestamp *hwts);
int minic_tx_frame(uint8_t * hdr, uint8_t * payload, uint32_t size,
int minic_tx_frame(struct wr_ethhdr_vlan *hdr, uint8_t * payload, uint32_t size,
struct hw_timestamp *hwts);
#endif
......@@ -8,8 +8,14 @@
#include <stdlib.h>
#include <stdint.h>
#ifndef __IEEE_BIG_ENDIAN
#error "Not big endian, or unknown endianness"
#endif
#ifdef CONFIG_HOST_PROCESS
# include <arpa/inet.h>
#else
# ifndef __IEEE_BIG_ENDIAN
# error "Not big endian, or unknown endianness"
# endif
static inline uint16_t ntohs(uint16_t x) {return x;}
static inline uint16_t ntohs(uint16_t x) {return x;}
#endif
......@@ -15,17 +15,14 @@
#include <board.h>
//#include <inttypes.h>
#define PTPD_SOCK_RAW_ETHERNET 1 /* used in ppsi to no aim: remove this */
#define PTPD_SOCK_UDP 0 /* wrong name, it should be "WRPC" */
#define PTPD_SOCK_RAW_ETHERNET 1 /* but used in ppsi, which I won't change */
#define PTPD_FLAGS_MULTICAST 0x1
// error codes (to be extended)
#define PTPD_NETIF_READY 1
#define PTPD_NETIF_OK 0
#define PTPD_NETIF_ERROR -1
#define PTPD_NETIF_NOT_READY -2
#define PTPD_NETIF_NOT_FOUND -3
extern int link_status;
#define LINK_DOWN 0
#define LINK_WENT_UP 1
#define LINK_WENT_DOWN 2
#define LINK_UP 3
// GCC-specific
#ifndef PACKED
......@@ -34,35 +31,38 @@
#define PHYS_PORT_ANY (0xffff)
#define PTPD_NETIF_TX 1
#define PTPD_NETIF_RX 2
#define IFACE_NAME_LEN 16
#define SLAVE_PRIORITY_0 0
#define SLAVE_PRIORITY_1 1
#define SLAVE_PRIORITY_2 2
#define SLAVE_PRIORITY_3 3
#define SLAVE_PRIORITY_4 4
// Some system-independent definitions
typedef uint8_t mac_addr_t[6];
typedef uint32_t ipv4_addr_t;
// WhiteRabbit socket - it's void pointer as the real socket structure is private and probably platform-specific.
typedef void *wr_socket_t;
// Socket address for ptp_netif_ functions
typedef struct {
// MAC address
struct wr_sockaddr {
// MAC address
mac_addr_t mac;
// Destination MASC address, filled by recvfrom() function on interfaces bound to multiple addresses
// Destination MAC address, filled by recvfrom()
mac_addr_t mac_dest;
// RAW ethertype
// RAW ethertype
uint16_t ethertype;
} wr_sockaddr_t;
uint16_t udpport;
uint16_t vlan;
};
PACKED struct _wr_timestamp {
struct sockq {
uint16_t head, tail, avail, size;
uint16_t n;
uint8_t *buff;
};
struct wrpc_socket {
struct wr_sockaddr bind_addr;
mac_addr_t local_mac;
uint16_t prio;
uint32_t phase_transition;
uint32_t dmtd_phase;
struct sockq queue;
};
PACKED struct wr_timestamp {
// Seconds
int64_t sec;
......@@ -70,7 +70,7 @@ PACKED struct _wr_timestamp {
// Nanoseconds
int32_t nsec;
// Phase (in picoseconds), linearized for receive timestamps, zero for send timestamps
// Phase (in picoseconds), linearized for rx, zero for send timestamps
int32_t phase; // phase(picoseconds)
/* Raw time (non-linearized) for debugging purposes */
......@@ -78,54 +78,45 @@ PACKED struct _wr_timestamp {
int32_t raw_nsec;
int32_t raw_ahead;
// correctness flag: when 0, the timestamp MAY be incorrect (e.g. generated during timebase adjustment)
// when 0, tstamp MAY be incorrect (e.g. during timebase adjustment)
int correct;
//int cntr_ahead;
};
typedef struct _wr_timestamp wr_timestamp_t;
/* OK. These functions we'll develop along with network card driver. You can write your own UDP-based stubs for testing purposes. */
// Initialization of network interface:
// - opens devices
// - does necessary ioctls()
// - initializes connection with the mighty HAL daemon
int ptpd_netif_init(void);
// Creates UDP or Ethernet RAW socket (determined by sock_type) bound to bind_addr. If PTPD_FLAG_MULTICAST is set, the socket is
// automatically added to multicast group. User can specify physical_port field to bind the socket to specific switch port only.
wr_socket_t *ptpd_netif_create_socket(int unused, int unused2,
wr_sockaddr_t * bind_addr);
// Creates UDP or Ethernet RAW socket (determined by sock_type) bound
// to bind_addr.
struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *s,
struct wr_sockaddr * bind_addr,
int udp_or_raw, int udpport);
// Sends a UDP/RAW packet (data, data_length) to address provided in wr_sockaddr_t.
// Sends a UDP/RAW packet (data, data_length) to addr in wr_sockaddr.
// For raw frames, mac/ethertype needs to be provided, for UDP - ip/port.
// Every transmitted frame has assigned a tag value, stored at tag parameter. This value is later used
// for recovering the precise transmit timestamp. If user doesn't need it, tag parameter can be left NULL.
int ptpd_netif_sendto(wr_socket_t * sock, wr_sockaddr_t * to, void *data,
size_t data_length, wr_timestamp_t * tx_ts);
// Receives an UDP/RAW packet. Data is written to (data) and length is returned. Maximum buffer length can be specified
// by data_length parameter. Sender information is stored in structure specified in 'from'. All RXed packets are timestamped and the timestamp
// Every transmitted frame has assigned a tag value, stored at tag parameter.
// This value is later used for recovering the precise transmit timestamp.
// If user doesn't need it, tag parameter can be left NULL.
int ptpd_netif_sendto(struct wrpc_socket *sock, struct wr_sockaddr *to, void *data,
size_t data_length, struct wr_timestamp *tx_ts);
// Receives an UDP/RAW packet. Data is written to (data) and len is returned.
// Maximum buffer length can be specified by data_length parameter.
// Sender information is stored in structure specified in 'from'.
// All RXed packets are timestamped and the timestamp
// is stored in rx_timestamp (unless it's NULL).
int ptpd_netif_recvfrom(wr_socket_t * sock, wr_sockaddr_t * from, void *data,
size_t data_length, wr_timestamp_t * rx_timestamp);
int ptpd_netif_recvfrom(struct wrpc_socket *sock, struct wr_sockaddr *from, void *data,
size_t data_length, struct wr_timestamp *rx_timestamp);
// Closes the socket.
int ptpd_netif_close_socket(wr_socket_t * sock);
int ptpd_netif_get_hw_addr(wr_socket_t * sock, mac_addr_t * mac);
int ptpd_netif_close_socket(struct wrpc_socket * sock);
int ptpd_netif_get_hw_addr(wr_socket_t * sock, mac_addr_t * mac);
int ptpd_netif_get_hw_addr(struct wrpc_socket * sock, mac_addr_t * mac);
void ptpd_netif_linearize_rx_timestamp(wr_timestamp_t * ts, int32_t dmtd_phase,
void ptpd_netif_linearize_rx_timestamp(struct wr_timestamp *ts,
int32_t dmtd_phase,
int cntr_ahead, int transition_point,
int clock_period);
void ptpd_netif_set_phase_transition(uint32_t phase);
struct hal_port_state;
int wrpc_get_port_state(struct hal_port_state *port, const char *port_name /* unused */);
int wrpc_get_port_state(struct hal_port_state *port,
const char *port_name /* unused */);
#endif /* __PTPD_NETIF_H */
......@@ -4,5 +4,6 @@
extern const char *build_revision;
extern const char *build_date;
extern const char *build_time;
extern const char *build_by;
#endif /* __REVISION_H__ */
......@@ -9,10 +9,27 @@
#include <stdint.h>
#define SFP_PN_LEN 16
#define SFP_NOT_MATCHED 1
#define SFP_MATCHED 2
#define SFP_GET 0
#define SFP_ADD 1
extern char sfp_pn[SFP_PN_LEN];
extern int32_t sfp_in_db;
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);
#endif
......@@ -14,6 +14,10 @@ extern int wrc_stat_running;
const char *fromhex(const char *hex, int *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);
void decode_ip(const char *str, unsigned char *ip);
char *format_ip(char *s, const unsigned char *ip);
struct wrc_shell_cmd {
char *name;
......@@ -31,8 +35,8 @@ int env_set(const char *var, const char *value);
void env_init(void);
int shell_exec(const char *buf);
void shell_interactive(void);
int shell_interactive(void);
int shell_boot_script(void);
void shell_boot_script(void);
#endif
......@@ -11,6 +11,8 @@ typedef signed short int16_t;
typedef signed int int32_t;
typedef signed long long int64_t;
typedef unsigned long intptr_t;
#define UINT32_MAX 4294967295U
#endif
......@@ -9,21 +9,43 @@
#ifndef __STORAGE_H
#define __STORAGE_H
#include "sfp.h"
#define SFP_SECTION_PATTERN 0xdeadbeef
#if defined CONFIG_LEGACY_EEPROM
#define EE_BASE_CAL (4 * 1024)
#define EE_BASE_SFP (4 * 1024 + 4)
/* Limit SFPs to 3, see comments below why. */
#define SFPS_MAX 3
/* The definition of EE_BASE_INIT below is wrong! But kept for backward
* compatibility. */
#define EE_BASE_INIT (4 * 1024 + 4 * 29)
/* It should be:
* #define EE_BASE_INIT (EE_BASE_SFP + sizeof(sfpcount) + \
* SFPS_MAX * sizeof(struct s_sfpinfo))
* The used definition define the start of the init script 5 bytes
* (sizeof(sfpcount) + sizeof(t24p)) before the end of SFP database.
* To make the init script working during the update of old versions of wrpc
* SFPS_MAX is limited to 3. Adding the 4th SFP will corrupt the init script
* anyway.
* If someone needs to have 4 SFPs in the database SFPS_MAX can be set to 4 and
* the proper define should be used.
* SDB is not affected by this bug.
*/
#endif
#if defined CONFIG_SDB_STORAGE
#define SFPS_MAX 4
#define SFP_PN_LEN 16
#define EE_BASE_CAL 4*1024
#define EE_BASE_SFP 4*1024+4
#define EE_BASE_INIT 4*1024+SFPS_MAX*29
#endif
#define EE_RET_I2CERR -1
#define EE_RET_DBFULL -2
#define EE_RET_CORRPT -3
#define EE_RET_POSERR -4
extern int32_t sfp_alpha;
extern int32_t sfp_deltaTx;
extern int32_t sfp_deltaRx;
extern uint32_t cal_phase_transition;
extern uint8_t has_eeprom;
......
......@@ -34,7 +34,9 @@ static inline void timer_delay_ms(int ms)
/* usleep.c */
extern void usleep_init(void);
#ifndef unix
extern int usleep(useconds_t usec);
#endif
#ifdef CONFIG_WR_NODE
......
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2016 GSI (www.gsi.de)
* Author: Alessandro rubini
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#ifndef __TEMPERATURE_H__
#define __TEMPERATURE_H__
struct wrc_onetemp {
char *name;
int32_t t; /* fixed point, 16.16 (signed!) */
};
#define TEMP_INVALID (0x8000 << 16)
struct wrc_temp {
int (*read)(struct wrc_temp *);
void *data;
struct wrc_onetemp *t; /* zero-terminated */
};
#define DEFINE_TEMPERATURE(_name) \
static struct wrc_temp __wrc_temp_ ## _name \
__attribute__((section(".temp"), __used__))
/* lib functions */
extern uint32_t wrc_temp_get(char *name);
struct wrc_onetemp *wrc_temp_getnext(struct wrc_onetemp *);
extern int wrc_temp_format(char *buffer, int len);
#endif /* __TEMPERATURE_H__ */
#ifndef __FREESTANDING_TRACE_H__
#define __FREESTANDING_TRACE_H__
#ifdef CONFIG_WR_NODE
#include <wrc.h>
#ifdef CONFIG_NET_VERBOSE
#define NET_IS_VERBOSE 1
#else
#define NET_IS_VERBOSE 0
#endif
#ifdef CONFIG_PLL_VERBOSE
#define PLL_IS_VERBOSE 1
#else
#define PLL_IS_VERBOSE 0
#endif
#ifdef CONFIG_PFILTER_VERBOSE
#define PFILTER_IS_VERBOSE 1
#else
#define PFILTER_IS_VERBOSE 0
#endif
#ifdef CONFIG_WRC_VERBOSE
#define WRC_IS_VERBOSE 1
#else
#define WRC_IS_VERBOSE 0
#endif
#ifdef CONFIG_SNMP_VERBOSE
#define SNMP_IS_VERBOSE 1
#else
#define SNMP_IS_VERBOSE 0
#endif
#define TRACE_WRAP(...)
#define TRACE_DEV(...) wrc_debug_printf(0, __VA_ARGS__)
#define pll_verbose(...) \
({if (PLL_IS_VERBOSE) __debug_printf(__VA_ARGS__);})
#else /* WR_SWITCH */
#define pfilter_verbose(...) \
({if (PFILTER_IS_VERBOSE) __debug_printf(__VA_ARGS__);})
#include <pp-printf.h>
#define TRACE(...) pp_printf(__VA_ARGS__)
#define TRACE_DEV(...) pp_printf(__VA_ARGS__)
#define wrc_verbose(...) \
({if (WRC_IS_VERBOSE) __debug_printf(__VA_ARGS__);})
#endif /* node/switch */
#define net_verbose(...) \
({if (NET_IS_VERBOSE) __debug_printf(__VA_ARGS__);})
#define snmp_verbose(...) \
({if (SNMP_IS_VERBOSE) __debug_printf(__VA_ARGS__);})
#ifdef CONFIG_HOST_PROCESS
#define IS_HOST_PROCESS 1
#else
#define IS_HOST_PROCESS 0
#endif
#endif /* __FREESTANDING_TRACE_H__ */
......@@ -16,14 +16,19 @@
#define C_BLUE 4
/* Return TAI date/time in human-readable form. Non-reentrant. */
char *format_time(uint64_t sec);
char *format_time(uint64_t sec, int format);
#define TIME_FORMAT_LEGACY 0
#define TIME_FORMAT_SYSLOG 1
#define TIME_FORMAT_SORTED 2
/* Color printf() variant. */
void cprintf(int color, const char *fmt, ...);
/* Color printf() variant, sets curspor position to (row, col) before printing. */
/* Color printf() variant, sets curspor position to (row, col) too. */
void pcprintf(int row, int col, int color, const char *fmt, ...);
void __debug_printf(const char *fmt, ...);
/* Clears the terminal scree. */
void term_clear(void);
......
/*
* This work is part of the White Rabbit project
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#ifndef __WRC_TASK_H__
#define __WRC_TASK_H__
/*
* A task is a data structure, but currently suboptimal.
* FIXME: init must return int, and both should get a pointer to data
* (but doing this is heavy, and forces to change the submodule too).
*/
struct wrc_task {
char *name;
int *enable; /* A global enable variable */
void (*init)(void);
int (*job)(void);
/* And we keep statistics about cpu usage */
unsigned long nrun;
unsigned long seconds;
unsigned long nanos;
};
/* An helper for periodic tasks, relying on a static varible */
static inline int __task_not_yet(uint32_t *lastt, unsigned period,
uint32_t now)
{
if (!*lastt) {
*lastt = now;
return 0;
}
if (time_before(now, *lastt + period))
return 1; /* not yet */
*lastt += period;
return 0;
}
static inline int task_not_yet(uint32_t *lastt, unsigned period)
{
return __task_not_yet(lastt, period, timer_get_tics());
}
/* Put the tasks in their own section */
#define DEFINE_WRC_TASK(_name) \
static struct wrc_task __task_ ## _name \
__attribute__((section(".task"), used, aligned(sizeof(unsigned long))))
/* Task 0 must be first, sorry! */
#define DEFINE_WRC_TASK0(_name) \
static struct wrc_task __task_ ## _name \
__attribute__((section(".task0"), used, aligned(sizeof(unsigned long))))
extern struct wrc_task __task_begin[];
extern struct wrc_task __task_end[];
#define for_each_task(t) for ((t) = __task_begin; (t) < __task_end; (t)++)
#endif /* __WRC_TASK_H__ */
......@@ -15,11 +15,21 @@
#include <inttypes.h>
#include <syscon.h>
#include <pp-printf.h>
#include <util.h>
#include <trace.h>
#include <wrc-task.h>
#define vprintf pp_vprintf
#define sprintf pp_sprintf
#ifndef min
#define min(a, b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a < _b ? _a : _b; })
#endif
#undef offsetof
#define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)
#define offsetof(TYPE, MEMBER) ((long) &((TYPE *)0)->MEMBER)
#undef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
......@@ -32,10 +42,10 @@
# define is_wr_node 1
#endif
void wrc_mon_gui(void);
extern int wrc_vlan_number;
int wrc_mon_gui(void);
void shell_init(void);
int wrc_log_stats(void);
void wrc_debug_printf(int subsys, const char *fmt, ...);
/* This header is included by softpll: manage wrc/wrs difference */
#ifdef CONFIG_WR_NODE
......@@ -50,10 +60,6 @@ void wrc_debug_printf(int subsys, const char *fmt, ...);
/* This is in the library, somewhere */
extern int abs(int val);
/* The following from ptp-noposix */
extern void wr_servo_reset(void);
void update_rx_queues(void);
/* refresh period for _gui_ and _stat_ commands */
extern int wrc_ui_refperiod;
......
......@@ -188,8 +188,9 @@ int minipc_server_action(struct minipc_ch *ch, int timeoutms)
if (!(strcmp(p_in->name, flist->pd->name)))
break;
if (!flist) {
int i = EOPNOTSUPP;
p_out->type = MINIPC_ARG_ENCODE(MINIPC_ATYPE_ERROR, int);
*(int *)(&p_out->val) = EOPNOTSUPP;
memcpy(&p_out->val, &i, sizeof(i));
goto send_reply;
}
pd = flist->pd;
......@@ -198,7 +199,7 @@ int minipc_server_action(struct minipc_ch *ch, int timeoutms)
i = pd->f(pd, p_in->args, p_out->val);
if (i < 0) {
p_out->type = MINIPC_ARG_ENCODE(MINIPC_ATYPE_ERROR, int);
*(int *)(&p_out->val) = errno;
memcpy(&p_out->val, &errno, sizeof(errno));
} else {
/* Use retval, but fix the length for strings */
if (MINIPC_GET_ATYPE(pd->retval) == MINIPC_ATYPE_STRING) {
......
......@@ -40,7 +40,7 @@ static void clear_state(void)
/* Sets the phase setpoint on a given channel */
int rts_adjust_phase(int channel, int32_t phase_setpoint)
{
// TRACE("Adjusting phase: ref channel %d, setpoint=%d ps.\n", channel, phase_setpoint);
// pp_printf("Adjusting phase: ref channel %d, setpoint=%d ps.\n", channel, phase_setpoint);
spll_set_phase_shift(0, phase_setpoint);
pstate.channels[channel].phase_setpoint = phase_setpoint;
return 0;
......@@ -69,7 +69,7 @@ int rts_set_mode(int mode)
for(i=0;options[i].desc != NULL;i++)
if(mode == options[i].mode_rt)
{
TRACE("RT: Setting mode to %s.\n", options[i].desc);
pp_printf("RT: Setting mode to %s.\n", options[i].desc);
if(options[i].do_init)
spll_init(options[i].mode_spll, 0, 1);
else
......@@ -84,12 +84,12 @@ int rts_lock_channel(int channel, int priority)
{
if(pstate.mode != RTS_MODE_BC)
{
TRACE("trying to lock while not in slave mode,..\n");
pp_printf("trying to lock while not in slave mode,..\n");
return -1;
}
TRACE("RT [slave]: Locking to: %d (prio %d)\n", channel, priority);
pp_printf("RT [slave]: Locking to: %d (prio %d)\n", channel, priority);
spll_init(SPLL_MODE_SLAVE, channel, 0);
pstate.current_ref = channel;
......
This diff is collapsed.
......@@ -16,7 +16,12 @@
#define htons(x) x
#endif
static wr_socket_t *arp_socket;
static uint8_t __arp_queue[128];
static struct wrpc_socket __static_arp_socket = {
.queue.buff = __arp_queue,
.queue.size = sizeof(__arp_queue),
};
static struct wrpc_socket *arp_socket;
#define ARP_HTYPE 0
#define ARP_PTYPE (ARP_HTYPE+2)
......@@ -29,16 +34,17 @@ static wr_socket_t *arp_socket;
#define ARP_TPA (ARP_THA+6)
#define ARP_END (ARP_TPA+4)
void arp_init(void)
static void arp_init(void)
{
wr_sockaddr_t saddr;
struct wr_sockaddr saddr;
/* Configure socket filter */
memset(&saddr, 0, sizeof(saddr));
memset(&saddr.mac, 0xFF, 6); /* Broadcast */
saddr.ethertype = htons(0x0806); /* ARP */
arp_socket = ptpd_netif_create_socket(0, 0 /* both unused */, &saddr);
arp_socket = ptpd_netif_create_socket(&__static_arp_socket, &saddr,
PTPD_SOCK_RAW_ETHERNET, 0);
}
static int process_arp(uint8_t * buf, int len)
......@@ -82,17 +88,27 @@ static int process_arp(uint8_t * buf, int len)
return ARP_END;
}
void arp_poll(void)
static int arp_poll(void)
{
uint8_t buf[ARP_END + 100];
wr_sockaddr_t addr;
struct wr_sockaddr addr;
int len;
if (needIP)
return; /* can't do ARP w/o an address... */
if (ip_status == IP_TRAINING)
return 0; /* can't do ARP w/o an address... */
if ((len = ptpd_netif_recvfrom(arp_socket,
&addr, buf, sizeof(buf), 0)) > 0)
&addr, buf, sizeof(buf), 0)) > 0) {
if ((len = process_arp(buf, len)) > 0)
ptpd_netif_sendto(arp_socket, &addr, buf, len, 0);
return 1;
}
return 0;
}
DEFINE_WRC_TASK(arp) = {
.name = "arp",
.enable = &link_status,
.init = arp_init,
.job = arp_poll,
};
......@@ -12,30 +12,6 @@
#include "ipv4.h"
#define IP_VERSION 0
#define IP_TOS (IP_VERSION+1)
#define IP_LEN (IP_TOS+1)
#define IP_ID (IP_LEN+2)
#define IP_FLAGS (IP_ID+2)
#define IP_TTL (IP_FLAGS+2)
#define IP_PROTOCOL (IP_TTL+1)
#define IP_CHECKSUM (IP_PROTOCOL+1)
#define IP_SOURCE (IP_CHECKSUM+2)
#define IP_DEST (IP_SOURCE+4)
#define IP_END (IP_DEST+4)
#define UDP_VIRT_SADDR (IP_END-12)
#define UDP_VIRT_DADDR (UDP_VIRT_SADDR+4)
#define UDP_VIRT_ZEROS (UDP_VIRT_DADDR+4)
#define UDP_VIRT_PROTO (UDP_VIRT_ZEROS+1)
#define UDP_VIRT_LENGTH (UDP_VIRT_PROTO+1)
#define UDP_SPORT (IP_END)
#define UDP_DPORT (UDP_SPORT+2)
#define UDP_LENGTH (UDP_DPORT+2)
#define UDP_CHECKSUM (UDP_LENGTH+2)
#define UDP_END (UDP_CHECKSUM+2)
#define BOOTP_OP (UDP_END)
#define BOOTP_HTYPE (BOOTP_OP+1)
#define BOOTP_HLEN (BOOTP_HTYPE+1)
......@@ -53,9 +29,9 @@
#define BOOTP_VEND (BOOTP_FILE+128)
#define BOOTP_END (BOOTP_VEND+64)
int send_bootp(uint8_t * buf, int retry)
int prepare_bootp(struct wr_sockaddr *addr, uint8_t * buf, int retry)
{
unsigned short sum;
struct wr_udp_addr uaddr;
// ----------- BOOTP ------------
buf[BOOTP_OP] = 1; /* bootrequest */
......@@ -86,54 +62,16 @@ int send_bootp(uint8_t * buf, int retry)
memset(buf + BOOTP_FILE, 0, 128); /* desired BOOTP file */
memset(buf + BOOTP_VEND, 0, 64); /* vendor extensions */
// ------------ UDP -------------
memset(buf + UDP_VIRT_SADDR, 0, 4);
memset(buf + UDP_VIRT_DADDR, 0xFF, 4);
buf[UDP_VIRT_ZEROS] = 0;
buf[UDP_VIRT_PROTO] = 0x11; /* UDP */
buf[UDP_VIRT_LENGTH] = (BOOTP_END - IP_END) >> 8;
buf[UDP_VIRT_LENGTH + 1] = (BOOTP_END - IP_END) & 0xff;
buf[UDP_SPORT] = 0;
buf[UDP_SPORT + 1] = 68; /* BOOTP client */
buf[UDP_DPORT] = 0;
buf[UDP_DPORT + 1] = 67; /* BOOTP server */
buf[UDP_LENGTH] = (BOOTP_END - IP_END) >> 8;
buf[UDP_LENGTH + 1] = (BOOTP_END - IP_END) & 0xff;
buf[UDP_CHECKSUM] = 0;
buf[UDP_CHECKSUM + 1] = 0;
sum =
ipv4_checksum((unsigned short *)(buf + UDP_VIRT_SADDR),
(BOOTP_END - UDP_VIRT_SADDR) / 2);
if (sum == 0)
sum = 0xFFFF;
buf[UDP_CHECKSUM + 0] = (sum >> 8);
buf[UDP_CHECKSUM + 1] = sum & 0xff;
// ------------ IP --------------
buf[IP_VERSION] = 0x45;
buf[IP_TOS] = 0;
buf[IP_LEN + 0] = (BOOTP_END) >> 8;
buf[IP_LEN + 1] = (BOOTP_END) & 0xff;
buf[IP_ID + 0] = 0;
buf[IP_ID + 1] = 0;
buf[IP_FLAGS + 0] = 0;
buf[IP_FLAGS + 1] = 0;
buf[IP_TTL] = 63;
buf[IP_PROTOCOL] = 17; /* UDP */
buf[IP_CHECKSUM + 0] = 0;
buf[IP_CHECKSUM + 1] = 0;
memset(buf + IP_SOURCE, 0, 4);
memset(buf + IP_DEST, 0xFF, 4);
sum =
ipv4_checksum((unsigned short *)(buf + IP_VERSION),
(IP_END - IP_VERSION) / 2);
buf[IP_CHECKSUM + 0] = sum >> 8;
buf[IP_CHECKSUM + 1] = sum & 0xff;
/* complete with udp helper */
memset(&uaddr.saddr, 0, 4);
memset(&uaddr.daddr, 0xff, 4);
uaddr.sport = ntohs(68);
uaddr.dport = ntohs(67);
fill_udp(buf, BOOTP_END, &uaddr);
/* and fix destination before sending it */
memset(addr->mac, 0xFF, 6);
// pp_printf("Sending BOOTP request...\n");
return BOOTP_END;
}
......@@ -148,17 +86,13 @@ int process_bootp(uint8_t * buf, int len)
if (len != BOOTP_END)
return 0;
if (buf[IP_VERSION] != 0x45)
return 0;
if (buf[IP_PROTOCOL] != 17 ||
buf[UDP_DPORT] != 0 || buf[UDP_DPORT + 1] != 68 ||
buf[UDP_SPORT] != 0 || buf[UDP_SPORT + 1] != 67)
if (buf[UDP_SPORT] != 0 || buf[UDP_SPORT + 1] != 67)
return 0;
if (memcmp(buf + BOOTP_CHADDR, mac, 6))
return 0;
ip_status = IP_OK_BOOTP;
setIP(buf + BOOTP_YIADDR);
getIP(ip);
......
This diff is collapsed.
......@@ -7,22 +7,63 @@
#define IPV4_H
#include <inttypes.h>
#include "ptpd_netif.h" /* for sockaddr in prototype */
void ipv4_init(void);
void ipv4_poll(void);
#undef IP_TOS /* These two are defined by arpa/inet.h, and will conflict */
#undef IP_TTL /* when we build for the host */
#define IP_VERSION 0
#define IP_TOS (IP_VERSION+1)
#define IP_LEN (IP_TOS+1)
#define IP_ID (IP_LEN+2)
#define IP_FLAGS (IP_ID+2)
#define IP_TTL (IP_FLAGS+2)
#define IP_PROTOCOL (IP_TTL+1)
#define IP_CHECKSUM (IP_PROTOCOL+1)
#define IP_SOURCE (IP_CHECKSUM+2)
#define IP_DEST (IP_SOURCE+4)
#define IP_END (IP_DEST+4)
#define UDP_VIRT_SADDR (IP_END-12)
#define UDP_VIRT_DADDR (UDP_VIRT_SADDR+4)
#define UDP_VIRT_ZEROS (UDP_VIRT_DADDR+4)
#define UDP_VIRT_PROTO (UDP_VIRT_ZEROS+1)
#define UDP_VIRT_LENGTH (UDP_VIRT_PROTO+1)
#define UDP_SPORT (IP_END)
#define UDP_DPORT (UDP_SPORT+2)
#define UDP_LENGTH (UDP_DPORT+2)
#define UDP_CHECKSUM (UDP_LENGTH+2)
#define UDP_END (UDP_CHECKSUM+2)
/* Internal to IP stack: */
unsigned int ipv4_checksum(unsigned short *buf, int shorts);
void arp_init(void);
void arp_poll(void);
extern int needIP;
enum ip_status {
IP_TRAINING,
IP_OK_BOOTP,
IP_OK_STATIC,
};
extern enum ip_status ip_status;
void setIP(unsigned char *IP);
void getIP(unsigned char *IP);
int process_icmp(uint8_t * buf, int len);
int process_bootp(uint8_t * buf, int len); /* non-zero if IP was set */
int send_bootp(uint8_t * buf, int retry);
int prepare_bootp(struct wr_sockaddr *addr, uint8_t * buf, int retry);
/* The UDP helper needs some information, if not replying to a frame */
struct wr_udp_addr {
uint32_t saddr; /* all fields in network order, for memcpy */
uint32_t daddr;
uint16_t sport;
uint16_t dport;
};
void fill_udp(uint8_t * buf, int len, struct wr_udp_addr *uaddr);
int check_dest_ip(unsigned char *buf);
void syslog_init(void);
int syslog_poll(void);
#endif
This diff is collapsed.
obj-y += lib/util.o lib/atoi.o
obj-y += lib/usleep.o
obj-y += lib/util.o
obj-$(CONFIG_LM32) += \
lib/atoi.o \
lib/usleep.o
obj-$(CONFIG_WR_NODE) += lib/net.o
obj-$(CONFIG_ETHERBONE) += lib/arp.o lib/icmp.o lib/ipv4.o lib/bootp.o
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
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
ppsi @ c93d7100
Subproject commit b203cc96df8d4008fe311deaf7baab8e555d5c96
Subproject commit c93d7100eb7a87d41c0422dd1e033196231e3ce7
......@@ -13,6 +13,7 @@ const char *build_revision = stats.commit_id;
const char *build_date = stats.build_date;
const char *build_time = stats.build_time;
const char *build_by = stats.build_by;
/*
* We export softpll internal status to the ARM cpu, for SNMP. Thus,
* we place this structure at a known address in the linker script
......@@ -22,9 +23,12 @@ struct spll_stats stats __attribute__((section(".stats"))) = {
.ver = SPLL_STATS_VER,
#ifdef CONFIG_DETERMINISTIC_BINARY
.build_date = "",
.build_time = "",
.build_by = "",
#else
.build_date = __DATE__,
.build_time = __TIME__,
.build_by = __GIT_USR__,
#endif
.commit_id = __GIT_VER__,
};
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
obj-y += \
obj-$(CONFIG_LM32) += \
softpll/spll_common.o \
softpll/spll_external.o \
softpll/spll_helper.o \
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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