Commit e859ad5f authored by Adam Wujek's avatar Adam Wujek 💬

Merge branch 'jcb-HA-implementation'

Signed-off-by: Adam Wujek's avatarAdam Wujek <adam.wujek@cern.ch>
parents 499ee8c8 656cb314
......@@ -387,139 +387,7 @@ config KEEP_ROOTFS
endmenu
menu "Port Timing Configuration"
config PORT01_PARAMS
string "Parameters for port 1"
default "name=wri1,proto=raw,tx=223897,rx=226273,role=slave,ext=WR,dm=e2e,monitor=y,fiber=0" if TIME_BC
default "name=wri1,proto=raw,tx=223897,rx=226273,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
help
This item, and the following ones, are used to assign the tx and rx
constant delays (likely from calibration), protocol type (raw or udp),
port roles, type of fiber (number referring to the corresponding
FIBERXX_PARAMS) and vlan configuration of PPSi for each of the ports.
Please refer to the user manual for more information.
"role" can be one of the following:
- master - configure port as a master
- slave - configure port as a slave
- auto - when a port is connected to master behave as a slave,
otherwise behave as master
- non-wr - (obsolete) don't report problems with this port via SNMP
like SFP not in DB, copper SFP connected, non 1GB SFP
etc.
- none - disable White Rabbit and PTP on a port
"ext" (extension) can be one of the following:
- WR - use White Rabbit as an extension on this port (default)
- none - no extension on this port
"dm" (delay mechanism) can be one of the following:
- e2e - end to end (default)
- p2p - peer to peer
"monitor" option to disable ("n") or enable ("y") triggering errors in SNMP on a port; "y" by default
config PORT02_PARAMS
string "Parameters for port 2"
default "name=wri2,proto=raw,tx=224037,rx=226377,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
help
Please check the help of PORT01_PARAMS
config PORT03_PARAMS
string "Parameters for port 3"
default "name=wri3,proto=raw,tx=224142,rx=226638,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
help
Please check the help of PORT01_PARAMS
config PORT04_PARAMS
string "Parameters for port 4"
default "name=wri4,proto=raw,tx=224313,rx=226471,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
help
Please check the help of PORT01_PARAMS
config PORT05_PARAMS
string "Parameters for port 5"
default "name=wri5,proto=raw,tx=224455,rx=227679,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
help
Please check the help of PORT01_PARAMS
config PORT06_PARAMS
string "Parameters for port 6"
default "name=wri6,proto=raw,tx=224603,rx=227891,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
help
Please check the help of PORT01_PARAMS
config PORT07_PARAMS
string "Parameters for port 7"
default "name=wri7,proto=raw,tx=224761,rx=228055,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
help
Please check the help of PORT01_PARAMS
config PORT08_PARAMS
string "Parameters for port 8"
default "name=wri8,proto=raw,tx=224898,rx=228178,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
help
Please check the help of PORT01_PARAMS
config PORT09_PARAMS
string "Parameters for port 9"
default "name=wri9,proto=raw,tx=225069,rx=228277,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
help
Please check the help of PORT01_PARAMS
config PORT10_PARAMS
string "Parameters for port 10"
default "name=wri10,proto=raw,tx=225245,rx=228435,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
help
Please check the help of PORT01_PARAMS
config PORT11_PARAMS
string "Parameters for port 11"
default "name=wri11,proto=raw,tx=225463,rx=228963,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
help
Please check the help of PORT01_PARAMS
config PORT12_PARAMS
string "Parameters for port 12"
default "name=wri12,proto=raw,tx=225645,rx=229107,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
help
Please check the help of PORT01_PARAMS
config PORT13_PARAMS
string "Parameters for port 13"
default "name=wri13,proto=raw,tx=225801,rx=229225,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
help
Please check the help of PORT01_PARAMS
config PORT14_PARAMS
string "Parameters for port 14"
default "name=wri14,proto=raw,tx=225983,rx=229463,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
help
Please check the help of PORT01_PARAMS
config PORT15_PARAMS
string "Parameters for port 15"
default "name=wri15,proto=raw,tx=226208,rx=229850,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
help
Please check the help of PORT01_PARAMS
config PORT16_PARAMS
string "Parameters for port 16"
default "name=wri16,proto=raw,tx=226393,rx=229907,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
help
Please check the help of PORT01_PARAMS
config PORT17_PARAMS
string "Parameters for port 17"
default "name=wri17,proto=raw,tx=226594,rx=230106,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
help
Please check the help of PORT01_PARAMS
config PORT18_PARAMS
string "Parameters for port 18"
default "name=wri18,proto=raw,tx=226737,rx=230273,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
help
Please check the help of PORT01_PARAMS
endmenu
source Kconfig_port_timing.in
menu "SFP and Media Timing Configuration"
......@@ -665,6 +533,48 @@ config TIME_BC
endchoice
menu "PPS generation"
config PPSGEN_PTP_FALLBACK
bool "PTP fallback"
default N
help
This option enables the PPS generation if a slave instance
programmed to use an extension protocol (WR, L1Sync, ...) is falling back
to PTP communication only.
config PPSGEN_PTP_THRESHOLD_MS
int "PTP threshold (ms)"
default 500
range 1 1000
help
This option defines the threshold corresponding to the offset from the
master used to start the generation of the PPS. It is either used by a PTP slave
instance or a instance using a protocol extension but going into the fallback PTP mode
and with the PTP fallback option active.
A 0 value means that the PPS will be not generated for the considerated cases.
When the PPS is generated, it can be also disabled when the offset from master becomes greater
than the threshold value + 20%
config PPSGEN_GM_DELAY_TO_GEN_PPS_SEC
int "Grand Master delay for PPS (sec)"
default 0
range 0 1000
help
This option allows a boundary/ordinary clock to generate PPS when it becomes Grand Master (GM) by BMCA. Becoming GM
by BMCA might be a transitory situation during a network discovery. The PPS must be activated only when all this
transitory phase is terminated. This option then allows to define a delay in seconds to respect before
generating the PPS when a GM by BMCA is detected.
A 0 value desactivate this feature.
config PPSGEN_FORCE
bool "Force PPS for testing purpose"
default N
help
This option enables the PPS generation for all cases. It should only be used for testing purpose.
endmenu
choice
prompt "PTP Port Assignment"
default PTP_PORT_PARAMS
......@@ -716,10 +626,19 @@ config PTP_CONF_URL
For example: tftp://morgana/wrs-IPADDR-ppsi.conf
menu "PTP options"
depends on PTP_PORT_PARAMS
config PTP_OPT_OVERWRITE_CLOCK_CLASS
boolean "Overwrite default clock-class"
default FALSE
help
The clock class is automatically set depending of the timing mode.
This option allows to overwrite the default value.
config PTP_OPT_CLOCK_CLASS
string "clock-class"
int "clock-class"
default 248
range 0 255
depends on PTP_OPT_OVERWRITE_CLOCK_CLASS
help
An attribute defining the TAI traceability, synchronization state and
expected performance of the time or frequency distributed by a
......@@ -729,7 +648,9 @@ config PTP_OPT_CLOCK_CLASS
ppsi-pre.conf during generation of ppsi.conf.
config PTP_OPT_CLOCK_ACCURACY
string "clock-accuracy"
int "clock-accuracy"
range 0 255
default "254"
help
An attribute defining the accuracy of the Local Clock (e.g. local
oscillator) of a Boundary Clock or Ordinary Clock.
......@@ -738,7 +659,9 @@ config PTP_OPT_CLOCK_ACCURACY
ppsi-pre.conf during generation of ppsi.conf.
config PTP_OPT_CLOCK_ALLAN_VARIANCE
string "clock-allan-variance/offsetScaledLogVariance"
int "clock-allan-variance/offsetScaledLogVariance"
default "65535"
range 0 65535
help
An attribute defining the stability of the Local Clock of a
Boundary Clock or Ordinary Clock.
......@@ -747,44 +670,29 @@ config PTP_OPT_CLOCK_ALLAN_VARIANCE
ppsi-pre.conf during generation of ppsi.conf.
config PTP_OPT_DOMAIN_NUMBER
string "domain-number"
int "domain-number"
default 0
range 0 255
help
A domain consists of one or more PTP devices communicating with each
other as defined by the PTP protocol. A domain defines the scope of
PTP message communication, state, operations, data sets, and
timescale. PTP devices may participate in multiple domains.
For more details please refer to the IEEE 1588-2008 standard.
If set, this configuration item overwrites the default value from
ppsi-pre.conf during generation of ppsi.conf.
config PTP_OPT_ANNOUNCE_INTERVAL
string "announce-interval"
help
The mean time interval between transmissions of successive
Announce messages.
If set, this configuration item overwrites the default value from
ppsi-pre.conf during generation of ppsi.conf.
config PTP_OPT_SYNC_INTERVAL
string "sync-interval"
help
The mean time interval between transmission of successive
Sync messages, i.e., the sync-interval, when transmitted
as multicast messages. The value is the logarithm to the base 2.
If set, this configuration item overwrites the default value from
ppsi-pre.conf during generation of ppsi.conf.
config PTP_OPT_PRIORITY1
string "priority1"
int "priority1"
default "128"
range 0 255
help
A user configurable designation that a clock belongs to an ordered
set of PTP devices from which a PTP Master is selected.
For more details please refer to the IEEE 1588-2008 standard
If set, this configuration item overwrites the default value from
ppsi-pre.conf during generation of ppsi.conf.
config PTP_OPT_PRIORITY2
string "priority2"
int "priority2"
default "128"
range 0 255
help
A user configurable designation that provides finer grained ordering
among otherwise equivalent PTP devices.
......@@ -792,8 +700,18 @@ config PTP_OPT_PRIORITY2
If set, this configuration item overwrites the default value from
ppsi-pre.conf during generation of ppsi.conf.
config PTP_OPT_OVERWRITE_TIME_SOURCE
boolean "Overwrite default time-source"
default FALSE
help
The clock class is automatically set depending of the timing mode.
This option allows to overwrite the default value.
config PTP_OPT_TIME_SOURCE
string "time-source"
int "time-source"
default 160
range 0 255
depends on PTP_OPT_OVERWRITE_TIME_SOURCE
help
This information-only attribute indicates the source of time used
by the grandmaster (or free-running master).
......@@ -1123,6 +1041,38 @@ config READ_SFP_DIAG_ENABLE
help
Let HAL to read Diagnostic Monitoring from SFP's eeprom.
choice
prompt "Compilation optimization"
config OPTIMIZATION_SPEED
boolean "Execution time (-O2)"
help
GCC performs nearly all supported optimizations that do not involve a space-speed tradeoff.
config OPTIMIZATION_SIZE_SPEED
boolean "Size and execution time (-Os)"
help
Optimize for size. Enables all -O2 optimizations except those that often increase code size.
config OPTIMIZATION_DEBUGGING
boolean "Debugging (-Og)"
help
Should be the optimization level of choice for the standard edit-compile-debug cycle
config OPTIMIZATION_NONE_DEBUGGING
boolean "Debugging without optimization(-ggdb)"
help
Compile without optimization and with debug informations
endchoice
config OPTIMIZATION
string
default "-Os -ggdb" if OPTIMIZATION_SIZE_SPEED
default "-O2 -ggdb" if OPTIMIZATION_SPEED
default "-Og -ggdb" if OPTIMIZATION_DEBUGGING
default "-ggdb" if OPTIMIZATION_NONE_DEBUGGING
default "-ggdb"
endmenu # "Developer options"
menu "RTU HP mask"
......@@ -1146,3 +1096,5 @@ config RTU_HP_MASK_VAL
endmenu
source Kconfig_vlans.in
This source diff could not be displayed because it is too large. You can view the blob instead.
No preview for this file type
......@@ -2,6 +2,9 @@
# Automatically generated file; DO NOT EDIT.
# White Rabbit Switch configuration
#
CONFIG_DOTCONF_FW_VERSION="5.1.0"
CONFIG_DOTCONF_HW_VERSION=""
CONFIG_DOTCONF_INFO=""
# CONFIG_DOTCONF_SOURCE_LOCAL is not set
# CONFIG_DOTCONF_SOURCE_REMOTE is not set
# CONFIG_DOTCONF_SOURCE_FORCE_DHCP is not set
......@@ -21,7 +24,8 @@ CONFIG_HOSTNAME_DHCP=y
#
# Root Password
#
# CONFIG_ROOT_PWD_IS_ENCRYPTED is not set
CONFIG_ROOT_PWD_IS_ENCRYPTED=y
CONFIG_ROOT_PWD_CYPHER="$1$YSMM6Ch4$qlAct1hjJNtYuw3CZzY0M1"
CONFIG_ROOT_PWD_CLEAR=""
CONFIG_NTP_SERVER=""
CONFIG_DNS_SERVER=""
......@@ -43,24 +47,601 @@ CONFIG_WRS_LOG_LEVEL_OTHER=""
#
# Port Timing Configuration
#
CONFIG_PORT01_PARAMS="name=wri1,proto=raw,tx=223897,rx=226273,role=slave,ext=WR,dm=e2e,monitor=y,fiber=0"
CONFIG_PORT02_PARAMS="name=wri2,proto=raw,tx=224037,rx=226377,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
CONFIG_PORT03_PARAMS="name=wri3,proto=raw,tx=224142,rx=226638,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
CONFIG_PORT04_PARAMS="name=wri4,proto=raw,tx=224313,rx=226471,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
CONFIG_PORT05_PARAMS="name=wri5,proto=raw,tx=224455,rx=227679,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
CONFIG_PORT06_PARAMS="name=wri6,proto=raw,tx=224603,rx=227891,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
CONFIG_PORT07_PARAMS="name=wri7,proto=raw,tx=224761,rx=228055,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
CONFIG_PORT08_PARAMS="name=wri8,proto=raw,tx=224898,rx=228178,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
CONFIG_PORT09_PARAMS="name=wri9,proto=raw,tx=225069,rx=228277,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
CONFIG_PORT10_PARAMS="name=wri10,proto=raw,tx=225245,rx=228435,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
CONFIG_PORT11_PARAMS="name=wri11,proto=raw,tx=225463,rx=228963,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
CONFIG_PORT12_PARAMS="name=wri12,proto=raw,tx=225645,rx=229107,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
CONFIG_PORT13_PARAMS="name=wri13,proto=raw,tx=225801,rx=229225,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
CONFIG_PORT14_PARAMS="name=wri14,proto=raw,tx=225983,rx=229463,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
CONFIG_PORT15_PARAMS="name=wri15,proto=raw,tx=226208,rx=229850,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
CONFIG_PORT16_PARAMS="name=wri16,proto=raw,tx=226393,rx=229907,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
CONFIG_PORT17_PARAMS="name=wri17,proto=raw,tx=226594,rx=230106,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
CONFIG_PORT18_PARAMS="name=wri18,proto=raw,tx=226737,rx=230273,role=master,ext=WR,dm=e2e,monitor=y,fiber=0"
CONFIG_PTP_OPT_EXT_PORT_CONFIG_ENABLED=y
#
# PORT 1
#
CONFIG_PORT01_IFACE="wri1"
CONFIG_PORT01_FIBER=0
CONFIG_PORT01_CONSTANT_ASYMMETRY=0
# CONFIG_PORT01_INSTANCE_COUNT_0 is not set
CONFIG_PORT01_INSTANCE_COUNT_1=y
# CONFIG_PORT01_INSTANCE_COUNT_2 is not set
#
# Instance 1
#
CONFIG_PORT01_INST01_PROTOCOL_RAW=y
# CONFIG_PORT01_INST01_PROTOCOL_UDP_IPV4 is not set
CONFIG_PORT01_INST01_MECHANISM_E2E=y
# CONFIG_PORT01_INST01_MECHANISM_P2P is not set
CONFIG_PORT01_INST01_MONITOR=y
# CONFIG_PORT01_INST01_PROFILE_PTP is not set
CONFIG_PORT01_INST01_PROFILE_WR=y
# CONFIG_PORT01_INST01_PROFILE_HA is not set
# CONFIG_PORT01_INST01_PROFILE_CUSTOM is not set
# CONFIG_PORT01_INST01_DESIRADE_STATE_MASTER is not set
CONFIG_PORT01_INST01_DESIRADE_STATE_SLAVE=y
# CONFIG_PORT01_INST01_DESIRADE_STATE_PASSIVE is not set
CONFIG_PORT01_INST01_ASYMMETRY_CORRECTION_ENABLE=y
CONFIG_PORT01_INST01_EGRESS_LATENCY=223897
CONFIG_PORT01_INST01_INGRESS_LATENCY=226273
CONFIG_PORT01_INST01_ANNOUNCE_INTERVAL=1
CONFIG_PORT01_INST01_ANNOUNCE_RECEIPT_TIMEOUT=3
CONFIG_PORT01_INST01_SYNC_INTERVAL=0
CONFIG_PORT01_INST01_MIN_DELAY_REQ_INTERVAL=0
#
# PORT 2
#
CONFIG_PORT02_IFACE="wri2"
CONFIG_PORT02_FIBER=0
CONFIG_PORT02_CONSTANT_ASYMMETRY=0
# CONFIG_PORT02_INSTANCE_COUNT_0 is not set
CONFIG_PORT02_INSTANCE_COUNT_1=y
# CONFIG_PORT02_INSTANCE_COUNT_2 is not set
#
# Instance 1
#
CONFIG_PORT02_INST01_PROTOCOL_RAW=y
# CONFIG_PORT02_INST01_PROTOCOL_UDP_IPV4 is not set
CONFIG_PORT02_INST01_MECHANISM_E2E=y
# CONFIG_PORT02_INST01_MECHANISM_P2P is not set
CONFIG_PORT02_INST01_MONITOR=y
# CONFIG_PORT02_INST01_PROFILE_PTP is not set
CONFIG_PORT02_INST01_PROFILE_WR=y
# CONFIG_PORT02_INST01_PROFILE_HA is not set
# CONFIG_PORT02_INST01_PROFILE_CUSTOM is not set
CONFIG_PORT02_INST01_DESIRADE_STATE_MASTER=y
# CONFIG_PORT02_INST01_DESIRADE_STATE_SLAVE is not set
# CONFIG_PORT02_INST01_DESIRADE_STATE_PASSIVE is not set
CONFIG_PORT02_INST01_ASYMMETRY_CORRECTION_ENABLE=y
CONFIG_PORT02_INST01_EGRESS_LATENCY=224037
CONFIG_PORT02_INST01_INGRESS_LATENCY=226377
CONFIG_PORT02_INST01_ANNOUNCE_INTERVAL=1
CONFIG_PORT02_INST01_ANNOUNCE_RECEIPT_TIMEOUT=3
CONFIG_PORT02_INST01_SYNC_INTERVAL=0
CONFIG_PORT02_INST01_MIN_DELAY_REQ_INTERVAL=0
#
# PORT 3
#
CONFIG_PORT03_IFACE="wri3"
CONFIG_PORT03_FIBER=0
CONFIG_PORT03_CONSTANT_ASYMMETRY=0
# CONFIG_PORT03_INSTANCE_COUNT_0 is not set
CONFIG_PORT03_INSTANCE_COUNT_1=y
# CONFIG_PORT03_INSTANCE_COUNT_2 is not set
#
# Instance 1
#
CONFIG_PORT03_INST01_PROTOCOL_RAW=y
# CONFIG_PORT03_INST01_PROTOCOL_UDP_IPV4 is not set
CONFIG_PORT03_INST01_MECHANISM_E2E=y
# CONFIG_PORT03_INST01_MECHANISM_P2P is not set
CONFIG_PORT03_INST01_MONITOR=y
# CONFIG_PORT03_INST01_PROFILE_PTP is not set
CONFIG_PORT03_INST01_PROFILE_WR=y
# CONFIG_PORT03_INST01_PROFILE_HA is not set
# CONFIG_PORT03_INST01_PROFILE_CUSTOM is not set
CONFIG_PORT03_INST01_DESIRADE_STATE_MASTER=y
# CONFIG_PORT03_INST01_DESIRADE_STATE_SLAVE is not set
# CONFIG_PORT03_INST01_DESIRADE_STATE_PASSIVE is not set
CONFIG_PORT03_INST01_ASYMMETRY_CORRECTION_ENABLE=y
CONFIG_PORT03_INST01_EGRESS_LATENCY=224142
CONFIG_PORT03_INST01_INGRESS_LATENCY=226638
CONFIG_PORT03_INST01_ANNOUNCE_INTERVAL=1
CONFIG_PORT03_INST01_ANNOUNCE_RECEIPT_TIMEOUT=3
CONFIG_PORT03_INST01_SYNC_INTERVAL=0
CONFIG_PORT03_INST01_MIN_DELAY_REQ_INTERVAL=0
#
# PORT 4
#
CONFIG_PORT04_IFACE="wri4"
CONFIG_PORT04_FIBER=0
CONFIG_PORT04_CONSTANT_ASYMMETRY=0
# CONFIG_PORT04_INSTANCE_COUNT_0 is not set
CONFIG_PORT04_INSTANCE_COUNT_1=y
# CONFIG_PORT04_INSTANCE_COUNT_2 is not set
#
# Instance 1
#
CONFIG_PORT04_INST01_PROTOCOL_RAW=y
# CONFIG_PORT04_INST01_PROTOCOL_UDP_IPV4 is not set
CONFIG_PORT04_INST01_MECHANISM_E2E=y
# CONFIG_PORT04_INST01_MECHANISM_P2P is not set
CONFIG_PORT04_INST01_MONITOR=y
# CONFIG_PORT04_INST01_PROFILE_PTP is not set
CONFIG_PORT04_INST01_PROFILE_WR=y
# CONFIG_PORT04_INST01_PROFILE_HA is not set
# CONFIG_PORT04_INST01_PROFILE_CUSTOM is not set
CONFIG_PORT04_INST01_DESIRADE_STATE_MASTER=y
# CONFIG_PORT04_INST01_DESIRADE_STATE_SLAVE is not set
# CONFIG_PORT04_INST01_DESIRADE_STATE_PASSIVE is not set
CONFIG_PORT04_INST01_ASYMMETRY_CORRECTION_ENABLE=y
CONFIG_PORT04_INST01_EGRESS_LATENCY=224313
CONFIG_PORT04_INST01_INGRESS_LATENCY=226471
CONFIG_PORT04_INST01_ANNOUNCE_INTERVAL=1
CONFIG_PORT04_INST01_ANNOUNCE_RECEIPT_TIMEOUT=3
CONFIG_PORT04_INST01_SYNC_INTERVAL=0
CONFIG_PORT04_INST01_MIN_DELAY_REQ_INTERVAL=0
#
# PORT 5
#
CONFIG_PORT05_IFACE="wri5"
CONFIG_PORT05_FIBER=0
CONFIG_PORT05_CONSTANT_ASYMMETRY=0
# CONFIG_PORT05_INSTANCE_COUNT_0 is not set
CONFIG_PORT05_INSTANCE_COUNT_1=y
# CONFIG_PORT05_INSTANCE_COUNT_2 is not set
#
# Instance 1
#
CONFIG_PORT05_INST01_PROTOCOL_RAW=y
# CONFIG_PORT05_INST01_PROTOCOL_UDP_IPV4 is not set
CONFIG_PORT05_INST01_MECHANISM_E2E=y
# CONFIG_PORT05_INST01_MECHANISM_P2P is not set
CONFIG_PORT05_INST01_MONITOR=y
# CONFIG_PORT05_INST01_PROFILE_PTP is not set
CONFIG_PORT05_INST01_PROFILE_WR=y
# CONFIG_PORT05_INST01_PROFILE_HA is not set
# CONFIG_PORT05_INST01_PROFILE_CUSTOM is not set
CONFIG_PORT05_INST01_DESIRADE_STATE_MASTER=y
# CONFIG_PORT05_INST01_DESIRADE_STATE_SLAVE is not set
# CONFIG_PORT05_INST01_DESIRADE_STATE_PASSIVE is not set
CONFIG_PORT05_INST01_ASYMMETRY_CORRECTION_ENABLE=y
CONFIG_PORT05_INST01_EGRESS_LATENCY=224455
CONFIG_PORT05_INST01_INGRESS_LATENCY=227679
CONFIG_PORT05_INST01_ANNOUNCE_INTERVAL=1
CONFIG_PORT05_INST01_ANNOUNCE_RECEIPT_TIMEOUT=3
CONFIG_PORT05_INST01_SYNC_INTERVAL=0
CONFIG_PORT05_INST01_MIN_DELAY_REQ_INTERVAL=0
#
# PORT 6
#
CONFIG_PORT06_IFACE="wri6"
CONFIG_PORT06_FIBER=0
CONFIG_PORT06_CONSTANT_ASYMMETRY=0
# CONFIG_PORT06_INSTANCE_COUNT_0 is not set
CONFIG_PORT06_INSTANCE_COUNT_1=y
# CONFIG_PORT06_INSTANCE_COUNT_2 is not set
#
# Instance 1
#
CONFIG_PORT06_INST01_PROTOCOL_RAW=y
# CONFIG_PORT06_INST01_PROTOCOL_UDP_IPV4 is not set
CONFIG_PORT06_INST01_MECHANISM_E2E=y
# CONFIG_PORT06_INST01_MECHANISM_P2P is not set
CONFIG_PORT06_INST01_MONITOR=y
# CONFIG_PORT06_INST01_PROFILE_PTP is not set
CONFIG_PORT06_INST01_PROFILE_WR=y
# CONFIG_PORT06_INST01_PROFILE_HA is not set
# CONFIG_PORT06_INST01_PROFILE_CUSTOM is not set
CONFIG_PORT06_INST01_DESIRADE_STATE_MASTER=y
# CONFIG_PORT06_INST01_DESIRADE_STATE_SLAVE is not set
# CONFIG_PORT06_INST01_DESIRADE_STATE_PASSIVE is not set
CONFIG_PORT06_INST01_ASYMMETRY_CORRECTION_ENABLE=y
CONFIG_PORT06_INST01_EGRESS_LATENCY=224603
CONFIG_PORT06_INST01_INGRESS_LATENCY=227891
CONFIG_PORT06_INST01_ANNOUNCE_INTERVAL=1
CONFIG_PORT06_INST01_ANNOUNCE_RECEIPT_TIMEOUT=3
CONFIG_PORT06_INST01_SYNC_INTERVAL=0
CONFIG_PORT06_INST01_MIN_DELAY_REQ_INTERVAL=0
#
# PORT 7
#
CONFIG_PORT07_IFACE="wri7"
CONFIG_PORT07_FIBER=0
CONFIG_PORT07_CONSTANT_ASYMMETRY=0
# CONFIG_PORT07_INSTANCE_COUNT_0 is not set
CONFIG_PORT07_INSTANCE_COUNT_1=y
# CONFIG_PORT07_INSTANCE_COUNT_2 is not set
#
# Instance 1
#
CONFIG_PORT07_INST01_PROTOCOL_RAW=y
# CONFIG_PORT07_INST01_PROTOCOL_UDP_IPV4 is not set
CONFIG_PORT07_INST01_MECHANISM_E2E=y
# CONFIG_PORT07_INST01_MECHANISM_P2P is not set
CONFIG_PORT07_INST01_MONITOR=y
# CONFIG_PORT07_INST01_PROFILE_PTP is not set
CONFIG_PORT07_INST01_PROFILE_WR=y
# CONFIG_PORT07_INST01_PROFILE_HA is not set
# CONFIG_PORT07_INST01_PROFILE_CUSTOM is not set
CONFIG_PORT07_INST01_DESIRADE_STATE_MASTER=y
# CONFIG_PORT07_INST01_DESIRADE_STATE_SLAVE is not set
# CONFIG_PORT07_INST01_DESIRADE_STATE_PASSIVE is not set
CONFIG_PORT07_INST01_ASYMMETRY_CORRECTION_ENABLE=y
CONFIG_PORT07_INST01_EGRESS_LATENCY=224761
CONFIG_PORT07_INST01_INGRESS_LATENCY=228055
CONFIG_PORT07_INST01_ANNOUNCE_INTERVAL=1
CONFIG_PORT07_INST01_ANNOUNCE_RECEIPT_TIMEOUT=3
CONFIG_PORT07_INST01_SYNC_INTERVAL=0
CONFIG_PORT07_INST01_MIN_DELAY_REQ_INTERVAL=0
#
# PORT 8
#
CONFIG_PORT08_IFACE="wri8"
CONFIG_PORT08_FIBER=0
CONFIG_PORT08_CONSTANT_ASYMMETRY=0
# CONFIG_PORT08_INSTANCE_COUNT_0 is not set
CONFIG_PORT08_INSTANCE_COUNT_1=y
# CONFIG_PORT08_INSTANCE_COUNT_2 is not set
#
# Instance 1
#
CONFIG_PORT08_INST01_PROTOCOL_RAW=y
# CONFIG_PORT08_INST01_PROTOCOL_UDP_IPV4 is not set
CONFIG_PORT08_INST01_MECHANISM_E2E=y
# CONFIG_PORT08_INST01_MECHANISM_P2P is not set
CONFIG_PORT08_INST01_MONITOR=y
# CONFIG_PORT08_INST01_PROFILE_PTP is not set
CONFIG_PORT08_INST01_PROFILE_WR=y
# CONFIG_PORT08_INST01_PROFILE_HA is not set
# CONFIG_PORT08_INST01_PROFILE_CUSTOM is not set
CONFIG_PORT08_INST01_DESIRADE_STATE_MASTER=y
# CONFIG_PORT08_INST01_DESIRADE_STATE_SLAVE is not set
# CONFIG_PORT08_INST01_DESIRADE_STATE_PASSIVE is not set
# CONFIG_PORT08_INST01_ASYMMETRY_CORRECTION_ENABLE is not set
CONFIG_PORT08_INST01_EGRESS_LATENCY=224898
CONFIG_PORT08_INST01_INGRESS_LATENCY=228178
CONFIG_PORT08_INST01_ANNOUNCE_INTERVAL=1
CONFIG_PORT08_INST01_ANNOUNCE_RECEIPT_TIMEOUT=3
CONFIG_PORT08_INST01_SYNC_INTERVAL=0
CONFIG_PORT08_INST01_MIN_DELAY_REQ_INTERVAL=0
#
# PORT 9
#
CONFIG_PORT09_IFACE="wri9"
CONFIG_PORT09_FIBER=0
CONFIG_PORT09_CONSTANT_ASYMMETRY=0
# CONFIG_PORT09_INSTANCE_COUNT_0 is not set
CONFIG_PORT09_INSTANCE_COUNT_1=y
# CONFIG_PORT09_INSTANCE_COUNT_2 is not set
#
# Instance 1
#
CONFIG_PORT09_INST01_PROTOCOL_RAW=y
# CONFIG_PORT09_INST01_PROTOCOL_UDP_IPV4 is not set
CONFIG_PORT09_INST01_MECHANISM_E2E=y
# CONFIG_PORT09_INST01_MECHANISM_P2P is not set
CONFIG_PORT09_INST01_MONITOR=y
# CONFIG_PORT09_INST01_PROFILE_PTP is not set
CONFIG_PORT09_INST01_PROFILE_WR=y
# CONFIG_PORT09_INST01_PROFILE_HA is not set
# CONFIG_PORT09_INST01_PROFILE_CUSTOM is not set
CONFIG_PORT09_INST01_DESIRADE_STATE_MASTER=y
# CONFIG_PORT09_INST01_DESIRADE_STATE_SLAVE is not set
# CONFIG_PORT09_INST01_DESIRADE_STATE_PASSIVE is not set
CONFIG_PORT09_INST01_ASYMMETRY_CORRECTION_ENABLE=y
CONFIG_PORT09_INST01_EGRESS_LATENCY=225069
CONFIG_PORT09_INST01_INGRESS_LATENCY=228277
CONFIG_PORT09_INST01_ANNOUNCE_INTERVAL=1
CONFIG_PORT09_INST01_ANNOUNCE_RECEIPT_TIMEOUT=3
CONFIG_PORT09_INST01_SYNC_INTERVAL=0
CONFIG_PORT09_INST01_MIN_DELAY_REQ_INTERVAL=0
#
# PORT 10
#
CONFIG_PORT10_IFACE="wri10"
CONFIG_PORT10_FIBER=0
CONFIG_PORT10_CONSTANT_ASYMMETRY=0
# CONFIG_PORT10_INSTANCE_COUNT_0 is not set
CONFIG_PORT10_INSTANCE_COUNT_1=y
# CONFIG_PORT10_INSTANCE_COUNT_2 is not set
#
# Instance 1
#
CONFIG_PORT10_INST01_PROTOCOL_RAW=y
# CONFIG_PORT10_INST01_PROTOCOL_UDP_IPV4 is not set
CONFIG_PORT10_INST01_MECHANISM_E2E=y
# CONFIG_PORT10_INST01_MECHANISM_P2P is not set
CONFIG_PORT10_INST01_MONITOR=y
# CONFIG_PORT10_INST01_PROFILE_PTP is not set
CONFIG_PORT10_INST01_PROFILE_WR=y
# CONFIG_PORT10_INST01_PROFILE_HA is not set
# CONFIG_PORT10_INST01_PROFILE_CUSTOM is not set
CONFIG_PORT10_INST01_DESIRADE_STATE_MASTER=y
# CONFIG_PORT10_INST01_DESIRADE_STATE_SLAVE is not set
# CONFIG_PORT10_INST01_DESIRADE_STATE_PASSIVE is not set
CONFIG_PORT10_INST01_ASYMMETRY_CORRECTION_ENABLE=y
CONFIG_PORT10_INST01_EGRESS_LATENCY=225245
CONFIG_PORT10_INST01_INGRESS_LATENCY=228435
CONFIG_PORT10_INST01_ANNOUNCE_INTERVAL=1
CONFIG_PORT10_INST01_ANNOUNCE_RECEIPT_TIMEOUT=3
CONFIG_PORT10_INST01_SYNC_INTERVAL=0
CONFIG_PORT10_INST01_MIN_DELAY_REQ_INTERVAL=0
#
# PORT 11
#
CONFIG_PORT11_IFACE="wri11"
CONFIG_PORT11_FIBER=0
CONFIG_PORT11_CONSTANT_ASYMMETRY=0
# CONFIG_PORT11_INSTANCE_COUNT_0 is not set
CONFIG_PORT11_INSTANCE_COUNT_1=y
# CONFIG_PORT11_INSTANCE_COUNT_2 is not set
#
# Instance 1
#
CONFIG_PORT11_INST01_PROTOCOL_RAW=y
# CONFIG_PORT11_INST01_PROTOCOL_UDP_IPV4 is not set
CONFIG_PORT11_INST01_MECHANISM_E2E=y
# CONFIG_PORT11_INST01_MECHANISM_P2P is not set
CONFIG_PORT11_INST01_MONITOR=y
# CONFIG_PORT11_INST01_PROFILE_PTP is not set
CONFIG_PORT11_INST01_PROFILE_WR=y
# CONFIG_PORT11_INST01_PROFILE_HA is not set
# CONFIG_PORT11_INST01_PROFILE_CUSTOM is not set
CONFIG_PORT11_INST01_DESIRADE_STATE_MASTER=y
# CONFIG_PORT11_INST01_DESIRADE_STATE_SLAVE is not set
# CONFIG_PORT11_INST01_DESIRADE_STATE_PASSIVE is not set
CONFIG_PORT11_INST01_ASYMMETRY_CORRECTION_ENABLE=y
CONFIG_PORT11_INST01_EGRESS_LATENCY=225463
CONFIG_PORT11_INST01_INGRESS_LATENCY=228963
CONFIG_PORT11_INST01_ANNOUNCE_INTERVAL=1
CONFIG_PORT11_INST01_ANNOUNCE_RECEIPT_TIMEOUT=3
CONFIG_PORT11_INST01_SYNC_INTERVAL=0
CONFIG_PORT11_INST01_MIN_DELAY_REQ_INTERVAL=0
#
# PORT 12
#
CONFIG_PORT12_IFACE="wri12"
CONFIG_PORT12_FIBER=0
CONFIG_PORT12_CONSTANT_ASYMMETRY=0
# CONFIG_PORT12_INSTANCE_COUNT_0 is not set
CONFIG_PORT12_INSTANCE_COUNT_1=y
# CONFIG_PORT12_INSTANCE_COUNT_2 is not set
#
# Instance 1
#
CONFIG_PORT12_INST01_PROTOCOL_RAW=y
# CONFIG_PORT12_INST01_PROTOCOL_UDP_IPV4 is not set
CONFIG_PORT12_INST01_MECHANISM_E2E=y
# CONFIG_PORT12_INST01_MECHANISM_P2P is not set
CONFIG_PORT12_INST01_MONITOR=y
# CONFIG_PORT12_INST01_PROFILE_PTP is not set
CONFIG_PORT12_INST01_PROFILE_WR=y
# CONFIG_PORT12_INST01_PROFILE_HA is not set
# CONFIG_PORT12_INST01_PROFILE_CUSTOM is not set
CONFIG_PORT12_INST01_DESIRADE_STATE_MASTER=y
# CONFIG_PORT12_INST01_DESIRADE_STATE_SLAVE is not set
# CONFIG_PORT12_INST01_DESIRADE_STATE_PASSIVE is not set
CONFIG_PORT12_INST01_ASYMMETRY_CORRECTION_ENABLE=y
CONFIG_PORT12_INST01_EGRESS_LATENCY=225645
CONFIG_PORT12_INST01_INGRESS_LATENCY=229107
CONFIG_PORT12_INST01_ANNOUNCE_INTERVAL=1
CONFIG_PORT12_INST01_ANNOUNCE_RECEIPT_TIMEOUT=3
CONFIG_PORT12_INST01_SYNC_INTERVAL=0
CONFIG_PORT12_INST01_MIN_DELAY_REQ_INTERVAL=0
#
# PORT 13
#
CONFIG_PORT13_IFACE="wri13"
CONFIG_PORT13_FIBER=0
CONFIG_PORT13_CONSTANT_ASYMMETRY=0
# CONFIG_PORT13_INSTANCE_COUNT_0 is not set
CONFIG_PORT13_INSTANCE_COUNT_1=y
# CONFIG_PORT13_INSTANCE_COUNT_2 is not set
#
# Instance 1
#
CONFIG_PORT13_INST01_PROTOCOL_RAW=y
# CONFIG_PORT13_INST01_PROTOCOL_UDP_IPV4 is not set
CONFIG_PORT13_INST01_MECHANISM_E2E=y
# CONFIG_PORT13_INST01_MECHANISM_P2P is not set
CONFIG_PORT13_INST01_MONITOR=y
# CONFIG_PORT13_INST01_PROFILE_PTP is not set
CONFIG_PORT13_INST01_PROFILE_WR=y
# CONFIG_PORT13_INST01_PROFILE_HA is not set
# CONFIG_PORT13_INST01_PROFILE_CUSTOM is not set
CONFIG_PORT13_INST01_DESIRADE_STATE_MASTER=y
# CONFIG_PORT13_INST01_DESIRADE_STATE_SLAVE is not set
# CONFIG_PORT13_INST01_DESIRADE_STATE_PASSIVE is not set
CONFIG_PORT13_INST01_ASYMMETRY_CORRECTION_ENABLE=y
CONFIG_PORT13_INST01_EGRESS_LATENCY=225801
CONFIG_PORT13_INST01_INGRESS_LATENCY=229225
CONFIG_PORT13_INST01_ANNOUNCE_INTERVAL=1
CONFIG_PORT13_INST01_ANNOUNCE_RECEIPT_TIMEOUT=3
CONFIG_PORT13_INST01_SYNC_INTERVAL=0
CONFIG_PORT13_INST01_MIN_DELAY_REQ_INTERVAL=0
#
# PORT 14
#
CONFIG_PORT14_IFACE="wri14"
CONFIG_PORT14_FIBER=0
CONFIG_PORT14_CONSTANT_ASYMMETRY=0
# CONFIG_PORT14_INSTANCE_COUNT_0 is not set
CONFIG_PORT14_INSTANCE_COUNT_1=y
# CONFIG_PORT14_INSTANCE_COUNT_2 is not set
#
# Instance 1
#
CONFIG_PORT14_INST01_PROTOCOL_RAW=y
# CONFIG_PORT14_INST01_PROTOCOL_UDP_IPV4 is not set
CONFIG_PORT14_INST01_MECHANISM_E2E=y
# CONFIG_PORT14_INST01_MECHANISM_P2P is not set
CONFIG_PORT14_INST01_MONITOR=y
# CONFIG_PORT14_INST01_PROFILE_PTP is not set
CONFIG_PORT14_INST01_PROFILE_WR=y
# CONFIG_PORT14_INST01_PROFILE_HA is not set
# CONFIG_PORT14_INST01_PROFILE_CUSTOM is not set
CONFIG_PORT14_INST01_DESIRADE_STATE_MASTER=y
# CONFIG_PORT14_INST01_DESIRADE_STATE_SLAVE is not set
# CONFIG_PORT14_INST01_DESIRADE_STATE_PASSIVE is not set
CONFIG_PORT14_INST01_ASYMMETRY_CORRECTION_ENABLE=y
CONFIG_PORT14_INST01_EGRESS_LATENCY=225983
CONFIG_PORT14_INST01_INGRESS_LATENCY=229463
CONFIG_PORT14_INST01_ANNOUNCE_INTERVAL=1
CONFIG_PORT14_INST01_ANNOUNCE_RECEIPT_TIMEOUT=3
CONFIG_PORT14_INST01_SYNC_INTERVAL=0
CONFIG_PORT14_INST01_MIN_DELAY_REQ_INTERVAL=0
#
# PORT 15
#
CONFIG_PORT15_IFACE="wri15"
CONFIG_PORT15_FIBER=0
CONFIG_PORT15_CONSTANT_ASYMMETRY=0
# CONFIG_PORT15_INSTANCE_COUNT_0 is not set
CONFIG_PORT15_INSTANCE_COUNT_1=y
# CONFIG_PORT15_INSTANCE_COUNT_2 is not set
#
# Instance 1
#
CONFIG_PORT15_INST01_PROTOCOL_RAW=y
# CONFIG_PORT15_INST01_PROTOCOL_UDP_IPV4 is not set
CONFIG_PORT15_INST01_MECHANISM_E2E=y
# CONFIG_PORT15_INST01_MECHANISM_P2P is not set
CONFIG_PORT15_INST01_MONITOR=y
# CONFIG_PORT15_INST01_PROFILE_PTP is not set
CONFIG_PORT15_INST01_PROFILE_WR=y
# CONFIG_PORT15_INST01_PROFILE_HA is not set
# CONFIG_PORT15_INST01_PROFILE_CUSTOM is not set
CONFIG_PORT15_INST01_DESIRADE_STATE_MASTER=y
# CONFIG_PORT15_INST01_DESIRADE_STATE_SLAVE is not set
# CONFIG_PORT15_INST01_DESIRADE_STATE_PASSIVE is not set
CONFIG_PORT15_INST01_ASYMMETRY_CORRECTION_ENABLE=y
CONFIG_PORT15_INST01_EGRESS_LATENCY=226208
CONFIG_PORT15_INST01_INGRESS_LATENCY=229850
CONFIG_PORT15_INST01_ANNOUNCE_INTERVAL=1
CONFIG_PORT15_INST01_ANNOUNCE_RECEIPT_TIMEOUT=3
CONFIG_PORT15_INST01_SYNC_INTERVAL=0
CONFIG_PORT15_INST01_MIN_DELAY_REQ_INTERVAL=0
#
# PORT 16
#
CONFIG_PORT16_IFACE="wri16"
CONFIG_PORT16_FIBER=0
CONFIG_PORT16_CONSTANT_ASYMMETRY=0
# CONFIG_PORT16_INSTANCE_COUNT_0 is not set
CONFIG_PORT16_INSTANCE_COUNT_1=y
# CONFIG_PORT16_INSTANCE_COUNT_2 is not set
#
# Instance 1
#
CONFIG_PORT16_INST01_PROTOCOL_RAW=y
# CONFIG_PORT16_INST01_PROTOCOL_UDP_IPV4 is not set
CONFIG_PORT16_INST01_MECHANISM_E2E=y
# CONFIG_PORT16_INST01_MECHANISM_P2P is not set
CONFIG_PORT16_INST01_MONITOR=y
# CONFIG_PORT16_INST01_PROFILE_PTP is not set
CONFIG_PORT16_INST01_PROFILE_WR=y
# CONFIG_PORT16_INST01_PROFILE_HA is not set
# CONFIG_PORT16_INST01_PROFILE_CUSTOM is not set
CONFIG_PORT16_INST01_DESIRADE_STATE_MASTER=y
# CONFIG_PORT16_INST01_DESIRADE_STATE_SLAVE is not set
# CONFIG_PORT16_INST01_DESIRADE_STATE_PASSIVE is not set
CONFIG_PORT16_INST01_ASYMMETRY_CORRECTION_ENABLE=y
CONFIG_PORT16_INST01_EGRESS_LATENCY=226393
CONFIG_PORT16_INST01_INGRESS_LATENCY=229907
CONFIG_PORT16_INST01_ANNOUNCE_INTERVAL=1
CONFIG_PORT16_INST01_ANNOUNCE_RECEIPT_TIMEOUT=3
CONFIG_PORT16_INST01_SYNC_INTERVAL=0
CONFIG_PORT16_INST01_MIN_DELAY_REQ_INTERVAL=0
#
# PORT 17
#
CONFIG_PORT17_IFACE="wri17"
CONFIG_PORT17_FIBER=0
CONFIG_PORT17_CONSTANT_ASYMMETRY=0
# CONFIG_PORT17_INSTANCE_COUNT_0 is not set
CONFIG_PORT17_INSTANCE_COUNT_1=y
# CONFIG_PORT17_INSTANCE_COUNT_2 is not set
#
# Instance 1
#
CONFIG_PORT17_INST01_PROTOCOL_RAW=y
# CONFIG_PORT17_INST01_PROTOCOL_UDP_IPV4 is not set
CONFIG_PORT17_INST01_MECHANISM_E2E=y
# CONFIG_PORT17_INST01_MECHANISM_P2P is not set
CONFIG_PORT17_INST01_MONITOR=y
# CONFIG_PORT17_INST01_PROFILE_PTP is not set
CONFIG_PORT17_INST01_PROFILE_WR=y
# CONFIG_PORT17_INST01_PROFILE_HA is not set
# CONFIG_PORT17_INST01_PROFILE_CUSTOM is not set
CONFIG_PORT17_INST01_DESIRADE_STATE_MASTER=y
# CONFIG_PORT17_INST01_DESIRADE_STATE_SLAVE is not set
# CONFIG_PORT17_INST01_DESIRADE_STATE_PASSIVE is not set
CONFIG_PORT17_INST01_ASYMMETRY_CORRECTION_ENABLE=y
CONFIG_PORT17_INST01_EGRESS_LATENCY=226594
CONFIG_PORT17_INST01_INGRESS_LATENCY=230106
CONFIG_PORT17_INST01_ANNOUNCE_INTERVAL=1
CONFIG_PORT17_INST01_ANNOUNCE_RECEIPT_TIMEOUT=3
CONFIG_PORT17_INST01_SYNC_INTERVAL=0
CONFIG_PORT17_INST01_MIN_DELAY_REQ_INTERVAL=0
#
# PORT 18
#
CONFIG_PORT18_IFACE="wri18"
CONFIG_PORT18_FIBER=0
CONFIG_PORT18_CONSTANT_ASYMMETRY=0
# CONFIG_PORT18_INSTANCE_COUNT_0 is not set
CONFIG_PORT18_INSTANCE_COUNT_1=y
# CONFIG_PORT18_INSTANCE_COUNT_2 is not set
#
# Instance 1
#
CONFIG_PORT18_INST01_PROTOCOL_RAW=y
# CONFIG_PORT18_INST01_PROTOCOL_UDP_IPV4 is not set
CONFIG_PORT18_INST01_MECHANISM_E2E=y
# CONFIG_PORT18_INST01_MECHANISM_P2P is not set
CONFIG_PORT18_INST01_MONITOR=y
# CONFIG_PORT18_INST01_PROFILE_PTP is not set
CONFIG_PORT18_INST01_PROFILE_WR=y
# CONFIG_PORT18_INST01_PROFILE_HA is not set
# CONFIG_PORT18_INST01_PROFILE_CUSTOM is not set
CONFIG_PORT18_INST01_DESIRADE_STATE_MASTER=y
# CONFIG_PORT18_INST01_DESIRADE_STATE_SLAVE is not set
# CONFIG_PORT18_INST01_DESIRADE_STATE_PASSIVE is not set
CONFIG_PORT18_INST01_ASYMMETRY_CORRECTION_ENABLE=y
CONFIG_PORT18_INST01_EGRESS_LATENCY=226737
CONFIG_PORT18_INST01_INGRESS_LATENCY=230273
CONFIG_PORT18_INST01_ANNOUNCE_INTERVAL=1
CONFIG_PORT18_INST01_ANNOUNCE_RECEIPT_TIMEOUT=3
CONFIG_PORT18_INST01_SYNC_INTERVAL=0
CONFIG_PORT18_INST01_MIN_DELAY_REQ_INTERVAL=0
#
# SFP and Media Timing Configuration
......@@ -82,10 +663,29 @@ CONFIG_FIBER03_PARAMS="alpha_1310_1490=2.6787e-04"
# CONFIG_TIME_GM is not set
# CONFIG_TIME_FM is not set
CONFIG_TIME_BC=y
#
# PPS generation
#
CONFIG_PPSGEN_PTP_FALLBACK=y
CONFIG_PPSGEN_PTP_THRESHOLD_MS=500
CONFIG_PPSGEN_GM_DELAY_TO_GEN_PPS_SEC=120
# CONFIG_PPSGEN_FORCE is not set
CONFIG_PTP_PORT_PARAMS=y
# CONFIG_PTP_CUSTOM is not set
# CONFIG_PTP_REMOTE_CONF is not set
#
# PTP options
#
# CONFIG_PTP_OPT_OVERWRITE_CLOCK_CLASS is not set
CONFIG_PTP_OPT_CLOCK_ACCURACY=254
CONFIG_PTP_OPT_CLOCK_ALLAN_VARIANCE=65535
CONFIG_PTP_OPT_DOMAIN_NUMBER=0
CONFIG_PTP_OPT_PRIORITY1=128
CONFIG_PTP_OPT_PRIORITY2=128
# CONFIG_PTP_OPT_OVERWRITE_TIME_SOURCE is not set
#
# Management configuration
#
......@@ -112,12 +712,22 @@ CONFIG_WRSAUXCLK_PPSHIFT="0"
# NIC throttling configuration
#
# CONFIG_NIC_THROTTLING_ENABLED is not set
# CONFIG_PPS_IN_TERM_50OHM is not set
#
# Custom boot script configuration
#
# CONFIG_CUSTOM_BOOT_SCRIPT_ENABLED is not set
#
# LLDP options
#
# CONFIG_LLDPD_DISABLE is not set
CONFIG_LLDPD_TX_INTERVAL=5
# CONFIG_LLDPD_MANAGEMENT_PORT_DISABLE is not set
# CONFIG_LLDPD_MINIMUM_FRAME_SIZE is not set
# CONFIG_HTTPD_DISABLE is not set
#
# Developer options
#
......@@ -129,6 +739,15 @@ CONFIG_WRSAUXCLK_PPSHIFT="0"
# CONFIG_FAN_HYSTERESIS is not set
# CONFIG_READ_SFP_DIAG_ENABLE is not set
#
# COMPILATION FLAGS
#
CONFIG_OPTIMIZATION_SPEED=y
# CONFIG_OPTIMIZATION_SIZE_SPEED is not set
# CONFIG_OPTIMIZATION_DEBUGGING is not set
# CONFIG_OPTIMIZATION_NONE_DEBUGGING is not set
CONFIG_OPTIMIZATION="-O2 -ggdb"
#
# RTU HP mask
#
......
#!/bin/bash
# Jean-Claude BAU @CERN
# script to generate Kconfig timing port configuration.
#
# Parameters:
# -o file Overwrite the default output file name
#
OUTPUT_FILE="Kconfig_port_timing.in"
script_name="$0"
#decode script parameters
while getopts o: option
do
case "${option}" in
"o") OUTPUT_FILE=${OPTARG};;
esac
done
function print_header() {
echo -e "menu \"Port Timing Configuration\"" >$OUTPUT_FILE
echo -e "config PTP_OPT_EXT_PORT_CONFIG_ENABLED" >>$OUTPUT_FILE
echo -e "\tbool \"externalPortConfigurationEnabled\" " >>$OUTPUT_FILE
echo -e "\tdefault true" >>$OUTPUT_FILE
echo -e "\thelp" >>$OUTPUT_FILE
echo -e "\t This option is used by the high accuracy profile to force the port state." >>$OUTPUT_FILE
echo -e "\t For more details please refer to the IEEE 1588-20019 (clause 17.6.2)" >>$OUTPUT_FILE
echo -e "\nconfig PTP_SLAVE_ONLY" >>$OUTPUT_FILE
echo -e "\tdepends on PTP_OPT_EXT_PORT_CONFIG_ENABLED=\"n\" " >>$OUTPUT_FILE
echo -e "\tbool \"slaveOnly\" " >>$OUTPUT_FILE
echo -e "\tdefault false" >>$OUTPUT_FILE
echo -e "\thelp" >>$OUTPUT_FILE
echo -e "\t A slaveOnly Ordinary Clock utilizes the slaveOnly state machine" >>$OUTPUT_FILE
echo -e "\t which does not enable transition to MASTER state." >>$OUTPUT_FILE
echo -e "\t For more details please refer to the IEEE 1588-20019 (clause 9.2.2.1)" >>$OUTPUT_FILE
}
function print_footer() {
echo -e "\nendmenu" >>$OUTPUT_FILE
}
function print_port_header() {
#remove leading zero from i_port (params has numbers with leading zero,
#interface names are without leading zero)
local portIdx=$(expr $1 + 0)
echo -e "\nmenu \"PORT ${portIdx}\"" >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_IFACE" >>$OUTPUT_FILE
echo -e "\tstring \"Network interface\"" >>$OUTPUT_FILE
echo -e "\tdefault \"wri${portIdx}\"" >>$OUTPUT_FILE
echo -e "\thelp" >>$OUTPUT_FILE
echo -e "\t Used to set the physical port interface name: \"wri[1-18]\"" >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_FIBER" >>$OUTPUT_FILE
echo -e "\tint \"Fiber type\"" >>$OUTPUT_FILE
echo -e "\tdefault 0" >>$OUTPUT_FILE
echo -e "\thelp" >>$OUTPUT_FILE
echo -e "\t Used to set the type of fiber (number referring to the corresponding " >>$OUTPUT_FILE
echo -e "\t FIBERXX_PARAMS)" >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_CONSTANT_ASYMMETRY" >>$OUTPUT_FILE
echo -e "\tint \"asymmetryCorrectionPortDS.constantAsymmetry\"" >>$OUTPUT_FILE
echo -e "\tdefault 0" >>$OUTPUT_FILE
echo -e "\thelp" >>$OUTPUT_FILE
echo -e "\t Used to set the constant delay asymmetry." >>$OUTPUT_FILE
echo -e "\nchoice" >>$OUTPUT_FILE
echo -e "\tprompt \"Number of port instances\"" >>$OUTPUT_FILE
echo -e "\tdefault PORT${1}_INSTANCE_COUNT_1" >>$OUTPUT_FILE
echo -e "\tconfig PORT${1}_INSTANCE_COUNT_0" >>$OUTPUT_FILE
echo -e "\t bool \"0\"" >>$OUTPUT_FILE
echo -e "\tconfig PORT${1}_INSTANCE_COUNT_1" >>$OUTPUT_FILE
echo -e "\t bool \"1\"" >>$OUTPUT_FILE
echo -e "\tconfig PORT${1}_INSTANCE_COUNT_2" >>$OUTPUT_FILE
echo -e "\t bool \"2\"" >>$OUTPUT_FILE
echo -e "endchoice" >>$OUTPUT_FILE
}
function print_port_footer() {
echo -e "\nendmenu" >>$OUTPUT_FILE
}
function print_instance_header() {
#remove leading zero from i_port (params has numbers with leading zero,
#interface names are without leading zero)
local portIdx=$(expr $1 + 0)
local instIdx=$(expr $2 + 0)
if [ $instIdx -eq 1 ] ; then prof=WR ; else prof=HA ; fi
local tx=${port_tx[$1]}
local rx=${port_rx[$1]}
echo -e "\nmenu \"Instance ${instIdx}\"" >>$OUTPUT_FILE
if [ $instIdx -eq 1 ] ; then
echo -e " depends on PORT${1}_INSTANCE_COUNT_1 || PORT${1}_INSTANCE_COUNT_2 " >>$OUTPUT_FILE
else
echo -e " depends on PORT${1}_INSTANCE_COUNT_2 " >>$OUTPUT_FILE
fi
echo -e "\nchoice" >>$OUTPUT_FILE
echo -e " prompt \"Network protocol\"" >>$OUTPUT_FILE
echo -e " default PORT${1}_INST${2}_PROTOCOL_RAW" >>$OUTPUT_FILE
echo -e " config PORT${1}_INST${2}_PROTOCOL_RAW" >>$OUTPUT_FILE
echo -e " bool \"IEEE 802.3\"" >>$OUTPUT_FILE
echo -e " config PORT${1}_INST${2}_PROTOCOL_UDP_IPV4" >>$OUTPUT_FILE
echo -e " bool \"UDP/Ipv4\"" >>$OUTPUT_FILE
echo -e "endchoice" >>$OUTPUT_FILE
echo -e "\nchoice" >>$OUTPUT_FILE
echo -e " prompt \"Delay mechanism\"" >>$OUTPUT_FILE
echo -e " default PORT${1}_INST${2}_MECHANISM_E2E" >>$OUTPUT_FILE
echo -e " config PORT${1}_INST${2}_MECHANISM_E2E" >>$OUTPUT_FILE
echo -e " bool \"End-to-end\"" >>$OUTPUT_FILE
echo -e " config PORT${1}_INST${2}_MECHANISM_P2P" >>$OUTPUT_FILE
echo -e " bool \"Peer-to-peer\"" >>$OUTPUT_FILE
echo -e "endchoice" >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_INST${2}_MONITOR" >>$OUTPUT_FILE
echo -e " bool \"SNMP monitoring\"" >>$OUTPUT_FILE
echo -e " default y" >>$OUTPUT_FILE
echo -e " help" >>$OUTPUT_FILE
echo -e " Option to disable or enable triggering errors in SNMP on a port" >>$OUTPUT_FILE
echo -e "\nchoice" >>$OUTPUT_FILE
echo -e " prompt \"Profile\"" >>$OUTPUT_FILE
echo -e " default PORT${1}_INST${2}_PROFILE_WR" >>$OUTPUT_FILE
echo -e " config PORT${1}_INST${2}_PROFILE_PTP" >>$OUTPUT_FILE
echo -e " bool \"PTP\"" >>$OUTPUT_FILE
echo -e " config PORT${1}_INST${2}_PROFILE_WR" >>$OUTPUT_FILE
echo -e " bool \"WhiteRabbit\"" >>$OUTPUT_FILE
echo -e " config PORT${1}_INST${2}_PROFILE_HA" >>$OUTPUT_FILE
echo -e " bool \"HighAccuracy\"" >>$OUTPUT_FILE
echo -e " config PORT${1}_INST${2}_PROFILE_CUSTOM" >>$OUTPUT_FILE
echo -e " bool \"Custom\"" >>$OUTPUT_FILE
echo -e "endchoice" >>$OUTPUT_FILE
echo -e "\nchoice" >>$OUTPUT_FILE
echo -e " prompt \"Desired state\"" >>$OUTPUT_FILE
echo -e " depends on PTP_OPT_EXT_PORT_CONFIG_ENABLED" >>$OUTPUT_FILE
[[ $portIdx -eq 1 ]] && echo -e " default PORT${1}_INST${2}_DESIRADE_STATE_SLAVE if TIME_BC" >>$OUTPUT_FILE
echo -e " default PORT${1}_INST${2}_DESIRADE_STATE_MASTER" >>$OUTPUT_FILE
echo -e " config PORT${1}_INST${2}_DESIRADE_STATE_MASTER" >>$OUTPUT_FILE
echo -e " bool \"Master\"" >>$OUTPUT_FILE
echo -e " config PORT${1}_INST${2}_DESIRADE_STATE_SLAVE" >>$OUTPUT_FILE
echo -e " bool \"Slave\"" >>$OUTPUT_FILE
echo -e " config PORT${1}_INST${2}_DESIRADE_STATE_PASSIVE" >>$OUTPUT_FILE
echo -e " bool \"Passive\"" >>$OUTPUT_FILE
echo -e "endchoice" >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_INST${2}_ASYMMETRY_CORRECTION_ENABLE" >>$OUTPUT_FILE
echo -e " depends on PORT${1}_INST${2}_PROFILE_HA=\"n\" " >>$OUTPUT_FILE
echo -e " bool \"asymmetryCorrectionPortDS.enable\"" >>$OUTPUT_FILE
echo -e " default true" >>$OUTPUT_FILE
echo -e " help" >>$OUTPUT_FILE
echo -e " When supported, the value TRUE shall indicate that the mechanism of for the calculation" >>$OUTPUT_FILE
echo -e " of the <delayAsymmetry> for certain media is enabled on the PTP port." >>$OUTPUT_FILE
echo -e "\nchoice" >>$OUTPUT_FILE
echo -e " prompt \"BMCA mode\"" >>$OUTPUT_FILE
echo -e " depends on PTP_OPT_EXT_PORT_CONFIG_ENABLED!=y" >>$OUTPUT_FILE
echo -e " default PORT${1}_INST${2}_BMODE_MASTER_ONLY if TIME_BC" >>$OUTPUT_FILE
echo -e " default PORT${1}_INST${2}_BMODE_AUTO" >>$OUTPUT_FILE
echo -e " config PORT${1}_INST${2}_BMODE_MASTER_ONLY" >>$OUTPUT_FILE
echo -e " bool \"MasterOnly\"" >>$OUTPUT_FILE
echo -e " config PORT${1}_INST${2}_BMODE_AUTO" >>$OUTPUT_FILE
echo -e " bool \"Auto\"" >>$OUTPUT_FILE
echo -e "endchoice" >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_INST${2}_EGRESS_LATENCY" >>$OUTPUT_FILE
echo -e " int \"timestampCorrectionPortDS.egressLatency (ps)\"" >>$OUTPUT_FILE
echo -e " default ${tx}" >>$OUTPUT_FILE
echo -e " help" >>$OUTPUT_FILE
echo -e " Defines the transmission constant delay (ps)" >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_INST${2}_INGRESS_LATENCY" >>$OUTPUT_FILE
echo -e " int \"timestampCorrectionPortDS.ingressLatency (ps)\"" >>$OUTPUT_FILE
echo -e " default ${rx}" >>$OUTPUT_FILE
echo -e " help" >>$OUTPUT_FILE
echo -e " Defines the reception constant delay (ps)" >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_INST${2}_ANNOUNCE_INTERVAL" >>$OUTPUT_FILE
echo -e " int \"logAnnounceInterval\" " >>$OUTPUT_FILE
echo -e " default 1" >>$OUTPUT_FILE
echo -e " range 0 4" >>$OUTPUT_FILE
echo -e " help" >>$OUTPUT_FILE
echo -e " The mean time interval between transmissions of successive" >>$OUTPUT_FILE
echo -e " Announce messages. The value is the logarithm to the base 2." >>$OUTPUT_FILE
echo -e " The configurable range shall be 0 to 4." >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_INST${2}_ANNOUNCE_RECEIPT_TIMEOUT" >>$OUTPUT_FILE
echo -e " int \"announceReceiptTimeout\"" >>$OUTPUT_FILE
echo -e " default 3" >>$OUTPUT_FILE
echo -e " range 2 255" >>$OUTPUT_FILE
echo -e " help" >>$OUTPUT_FILE
echo -e " The announceReceiptTimeout specifies the number of announceIntervals " >>$OUTPUT_FILE
echo -e " that must pass without receipt of an Announce message before the " >>$OUTPUT_FILE
echo -e " occurrence of the event ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES." >>$OUTPUT_FILE
echo -e " The value is the logarithm to the base 2." >>$OUTPUT_FILE
echo -e " The configurable range shall be 2 to 255" >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_INST${2}_SYNC_INTERVAL" >>$OUTPUT_FILE
echo -e " int \"logSyncInterval\"" >>$OUTPUT_FILE
echo -e " default 0" >>$OUTPUT_FILE
echo -e " range -1 1" >>$OUTPUT_FILE
echo -e " help" >>$OUTPUT_FILE
echo -e " The mean time interval between transmission of successive" >>$OUTPUT_FILE
echo -e " Sync messages, i.e., the sync-interval, when transmitted" >>$OUTPUT_FILE
echo -e " as multicast messages. The value is the logarithm to the base 2." >>$OUTPUT_FILE
echo -e " The configurable range shall be -1 to +1" >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_INST${2}_MIN_DELAY_REQ_INTERVAL" >>$OUTPUT_FILE
echo -e " depends on PORT${1}_INST${2}_MECHANISM_E2E " >>$OUTPUT_FILE
echo -e " int \"minDelayRequestInterval\"" >>$OUTPUT_FILE
echo -e " default 0" >>$OUTPUT_FILE
echo -e " range 0 5" >>$OUTPUT_FILE
echo -e " help" >>$OUTPUT_FILE
echo -e " The minDelayRequestInterval specifies the minimum permitted" >>$OUTPUT_FILE
echo -e " mean time interval between successive Delay_Req messages." >>$OUTPUT_FILE
echo -e " The value is the logarithm to the base 2." >>$OUTPUT_FILE
echo -e " The configurable range shall be 0 to 5" >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_INST${2}_MIN_PDELAY_REQ_INTERVAL" >>$OUTPUT_FILE
echo -e " depends on PORT${1}_INST${2}_MECHANISM_P2P " >>$OUTPUT_FILE
echo -e " int \"minPDelayRequestInterval\"" >>$OUTPUT_FILE
echo -e " default 0" >>$OUTPUT_FILE
echo -e " range 0 5" >>$OUTPUT_FILE
echo -e " help" >>$OUTPUT_FILE
echo -e " The minPDelayRequestInterval specifies the minimum permitted" >>$OUTPUT_FILE
echo -e " mean time interval between successive Pdelay_Req messages." >>$OUTPUT_FILE
echo -e " The value is the logarithm to the base 2." >>$OUTPUT_FILE
echo -e " The configurable range shall be 0 to 5" >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_INST${2}_L1SYNC_ENABLED" >>$OUTPUT_FILE
echo -e " depends on PORT${1}_INST${2}_PROFILE_CUSTOM " >>$OUTPUT_FILE
echo -e " bool \"L1SyncBasicPortDS.L1SyncEnabled\"" >>$OUTPUT_FILE
echo -e " default y" >>$OUTPUT_FILE
echo -e " help" >>$OUTPUT_FILE
echo -e " This parameter specifies whether the L1Sync option is enabled on the PTP Port. If" >>$OUTPUT_FILE
echo -e " L1SyncEnabled is TRUE, then the L1Sync message exchange is supported and enabled" >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_INST${2}_L1SYNC_INTERVAL" >>$OUTPUT_FILE
echo -e " depends on PORT${1}_INST${2}_PROFILE_HA || (PORT${1}_INST${2}_PROFILE_CUSTOM && PORT${1}_INST${2}_L1SYNC_ENABLED=\"y\") " >>$OUTPUT_FILE
echo -e " int \"L1SyncBasicPortDS.logL1SyncInterval\"" >>$OUTPUT_FILE
echo -e " default 0" >>$OUTPUT_FILE
echo -e " range -4 4" >>$OUTPUT_FILE
echo -e " help" >>$OUTPUT_FILE
echo -e " The L1Sync interval specifies the time interval" >>$OUTPUT_FILE
echo -e " between successive periodic L1_SYNC TLV." >>$OUTPUT_FILE
echo -e " The value is the logarithm to the base 2." >>$OUTPUT_FILE
echo -e " The configurable range shall be -4 to 4" >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_INST${2}_L1SYNC_RECEIPT_TIMEOUT" >>$OUTPUT_FILE
echo -e " depends on PORT${1}_INST${2}_PROFILE_HA || (PORT${1}_INST${2}_PROFILE_CUSTOM && PORT${1}_INST${2}_L1SYNC_ENABLED=\"y\") " >>$OUTPUT_FILE
echo -e " int \"L1SyncBasicPortDS.L1SyncReceiptTimeout\"" >>$OUTPUT_FILE
echo -e " default 3" >>$OUTPUT_FILE
echo -e " range 2 10" >>$OUTPUT_FILE
echo -e " help" >>$OUTPUT_FILE
echo -e " The value of L1SyncReceiptTimeout specifies the number of elapsed " >>$OUTPUT_FILE
echo -e " L1SyncIntervals that must pass without reception of the L1_SYNC TLV " >>$OUTPUT_FILE
echo -e " before the L1_SYNC TLV reception timeout occurs." >>$OUTPUT_FILE
echo -e " The value is the logarithm to the base 2." >>$OUTPUT_FILE
echo -e " The configurable range shall be 2 to 10" >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_INST${2}_L1SYNC_TX_COHERENCY_IS_REQUIRED" >>$OUTPUT_FILE
echo -e " depends on PORT${1}_INST${2}_PROFILE_CUSTOM && PORT${1}_INST${2}_L1SYNC_ENABLED=\"y\" " >>$OUTPUT_FILE
echo -e " bool \"L1SyncBasicPortDS.txCoherencyIsRequired\"" >>$OUTPUT_FILE
echo -e " default y" >>$OUTPUT_FILE
echo -e " help" >>$OUTPUT_FILE
echo -e " The Boolean attribute txCoherentIsRequired specifies the configuration of the L1Sync port and the" >>$OUTPUT_FILE
echo -e " expected configuration of its peer L1Sync port. This configuration indicates whether the L1Sync port is" >>$OUTPUT_FILE
echo -e " required to be a transmit coherent port." >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_INST${2}_L1SYNC_RX_COHERENCY_IS_REQUIRED" >>$OUTPUT_FILE
echo -e " depends on PORT${1}_INST${2}_PROFILE_CUSTOM && PORT${1}_INST${2}_L1SYNC_ENABLED=\"y\" " >>$OUTPUT_FILE
echo -e " bool \"L1SyncBasicPortDS.rxCoherencyIsRequired\"" >>$OUTPUT_FILE
echo -e " default y" >>$OUTPUT_FILE
echo -e " help" >>$OUTPUT_FILE
echo -e " The Boolean attribute rxCoherentIsRequired specifies the configuration of the L1Sync port and the" >>$OUTPUT_FILE
echo -e " expected configuration of its peer L1Sync port. This configuration indicates whether the L1Sync port is" >>$OUTPUT_FILE
echo -e " required to be a receive coherent port." >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_INST${2}_L1SYNC_CONGRUENCY_IS_REQUIRED" >>$OUTPUT_FILE
echo -e " depends on PORT${1}_INST${2}_PROFILE_CUSTOM && PORT${1}_INST${2}_L1SYNC_ENABLED=\"y\" " >>$OUTPUT_FILE
echo -e " bool \"L1SyncBasicPortDS.congruencyIsRequired\"" >>$OUTPUT_FILE
echo -e " default y" >>$OUTPUT_FILE
echo -e " help" >>$OUTPUT_FILE
echo -e " The Boolean attribute congruentIsRequired specifies configuration of the L1Sync port and the expected" >>$OUTPUT_FILE
echo -e " configuration of its peer L1Sync port. This configuration indicates whether the L1Sync port is required to" >>$OUTPUT_FILE
echo -e " be a congruent port" >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_INST${2}_L1SYNC_OPT_PARAMS_ENABLED" >>$OUTPUT_FILE
echo -e " depends on PORT${1}_INST${2}_PROFILE_CUSTOM && PORT${1}_INST${2}_L1SYNC_ENABLED=\"y\" " >>$OUTPUT_FILE
echo -e " bool \"L1SyncBasicPortDS.optParamsEnabled\"" >>$OUTPUT_FILE
echo -e " default n" >>$OUTPUT_FILE
echo -e " help" >>$OUTPUT_FILE
echo -e " The Boolean attribute optParamsEnabled specifies whether the L1Sync port transmitting the L1_SYNC" >>$OUTPUT_FILE
echo -e " TLV extends this TLV with the information about the optional parameters." >>$OUTPUT_FILE
echo -e "\nconfig PORT${1}_INST${2}_L1SYNC_OPT_PARAMS_TS_CORRECTED_TX_ENABLED" >>$OUTPUT_FILE
echo -e " depends on PORT${1}_INST${2}_L1SYNC_OPT_PARAMS_ENABLED=\"y\" " >>$OUTPUT_FILE
echo -e " bool \"L1SyncBasicPortDS.timestampsCorrectedTx\"" >>$OUTPUT_FILE
echo -e " default n" >>$OUTPUT_FILE
echo -e " help" >>$OUTPUT_FILE
echo -e " When L1SyncOptParamsPortDS.timestampsCorrectedTx is TRUE, " >>$OUTPUT_FILE
echo -e " the L1Sync port shall correct the transmitted egress timestamps with " >>$OUTPUT_FILE
echo -e " the known value of the phase offset." >>$OUTPUT_FILE
}
function print_instance_footer() {
echo -e "\nendmenu" >>$OUTPUT_FILE
}
declare -A port_tx=(
[01]=223897 [02]=224037 [03]=224142 [04]=224313 [05]=224455 [06]=224603
[07]=224761 [08]=224898 [09]=225069 [10]=225245 [11]=225463 [12]=225645
[13]=225801 [14]=225983 [15]=226208 [16]=226393 [17]=226594 [18]=226737
)
declare -A port_rx=(
[01]=226273 [02]=226377 [03]=226638 [04]=226471 [05]=227679 [06]=227891
[07]=228055 [08]=228178 [09]=228277 [10]=228435 [11]=228963 [12]=229107
[13]=229225 [14]=229463 [15]=229850 [16]=229907 [17]=230106 [18]=230273
)
print_header
for i_port in {01..18}; do
print_port_header ${i_port}
for i_inst in {01..02}; do
print_instance_header ${i_port} ${i_inst}
print_instance_footer ${i_port} ${i_inst}
done
print_port_footer ${i_port}
done
print_footer
......@@ -24,6 +24,28 @@ static __iomem struct PPSG_WB *wrcs_ppsg;
static int wrcs_is_registered; /* no need for atomic_t or whatever */
/* prototypes */
static int pps_gen_busy(void);
static cycle_t wrcs_read(struct clocksource *cs);
static struct clocksource wrcs_cs = {
.name = "white-rabbit",
.rating = 450, /* perfect... */
.read = wrcs_read,
/* no enable/disable */
.mask = 0xffffffff, /* We fake a 32-bit thing */
.max_idle_ns = 900 * 1000 * 1000, /* well, 1s... */
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
static int pps_gen_busy(void)
{
uint32_t cr = readl(&wrcs_ppsg->CR);
return cr & PPSG_CR_CNT_ADJ ? 0 : 1;
}
/* If so requested, print statistics once per second */
static inline void wrcs_do_stats(void)
{
......@@ -46,41 +68,6 @@ static inline void wrcs_do_stats(void)
ncalls++;
}
DEFINE_SPINLOCK(wrcs_lock);
static cycle_t wrcs_read(struct clocksource *cs)
{
static uint32_t offset, last, this;
unsigned long flags;
wrcs_do_stats();
/* FIXME: identify a time jump by monitoring the tick counter */
/*
* Turn the counter into a 32-bit one (see cs->mask below).
* We reset at 0x3b9aca0, so without this we should use mask = 0x1f
* and mac_idle = 32 ticks = 512ns. Unaffordable.
*/
spin_lock_irqsave(&wrcs_lock, flags);
this = readl(&wrcs_ppsg->CNTR_NSEC);
if (this < last)
offset += WRCS_FREQUENCY;
last = this;
spin_unlock_irqrestore(&wrcs_lock, flags);
return offset + this;
}
static struct clocksource wrcs_cs = {
.name = "white-rabbit",
.rating = 450, /* perfect... */
.read = wrcs_read,
/* no enable/disable */
.mask = 0xffffffff, /* We fake a 32-bit thing */
.max_idle_ns = 900 * 1000 * 1000, /* well, 1s... */
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
/*
* The timer is used to check when does WR synchronize. When that
......@@ -95,7 +82,16 @@ static void wrcs_timer_fn(unsigned long unused)
uint32_t ticks, tai_l, tai_h;
int64_t tai;
/* Read ppsg, all fields consistently se we can use the value */
if ( pps_gen_busy() ){
printk(KERN_DEBUG " %s: Adjusting in progress \n",__func__);
/* NS counter adjustment in progress. Try later */
goto retryLater;
}
wrcs_cs.rating=450; /* Perfect */
printk(KERN_DEBUG " %s: Timer function \n",__func__);
/* Read ppsg, all fields consistently so we can use the value */
do {
tai_l = readl(&wrcs_ppsg->CNTR_UTCLO);
tai_h = readl(&wrcs_ppsg->CNTR_UTCHI);
......@@ -104,14 +100,62 @@ static void wrcs_timer_fn(unsigned long unused)
tai = (typeof(tai))tai_h << 32 | tai_l;
/* If we are before 2010 (date +%s --date=2010-01-01), try again */
if (tai < 1262300400LL) {
mod_timer(&wrcs_timer, jiffies + HZ);
return;
}
if (tai < 1262300400LL)
goto retryLater;
clocksource_register_hz(&wrcs_cs, WRCS_FREQUENCY);
wrcs_is_registered = 1;
/* And don't restart the timer */
return;
retryLater:;
wrcs_cs.rating=450; /* Perfect */
mod_timer(&wrcs_timer, jiffies + HZ);
return;
}
DEFINE_SPINLOCK(wrcs_lock);
static cycle_t wrcs_read(struct clocksource *cs)
{
static uint32_t offset, last, this, adjustOffset;
static char cntWasNeg;
int32_t ticksCounter;
unsigned long flags;
wrcs_do_stats();
/* FIXME: identify a time jump by monitoring the tick counter */
/*
* Turn the counter into a 32-bit one (see cs->mask below).
* We reset at 0x3b9aca0, so without this we should use mask = 0x1f
* and mac_idle = 32 ticks = 512ns. Unaffordable.
*/
spin_lock_irqsave(&wrcs_lock, flags);
ticksCounter = readl(&wrcs_ppsg->CNTR_NSEC);
if ( (ticksCounter & 0x8000000)!=0 ) {
// Negative value
ticksCounter|= 0xF0000000;
if ( ! cntWasNeg ) {
/* Jump from positive to negative counter value */
adjustOffset+=-ticksCounter;
adjustOffset%=WRCS_FREQUENCY;
cntWasNeg=1;
}
} else {
/* the counter is positive */
cntWasNeg=0;
}
this=(ticksCounter+adjustOffset)%WRCS_FREQUENCY;
if ( this < last) {
offset += WRCS_FREQUENCY;
}
last = this;
spin_unlock_irqrestore(&wrcs_lock, flags);
return offset + this;
}
static int wrcs_init(void)
......
Kconfig
Kconfig_port_timing.in
Kconfig_vlans.in
dot-config
conf
......
......@@ -15,7 +15,7 @@ OBJDUMP = $(CROSS_COMPILE)objdump
CFLAGS = -D KBUILD_NO_NLS
# most of this is just copying stuff in
RFILES = Kconfig Kconfig_vlans.in dot-config wrs_release_defconfig
RFILES = Kconfig_port_timing.in Kconfig Kconfig_vlans.in dot-config wrs_release_defconfig
XFILES = conf mconf nconf
FILES = $(RFILES) $(XFILES)
......@@ -36,6 +36,9 @@ dot-config: $(WRS_BASE_DIR)/../.config
Kconfig: $(WRS_BASE_DIR)/../Kconfig
cp $^ $@
Kconfig_port_timing.in: $(WRS_BASE_DIR)/../Kconfig_port_timing.in
cp $^ $@
Kconfig_vlans.in: $(WRS_BASE_DIR)/../Kconfig_vlans.in
cp $^ $@
......
......@@ -38,6 +38,9 @@
#define HEXP_PPSG_CMD_ADJUST_NSEC 3
#define HEXP_PPSG_CMD_POLL 4
#define HEXP_PPSG_CMD_SET_VALID 5
#define HEXP_PPSG_CMD_SET_TIMING_MODE 6
#define HEXP_PPSG_CMD_GET_TIMING_MODE 7
#define HEXP_PPSG_CMD_GET_TIMING_MODE_STATE 8
#define HEXP_ON 1
#define HEXP_OFF 0
......@@ -56,6 +59,11 @@
#define HAL_TIMING_MODE_GRAND_MASTER 0
#define HAL_TIMING_MODE_FREE_MASTER 1
#define HAL_TIMING_MODE_BC 2
#define HAL_TIMING_MODE_DISABLED 3
#define HAL_TIMING_MODE_TMDT_UNLOCKED 0
#define HAL_TIMING_MODE_TMDT_LOCKED 1
#define HAL_TIMING_MODE_TMDT_HOLDHOVER 2
typedef struct {
......@@ -72,6 +80,7 @@ typedef struct {
uint64_t current_sec;
uint32_t current_nsec;
uint32_t timing_mode;
} hexp_pps_params_t;
/* Port modes (hal_port_state.mode) */
......@@ -87,36 +96,11 @@ typedef struct {
#define HEXP_PORT_TSC_FALLING 2
*/
extern struct minipc_pd __rpcdef_lock_cmd;
extern struct minipc_pd __rpcdef_pps_cmd;
/* Prototypes of functions that call on rpc */
extern int halexp_lock_cmd(const char *port_name, int command, int priority);
extern int halexp_pps_cmd(int cmd, hexp_pps_params_t *params);
/* Export structures, shared by server and client for argument matching */
#ifdef HAL_EXPORT_STRUCTURES
//int halexp_lock_cmd(const char *port_name, int command, int priority);
struct minipc_pd __rpcdef_lock_cmd = {
.name = "lock_cmd",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRING, char *),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_END,
},
};
//int halexp_pps_cmd(int cmd, hexp_pps_params_t *params);
struct minipc_pd __rpcdef_pps_cmd = {
.name = "pps_cmd",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRUCT, hexp_pps_params_t),
MINIPC_ARG_END,
},
};
#endif /* HAL_EXPORT_STRUCTURES */
#endif
......@@ -4,7 +4,8 @@
#include <stdio.h>
#include <stdlib.h>
#define PTPDEXP_COMMAND_TRACKING 1
#define PTPDEXP_COMMAND_WR_TRACKING 1
#define PTPDEXP_COMMAND_L1SYNC_TRACKING 2
extern int ptpdexp_cmd(int cmd, int value);
......
# We are now Kconfig-based
-include ../../.config
LINUX ?= /lib/modules/$(shell uname -r)/build
# If we compile for the kernel, we need to include real kernel headers.
......@@ -19,7 +22,10 @@ OBJDUMP = $(CROSS_COMPILE)objdump
# calculate endianness at compile time
ENDIAN := $(shell ./check-endian $(CC))
CFLAGS = -Wall -ggdb -O2
export CFLAGS_OPTIMIZATION:= ${shell echo $(CONFIG_OPTIMIZATION)}
CFLAGS += $(CFLAGS_OPTIMIZATION)
CFLAGS += -Wall
CFLAGS += -I../include/linux -I../include # for <sdb.h>
CFLAGS += -ffunction-sections -fdata-sections
CFLAGS += -Wno-pointer-sign
......
# We are now Kconfig-based
-include ../../.config
OBJS = init.o fpga_io.o util.o pps_gen.o i2c.o shw_io.o i2c_bitbang.o \
i2c_fpga_reg.o pio.o libshw_i2c.o i2c_sfp.o fan.o i2c_io.o hwiu.o \
ptpd_netif.o hal_client.o \
ptpd_netif.o hal_client.o hal_minirpc.o\
shmem.o rt_client.o \
dot-config.o wrs-msg.o \
mac.o \
......@@ -21,8 +25,10 @@ STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
CFLAGS = -Wall -I. -O2 -ggdb \
-Wstrict-prototypes \
export CFLAGS_OPTIMIZATION:= ${shell echo $(CONFIG_OPTIMIZATION)}
CFLAGS += $(CFLAGS_OPTIMIZATION)
CFLAGS += -Wall -I. -Wstrict-prototypes \
-DLIBWR_INTERNAL \
-I./include \
-I../include \
......
......@@ -226,7 +226,13 @@ static int libwr_cfg_read_kconfig(struct kc **all_configs,
if (!f)
return -1;
while (fgets(s, sizeof(s), f)) {
if (sscanf(s, "source %s", name) == 1) {
char *ss=s;
/* Remove leading spaces */
while ( *ss==' ' || *ss=='\t')
ss++;
if (sscanf(ss, "source %s", name) == 1) {
/* Recursive call for sourced files */
ret = libwr_cfg_read_kconfig(all_configs,
kconfig_dirname, name,
......@@ -234,7 +240,7 @@ static int libwr_cfg_read_kconfig(struct kc **all_configs,
if (ret)
break;
}
if (sscanf(s, "config %s", name) != 1)
if (sscanf(ss, "config %s", name) != 1)
continue;
kc = malloc(sizeof(*kc));
if (!kc) {
......
#include <minipc.h>
#include <hal_exports.h> /* for exported structs/function protos */
/* Export structures, shared by server and client for argument matching */
//int halexp_lock_cmd(const char *port_name, int command, int priority);
struct minipc_pd __rpcdef_lock_cmd = {
.name = "lock_cmd",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRING, char *),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_END,
},
};
//int halexp_pps_cmd(int cmd, hexp_pps_params_t *params);
struct minipc_pd __rpcdef_pps_cmd = {
.name = "pps_cmd",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRUCT, hexp_pps_params_t),
MINIPC_ARG_END,
},
};
......@@ -39,6 +39,9 @@ typedef struct hal_port_calibration {
uint32_t delta_tx_phy;
uint32_t delta_rx_phy;
/* bit slide expresse in picos */
uint32_t bitslide_ps;
/* Current board routing delays (between the DDMTD inputs to
the PHY clock inputs/outputs), in picoseconds */
uint32_t delta_tx_board;
......@@ -71,9 +74,6 @@ struct hal_port_state {
int fd;
int hw_addr_auto;
/* port timing mode (HEXP_PORT_MODE_xxxx) */
int mode;
/* port FSM state (HAL_PORT_STATE_xxxx) */
int state;
......
......@@ -42,4 +42,14 @@ int shw_pps_gen_in_term_read(void);
/* Enables PPS_IN 50Ohm termination based on dot-config option */
int shw_pps_gen_in_term_init(void);
/* Get the timing mode state */
int shw_pps_get_timing_mode_state(void);
/* Get the timing mode */
int shw_pps_get_timing_mode(void);
/* Set the timing mode */
int shw_pps_set_timing_mode(int tm);
#endif /* __LIBWR_PPS_GEN_H */
......@@ -11,6 +11,7 @@
#include <sys/time.h>
#include <fpga_io.h>
#include <rt_ipc.h>
#include <regs/ppsg-regs.h>
#include <libwr/switch_hw.h>
......@@ -95,6 +96,62 @@ int shw_pps_gen_enable_output_read(void)
PPSG_PPS_OUT_ENABLE : PPSG_PPS_OUT_DISABLE;
}
int shw_pps_set_timing_mode(int tm) {
int mode=-1;
switch (tm) {
case HAL_TIMING_MODE_GRAND_MASTER:
mode=RTS_MODE_GM_EXTERNAL;
break;
case HAL_TIMING_MODE_FREE_MASTER:
mode=RTS_MODE_GM_FREERUNNING;
break;
case HAL_TIMING_MODE_BC:
mode=RTS_MODE_BC;
break;
default :
pr_error("%s: Invalid timing mode %d\n", __func__, tm);
return -1;
}
if ( rts_set_mode(mode)==-1) {
pr_error("%s: Cannot set timing mode to %d (HAL_TIMING_...)\n", __func__, tm);
return -1;
}
return tm;
}
int shw_pps_get_timing_mode(void) {
struct rts_pll_state state;
if ( rts_get_state(&state)==-1 ) {
return -1;
}
switch ( state.mode ) {
case RTS_MODE_GM_EXTERNAL :
return HAL_TIMING_MODE_GRAND_MASTER;
break;
case RTS_MODE_GM_FREERUNNING :
return RTS_MODE_GM_FREERUNNING;
break;
case RTS_MODE_BC :
return HAL_TIMING_MODE_BC;
break;
case RTS_MODE_DISABLED :
return HAL_TIMING_MODE_DISABLED;
default :
return -1;
}
}
int shw_pps_get_timing_mode_state(void) {
struct rts_pll_state state;
if ( rts_get_state(&state)==-1 ) {
return -1;
}
/* In the future, we should be able to provide also the state HAL_TIMING_MODE_TMDT_HOLDOVER */
return (state.flags & RTS_DMTD_LOCKED) ? HAL_TIMING_MODE_TMDT_LOCKED : HAL_TIMING_MODE_TMDT_UNLOCKED;
}
void shw_pps_gen_read_time(uint64_t * seconds, uint32_t * nanoseconds)
{
uint32_t ns_cnt;
......
Subproject commit 2dc1b9094a287167ff6297a43e34f4d25e50acf4
Subproject commit be8e037238a2ca33e636f26ba693a5520192b97e
......@@ -20,6 +20,11 @@ start_counter() {
start() {
echo -n "Starting dropbear sshd: "
# copy authorized keys if exists
if [ -f /usr/authorized_keys ] ; then
mkdir -p /root/.ssh/
cp /usr/authorized_keys /root/.ssh/
fi
# Make sure dropbear directory exists
if [ ! -d /etc/dropbear ] ; then
mkdir -p /etc/dropbear
......
#!/bin/bash
#!/bin/bash
# Adam Wujek @ CERN
# Adam Wujek & Jean-Claude BAU @CERN
# script to assembly ppsi.conf based on dot-config configuration
#
# Parameters:
# -j generate JSON format of ppsi.conf
# -o file Overwrite the default output file name
# -i file Overwrite the default input dot-config file
# -p file Overwrite the default input psi-pre file
#
PRE_FILE="/wr/etc/ppsi-pre.conf"
OUTPUT_FILE="/etc/ppsi.conf"
DOTCONFIG_FILE="/wr/etc/dot-config"
unset JSON_FORMAT
#decode script parameters
while getopts jo:i:p: option
do
case "${option}" in
"j") JSON_FORMAT=1;;
"o") OUTPUT_FILE=${OPTARG};;
"i") DOTCONFIG_FILE=${OPTARG};;
"p") PRE_FILE=$OPTARG;;
esac
done
if [ -f "$DOTCONFIG_FILE" ]; then
. "$DOTCONFIG_FILE"
......@@ -15,191 +35,577 @@ else
exit 1
fi
echo "# Autogenerated file, please don't edit." > $OUTPUT_FILE
echo "# This file will be overwritten at next boot." >> $OUTPUT_FILE
script_name="$0"
#
# This function retreive the fiber delay coefficient from
# the CONFIG_FIBER${1}_PARAMS parameter
# Parameter :
# $1 = fiber index
# Return the fiber delay coefficient
function get_fiber_delay_coeff() {
local dc=0
local fb=$1
if [ -n "$fb" ]; then # check if fiber parameter exists
if [[ "$fb" =~ ^-?[0-9]+$ ]]; then # check if fiber parameter is an integer
printf -v fb "%02d" $fb
local fiber_param=$(eval "echo \$CONFIG_FIBER${fb}_PARAMS")
if [ -n "$fiber_param" ]; then # check if the fiber exists
IFS='=' read -a fpa <<< "$fiber_param"
dc=${fpa[1]}
else
echo "$script_name: Unknown fiber=\"$fb\" in CONFIG_PORT"$i_port"_FIBER"
fi
else
echo "$script_name: Invalid parameter fiber=\"$fb\" in CONFIG_PORT"$i_port"_FIBER"
fi
fi
echo "$dc"
}
#
# Decode ppsi.conf 'pre' file. It is used to define or override global keys.
# Expected file format :
# - must define key/value pairs separated with a space character : 'key value'
# - empty line are allowed
# - a comment start at the beginning of the line with the character '#'
# Parameter: $1 file_to_open
#
function decode_pre_file(){
filename="$1"
# read globals entries
while IFS='' read -r line ; do
if [[ -n "$line" ]] && [[ ${line:0:1} != "#" ]] ; then
IFS=' ' read var1 var2 <<< $line
if [[ -n $var1 ]] && [[ -n $var2 ]] ; then
globals[$var1]=$var2
fi
fi
done < "$filename"
}
#copy top of ppsi.conf
cat $PRE_FILE >> $OUTPUT_FILE
#
# Generate the ppsi.conf file using the default text format:
# - define key/value pairs separated with a space character : 'key value'
# - empty line are allowed
# - a comment start at the beginning of the line with the character '#'
# - port instances are separated by a empty line
#
# Parameter : $1 output_file_name
# $2 pre_file_name
function gen_ppsi_conf() {
# Read destination - stdout if not defined
output=${1:-/dev/stdout}
if [ -n "$CONFIG_PTP_OPT_CLOCK_CLASS" ]; then
echo clock-class "$CONFIG_PTP_OPT_CLOCK_CLASS" >> $OUTPUT_FILE
echo "# Autogenerated file, please don't edit." >$output
echo "# This file will be overwritten at next boot." >>$output
echo -e "\n# Globals\n" >>$output
# globals
for key in ${globals_indexes}; do
prefix=""
if [[ $key = *"${globals_not_yet_supported}"* ]] ; then
prefix="# Parameter not yet supported // "
fi
value=${globals[$key]}
if [ -n "$value" ]; then
echo "${prefix}$key $value" >>$output
fi
done
echo -e "\n\n# Port instances\n" >>$output
local size
# Physical ports
for i_port in {01..18}; do # scan all the physical ports
port_vn="port${i_port}"
# PPSI instances
for j_inst in {01..02}; do # scan all the ppsi instances for a given port
inst_vn="${port_vn}inst${j_inst}"
eval array=\( \${${inst_vn}[@]} \)
size=${#array[@]}
if [ "${size}" == "0" ] ; then
continue
fi
hpKeys="port proto iface profile"
for k in $hpKeys; do
v="$port_vn[$k]";[[ -n "${!v}" ]] && echo "$k ${!v}" >>$output
v="$inst_vn[$k]";[[ -n "${!v}" ]] && echo "$k ${!v}" >>$output
done
# print remaining keys
for k in $port_ppsi_keys ; do
[[ "$hpKeys" != *"$k"* ]] && (v="$port_vn[$k]";[[ -n "${!v}" ]] && echo "$k ${!v}" >>$output)
done
for k in $inst_ppsi_keys ; do
[[ "$hpKeys" != *"$k"* ]] && (v="$inst_vn[$k]";[[ -n "${!v}" ]] && echo "$k ${!v}" >>$output)
done
echo -n -e "\n\n" >>$output
done
done
}
#
# Generate the ppsi.conf file using a JSON format:
# {
# "globals": {
# "clock-class" : 187,
# ...
# },
# "ports" : [
# {
# "iface" : "wri1",
# ...
# "instances" : [
# {
# "name" : "wri1-i1",
# ...
# },
# { ... }
# ]
# },
# { ... }
# ]
# }
#
# Parameter : $1 output_file_name
# $2 pre_file_name
function gen_ppsi_conf_json() {
# Read destination - stdout if not defined
output=${1:-/dev/stdout}
# start globals
echo -e "{\n \"globals\": {\n" >$output
# globals
unset comma_g
for key in ${globals_indexes}; do
if [[ $key = *"${globals_not_yet_supported}"* ]] ; then
continue
fi
value=${globals[$key]}
if [ -n "$value" ]; then
[[ -n "${comma_g}" ]] && echo "," >>$output
echo -e -n " \"$key\": \"$value\"" >>$output
comma_g=1
fi
done
# end globals
echo -e -n "\n }" >>$output
# start ports
echo -e ",\n \"ports\": [" >>$output
local size
# Physical ports
for i_port in {01..18}; do # scan all the physical ports
port_vn="port${i_port}"
# start port
if [ $i_port == "01" ] ; then
echo -e " {" >>$output
else
echo -e ",\n {" >>$output
fi
hpKeys="iface"
for k in $hpKeys; do
v="$port_vn[$k]";[[ -n "${!v}" ]] && echo -e " \"$k\": \"${!v}\"," >>$output
done
# print remaining keys
for k in $port_ppsi_keys; do
[[ "$hpKeys" != *"$k"* ]] && (v="$port_vn[$k]"; [[ -n "${!v}" ]] && echo -e " \"$k\": \"${!v}\"," >>$output)
done
# start instances
echo -e " \"instances\": [" >>$output
# PPSI instances
for j_inst in {01..02}; do # scan all the ppsi instances for a given port
inst_vn="${port_vn}inst${j_inst}"
eval array=\( \${${inst_vn}[@]} \)
size=${#array[@]}
if [ "${size}" == "0" ] ; then
continue
fi
# start instance /instances
if [ $j_inst == "01" ] ; then
# start instances
echo -e " {" >>$output
else
echo -e ",\n {" >>$output
fi
hpKeys="port proto iface profile"
for k in $hpKeys; do
v="$inst_vn[$k]";[[ -n "${!v}" ]] && echo -e " \"$k\": \"${!v}\"," >>$output
done
# print remaining keys
for k in $inst_ppsi_keys ; do
[[ "$hpKeys" != *"$k"* ]] && (v="$inst_vn[$k]";[[ -n "${!v}" ]] && echo -e " \"$k\": \"${!v}\"," >>$output)
done
# end instance
echo -e -n "\n }" >>$output
done
# end instances
echo -e "\n ]" >>$output
# end port
echo -e -n " }" >>$output
done
# end ports
echo -e "\n ]" >>$output
# end main block
echo "}" >>$output
}
function disable_L1sync() {
local inst=$1
local lv
for k in l1SyncEnabled l1SyncTxCoherencyIsRequired l1SyncRxCoherencyIsRequired \
l1SyncCongruencyIsRequired logL1SyncInterval l1SyncReceiptTimeout l1SyncOptParamsEnabled; do
lv="$inst[$k]"; unset ${lv}
done
}
function set_profile_for_PTP() {
local inst=$1
local lv
disable_L1sync $inst
}
function set_profile_for_WR() {
local inst=$1
local lv
disable_L1sync $inst
}
function set_profile_for_HA() {
local inst=$1
local lv
# L1SYNC mandatory values
for k in l1SyncEnabled l1SyncTxCoherencyIsRequired l1SyncRxCoherencyIsRequired l1SyncCongruencyIsRequired ; do
lv="$inst[$k]"; eval ${lv}="y"
done
lv="$inst[l1SyncOptParamsEnabled]"; eval ${lv}="n"
# Free parameters
test ! ${inst_vn[logL1SyncInterval]+_} && (lv="$inst_vn[logL1SyncInterval]"; eval ${lv}="0") # Set default value
test ! ${inst_vn[l1SyncReceiptTimeout]+_} && (lv="$inst_vn[l1SyncReceiptTimeout]"; eval ${lv}="3") # Set default value
# Force asymmetry correction
lv="$inst[asymmetryCorrectionEnable]"; eval ${lv}="y"
}
function set_instance_profile() {
local inst=$1
local lv="$inst[profile]"
local value=${!lv}
if [ "${value}" == "wr" ]; then
eval ${lv}="wr"
set_profile_for_WR $inst
elif [ "${value}" == "ha" ]; then
eval ${lv}="ha"
elif [ "${value}" == "custom" ]; then
eval ${lv}="custom"
elif [ "${value}" == "none" ] || [ "${value}" == "ptp" ]; then
# do nothing
eval ${lv}="ptp"
set_profile_for_PTP $inst
elif [ -n "$p" ]; then
echo "$script_name: Invalid parameter profile=\"$p\" in ${inst}"
eval ${lv}="ha"
else
# default
eval ${lv}="ha"
fi
value=${!lv}
if [ "${value}" == "ha" ]; then
set_profile_for_HA $inst
fi
}
function build_port_ppsi_keys() {
local s=""
for i in "${!port_dotc_ppsi_key_mapping[@]}"
do
value=`echo ${port_dotc_ppsi_key_mapping[$i]} | head -n1 | cut -d " " -f1`;
[[ "$s" != *"$value"* ]] && s="$s $value"
done
echo `echo $s | xargs -n1 | sort -u | xargs`
}
function build_inst_ppsi_keys() {
local s=""
for i in "${!inst_dotc_ppsi_key_mapping[@]}"
do
value=`echo ${inst_dotc_ppsi_key_mapping[$i]} | head -n1 | cut -d " " -f1`;
[[ "$s" != *"$value"* ]] && s="$s $value"
done
echo `echo $s | xargs -n1 | sort -u | xargs`
}
globals_indexes='clock-class clock-accuracy clock-allan-variance domain-number priority1 priority2 time-source externalPortConfigurationEnabled slaveOnly ptpPpsThresholdMs ptpFallbackPpsGen gmDelayToGenPpsSec forcePpsGen'
globals_not_yet_supported='time-source'
# PHYSICAL PORT PARAMETERS
declare -A port_dotc_ppsi_key_mapping='(\
[FIBER]="delayCoefficient" \
[IFACE]="iface" \
[CONSTANT_ASYMMETRY]="constantAsymmetry" \
)'
port_dotc_keys="${!port_dotc_ppsi_key_mapping[@]}"
port_ppsi_keys=$(build_port_ppsi_keys)
# PPSI INSTANCE PARAMETERS
declare -A inst_dotc_ppsi_key_mapping='(\
[PROTOCOL_RAW]="proto raw" [PROTOCOL_UDP_IPV4]="proto udp" \
[MECHANISM_E2E]="mechanism e2e" [MECHANISM_P2P]="mechanism p2p" \
[PROFILE_PTP]="profile ptp" [PROFILE_WR]="profile wr" [PROFILE_HA]="profile ha" [PROFILE_CUSTOM]="profile custom" \
[DESIRADE_STATE_MASTER]="desiredState master" [DESIRADE_STATE_SLAVE]="desiredState slave" [DESIRADE_STATE_PASSIVE]="desiredState passive" \
[ANNOUNCE_INTERVAL]="logAnnounceInterval" [ANNOUNCE_RECEIPT_TIMEOUT]="announceReceiptTimeout" \
[MIN_DELAY_REQ_INTERVAL]="logMinDelayReqInterval" [MIN_PDELAY_REQ_INTERVAL]="logMinPDelayReqInterval" \
[ASYMMETRY_CORRECTION_ENABLE]="asymmetryCorrectionEnable" \
[BMODE_MASTER_ONLY]="masterOnly" \
[EGRESS_LATENCY]="egressLatency" [INGRESS_LATENCY]="ingressLatency" \
[L1SYNC_ENABLED]="l1SyncEnabled" [L1SYNC_INTERVAL]="logL1SyncInterval" \
[L1SYNC_RECEIPT_TIMEOUT]="l1SyncReceiptTimeout" \
[L1SYNC_OPT_PARAMS_ENABLED]="l1SyncOptParamsEnabled" [L1SYNC_OPT_PARAMS_TS_CORRECTED_TX_ENABLED]="l1SyncTimestampsCorrectedTxEnabled" \
[L1SYNC_TX_COHERENCY_IS_REQUIRED]="l1SyncTxCoherencyIsRequired" \
[L1SYNC_RX_COHERENCY_IS_REQUIRED]="l1SyncRxCoherencyIsRequired" [L1SYNC_CONGRUENCY_IS_REQUIRED]="l1SyncCongruencyIsRequired" \
)'
inst_dotc_keys="${!inst_dotc_ppsi_key_mapping[@]}"
inst_ppsi_keys=$(build_inst_ppsi_keys)
declare -A globals
# Read specific configuration : Still use the old format - to discuss
[[ "$PRE_FILE" != "" ]] && [[ -f $PRE_FILE ]] && decode_pre_file "$PRE_FILE"
# Use default value of clock class if not overwritten or empty string
if [ -v CONFIG_PTP_OPT_OVERWRITE_CLOCK_CLASS ] && [ -n "$CONFIG_PTP_OPT_CLOCK_CLASS" ]; then
globals[clock-class]="$CONFIG_PTP_OPT_CLOCK_CLASS"
else
if [ "$CONFIG_TIME_GM" = "y" ]; then
echo clock-class 6 >> $OUTPUT_FILE
globals[clock-class]=6
fi
if [ "$CONFIG_TIME_FM" = "y" ]; then
echo clock-class 52 >> $OUTPUT_FILE
globals[clock-class]=52
fi
if [ "$CONFIG_TIME_BC" = "y" ]; then
echo clock-class 248 >> $OUTPUT_FILE
globals[clock-class]=248
fi
fi
if [ -n "$CONFIG_PTP_OPT_CLOCK_ACCURACY" ]; then
echo clock-accuracy "$CONFIG_PTP_OPT_CLOCK_ACCURACY" >> $OUTPUT_FILE
globals[clock-accuracy]="$CONFIG_PTP_OPT_CLOCK_ACCURACY"
fi
if [ -n "$CONFIG_PTP_OPT_CLOCK_ALLAN_VARIANCE" ]; then
echo clock-allan-variance "$CONFIG_PTP_OPT_CLOCK_ALLAN_VARIANCE" >> $OUTPUT_FILE
globals[clock-allan-variance]="$CONFIG_PTP_OPT_CLOCK_ALLAN_VARIANCE"
fi
if [ -n "$CONFIG_PTP_OPT_DOMAIN_NUMBER" ]; then
echo domain-number "$CONFIG_PTP_OPT_DOMAIN_NUMBER" >> $OUTPUT_FILE
globals[domain-number]="$CONFIG_PTP_OPT_DOMAIN_NUMBER"
fi
if [ -n "$CONFIG_PTP_OPT_ANNOUNCE_INTERVAL" ]; then
echo announce-interval "$CONFIG_PTP_OPT_ANNOUNCE_INTERVAL" >> $OUTPUT_FILE
globals[announce-interval]="$CONFIG_PTP_OPT_ANNOUNCE_INTERVAL"
fi
if [ -n "$CONFIG_PTP_OPT_SYNC_INTERVAL" ]; then
echo sync-interval "$CONFIG_PTP_OPT_SYNC_INTERVAL" >> $OUTPUT_FILE
globals[sync-interval]="$CONFIG_PTP_OPT_SYNC_INTERVAL"
fi
if [ -n "$CONFIG_PTP_OPT_PRIORITY1" ]; then
echo priority1 "$CONFIG_PTP_OPT_PRIORITY1" >> $OUTPUT_FILE
globals[priority1]="$CONFIG_PTP_OPT_PRIORITY1"
fi
if [ -n "$CONFIG_PTP_OPT_PRIORITY2" ]; then
echo priority2 "$CONFIG_PTP_OPT_PRIORITY2" >> $OUTPUT_FILE
globals[priority2]="$CONFIG_PTP_OPT_PRIORITY2"
fi
if [ -n "$CONFIG_PTP_OPT_TIME_SOURCE" ]; then
echo time-source "$CONFIG_PTP_OPT_TIME_SOURCE" >> $OUTPUT_FILE
if [ -v CONFIG_PTP_OPT_OVERWRITE_TIME_SOURCE ] && [ -n "$CONFIG_PTP_OPT_TIME_SOURCE" ]; then
globals[time-source]="$CONFIG_PTP_OPT_TIME_SOURCE"
else
if [ "$CONFIG_TIME_GM" = "y" ]; then
globals[time-source]=16 # ATOMIC_CLOCK
fi
if [ "$CONFIG_TIME_FM" = "y" ]; then
globals[time-source]=160 # INTERNAL_OSCILLATOR
fi
if [ "$CONFIG_TIME_BC" = "y" ]; then
globals[time-source]=160 # INTERNAL_OSCILLATOR
fi
fi
if [ -n "$CONFIG_PTP_OPT_EXT_PORT_CONFIG_ENABLED" ]; then
globals[externalPortConfigurationEnabled]="$CONFIG_PTP_OPT_EXT_PORT_CONFIG_ENABLED"
else
globals[externalPortConfigurationEnabled]="n"
fi
# 2 new lines
echo -n -e "\n\n" >> $OUTPUT_FILE
if [ -n "$CONFIG_PTP_SLAVE_ONLY" ] && [ "${globals[externalPortConfigurationEnabled]}" = "n" ]; then
globals[slaveOnly]="$CONFIG_PTP_SLAVE_ONLY"
else
globals[slaveOnly]="n"
fi
for i_zero in {01..18};do
# unset parametes
unset p_name
unset p_proto
unset p_role
unset p_ext
# delay mechanism
unset p_dm
unset p_monitor
# parse parameters
param_line=$(eval "echo \$CONFIG_PORT"$i_zero"_PARAMS")
IFS_OLD=$IFS
IFS=','
# save pairs into array
pair_array=($param_line)
IFS=$IFS_OLD
for pair in ${pair_array[@]}
do
# split pairs
IFS='=' read param value <<< "$pair"
case "$param" in
"name")
p_name="$value";;
"proto")
p_proto="$value";;
"role")
p_role="$value";;
"ext")
p_ext="$value";;
"dm")
p_dm="$value";;
"monitor")
# read by SNMP directly from the config
continue;;
"rx"|"tx"|"fiber")
continue;;
*)
echo "$0: Invalid parameter $param in CONFIG_PORT"$i_zero"_PARAMS" ;;
esac
if [ -n "$CONFIG_PPSGEN_PTP_THRESHOLD_MS" ]; then
globals[ptpPpsThresholdMs]="$CONFIG_PPSGEN_PTP_THRESHOLD_MS"
fi
if [ -n "$CONFIG_PPSGEN_PTP_FALLBACK" ]; then
globals[ptpFallbackPpsGen]="$CONFIG_PPSGEN_PTP_FALLBACK"
fi
if [ -n "$CONFIG_PPSGEN_GM_DELAY_TO_GEN_PPS_SEC" ]; then
globals[gmDelayToGenPpsSec]="$CONFIG_PPSGEN_GM_DELAY_TO_GEN_PPS_SEC"
fi
if [ -n "$CONFIG_PPSGEN_FORCE" ]; then
globals[forcePpsGen]="$CONFIG_PPSGEN_FORCE"
fi
done
for i_port in {01..18}; do # scan all the physical ports
# if role "none" skip port configuration
if [ "$p_role" == "none" ]; then
continue
fi
port_vn="port${i_port}"
declare -A $port_vn
#remove leading zero from i_zero (params has numbers with leading zero,
#remove leading zero from i_port (params has numbers with leading zero,
#interface names are without leading zero)
i=$(expr $i_zero + 0)
if [ -n "$p_proto" ]; then
echo "port wri$i-$p_proto" >> $OUTPUT_FILE
echo "proto $p_proto" >> $OUTPUT_FILE
else
echo "port wri$i-raw" >> $OUTPUT_FILE
fi
echo "iface wri$i" >> $OUTPUT_FILE
i_port_int=$(expr $i_port + 0)
# parse parameters
port_key="CONFIG_PORT${i_port}"
for p in $port_dotc_keys; do
k="${port_key}_$p"
plc="${port_dotc_ppsi_key_mapping[$p]}"
if [ -n "${!k}" ] && [ "$plc" != "" ]; then
v="$port_vn[${plc}]";
if [ "$p" == "FIBER" ] ; then
# Special treatment for FIBER : Retreive the delay coefficient from the DB
fiber_num="${!k}"
eval ${v}=$(get_fiber_delay_coeff $fiber_num)
else
eval ${v}="${!k}"
fi
fi
done
if [ -n "$p_role" ]; then
echo "role $p_role" >> $OUTPUT_FILE
else
echo "$0: Role not defined in CONFIG_PORT"$i_zero"_PARAMS"
fi
for j_inst in {01..02}; do # scan all the ppsi instances for a given port
if [ "${p_ext,,}" = "wr" ]; then # lower case
echo "extension whiterabbit" >> $OUTPUT_FILE
# add HA one day...
# elif [ "${p_ext,,}" = "ha" ]; then # lower case
# echo "extension whiterabbit" >> $OUTPUT_FILE
elif [ "${p_ext,,}" = "none" ]; then # lower case
# do nothing
echo "# no extension" >> $OUTPUT_FILE
elif [ -n "$p_ext" ]; then
echo "$0: Invalid parameter ext=\"$p_ext\" in CONFIG_PORT"$i_zero"_PARAMS"
else
# default
echo "extension whiterabbit" >> $OUTPUT_FILE
fi
#remove leading zero from i_port (params has numbers with leading zero,
#interface names are without leading zero)
j_inst_int=$(expr $j_inst + 0)
inst_count="CONFIG_PORT${i_port}_INSTANCE_COUNT_`expr ${j_inst_int} - 1`"
inst_count_value=$(eval "echo \$${inst_count}")
if [ -n "${inst_count_value}" ]; then
break # number of defined instances reached
fi
inst_vn="${port_vn}inst${j_inst}"
declare -A $inst_vn
inst_key="CONFIG_PORT${i_port}_INST${j_inst}"
if [ "${p_dm,,}" = "p2p" ]; then # lower case
echo "mechanism p2p" >> $OUTPUT_FILE
elif [ "${p_dm,,}" = "e2e" ]; then # lower case
# do nothing
true
elif [ -n "$p_dm" ]; then
echo "$0: Invalid parameter dm=\"$p_dm\" in CONFIG_PORT"$i_zero"_PARAMS"
fi
for p in $inst_dotc_keys; do
k="${inst_key}_$p"
plc="${inst_dotc_ppsi_key_mapping[$p]}"
if [ -n "${!k}" ] && [ "$plc" != "" ]; then
# Check if the string contains 2 elements separated by a space
OIFS=${IFS}; IFS=' ' read -a tokens <<< "${plc}"; IFS=${OIFS}
plc=${tokens[0]};
v="$inst_vn[${plc}]"
if [ "${#tokens[@]}" -gt "1" ] ; then
eval ${v}="${tokens[1]}";
else
eval ${v}="${!k}"
fi
fi
done
# add vlans
if [ "$CONFIG_VLANS_ENABLE" = "y" ]; then
unset ppsi_vlans;
unset port_mode_access;
unset port_mode_trunk;
unset port_mode_unqualified;
unset port_mode_disabled;
# check port mode
port_mode_access=$(eval "echo \$CONFIG_VLANS_PORT"$i_zero"_MODE_ACCESS")
port_mode_trunk=$(eval "echo \$CONFIG_VLANS_PORT"$i_zero"_MODE_TRUNK")
port_mode_unqualified=$(eval "echo \$CONFIG_VLANS_PORT"$i_zero"_MODE_UNQUALIFIED")
port_mode_disabled=$(eval "echo \$CONFIG_VLANS_PORT"$i_zero"_MODE_DISABLED")
# check port mode
if [ "$port_mode_access" = "y" ]; then
ppsi_vlans=$(eval "echo \$CONFIG_VLANS_PORT"$i_zero"_VID")
# use "&> /dev/null" to avoid error when $ppsi_vlans
# is not a number
if [ "$ppsi_vlans" -ge 0 ] &> /dev/null \
&& [ "$ppsi_vlans" -le 4094 ] &> /dev/null; then
echo "vlan $ppsi_vlans" >> $OUTPUT_FILE
else
echo "$0: Wrong value \"$ppsi_vlans\" in CONFIG_VLANS_PORT"$i_zero"_VID"
continue;
v="$inst_vn[proto]"
if [ ! -n "${!v}" ]; then
eval ${v}="raw" # proto not defined. Set it to raw by default
fi
# set the profile
set_instance_profile $inst_vn
v="$inst_vn[profile]"; p_profile=${!v}
# define instance name
v="$port_vn[iface]"; p_iface=${!v}
v="$inst_vn[proto]"; p_proto=${!v}
v="$inst_vn[port]"; eval ${v}="${p_iface}-${j_inst_int}-${p_profile:0:2}-${p_proto}"
# if extPortConfiguration enabled, get the desired state
if [ "$CONFIG_PTP_OPT_EXT_PORT_CONFIG_ENABLED" == 'y' ] ; then
v="$inst_vn[desiredState]";
if [ -z "{!v}" ] ; then
eval ${v}="passive" # default value
fi
v="$inst_vn[masteronly]"; unset ${v} # remove master only
fi
if [ "$port_mode_trunk" = "y" ] \
|| [ "$port_mode_disabled" = "y" ] \
|| [ "$port_mode_unqualified" = "y" ]; then
ppsi_vlans=$(eval "echo \$CONFIG_VLANS_PORT"$i_zero"_VID")
if [ -n "$ppsi_vlans" ]; then
mod_vlans=${ppsi_vlans//;/,}
echo "vlan $mod_vlans" >> $OUTPUT_FILE
# add vlans
if [ "$CONFIG_VLANS_ENABLE" = "y" ]; then
unset ppsi_vlans;
unset port_mode_access;
unset port_mode_trunk;
unset port_mode_unqualified;
unset port_mode_disabled;
# check port mode
port_mode_access=$(eval "echo \$CONFIG_VLANS_PORT"$i_port"_MODE_ACCESS")
port_mode_trunk=$(eval "echo \$CONFIG_VLANS_PORT"$i_port"_MODE_TRUNK")
port_mode_unqualified=$(eval "echo \$CONFIG_VLANS_PORT"$i_port"_MODE_UNQUALIFIED")
port_mode_disabled=$(eval "echo \$CONFIG_VLANS_PORT"$i_port"_MODE_DISABLED")
# check port mode
if [ "$port_mode_access" = "y" ]; then
ppsi_vlans=$(eval "echo \$CONFIG_VLANS_PORT"$i_port"_VID")
# use "&> /dev/null" to avoid error when $ppsi_vlans
# is not a number
if [ "$ppsi_vlans" -ge 0 ] &> /dev/null \
&& [ "$ppsi_vlans" -le 4094 ] &> /dev/null; then
v="$inst_vn[vlan]"; eval ${v}="$ppsi_vlans"
else
echo "$script_name: Wrong value \"$ppsi_vlans\" in CONFIG_VLANS_PORT"$i_port"_VID"
continue;
fi
fi
if [ "$port_mode_trunk" = "y" ] \
|| [ "$port_mode_disabled" = "y" ] \
|| [ "$port_mode_unqualified" = "y" ]; then
ppsi_vlans=$(eval "echo \$CONFIG_VLANS_PORT"$i_port"_VID")
if [ -n "$ppsi_vlans" ]; then
mod_vlans=${ppsi_vlans//;/,}
v="$inst_vn[vlan]"; eval ${v}="$mod_vlans"
fi
fi
fi
fi
done # scan all the ppsi instances in a port
done # scan all the physical ports
# separate ports
echo "" >> $OUTPUT_FILE
done
if [ -v JSON_FORMAT ] ; then
gen_ppsi_conf_json ${OUTPUT_FILE} ${PRE_FILE}
else
gen_ppsi_conf ${OUTPUT_FILE} ${PRE_FILE}
fi
......@@ -7,90 +7,90 @@ clock-accuracy 254
port wri1
iface wri1
role auto
extension whiterabbit
profile whiterabbit
port wri2
iface wri2
role auto
extension whiterabbit
profile whiterabbit
port wri3
iface wri3
role auto
extension whiterabbit
profile whiterabbit
port wri4
iface wri4
role auto
extension whiterabbit
profile whiterabbit
port wri5
iface wri5
role auto
extension whiterabbit
profile whiterabbit
port wri6
iface wri6
role auto
extension whiterabbit
profile whiterabbit
port wri7
iface wri7
role auto
extension whiterabbit
profile whiterabbit
port wri8
iface wri8
role auto
extension whiterabbit
profile whiterabbit
port wri9
iface wri9
role auto
extension whiterabbit
profile whiterabbit
port wri10
iface wri10
role auto
extension whiterabbit
profile whiterabbit
port wri11
iface wri11
role auto
extension whiterabbit
profile whiterabbit
port wri12
iface wri12
role auto
extension whiterabbit
profile whiterabbit
port wri13
iface wri13
role auto
extension whiterabbit
profile whiterabbit
port wri14
iface wri14
role auto
extension whiterabbit
profile whiterabbit
port wri15
iface wri15
role auto
extension whiterabbit
profile whiterabbit
port wri16
iface wri16
role auto
extension whiterabbit
profile whiterabbit
port wri17
iface wri17
role auto
extension whiterabbit
profile whiterabbit
port wri18
iface wri18
role auto
extension whiterabbit
profile whiterabbit
# Global settings
clock-class 187
clock-accuracy 254
# This file is used to declare global settings which are not defined or left empty
# in the dot-config file.
......@@ -10,7 +10,8 @@ int hal_nports_local;
/* PPSI */
struct wrs_shm_head *ppsi_head;
static struct pp_globals *ppg;
struct wr_servo_state *ppsi_servo;
struct pp_servo *ppsi_servo;
struct wr_servo_state *ppsi_wr_servo;
struct pp_instance *ppsi_ppi;
int *ppsi_ppi_nlinks;
......@@ -111,11 +112,13 @@ static int init_shm_ppsi(void)
}
ppg = (void *)ppsi_head + ppsi_head->data_off;
ppsi_servo = wrs_shm_follow(ppsi_head, ppg->global_ext_data);
if (!ppsi_servo) {
snmp_log(LOG_ERR, "Cannot follow ppsi_servo in shmem.\n");
return 4;
}
/* TODO JCB Servo is part of an instance now */
ppsi_servo=NULL;
// ppsi_servo = wrs_shm_follow(ppsi_head, ppg->servo);
// if (!ppsi_servo) {
// snmp_log(LOG_ERR, "Cannot follow ppsi_servo in shmem.\n");
// return 4;
// }
ppsi_ppi = wrs_shm_follow(ppsi_head, ppg->pp_instances);
if (!ppsi_ppi) {
......
......@@ -15,7 +15,7 @@ extern int hal_nports_local;
/* PPSI */
extern struct wrs_shm_head *ppsi_head;
extern struct wr_servo_state *ppsi_servo;
extern struct pp_servo *ppsi_servo;
extern struct pp_instance *ppsi_ppi;
extern int *ppsi_ppi_nlinks;
......
......@@ -93,10 +93,6 @@ time_t wrsPortStatusTable_data_fill(unsigned int *n_rows)
*/
wrsPortStatusTable_array[i].wrsPortStatusLink =
1 + state_up(port_state->state);
/* values defined as
* WRS_PORT_STATUS_CONFIGURED_MODE_* */
wrsPortStatusTable_array[i].wrsPortStatusConfiguredMode =
port_state->mode;
if (port_state->state == HAL_PORT_STATE_DISABLED) {
wrsPortStatusTable_array[i].wrsPortStatusSfpError =
WRS_PORT_STATUS_SFP_ERROR_PORT_DOWN;
......
......@@ -83,34 +83,32 @@ time_t wrsPtpDataTable_data_fill(unsigned int *n_rows)
while (1) {
ii = wrs_shm_seqbegin(ppsi_head);
strncpy(wrsPtpDataTable_array[0].wrsPtpServoState,
ppsi_servo->servo_state_name,
sizeof(ppsi_servo->servo_state_name));
wrsPtpDataTable_array[0].wrsPtpServoStateN = ppsi_servo->state;
/* Keep value 0 for Not available */
wrsPtpDataTable_array[0].wrsPtpPhaseTracking =
1 + ppsi_servo->tracking_enabled;
wrsPtpDataTable_array[0].wrsPtpRTT = ppsi_servo->picos_mu;
wrsPtpDataTable_array[0].wrsPtpClockOffsetPs =
ppsi_servo->offset;
wrsPtpDataTable_array[0].wrsPtpClockOffsetPsHR =
int_saturate(ppsi_servo->offset);
wrsPtpDataTable_array[0].wrsPtpSkew =
int_saturate(ppsi_servo->skew);
wrsPtpDataTable_array[0].wrsPtpLinkLength =
(uint32_t)(ppsi_servo->delta_ms/1e12 * 300e6 / 1.55);
wrsPtpDataTable_array[0].wrsPtpServoUpdates =
ppsi_servo->update_count;
wrsPtpDataTable_array[0].wrsPtpDeltaTxM = ppsi_servo->delta_tx_m;
wrsPtpDataTable_array[0].wrsPtpDeltaRxM = ppsi_servo->delta_rx_m;
wrsPtpDataTable_array[0].wrsPtpDeltaTxS = ppsi_servo->delta_tx_s;
wrsPtpDataTable_array[0].wrsPtpDeltaRxS = ppsi_servo->delta_rx_s;
wrsPtpDataTable_array[0].wrsPtpServoStateErrCnt = ppsi_servo->n_err_state;
wrsPtpDataTable_array[0].wrsPtpClockOffsetErrCnt = ppsi_servo->n_err_offset;
wrsPtpDataTable_array[0].wrsPtpRTTErrCnt = ppsi_servo->n_err_delta_rtt;
wrsPtpDataTable_array[0].wrsPtpServoUpdateTime =
ppsi_servo->update_time.secs * 1000 * 1000 * 1000
+ (ppsi_servo->update_time.scaled_nsecs >> 16);
//TODO JCB : Search servo instance to display
// strncpy(wrsPtpDataTable_array[0].wrsPtpServoState,
// ppsi_servo->servo_state_name,
// sizeof(ppsi_servo->servo_state_name));
// wrsPtpDataTable_array[0].wrsPtpServoStateN = ppsi_servo->state;
// /* Keep value 0 for Not available */
// wrsPtpDataTable_array[0].wrsPtpPhaseTracking = 0; //JCB TODO 1 + ppsi_servo->tracking_enabled;
// wrsPtpDataTable_array[0].wrsPtpRTT = 0; //JCB TODO ppsi_servo->picos_mu;
// wrsPtpDataTable_array[0].wrsPtpClockOffsetPs = pp_time_to_picos(&ppsi_servo->offsetFromMaster);
// wrsPtpDataTable_array[0].wrsPtpClockOffsetPsHR =
// int_saturate(wrsPtpDataTable_array[0].wrsPtpClockOffsetPs);
// wrsPtpDataTable_array[0].wrsPtpSkew = 0; //JCB TODO int_saturate(ppsi_servo->skew);
// wrsPtpDataTable_array[0].wrsPtpLinkLength =
// (uint32_t)(pp_time_to_picos(&ppsi_servo->delayMS)/1e12 * 300e6 / 1.55);
// wrsPtpDataTable_array[0].wrsPtpServoUpdates =
// ppsi_servo->update_count;
// wrsPtpDataTable_array[0].wrsPtpDeltaTxM = 0;//JCB TODO ppsi_servo->delta_txm_ps;
// wrsPtpDataTable_array[0].wrsPtpDeltaRxM = 0;//JCB TODO ppsi_servo->delta_rxm_ps;
// wrsPtpDataTable_array[0].wrsPtpDeltaTxS = 0;//JCB TODO ppsi_servo->delta_txs_ps;
// wrsPtpDataTable_array[0].wrsPtpDeltaRxS = 0;//JCB TODO ppsi_servo->delta_rxs_ps;
// wrsPtpDataTable_array[0].wrsPtpServoStateErrCnt = 0;//JCB TODO ppsi_servo->n_err_state;
// wrsPtpDataTable_array[0].wrsPtpClockOffsetErrCnt = 0;//JCB TODO ppsi_servo->n_err_offset;
// wrsPtpDataTable_array[0].wrsPtpRTTErrCnt = 0;//JCB TODO ppsi_servo->n_err_delta_rtt;
// wrsPtpDataTable_array[0].wrsPtpServoUpdateTime = 0;
// //JCB TODO ppsi_servo->update_time.secs * 1000 * 1000 * 1000
// //JCB TODO + (ppsi_servo->update_time.scaled_nsecs >> 16);
retries++;
if (retries > 100) {
snmp_log(LOG_ERR, "%s: too many retries to read PPSI\n",
......
# We are now Kconfig-based
-include ../../.config
TOOLS = rtu_stat wr_mon wr_phytool wrs_pps_control spll_dbg_proxy load-lm32 load-virtex com
TOOLS += mapper wmapper
TOOLS += wrs_version wr_date lm32-vuart wrs_pstats
......@@ -28,7 +32,10 @@ OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
# LOTs of includes
CFLAGS = -O2 -g -Wall \
export CFLAGS_OPTIMIZATION:= ${shell echo $(CONFIG_OPTIMIZATION)}
CFLAGS += $(CFLAGS_OPTIMIZATION)
CFLAGS += -Wall \
-Wstrict-prototypes \
-I$(LINUX)/arch/arm/mach-at91/include \
-I../wrsw_rtud \
......@@ -69,10 +76,10 @@ check:
$(CC) $*.o $(LDFLAGS) -o $*
VPATH+=../ppsi/tools
wrs_dump_shmem: wrs_dump_shmem.o wrs_dump_shmem_ppsi.o
wrs_dump_shmem: wrs_dump_shmem.o wrs_dump_shmem_ppsi.o time_lib.o
${CC} -o $@ $^ $(LDFLAGS)
wr_mon: wr_mon.o term.o
wr_mon: wr_mon.o term.o time_lib.o
${CC} -o $@ $^ $(LDFLAGS)
wr_management: wr_management.o term.o
......
/**
* Time to string conversion functions
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <ppsi/ppsi.h>
char * timeIntervalToString(TimeInterval time,char *buf) {
int64_t sign,nanos,picos;
if ( time<0 && time !=INT64_MIN) {
sign=-1;
time=-time;
} else {
sign=1;
}
nanos = time >> TIME_INTERVAL_FRACBITS;
picos = (((time & TIME_INTERVAL_FRACMASK) * 1000) + TIME_INTERVAL_ROUNDING_VALUE ) >> TIME_INTERVAL_FRACBITS;
sprintf(buf,"%" PRId64 ".%03" PRId64, sign*nanos,picos);
return buf;
}
char * timeToString(struct pp_time *time, char *buf) {
char sign = '+';
int64_t scaled_nsecs = time->scaled_nsecs;
int64_t secs = time->secs, nanos, picos;
if (!is_incorrect(time)) {
if (scaled_nsecs < 0 || secs < 0) {
sign = '-';
scaled_nsecs = -scaled_nsecs;
secs = -secs;
}
nanos = scaled_nsecs >> TIME_FRACBITS;
picos = ((scaled_nsecs & TIME_FRACMASK) * 1000 + TIME_ROUNDING_VALUE)
>> TIME_FRACBITS;
sprintf(buf,"%c%" PRId64 ".%09" PRId64 "%03" PRId64,
sign,secs,nanos,picos);
} else {
sprintf(buf, "--Incorrect--");
}
return buf;
}
char * timestampToString(struct Timestamp *time,char *buf){
uint64_t sec=(time->secondsField.msb << sizeof(time->secondsField.msb)) + time->secondsField.lsb;
sprintf(buf,"%" PRIu64 ".%09" PRIu32 "000",
sec, (uint32_t)time->nanosecondsField);
return buf;
}
char * relativeDifferenceToString(RelativeDifference time, char *buf ) {
int32_t nsecs=time >> REL_DIFF_FRACBITS;
uint64_t sub_yocto=0;
int64_t fraction;
uint64_t bitWeight=500000000000000000;
uint64_t mask;
fraction=time & REL_DIFF_FRACMASK;
for (mask=(uint64_t) 1<< (REL_DIFF_FRACBITS-1);mask!=0; mask>>=1 ) {
if ( mask & fraction )
sub_yocto+=bitWeight;
bitWeight/=2;
}
sprintf(buf,"%"PRId32".%018"PRIu64, nsecs, sub_yocto);
return buf;
}
#include <ppsi/ppsi.h>
/* Prototypes */
char * timeIntervalToString(TimeInterval time,char *buf);
char * timeToString(struct pp_time *time,char *buf);
char * timestampToString(struct Timestamp *time,char *buf);
char * relativeDifferenceToString(RelativeDifference time, char *buf );
......@@ -29,6 +29,9 @@
/* Address for hardware, from nic-hardware.h */
#define FPGA_BASE_PPSG 0x10010500
extern int init_module(void *module, unsigned long len, const char *options);
extern int delete_module(const char *module, unsigned int flags);
void help(char *prgname)
{
fprintf(stderr, "%s: Use: \"%s [<options>] <cmd> [<args>]\n",
......@@ -43,6 +46,7 @@ void help(char *prgname)
" get tohost print WR time and set system time\n"
" set <value> set WR time to scalar seconds\n"
" set host set TAI from current host time\n"
" stat print statistics between TAI (WR time) and linux UTC\n"
/* " set ntp set TAI from ntp and leap seconds" */
/* " set ntp:<ip> set from specified ntp server\n" */
, WRDATE_CFG_FILE);
......@@ -216,16 +220,108 @@ int fix_host_tai(void)
return tai_offset;
}
#define ADJ_SEC_ITER 10
static int wait_wr_adjustment(struct PPSG_WB *pps)
{
int count=0;
while ((pps->CR & PPSG_CR_CNT_ADJ)==0) {
if ( (count++)>=ADJ_SEC_ITER ) {
fprintf(stderr, "%s: warning: WR time adjustment not finished after %ds !!!\n",prgname,ADJ_SEC_ITER);
return 0;
}
if (opt_verbose)
printf("WR time adjustment: waiting.\n");
sleep(1);
}
if (opt_verbose)
printf("WR time adjustment: done.\n");
return 1;
}
#define CLOCK_SOURCE_MODULE_NAME "wr_clocksource"
#define CLOCK_SOURCE_MODULE_ELF "/wr/lib/modules/" CLOCK_SOURCE_MODULE_NAME ".ko"
int removeClockSourceModule(void) {
int ret= delete_module(CLOCK_SOURCE_MODULE_NAME, 0);
if ( ret<0 ) {
fprintf(stderr, "%s: Warning: Cannot remove module "CLOCK_SOURCE_MODULE_NAME " : error=%s\n" ,
prgname,
strerror(errno));
return 0;
}
if (opt_verbose) {
printf("Driver module "CLOCK_SOURCE_MODULE_NAME" removed.\n");
}
return 1;
}
int installClockSourceModule(void) {
struct stat st;
void *image=NULL;
int fd;
int ret=0;
const char *params="";
if ((fd = open(CLOCK_SOURCE_MODULE_ELF, O_RDONLY))<0 ) {
fprintf(stderr, "%s: Warning: Cannot open file "CLOCK_SOURCE_MODULE_ELF " : error=%s\n" ,
prgname,
strerror(errno));
goto out;;
}
if ( fstat(fd, &st)<0 ) {
fprintf(stderr, "%s: Warning: Cannot stat file "CLOCK_SOURCE_MODULE_ELF " : error=%s\n" ,
prgname,
strerror(errno));
goto out;
}
if ( (image = malloc(st.st_size)) ==NULL ) {
fprintf(stderr, "%s: Warning: Cannot allocate memory : error=%s\n" ,
prgname,
strerror(errno));
goto out;
}
if ( read(fd, image, st.st_size)< 0 ) {
fprintf(stderr, "%s: Warning: Cannot read file "CLOCK_SOURCE_MODULE_ELF " : error=%s\n" ,
prgname,
strerror(errno));
goto out;
}
if (init_module(image, st.st_size, params) != 0) {
fprintf(stderr, "%s: Warning: Cannot init module "CLOCK_SOURCE_MODULE_NAME " : error=%s\n" ,
prgname,
strerror(errno));
goto out;
}
ret=1;
out:;
if ( fd >=0 )
close(fd);
if ( image!=NULL)
free(image);
return ret;
}
/* This sets WR time from host time */
int wrdate_internal_set(struct PPSG_WB *pps)
int __wrdate_internal_set(struct PPSG_WB *pps, int deep)
{
struct timeval tvh, tvr; /* host, rabbit */
signed long long diff64;
signed long diff;
int tai_offset;
int modRemoved=0;
if ( deep > 4 )
return 0; /* Avoid stack overflow (recursive function) in case of error */
if ( deep==0 ) {
modRemoved=removeClockSourceModule(); // The driver must be removed otherwise the time cannot be set properly
}
tai_offset = fix_host_tai();
usleep(100);
gettimeofday(&tvh, NULL);
gettimeof_wr(&tvr, pps);
......@@ -246,7 +342,7 @@ int wrdate_internal_set(struct PPSG_WB *pps)
fprintf(stderr, "%s: Warning: fractional second differs by"
"more than 0.2 (%li ms)\n", prgname, diff / 1000);
if (opt_verbose) {
if (opt_verbose && deep==0) {
printf("Host time: %9li.%06li\n", (long)(tvh.tv_sec),
(long)(tvh.tv_usec));
printf("WR time: %9li.%06li\n", (long)(tvr.tv_sec),
......@@ -263,18 +359,41 @@ int wrdate_internal_set(struct PPSG_WB *pps)
pps->ADJ_NSEC = 0;
asm("" : : : "memory"); /* barrier... */
pps->CR = pps->CR | PPSG_CR_CNT_ADJ;
if ( wait_wr_adjustment(pps) )
__wrdate_internal_set(pps,deep+1); /* adjust the usecs */
} else {
if (opt_verbose)
printf("adjusting by %li usecs\n", diff);
pps->ADJ_UTCLO = 0;
pps->ADJ_UTCHI = 0;
pps->ADJ_NSEC = diff * 64 + diff / 2;
pps->ADJ_NSEC = (diff*1000)/16;
asm("" : : : "memory"); /* barrier... */
pps->CR = pps->CR | PPSG_CR_CNT_ADJ;
wait_wr_adjustment(pps);
}
if ( deep==0 && modRemoved ) {
installClockSourceModule();
}
if (opt_verbose && deep==0) {
usleep(100);
gettimeofday(&tvh, NULL);
gettimeof_wr(&tvr, pps);
printf("Host time: %9li.%06li\n", (long)(tvh.tv_sec),
(long)(tvh.tv_usec));
printf("WR time: %9li.%06li\n", (long)(tvr.tv_sec),
(long)(tvr.tv_usec));
}
return 0;
}
/* This sets WR time from host time */
int wrdate_internal_set(struct PPSG_WB *pps) {
return __wrdate_internal_set(pps,0);
}
/* Frontend to the set mechanism: parse the argument */
int wrdate_set(struct PPSG_WB *pps, char *arg)
{
......@@ -303,6 +422,57 @@ int wrdate_set(struct PPSG_WB *pps, char *arg)
return 0;
}
/* Print statistics between TAI and UTC dates */
#define STAT_SAMPLE_COUNT 20
int wrdate_stat(struct PPSG_WB *pps)
{
int udiff_ref=0,udiff_last;
printf("Diff_TAI_UTC[sec] Diff_with_last[usec] Diff_with_ref[usec]\n");
while ( 1 ) {
int64_t udiff_arr[STAT_SAMPLE_COUNT]; // Diff in useconds
struct timeval tv_tai,tv_host;
int i;
int64_t udiff_sum=0, udiff;
for ( i=0; i<STAT_SAMPLE_COUNT; i++ ) {
int64_t *udiff_tmp=&udiff_arr[i];
// Get time
usleep(100); // Increase stability of measures : less preempted during time measures
gettimeof_wr(&tv_tai,pps);
gettimeofday(&tv_host, NULL);
// Calculate difference
*udiff_tmp=(tv_host.tv_sec-tv_tai.tv_sec)*1000000;
if ( tv_host.tv_usec > tv_tai.tv_usec ) {
*udiff_tmp+=tv_host.tv_usec-tv_tai.tv_usec;
} else {
*udiff_tmp-=tv_tai.tv_usec-tv_host.tv_usec;
}
udiff_sum+=*udiff_tmp;
}
udiff=udiff_sum/STAT_SAMPLE_COUNT;
if ( udiff_ref==0) {
udiff_ref=udiff_last=udiff;
}
printf("%03d.%06d %6li %6li\n",
(int)(udiff/1000000),
abs(udiff%1000000),
(long) (udiff_last-udiff),
(long) (udiff_ref-udiff)
);
udiff_last=udiff;
sleep(1);
}
return 0;
}
int main(int argc, char **argv)
{
int c, tohost = 0;
......@@ -352,9 +522,15 @@ int main(int argc, char **argv)
return wrdate_get(pps, tohost);
}
if (!strcmp(cmd, "stat")) {
/* parse the optional "tohost" argument */
return wrdate_stat(pps);
}
/* only other command is "set", with one argument */
if (strcmp(cmd, "set") || optind != argc - 1)
help(argv[0]);
return wrdate_set(pps, argv[optind]);
}
......@@ -5,6 +5,7 @@
#include <unistd.h>
#include <time.h>
#include <sys/timex.h>
#include <inttypes.h>
#include <ppsi/ppsi.h>
#include <libwr/shmem.h>
#include <libwr/hal_shmem.h>
......@@ -16,6 +17,7 @@
#include <signal.h>
#include "term.h"
#include <time_lib.h>
#define PTP_EXPORT_STRUCTURES
#include "ptpd_exports.h"
......@@ -36,6 +38,90 @@
#define SHOW_ALL (SHOW_ALL_PORTS | SHOW_SERVO | \
SHOW_TEMPERATURES | SHOW_WR_TIME)
#define MAX_INST_SERVO 2
struct inst_servo_t {
struct pp_instance * ppi; /* pointer to the ppi instance */
int valid_servo_data; /* 1 means servo data are vaild */
TimeInterval offsetFromMaster; /* currentDS.offsetFromMaster */
TimeInterval meanDelay; /* currentDS.meanDelay */
TimeInterval delayAsymmetry; /* portDS.delayAsymmetry */
RelativeDifference scaledDelayCoefficient; /* AsymmetryCorrectionPortDS.scaledDelayCoefficient */
TimeInterval egressLatency; /* timestampCorrectionPortDS.egressLatency */
TimeInterval ingressLatency; /* timestampCorrectionPortDS.ingressLatency */
TimeInterval semistaticLatency;/* timestampCorrectionPortDS.semistaticLatency */
TimeInterval constantAsymmetry;/* asymmetryCorrectionPortDS.constantAsymmetry */
struct pp_servo servo_snapshot; /* image of a the ppsi servo */
void * servo_ext_snapshot; /* image of the extension servo */
};
/* protocol extension data */
#define IS_PROTO_EXT_INFO_AVAILABLE( proto_id ) \
((proto_id < sizeof(proto_ext_info)/sizeof(struct proto_ext_info_t)) \
&& (proto_ext_info[proto_id].valid==1))
struct proto_ext_info_t {
int valid;
char *ext_name; /* Extension name */
char short_ext_name; /* Very short extension name - just one character */
int servo_ext_size; /* Size of the extension */
int ipc_cmd_tacking; /* Command to enable/disable servo tacking*/
int track_onoff; /* Tracking on/off */
time_t lastt;
int last_count;
};
static struct proto_ext_info_t proto_ext_info [] = {
[PPSI_EXT_NONE] = {
.valid=1,
.ext_name="PTP",
.short_ext_name='P',
.ipc_cmd_tacking=-1, /* Invalid */
},
#if CONFIG_HAS_EXT_WR
[PPSI_EXT_WR] = {
.valid=1,
.ext_name="White-Rabbit",
.short_ext_name='W',
.servo_ext_size=sizeof(struct wr_data),
.ipc_cmd_tacking=PTPDEXP_COMMAND_WR_TRACKING,
.track_onoff = 1,
},
#endif
#if CONFIG_HAS_EXT_L1SYNC
[PPSI_EXT_L1S] = {
.valid=1,
.ext_name="L1Sync",
.short_ext_name='L',
.servo_ext_size=sizeof(struct l1e_data),
.ipc_cmd_tacking=PTPDEXP_COMMAND_L1SYNC_TRACKING,
.track_onoff = 1,
},
#endif
#if CONFIG_HAS_EXT_CUSTOM
[PPSI_EXT_CUSTOM] = {
.valid=1,
.ext_name="Custom",
.short_ext_name='C',
.servo_ext_size=sizeof(struct l1e_data),
.ipc_cmd_tacking=PTPDEXP_COMMAND_L1SYNC_TRACKING,
.track_onoff = 1,
},
#endif
};
typedef struct {
struct pp_instance *ppi;
portDS_t *portDS;
}pp_instance_ptr_t;
static pp_instance_ptr_t instances[PP_MAX_LINKS];
static struct inst_servo_t servos[MAX_INST_SERVO];
int mode = SHOW_GUI;
static struct minipc_ch *ptp_ch;
......@@ -47,8 +133,7 @@ static struct hal_port_state hal_ports_local_copy[HAL_MAX_PORTS];
static int hal_nports_local;
static struct wrs_shm_head *ppsi_head;
static struct pp_globals *ppg;
static struct wr_servo_state *ppsi_servo;
static struct wr_servo_state ppsi_servo_local; /* local copy of servo status */
static defaultDS_t *defaultDS;
static pid_t ptp_ch_pid; /* pid of ppsi connected via minipc */
static struct hal_temp_sensors *temp_sensors;
/* local copy of temperature sensor readings */
......@@ -60,43 +145,88 @@ static uint32_t nanoseconds;
static int ignore_alive;
/* define size of pp_instance_state_to_name as a last element + 1 */
#define PP_INSTANCE_STATE_MAX (WR_PORT_CALIBRATION_8 + 1)
#define PP_INSTANCE_STATE_MAX (sizeof(pp_instance_state_to_name)/sizeof(char *))
/* define conversion array for the field state in the struct pp_instance */
static char *pp_instance_state_to_name[PP_INSTANCE_STATE_MAX] = {
static char *pp_instance_state_to_name[] = {
/* from ppsi/include/ppsi/ieee1588_types.h, enum pp_std_states */
/* PPS_END_OF_TABLE = 0 */
[PPS_END_OF_TABLE] = "EOT ",
[PPS_INITIALIZING] = "initing ",
[PPS_FAULTY] = "faulty ",
[PPS_DISABLED] = "disabled ",
[PPS_LISTENING] = "listening ",
[PPS_PRE_MASTER] = "pre master",
[PPS_MASTER] = "master ",
[PPS_PASSIVE] = "passive ",
[PPS_UNCALIBRATED] = "uncalib ",
[PPS_SLAVE] = "slave ",
/* from ppsi/proto-ext-whiterabbit/wr-constants.h */
/* WRS_PRESENT = 100 */
[WRS_PRESENT] = "WR_PRESENT",
[WRS_S_LOCK] = "WR_S_LOCK ",
[WRS_M_LOCK] = "WR_M_LOCK ",
[WRS_LOCKED] = "WR_LOCKED ",
[WRS_CALIBRATION] = "WR_CAL-ION",
[WRS_CALIBRATED] = "WR_CAL-ED ",
[WRS_RESP_CALIB_REQ] = "WR_RSP_CAL",
[WRS_WR_LINK_ON] = "WR_LINK_ON",
/* substates: used within WRS_CALIBRATED as wrPortState field */
[WR_PORT_CALIBRATION_0] = "WR_P_CAL0 ",
[WR_PORT_CALIBRATION_1] = "WR_P_CAL1 ",
[WR_PORT_CALIBRATION_2] = "WR_P_CAL2 ",
[WR_PORT_CALIBRATION_3] = "WR_P_CAL3 ",
[WR_PORT_CALIBRATION_4] = "WR_P_CAL4 ",
[WR_PORT_CALIBRATION_5] = "WR_P_CAL5 ",
[WR_PORT_CALIBRATION_6] = "WR_P_CAL6 ",
[WR_PORT_CALIBRATION_7] = "WR_P_CAL7 ",
[WR_PORT_CALIBRATION_8] = "WR_P_CAL8 ",
[PPS_INITIALIZING] = "INITING ",
[PPS_FAULTY] = "FAULTY ",
[PPS_DISABLED] = "DISABLED ",
[PPS_LISTENING] = "LISTENING ",
[PPS_PRE_MASTER] = "PRE_MASTER",
[PPS_MASTER] = "MASTER ",
[PPS_PASSIVE] = "PASSIVE ",
[PPS_UNCALIBRATED] = "UNCALIBRAT",
[PPS_SLAVE] = "SLAVE ",
};
#define EMPTY_EXTENSION_STATE_NAME " "
#if CONFIG_HAS_EXT_L1SYNC
static char * l1e_instance_extension_state[]={
[__L1SYNC_MISSING ] = "INVALID ",
[L1SYNC_DISABLED ] = "DISABLED ",
[L1SYNC_IDLE ] = "IDLE ",
[L1SYNC_LINK_ALIVE ] = "LINK ALIVE",
[L1SYNC_CONFIG_MATCH] = "CFG MATCH ",
[L1SYNC_UP ] = "UP "
};
#define L1S_INSTANCE_EXTENSION_STATE_MAX (sizeof (l1e_instance_extension_state)/sizeof(char *) )
#endif
#if CONFIG_HAS_EXT_WR
static char * wr_instance_extension_state[]={
[WRS_IDLE ]= "IDLE ",
[WRS_PRESENT] = "WR_PRESENT",
[WRS_S_LOCK] = "WR_S_LOCK ",
[WRS_M_LOCK] = "WR_M_LOCK ",
[WRS_LOCKED] = "WR_LOCKED ",
[WRS_CALIBRATION] = "WR_CAL-ION",
[WRS_CALIBRATED] = "WR_CAL-ED ",
[WRS_RESP_CALIB_REQ] = "WR_RSP_CAL",
[WRS_WR_LINK_ON] = "WR_LINK_ON",
};
#define WR_INSTANCE_EXTENSION_STATE_MAX (sizeof (wr_instance_extension_state)/sizeof(char *) )
#endif
static char *prot_link_state_name[]={
"NONE ", /* No meaning. No extension present */
"PDETECT", /* Checking if the peer instance is using the same protocol */
"IN_PROG", /* Right protocol detected. Try to establish the link with peer instance */
"LINKED ", /* Link with peer well established */
"PERROR ", /* Problem detected by the extension */
"FAILURE" /* Impossible to connect correctly to a peer instance */
};
/* prototypes */
int read_instances(void);
int64_t interval_to_picos(TimeInterval interval)
{
return (interval * 1000) >> TIME_INTERVAL_FRACBITS;
}
int64_t pp_time_to_picos(struct pp_time *ts)
{
return ts->secs * PP_NSEC_PER_SEC
+ ((ts->scaled_nsecs * 1000 + 0x8000) >> TIME_INTERVAL_FRACBITS);
}
static double alpha_to_double(int32_t alpha) {
double f ;
int neg = alpha<0;
if(neg) alpha= ~alpha+1;
f= (double)alpha/(double)(1LL<<FIX_ALPHA_FRACBITS);
return neg ? -f : f;
}
void help(char *prgname)
{
fprintf(stderr, "%s: Use: \"%s [<options>] <cmd> [<args>]\n",
......@@ -143,22 +273,111 @@ int read_hal(void){
return 0;
}
int read_servo(void){
unsigned ii;
unsigned retries = 0;
int read_instances(void) {
struct pp_instance *pp_array;
int l;
/* read data, with the sequential lock to have all data consistent */
while (1) {
ii = wrs_shm_seqbegin(ppsi_head);
memcpy(&ppsi_servo_local, ppsi_servo, sizeof(*ppsi_servo));
retries++;
if (retries > 100)
bzero(instances,sizeof(instances));
if ( !(pp_array = wrs_shm_follow(ppsi_head, ppg->pp_instances)) )
return -1;
for (l = 0; l < ppg->nlinks; l++) {
instances[l].ppi=&pp_array[l];
if ( ! (instances[l].portDS=wrs_shm_follow(ppsi_head, instances[l].ppi->portDS)) )
return -1;
if (!wrs_shm_seqretry(ppsi_head, ii))
break; /* consistent read */
usleep(1000);
}
return 0;
}
int read_servo(void){
unsigned int i, servoIdx;
/* Clear servo structure */
for (i=0; i<MAX_INST_SERVO; i++) {
if (servos[i].ppi ) {
if ( servos[i].servo_ext_snapshot )
free(servos[i].servo_ext_snapshot);
}
}
bzero(&servos, sizeof(servos));
servoIdx=0;
for (i = 0; i < ppg->nlinks; i++) {
struct pp_instance *ppi = instances[i].ppi;
/* we are only interested on instances in SLAVE state */
if (ppi->state == PPS_SLAVE ) {
struct inst_servo_t *servo=&servos[servoIdx++];
int alloc_size=IS_PROTO_EXT_INFO_AVAILABLE(ppi->protocol_extension) ?
proto_ext_info[ppi->protocol_extension].servo_ext_size :
0;
/* Allocate extension data memory if needed */
if ( alloc_size > 0 )
if ( !(servo->servo_ext_snapshot=malloc(alloc_size)) )
return -1;
while (1) {
unsigned ii = wrs_shm_seqbegin(ppsi_head);
unsigned retries = 0;
struct pp_servo *ppsi_servo;
/* Copy common data */
if ( !(ppsi_servo = wrs_shm_follow(ppsi_head, ppi->servo)) )
break;
memcpy(&servo->servo_snapshot, ppsi_servo, sizeof(struct pp_servo));
/* Copy extension servo data */
if ( servo->servo_ext_snapshot ) {
void *ppsi_servo_ext;
if ( !(ppsi_servo_ext = wrs_shm_follow(ppsi_head, ppi->ext_data)) )
break;
memcpy(servo->servo_ext_snapshot, ppsi_servo_ext,alloc_size);
}
/* Copy extra interesting data */
{
currentDS_t *currenDS;
if ( !(currenDS = wrs_shm_follow(ppsi_head, ppg->currentDS) ) )
break;
servo->offsetFromMaster=currenDS->offsetFromMaster; /* currentDS.offsetFromMaster */
servo->meanDelay=currenDS->meanDelay; /* currentDS.meanDelay */
}
{
portDS_t *portDS;
if ( !(portDS = wrs_shm_follow(ppsi_head, ppi->portDS) ) )
break;
servo->delayAsymmetry=portDS->delayAsymmetry; /* portDS.delayAsymmetry */
}
servo->scaledDelayCoefficient=ppi->asymmetryCorrectionPortDS.scaledDelayCoefficient; /* AsymmetryCorrectionPortDS.scaledDelayCoefficient */
servo->constantAsymmetry=ppi->asymmetryCorrectionPortDS.constantAsymmetry;/* asymmetryCorrectionPortDS.constantAsymmetry */
servo->egressLatency=ppi->timestampCorrectionPortDS.egressLatency; /* timestampCorrectionPortDS.egressLatency */
servo->ingressLatency=ppi->timestampCorrectionPortDS.ingressLatency; /* timestampCorrectionPortDS.ingressLatency */
servo->semistaticLatency=ppi->timestampCorrectionPortDS.semistaticLatency; /* timestampCorrectionPortDS.semistaticLatency */
if (!wrs_shm_seqretry(ppsi_head, ii)) {
servo->valid_servo_data=1;
break; /* consistent read */
}
retries++;
if (retries > 100)
break;
}
if ( servo->valid_servo_data ) {
servo->ppi=ppi;
} else {
if ( servo->servo_ext_snapshot ) {
free (servo->servo_ext_snapshot);
}
}
}
}
return 0;
}
......@@ -254,16 +473,36 @@ void init_shm(void)
}
ppg = (void *)ppsi_head + ppsi_head->data_off;
ppsi_servo = wrs_shm_follow(ppsi_head, ppg->global_ext_data);
if (!ppsi_servo) {
pr_error("Cannot follow ppsi_servo in shmem.\n");
/* Access to defaultDS data */
defaultDS = wrs_shm_follow(ppsi_head, ppg->defaultDS);
if (!defaultDS) {
pr_error("Unable to follow defaultDS pointer in PPSI's shmem\n");
exit(1);
}
if ( read_instances()==-1 )
exit(1);
ppsi_connect_minipc();
}
void show_ports(int alive)
static struct desired_state_t{
char *str_state;
int state;
} desired_states[] = {
{ "initializing", PPS_INITIALIZING},
{ "faulty", PPS_FAULTY},
{ "disabled", PPS_DISABLED},
{ "listening", PPS_LISTENING},
{ "pre-master", PPS_PRE_MASTER},
{ "master", PPS_MASTER},
{ "passive", PPS_PASSIVE},
{ "uncalibrated", PPS_UNCALIBRATED},
{ "slave", PPS_SLAVE},
{}
};
void show_ports(int hal_alive, int ppsi_alive)
{
int i, j;
time_t t;
......@@ -271,12 +510,11 @@ void show_ports(int alive)
struct tm *tm;
char datestr[32];
struct hal_port_state *port_state;
struct pp_instance *pp_array;
int vlan_i;
int nvlans;
int *p;
if (!alive) {
if (!hal_alive) {
if (mode == SHOW_GUI)
term_cprintf(C_RED, "HAL is dead!\n");
else if (mode == SHOW_ALL)
......@@ -284,8 +522,6 @@ void show_ports(int alive)
return;
}
pp_array = wrs_shm_follow(ppsi_head, ppg->pp_instances);
if (mode == SHOW_GUI) {
t = (time_t)_fpga_readl(FPGA_BASE_PPS_GEN + 8 /* UTC_LO */);
tm = localtime(&t);
......@@ -307,10 +543,10 @@ void show_ports(int alive)
term_cprintf(C_WHITE, "%3d\n", *p);
}
/* -------------------------------------------------------------------------------*/
term_cprintf(C_CYAN, "------------- HAL -----------|-------------- PPSI -----------------------------\n");
term_cprintf(C_CYAN, " Port | Link | WRconf | Freq |Inst| MAC of peer port | PTP state | Pro | VLANs\n");
term_cprintf(C_CYAN, "------|------|--------|------|----|-------------------|-----------|-----|------\n");
term_cprintf(C_CYAN, "----- HAL ---|---------------------------------- PPSI --------------------------------------------------------\n");
term_cprintf(C_CYAN, " Iface| Freq |Inst| Name | Config | MAC of peer port | PTP/EXT/PLINK states | Pro | VLANs\n");
term_cprintf(C_CYAN, "------+------+----+--------------+------------+-------------------+------------------------------+-----+------\n");
}
if (mode & (SHOW_SLAVE_PORTS|SHOW_MASTER_PORTS)) {
printf("PORTS ");
......@@ -318,9 +554,9 @@ void show_ports(int alive)
for (i = 0; i < hal_nports_local; i++) {
char if_name[10];
char if_mode[15];
int print_port = 0;
int instance_port = 0;
int color;
snprintf(if_name, 10, "wri%d", i + 1);
......@@ -329,81 +565,13 @@ void show_ports(int alive)
if (!port_state)
continue;
switch (port_state->mode) {
case HEXP_PORT_MODE_WR_MASTER:
if (mode == SHOW_GUI) {
strcpy(if_mode, "Master");
} else if (mode & SHOW_MASTER_PORTS) {
print_port = 1;
strcpy(if_mode, "M");
} else if (mode & WEB_INTERFACE) {
strcpy(if_mode, "Master");
}
break;
case HEXP_PORT_MODE_WR_SLAVE:
if (mode == SHOW_GUI) {
strcpy(if_mode, "Slave ");
} else if (mode & SHOW_SLAVE_PORTS) {
print_port = 1;
strcpy(if_mode, "S");
} else if (mode & WEB_INTERFACE) {
strcpy(if_mode, "Slave");
}
break;
case HEXP_PORT_MODE_NON_WR:
if (mode == SHOW_GUI) {
strcpy(if_mode, "Non WR");
} else if (mode & SHOW_OTHER_PORTS) {
print_port = 1;
strcpy(if_mode, "N");
} else if (mode & WEB_INTERFACE) {
strcpy(if_mode, "Non WR");
}
break;
case HEXP_PORT_MODE_NONE:
if (mode == SHOW_GUI) {
strcpy(if_mode, "None ");
} else if (mode & SHOW_OTHER_PORTS) {
print_port = 1;
strcpy(if_mode, "X");
} else if (mode & WEB_INTERFACE) {
strcpy(if_mode, "None");
}
break;
case HEXP_PORT_MODE_WR_M_AND_S:
if (mode == SHOW_GUI) {
strcpy(if_mode, "Auto ");
} else if (mode &
(SHOW_SLAVE_PORTS|SHOW_MASTER_PORTS)) {
print_port = 1;
strcpy(if_mode, "A");
} else if (mode & WEB_INTERFACE) {
strcpy(if_mode, "Auto");
}
break;
default:
if (mode == SHOW_GUI) {
strcpy(if_mode, "Unkn ");
} else if (mode & SHOW_OTHER_PORTS) {
print_port = 1;
strcpy(if_mode, "U");
} else if (mode & WEB_INTERFACE) {
strcpy(if_mode, "Unknown");
}
break;
}
if (mode == SHOW_GUI) {
term_cprintf(C_WHITE, "%-5s", if_name);
term_cprintf(C_CYAN, " | ");
/* check if link is up */
if (state_up(port_state->state))
term_cprintf(C_GREEN, "up ");
term_cprintf(C_GREEN, " %-5s", if_name);
else
term_cprintf(C_RED, "down");
term_cprintf(C_CYAN, " | ");
term_cprintf(C_WHITE, if_mode);
term_cprintf(C_CYAN, " | ");
term_cprintf(C_RED, "*%-5s", if_name);
term_cprintf(C_CYAN, "| ");
if (port_state->locked)
term_cprintf(C_GREEN, "Lock ");
else
......@@ -416,115 +584,162 @@ void show_ports(int alive)
* Actually, what is interesting is the PTP state.
* For this lookup, the port in ppsi shmem
*/
for (j = 0; j < ppg->nlinks; j++) {
if (strcmp(if_name,
pp_array[j].cfg.iface_name)) {
/* Instance not for this interface
* skip */
continue;
}
if (instance_port > 0) {
term_cprintf(C_CYAN, "\n | |"
" | |");
}
instance_port++;
/* print instance number */
term_cprintf(C_WHITE, " %2d ", j);
term_cprintf(C_CYAN, "| ");
/* Note: we may have more pp instances per
* port */
if (state_up(port_state->state)) {
unsigned char *p = pp_array[j].peer;
term_cprintf(C_WHITE, "%02x:%02x"
":%02x:%02x:%02x:%02x ",
p[0], p[1], p[2], p[3],
p[4], p[5]);
term_cprintf(C_CYAN, "| ");
if (pp_array[j].state < PP_INSTANCE_STATE_MAX) {
/* Known state */
term_cprintf(C_GREEN, "%s",
pp_instance_state_to_name[pp_array[j].state]);
if ( ppsi_alive ) {
for (j = 0; j < ppg->nlinks; j++) {
char str_config[15];
pp_instance_ptr_t *ppi_pt=&instances[j];
struct pp_instance *ppi=ppi_pt->ppi;
int proto_extension=ppi->protocol_extension;
struct proto_ext_info_t *pe_info= IS_PROTO_EXT_INFO_AVAILABLE(proto_extension) ? &proto_ext_info[proto_extension] : &proto_ext_info[0] ;
if (strcmp(if_name,
ppi->cfg.iface_name)) {
/* Instance not for this interface
* skip */
continue;
}
if (instance_port > 0) {
term_cprintf(C_CYAN, "\n | |");
}
instance_port++;
// Evaluate the instance configuration
strcpy(str_config,"unknown");
if ( defaultDS->slaveOnly) {
strncpy(str_config,"slaveOnly",sizeof(str_config)-1);
} else {
/* Unknown ptp state */
term_cprintf(C_GREEN,
"unkn(%3i)",
pp_array[j].state);
if ( defaultDS->externalPortConfigurationEnabled ) {
int s=0;
for ( s=0; s<sizeof(desired_states)/sizeof(struct desired_state_t); s++ ) {
if (desired_states[s].state == ppi->externalPortConfigurationPortDS.desiredState) {
strncpy(str_config,desired_states[s].str_state,sizeof(str_config)-1);
break;
}
}
} else {
if ( ppi_pt->portDS->masterOnly ) {
strncpy(str_config,"masterOnly",sizeof(str_config)-1);
} else {
strncpy(str_config,"auto",sizeof(str_config)-1);
}
}
}
} else {
term_cprintf(C_WHITE, " "
" ");
str_config[sizeof(str_config)-1]=0; // Force the string to be well terminated
/* print instance number */
term_cprintf(C_WHITE, " %2d ", j);
term_cprintf(C_CYAN, "|");
term_cprintf(C_WHITE, " ");
}
term_cprintf(C_CYAN, "| ");
if (pp_array[j].proto == PPSI_PROTO_RAW) {
term_cprintf(C_WHITE, "R");
} else if (pp_array[j].proto
== PPSI_PROTO_UDP) {
term_cprintf(C_WHITE, "U");
} else if (pp_array[j].proto
== PPSI_PROTO_VLAN) {
term_cprintf(C_WHITE, "V");
} else {
term_cprintf(C_WHITE, "?");
}
if (pp_array[j].cfg.ext == PPSI_EXT_WR) {
term_cprintf(C_WHITE, "-W");
} else if (pp_array[j].cfg.ext
== PPSI_EXT_NONE) {
term_cprintf(C_WHITE, " ");
} else {
term_cprintf(C_WHITE, "-?");
}
/* print instance name */
term_cprintf(C_WHITE, "%-14s",ppi->cfg.port_name);
term_cprintf(C_CYAN, "|");
term_cprintf(C_WHITE, "%-12s",str_config);
term_cprintf(C_CYAN, "| ");
nvlans = pp_array[j].nvlans;
term_cprintf(C_CYAN, " | ");
for (vlan_i = 0; vlan_i < nvlans; vlan_i++) {
term_cprintf(C_WHITE, "%d",
pp_array[j].vlans[vlan_i]);
if (vlan_i < nvlans - 1)
term_cprintf(C_WHITE, ",");
/* Note: we may have more pp instances per port */
/* if (state_up(port_state->state)) */ {
unsigned char *p = ppi->peer;
char * extension_state_name=EMPTY_EXTENSION_STATE_NAME;
term_cprintf(C_WHITE, "%02x:%02x"
":%02x:%02x:%02x:%02x ",
p[0], p[1], p[2], p[3],
p[4], p[5]);
term_cprintf(C_CYAN, "| ");
if (ppi->state < PP_INSTANCE_STATE_MAX) {
/* Known state */
term_cprintf(C_GREEN, "%s/",
pp_instance_state_to_name[ppi->state]);
} else {
/* Unknown ptp state */
term_cprintf(C_GREEN,
"unkn(%3i)",
ppi->state);
}
/* print extension state */
switch (ppi->protocol_extension ) {
#if CONFIG_HAS_EXT_WR
case PPSI_EXT_WR :
{
portDS_t *portDS;
extension_state_name="????????? ";
if ( (portDS = wrs_shm_follow(ppsi_head, ppi->portDS) ) ) {
struct wr_dsport *extPortDS;
if ( (extPortDS = wrs_shm_follow(ppsi_head, portDS->ext_dsport) ) ) {
if ( extPortDS->state <= WR_INSTANCE_EXTENSION_STATE_MAX )
extension_state_name=wr_instance_extension_state[extPortDS->state];
}
}
break;
}
#endif
#if CONFIG_HAS_EXT_L1SYNC
case PPSI_EXT_L1S :
{
portDS_t *portDS;
extension_state_name="????????? ";
if ( (portDS = wrs_shm_follow(ppsi_head, ppi->portDS) ) ) {
l1e_ext_portDS_t *extPortDS;
if ( (extPortDS = wrs_shm_follow(ppsi_head, portDS->ext_dsport) ) ) {
if ( extPortDS->basic.L1SyncState <= L1S_INSTANCE_EXTENSION_STATE_MAX )
extension_state_name=l1e_instance_extension_state[extPortDS->basic.L1SyncState];
}
}
break;
}
#endif
}
term_cprintf(C_GREEN, "%s/%s",extension_state_name,prot_link_state_name[ppi->link_state]);
} // else {
// term_cprintf(C_WHITE, " ");
// term_cprintf(C_CYAN, "|");
// term_cprintf(C_WHITE, " ");
// }
term_cprintf(C_CYAN, "| ");
if (ppi->proto == PPSI_PROTO_RAW) {
term_cprintf(C_WHITE, "R");
} else if (ppi->proto
== PPSI_PROTO_UDP) {
term_cprintf(C_WHITE, "U");
} else if (ppi->proto
== PPSI_PROTO_VLAN) {
term_cprintf(C_WHITE, "V");
} else {
term_cprintf(C_WHITE, "?");
}
color=ppi->protocol_extension!=PPSI_EXT_NONE && !ppi->ext_enabled ? C_RED : C_WHITE;
term_cprintf(color, "-%c",pe_info->short_ext_name);
nvlans = ppi->nvlans;
term_cprintf(C_CYAN, " | ");
for (vlan_i = 0; vlan_i < nvlans; vlan_i++) {
term_cprintf(C_WHITE, "%d",
ppi->vlans[vlan_i]);
if (vlan_i < nvlans - 1)
term_cprintf(C_WHITE, ",");
}
}
}
if (!instance_port) {
if (!instance_port || !ppsi_alive) {
term_cprintf(C_WHITE, " -- ");
term_cprintf(C_CYAN, "| | "
" | |");
term_cprintf(C_CYAN, "| | | | | |");
}
term_cprintf(C_WHITE, "\n");
} else if (mode & WEB_INTERFACE) {
printf("%-5s ", if_name);
printf("%s ", state_up(port_state->state)
? "up" : "down");
printf("%s ", if_mode);
// JCB mode is per instance // printf("%s ", if_mode);
printf("%s ", port_state->locked
? "Locked" : "NoLock");
printf("%s ", port_state->calib.rx_calibrated
&& port_state->calib.tx_calibrated
? "Calibrated" : "Uncalibrated");
for (j = 0; j < ppg->nlinks; j++) {
if (strcmp(if_name,
pp_array[j].cfg.iface_name)
) {
/* Instance not for this interface
* skip */
continue;
}
if (state_up(port_state->state)) {
unsigned char *p = pp_array[j].peer;
printf("%02x:%02x:%02x:%02x:%02x:%02x"
" ", p[0], p[1], p[2], p[3],
p[4], p[5]);
}
}
printf("\n");
} else if (print_port) {
printf("port:%s ", if_name);
printf("lnk:%d ", state_up(port_state->state));
printf("mode:%s ", if_mode);
// JCB mode is per instance // printf("mode:%s ", if_mode);
printf("lock:%d ", port_state->locked);
print_port = 0;
}
......@@ -535,21 +750,26 @@ void show_ports(int alive)
}
}
void show_servo(int alive)
void show_servo(struct inst_servo_t *servo, int alive)
{
int64_t total_asymmetry;
int64_t crtt;
static time_t lastt;
static int last_count;
total_asymmetry = ppsi_servo_local.picos_mu -
2LL * ppsi_servo_local.delta_ms;
crtt = ppsi_servo_local.picos_mu - ppsi_servo_local.delta_tx_m -
ppsi_servo_local.delta_rx_m - ppsi_servo_local.delta_tx_s -
ppsi_servo_local.delta_rx_s;
wrh_servo_t * wr_servo;
wr_servo_ext_t * wr_servo_ext;
char buf[128];
wrh_servo_t * l1e_servo;
int proto_extension=servo->ppi->ext_enabled ? servo->ppi->protocol_extension : PPSI_EXT_NONE;
struct proto_ext_info_t *pe_info= IS_PROTO_EXT_INFO_AVAILABLE(proto_extension) ? &proto_ext_info[proto_extension] : &proto_ext_info[0] ;
wr_servo= (servo->ppi->protocol_extension==PPSI_EXT_WR && servo->ppi->ext_enabled) ?
( wrh_servo_t* ) servo->servo_ext_snapshot : NULL;
if ( wr_servo ) {
wr_servo_ext= &((struct wr_data *)wr_servo)->servo_ext;
}
l1e_servo= (servo->ppi->protocol_extension==PPSI_EXT_L1S && servo->ppi->ext_enabled) ?
( wrh_servo_t * ) servo->servo_ext_snapshot : NULL;
if (mode == SHOW_GUI) {
/* -------------------------------------------------------------------------------*/
term_cprintf(C_CYAN, "\n--------------------------- Synchronization status ----------------------------\n");
}
......@@ -560,54 +780,57 @@ void show_servo(int alive)
}
if (mode == SHOW_GUI) {
if (!(ppsi_servo_local.flags & WR_FLAG_VALID)) {
if (!(servo->servo_snapshot.flags & PP_SERVO_FLAG_VALID)) {
term_cprintf(C_RED,
"Master mode or sync info not valid\n");
return;
}
term_cprintf(C_BLUE, "Servo state: ");
if (lastt && time(NULL) - lastt > 5) {
if (pe_info->lastt && time(NULL) - pe_info->lastt > 5) {
term_cprintf(C_RED, "--- not updating ---\n");
} else {
term_cprintf(C_WHITE, "%s: %s%s\n",
ppsi_servo_local.if_name,
ppsi_servo_local.servo_state_name,
ppsi_servo_local.flags & WR_FLAG_WAIT_HW ?
term_cprintf(C_WHITE, "%s:%s: %s%s\n",
servo->ppi->cfg.iface_name,
pe_info->ext_name,
servo->servo_snapshot.servo_state_name,
servo->servo_snapshot.flags & PP_SERVO_FLAG_WAIT_HW ?
" (wait for hw)" : "");
}
/* "tracking disabled" is just a testing tool */
if (!ppsi_servo_local.tracking_enabled)
if (wr_servo && !wr_servo->tracking_enabled)
term_cprintf(C_RED, "Tracking forcibly disabled\n");
/* -------------------------------------------------------------------------------*/
term_cprintf(C_CYAN, "\n------------------------------ Timing parameters ------------------------------\n");
term_cprintf(C_CYAN, "\n +- Timing parameters ---------------------------------------------------------\n");
term_cprintf(C_BLUE, "Round-trip time (mu): ");
term_cprintf(C_WHITE, "%15.3f nsec\n",
ppsi_servo_local.picos_mu/1000.0);
term_cprintf(C_CYAN," | ");term_cprintf(C_BLUE, "meanDelay : ");
term_cprintf(C_WHITE, "%16s nsec\n", timeIntervalToString(servo->meanDelay,buf) );
term_cprintf(C_BLUE, "Estimated link length: ");
term_cprintf(C_CYAN," | ");term_cprintf(C_BLUE, "delayMS : ");
term_cprintf(C_WHITE, "%16s sec\n",timeToString(&servo->servo_snapshot.delayMS,buf));
//term_cprintf(C_BLUE, "Estimated link length: ");
/* (RTT - deltas) / 2 * c / ri
c = 299792458 - speed of light in m/s
ri = 1.4682 - refractive index for fiber g.652. However,
experimental measurements using long (~5km) and
short (few m) fibers gave a value 1.4827
*/
term_cprintf(C_WHITE, "%10.2f meters\n",
crtt / 2 / 1e6 * 299.792458 / 1.4827);
term_cprintf(C_BLUE, "Master-slave delay: ");
term_cprintf(C_WHITE, "%15.3f nsec\n",
ppsi_servo_local.delta_ms/1000.0);
term_cprintf(C_BLUE, "Total link asymmetry: ");
term_cprintf(C_WHITE, "%15.3f nsec, ",
total_asymmetry / 1000.0);
/* print alpha as fixed point number */
term_cprintf(C_BLUE, "alpha: ");
term_cprintf(C_WHITE, "%d\n",
ppsi_servo_local.fiber_fix_alpha);
//term_cprintf(C_WHITE, "%10.2f meters\n",
// crtt / 2 / 1e6 * 299.792458 / 1.4827);
term_cprintf(C_CYAN," | ");term_cprintf(C_BLUE, "delayAsymmetry : ");
term_cprintf(C_WHITE, "%16s nsec\n", timeIntervalToString(servo->delayAsymmetry,buf));
term_cprintf(C_CYAN," | ");term_cprintf(C_BLUE, "scaledDelayCoef : ");
term_cprintf(C_WHITE, "%s", relativeDifferenceToString(servo->scaledDelayCoefficient,buf));
term_cprintf(C_WHITE, "\n");
term_cprintf(C_CYAN," | ");term_cprintf(C_BLUE, "ingressLatency : ");
term_cprintf(C_WHITE, "%16s nsec\n", timeIntervalToString(servo->ingressLatency,buf));
term_cprintf(C_CYAN," | ");term_cprintf(C_BLUE, "egressLatency : ");
term_cprintf(C_WHITE, "%16s nsec\n", timeIntervalToString(servo->egressLatency,buf));
term_cprintf(C_CYAN," | ");term_cprintf(C_BLUE, "semistaticLatency: ");
term_cprintf(C_WHITE, "%16s nsec\n", timeIntervalToString(servo->semistaticLatency,buf));
/*if (0) {
term_cprintf(C_BLUE, "Fiber asymmetry: ");
......@@ -615,40 +838,44 @@ void show_servo(int alive)
ss.fiber_asymmetry/1000.0);
}*/
term_cprintf(C_BLUE, "Clock offset: ");
term_cprintf(C_WHITE, "%15.3f nsec\n",
ppsi_servo_local.offset/1000.0);
term_cprintf(C_CYAN," | ");term_cprintf(C_BLUE, "offsetFromMaster : ");
term_cprintf(C_WHITE, "%16s nsec\n", timeIntervalToString (servo->offsetFromMaster,buf));
if ( wr_servo ) {
term_cprintf(C_CYAN," | ");term_cprintf(C_BLUE, "Phase setpoint : ");
term_cprintf(C_WHITE, "%15.3f nsec\n",wr_servo->cur_setpoint_ps/1000.0);
term_cprintf(C_CYAN," | ");term_cprintf(C_BLUE, "Skew : ");
term_cprintf(C_WHITE, "%15.3f nsec\n",wr_servo->skew_ps/1000.0);
}
term_cprintf(C_BLUE, "Phase setpoint: ");
term_cprintf(C_WHITE, "%15.3f nsec\n",
ppsi_servo_local.cur_setpoint/1000.0);
if ( l1e_servo ) {
term_cprintf(C_CYAN," | ");term_cprintf(C_BLUE, "Phase setpoint : ");
term_cprintf(C_WHITE, "%16.3f nsec\n",l1e_servo->cur_setpoint_ps/1000.0);
term_cprintf(C_BLUE, "Skew: ");
term_cprintf(C_WHITE, "%15.3f nsec\n",
ppsi_servo_local.skew/1000.0);
term_cprintf(C_CYAN," | ");term_cprintf(C_BLUE, "Skew : ");
term_cprintf(C_WHITE, "%16.3f nsec\n",l1e_servo->skew_ps/1000.0);
}
term_cprintf(C_CYAN," | ");term_cprintf(C_BLUE, "Update counter : ");
term_cprintf(C_WHITE, "%16u times\n", servo->servo_snapshot.update_count);
if (servo->servo_snapshot.update_count != pe_info->last_count) {
pe_info->lastt = time(NULL);
pe_info->last_count = servo->servo_snapshot.update_count;
}
term_cprintf(C_BLUE, "Servo update counter: ");
term_cprintf(C_WHITE, "%15u times\n",
ppsi_servo_local.update_count);
if (ppsi_servo_local.update_count != last_count) {
lastt = time(NULL);
last_count = ppsi_servo_local.update_count;
if ( wr_servo ) {
term_cprintf(C_CYAN," | ");term_cprintf(C_BLUE, "Master PHY delays ");
term_cprintf(C_BLUE, "TX: ");
term_cprintf(C_WHITE, "%s sec, ", timeToString(&wr_servo_ext->delta_txm,buf));
term_cprintf(C_BLUE, "RX: ");
term_cprintf(C_WHITE, "%s sec\n", timeToString(&wr_servo_ext->delta_rxm,buf));
term_cprintf(C_CYAN," | ");term_cprintf(C_BLUE, "Slave PHY delays ");
term_cprintf(C_BLUE, "TX: ");
term_cprintf(C_WHITE, "%s sec, ", timeToString(&wr_servo_ext->delta_txs,buf));
term_cprintf(C_BLUE, "RX: ");
term_cprintf(C_WHITE, "%s sec\n",timeToString(&wr_servo_ext->delta_rxs,buf));
}
term_cprintf(C_BLUE, "Master PHY delays: ");
term_cprintf(C_BLUE, "TX: ");
term_cprintf(C_WHITE, "%11.3f nsec, ",
ppsi_servo_local.delta_tx_m/1000.0);
term_cprintf(C_BLUE, "RX: ");
term_cprintf(C_WHITE, "%11.3f nsec\n",
ppsi_servo_local.delta_rx_m/1000.0);
term_cprintf(C_BLUE, "Slave PHY delays: ");
term_cprintf(C_BLUE, "TX: ");
term_cprintf(C_WHITE, "%11.3f nsec, ",
ppsi_servo_local.delta_tx_s/1000.0);
term_cprintf(C_BLUE, "RX: ");
term_cprintf(C_WHITE, "%11.3f nsec\n",
ppsi_servo_local.delta_rx_s/1000.0);
} else {
/* TJP: commented out fields are present on the SPEC,
* does the switch have similar fields?
......@@ -657,44 +884,67 @@ void show_servo(int alive)
/* printf("lnk:");*/
/* printf("rx:");*/
/* printf("tx:");*/
printf("lock:%i ", ppsi_servo_local.tracking_enabled);
printf("sv:%d ", ppsi_servo_local.flags & WR_FLAG_VALID ? 1 : 0);
printf("ss:'%s' ", ppsi_servo_local.servo_state_name);
printf("sv:%d ", servo->servo_snapshot.flags & PP_SERVO_FLAG_VALID ? 1 : 0);
printf("ss:'%s' ", servo->servo_snapshot.servo_state_name);
/* printf("aux:");*/
printf("mu:%llu ", ppsi_servo_local.picos_mu);
printf("dms:%llu ", ppsi_servo_local.delta_ms);
printf("dtxm:%d drxm:%d ", ppsi_servo_local.delta_tx_m,
ppsi_servo_local.delta_rx_m);
printf("dtxs:%d drxs:%d ", ppsi_servo_local.delta_tx_s,
ppsi_servo_local.delta_rx_s);
printf("asym:%lld ", total_asymmetry);
printf("md:%s ", timeIntervalToString(servo->meanDelay,buf));
printf("dms:%s ", timeToString(&servo->servo_snapshot.delayMS,buf));
if ( wr_servo ) {
int64_t crtt= wr_servo->delayMM_ps - pp_time_to_picos(&wr_servo_ext->delta_txm) -
pp_time_to_picos(&wr_servo_ext->delta_rxm) - pp_time_to_picos(&wr_servo_ext->delta_txs) -
pp_time_to_picos(&wr_servo_ext->delta_rxs);
printf("lock:%i ", wr_servo->tracking_enabled);
printf("dtxm:%s ", timeToString(&wr_servo_ext->delta_txm,buf));
printf("drxm:%s ", timeToString(&wr_servo_ext->delta_rxm,buf));
printf("dtxs:%s ", timeToString(&wr_servo_ext->delta_txs,buf));
printf("drxs:%s ", timeToString(&wr_servo_ext->delta_rxs,buf));
/* (RTT - deltas) / 2 * c / ri
c = 299792458 - speed of light in m/s
ri = 1.4682 - refractive index for fiber g.652. However,
experimental measurements using long (~5km) and
short (few m) fibers gave a value 1.4827
*/
printf("ll:%d ",
(int) (crtt / 2 / 1e6 * 299.792458 / 1.4827 * 100));
printf("crtt:%llu ", crtt);
printf("cko:%lld ", ppsi_servo_local.offset);
printf("setp:%d ", ppsi_servo_local.cur_setpoint);
//printf("ll:%d ",
// (int) (crtt / 2 / 1e6 * 299.792458 / 1.4827 * 100));
printf("crtt:%llu ", crtt);
printf("setp:%d ", wr_servo->cur_setpoint_ps);
}
if ( l1e_servo ) {
printf("lock:%i ", l1e_servo->tracking_enabled);
printf("setp:%d ", l1e_servo->cur_setpoint_ps);
}
printf("asym:%s ", timeIntervalToString(servo->delayAsymmetry,buf));
printf("cko:%s ", timeIntervalToString(servo->offsetFromMaster,buf));
/* printf("hd:");*/
/* printf("md:");*/
/* printf("ad:");*/
printf("ucnt:%u ", ppsi_servo_local.update_count);
printf("ucnt:%u ", servo->servo_snapshot.update_count);
/* SPEC shows temperature, but that can be selected separately
* in this program
*/
if (mode == WEB_INTERFACE)
printf("\n");
}
}
void show_servos(int alive) {
int i;
for (i=0; i<MAX_INST_SERVO; i++)
if (servos[i].ppi )
show_servo(&servos[i], alive);
}
void show_temperatures(void)
{
if ((mode == SHOW_GUI)) {
term_cprintf(C_CYAN, "\n-------------------------------- Temperatures ---------------------------------\n");
if ((mode == SHOW_GUI) || (mode & WEB_INTERFACE)) {
if (mode == SHOW_GUI) {
/* -------------------------------------------------------------------------------*/
term_cprintf(C_CYAN, "\n-------------------------------- Temperatures ---------------------------------\n");
} else {
term_cprintf(C_CYAN, "\nTemperatures:\n");
}
term_cprintf(C_BLUE, "FPGA: ");
term_cprintf(C_WHITE, "%2.2f ",
......@@ -714,16 +964,12 @@ void show_temperatures(void)
printf("pll:%2.2f ", temp_sensors_local.pll/256.0);
printf("psl:%2.2f ", temp_sensors_local.psl/256.0);
printf("psr:%2.2f", temp_sensors_local.psr/256.0);
if (mode == WEB_INTERFACE)
printf("\n");
}
}
void show_time(void)
{
printf("TIME sec:%lld nsec:%d ", seconds, nanoseconds);
if (mode == WEB_INTERFACE)
printf("\n");
}
void show_all(void)
......@@ -743,7 +989,7 @@ void show_all(void)
ppsi_alive = (ppsi_head->pid && (kill(ppsi_head->pid, 0) == 0))
+ ignore_alive;
if (mode & (SHOW_WR_TIME | WEB_INTERFACE)) {
if (mode & SHOW_WR_TIME) {
if (ppsi_alive)
show_time();
else if (mode == SHOW_ALL)
......@@ -751,11 +997,11 @@ void show_all(void)
}
if ((mode & (SHOW_ALL_PORTS|WEB_INTERFACE)) || mode == SHOW_GUI) {
show_ports(hal_alive);
show_ports(hal_alive,ppsi_alive);
}
if (mode & (SHOW_SERVO | WEB_INTERFACE) || mode == SHOW_GUI) {
show_servo(ppsi_alive);
if (mode & SHOW_SERVO || mode == SHOW_GUI) {
show_servos(ppsi_alive);
}
if (mode & (SHOW_TEMPERATURES | WEB_INTERFACE) || mode == SHOW_GUI) {
......@@ -770,11 +1016,30 @@ void show_all(void)
fflush(stdout);
}
static void enable_disable_tracking(int proto_extension) {
if ( IS_PROTO_EXT_INFO_AVAILABLE(proto_extension) ) {
struct proto_ext_info_t *pe_info= &proto_ext_info[proto_extension];
if ( pe_info->ipc_cmd_tacking!=-1 ) {
int rval;
pe_info->track_onoff = 1-pe_info->track_onoff;
if (ptp_ch_pid != ppsi_head->pid) {
/* ppsi was restarted since minipc
* connection, reconnect now */
ppsi_connect_minipc();
}
minipc_call(ptp_ch, 200, &__rpcdef_cmd,
&rval, pe_info->ipc_cmd_tacking,pe_info->track_onoff);
}
}
}
int main(int argc, char *argv[])
{
int opt;
int usecolor = 1;
int track_onoff = 1;
/* try a pps_gen based approach */
uint64_t last_seconds = 0;
......@@ -850,20 +1115,15 @@ int main(int argc, char *argv[])
if (term_poll(10)) {
int c = term_get();
if (c == 'q')
switch (c) {
case 'q':
goto quit;
case 'w' :
enable_disable_tracking (PPSI_EXT_WR);
break;
case 'l' :
enable_disable_tracking (PPSI_EXT_L1S);
break;
if (c == 't') {
int rval;
track_onoff = 1-track_onoff;
if (ptp_ch_pid != ppsi_head->pid) {
/* ppsi was restarted since minipc
* connection, reconnect now */
ppsi_connect_minipc();
}
minipc_call(ptp_ch, 200, &__rpcdef_cmd,
&rval, PTPDEXP_COMMAND_TRACKING,
track_onoff);
}
}
......@@ -881,6 +1141,7 @@ int main(int argc, char *argv[])
exit(1);
}
quit:;
term_restore();
setlinebuf(stdout);
printf("\n");
......
......@@ -452,6 +452,27 @@ void pps_adjustment_test(int ep, int argc, char *argv[])
}
}
char * getRtsTimingMode(int mode) {
static struct {
char *name;
int mode;
} *m, modes[] = {
{"TIME_GM", RTS_MODE_GM_EXTERNAL},
{"TIME_FM", RTS_MODE_GM_FREERUNNING},
{"TIME_BC", RTS_MODE_BC},
{"TIME_DS", RTS_MODE_DISABLED},
{"???????",-1}
};
m=modes;
do {
if ( m->mode==mode )
break;
m++;
} while (m->mode!=-1);
return m->name;
}
void rt_command(int ep, int argc, char *argv[])
{
/* ep is 0..17 */
......@@ -473,7 +494,7 @@ void rt_command(int ep, int argc, char *argv[])
{
printf("RTS State Dump [%d physical ports]:\n",
hal_nports_local);
printf("CurrentRef: %d Mode: %d Flags: %x\n", pstate.current_ref, pstate.mode, pstate.flags);
printf("CurrentRef: %d Mode: %s (%d) Flags: %x\n", pstate.current_ref, getRtsTimingMode(pstate.mode), pstate.mode, pstate.flags);
for (i = 0; i < hal_nports_local; i++)
printf("wri%-2d: setpoint: %-8dps current: %-8dps "
"loopback: %-8dps flags: %x\n", i + 1,
......@@ -483,28 +504,27 @@ void rt_command(int ep, int argc, char *argv[])
pstate.channels[i].flags);
} else if (!strcmp(argv[3], "lock"))
{
int i;
printf("locking to: port %d wri%d\n", ep + 1, ep + 1);
for(i=0;i<100;i++)
{
rts_get_state(&pstate);
printf("setmode rv %d\n", rts_set_mode(RTS_MODE_BC));
printf("lock rv %d\n", rts_lock_channel(ep, 0));
}
} else if (!strcmp(argv[3], "master"))
rts_get_state(&pstate);
printf("setmode rv %d\n", rts_set_mode(RTS_MODE_BC));
printf("lock rv %d\n", rts_lock_channel(ep, 0));
} else if (!strcmp(argv[3], "fr"))
{
int i;
printf("Enabling free-running master mode\n");
for(i=0;i<10;i++)
{
printf("rv: %d\n", rts_set_mode(RTS_MODE_GM_FREERUNNING));
}
// rts_lock_channel(ep);
printf("Enabling free-running master timing mode\n");
printf("rv: %d\n", rts_set_mode(RTS_MODE_GM_FREERUNNING));
}
else if (!strcmp(argv[3], "gm"))
{
printf("Enabling grand master timing mode\n");
printf("rv: %d\n", rts_set_mode(RTS_MODE_GM_EXTERNAL));
}
else if (!strcmp(argv[3], "track"))
else if (!strcmp(argv[3], "ds"))
{
printf("Disable timing mode\n");
printf("rv: %d\n", rts_set_mode(RTS_MODE_DISABLED));
}else if (!strcmp(argv[3], "track"))
{
printf("Enabling ptracker @ port %d (wri%d)\n", ep + 1, ep + 1);
rts_enable_ptracker(ep, 1);
}
}
......@@ -559,7 +579,7 @@ struct {
{
"rt",
"",
"RT subsystem command [show,lock,master,gm]",
"RT subsystem command [show,lock,[gm,fr,ds],track]",
rt_command},
{NULL}
......
......@@ -8,6 +8,7 @@
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <inttypes.h>
#include <sys/mman.h>
#include <libwr/shmem.h>
#include <libwr/hal_shmem.h>
......@@ -16,6 +17,13 @@
#include <libwr/util.h>
#include <ppsi/ppsi.h>
#include <ppsi-wrs.h>
#include "time_lib.h"
/* be safe, in case some other header had them slightly differently */
#undef container_of
#undef offsetof
#undef ARRAY_SIZE
#include "wrs_dump_shmem.h"
#define FPGA_SPLL_STAT 0x10006800
......@@ -72,17 +80,44 @@ static int dump_all_rtu_entries = 0; /* rtu exports 4096 vlans and 2048 htab
entries */
void dump_one_field(void *addr, struct dump_info *info)
#define REL_DIFF_FRACBITS 62
#define REL_DIFF_FRACMASK 0x3fffffffffffffff
void decode_relative_difference(RelativeDifference rd, int32_t *nsecs, uint64_t *sub_yocto) {
int64_t fraction;
uint64_t bitWeight=500000000000000000;
uint64_t mask;
*sub_yocto=0;
*nsecs = (int32_t)(rd >> REL_DIFF_FRACBITS);
fraction=(int64_t)rd & REL_DIFF_FRACMASK;
for (mask=(uint64_t) 1<< (REL_DIFF_FRACBITS-1);mask!=0; mask>>=1 ) {
if ( mask & fraction )
*sub_yocto+=bitWeight;
bitWeight/=2;
}
}
void dump_one_field(void *addr, struct dump_info *info, char *info_prefix)
{
void *p = addr + info->offset;
char buf[128];
struct pp_time *t = p;
RelativeDifference *rd=p;
Timestamp *ts=p;
TimeInterval *ti=p;
struct PortIdentity *pi = p;
struct ClockQuality *cq = p;
char format[16];
long nano, pico;
int i;
char pname[128];
if (info_prefix!=NULL )
sprintf(pname,"%s.%s",info_prefix,info->name);
else
strcpy(pname,info->name);
printf(" %-30s ", info->name); /* name includes trailing ':' */
printf("%-40s ", pname); /* name includes trailing ':' */
switch(info->type) {
case dump_type_char:
sprintf(format,"\"%%.%is\"\n", info->size);
......@@ -108,6 +143,7 @@ void dump_one_field(void *addr, struct dump_info *info)
case dump_type_uint64_t:
printf("%lld\n", *(unsigned long long *)p);
break;
case dump_type_long_long:
case dump_type_Integer64:
printf("%lld\n", *(long long *)p);
break;
......@@ -129,6 +165,9 @@ void dump_one_field(void *addr, struct dump_info *info)
case dump_type_Boolean:
printf("%i\n", *(unsigned char *)p);
break;
case dump_type_UInteger4:
printf("%i\n", *(unsigned char *)p & 0xF);
break;
case dump_type_UInteger16:
case dump_type_uint16_t:
case dump_type_unsigned_short:
......@@ -146,14 +185,22 @@ void dump_one_field(void *addr, struct dump_info *info)
case dump_type_Integer16:
printf("%i\n", *(short *)p);
break;
case dump_type_time:
nano = t->scaled_nsecs >> 16;
pico = t->scaled_nsecs & 0xffff;
pico = (pico * 1000) >> 16;
printf("correct %i: %10lli.%09li.%03li\n",
!is_incorrect(t), t->secs, nano,pico);
printf("%s\n",timeToString(t,buf));
break;
case dump_type_Timestamp:
printf("%s\n",timestampToString(ts,buf));
break;
case dump_type_TimeInterval:
printf("%s\n",timeIntervalToString(*ti,buf));
break;
case dump_type_RelativeDifference:
printf("%s\n",relativeDifferenceToString(*rd,buf));
break;
case dump_type_ip_address:
for (i = 0; i < 4; i++)
printf("%02x%c", ((unsigned char *)p)[i],
......@@ -174,7 +221,7 @@ void dump_one_field(void *addr, struct dump_info *info)
break;
case dump_type_ClockQuality:
printf("class %i, accuracy %02x (%i), logvariance %i\n",
printf("class=%i, accuracy=0x%02x (%i), logvariance=%i\n",
cq->clockClass, cq->clockAccuracy, cq->clockAccuracy,
cq->offsetScaledLogVariance);
break;
......@@ -305,7 +352,8 @@ void dump_one_field(void *addr, struct dump_info *info)
break;
}
}
void dump_many_fields(void *addr, struct dump_info *info, int ninfo)
void dump_many_fields(void *addr, struct dump_info *info, int ninfo, char *prefix)
{
int i;
......@@ -313,8 +361,9 @@ void dump_many_fields(void *addr, struct dump_info *info, int ninfo)
fprintf(stderr, "dump: pointer not valid\n");
return;
}
for (i = 0; i < ninfo; i++)
dump_one_field(addr, info + i);
for (i = 0; i < ninfo; i++) {
dump_one_field(addr, info + i,prefix);
}
}
/* the macro below relies on an externally-defined structure type */
......@@ -352,7 +401,6 @@ struct dump_info hal_port_info [] = {
DUMP_FIELD(int, hw_index),
DUMP_FIELD(int, fd),
DUMP_FIELD(int, hw_addr_auto),
DUMP_FIELD(port_mode, mode),
DUMP_FIELD(int, state),
DUMP_FIELD(int, fiber_index),
DUMP_FIELD(int, locked),
......@@ -411,7 +459,7 @@ int dump_hal_mem(struct wrs_shm_head *head)
h = (void *)head + head->data_off;
/* dump hal's shmem */
dump_many_fields(h, hal_shmem_info, ARRAY_SIZE(hal_shmem_info));
dump_many_fields(h, hal_shmem_info, ARRAY_SIZE(hal_shmem_info),"HAL");
n = h->nports;
p = wrs_shm_follow(head, h->ports);
......@@ -422,8 +470,10 @@ int dump_hal_mem(struct wrs_shm_head *head)
}
for (i = 0; i < n; i++, p++) {
printf("dump port %i\n", i + 1);
dump_many_fields(p, hal_port_info, ARRAY_SIZE(hal_port_info));
char prefix[64];
sprintf(prefix,"HAL.port.%d",i+1);
dump_many_fields(p, hal_port_info, ARRAY_SIZE(hal_port_info),prefix);
}
return 0;
}
......@@ -474,6 +524,7 @@ int dump_rtu_mem(struct wrs_shm_head *head)
struct rtu_filtering_entry *rtu_filters_cur;
struct rtu_vlan_table_entry *rtu_vlans;
int i, j;
char prefix[64];
if (head->version != RTU_SHMEM_VERSION) {
fprintf(stderr, "dump rtu: unknown version %i (known is %i)\n",
......@@ -496,9 +547,9 @@ int dump_rtu_mem(struct wrs_shm_head *head)
&& (!rtu_filters_cur->valid))
/* don't display empty entries */
continue;
printf("dump htab[%d][%d]\n", i, j);
sprintf(prefix,"rtu.htab.%d.%d",i,j);
dump_many_fields(rtu_filters_cur, htab_info,
ARRAY_SIZE(htab_info));
ARRAY_SIZE(htab_info),prefix);
}
}
......@@ -507,8 +558,8 @@ int dump_rtu_mem(struct wrs_shm_head *head)
&& rtu_vlans->port_mask == 0x0))
/* don't display empty entries */
continue;
printf("dump vlan %i\n", i);
dump_many_fields(rtu_vlans, vlan_info, ARRAY_SIZE(vlan_info));
sprintf(prefix,"rtu.vlan.%d",i);
dump_many_fields(rtu_vlans, vlan_info, ARRAY_SIZE(vlan_info),prefix);
}
return 0;
}
......@@ -537,8 +588,6 @@ struct dump_info spll_stats_info[] = {
static int dump_spll_mem(struct spll_stats *spll)
{
printf("ID: Soft PLL:\n");
/* Check magic */
if (spll->magic != SPLL_MAGIC) {
/* Wrong magic */
......@@ -546,7 +595,7 @@ static int dump_spll_mem(struct spll_stats *spll)
spll->magic, SPLL_MAGIC);
}
dump_many_fields(spll, spll_stats_info, ARRAY_SIZE(spll_stats_info));
dump_many_fields(spll, spll_stats_info, ARRAY_SIZE(spll_stats_info),"SoftPll");
return 0; /* this is complete */
}
......@@ -656,20 +705,17 @@ int main(int argc, char **argv)
}
head = m;
if (!head->pidsequence) {
printf("ID %i (\"%s\"): no data\n",
i, name_id_to_name[i]);
printf("shm.%d.name: %s\n",i,name_id_to_name[i]);
printf("shm.%d.iterations: %d (no data)\n",i,head->pidsequence);
wrs_shm_put(m);
continue;
}
printf("shm.%d.name: %s\n",i,head->name);
printf("shm.%d.pid: %d\n",i,head->pid);
if (head->pid) {
printf("ID %i (\"%s\"): pid %i (%s, %i iterations)\n",
i, head->name, head->pid,
kill(head->pid, 0) < 0 ? "dead" : "alive",
head->pidsequence);
} else {
printf("ID %i (\"%s\"): no pid (after %i iterations)\n",
i, head->name, head->pidsequence);
printf("shm.%d.status: %s\n",i,kill(head->pid, 0) < 0 ? "dead" : "alive");
}
printf("shm.%d.iterations: %d\n",i,head->pidsequence);
f = name_id_to_f[i];
/* if the area-specific function fails, fall back to generic */
......
......@@ -38,6 +38,7 @@ enum dump_type {
dump_type_uint16_t,
dump_type_int,
dump_type_unsigned_long,
dump_type_long_long,
dump_type_unsigned_char,
dump_type_unsigned_short,
dump_type_double,
......@@ -52,11 +53,15 @@ enum dump_type {
dump_type_Integer16,
dump_type_UInteger8,
dump_type_Integer8,
dump_type_UInteger4,
dump_type_Enumeration8,
dump_type_Boolean,
dump_type_ClockIdentity,
dump_type_PortIdentity,
dump_type_ClockQuality,
dump_type_TimeInterval,
dump_type_RelativeDifference,
dump_type_Timestamp,
/* and this is ours */
dump_type_time,
dump_type_ip_address,
......@@ -88,5 +93,6 @@ struct dump_info {
int size; /* only for strings or binary strings */
};
void dump_many_fields(void *addr, struct dump_info *info, int ninfo);
void dump_many_fields(void *addr, struct dump_info *info, int ninfo,
char *prefix);
int dump_ppsi_mem(struct wrs_shm_head *head);
# We are now Kconfig-based
-include ../../.config
OBJS = wrs_watchdog.o
BINARY = wrs_watchdog
......@@ -16,7 +19,10 @@ STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
CFLAGS = -O -g -Wall \
export CFLAGS_OPTIMIZATION:= ${shell echo $(CONFIG_OPTIMIZATION)}
CFLAGS += $(CFLAGS_OPTIMIZATION)
CFLAGS = -Wall \
-Wstrict-prototypes \
-I../include \
-I../libwr/include \
......
# We are now Kconfig-based
-include ../../.config
OBJS = hal_exports.o hal_main.o hal_ports.o hal_timing.o
BINARY = wrsw_hal
......@@ -16,7 +19,10 @@ STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
CFLAGS = -O -g -Wall \
export CFLAGS_OPTIMIZATION:= ${shell echo $(CONFIG_OPTIMIZATION)}
CFLAGS += $(CFLAGS_OPTIMIZATION)
CFLAGS += -Wall \
-Wstrict-prototypes \
-I../include \
-I../libwr/include \
......@@ -34,6 +40,7 @@ LDFLAGS = -L../libwr -L../mini-rpc \
all: $(BINARY)
$(BINARY): $(OBJS)
pwd
$(CC) -o $@ $^ $(LDFLAGS)
install: all
......
......@@ -15,7 +15,6 @@
#include <minipc.h>
#include <libwr/shmem.h>
#define HAL_EXPORT_STRUCTURES
#include <hal_exports.h> /* for exported structs/function protos */
static struct minipc_ch *hal_ch;
......@@ -28,7 +27,7 @@ int halexp_lock_cmd(const char *port_name, int command, int priority)
{
int rval;
pr_debug("halexp_lock_cmd: cmd=%d port=%s\n", command, port_name);
/* pr_debug("halexp_lock_cmd: cmd=%d port=%s\n", command, port_name); */
switch (command) {
case HEXP_LOCK_CMD_ENABLE_TRACKING:
......@@ -78,8 +77,9 @@ int halexp_lock_cmd(const char *port_name, int command, int priority)
* both the PLLs and the PPS Generator. */
int halexp_pps_cmd(int cmd, hexp_pps_params_t * params)
{
int busy;
int busy,ret;
pr_debug("halexp_pps_cmd: cmd=%d\n", cmd);
switch (cmd) {
/* fixme: TODO: implement HEXP_PPSG_CMD_GET call */
......@@ -142,6 +142,19 @@ int halexp_pps_cmd(int cmd, hexp_pps_params_t * params)
case HEXP_PPSG_CMD_SET_VALID:
return shw_pps_gen_enable_output(params->pps_valid);
case HEXP_PPSG_CMD_SET_TIMING_MODE:
ret=shw_pps_set_timing_mode(params->timing_mode);
hal_update_timing_mode();
return ret;
case HEXP_PPSG_CMD_GET_TIMING_MODE:{
ret=hal_get_timing_mode();
printf("JCB: shw_pps_get_timing_mode() returns %d\n",ret);
return ret;
}
case HEXP_PPSG_CMD_GET_TIMING_MODE_STATE:
return shw_pps_get_timing_mode_state();
}
return -1; /* fixme: real error code */
}
......
......@@ -37,6 +37,13 @@
#define UPDATE_LINK_LEDS_PERIOD 500 /* ms */
#define UPDATE_SFP_DOM_PERIOD 1000 /* ms */
typedef struct {
struct pp_instance * ppi; /* pointer to the ppi instance */
struct pp_servo servo_snapshot; /* image of a the ppsi servo */
} inst_servo_t ;
static inst_servo_t servo;
extern struct hal_shmem_header *hal_shmem;
extern struct wrs_shm_head *hal_shmem_hdr;
......@@ -47,8 +54,8 @@ static struct hal_port_state *ports;
static int hal_port_fd;
/* RT subsystem PLL state, polled regularly via mini-ipc */
static struct rts_pll_state hal_port_rts_state;
static int hal_port_rts_state_valid = 0;
struct rts_pll_state hal_port_rts_state;
int hal_port_rts_state_valid = 0;
/* Polling timeouts (RT Subsystem & SFP detection) */
static timeout_t hal_port_tmo_rts, hal_port_tmo_sfp;
......@@ -56,8 +63,7 @@ static timeout_t update_sync_leds_tmo, update_link_leds_tmo;
static timeout_t update_sfp_dom_tmo;
static int hal_port_nports;
static struct wr_servo_state *ppsi_servo;
static struct wr_servo_state ppsi_servo_local;
static struct pp_globals *ppg;
static struct pp_instance *ppsi_instances;
static struct pp_instance ppsi_instances_local[PP_MAX_LINKS];
static struct wrs_shm_head *ppsi_head;
......@@ -111,9 +117,12 @@ static int hal_port_check_presence(const char *if_name, unsigned char *mac)
static int hal_port_init(int index)
{
struct hal_port_state *p = &ports[index];
char name[128], s[128];
int val, error;
int i;
char key[128];
int val;
int wrInstanceFound=0;
int port_i;
char *retValue;
/* index is 0..17, port_i 1..18 */
port_i = index + 1;
......@@ -121,35 +130,53 @@ static int hal_port_init(int index)
/* make sure the states and other variables are in their init state */
hal_port_reset_state(p);
/* read dot-config values for this index, starting from name */
error = libwr_cfg_convert2("PORT%02i_PARAMS", "name", LIBWR_STRING,
name, port_i);
if (error)
/* read dot-config values to get the interface name */
sprintf(key,"PORT%02i_IFACE",port_i);
if( (retValue=libwr_cfg_get(key))==NULL)
return -1;
strncpy(p->name, name, 16);
strncpy(p->name, retValue, 16);
/* check if the port is built into the firmware, if not, we are done */
if (!hal_port_check_presence(name, p->hw_addr))
if (!hal_port_check_presence(p->name, p->hw_addr))
return -1;
p->state = HAL_PORT_STATE_DISABLED;
p->in_use = 1;
/* Search an instance using the WR profile */
for (i=1; i<=2; i++) {
sprintf(key,"PORT%02i_INST%02i_PROFILE_WR",port_i,i);
if( ((retValue=libwr_cfg_get(key))!=NULL) && (*retValue=='y') ) {
wrInstanceFound++;
break; // Found
}
}
val = 18 * 800; /* magic default from previous code */
error = libwr_cfg_convert2("PORT%02i_PARAMS", "tx", LIBWR_INT,
&val, port_i);
if (error)
pr_error("port %i (%s): no \"tx=\" specified\n",
port_i, name);
p->calib.phy_tx_min = val;
if ( wrInstanceFound ) {
// WR instance found
val = 18 * 800; /* magic default from previous code */
for ( i=0; i<2; i++ ) {
char *latency=i==0 ? "EGRESS": "INGRESS";
uint32_t *phy_min=i==0 ? &p->calib.phy_tx_min: &p->calib.phy_rx_min;
sprintf(key,"PORT%02i_INST%02i_%s_LATENCY",port_i,i,latency);
if( (retValue=libwr_cfg_get(key))==NULL ) {
pr_error("port %i (%s): no key \"%s\" specified\n",
port_i, p->name,key);
} else {
if (sscanf(retValue, "%i", &val) != 1) {
pr_error("port %i (%s): Invalid key \"%s\" value (%d)\n",
port_i, p->name, key,*retValue);
}
}
*phy_min = val;
}
val = 18 * 800; /* magic default from previous code */
error = libwr_cfg_convert2("PORT%02i_PARAMS", "rx", LIBWR_INT,
&val, port_i);
if (error)
pr_error("port %i (%s): no \"rx=\" specified\n",
port_i, name);
p->calib.phy_rx_min = val;
} else {
pr_error("port %i (%s): no WhiteRabbit instance defined\n",
port_i, p->name);
p->calib.phy_tx_min = p->calib.phy_rx_min = val;
}
p->calib.delta_tx_board = 0; /* never set */
p->calib.delta_rx_board = 0; /* never set */
......@@ -162,61 +189,25 @@ static int hal_port_init(int index)
p->t4_phase_transition = DEFAULT_T4_PHASE_TRANS;
p->clock_period = REF_CLOCK_PERIOD_PS;
/* enabling of ports is done by startup script */
{
static struct roletab { char *name; int value; } *rp, rt[] = {
{"auto", HEXP_PORT_MODE_WR_M_AND_S},
{"master", HEXP_PORT_MODE_WR_MASTER},
{"slave", HEXP_PORT_MODE_WR_SLAVE},
{"non-wr", HEXP_PORT_MODE_NON_WR},
{"none", HEXP_PORT_MODE_NONE},
{NULL, HEXP_PORT_MODE_NON_WR /* default,
* should exist and be last*/},
};
strcpy(s, "non-wr"); /* default if no string passed */
p->mode = HEXP_PORT_MODE_NON_WR;
error = libwr_cfg_convert2("PORT%02i_PARAMS", "role",
LIBWR_STRING, s, port_i);
if (error)
pr_error("port %i (%s): "
"no \"role=\" specified\n", port_i, name);
for (rp = rt; rp->name; rp++)
if (!strcasecmp(s, rp->name))
break;
p->mode = rp->value;
if (!rp->name) {
for (rp = rt; rp->name; rp++)
if (p->mode == rp->value)
break;
pr_error("port %i (%s): invalid role "
"\"%s\" specified; using mode %s\n", port_i,
name, s, rp->name);
/* Get fiber type */
p->fiber_index = 0; /* Default fiber value */
sprintf(key,"PORT%02i_INST%02i_FIBER",port_i,i);
if( (retValue=libwr_cfg_get(key))==NULL ) {
pr_error("port %i (%s): no key \"%s\" specified. Default fiber 0\n",
port_i, p->name,key);
} else {
if (sscanf(retValue, "%i", &p->fiber_index) != 1) {
pr_error("port %i (%s): Invalid key \"%s\" value (%d). Default fiber 0\n",
port_i, p->name, key,*retValue);
}
pr_debug("Port %s: mode %s (%i)\n", p->name, rp->name,
p->mode);
}
/* Get fiber type */
error = libwr_cfg_convert2("PORT%02i_PARAMS", "fiber",
LIBWR_INT, &p->fiber_index, port_i);
if (error) {
pr_error("port %i (%s): "
"no \"fiber=\" specified, default fiber to 0\n",
port_i, name);
p->fiber_index = 0;
}
if (p->fiber_index > 3) {
pr_error("port %i (%s): "
"not supported \"fiber=\" value, default to 0\n",
port_i, name);
"not supported fiber value (%d), default to 0\n",
port_i, p->name,p->fiber_index);
p->fiber_index = 0;
}
}
/* Used to pre-calibrate the TX path for each port. No more in V3 */
......@@ -345,15 +336,14 @@ int hal_port_pshifter_busy()
/* Updates the current value of the phase shift on a given
* port. Called by the main update function regularly. */
static void poll_rts_state(void)
int hal_port_poll_rts_state(void)
{
struct rts_pll_state *hs = &hal_port_rts_state;
if (libwr_tmo_expired(&hal_port_tmo_rts)) {
hal_port_rts_state_valid = rts_get_state(hs) < 0 ? 0 : 1;
if (!hal_port_rts_state_valid)
printf("rts_get_state failure, weird...\n");
}
hal_port_rts_state_valid = rts_get_state(hs) < 0 ? 0 : 1;
if (!hal_port_rts_state_valid)
printf("rts_get_state failure, weird...\n");
return hal_port_rts_state_valid;
}
static uint32_t pcs_readl(struct hal_port_state * p, int reg)
......@@ -383,8 +373,10 @@ static int hal_port_link_down(struct hal_port_state * p, int link_up)
if (p->locked) {
pr_info("Switching RTS to use local reference\n");
if (hal_get_timing_mode()
!= HAL_TIMING_MODE_GRAND_MASTER)
rts_set_mode(RTS_MODE_GM_FREERUNNING);
!= HAL_TIMING_MODE_GRAND_MASTER) {
shw_pps_set_timing_mode(HAL_TIMING_MODE_FREE_MASTER);
hal_update_timing_mode();
}
}
/* turn off synced LED */
......@@ -426,14 +418,17 @@ static void hal_port_fsm(struct hal_port_state * p)
case HAL_PORT_STATE_RESET:
{
if (link_up) {
uint32_t bit_slide_steps;
p->calib.tx_calibrated = 1;
p->calib.rx_calibrated = 1;
/* FIXME: use proper register names */
pr_info("Bitslide: %d\n",
((pcs_readl(p, 16) >> 4) & 0x1f));
bit_slide_steps=(pcs_readl(p, 16) >> 4) & 0x1f;
p->calib.bitslide_ps=bit_slide_steps*800; /* 1 step = 800ps */
pr_info("Bitslide: %d\n",bit_slide_steps);
p->calib.delta_rx_phy =
p->calib.phy_rx_min +
((pcs_readl(p, 16) >> 4) & 0x1f) * 800;
p->calib.phy_rx_min;
p->calib.delta_tx_phy = p->calib.phy_tx_min;
if (0)
......@@ -627,7 +622,6 @@ static void hal_port_remove_sfp(struct hal_port_state * p)
/* detects insertion/removal of SFP transceivers */
static void hal_port_poll_sfp(void)
{
if (libwr_tmo_expired(&hal_port_tmo_sfp)) {
uint32_t mask = shw_sfp_module_scan();
static int old_mask = 0;
......@@ -651,7 +645,6 @@ static void hal_port_poll_sfp(void)
}
}
old_mask = mask;
}
}
/* Executes the port FSM for all ports. Called regularly by the main loop. */
......@@ -660,11 +653,13 @@ void hal_port_update_all()
int i;
/* poll_rts_state does not write to shmem */
poll_rts_state();
if (libwr_tmo_expired(&hal_port_tmo_rts))
hal_port_poll_rts_state();
/* lock shmem */
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_BEGIN);
hal_port_poll_sfp();
if (libwr_tmo_expired(&hal_port_tmo_sfp))
hal_port_poll_sfp();
for (i = 0; i < HAL_MAX_PORTS; i++)
if (ports[i].in_use)
......@@ -719,25 +714,24 @@ int hal_port_start_lock(const char *port_name, int priority)
{
struct hal_port_state *p = hal_lookup_port(ports, hal_port_nports,
port_name);
int ret=-1;
if (!p)
return -1;
/* can't lock to a disconnected port */
if (p->state != HAL_PORT_STATE_UP)
return -1;
/* lock shmem */
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_BEGIN);
/* fixme: check the main FSM state before */
p->state = HAL_PORT_STATE_LOCKING;
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_END);
if (!p && p->state != HAL_PORT_STATE_UP )
return -1; /* can't lock to a disconnected port */
pr_info("Locking to port: %s\n", port_name);
rts_set_mode(RTS_MODE_BC);
hal_port_poll_rts_state(); // update rts state
if ( (hal_get_timing_mode()==HAL_TIMING_MODE_BC) &&
(ret=rts_lock_channel(p->hw_index, 0))>0 ) {
/* lock shmem */
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_BEGIN);
/* fixme: check the main FSM state before */
p->state = HAL_PORT_STATE_LOCKING;
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_END);
}
return ret;
return rts_lock_channel(p->hw_index, 0); /* 0 or -1 already */
}
/* Returns 1 if the port is locked */
......@@ -756,7 +750,8 @@ int hal_port_check_lock(const char *port_name)
if (hs->delock_count > 0)
return 0;
return (hs->current_ref == p->hw_index &&
return ( hs->mode==RTS_MODE_BC &&
hs->current_ref == p->hw_index &&
(hs->flags & RTS_DMTD_LOCKED) &&
(hs->flags & RTS_REF_LOCKED));
}
......@@ -771,12 +766,6 @@ int hal_port_reset(const char *port_name)
if (p->state != HAL_PORT_STATE_LINK_DOWN
&& p->state != HAL_PORT_STATE_DISABLED) {
if (p->locked) {
pr_info("Switching RTS to use local reference\n");
if (hal_get_timing_mode()
!= HAL_TIMING_MODE_GRAND_MASTER)
rts_set_mode(RTS_MODE_GM_FREERUNNING);
}
/* turn off synced LED */
set_led_synced(p->hw_index, 0);
......@@ -921,15 +910,18 @@ static void update_sync_leds(void)
int i;
static uint32_t update_count = 0;
static uint32_t since_last_servo_update = 0;
char *iface_name;
/* read servo */
if (read_servo())
return;
if (!strnlen(ppsi_servo_local.if_name, 16))
iface_name=servo.ppi->cfg.iface_name;
if (!strnlen(iface_name, 16))
return;
for (i = 0; i < HAL_MAX_PORTS; i++) {
/* Check:
* --port in use
* --link is up
......@@ -939,56 +931,80 @@ static void update_sync_leds(void)
*/
if (ports[i].in_use
&& state_up(ports[i].state)
&& !strcmp(ppsi_servo_local.if_name, ports[i].name)) {
if (update_count == ppsi_servo_local.update_count) {
&& !strcmp(iface_name, ports[i].name)) {
int ledValue=0; /* default value */
if (update_count == servo.servo_snapshot.update_count) {
if (since_last_servo_update < 7)
since_last_servo_update++;
} else {
since_last_servo_update = 0;
update_count = ppsi_servo_local.update_count;
update_count = servo.servo_snapshot.update_count;
}
/* Check:
* --port in slave mode
* --servo is in track phase
* --ppsi instance in slave state
* --servo is locked
* --WR of HA PTP servo
* --servo is updating
*/
if (ports[i].mode == HEXP_PORT_MODE_WR_SLAVE
&& ppsi_servo_local.state == WR_TRACK_PHASE
ledValue=(servo.ppi->state == PPS_SLAVE
&& servo.servo_snapshot.servo_locked
&& (servo.ppi->protocol_extension == PPSI_EXT_WR || servo.ppi->protocol_extension == PPSI_EXT_L1S)
&& since_last_servo_update < 7
) {
set_led_synced(i, 1);
} else {
set_led_synced(i, 0);
}
) ? 1 : 0;
set_led_synced(i, ledValue);
}
}
}
static int read_servo(void){
unsigned ii;
unsigned retries = 0;
/* read data, with the sequential lock to have all data consistent */
while (1) {
ii = wrs_shm_seqbegin(ppsi_head);
memcpy(&ppsi_servo_local, ppsi_servo, sizeof(*ppsi_servo));
retries++;
if (retries > 100)
return -1;
if (!wrs_shm_seqretry(ppsi_head, ii))
break; /* consistent read */
}
unsigned int i;
return 0;
if ( read_ppsi_instances() )
return -1;
bzero(&servo.servo_snapshot,sizeof(struct pp_servo));
for (i = 0; i < ppg->nlinks; i++) {
struct pp_instance *ppi = &ppsi_instances_local[i];
/* we are only interested on instances in SLAVE state */
if (ppi->state == PPS_SLAVE ) {
/* ppsi-servo points to instance servo data */
struct pp_servo *ppsi_servo = wrs_shm_follow(ppsi_head, ppi->servo);
if (!ppsi_servo) {
return -1; /* Cannot access servo data */
}
while (1) {
unsigned ii = wrs_shm_seqbegin(ppsi_head);
unsigned retries = 0;
memcpy(&servo.servo_snapshot, ppsi_servo, sizeof(struct pp_servo));
servo.ppi=ppi;
if (!wrs_shm_seqretry(ppsi_head, ii)) {
break; /* consistent read */
}
retries++;
if (retries > 100)
return -1;
}
return 0; /* We assume that we have only one servo */
}
}
return -1; /* No active servo found */
}
static int try_open_ppsi_shmem(void)
{
int ret;
struct pp_globals *ppg;
static int open_error;
if (ppsi_servo && ppsi_instances) {
if (ppsi_instances) {
/* shmem already opened */
return 1;
}
......@@ -1021,13 +1037,6 @@ static int try_open_ppsi_shmem(void)
}
ppg = (void *)ppsi_head + ppsi_head->data_off;
/* there is an assumption that there is only one servo in ppsi! */
ppsi_servo = wrs_shm_follow(ppsi_head, ppg->global_ext_data);
if (!ppsi_servo) {
pr_error("Cannot follow ppsi_servo in shmem.\n");
return 0;
}
ppsi_instances = wrs_shm_follow(ppsi_head, ppg->pp_instances);
if (!ppsi_instances) {
pr_error("Cannot follow pp_instances in shmem.\n");
......@@ -1038,3 +1047,5 @@ static int try_open_ppsi_shmem(void)
return 1;
}
......@@ -15,107 +15,44 @@
#include <rt_ipc.h>
#include <hal_exports.h>
static int timing_mode;
#define LOCK_TIMEOUT_EXT 60000
#define LOCK_TIMEOUT_INT 10000
extern struct rts_pll_state hal_port_rts_state;
extern int hal_port_rts_state_valid;
int hal_init_timing_mode(void)
{
static struct {
char *cfgname;
int modevalue;
} *m, modes[] = {
{"TIME_GM", HAL_TIMING_MODE_GRAND_MASTER},
{"TIME_FM", HAL_TIMING_MODE_FREE_MASTER},
{"TIME_BC", HAL_TIMING_MODE_BC},
{NULL, HAL_TIMING_MODE_BC /* default */},
};
if (rts_connect(NULL) < 0) {
pr_error(
"Failed to establish communication with the RT subsystem.\n");
return -1;
}
/* Read the mode from dot-config */
for (m = modes; m->cfgname; m++)
if (libwr_cfg_get(m->cfgname))
break;
timing_mode = m->modevalue;
if (!m->cfgname)
pr_error("%s: no config variable set, defaults used\n",
__func__);
return 0;
}
int hal_init_timing(char *filename)
{
timeout_t lock_tmo;
/* initialize the RT Subsys */
switch (timing_mode) {
case HAL_TIMING_MODE_GRAND_MASTER:
rts_set_mode(RTS_MODE_GM_EXTERNAL);
libwr_tmo_init(&lock_tmo, LOCK_TIMEOUT_EXT, 0);
break;
default: /* never hit, but having it here prevents a warning */
pr_error("%s: Unable to determine HAL mode! Use BC as"
" default\n", __func__);
case HAL_TIMING_MODE_FREE_MASTER:
case HAL_TIMING_MODE_BC:
rts_set_mode(RTS_MODE_GM_FREERUNNING);
libwr_tmo_init(&lock_tmo, LOCK_TIMEOUT_INT, 0);
break;
}
while (1) {
struct rts_pll_state pstate;
if (libwr_tmo_expired(&lock_tmo)) {
pr_error("Can't lock the PLL. "
"If running in the GrandMaster mode, "
"are you sure the 1-PPS and 10 MHz "
"reference clock signals are properly connected?,"
" retrying...\n");
if (timing_mode == HAL_TIMING_MODE_GRAND_MASTER) {
/*ups... something went wrong, try again */
rts_set_mode(RTS_MODE_GM_EXTERNAL);
libwr_tmo_init(&lock_tmo, LOCK_TIMEOUT_EXT, 0);
} else {
pr_error("Got timeout\n");
return -1;
}
}
if (rts_get_state(&pstate) < 0) {
/* Don't give up when rts_get_state fails, it may be
* due to race with ppsi at boot. No problems seen
* because of waiting here. */
pr_error("rts_get_state failed try again\n");
continue;
}
if (pstate.flags & RTS_DMTD_LOCKED) {
if (timing_mode == HAL_TIMING_MODE_GRAND_MASTER)
pr_info("GrandMaster locked to external "
"reference\n");
break;
}
usleep(100000);
}
/*
* We had "timing.use_nmea", but it was hardwired to /dev/ttyS2
* which is not wired out any more, so this is removed after v4.1
*/
return 0;
}
int hal_get_timing_mode()
int hal_get_timing_mode(void)
{
return timing_mode;
struct rts_pll_state *hs = &hal_port_rts_state;
if (hal_port_rts_state_valid)
switch (hs->mode) {
case RTS_MODE_GM_EXTERNAL:
return HAL_TIMING_MODE_GRAND_MASTER;
case RTS_MODE_GM_FREERUNNING:
return HAL_TIMING_MODE_FREE_MASTER;
case RTS_MODE_BC:
return HAL_TIMING_MODE_BC;
case RTS_MODE_DISABLED:
return HAL_TIMING_MODE_DISABLED;
}
return -1;
}
int hal_update_timing_mode(void) {
return hal_port_poll_rts_state();
}
......@@ -31,10 +31,12 @@ int hal_port_start_lock(const char *port_name, int priority);
int hal_port_check_lock(const char *port_name);
int hal_port_reset(const char *port_name);
int hal_port_enable_tracking(const char *port_name);
int hal_port_poll_rts_state(void);
int hal_init_timing_mode(void);
int hal_init_timing(char *filename);
int hal_get_timing_mode(void);
int hal_update_timing_mode(void);
int hal_port_pshifter_busy(void);
#endif
# We are now Kconfig-based
-include ../../.config
PROGRAM = wrsw_rtud
SRCFILES = rtu_drv.c rtu_ext_drv.c rtu_hash.c rtu_fd.c rtud.c \
rtud_exports.c utils.c
......@@ -17,7 +20,10 @@ STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
CFLAGS = -O2 -Wall -ggdb \
export CFLAGS_OPTIMIZATION:= ${shell echo $(CONFIG_OPTIMIZATION)}
CFLAGS += $(CFLAGS_OPTIMIZATION)
CFLAGS = -Wall \
-Wstrict-prototypes \
-I../mini-rpc \
-I../include \
......
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