Commit 3d815ee0 authored by Adam Wujek's avatar Adam Wujek

changes needed by an uplift of PPSI in WRPC

parents 85b73ff4 300c22b9
......@@ -125,6 +125,12 @@ menu "PTP Protocol Options"
default 0 if E2E_ONLY
default 1
config LEAP_SECONDS_VAL
int "Value of Leap Seconds"
depends on ARCH_WRPC
default 37
help
Difference in seconds between TAI and UTC.
endmenu
menu "Enabled profiles"
......
......@@ -55,7 +55,9 @@ CFLAGS += $(CFLAGS_OPTIMIZATION)
CFLAGS += -Iinclude -fno-common
CFLAGS += -DPPSI_VERSION=\"$(VERSION)\"
ifneq ($(WRPCSW_ROOT),)
CFLAGS += -I$(WRPCSW_ROOT)
endif
# to avoid ifdef as much as possible, I use the kernel trick for OBJ variables
OBJ-y := fsm.o diag.o timeout.o msgtype.o
......@@ -104,7 +106,7 @@ export CFLAGS
# libraries: see proto-standard/Makefile as an example.
$(TARGET).o: $(OBJ-y)
$(LD) --gc-sections --entry=main -Map $(TARGET).map1 -r -o $@ $(PPSI_O_LDFLAGS) \
$(LD) --gc-sections -Map $(TARGET).map1 -r -o $@ $(PPSI_O_LDFLAGS) \
--start-group $(OBJ-y) --end-group
$(OBJ-y): .config $(wildcard include/ppsi/*.h)
......
CFLAGS += -ffreestanding -Os \
CFLAGS += -ffreestanding \
-ffunction-sections -fdata-sections \
-mmultiply-enabled -mbarrel-shift-enabled \
-Itools -Iproto-standard
......@@ -9,7 +9,8 @@ WRPCSW_ROOT ?= $(CONFIG_WRPCSW_ROOT)
CFLAGS += -I$(WRPCSW_ROOT)/include -I$(WRPCSW_ROOT)/include/std -I$(WRPCSW_ROOT)/softpll
PPSI_O_LDFLAGS = -u wrc_ptp_init
# TODOA: remove --no-gc-sections
PPSI_O_LDFLAGS = --no-gc-sections -u wrc_ptp_init
# Let's use the pp_printf we already have in wrpc-sw
CONFIG_NO_PRINTF = y
......@@ -26,7 +27,6 @@ OBJ-y += \
lib/drop.o \
lib/div64.o \
lib/time-arith.o \
lib/iicomm.o
OBJ-$(CONFIG_WRPC_FAULTS) += $A/faults.o
......
This diff is collapsed.
/*
* Copyright (C) 2012 CERN (www.cern.ch)
* Author: Aurelio Colosimo
* Copyright (C) 2012-2020 CERN (www.cern.ch)
* Author: Aurelio Colosimo, Adam Wujek
*
* Released to the public domain
*/
......@@ -11,87 +11,57 @@
#include <hal_exports.h>
#include "wrpc.h"
#include "../proto-ext-whiterabbit/wr-constants.h"
#include "board.h"
extern int32_t sfp_alpha;
extern int64_t sfp_alpha;
int wrpc_read_calibration_data(struct pp_instance *ppi,
uint32_t *deltaTx, uint32_t *deltaRx, int32_t *fix_alpha,
int32_t *clock_period)
int wrpc_read_calibration_data(
struct pp_instance *ppi,
int32_t *clock_period,
TimeInterval *scaledBitSlide,
RelativeDifference *scaledDelayCoefficient,
TimeInterval *scaledSfpDeltaTx,
TimeInterval *scaledSfpDeltaRx)
{
struct hal_port_state state;
wrpc_get_port_state(&state, ppi->iface_name);
if (wrpc_get_port_state(&state, ppi->iface_name))
return WRH_HW_CALIB_NOT_FOUND;
/* check if the data is available */
if (fix_alpha)
/* take local alpha instead of HAL */
*fix_alpha = sfp_alpha;
if (scaledDelayCoefficient)
*scaledDelayCoefficient= (RelativeDifference) sfp_alpha;
if (scaledBitSlide)
*scaledBitSlide = picos_to_interval((int64_t)state.calib.bitslide_ps);
if (clock_period)
*clock_period = state.clock_period;
/* check if tx is calibrated,
* if so read data */
if (state.calib.tx_calibrated) {
if (deltaTx)
*deltaTx = state.calib.delta_tx_phy
+ state.calib.sfp.delta_tx_ps
+ state.calib.delta_tx_board;
} else
return WR_HW_CALIB_NOT_FOUND;
if (scaledSfpDeltaTx) {
if (state.calib.tx_calibrated) {
*scaledSfpDeltaTx = picos_to_interval(
state.calib.delta_tx_phy
+ state.calib.sfp.delta_tx_ps
+ state.calib.delta_tx_board
);
} else
return WRH_HW_CALIB_NOT_FOUND;
}
/* check if rx is calibrated,
* if so read data */
if (state.calib.rx_calibrated) {
if (deltaRx)
*deltaRx = state.calib.delta_rx_phy
+ state.calib.sfp.delta_rx_ps
+ state.calib.delta_rx_board;
} else
return WR_HW_CALIB_NOT_FOUND;
return WR_HW_CALIB_OK;
}
/* Begin of exported functions */
int wrpc_calibrating_disable(struct pp_instance *ppi, int txrx)
{
return WR_HW_CALIB_OK;
}
int wrpc_calibrating_enable(struct pp_instance *ppi, int txrx)
{
return WR_HW_CALIB_OK;
}
int wrpc_calibrating_poll(struct pp_instance *ppi, int txrx, uint32_t *delta)
{
uint32_t delta_rx = 0, delta_tx = 0;
/* FIXME: why delta was 64bit whereas ep_get_deltas accepts 32bit? */
wrpc_read_calibration_data(ppi, &delta_tx, &delta_rx, NULL, NULL);
if (txrx == WRH_HW_CALIB_TX)
*delta = delta_tx;
else
*delta = delta_rx;
return WR_HW_CALIB_READY;
}
int wrpc_calibration_pattern_enable(struct pp_instance *ppi,
unsigned int calibrationPeriod,
unsigned int calibrationPattern,
unsigned int calibrationPatternLen)
{
ep_cal_pattern_enable();
return WR_HW_CALIB_OK;
}
int wrpc_calibration_pattern_disable(struct pp_instance *ppi)
{
ep_cal_pattern_disable();
return WR_HW_CALIB_OK;
if (scaledSfpDeltaRx) {
if (state.calib.rx_calibrated) {
*scaledSfpDeltaRx = picos_to_interval(
state.calib.delta_rx_phy
+ state.calib.sfp.delta_rx_ps
+ state.calib.delta_rx_board
);
} else
return WRH_HW_CALIB_NOT_FOUND;
}
return WRH_HW_CALIB_OK;
}
......@@ -6,6 +6,7 @@
*/
#include <stdint.h>
#include <errno.h>
#include <ppsi/ppsi.h>
#include <dev/pps_gen.h>
#include <softpll_ng.h>
......@@ -19,22 +20,24 @@ extern uint32_t cal_phase_transition;
int wrpc_spll_locking_enable(struct pp_instance *ppi)
{
if (wrc_ptp_get_mode() == WRC_MODE_GM) {
/* If in grand master don't change pll mode */
return WRH_SPLL_OK;
}
spll_init(SPLL_MODE_SLAVE, 0, SPLL_FLAG_ALIGN_PPS);
WRPC_ARCH_I(ppi)->timingMode = WRH_TM_BOUNDARY_CLOCK;
spll_enable_ptracker(0, 1);
rxts_calibration_start();
return WRH_SPLL_OK;
}
int wrpc_spll_locking_poll(struct pp_instance *ppi, int grandmaster)
int wrpc_spll_locking_poll(struct pp_instance *ppi)
{
int locked;
static int t24p_calibrated = 0;
locked = spll_check_lock(0); /* both slave and gm mode */
if (grandmaster)
return locked ? WRH_SPLL_READY : WRH_SPLL_ERROR;
/* Else, slave: ensure calibration is done */
if(!locked) {
t24p_calibrated = 0;
......@@ -42,16 +45,43 @@ int wrpc_spll_locking_poll(struct pp_instance *ppi, int grandmaster)
else if(locked && !t24p_calibrated) {
/*run t24p calibration if needed*/
if (calib_t24p(WRC_MODE_SLAVE, &cal_phase_transition) < 0)
return WRH_SPLL_CALIB_NOT_READY;
return WRH_SPLL_UNLOCKED;
t24p_calibrated = 1;
}
return locked ? WRH_SPLL_READY : WRH_SPLL_ERROR;
return locked ? WRH_SPLL_LOCKED : WRH_SPLL_ERROR;
}
int wrpc_spll_check_lock_with_timeout(int lock_timeout)
{
uint32_t start_tics;
start_tics = timer_get_tics();
pp_printf("Locking PLL");
while (!spll_check_lock(0) && lock_timeout) {
spll_update();
timer_delay(TICS_PER_SECOND);
if (timer_get_tics() - start_tics > lock_timeout) {
pp_printf("\nLock timeout.");
return -ETIMEDOUT;
}
pp_printf(".");
}
pp_printf("\n");
return 0;
}
int wrpc_spll_locking_reset(struct pp_instance *ppi)
{
//TODO?
/* if configured as master, but due to BMCA changed into BC */
if (wrc_ptp_get_mode() == WRC_MODE_MASTER && WRPC_ARCH_I(ppi)->timingMode == WRH_TM_BOUNDARY_CLOCK) {
spll_init(SPLL_MODE_FREE_RUNNING_MASTER, 0, SPLL_FLAG_ALIGN_PPS);
WRPC_ARCH_I(ppi)->timingMode = WRH_TM_FREE_MASTER;
/* wait for spll to lock */
wrpc_spll_check_lock_with_timeout(LOCK_TIMEOUT_FM);
}
return WRH_SPLL_OK;
}
......@@ -68,13 +98,14 @@ int wrpc_spll_enable_ptracker(struct pp_instance *ppi)
return WRH_SPLL_OK;
}
int wrpc_enable_timing_output(struct pp_instance *ppi, int enable)
int wrpc_enable_timing_output(struct pp_globals *ppg, int enable)
{
if (enable == WR_DSPOR(ppi)->ppsOutputOn)
return WR_SPLL_OK;
WR_DSPOR(ppi)->ppsOutputOn = enable;
static int pps_enable;
shw_pps_gen_enable_output(enable);
if (enable != 2) {
pps_enable = enable;
}
shw_pps_gen_enable_output(pps_enable | GOPTS(ppg)->forcePpsGen);
return WRH_SPLL_OK;
}
......@@ -98,3 +129,13 @@ int wrpc_adjust_phase(int32_t phase_ps)
return WRH_SPLL_OK;
}
int wrpc_get_GM_lock_state(struct pp_globals *ppg, pp_timing_mode_state_t *state)
{
if (spll_check_lock(0))
*state = PP_TIMING_MODE_STATE_LOCKED;
else
*state = PP_TIMING_MODE_STATE_UNLOCKED;
/* Holdover not implemented (PP_TIMING_MODE_STATE_HOLDOVER) */
return 0;
}
......@@ -12,6 +12,9 @@
#include <ppsi/ppsi.h>
#include <libwr/hal_shmem.h>
#define LOCK_TIMEOUT_FM (4 * TICS_PER_SECOND)
#define LOCK_TIMEOUT_GM (60 * TICS_PER_SECOND)
/* This part is exactly wrpc-sw::wrc_ptp.h */
#define WRC_MODE_UNKNOWN 0
#define WRC_MODE_GM 1
......@@ -41,29 +44,59 @@ struct wrpc_ethhdr {
uint16_t h_proto;
} __attribute__((packed));
typedef struct wrpc_arch_data_t {
wrh_timing_mode_t timingMode; /* Timing mode: Grand master, Free running,...*/
/* Keep a copy of configured mode for dump */
int wrpcModeCfg; /* Mode: Grand master, master, slave, abscal */
} wrpc_arch_data_t;
/* values mapped to pp_globals->pp_runtime_opts->forcePpsGen */
typedef enum {
pps_force_off,
pps_force_on,
pps_force_check
} wrpc_pps_force_t;
/* wrpc-spll.c (some should move to time-wrpc/) */
int wrpc_spll_locking_enable(struct pp_instance *ppi);
int wrpc_spll_locking_poll(struct pp_instance *ppi, int grandmaster);
int wrpc_spll_locking_poll(struct pp_instance *ppi);
int wrpc_spll_locking_disable(struct pp_instance *ppi);
int wrpc_spll_locking_reset(struct pp_instance *ppi);
int wrpc_spll_enable_ptracker(struct pp_instance *ppi);
int wrpc_adjust_in_progress(void);
int wrpc_adjust_counters(int64_t adjust_sec, int32_t adjust_nsec);
int wrpc_adjust_phase(int32_t phase_ps);
int wrpc_enable_timing_output(struct pp_instance *ppi, int *ppsOutputOn, int enable);
int wrpc_enable_timing_output(struct pp_globals *ppg, int enable);
int wrpc_spll_check_lock_with_timeout(int lock_timeout);
int wrc_ptp_bmc_update(void);
int wrc_ptp_link_down(void);
int wrc_pps_force(wrpc_pps_force_t action);
int wrpc_get_GM_lock_state(struct pp_globals *ppg, pp_timing_mode_state_t *state);
void wrc_ptp_set_leapsec(int leapsec);
void wrc_ptp_get_leapsec(int *ptp, int *system);
/* wrpc-calibration.c */
int wrpc_read_calibration_data(struct pp_instance *ppi,
uint32_t *deltaTx, uint32_t *deltaRx,
int32_t *fix_alpha, int32_t *clock_period);
int wrpc_calibrating_disable(struct pp_instance *ppi, int txrx);
int wrpc_calibrating_enable(struct pp_instance *ppi, int txrx);
int wrpc_calibrating_poll(struct pp_instance *ppi, int txrx, uint32_t *delta);
int wrpc_calibration_pattern_enable(struct pp_instance *ppi,
unsigned int calibrationPeriod,
unsigned int calibrationPattern,
unsigned int calibrationPatternLen);
int wrpc_calibration_pattern_disable(struct pp_instance *ppi);
int wrpc_read_calibration_data(
struct pp_instance *ppi,
int32_t *clock_period,
TimeInterval *scaledBitSlide,
RelativeDifference *scaledDelayCoefficient,
TimeInterval *scaledSfpDeltaTx,
TimeInterval *scaledSfpDeltaRx);
int wrpc_get_port_state(struct hal_port_state *port, const char *port_name);
static inline wrpc_arch_data_t *WRPC_ARCH_I(struct pp_instance *ppi)
{
return (wrpc_arch_data_t *) GLBS(ppi)->arch_data;
}
static inline wrpc_arch_data_t *WRPC_ARCH_G(struct pp_globals *ppg)
{
return (wrpc_arch_data_t *) ppg->arch_data;
}
#endif /* __WRPC_H */
......@@ -5,6 +5,10 @@ A := arch-$(ARCH)
SIZE = $(CROSS_COMPILE)size
CFLAGS += -Itools
# needed for --gc-sections option of ld
PPSI_O_LDFLAGS = --entry=main
# Prevent a warning for a missing prototype in pp_printf, bug since ever
ARCH_PP_PRINTF_CFLAGS += -include ../$A/include/strnlen.h
......
......@@ -144,10 +144,10 @@ static unsigned int run_all_state_machines(struct pp_globals *ppg)
ppi->iface_name, ppi->link_up ? "up":"down");
if (ppi->link_up) {
TimeInterval scaledBitSlide;
RelativeDifference scaledDelayCoefficient;
TimeInterval scaledSfpDeltaTx;
TimeInterval scaledSfpDeltaRx;
TimeInterval scaledBitSlide = 0;
RelativeDifference scaledDelayCoefficient = 0;
TimeInterval scaledSfpDeltaTx = 0;
TimeInterval scaledSfpDeltaRx = 0;
ppi->state = PPS_INITIALIZING;
if ( wrs_read_calibration_data(ppi,NULL,
......@@ -155,20 +155,19 @@ static unsigned int run_all_state_machines(struct pp_globals *ppg)
&scaledDelayCoefficient,
&scaledSfpDeltaTx,
&scaledSfpDeltaRx)!= WRH_HW_CALIB_OK ) {
pp_diag(ppi, fsm, 1, "Cannot read bit_slide value values\n");
scaledBitSlide=0;
pp_diag(ppi, fsm, 1, "Cannot get calibration values (bitslide, alpha, TX/Rx delays\n");
}
ppi->timestampCorrectionPortDS.semistaticLatency= scaledBitSlide;
if (scaledDelayCoefficient>=PP_MIN_DELAY_COEFFICIENT_AS_RELDIFF &&
scaledDelayCoefficient<=PP_MAX_DELAY_COEFFICIENT_AS_RELDIFF ) {
/* Scaled delay coefficient is valid then delta tx and rx also */
if ( ppi->asymmetryCorrectionPortDS.enable ) {
ppi->cfg.scaledDelayCoefficient=scaledDelayCoefficient;
enable_asymmetryCorrection(ppi,TRUE);
}
ppi->timestampCorrectionPortDS.egressLatency=picos_to_interval(ppi->cfg.egressLatency_ps)+scaledSfpDeltaTx;
ppi->timestampCorrectionPortDS.ingressLatency=picos_to_interval(ppi->cfg.ingressLatency_ps)+scaledSfpDeltaRx;
}
if (scaledDelayCoefficient>=PP_MIN_DELAY_COEFFICIENT_AS_RELDIFF
&& scaledDelayCoefficient<=PP_MAX_DELAY_COEFFICIENT_AS_RELDIFF ) {
/* Scaled delay coefficient is valid then delta tx and rx also */
if ( ppi->asymmetryCorrectionPortDS.enable ) {
ppi->cfg.scaledDelayCoefficient=scaledDelayCoefficient;
enable_asymmetryCorrection(ppi,TRUE);
}
ppi->timestampCorrectionPortDS.egressLatency=picos_to_interval(ppi->cfg.egressLatency_ps)+scaledSfpDeltaTx;
ppi->timestampCorrectionPortDS.ingressLatency=picos_to_interval(ppi->cfg.ingressLatency_ps)+scaledSfpDeltaRx;
}
}
else {
ppi->next_state = PPS_DISABLED;
......
......@@ -9,6 +9,14 @@ CONFIG_ARCH_WRPC=y
# CONFIG_ARCH_WRS is not set
# CONFIG_ARCH_SIMULATOR is not set
CONFIG_ARCH="wrpc"
CONFIG_CROSS_COMPILE="/opt/gcc-lm32/bin/lm32-elf-"
CONFIG_ARCH_CFLAGS=""
CONFIG_ARCH_LDFLAGS=""
CONFIG_WRPCSW_ROOT="../wrpc-sw"
#
# Options
#
#
# PTP Protocol Options
......@@ -17,15 +25,61 @@ CONFIG_E2E=y
# CONFIG_P2P is not set
CONFIG_E2E_ONLY=y
CONFIG_HAS_P2P=0
CONFIG_EXT_WR=y
# CONFIG_EXT_NONE is not set
CONFIG_EXTENSION="whiterabbit"
CONFIG_CROSS_COMPILE="/opt/gcc-lm32/bin/lm32-elf-"
CONFIG_ARCH_CFLAGS=""
CONFIG_ARCH_LDFLAGS=""
CONFIG_WRPCSW_ROOT="../wrpc-sw"
CONFIG_LEAP_SECONDS_VAL=37
#
# Enabled profiles
#
CONFIG_PROFILE_WR=y
# CONFIG_PROFILE_HA is not set
# CONFIG_PROFILE_CUSTOM is not set
CONFIG_PROFILE_PTP=y
CONFIG_HAS_EXT_WR=1
CONFIG_HAS_EXT_L1SYNC=0
CONFIG_HAS_EXT_NONE=0
CONFIG_HAS_PROFILE_PTP=1
CONFIG_HAS_PROFILE_HA=0
CONFIG_HAS_PROFILE_WR=1
CONFIG_HAS_PROFILE_CUSTOM=0
#
# VLAN
#
CONFIG_HAS_VLAN=y
CONFIG_VLAN=y
CONFIG_VLAN_ARRAY_SIZE=1
# CONFIG_DISABLE_OPTIMIZATION is not set
CONFIG_OPTIMIZATION=2
# CONFIG_ASSERT is not set
CONFIG_NR_FOREIGN_RECORDS=1
CONFIG_SINGLE_FMASTER=y
CONFIG_NR_PORTS=1
CONFIG_NR_INSTANCES_PER_PORT=1
#
# Code optimization
#
CONFIG_CODEOPT_ENABLED=y
CONFIG_SINGLE_INSTANCE_PER_PORT=y
CONFIG_SINGLE_INSTANCE=y
CONFIG_SINGLE_PORT=y
# CONFIG_CODEOPT_SINGLE_PORT is not set
# CONFIG_CODEOPT_SINGLE_FMASTER is not set
# CONFIG_CODEOPT_SINGLE_INSTANCE_PER_PORT is not set
CONFIG_CODEOPT_EPC_SO_DISABLED=y
# CONFIG_CODEOPT_EPC_ENABLED is not set
# CONFIG_CODEOPT_SO_ENABLED is not set
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"
# CONFIG_FAULT_INJECTION_MECHANISM is not set
CONFIG_HAS_FAULT_INJECTION_MECHANISM=0
CONFIG_HAS_WRPC_FAULTS=0
CONFIG_HAS_CODEOPT_SINGLE_FMASTER=0
CONFIG_HAS_CODEOPT_SINGLE_PORT=0
CONFIG_HAS_CODEOPT_SINGLE_INSTANCE_PER_PORT=0
CONFIG_HAS_CODEOPT_EPC_ENABLED=0
CONFIG_HAS_CODEOPT_SO_ENABLED=0
CONFIG_ARCH_IS_WRS=0
CONFIG_ARCH_IS_WRPC=1
CONFIG_HAS_ASSERT=0
......@@ -58,7 +58,7 @@
@top Introduction
PPSi (@sc{ptp} Ported to Silicon) is an application which, in
its basic operation, implements @sc{ieee} 1588-2020 specification in a way
its basic operation, implements @sc{ieee} 1588-2019 specification in a way
that is portable to several architectures, including OS-less ones.
This manual is mainly aimed at developers: people who are working with
......@@ -376,7 +376,7 @@ As of 2013-05 the project suffers from these known bugs:
@itemize
@item All frames must be sent according to a pseudo-random distribution;
this is mostly in place but mut be audited project-wide.
this is mostly in place but must be audited project-wide.
@item We removed @i{peer-delay} support. We plan to add it back, and
actually move White Rabbit to use @i{peer-delay} @sc{ptp} instead of
@i{end-to-end} @sc{ptp}.
......@@ -445,7 +445,7 @@ following 'port-specific' keywords will be associated to this port until
a new keyword 'port' or 'link' appears.
@anchor{arg-types}
An option is a key/value(s) pair separated by at least a space character '@t{key value(s)}'. The '@t{value{s}}' entry
An option is a key/value(s) pair separated by at least a space character '@t{key value(s)}'. The '@t{value(s)}' entry
depends on the option type. Few types are supported by PPSi:
......@@ -508,25 +508,25 @@ Some old keywords will be marked '@i{(deprecated)}', and will be removed in the
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-2020 standard.
For more details please refer to the IEEE 1588-2019 standard.
@item @b{priority1} @i{[Int32]}
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-2020 standard.
For more details please refer to the IEEE 1588-2019 standard.
@item @b{priority2} @i{[Int32]}
A user configurable designation that provides finer grained ordering
among otherwise equivalent PTP devices.
For more details please refer to the IEEE 1588-2020 standard.
For more details please refer to the IEEE 1588-2019 standard.
@item @b{forcePpsGen} @i{[Boolean]}
Configuration of the PPS output. By default, the PPS is generated
only when the clock class is set to 6(Grand master) or to 193(Free Running master.
When this option is set, the PPS is always generated.
Configuration of the PPS output. By default, the PPS is generated all the time
only when the clock class is set to 6 (Grand master) or to 193 (Free Running master).
When this option is set, the PPS is generated all the time for all clock class.
@item @b{ptpFallbackPpsGen} @i{[Boolean]}
if activated, enables the PPS generation if a slave instance
if activated, enables the PPS generation if a slave instance
programmed to use an extension protocol (WR, L1Sync, ...) is falling back
to PTP communication only.
......@@ -548,14 +548,14 @@ Some old keywords will be marked '@i{(deprecated)}', and will be removed in the
This option is used to force the state of all port instances. The BMCA is then disabled
in PPSi.
When enabled, the port-specific option @t{desiredState} must be defined for each port instance
For more details please refer to the IEEE 1588-2020 (clause 17.6.2)
For more details please refer to the IEEE 1588-2019 (clause 17.6.2)
@item @b{slaveOnly} @i{[Boolean]}
A @t{slaveOnly} Ordinary Clock utilizes the slaveOnly state machine
which does not enable transition to MASTER state.
This option must not be used when @i{externalPortConfigurationEnabled} is
enabled.
For more details please refer to the IEEE 1588-2020 (clause 9.2.2.1)
For more details please refer to the IEEE 1588-2019 (clause 9.2.2.1)
@end table
......@@ -595,7 +595,7 @@ Some old keywords will be marked '@i{(deprecated)}', and will be removed in the
@item @b{masterOnly} @i{[Boolean]}
If enabled , activates the optional '@i{masterOnly}' feature
(refer to the IEEE 1588-2020 - clause 9.2.2.2).
(refer to the IEEE 1588-2019 - clause 9.2.2.2).
This option cannot be used if the global option '@i{externalPortConfiguration}' is
enabled.
If this option is not set, then the standard BMCA algorithm will be used.
......
......@@ -9,13 +9,14 @@
#ifndef __WRH_H__
#define __WRH_H__
#include <stdint.h>
#include <hal_exports.h>
#include <ppsi/lib.h>
/* Please increment WRS_PPSI_SHMEM_VERSION if you change any exported data structure */
#define WRS_PPSI_SHMEM_VERSION 33
/* Don't include the Following when this file is included in assembler. */
#ifndef __ASSEMBLY__
#include <stdint.h>
#include <ppsi/lib.h>
/* White Rabbit softpll status values */
#define WRH_SPLL_ERROR -1
#define WRH_SPLL_OK 0
......@@ -146,11 +147,12 @@ static inline wrh_servo_t *WRH_SRV(struct pp_instance *ppi)
extern void wrh_servo_enable_tracking(int enable);
extern int wrh_servo_init(struct pp_instance *ppi);
extern void wrh_servo_reset(struct pp_instance *ppi);
extern void wrh_servo_enable_tracking(int enable);
extern int wrh_servo_got_sync(struct pp_instance *ppi);
extern int wrh_servo_got_resp(struct pp_instance *ppi);
extern int wrh_servo_got_presp(struct pp_instance *ppi);
extern int wrh_update_correction_values(struct pp_instance *ppi);
#endif /* __ASSEMBLY__ */
#endif /* __WRH_H__ */
......@@ -126,7 +126,7 @@
/* Free running master */
#define PP_FRUNNING_CLOCK_CLASS PP_ARB_CLASS_GM_UNLOCKED_B
#define PP_FRUNNING_CLOCK_VARIANCE PP_ARB_VARIANCE_GM_UNLOCKED
#define PP_FRUNNING_CLOCK_ACCURACY PP_ARB_ACCURACY_GM_UNLOCKED
#define PP_FRUNNING_CLOCK_ACCURACY PP_ARB_ACCURACY_GM_UNLOCKED_B
#define PP_NR_FOREIGN_RECORDS CONFIG_NR_FOREIGN_RECORDS /* Clause 9.3.2.4.5 */
#define PP_FOREIGN_MASTER_TIME_WINDOW 4
......
......@@ -72,7 +72,7 @@ typedef struct Timestamp { /* page 13 (33) -- no typedef expected */
UInteger32 nanosecondsField;
} Timestamp;
/** ******************* IEEE1588-2018 **************************************/
/** ******************* IEEE1588-2019 **************************************/
#define REL_DIFF_FRACBITS 62
#define REL_DIFF_FRACBITS_AS_FLOAT 62.0
#define REL_DIFF_TWO_POW_FRACBITS ((double)4.611686018427388E18) /* double value returned by pow(2.0,62.0) */
......@@ -86,7 +86,7 @@ typedef struct Timestamp { /* page 13 (33) -- no typedef expected */
/*draft P1588_v_29: page 17*/
/* The scaledRelativeDifference member is the relative difference expressed
* as a dimensionless fraction and multiplied by 2+^62, with any remaining
* as a dimensionless fraction and multiplied by 2^+62, with any remaining
* fractional part truncated. */
typedef Integer64 RelativeDifference;
......@@ -229,7 +229,7 @@ typedef struct { /* page 65 */
UInteger8 priority2;
UInteger8 domainNumber;
Boolean slaveOnly;
/** Optional (IEEE1588-2018) */
/** Optional (IEEE1588-2019) */
Timestamp currentTime; /*draft P1588_v_29: page 85*/
Boolean instanceEnable; /*draft P1588_v_29: page 86*/
Boolean externalPortConfigurationEnabled; /*draft P1588_v_29: page 86*/
......@@ -280,7 +280,7 @@ typedef struct { /* page 72 */
UInteger4 versionNumber;
void *ext_dsport;
/** (IEEE1588-2018) */
/** (IEEE1588-2019) */
Integer8 logMinPdelayReqInterval; /*draft P1588_v_29: page 124 */
UInteger4 minorVersionNumber; /*draft P1588_v_29: page 124 */
TimeInterval delayAsymmetry; /*draft P1588_v_29: page 124 */
......@@ -305,7 +305,7 @@ typedef struct { /* page 70 */
Enumeration8 timeSource;
} timePropertiesDS_t;
/** ******************* IEEE1588-2018 **************************************
/** ******************* IEEE1588-2019 **************************************
* Adding new optional data sets (DS) defined in clause, only these relevant
* for HA
*/
......
......@@ -20,7 +20,7 @@ struct pp_runtime_opts {
int clock_quality_clockAccuracy; // ClockQuality.clockAccuracy
int clock_quality_offsetScaledLogVariance; // ClockQuality.offsetScaledLogVariance
int timeSource; // timePropertiesDS_t.timeSource
Boolean ptpTimeScale; // timePropertiesDS_t.timeSource
Boolean ptpTimeScale; // timePropertiesDS_t.timeScale
Boolean frequencyTraceable; // timePropertiesDS_t.frequencyTraceable
Boolean timeTraceable; // timePropertiesDS_t.timeTraceable
Integer32 ttl;
......
......@@ -9,9 +9,9 @@
#define __PPSI_PPSI_H__
#include <generated/autoconf.h>
//#if defined(CONFIG_WRPCSW_ROOT)
#if defined(CONFIG_WRPCSW_ROOT)
#include "../../../include/generated/autoconf.h"
//#endif
#endif
#include <stdint.h>
#include <limits.h>
......
......@@ -115,8 +115,8 @@ int64_t pp_time_to_picos(struct pp_time *t)
void fixedDelta_to_pp_time(struct FixedDelta fd, struct pp_time *t) {
/* FixedDelta is expressed in ps*2^16 */
uint64_t *v=(uint64_t*)&fd;
t->scaled_nsecs=*v/1000L; /* We can do it because scaled_nsecs is also multiply by 2^16 */
uint64_t v = ((uint64_t)fd.scaledPicoseconds.msb)<<32 | (uint64_t)fd.scaledPicoseconds.lsb;
t->scaled_nsecs=v/1000L; /* We can do it because scaled_nsecs is also multiply by 2^16 */
t->secs=0;
normalize_pp_time(t);
}
......@@ -281,7 +281,7 @@ char *interval_to_string(TimeInterval time)
}
nanos = time >> TIME_INTERVAL_FRACBITS;
picos = (((time & TIME_INTERVAL_FRACMASK) * 1000) + TIME_INTERVAL_ROUNDING_VALUE ) >> TIME_INTERVAL_FRACBITS;
sprintf(time_as_string,"%" PRId64 ".%03" PRId64, sign*nanos,picos);
pp_sprintf(time_as_string,"%" PRId64 ".%03" PRId64, sign*nanos,picos);
return time_as_string;
}
......@@ -300,6 +300,6 @@ char *relative_interval_to_string(TimeInterval time) {
sub_yocto+=bitWeight;
bitWeight/=2;
}
sprintf(time_as_string,"%"PRId32".%018"PRIu64, nsecs, sub_yocto);
pp_sprintf(time_as_string,"%"PRId32".%018"PRIu64, nsecs, sub_yocto);
return time_as_string;
}
......@@ -365,7 +365,7 @@ static int __wrh_servo_update(struct pp_instance *ppi)
}
gs->servo_locked=gs->state==WRH_TRACK_PHASE;
gs->servo_locked = (gs->state==WRH_TRACK_PHASE);
/* Increase number of servo updates with state different than
* WRH_TRACK_PHASE. (Used by SNMP) */
......
......@@ -79,7 +79,7 @@ typedef struct { /*draft P1588_v_29: page 100 and 333-335 */
Boolean peerIsTxCoherent;
Boolean peerIsRxCoherent;
Boolean peerIsCongruent;
/* None compliant members with IEEE1558-2018 */
/* None compliant members with IEEE1558-2019 */
Enumeration8 next_state;
} L1SyncBasicPortDS_t;
......
......@@ -19,24 +19,29 @@ int wr_calibration(struct pp_instance *ppi, void *buf, int len, int new_state)
{
struct wr_dsport *wrp = WR_DSPOR(ppi);
wr_servo_ext_t *se =WRE_SRV(ppi);
UInteger64 *delta;
FixedDelta *delta;
TimeInterval ti;
/* Calculate deltaTx and update servo*/
delta=(UInteger64 *)&wrp->deltaTx;
*delta= (UInteger64)(ppi->timestampCorrectionPortDS.egressLatency*1000);
delta = &wrp->deltaTx;
ti = ppi->timestampCorrectionPortDS.egressLatency*1000;
delta->scaledPicoseconds.msb = ti >> 32;
delta->scaledPicoseconds.lsb = ti & 0xFFFFFFFF;
pp_diag(ppi, ext, 1, "deltaTx: msb=0x%x lsb=0x%x\n",
wrp->deltaTx.scaledPicoseconds.msb,
wrp->deltaTx.scaledPicoseconds.lsb);
fixedDelta_to_pp_time(*(struct FixedDelta *)delta,&se->delta_txs);/* Update servo specific data */
fixedDelta_to_pp_time(*delta, &se->delta_txs);/* Update servo specific data */
/* Calculate deltaRx and update servo*/
delta=(UInteger64 *)&wrp->deltaRx;
*delta=(UInteger64)((ppi->timestampCorrectionPortDS.ingressLatency +
delta = &wrp->deltaRx;
ti= ((ppi->timestampCorrectionPortDS.ingressLatency +
ppi->timestampCorrectionPortDS.semistaticLatency) * 1000);
delta->scaledPicoseconds.msb = ti >> 32;
delta->scaledPicoseconds.lsb = ti & 0xFFFFFFFF;
pp_diag(ppi, ext, 1, "deltaRx: msb=0x%x lsb=0x%x\n",
wrp->deltaRx.scaledPicoseconds.msb,
wrp->deltaRx.scaledPicoseconds.lsb);
fixedDelta_to_pp_time(*(struct FixedDelta *)delta, &se->delta_rxs);/* Update servo specific data */
fixedDelta_to_pp_time(*delta, &se->delta_rxs);/* Update servo specific data */
/* Go to the next state */
wrp->next_state = WRS_CALIBRATED;
......
......@@ -31,10 +31,9 @@ int wr_link_on(struct pp_instance *ppi, void *buf, int len, int new_state)
* absolute calibration only exists in arch-wrpc, so far, but
* we can't include wrpc headers, not available in wrs builds
*/
extern int ptp_mode;
extern int ep_get_bitslide(void);
if (ptp_mode == 4 /* WRC_MODE_ABSCAL */) {
if (wrc_ptp_is_abscal() /* WRC_MODE_ABSCAL */) {
wrp->next_state = WRS_ABSCAL;
/* print header for the serial port stream of stamps */
pp_printf("### t4.phase is already corrected for bitslide\n");
......
......@@ -18,41 +18,40 @@ int wr_resp_calib_req(struct pp_instance *ppi, void *buf, int len, int new_state
if (new_state) {
wrp->wrStateRetry = WR_STATE_RETRY;
pp_timeout_set_rename(ppi, wrTmoIdx,WR_TMO_MS*(WR_STATE_RETRY+1),WR_TMO_NAME);
} else {
if (ppi->received_ptp_header.messageType == PPM_SIGNALING) {
Enumeration16 wrMsgId;
MsgSignaling wrsig_msg;
if ( msg_unpack_wrsig(ppi, buf, &wrsig_msg, &wrMsgId) ) {
if ( wrMsgId == CALIBRATED) {
/* Update servo */
wr_servo_ext_t *se =WRE_SRV(ppi);
fixedDelta_to_pp_time(wrp->otherNodeDeltaTx,&se->delta_txm);
fixedDelta_to_pp_time(wrp->otherNodeDeltaRx,&se->delta_rxm);
wrp->next_state = (wrp->wrMode == WR_MASTER) ?
WRS_WR_LINK_ON :
WRS_CALIBRATION;
} else {
pp_diag(ppi, ext, 1, "WR: Invalid msgId(x%04x) received. CALIBRATED was expected\n",wrMsgId);
wr_handshake_fail(ppi);
}
return 0;
}
/* Check whether a message is received, otherwise it may downgrade a link to ptp for wrs v5.0.x */
if (ppi->received_ptp_header.messageType == PPM_SIGNALING) {
Enumeration16 wrMsgId;
MsgSignaling wrsig_msg;
if ( msg_unpack_wrsig(ppi, buf, &wrsig_msg, &wrMsgId) ) {
if ( wrMsgId == CALIBRATED) {
/* Update servo */
wr_servo_ext_t *se =WRE_SRV(ppi);
fixedDelta_to_pp_time(wrp->otherNodeDeltaTx,&se->delta_txm);
fixedDelta_to_pp_time(wrp->otherNodeDeltaRx,&se->delta_rxm);
wrp->next_state = (wrp->wrMode == WR_MASTER) ?
WRS_WR_LINK_ON :
WRS_CALIBRATION;
} else {
pp_diag(ppi, ext, 1, "WR: Invalid msgId(x%04x) received. CALIBRATED was expected\n",wrMsgId);
wr_handshake_fail(ppi);
}
return 0;
}
}
{ /* Check remaining time */
int rms=pp_next_delay_1(ppi, wrTmoIdx);
if ( rms<=(wrp->wrStateRetry*WR_TMO_MS)) {
if ( !rms ) {
pp_diag(ppi, time, 1, "timeout expired: "WR_TMO_NAME"\n");
wr_handshake_fail(ppi);
return 0; /* non-wr already */
}
wr_handshake_retry(ppi);
{ /* Check remaining time */
int rms=pp_next_delay_1(ppi, wrTmoIdx);
if ( rms<=(wrp->wrStateRetry*WR_TMO_MS)) {
if ( !rms ) {
pp_diag(ppi, time, 1, "timeout expired: "WR_TMO_NAME"\n");
wr_handshake_fail(ppi);
return 0; /* non-wr already */
}
wr_handshake_retry(ppi);
}
}
......
......@@ -47,5 +47,5 @@ int wr_s_lock(struct pp_instance *ppi, void *buf, int len, int new_state)
WRH_OPER()->locking_enable(ppi);
}
return 100 ;/* 100ms : We check every 100ms if the PLL is locked */
return 0; /* 0ms : If needed we yeld in locking_poll during waiting for the PLL to lock */
}
......@@ -115,7 +115,6 @@ void wr_reset_process(struct pp_instance *ppi, wr_role_t role);
/* wr_servo interface */
int wr_servo_init(struct pp_instance *ppi);
void wr_servo_enable_tracking(int enable);
typedef struct wr_servo_ext {
struct pp_time delta_txm;
......
......@@ -3,14 +3,6 @@
#include <libwr/shmem.h>
#include "../proto-standard/common-fun.h"
/* Enable tracking by default. Disabling the tracking is used for demos. */
static int wr_tracking_enabled = 1;
void wr_servo_enable_tracking(int enable)
{
wr_tracking_enabled = enable;
}
static inline void _calculate_raw_delayMM(struct pp_instance *ppi,
struct pp_time *ta,struct pp_time *tb,
struct pp_time *tc,struct pp_time *td ) {
......
......@@ -27,7 +27,7 @@ static wr_state_machine_t wr_state_actions[] ={
.action=wr_present,
},
[WRS_M_LOCK]{
.name="wr_m_lock",
.name="wr-m-lock",
.action=wr_m_lock,
},
[WRS_S_LOCK]{
......
......@@ -317,8 +317,8 @@ void bmc_update_clock_quality(struct pp_globals *ppg)
"Timing mode changed : %s, "
"clock class: %d"
", clock accuracy: %d"
", clock variance: x%04x"
", timeSource: x%02x"
", clock variance: 0x%04x"
", timeSource: 0x%02x"
", ptpTimeScale: %d"
", frequencyTraceable: %d"
", timeTraceable: %d"
......
......@@ -7,15 +7,13 @@
#ifndef __MSG_H
#define __MSG_H
#define htonll(x) ((*(char *)&endianess == 1) ? \
htobe64(x) /* Little endian */ \
: \
(x)) /* Big endian */
#define ntohll(x) ((*(char *)&endianess == 1) ? \
be64toh(x) /* Little endian */ \
: \
(x)) /* Big endian */
#if __BYTE_ORDER == __BIG_ENDIAN
# define htonll(x) (x)
# define ntohll(x) (x)
#else
# define htonll(x) htobe64(x)
# define ntohll(x) be64toh(x)
#endif
extern const int endianess; /* use to check endianess */
......
......@@ -11,6 +11,7 @@
#include <dev/syscon.h> /* wrpc-sw */
#include <dev/endpoint.h> /* wrpc-sw */
#include <ptpd_netif.h> /* wrpc-sw */
#include "board.h"
#ifdef CONFIG_ABSCAL
#define HAS_ABSCAL 1
......@@ -77,7 +78,9 @@ static int wrpc_net_recv(struct pp_instance *ppi, void *pkt, int len,
&& (!HAS_ABSCAL || ptp_mode != WRC_MODE_ABSCAL))
mark_incorrect(t);
}
/* copy MAC and vlan of a peer to ppi */
memcpy(ppi->peer, &addr.mac, ETH_ALEN);
ppi->peer_vid = addr.vlan;
/* wrpc-sw may pass this in USER_CFLAGS, to remove footprint */
#ifndef CONFIG_NO_PTPDUMP
/* The header is separate, so dump payload only */
......@@ -90,7 +93,7 @@ static int wrpc_net_recv(struct pp_instance *ppi, void *pkt, int len,
/* WR counts bitslide later, in fixed-delta, so subtract it */
t4 = *t;
bitslide = ep_get_bitslide();
bitslide = ep_get_bitslide(&wrc_endpoint_dev);
t_bts.secs = 0;
t_bts.scaled_nsecs = (bitslide << 16) / 1000;
pp_time_sub(&t4, &t_bts);
......
......@@ -8,6 +8,9 @@
#include <ppsi/ppsi.h>
#include "dev/pps_gen.h" /* in wrpc-sw */
#include "dev/syscon.h" /* in wrpc-sw */
#include "../arch-wrpc/wrpc.h"
static int utcOffset = CONFIG_LEAP_SECONDS_VAL;
static int wrpc_time_get_utc_time(struct pp_instance *ppi, int *hours, int *minutes, int *seconds)
{
......@@ -20,29 +23,15 @@ static int wrpc_time_get_utc_time(struct pp_instance *ppi, int *hours, int *minu
static int wrpc_time_get_utc_offset(struct pp_instance *ppi, int *offset, int *leap59, int *leap61)
{
/* no UTC offset */
*leap59 = 0;
*leap61 = 0;
*offset = 0;
return -1;
*offset = utcOffset;
return 0;
}
static int wrpc_time_set_utc_offset(struct pp_instance *ppi, int offset, int leap59, int leap61)
{
/* no UTC offset */
return -1;
}
static int wrpc_time_get_servo_state(struct pp_instance *ppi, int *state)
{
struct wr_dsport *wrp = WR_DSPOR(ppi);
int locked;
locked = wrp->ops->locking_poll(ppi, 1);
if (locked == WR_SPLL_READY)
*state = PP_SERVO_LOCKED;
else
*state = PP_SERVO_UNLOCKED;
utcOffset = offset;
return 0;
}
......@@ -105,11 +94,12 @@ struct pp_time_operations wrpc_time_ops = {
.get_utc_time = wrpc_time_get_utc_time,
.get_utc_offset = wrpc_time_get_utc_offset,
.set_utc_offset = wrpc_time_set_utc_offset,
.get_servo_state = wrpc_time_get_servo_state,
.get = wrpc_time_get,
.set = wrpc_time_set,
.adjust = wrpc_time_adjust,
.adjust_offset = wrpc_time_adjust_offset,
.adjust_freq = NULL,
.calc_timeout = wrpc_calc_timeout,
.get_GM_lock_state = wrpc_get_GM_lock_state,
.enable_timing_output = wrpc_enable_timing_output,
};
......@@ -308,6 +308,9 @@ int wrs_locking_poll(struct pp_instance *ppi)
char *pp_diag_msg;
char text[128];
/* Wait 10ms between checks when polling */
usleep(10 * 1000);
ret = minipc_call(hal_ch, DEFAULT_TO, &__rpcdef_lock_cmd,
&rval, ppi->iface_name, HEXP_LOCK_CMD_CHECK, 0);
if ( ret<0 ) {
......
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