Commit 41bedca5 authored by Jean-Claude BAU's avatar Jean-Claude BAU Committed by Adam Wujek

Arch. changes for HA integration + bring into compliance with the

standard IEEE1588-2018

We bring here a lot of changes to :
- make the implementation more complaiant with the standard
IEEE1588-2018.
  We introduce new structures for the time (TimeInterval, Relative
difference)
  Named used in structures are aligned to the standard, ...
  It is just a first step. More work is needed
- be able to use more than one protocol extension at the same time
  (configurations, structures, ...)
- add the concept of profile
- increase diagnostics by displaying also standard PTP servo
informations
parent f290c38b
......@@ -116,7 +116,7 @@ config PROFILE_WR
config PROFILE_HA
bool
default y if ARCH_WRS || ARCH_WRPC
default n if ARCH_WRS || ARCH_WRPC
config PROFILE_PTP
bool
......@@ -134,14 +134,6 @@ config EXT_NONE
bool
default y if PROFILE_PTP
config EXTENSIONS
string
default "whiterabbit l1sync" if (EXT_WR && EXT_L1SYNC)
default "whiterabbit" if (EXT_WR && !EXT_L1SYNC)
default "l1sync" if (!EXT_WR && EXT_L1SYNC)
default "" if PROFILE_PTP
config CROSS_COMPILE
string "Cross compiler prefix"
default "/opt/gcc-lm32/bin/lm32-elf-" if ARCH_WRPC
......
......@@ -75,10 +75,11 @@ CFLAGS += -Iarch-$(ARCH)/include
# proto-standard is always included, as it provides default function
# so the extension can avoid duplication of code.
ifneq ($(PROTO_EXTS),)
PROT_EXT_DIRS=${foreach EXT_NAME,${subst $\",,${PROTO_EXTS}},proto-ext-${EXT_NAME} }
PROT_EXT_MKFS=${foreach PROT_EXT_MKF,${PROT_EXT_DIRS},${PROT_EXT_MKF}/Makefile}
include ${PROT_EXT_MKFS}
ifeq ($(CONFIG_EXT_WR),y)
include proto-ext-whiterabbit/Makefile
endif
ifeq ($(CONFIG_EXT_L1SYNC),y)
include proto-ext-l1sync/Makefile
endif
include proto-standard/Makefile
......
......@@ -68,7 +68,7 @@ int main(int argc, char **argv)
ppi = INST(ppg, i);
ppi->proto = PP_DEFAULT_PROTO;
ppi->role = PP_DEFAULT_ROLE;
ppi->mech = PP_E2E_MECH;
ppi->delayMechanism = E2E;
}
/* Set offset here, so config parsing can override it */
......@@ -94,7 +94,7 @@ int main(int argc, char **argv)
ppi->vlans_array_len = CONFIG_VLAN_ARRAY_SIZE,
ppi->iface_name = ppi->cfg.iface_name;
ppi->port_name = ppi->cfg.port_name;
ppi->mech = ppi->cfg.mech;
ppi->delayMechanism = ppi->cfg.delayMechanism;
ppi->ext_hooks= &pp_hooks;
/* The following default names depend on TIME= at build time */
......
......@@ -82,7 +82,7 @@ struct pp_instance ppi_static = {
.t_ops = &wrpc_time_ops,
.vlans_array_len = CONFIG_VLAN_ARRAY_SIZE,
.proto = PP_DEFAULT_PROTO,
.mech = PP_E2E_MECH, /* until changed by cfg */
.delayMechanism = E2E, /* until changed by cfg */
.iface_name = "wr1",
.port_name = "wr1",
.__tx_buffer = __tx_buffer,
......@@ -225,18 +225,18 @@ int wrc_ptp_sync_mech(int e2e_p2p_qry)
int running;
if (!CONFIG_HAS_P2P)
return ppi->mech;
return ppi->delayMechanism;
switch(e2e_p2p_qry) {
case PP_E2E_MECH:
case PP_P2P_MECH:
case E2E:
case P2P:
running = wrc_ptp_run(-1);
wrc_ptp_run(0);
ppi->mech = e2e_p2p_qry;
ppi->delayMechanism = e2e_p2p_qry;
wrc_ptp_run(running);
return 0;
default:
return ppi->mech;
return ppi->delayMechanism;
}
}
......
......@@ -19,7 +19,8 @@ OBJ-y += $A/wrs-startup.o \
lib/dump-funcs.o \
lib/drop.o \
lib/assert.o \
lib/div64.o
lib/div64.o \
lib/time-arith.o
# We only support "wrs" time operations
TIME = wrs
......
......@@ -2,8 +2,9 @@
#define __ARCH_H__
#include <ppsi/assert.h>
/* This arch exports wr functions, so include this for consistency checking */
/* This arch exports wr/l1e functions, so include this for consistency checking */
#include "../proto-ext-whiterabbit/wr-api.h"
#include "../proto-ext-l1sync/l1e-api.h"
/* Architecture-specific defines, included by top-level stuff */
......
......@@ -30,26 +30,6 @@ static inline struct hal_port_state *pp_wrs_lookup_port(char *name)
#define DEFAULT_TO 200000 /* ms */
/* FIXME return values, here copied from proto-ext-whiterabbit.
* I do not include proto-ext-whiterabbit/wr-constants.h in order not to
* have a dependency on ext when compiling wrs architecture. All the return
* values mechanism of wrs hw should be reviewed in this src and in the
* whole ppsi */
/* White Rabbit softpll status values */
#define WR_SPLL_OK 0
#define WR_SPLL_READY 1
#define WR_SPLL_CALIB_NOT_READY 2
#define WR_SPLL_ERROR -1
/* White Rabbit calibration defines */
#define WR_HW_CALIB_TX 1
#define WR_HW_CALIB_RX 2
#define WR_HW_CALIB_OK 0
#define WR_HW_CALIB_READY 1
#define WR_HW_CALIB_ERROR -1
#define WR_HW_CALIB_NOT_FOUND -3
#define POSIX_ARCH(ppg) ((struct unix_arch_data *)(ppg->arch_data))
struct unix_arch_data {
struct timeval tv;
......
......@@ -24,10 +24,10 @@ int wrs_read_calibration_data(struct pp_instance *ppi,
p = pp_wrs_lookup_port(ppi->iface_name);
if (!p)
return WR_HW_CALIB_NOT_FOUND;
return WRH_HW_CALIB_NOT_FOUND;
if(!p->calib.tx_calibrated || !p->calib.rx_calibrated)
return WR_HW_CALIB_NOT_FOUND;
return WRH_HW_CALIB_NOT_FOUND;
/*
* Like in wrs_net_init, we build fields that were in
......@@ -54,7 +54,7 @@ int wrs_read_calibration_data(struct pp_instance *ppi,
*fix_alpha = port_fix_alpha;
if(clock_period)
*clock_period = 16000; /* REF_CLOCK_PERIOD_PS */
return WR_HW_CALIB_OK;
return WRH_HW_CALIB_OK;
}
int wrs_calibrating_disable(struct pp_instance *ppi, int txrx)
......@@ -73,9 +73,9 @@ int wrs_calibrating_poll(struct pp_instance *ppi, int txrx, uint32_t *delta)
wrs_read_calibration_data(ppi, &delta_tx, &delta_rx, NULL, NULL);
*delta = (txrx == WR_HW_CALIB_TX) ? delta_tx : delta_rx;
*delta = (txrx == WRH_HW_CALIB_TX) ? delta_tx : delta_rx;
return WR_HW_CALIB_READY;
return WRH_HW_CALIB_READY;
}
int wrs_calibration_pattern_enable(struct pp_instance *ppi,
......@@ -83,10 +83,10 @@ int wrs_calibration_pattern_enable(struct pp_instance *ppi,
unsigned int calib_pattern,
unsigned int calib_pattern_len)
{
return WR_HW_CALIB_OK;
return WRH_HW_CALIB_OK;
}
int wrs_calibration_pattern_disable(struct pp_instance *ppi)
{
return WR_HW_CALIB_OK;
return WRH_HW_CALIB_OK;
}
......@@ -12,7 +12,8 @@
/* minipc Encoding of the supported commands */
#define PTPDEXP_COMMAND_TRACKING 1
#define PTPDEXP_COMMAND_WR_TRACKING 1
#define PTPDEXP_COMMAND_L1SYNC_TRACKING 2
static struct minipc_pd __rpcdef_cmd = {
.name = "cmd",
......@@ -27,9 +28,17 @@ static struct minipc_pd __rpcdef_cmd = {
/* Execute command coming ipc */
static int wrsipc_cmd(int cmd, int value)
{
if(cmd == PTPDEXP_COMMAND_TRACKING) {
if(cmd == PTPDEXP_COMMAND_WR_TRACKING) {
#if CONFIG_EXT_WR == 1
wr_servo_enable_tracking(value);
return 0;
#endif
}
if(cmd == PTPDEXP_COMMAND_L1SYNC_TRACKING) {
#if CONFIG_EXT_L1SYNC == 1
l1e_servo_enable_tracking(value);
return 0;
#endif
}
return -1;
......
......@@ -28,12 +28,8 @@
#include <ppsi-wrs.h>
#include <libwr/shmem.h>
#if CONFIG_EXT_WR == 1
/* WR extension declaration */
#include "../proto-ext-whiterabbit/wr-api.h"
#include "../proto-ext-whiterabbit/wr-constants.h"
#endif
#include "../proto-ext-l1sync/l1e-api.h"
# define WRSW_HAL_RETRIES 1000
......@@ -179,8 +175,7 @@ int main(int argc, char **argv)
ppg->defaultDS = alloc_fn(ppsi_head, sizeof(*ppg->defaultDS));
ppg->currentDS = alloc_fn(ppsi_head, sizeof(*ppg->currentDS));
ppg->parentDS = alloc_fn(ppsi_head, sizeof(*ppg->parentDS));
ppg->timePropertiesDS = alloc_fn(ppsi_head,
sizeof(*ppg->timePropertiesDS));
ppg->timePropertiesDS = alloc_fn(ppsi_head,sizeof(*ppg->timePropertiesDS));
ppg->servo = alloc_fn(ppsi_head, sizeof(*ppg->servo));
ppg->rt_opts = &__pp_default_rt_opts;
......@@ -234,13 +229,13 @@ int main(int argc, char **argv)
ppi->vlans_array_len = CONFIG_VLAN_ARRAY_SIZE;
ppi->iface_name = ppi->cfg.iface_name;
ppi->port_name = ppi->cfg.port_name;
ppi->mech = ppi->cfg.mech;
ppi->delayMechanism = ppi->cfg.delayMechanism;
ppi->portDS = alloc_fn(ppsi_head, sizeof(*ppi->portDS));
ppi->ext_hooks=&pp_hooks; /* Default value. Can be overwritten by an extension */
if (ppi->portDS) {
if ( CONFIG_EXT_WR == 1 && ppi->cfg.ext==PPSI_PROFILE_WR ) {
struct wr_data *wdata;
#if CONFIG_EXT_WR == 1
if ( ppi->cfg.profile==PPSI_PROFILE_WR ) {
ppi->protocol_extension=PPSI_EXT_WR;
/* Add WR extension portDS */
if ( !(ppi->portDS->ext_dsport =
alloc_fn(ppsi_head, sizeof(struct wr_dsport))) ) {
......@@ -248,14 +243,33 @@ int main(int argc, char **argv)
}
/* Allocate WR data extension */
if (! (wdata=ppi->ext_data = alloc_fn(ppsi_head,sizeof(struct wr_data))) ) {
if (! (ppi->ext_data = alloc_fn(ppsi_head,sizeof(struct wr_data))) ) {
goto exit_out_of_memory;
}
wdata->servo_state.servo_head.extension=PPSI_EXT_WR;
/* Set WR extension hooks */
ppi->ext_hooks=&wr_ext_hooks;
ppg->global_ext_data=wdata;
}
#endif
#if CONFIG_EXT_L1SYNC == 1
if ( ppi->cfg.profile==PPSI_PROFILE_HA ) {
ppi->protocol_extension=PPSI_EXT_L1S;
/* Add L1E extension portDS */
if ( !(ppi->portDS->ext_dsport =alloc_fn(ppsi_head, sizeof(struct l1e_ext_portDS))) ) {
goto exit_out_of_memory;
}
/* Allocate WR data extension */
if (! (ppi->ext_data = alloc_fn(ppsi_head,sizeof(struct l1e_data))) ) {
goto exit_out_of_memory;
}
/* Set L1SYNC extension hooks */
ppi->ext_hooks=&l1e_ext_hooks;
/* Set default profile parameters */
ppg->defaultDS->externalPortConfigurationEnabled = 1;
ppi->portDS->masterOnly = 0;
}
#endif
} else {
goto exit_out_of_memory;
}
......
......@@ -12,15 +12,53 @@
#include <stdint.h>
#include <ppsi/lib.h>
/* Please increment WRS_PPSI_SHMEM_VERSION if you change any exported data structure */
#define WRS_PPSI_SHMEM_VERSION 31 /* changed wrs_shm_head */
/* White Rabbit softpll status values */
#define WRH_SPLL_OK 0
#define WRH_SPLL_READY 1
#define WRH_SPLL_CALIB_NOT_READY 2
#define WRH_SPLL_ERROR -1
/* White Rabbit calibration defines */
#define WRH_HW_CALIB_TX 1
#define WRH_HW_CALIB_RX 2
#define WRH_HW_CALIB_OK 0
#define WRH_HW_CALIB_READY 1
#define WRH_HW_CALIB_ERROR -1
#define WRH_HW_CALIB_NOT_FOUND -3
enum {
WRH_SERVO_ENTER, WRH_SERVO_LEAVE
};
struct wrh_servo_head {
int extension; /* Used to identify the servo extension. Useful for the monitoring tool */
};
#define FIX_ALPHA_FRACBITS 40
#define FIX_ALPHA_FRACBITS_AS_FLOAT 40.0
#define WRH_SERVO_OFFSET_STABILITY_THRESHOLD 60 /* psec */
#ifdef CONFIG_WRPC_FAULTS
#define PROTO_EXT_HAS_FAULTS 1
#else
#define PROTO_EXT_HAS_FAULTS 0
#endif
/* Contains portDS common stuff which is manipulated outside of the protocol extension code */
/* Must be declared on top of the extension portDS structure */
typedef struct {
Boolean extModeOn;
Boolean ppsOutputOn;
} wrh_portds_head_t;
/* The head is expected at the beginning of the portDS structure */
static inline wrh_portds_head_t *WRH_DSPOR_HEAD(struct pp_instance *ppi)
{
return (wrh_portds_head_t *) ppi->portDS->ext_dsport;
}
/* White Rabbit hw-dependent functions (code in arch-wrpc and arch-wrs) */
struct wrh_operations {
......@@ -46,7 +84,7 @@ struct wrh_operations {
unsigned int calibrationPatternLen);
int (*calib_pattern_disable)(struct pp_instance *ppi);
int (*enable_timing_output)(struct pp_instance *ppi, int enable);
int (*servo_hook)(struct wrh_servo_head *s, int action);
int (*servo_hook)(struct pp_instance *ppi, int action);
int (*read_corr_data)(struct pp_instance *ppi, int64_t *delayCoeff,
int64_t *ingressLatency, int64_t *egressLatency,
int64_t *msgTPointLatency, int64_t *delayAsymmetry,
......
......@@ -21,9 +21,11 @@ typedef uint8_t Octet;
typedef int8_t Integer8;
typedef int16_t Integer16;
typedef int32_t Integer32;
typedef int64_t Integer64;
typedef uint8_t UInteger8;
typedef uint16_t UInteger16;
typedef uint32_t UInteger32;
typedef uint64_t UInteger64;
/* Enumerations are unsigned, see 5.4.2, page 15 */
typedef uint16_t Enumeration16;
typedef uint8_t Enumeration8;
......@@ -38,23 +40,25 @@ typedef struct UInteger48 {
uint16_t msb;
} UInteger48;
typedef struct Integer64 {
typedef struct _Integer64 { /* TODO : Should be replaced by Integer64 */
uint32_t lsb;
int32_t msb;
} Integer64;
} _Integer64;
typedef struct UInteger64 {
typedef struct _UInteger64 { /*/* TODO : Should be replaced by UInteger64 */
uint32_t lsb;
uint32_t msb;
} UInteger64;
} _UInteger64;
struct TimeInterval { /* page 12 (32) -- never used */
Integer64 scaledNanoseconds;
};
/* Page 19 :the time interval is expressed in units of nanoseconds and multiplied by 2 +16 */
#define TIME_INTERVAL_FRACBITS 16
#define TIME_INTERVAL_FRACBITS_AS_FLOAT 16.0
typedef Integer64 TimeInterval;
/* White Rabbit extension */
typedef struct FixedDelta {
UInteger64 scaledPicoseconds;
_UInteger64 scaledPicoseconds;
} FixedDelta;
typedef struct Timestamp { /* page 13 (33) -- no typedef expected */
......@@ -62,6 +66,17 @@ typedef struct Timestamp { /* page 13 (33) -- no typedef expected */
UInteger32 nanosecondsField;
} Timestamp;
/** ******************* IEEE1588-2018 **************************************/
#define REL_DIFF_FRACBITS 62
#define REL_DIFF_FRACBITS_AS_FLOAT 62.0
/*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
* fractional part truncated. */
typedef Integer64 RelativeDifference;
typedef struct ClockIdentity { /* page 13 (33) */
Octet id[8];
} ClockIdentity;
......@@ -179,7 +194,7 @@ typedef struct MsgSignaling {
} MsgSignaling;
/* Management Message (table 37, page 137) */
typedef struct MsgManagement{
typedef struct {
PortIdentity targetPortIdentity;
UInteger8 startingBoundaryHops;
UInteger8 boundaryHops;
......@@ -188,7 +203,7 @@ typedef struct MsgManagement{
} MsgManagement;
/* Default Data Set */
typedef struct DSDefault { /* page 65 */
typedef struct { /* page 65 */
/* Static */
Boolean twoStepFlag;
ClockIdentity clockIdentity;
......@@ -200,21 +215,29 @@ typedef struct DSDefault { /* page 65 */
UInteger8 priority2;
UInteger8 domainNumber;
Boolean slaveOnly;
} DSDefault;
/** Optional (IEEE1588-2018) */
Timestamp currentTime; /*draft P1588_v_29: page 85*/
Boolean instanceEnable; /*draft P1588_v_29: page 86*/
Enumeration8 externalPortConfigurationEnabled; /*draft P1588_v_29: page 86*/
Enumeration8 maxStepsRemoved; /*draft P1588_v_29: page 86 (bug)*/
Enumeration8 SdoId; /*draft P1588_v_29: page 86 (bug)*/
Enumeration8 instanceType; /*draft P1588_v_29: page 86 */
/** *********************** */
} defaultDS_t;
/* Current Data Set */
typedef struct DSCurrent { /* page 67 */
typedef struct { /* page 67 */
/* Dynamic */
UInteger16 stepsRemoved;
struct pp_time offsetFromMaster;
struct pp_time meanPathDelay; /* oneWayDelay */
TimeInterval offsetFromMaster; /* page 112 */
TimeInterval meanDelay; /* page 112 : one Way Delay */
/* White Rabbit extension begin */
UInteger16 primarySlavePortNumber;
/* White Rabbit extension end */
} DSCurrent;
} currentDS_t;
/* Parent Data Set */
typedef struct DSParent { /* page 68 */
typedef struct { /* page 68 */
/* Dynamic */
PortIdentity parentPortIdentity;
/* Boolean parentStats; -- not used */
......@@ -224,10 +247,10 @@ typedef struct DSParent { /* page 68 */
ClockQuality grandmasterClockQuality;
UInteger8 grandmasterPriority1;
UInteger8 grandmasterPriority2;
} DSParent;
} parentDS_t;
/* Port Data set */
typedef struct DSPort { /* page 72 */
typedef struct { /* page 72 */
/* Static */
PortIdentity portIdentity;
/* Dynamic */
......@@ -241,10 +264,18 @@ typedef struct DSPort { /* page 72 */
UInteger4 versionNumber;
void *ext_dsport;
} DSPort;
/** (IEEE1588-2018) */
Integer8 logMinPdelayReqInterval; /*draft P1588_v_29: page 124 */
UInteger4 minorVersionNumber; /*draft P1588_v_29: page 124 */
TimeInterval delayAsymmetry; /*draft P1588_v_29: page 124 */
/** Optional: */
Boolean portEnable; /*draft P1588_v_29: page 124 */
Boolean masterOnly; /*draft P1588_v_29: page 124 */
/** *********************** */
} portDS_t;
/* Time Properties Data Set */
typedef struct DSTimeProperties { /* page 70 */
typedef struct { /* page 70 */
/* Dynamic */
Integer16 currentUtcOffset;
Boolean currentUtcOffsetValid;
......@@ -254,8 +285,54 @@ typedef struct DSTimeProperties { /* page 70 */
Boolean frequencyTraceable;
Boolean ptpTimescale;
Enumeration8 timeSource;
} DSTimeProperties;
} timePropertiesDS_t;
/** ******************* IEEE1588-2018 **************************************
* Adding new optional data sets (DS) defined in clause, only these relevant
* for HA
*/
typedef struct { /*draft P1588_v_29: page 118 */
Octet manufacturerIdentity[3];
struct PTPText productDescription;
struct PTPText productRevision;
struct PTPText userDescription;
} descriptionDS_t;
/* Optional, not implemented, Instance DS:
* faultLogDS: draft P1588_v_29: page 93
* nonvolatileStorageDS draft P1588_v_29: page 94
* pathTraceDS draft P1588_v_29: page 95
* alternateTimescaleOffsetsDS draft P1588_v_29: page 95
* holdoverUpgradeDS draft P1588_v_29: page 95
* grandmasterClusterDS draft P1588_v_29: page 95
* acceptableMasterTableDS draft P1588_v_29: page 95
* clockPerformanceMonitoringDS draft P1588_v_29: page 95
*
* Optional, not implemented, port DS
* descriptionPortDS draft P1588_v_29: page 99
* unicastNegotiationDS draft P1588_v_29: page 100
* alternateMasterDS draft P1588_v_29: page 100
* unicastDiscoveryDS draft P1588_v_29: page 100
* acceptableMasterPortDS draft P1588_v_29: page 100
* performanceMonitoringPortDS draft P1588_v_29: page 101
*
* For Transparent Clocks, not implemented
* transparentClockDefaultDS draft P1588_v_29: page 102
* transparentClockPortDS draft P1588_v_29: page 103
*/
typedef struct { /*draft P1588_v_29: page 128*/
TimeInterval egressLatency;
TimeInterval ingressLatency;
TimeInterval messageTimestampPointLatency;
/* Not in specification */
TimeInterval semistaticLatency;
} timestampCorrectionPortDS_t;
typedef struct { /*draft P1588_v_29: page129*/
TimeInterval constantAsymmetry;
RelativeDifference scaledDelayCoefficient;
} asymmetryCorrectionPortDS_t;
/** ************************************************************************/
/* Enumeration States (table 8, page 73) */
enum pp_std_states {
PPS_END_OF_TABLE = 0,
......@@ -286,6 +363,7 @@ enum pp_std_messages {
/* NO_MESSAGE means "no message received", or "eaten by hook" */
PPM_NO_MESSAGE,
PPM_NOTHING_TO_DO = 0x100, /* for hooks.master_msg() */
};
/* Enumeration Domain Number (table 2, page 41) */
......@@ -318,11 +396,13 @@ enum ENTimeSource {
INTERNAL_OSCILLATOR = 0xA0
};
/* Enumeration Delay mechanism (table 9, page 74) */
/* Enumeration Delay mechanism (table 21, page 126) */
enum ENDelayMechanism {
E2E = 1,
P2P = 2,
DELAY_DISABLED = 0xFE
COMMON_P2P = 3,
SPECIAL = 4,
NO_MECHANISM = 0xFE
};
#endif /* __PPSI_IEEE_1588_TYPES_H__ */
......@@ -20,11 +20,11 @@ struct pp_runtime_opts {
int flags; /* see below */
Integer16 ap, ai;
Integer16 s;
Integer8 announce_intvl;
int sync_intvl;
int prio1;
int prio2;
int domain_number;
Integer8 logAnnounceInterval;
int logSyncInterval;
int priority1;
int priority2;
int domainNumber;
void *arch_opts;
};
......@@ -89,7 +89,7 @@ struct pp_frgn_master {
* machine are implemented.
*
* pp_avg_fltr: It is a variable cutoff/delay low-pass, infinite impulse
* response (IIR) filter. The meanPathDelay filter has the difference equation:
* response (IIR) filter. The meanDelay filter has the difference equation:
* s*y[n] - (s-1)*y[n-1] = x[n]/2 + x[n-1]/2,
* where increasing the stiffness (s) lowers the cutoff and increases the delay.
*/
......@@ -99,11 +99,24 @@ struct pp_avg_fltr {
int64_t s_exp;
};
/* Servo flags for communication diagnostic tool */
#define PP_SERVO_FLAG_VALID (1<<0)
#define PP_SERVO_FLAG_WAIT_HW (1<<1)
struct pp_servo {
struct pp_time m_to_s_dly;
struct pp_time s_to_m_dly;
struct pp_time delayMS;
struct pp_time delaySM;
long long obs_drift;
struct pp_avg_fltr mpd_fltr;
struct pp_time meanDelay;
struct pp_time offsetFromMaster;
/* diagnostic data */
unsigned long flags; /* PP_SERVO_FLAG_INVALID, PP_SERVO_FLAG_VALID, ...*/
uint32_t update_count; /* incremented each time the servo is running */
char servo_state_name[32]; /* Updated by the servo itself */
int servo_locked; /* TRUE when servo is locked. This info can be used by HAL */
};
enum { /* The two sockets. They are called "net path" for historical reasons */
......@@ -119,8 +132,8 @@ enum { /* The two sockets. They are called "net path" for historical reasons */
struct pp_instance_cfg {
char port_name[16];
char iface_name[16];
int ext; /* 0: none, 1: whiterabbit. 2: HA */
int mech; /* 0: E2E, 1: P2P */
int profile; /* PPSI_PROFILE_PTP, PPSI_PROFILE_WR, PPSI_PROFILE_HA */
int delayMechanism; /* Should be enum ENDelayMechanism but forced to int for configuration parsing */
};
/*
......@@ -132,12 +145,13 @@ struct pp_instance {
struct pp_state_table_item *current_state_item;
void *arch_data; /* if arch needs it */
void *ext_data; /* if protocol ext needs it */
int protocol_extension; /* PPSI_EXT_NONE, PPSI_EXT_WR, PPSI_EXT_L1S */
struct pp_ext_hooks *ext_hooks; /* if protocol ext needs it */
unsigned long d_flags; /* diagnostics, ppi-specific flags */
unsigned char flags; /* protocol flags (see below) */
int role, /* same as in config file */
proto, /* same as in config file */
mech; /* same as in config file */
proto; /* same as in config file */
int delayMechanism; /* same as in config file */
/* Pointer to global instance owning this pp_instance*/
struct pp_globals *glbs;
......@@ -163,6 +177,7 @@ struct pp_instance {
/* Times, for the various offset computations */
struct pp_time t1, t2, t3, t4, t5, t6; /* *the* stamps */
Integer32 t4_cf, t6_cf;
uint64_t syncCF; /* transp. clocks */
struct pp_time last_rcv_time, last_snt_time; /* two temporaries */
......@@ -173,7 +188,13 @@ struct pp_instance {
Integer16 frgn_rec_best;
struct pp_frgn_master frgn_master[PP_NR_FOREIGN_RECORDS];
DSPort *portDS; /* page 72 */
portDS_t *portDS; /* page 72 */
/** (IEEE1588-2018) */
asymmetryCorrectionPortDS_t asymmetryCorrectionPortDS; /*draft P1588_v_29: page 99*/
timestampCorrectionPortDS_t timestampCorrectionPortDS; /*draft P1588_v_29: page 99*/
/** *********************** */
unsigned long timeouts[__PP_TO_ARRAY_SIZE];
UInteger16 recv_sync_sequence_id;
......@@ -215,10 +236,10 @@ struct pp_globals {
struct pp_runtime_opts *rt_opts;
/* Data sets */
DSDefault *defaultDS; /* page 65 */
DSCurrent *currentDS; /* page 67 */
DSParent *parentDS; /* page 68 */
DSTimeProperties *timePropertiesDS; /* page 70 */
defaultDS_t *defaultDS; /* page 65 */
currentDS_t *currentDS; /* page 67 */
parentDS_t *parentDS; /* page 68 */
timePropertiesDS_t *timePropertiesDS; /* page 70 */
/* Index of the pp_instance receiving the "Ebest" clock */
int ebest_idx;
......
......@@ -118,32 +118,32 @@ static inline struct pp_runtime_opts *OPTS(struct pp_instance *ppi)
return GOPTS(GLBS(ppi));
}
static inline struct DSDefault *GDSDEF(struct pp_globals *ppg)
static inline defaultDS_t *GDSDEF(struct pp_globals *ppg)
{
return ppg->defaultDS;
}
static inline struct DSDefault *DSDEF(struct pp_instance *ppi)
static inline defaultDS_t *DSDEF(struct pp_instance *ppi)
{
return GDSDEF(GLBS(ppi));
}
static inline struct DSCurrent *DSCUR(struct pp_instance *ppi)
static inline currentDS_t *DSCUR(struct pp_instance *ppi)
{
return GLBS(ppi)->currentDS;
}
static inline struct DSParent *DSPAR(struct pp_instance *ppi)
static inline parentDS_t *DSPAR(struct pp_instance *ppi)
{
return GLBS(ppi)->parentDS;
}
static inline struct DSPort *DSPOR(struct pp_instance *ppi)
static inline portDS_t *DSPOR(struct pp_instance *ppi)
{
return ppi->portDS;
}
static inline struct DSTimeProperties *DSPRO(struct pp_instance *ppi)
static inline timePropertiesDS_t *DSPRO(struct pp_instance *ppi)
{
return GLBS(ppi)->timePropertiesDS;
}
......@@ -173,7 +173,7 @@ extern void pp_prepare_pointers(struct pp_instance *ppi);
* allow NULL pointers.
*/
struct pp_ext_hooks {
int (*init)(struct pp_instance *ppg, void *buf, int len);
int (*init)(struct pp_instance *ppi, void *buf, int len);
int (*open)(struct pp_instance *ppi, struct pp_runtime_opts *rt_opts);
int (*close)(struct pp_instance *ppi);
int (*listening)(struct pp_instance *ppi, void *buf, int len);
......@@ -187,10 +187,12 @@ struct pp_ext_hooks {
int (*handle_followup)(struct pp_instance *ppi, struct pp_time *orig);
int (*handle_preq) (struct pp_instance * ppi);
int (*handle_presp) (struct pp_instance * ppi);
int (*handle_signaling) (struct pp_instance * ppi, void *buf, int len);
int (*pack_announce)(struct pp_instance *ppi);
void (*unpack_announce)(void *buf, MsgAnnounce *ann);
int (*state_decision)(struct pp_instance *ppi, int next_state);
void (*state_change)(struct pp_instance *ppi);
int (*run_ext_state_machine) (struct pp_instance *ppi);
};
/*
......@@ -318,7 +320,7 @@ struct pp_argline {
};
/* Below are macros for setting up pp_argline arrays */
#define OFFS(s,f) offsetof(struct s, f)
#define OFFS(s,f) offsetof(s, f)
#define OPTION(s,func,k,typ,a,field,i) \
{ \
......@@ -338,16 +340,23 @@ struct pp_argline {
}
#define INST_OPTION(func,k,t,a,field) \
OPTION(pp_instance,func,k,t,a,field,1)
OPTION(struct pp_instance,func,k,t,a,field,1)
#define INST_OPTION_INT(k,t,a,field) \
INST_OPTION(f_simple_int,k,t,a,field)
#define INST_OPTION_INT64(k,t,a,field) \
INST_OPTION(f_simple_int64,k,t,a,field)
#define INST_OPTION_DOUBLE(k,t,a,field) \
INST_OPTION(f_simple_double,k,t,a,field)
#define RT_OPTION(func,k,t,a,field) \
OPTION(pp_runtime_opts,func,k,t,a,field,0)
OPTION(struct pp_runtime_opts,func,k,t,a,field,0)
#define GLOB_OPTION(func,k,t,a,field) \
OPTION(pp_globals,func,k,t,a,field,0)
OPTION(struct pp_globals,func,k,t,a,field,0)
#define RT_OPTION_INT(k,t,a,field) \
RT_OPTION(f_simple_int,k,t,a,field)
......@@ -447,6 +456,15 @@ extern void normalize_pp_time(struct pp_time *t);
extern void pp_time_add(struct pp_time *t1, struct pp_time *t2);
extern void pp_time_sub(struct pp_time *t1, struct pp_time *t2);
extern void pp_time_div2(struct pp_time *t);
extern TimeInterval pp_time_to_interval(struct pp_time *ts);
extern TimeInterval picos_to_interval(int64_t picos);
/* Function for time conversion */
extern int64_t pp_time_to_picos(struct pp_time *ts);
extern void picos_to_pp_time(int64_t picos, struct pp_time *ts);
extern void pp_time_hardwarize(struct pp_time *time, int clock_period_ps,int32_t *ticks, int32_t *picos);
extern int64_t interval_to_picos(TimeInterval interval);
/*
* The state machine itself is an array of these structures.
......@@ -463,10 +481,13 @@ struct pp_state_table_item {
extern struct pp_state_table_item pp_state_table[]; /* 0-terminated */
/* Convert current state as a string value */
char *get_state_as_string(struct pp_instance *ppi, int state);
/* Standard state-machine functions */
extern pp_action pp_initializing, pp_faulty, pp_disabled, pp_listening,
pp_master, pp_passive, pp_uncalibrated,
pp_slave, pp_pclock;;
pp_slave, pp_pclock;
/* Enforce a state change */
extern int pp_leave_current_state(struct pp_instance *ppi);
......
......@@ -28,7 +28,7 @@ static struct cmd_line_opt cmd_line_list[] = {
{"-d STRING", "diagnostic level (see diag-macros.h)"},
CMD_LINE_SEPARATOR,
{"-t", "do not adjust the system clock"},
{"-w NUMBER", "specify meanPathDelay filter stiffness"},
{"-w NUMBER", "specify meanDelay filter stiffness"},
CMD_LINE_SEPARATOR,
//{"-u ADDRESS", "also send uni-cast to ADDRESS\n"}, -- FIXME: useful?
{"-g", "run as slave only"},
......
......@@ -217,20 +217,22 @@ static struct pp_argname arg_profile[] = {
{"ptp", PPSI_PROFILE_PTP},
#if CONFIG_PROFILE_WR == 1
{"whiterabbit", PPSI_PROFILE_WR},
{"wr", PPSI_PROFILE_WR},
#endif
#if CONFIG_PROFILE_HA == 1
{"highaccuracy", PPSI_PROFILE_WR},
{"highaccuracy", PPSI_PROFILE_HA},
{"ha", PPSI_PROFILE_HA},
#endif
{},
};
static struct pp_argname arg_mech[] = {
{"request-response", PP_E2E_MECH},
{"delay", PP_E2E_MECH},
{"e2e", PP_E2E_MECH},
static struct pp_argname arg_delayMechanism[] = {
{"request-response", E2E},
{"delay", E2E},
{"e2e", E2E},
#if CONFIG_HAS_P2P == 1
{"peer-delay", PP_P2P_MECH},
{"pdelay", PP_P2P_MECH},
{"p2p", PP_P2P_MECH},
{"peer-delay", P2P},
{"pdelay", P2P},
{"p2p", P2P},
#endif
{},
};
......@@ -241,9 +243,9 @@ static struct pp_argline pp_global_arglines[] = {
LEGACY_OPTION(f_if, "iface", ARG_STR),
INST_OPTION_INT("proto", ARG_NAMES, arg_proto, proto),
INST_OPTION_INT("role", ARG_NAMES, arg_role, role),
INST_OPTION_INT("extension", ARG_NAMES, arg_profile, cfg.ext), /* TODO: stay for backward compatibility. Should be removed in the future */
INST_OPTION_INT("profile", ARG_NAMES, arg_profile, cfg.ext),
INST_OPTION_INT("mechanism", ARG_NAMES, arg_mech, cfg.mech),
INST_OPTION_INT("extension", ARG_NAMES, arg_profile, cfg.profile), /* TODO: stay for backward compatibility. Should be removed in the future */
INST_OPTION_INT("profile", ARG_NAMES, arg_profile, cfg.profile),
INST_OPTION_INT("mechanism", ARG_NAMES, arg_delayMechanism, cfg.delayMechanism),
LEGACY_OPTION(f_vlan, "vlan", ARG_STR),
LEGACY_OPTION(f_diag, "diagnostic", ARG_STR),
RT_OPTION_INT("clock-class", ARG_INT, NULL, clock_quality.clockClass),
......
/*
* Copyright (C) 2011 CERN (www.cern.ch)
* Author: Aurelio Colosimo
* Based on PTPd project v. 2.1.0 (see AUTHORS for details)
* Author: Jean-Claude BAU
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*/
......@@ -59,3 +58,86 @@ void pp_time_div2(struct pp_time *t)
t->scaled_nsecs += sign * SNS_PER_S / 2;
t->secs >>= 1;
}
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);
}
void picos_to_pp_time(int64_t picos, struct pp_time *ts)
{
uint64_t sec, nsec;
int phase;
int sign = (picos < 0 ? -1 : 1);
picos *= sign;
nsec = picos;
phase = __div64_32(&nsec, 1000);
sec = nsec;
ts->scaled_nsecs = ((int64_t)__div64_32(&sec, PP_NSEC_PER_SEC)) << TIME_INTERVAL_FRACBITS;
ts->scaled_nsecs += (phase << TIME_INTERVAL_FRACBITS) / 1000;
ts->scaled_nsecs *= sign;
ts->secs = sec * sign;
}
/* "Hardwarizes" the timestamp - e.g. makes the nanosecond field a multiple
* of 8/16ns cycles and puts the extra nanoseconds in the picos result */
void pp_time_hardwarize(struct pp_time *time, int clock_period_ps,
int32_t *ticks, int32_t *picos)
{
int32_t s, ns, ps, clock_ns;
/* clock_period_ps *must* be a multiple of 1000 -- assert()? */
clock_ns = clock_period_ps / 1000;
/*
* In pp_time, both sec/nsec are positive, or both negative.
* Only 0 secs can have positive or negative nsecs.
*
* Here we need a positive count for both tick and picos. Or not.
* The code here replicates what found in original WR code.
*/
s = time->secs; /* a difference: known to fit 32 bits (really?) */
ps = time->scaled_nsecs & 0xffff; /* fractional nano */
ps = (ps * 1000) >> TIME_INTERVAL_FRACBITS; /* now picoseconds 0..999 -- positive*/
ns = time->scaled_nsecs >> TIME_INTERVAL_FRACBITS;
if (ns > 0) {
ps += (ns % clock_ns) * 1000;
ns -= (ns % clock_ns);
}
if (ns < 0) {
s--;
ns += PP_NSEC_PER_SEC;
}
if (s == -1 && ns > 0) {
s++;
ns -= PP_NSEC_PER_SEC;
}
if (ns < 0 && s == 0 && ns >= -clock_ns) {
/* originally, ns was a multiple of clock_ns, code differs */
ps += ns * 1000;
ns = 0;
}
*ticks = ns;
*picos = ps;
}
TimeInterval pp_time_to_interval(struct pp_time *ts)
{
return ((ts->secs * PP_NSEC_PER_SEC)<<TIME_INTERVAL_FRACBITS) + ts->scaled_nsecs ;
}
TimeInterval picos_to_interval(int64_t picos)
{
return (picos << TIME_INTERVAL_FRACBITS)/1000;
}
int64_t interval_to_picos(TimeInterval interval)
{
return (interval * 1000) >> TIME_INTERVAL_FRACBITS;
}
......@@ -10,9 +10,9 @@ static int wr_init(struct pp_instance *ppi, void *buf, int len)
pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
wrp->wrStateTimeout = WR_DEFAULT_STATE_TIMEOUT_MS;
wrp->calPeriod = WR_DEFAULT_CAL_PERIOD;
wrp->wrModeOn = 0;
wrp->head.extModeOn = 0;
wrp->parentWrConfig = NON_WR;
wrp->parentWrModeOn = 0;
wrp->parentExtModeOn = 0;
wrp->calibrated = !WR_DEFAULT_PHY_CALIBRATION_REQUIRED;
#ifdef CONFIG_ABSCAL
......@@ -38,7 +38,7 @@ static int wr_open(struct pp_instance *ppi, struct pp_runtime_opts *rt_opts)
{
pp_diag(NULL, ext, 2, "hook: %s\n", __func__);
if (ppi->cfg.ext == PPSI_EXT_WR) {
if (ppi->protocol_extension == PPSI_EXT_WR) {
switch (ppi->role) {
case PPSI_ROLE_MASTER:
WR_DSPOR(ppi)->wrConfig = WR_M_ONLY;
......@@ -71,25 +71,12 @@ static int wr_master_msg(struct pp_instance *ppi, void *buf, int len,
int msgtype)
{
MsgSignaling wrsig_msg;
struct pp_time *time = &ppi->last_rcv_time;
if (msgtype != PPM_NO_MESSAGE)
pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
switch (msgtype) {
/* This case is modified from the default one */
case PPM_DELAY_REQ:
msg_issue_delay_resp(ppi, time); /* no error check */
msgtype = PPM_NO_MESSAGE;
break;
case PPM_PDELAY_REQ:
/* nothing to do */
break;
if ( msgtype== PPM_SIGNALING ) {
/* This is missing in the standard protocol */
case PPM_SIGNALING:
msg_unpack_wrsig(ppi, buf, &wrsig_msg,
&(WR_DSPOR(ppi)->msgTmpWrMessageID));
if ((WR_DSPOR(ppi)->msgTmpWrMessageID == SLAVE_PRESENT) &&
......@@ -98,7 +85,6 @@ static int wr_master_msg(struct pp_instance *ppi, void *buf, int len,
wr_handshake_init(ppi, PPS_MASTER);
}
msgtype = PPM_NO_MESSAGE;
break;
}
return msgtype;
......@@ -113,7 +99,7 @@ static int wr_new_slave(struct pp_instance *ppi, void *buf, int len)
static int wr_handle_resp(struct pp_instance *ppi)
{
struct pp_time *ofm = &DSCUR(ppi)->offsetFromMaster;
struct pp_time *ofm = &SRV(ppi)->offsetFromMaster;
struct wr_dsport *wrp = WR_DSPOR(ppi);
pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
......@@ -125,7 +111,7 @@ static int wr_handle_resp(struct pp_instance *ppi)
* After we adjusted the pps counter, stamps are invalid, so
* we'll have the Unix time instead, marked by "correct"
*/
if (!wrp->wrModeOn) {
if (!wrp->head.extModeOn) {
if (is_incorrect(&ppi->t2) || is_incorrect(&ppi->t3)) {
pp_diag(ppi, servo, 1,
"T2 or T3 incorrect, discarding tuple\n");
......@@ -135,10 +121,7 @@ static int wr_handle_resp(struct pp_instance *ppi)
/*
* pps always on if offset less than 1 second,
* until ve have a configurable threshold */
if (ofm->secs)
WRH_OPER()->enable_timing_output(ppi, 0);
else
WRH_OPER()->enable_timing_output(ppi, 1);
WRH_OPER()->enable_timing_output(ppi, ofm->secs==0);
}
wr_servo_got_delay(ppi);
......@@ -152,7 +135,7 @@ static void wr_s1(struct pp_instance *ppi, struct pp_frgn_master *frgn_master)
pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
WR_DSPOR(ppi)->parentIsWRnode =
((frgn_master->ext_specific & WR_NODE_MODE) != NON_WR);
WR_DSPOR(ppi)->parentWrModeOn =
WR_DSPOR(ppi)->parentExtModeOn =
(frgn_master->ext_specific & WR_IS_WR_MODE) ? TRUE : FALSE;
WR_DSPOR(ppi)->parentCalibrated =
((frgn_master->ext_specific & WR_IS_CALIBRATED) ? 1 : 0);
......@@ -171,7 +154,7 @@ int wr_execute_slave(struct pp_instance *ppi)
if ((ppi->state == PPS_SLAVE) &&
(WR_DSPOR(ppi)->wrConfig & WR_S_ONLY) &&
(WR_DSPOR(ppi)->parentWrConfig & WR_M_ONLY) &&
(!WR_DSPOR(ppi)->wrModeOn || !WR_DSPOR(ppi)->parentWrModeOn)) {
(!WR_DSPOR(ppi)->head.extModeOn || !WR_DSPOR(ppi)->parentExtModeOn)) {
/* We must start the handshake as a WR slave */
wr_handshake_init(ppi, PPS_SLAVE);
}
......@@ -208,12 +191,12 @@ static int wr_handle_followup(struct pp_instance *ppi,
struct pp_time *t1) /* t1 == &ppi->t1 */
{
pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
if (!WR_DSPOR(ppi)->wrModeOn)
if (!WR_DSPOR(ppi)->head.extModeOn)
return 0;
wr_servo_got_sync(ppi, t1, &ppi->t2);
if (CONFIG_HAS_P2P && ppi->mech == PP_P2P_MECH)
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P)
wr_servo_update(ppi);
return 1; /* the caller returns too */
......@@ -222,7 +205,7 @@ static int wr_handle_followup(struct pp_instance *ppi,
static __attribute__((used)) int wr_handle_presp(struct pp_instance *ppi)
{
struct wr_dsport *wrp = WR_DSPOR(ppi);
struct pp_time *ofm = &DSCUR(ppi)->offsetFromMaster;
struct pp_time *ofm = &SRV(ppi)->offsetFromMaster;
/*
* If no WR mode is on, run normal code, if T2/T3 are valid.
......@@ -230,7 +213,7 @@ static __attribute__((used)) int wr_handle_presp(struct pp_instance *ppi)
* we'll have the Unix time instead, marked by "correct"
*/
if (!wrp->wrModeOn) {
if (!wrp->head.extModeOn) {
if (is_incorrect(&ppi->t3) || is_incorrect(&ppi->t6)) {
pp_diag(ppi, servo, 1,
"T3 or T6 incorrect, discarding tuple\n");
......@@ -240,10 +223,7 @@ static __attribute__((used)) int wr_handle_presp(struct pp_instance *ppi)
/*
* pps always on if offset less than 1 second,
* until ve have a configurable threshold */
if (ofm->secs)
WRH_OPER()->enable_timing_output(ppi, 0);
else
WRH_OPER()->enable_timing_output(ppi, 1);
WRH_OPER()->enable_timing_output(ppi, ofm->secs==0);
return 0;
}
......@@ -320,15 +300,15 @@ static void wr_state_change(struct pp_instance *ppi)
/* if we are leaving the WR locked states reset the WR process */
if ((ppi->next_state != ppi->state) &&
(wrp->wrModeOn == TRUE) &&
(wrp->head.extModeOn == TRUE) &&
((ppi->state == PPS_SLAVE) ||
(ppi->state == PPS_MASTER))) {
wrp->wrStateTimeout = WR_DEFAULT_STATE_TIMEOUT_MS;
wrp->calPeriod = WR_DEFAULT_CAL_PERIOD;
wrp->wrModeOn = FALSE;
wrp->head.extModeOn = FALSE;
wrp->parentWrConfig = NON_WR;
wrp->parentWrModeOn = FALSE;
wrp->parentExtModeOn = FALSE;
wrp->calibrated = !WR_DEFAULT_PHY_CALIBRATION_REQUIRED;
if (ppi->state == PPS_SLAVE)
......
......@@ -44,23 +44,23 @@ int wr_calibration(struct pp_instance *ppi, void *buf, int len)
case WR_PORT_CALIBRATION_0:
/* enable pattern sending */
if (WRH_OPER()->calib_pattern_enable(ppi, 0, 0, 0) ==
WR_HW_CALIB_OK)
WRH_HW_CALIB_OK)
wrp->wrPortState = WR_PORT_CALIBRATION_1;
else
break;
case WR_PORT_CALIBRATION_1:
/* enable Tx calibration */
if (WRH_OPER()->calib_enable(ppi, WR_HW_CALIB_TX)
== WR_HW_CALIB_OK)
if (WRH_OPER()->calib_enable(ppi, WRH_HW_CALIB_TX)
== WRH_HW_CALIB_OK)
wrp->wrPortState = WR_PORT_CALIBRATION_2;
else
break;
case WR_PORT_CALIBRATION_2:
/* wait until Tx calibration is finished */
if (WRH_OPER()->calib_poll(ppi, WR_HW_CALIB_TX, &delta) ==
WR_HW_CALIB_READY) {
if (WRH_OPER()->calib_poll(ppi, WRH_HW_CALIB_TX, &delta) ==
WRH_HW_CALIB_READY) {
wrp->deltaTx.scaledPicoseconds.msb =
0xFFFFFFFF & (((uint64_t)delta) >> 16);
wrp->deltaTx.scaledPicoseconds.lsb =
......@@ -77,31 +77,31 @@ int wr_calibration(struct pp_instance *ppi, void *buf, int len)
case WR_PORT_CALIBRATION_3:
/* disable Tx calibration */
if (WRH_OPER()->calib_disable(ppi, WR_HW_CALIB_TX)
== WR_HW_CALIB_OK)
if (WRH_OPER()->calib_disable(ppi, WRH_HW_CALIB_TX)
== WRH_HW_CALIB_OK)
wrp->wrPortState = WR_PORT_CALIBRATION_4;
else
break;
case WR_PORT_CALIBRATION_4:
/* disable pattern sending */
if (WRH_OPER()->calib_pattern_disable(ppi) == WR_HW_CALIB_OK)
if (WRH_OPER()->calib_pattern_disable(ppi) == WRH_HW_CALIB_OK)
wrp->wrPortState = WR_PORT_CALIBRATION_5;
else
break;
case WR_PORT_CALIBRATION_5:
/* enable Rx calibration using the pattern sent by other port */
if (WRH_OPER()->calib_enable(ppi, WR_HW_CALIB_RX) ==
WR_HW_CALIB_OK)
if (WRH_OPER()->calib_enable(ppi, WRH_HW_CALIB_RX) ==
WRH_HW_CALIB_OK)
wrp->wrPortState = WR_PORT_CALIBRATION_6;
else
break;
case WR_PORT_CALIBRATION_6:
/* wait until Rx calibration is finished */
if (WRH_OPER()->calib_poll(ppi, WR_HW_CALIB_RX, &delta) ==
WR_HW_CALIB_READY) {
if (WRH_OPER()->calib_poll(ppi, WRH_HW_CALIB_RX, &delta) ==
WRH_HW_CALIB_READY) {
pp_diag(ppi, ext, 1, "Rx fixed delay = %d\n", (int)delta);
wrp->deltaRx.scaledPicoseconds.msb =
0xFFFFFFFF & (delta >> 16);
......@@ -119,8 +119,8 @@ int wr_calibration(struct pp_instance *ppi, void *buf, int len)
case WR_PORT_CALIBRATION_7:
/* disable Rx calibration */
if (WRH_OPER()->calib_disable(ppi, WR_HW_CALIB_RX)
== WR_HW_CALIB_OK)
if (WRH_OPER()->calib_disable(ppi, WRH_HW_CALIB_RX)
== WRH_HW_CALIB_OK)
wrp->wrPortState = WR_PORT_CALIBRATION_8;
else
break;
......
......@@ -18,13 +18,13 @@ int wr_link_on(struct pp_instance *ppi, void *buf, int len)
struct wr_dsport *wrp = WR_DSPOR(ppi);
int e = 0;
wrp->wrModeOn = TRUE;
wrp->head.extModeOn = TRUE;
WRH_OPER()->enable_ptracker(ppi);
if (wrp->wrMode == WR_MASTER)
e = msg_issue_wrsig(ppi, WR_MODE_ON);
wrp->parentWrModeOn = TRUE;
wrp->parentExtModeOn = TRUE;
if (e != 0)
return -1;
......
......@@ -34,10 +34,10 @@ int wr_s_lock(struct pp_instance *ppi, void *buf, int len)
ppi->next_delay = wrp->wrStateTimeout;
poll_ret = WRH_OPER()->locking_poll(ppi, 0);
if (poll_ret == WR_SPLL_READY) {
if (poll_ret == WRH_SPLL_READY) {
ppi->next_state = WRS_LOCKED;
WRH_OPER()->locking_disable(ppi);
} else if (poll_ret == WR_SPLL_CALIB_NOT_READY) {
} else if (poll_ret == WRH_SPLL_CALIB_NOT_READY) {
/* rxts_calibration not ready, enter the same state without
* a delay */
ppi->next_delay = 0;
......
......@@ -9,14 +9,19 @@
#ifndef __WREXT_WR_API_H__
#define __WREXT_WR_API_H__
/* Please increment WRS_PPSI_SHMEM_VERSION if you change any exported data
* structure */
#define WRS_PPSI_SHMEM_VERSION 31 /* changed wrs_shm_head */
#if CONFIG_EXT_WR == 1
#define PROTO_EXT_WR (1)
#else
#define PROTO_EXT_WR (0)
#endif
#if CONFIG_EXT_WR == 1
/* Don't include the Following when this file is included in assembler. */
#ifndef __ASSEMBLY__
#include <ppsi/lib.h>
#include <wrh/wrh.h>
#include "../include/hw-specific/wrh.h"
#include "wr-constants.h"
/*
......@@ -24,15 +29,20 @@
* (see wrspec.v2-06-07-2011, page 17)
*/
struct wr_dsport {
wrh_portds_head_t head; /* Must on top of portDS */
Boolean parentExtModeOn;
FixedDelta deltaTx;
FixedDelta deltaRx;
FixedDelta otherNodeDeltaTx;
FixedDelta otherNodeDeltaRx;
Boolean doRestart;
Enumeration8 wrConfig;
Enumeration8 wrMode;
Boolean wrModeOn;
Boolean ppsOutputOn;
Enumeration8 wrPortState; /* used for sub-states during calibration */
/* FIXME check doc: knownDeltaTx, knownDeltaRx, deltasKnown?) */
Boolean calibrated;
FixedDelta deltaTx;
FixedDelta deltaRx;
UInteger32 wrStateTimeout;
UInteger8 wrStateRetry;
UInteger32 calPeriod; /* microseconsds, never changed */
......@@ -41,16 +51,12 @@ struct wr_dsport {
Boolean parentIsWRnode; /* FIXME Not in the doc */
/* FIXME check doc: (parentWrMode?) */
Enumeration16 msgTmpWrMessageID; /* FIXME Not in the doc */
Boolean parentWrModeOn;
Boolean parentCalibrated;
/* FIXME: are they in the doc? */
UInteger16 otherNodeCalSendPattern;
UInteger32 otherNodeCalPeriod;/* microseconsds, never changed */
UInteger8 otherNodeCalRetry;
FixedDelta otherNodeDeltaTx;
FixedDelta otherNodeDeltaRx;
Boolean doRestart;
};
/* This uppercase name matches "DSPOR(ppi)" used by standard protocol */
......@@ -111,33 +117,23 @@ int wr_servo_got_delay(struct pp_instance *ppi);
int wr_servo_update(struct pp_instance *ppi);
struct wr_servo_state {
struct wrh_servo_head servo_head; /* Must be on top of the structure */
char if_name[16]; /* Informative, for the monitoring tool through shmem */
unsigned long flags;
#define WR_FLAG_VALID 1
#define WR_FLAG_WAIT_HW 2
int state;
/* These fields are used by servo code, after asetting at init time */
int32_t delta_tx_m;
int32_t delta_rx_m;
int32_t delta_tx_s;
int32_t delta_rx_s;
int32_t delta_txm_ps;
int32_t delta_rxm_ps;
int32_t delta_txs_ps;
int32_t delta_rxs_ps;
int32_t fiber_fix_alpha;
int32_t clock_period_ps;
/* Following fields are for monitoring/diagnostics (use w/ shmem) */
struct pp_time mu;
int64_t picos_mu;
struct pp_time delayMM;
int64_t delayMM_ps;
int32_t cur_setpoint;
int64_t delta_ms;
uint32_t update_count;
int64_t delayMS_ps;
int tracking_enabled;
char servo_state_name[32];
int64_t skew;
int64_t offset;
/* Values used by snmp. Values are increased at servo update when
* erroneous condition occurs. */
......@@ -148,16 +144,10 @@ struct wr_servo_state {
/* These fields are used by servo code, across iterations */
struct pp_time t1, t2, t3, t4, t5, t6;
int64_t delta_ms_prev;
int64_t prev_delayMS_ps;
int missed_iters;
};
int wr_p2p_delay(struct pp_instance *ppi, struct wr_servo_state *s);
int wr_e2e_offset(struct pp_instance *ppi,
struct wr_servo_state *s, struct pp_time *ts_offset_hw);
int wr_p2p_offset(struct pp_instance *ppi,
struct wr_servo_state *s, struct pp_time *ts_offset_hw);
/* All data used as extension ppsi-wr must be put here */
struct wr_data {
......@@ -165,5 +155,7 @@ struct wr_data {
};
extern struct pp_ext_hooks wr_ext_hooks;
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_EXT_WR == 1*/
#endif /* __WREXT_WR_API_H__ */
......@@ -17,7 +17,9 @@
#define WR_IS_WR_MODE 0x08
#define WR_NODE_MODE 0x03 /* a mask, see NON_WR etc below */
# define WR_TLV_TYPE 0x2004
#define WR_TLV_TYPE 0x2004
#define FIX_ALPHA_FRACBITS 40
#define WR_DEFAULT_CAL_PERIOD 3000 /* [us] */
......@@ -48,20 +50,6 @@
#define WR_DEFAULT_PHY_CALIBRATION_REQUIRED FALSE
/* White Rabbit softpll status values */
#define WR_SPLL_OK 0
#define WR_SPLL_READY 1
#define WR_SPLL_CALIB_NOT_READY 2
#define WR_SPLL_ERROR -1
/* White Rabbit calibration defines */
#define WR_HW_CALIB_TX 1
#define WR_HW_CALIB_RX 2
#define WR_HW_CALIB_OK 0
#define WR_HW_CALIB_READY 1
#define WR_HW_CALIB_ERROR -1
#define WR_HW_CALIB_NOT_FOUND -3
/* Indicates if a port is configured as White Rabbit, and what kind
* (master/slave) */
enum {
......
......@@ -78,7 +78,7 @@ void msg_pack_announce_wr_tlv(struct pp_instance *ppi)
if (WR_DSPOR(ppi)->calibrated)
wr_flags = WR_IS_CALIBRATED | wr_flags;
if (WR_DSPOR(ppi)->wrModeOn)
if (WR_DSPOR(ppi)->head.extModeOn)
wr_flags = WR_IS_WR_MODE | wr_flags;
*(UInteger16 *)(buf + 76) = htons(wr_flags);
}
......@@ -111,16 +111,25 @@ void msg_unpack_announce_wr_tlv(void *buf, MsgAnnounce *ann)
ann->ext_specific = 0;
}
static inline int32_t delta_to_ps(struct FixedDelta d)
{
_UInteger64 *sps = &d.scaledPicoseconds; /* ieee type :( */
return (sps->lsb >> 16) | (sps->msb << 16);
}
/* White Rabbit: packing WR Signaling messages*/
int msg_pack_wrsig(struct pp_instance *ppi, Enumeration16 wr_msg_id)
{
void *buf;
UInteger16 len = 0;
struct wr_dsport *wrp = WR_DSPOR(ppi);
struct wr_servo_state *s =&((struct wr_data *)ppi->ext_data)->servo_state;
if ((WR_DSPOR(ppi)->wrMode == NON_WR) || (wr_msg_id == ANN_SUFIX)) {
if ( (wrp->wrMode == NON_WR) || (wr_msg_id == ANN_SUFIX)) {
pp_diag(ppi, frames, 1,
"BUG: Trying to send invalid wr_msg mode=%x id=%x",
WR_DSPOR(ppi)->wrMode, wr_msg_id);
wrp->wrMode, wr_msg_id);
return 0;
}
......@@ -152,7 +161,7 @@ int msg_pack_wrsig(struct pp_instance *ppi, Enumeration16 wr_msg_id)
switch (wr_msg_id) {
case CALIBRATE:
if (WR_DSPOR(ppi)->calibrated) {
if (wrp->calibrated) {
put_be16(buf+56,
(WR_DSPOR(ppi)->calRetry | 0x0000));
} else {
......@@ -165,14 +174,20 @@ int msg_pack_wrsig(struct pp_instance *ppi, Enumeration16 wr_msg_id)
case CALIBRATED: /* new fsm */
/* delta TX */
put_be32(buf+56, WR_DSPOR(ppi)->deltaTx.scaledPicoseconds.msb);
put_be32(buf+60, WR_DSPOR(ppi)->deltaTx.scaledPicoseconds.lsb);
put_be32(buf+56, wrp->deltaTx.scaledPicoseconds.msb);
put_be32(buf+60, wrp->deltaTx.scaledPicoseconds.lsb);
/* delta RX */
put_be32(buf+64, WR_DSPOR(ppi)->deltaRx.scaledPicoseconds.msb);
put_be32(buf+68, WR_DSPOR(ppi)->deltaRx.scaledPicoseconds.lsb);
put_be32(buf+64, wrp->deltaRx.scaledPicoseconds.msb);
put_be32(buf+68, wrp->deltaRx.scaledPicoseconds.lsb);
len = 24;
/*JCB: Hack. serrvo_init() called too early. PTP state machine must be modify. */
/* We should stay in UNCALIBRATED state during WR protocol */
s->delta_txm_ps = delta_to_ps(wrp->otherNodeDeltaTx);
s->delta_rxm_ps = delta_to_ps(wrp->otherNodeDeltaRx);
s->delta_txs_ps = delta_to_ps(wrp->deltaTx);
s->delta_rxs_ps = delta_to_ps(wrp->deltaRx);
break;
default:
......@@ -198,6 +213,8 @@ void msg_unpack_wrsig(struct pp_instance *ppi, void *buf,
UInteger16 tlv_magicNumber;
UInteger16 tlv_versionNumber;
Enumeration16 wr_msg_id;
struct wr_dsport *wrp = WR_DSPOR(ppi);
struct wr_servo_state *s =&((struct wr_data *)ppi->ext_data)->servo_state;
memcpy(&wrsig_msg->targetPortIdentity.clockIdentity, (buf + 34),
PP_CLOCK_IDENTITY_LENGTH);
......@@ -244,11 +261,11 @@ void msg_unpack_wrsig(struct pp_instance *ppi, void *buf,
switch (wr_msg_id) {
case CALIBRATE:
WR_DSPOR(ppi)->otherNodeCalSendPattern =
wrp->otherNodeCalSendPattern =
0x00FF & (get_be16(buf+56) >> 8);
WR_DSPOR(ppi)->otherNodeCalRetry =
wrp->otherNodeCalRetry =
0x00FF & get_be16(buf+56);
WR_DSPOR(ppi)->otherNodeCalPeriod = get_be32(buf+58);
wrp->otherNodeCalPeriod = get_be32(buf+58);
pp_diag(ppi, frames, 1, "otherNodeCalPeriod "
"from frame = 0x%x | stored = 0x%x \n", get_be32(buf+58),
......@@ -258,16 +275,20 @@ void msg_unpack_wrsig(struct pp_instance *ppi, void *buf,
case CALIBRATED:
/* delta TX */
WR_DSPOR(ppi)->otherNodeDeltaTx.scaledPicoseconds.msb =
wrp->otherNodeDeltaTx.scaledPicoseconds.msb =
get_be32(buf+56);
WR_DSPOR(ppi)->otherNodeDeltaTx.scaledPicoseconds.lsb =
wrp->otherNodeDeltaTx.scaledPicoseconds.lsb =
get_be32(buf+60);
/* delta RX */
WR_DSPOR(ppi)->otherNodeDeltaRx.scaledPicoseconds.msb =
wrp->otherNodeDeltaRx.scaledPicoseconds.msb =
get_be32(buf+64);
WR_DSPOR(ppi)->otherNodeDeltaRx.scaledPicoseconds.lsb =
wrp->otherNodeDeltaRx.scaledPicoseconds.lsb =
get_be32(buf+68);
/*JCB: Hack. serrvo_init() called too early. PTP state machine must be modify. */
/* We should stay in UNCALIBRATED state during WR protocol */
s->delta_txm_ps = delta_to_ps(wrp->otherNodeDeltaTx);
s->delta_rxm_ps = delta_to_ps(wrp->otherNodeDeltaRx);
break;
default:
......
This diff is collapsed.
......@@ -15,7 +15,6 @@ OBJ-y += $D/fsm-table.o \
$D/common-fun.o \
$D/bmc.o \
$D/msg.o \
$D/arith.o \
$D/servo.o \
$D/hooks.o \
$D/open-close.o
......@@ -24,18 +24,20 @@
/* ppi->port_idx port is becoming Master. Table 13 (9.3.5) of the spec. */
void bmc_m1(struct pp_instance *ppi)
{
struct DSParent *parent = DSPAR(ppi);
struct DSDefault *defds = DSDEF(ppi);
struct DSTimeProperties *prop = DSPRO(ppi);
parentDS_t *parent = DSPAR(ppi);
defaultDS_t *defds = DSDEF(ppi);
timePropertiesDS_t *prop = DSPRO(ppi);
int ret = 0;
int offset, leap59, leap61;
Boolean ptpTimescale;
Enumeration8 timeSource;
/* Current data set update */
DSCUR(ppi)->stepsRemoved = 0;
clear_time(&DSCUR(ppi)->offsetFromMaster);
clear_time(&DSCUR(ppi)->meanPathDelay);
DSCUR(ppi)->stepsRemoved =
DSCUR(ppi)->offsetFromMaster=
DSCUR(ppi)->meanDelay=0;
clear_time(&SRV(ppi)->meanDelay);
clear_time(&SRV(ppi)->offsetFromMaster);
/* Parent data set: we are the parent */
memset(parent, 0, sizeof(*parent));
......@@ -139,8 +141,8 @@ void bmc_m3(struct pp_instance *ppi)
void bmc_s1(struct pp_instance *ppi,
struct pp_frgn_master *frgn_master)
{
struct DSParent *parent = DSPAR(ppi);
struct DSTimeProperties *prop = DSPRO(ppi);
parentDS_t *parent = DSPAR(ppi);
timePropertiesDS_t *prop = DSPRO(ppi);
int ret = 0;
int offset, leap59, leap61;
int hours, minutes, seconds;
......@@ -573,7 +575,7 @@ static int bmc_state_decision(struct pp_instance *ppi)
int i;
int cmpres;
struct pp_frgn_master d0;
struct DSParent *parent = DSPAR(ppi);
parentDS_t *parent = DSPAR(ppi);
struct pp_globals *ppg = GLBS(ppi);
struct pp_instance *ppi_best;
struct pp_frgn_master *erbest = &ppi->frgn_master[ppi->frgn_rec_best];
......
This diff is collapsed.
......@@ -121,7 +121,7 @@ int st_com_peer_handle_pres(struct pp_instance *ppi, void *buf,
int e = 0;
/* if not in P2P mode, just return */
if (!CONFIG_HAS_P2P || ppi->mech != PP_P2P_MECH)
if (!CONFIG_HAS_P2P || ppi->delayMechanism != P2P)
return 0;
msg_unpack_pdelay_resp(buf, &resp);
......@@ -166,7 +166,7 @@ int st_com_peer_handle_pres_followup(struct pp_instance *ppi,
int e = 0;
/* if not in P2P mode, just return */
if (!CONFIG_HAS_P2P || ppi->mech != PP_P2P_MECH)
if (!CONFIG_HAS_P2P || ppi->delayMechanism != P2P)
return 0;
msg_unpack_pdelay_resp_follow_up(buf, &respFllw);
......@@ -197,7 +197,7 @@ int st_com_peer_handle_preq(struct pp_instance *ppi, void *buf,
int e = 0;
/* if not in P2P mode, just return */
if (!CONFIG_HAS_P2P || ppi->mech != PP_P2P_MECH)
if (!CONFIG_HAS_P2P || ppi->delayMechanism != P2P)
return 0;
if (ppi->ext_hooks->handle_preq)
......
......@@ -79,7 +79,7 @@ int pp_lib_may_issue_sync(struct pp_instance *ppi)
int pp_lib_may_issue_announce(struct pp_instance *ppi)
{
struct DSTimeProperties *prop = DSPRO(ppi);
timePropertiesDS_t *prop = DSPRO(ppi);
int ret = 0;
int offset, leap59, leap61;
int hours, minutes, seconds;
......
......@@ -138,7 +138,7 @@ void msg_unpack_sync(void *buf, MsgSync *sync)
*/
static void msg_set_announce_flags(struct pp_instance *ppi, UInteger8 *flags)
{
struct DSTimeProperties *prop = DSPRO(ppi);
timePropertiesDS_t *prop = DSPRO(ppi);
const Boolean *ptrs[] = {
&prop->leap61,
&prop->leap59,
......@@ -287,7 +287,7 @@ void msg_unpack_follow_up(void *buf, MsgFollowUp *flwup)
secs |= htonl(*(UInteger32 *) (buf + 36));
nsecs = htonl(*(UInteger32 *) (buf + 40));
/* cField add1ed by the caller, from already-converted header */
/* cField added by the caller, from already-converted header */
flwup->preciseOriginTimestamp.secs = secs;
flwup->preciseOriginTimestamp.scaled_nsecs = nsecs << 16;
}
......@@ -538,7 +538,7 @@ static int msg_issue_pdelay_req(struct pp_instance *ppi)
int msg_issue_request(struct pp_instance *ppi)
{
if (CONFIG_HAS_P2P && ppi->mech == PP_P2P_MECH)
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P)
return msg_issue_pdelay_req(ppi);
return msg_issue_delay_req(ppi);
}
......
......@@ -21,11 +21,11 @@ struct pp_runtime_opts __pp_default_rt_opts = {
.ap = PP_DEFAULT_AP,
.ai = PP_DEFAULT_AI,
.s = PP_DEFAULT_DELAY_S,
.announce_intvl = PP_DEFAULT_ANNOUNCE_INTERVAL,
.sync_intvl = PP_DEFAULT_SYNC_INTERVAL,
.prio1 = PP_DEFAULT_PRIORITY1,
.prio2 = PP_DEFAULT_PRIORITY2,
.domain_number = PP_DEFAULT_DOMAIN_NUMBER,
.logAnnounceInterval = PP_DEFAULT_ANNOUNCE_INTERVAL,
.logSyncInterval = PP_DEFAULT_SYNC_INTERVAL,
.priority1 = PP_DEFAULT_PRIORITY1,
.priority2 = PP_DEFAULT_PRIORITY2,
.domainNumber = PP_DEFAULT_DOMAIN_NUMBER,
.ttl = PP_DEFAULT_TTL,
};
......@@ -41,7 +41,7 @@ int pp_init_globals(struct pp_globals *ppg, struct pp_runtime_opts *pp_rt_opts)
* Initialize default data set
*/
int i,ret=0;
struct DSDefault *def = ppg->defaultDS;
defaultDS_t *def = ppg->defaultDS;
def->twoStepFlag = TRUE;
/* if ppg->nlinks == 0, let's assume that the 'pp_links style'
......@@ -63,9 +63,9 @@ int pp_init_globals(struct pp_globals *ppg, struct pp_runtime_opts *pp_rt_opts)
def->slaveOnly = 1; /* the for cycle below will set it to 0 if not
* ports are not all slave_only */
def->priority1 = rt_opts->prio1;
def->priority2 = rt_opts->prio2;
def->domainNumber = rt_opts->domain_number;
def->priority1 = rt_opts->priority1;
def->priority2 = rt_opts->priority2;
def->domainNumber = rt_opts->domainNumber;
for (i = 0; i < def->numberPorts; i++) {
struct pp_instance *ppi = INST(ppg, i);
......@@ -99,7 +99,7 @@ int pp_init_globals(struct pp_globals *ppg, struct pp_runtime_opts *pp_rt_opts)
int pp_close_globals(struct pp_globals *ppg)
{
int i,ret=0;;
struct DSDefault *def = ppg->defaultDS;
defaultDS_t *def = ppg->defaultDS;
for (i = 0; i < def->numberPorts; i++) {
struct pp_instance *ppi = INST(ppg, i);
......
......@@ -8,18 +8,36 @@
#include <ppsi/ppsi.h>
#ifdef CONFIG_ARCH_WRS
#include <libwr/shmem.h>
#define shmem_lock() wrs_shm_write(ppsi_head, WRS_SHM_WRITE_BEGIN);
#define shmem_unlock() wrs_shm_write(ppsi_head, WRS_SHM_WRITE_END);
extern struct wrs_shm_head *ppsi_head;
#else
#define shmem_lock()
#define shmem_unlock()
#endif
static void pp_servo_mpd_fltr(struct pp_instance *, struct pp_avg_fltr *,
struct pp_time *);
static int pp_servo_offset_master(struct pp_instance *, struct pp_time *,
struct pp_time *, struct pp_time *);
static int64_t pp_servo_pi_controller(struct pp_instance *, struct pp_time *);
static void _pp_servo_init(struct pp_instance *ppi);
void pp_servo_init(struct pp_instance *ppi)
{
int d;
shmem_lock(); /* Share memory locked */
_pp_servo_init(ppi);
shmem_unlock(); /* Share memory unlocked */
}
SRV(ppi)->mpd_fltr.s_exp = 0; /* clears meanPathDelay filter */
static void _pp_servo_init(struct pp_instance *ppi)
{
int d;
SRV(ppi)->mpd_fltr.s_exp = 0; /* clears meanDelay filter */
if (ppi->t_ops->init_servo) {
/* The system may pre-set us to keep current frequency */
......@@ -36,6 +54,9 @@ void pp_servo_init(struct pp_instance *ppi)
SRV(ppi)->obs_drift = 0;
}
SRV(ppi)->flags |= PP_SERVO_FLAG_VALID;
SRV(ppi)->update_count = 0;
pp_timeout_set(ppi, PP_TO_FAULT);
pp_diag(ppi, servo, 1, "Initialized: obs_drift %lli\n",
SRV(ppi)->obs_drift);
......@@ -57,27 +78,30 @@ static char *fmt_ppt(struct pp_time *t)
/* Called by slave and uncalib when we have t1 and t2 */
void pp_servo_got_sync(struct pp_instance *ppi)
{
struct pp_time *m_to_s_dly = &SRV(ppi)->m_to_s_dly;
struct pp_time *delayMS = &SRV(ppi)->delayMS;
/*
* calc 'master_to_slave_delay'; no correction field
* appears in the formulas because it's already merged with t1
*/
*m_to_s_dly = ppi->t2;
pp_time_sub(m_to_s_dly, &ppi->t1);
*delayMS = ppi->t2;
pp_time_sub(delayMS, &ppi->t1);
SRV(ppi)->update_count++;
}
/* Called by slave and uncalib when we have t1 and t2 */
void pp_servo_got_psync(struct pp_instance *ppi)
{
struct pp_time *m_to_s_dly = &SRV(ppi)->m_to_s_dly;
struct pp_time *mpd = &DSCUR(ppi)->meanPathDelay;
struct pp_time *ofm = &DSCUR(ppi)->offsetFromMaster;
struct pp_time *m_to_s_dly = &SRV(ppi)->delayMS;
struct pp_time *mpd = &SRV(ppi)->meanDelay;
struct pp_time *ofm = &SRV(ppi)->offsetFromMaster;
int adj32;
pp_diag(ppi, servo, 2, "T1: %s\n", fmt_ppt(&ppi->t1));
pp_diag(ppi, servo, 2, "T2: %s\n", fmt_ppt(&ppi->t2));
shmem_lock(); /* Share memory locked */
/*
* calc 'master_to_slave_delay'; no correction field
* appears in the formulas because it's already merged with t1
......@@ -86,8 +110,7 @@ void pp_servo_got_psync(struct pp_instance *ppi)
pp_time_sub(m_to_s_dly, &ppi->t1);
/* update 'offsetFromMaster' and possibly jump in time */
if (pp_servo_offset_master(ppi, mpd, ofm, m_to_s_dly))
return;
if (!pp_servo_offset_master(ppi, mpd, ofm, m_to_s_dly)) {
/* PI controller returns a scaled_nsecs adjustment, so shift back */
adj32 = (int)(pp_servo_pi_controller(ppi, ofm) >> 16);
......@@ -103,15 +126,18 @@ void pp_servo_got_psync(struct pp_instance *ppi)
pp_diag(ppi, servo, 2, "Observed drift: %9i\n",
(int)SRV(ppi)->obs_drift >> 10);
}
SRV(ppi)->update_count++;
shmem_unlock(); /* Share memory unlocked */
}
/* called by slave states when delay_resp is received (all t1..t4 are valid) */
void pp_servo_got_resp(struct pp_instance *ppi)
{
struct pp_time *m_to_s_dly = &SRV(ppi)->m_to_s_dly;
struct pp_time *s_to_m_dly = &SRV(ppi)->s_to_m_dly;
struct pp_time *mpd = &DSCUR(ppi)->meanPathDelay;
struct pp_time *ofm = &DSCUR(ppi)->offsetFromMaster;
struct pp_time *delayMS = &SRV(ppi)->delayMS;
struct pp_time *delaySM = &SRV(ppi)->delaySM;
struct pp_time *mpd = &SRV(ppi)->meanDelay;
struct pp_time *ofm = &SRV(ppi)->offsetFromMaster;
struct pp_avg_fltr *mpd_fltr = &SRV(ppi)->mpd_fltr;
int adj32;
......@@ -121,25 +147,28 @@ void pp_servo_got_resp(struct pp_instance *ppi)
pp_diag(ppi, servo, 2, "discard T3/T4: we miss T1/T2\n");
return;
}
shmem_lock(); /* Share memory locked */
/*
* calc 'slave_to_master_delay', removing delay_resp correction field
* added by transparent clocks in the path.
*/
*s_to_m_dly = ppi->t4;
pp_time_sub(s_to_m_dly, &ppi->t3);
*delaySM = ppi->t4;
pp_time_sub(delaySM, &ppi->t3);
pp_diag(ppi, servo, 2, "T1: %s\n", fmt_ppt(&ppi->t1));
pp_diag(ppi, servo, 2, "T2: %s\n", fmt_ppt(&ppi->t2));
pp_diag(ppi, servo, 2, "T3: %s\n", fmt_ppt(&ppi->t3));
pp_diag(ppi, servo, 2, "T4: %s\n", fmt_ppt(&ppi->t4));
pp_diag(ppi, servo, 1, "Master to slave: %s\n", fmt_ppt(m_to_s_dly));
pp_diag(ppi, servo, 1, "Slave to master: %s\n", fmt_ppt(s_to_m_dly));
pp_diag(ppi, servo, 1, "delayMS: %s\n", fmt_ppt(delayMS));
pp_diag(ppi, servo, 1, "delaySM: %s\n", fmt_ppt(delaySM));
/* Calc mean path delay, used later to calc "offset from master" */
*mpd = SRV(ppi)->m_to_s_dly;
pp_time_add(mpd, &SRV(ppi)->s_to_m_dly);
*mpd = SRV(ppi)->delayMS;
pp_time_add(mpd, &SRV(ppi)->delaySM);
pp_time_div2(mpd);
pp_diag(ppi, servo, 1, "meanPathDelay: %s\n", fmt_ppt(mpd));
DSCUR(ppi)->meanDelay=pp_time_to_interval (mpd); /* Update currentDS */
pp_diag(ppi, servo, 1, "meanDelay: %s\n", fmt_ppt(mpd));
if (mpd->secs) /* Hmm.... we called this "bad event" */
return;
......@@ -148,8 +177,7 @@ void pp_servo_got_resp(struct pp_instance *ppi)
pp_servo_mpd_fltr(ppi, mpd_fltr, mpd);
/* update 'offsetFromMaster' and possibly jump in time */
if (pp_servo_offset_master(ppi, mpd, ofm, m_to_s_dly))
return;
if (!pp_servo_offset_master(ppi, mpd, ofm, delayMS)) {
/* PI controller */
adj32 = (int)(pp_servo_pi_controller(ppi, ofm) >> 16);
......@@ -162,6 +190,9 @@ void pp_servo_got_resp(struct pp_instance *ppi)
else
ppi->t_ops->adjust_offset(ppi, -adj32);
}
}
SRV(ppi)->update_count++;
shmem_unlock(); /* Share memory unlocked */
pp_diag(ppi, servo, 2, "Observed drift: %9i\n",
(int)SRV(ppi)->obs_drift >> 10);
......@@ -170,42 +201,46 @@ void pp_servo_got_resp(struct pp_instance *ppi)
/* called by slave states when delay_resp is received (all t1..t4 are valid) */
void pp_servo_got_presp(struct pp_instance *ppi)
{
struct pp_time *m_to_s_dly = &SRV(ppi)->m_to_s_dly;
struct pp_time *s_to_m_dly = &SRV(ppi)->s_to_m_dly;
struct pp_time *mpd = &DSCUR(ppi)->meanPathDelay;
struct pp_time *delayMS = &SRV(ppi)->delayMS;
struct pp_time *delaySM = &SRV(ppi)->delaySM;
struct pp_time *mpd = &SRV(ppi)->meanDelay;
struct pp_avg_fltr *mpd_fltr = &SRV(ppi)->mpd_fltr;
shmem_lock(); /* Share memory locked */
/*
* calc 'slave_to_master_delay', removing the correction field
* added by transparent clocks in the path.
*/
*s_to_m_dly = ppi->t6;
pp_time_sub(s_to_m_dly, &ppi->t5);
*delaySM = ppi->t6;
pp_time_sub(delaySM, &ppi->t5);
*m_to_s_dly = ppi->t4;
pp_time_sub(m_to_s_dly, &ppi->t3);
*delayMS = ppi->t4;
pp_time_sub(delayMS, &ppi->t3);
pp_diag(ppi, servo, 2, "T3: %s\n", fmt_ppt(&ppi->t3));
pp_diag(ppi, servo, 2, "T4: %s\n", fmt_ppt(&ppi->t4));
pp_diag(ppi, servo, 2, "T5: %s\n", fmt_ppt(&ppi->t5));
pp_diag(ppi, servo, 2, "T6: %s\n", fmt_ppt(&ppi->t6));
pp_diag(ppi, servo, 1, "Master to slave: %s\n", fmt_ppt(m_to_s_dly));
pp_diag(ppi, servo, 1, "Slave to master: %s\n", fmt_ppt(s_to_m_dly));
pp_diag(ppi, servo, 1, "delayMS: %s\n", fmt_ppt(delayMS));
pp_diag(ppi, servo, 1, "delaySM: %s\n", fmt_ppt(delaySM));
/* Calc mean path delay, used later to calc "offset from master" */
*mpd = SRV(ppi)->m_to_s_dly;
pp_time_add(mpd, &SRV(ppi)->s_to_m_dly);
*mpd = SRV(ppi)->delayMS;
pp_time_add(mpd, &SRV(ppi)->delaySM);
pp_time_div2(mpd);
pp_diag(ppi, servo, 1, "meanPathDelay: %s\n", fmt_ppt(mpd));
if (mpd->secs) /* Hmm.... we called this "bad event" */
return;
DSCUR(ppi)->meanDelay=pp_time_to_interval(mpd); /* Update currentDS */
pp_diag(ppi, servo, 1, "meanDelay: %s\n", fmt_ppt(mpd));
if (!mpd->secs) /* =0 Hmm.... we called this "bad event" */
pp_servo_mpd_fltr(ppi, mpd_fltr, mpd);
SRV(ppi)->update_count++;
shmem_unlock(); /* Share memory unlocked */
}
static
void pp_servo_mpd_fltr(struct pp_instance *ppi, struct pp_avg_fltr *mpd_fltr,
static void pp_servo_mpd_fltr(struct pp_instance *ppi, struct pp_avg_fltr *mpd_fltr,
struct pp_time *mpd)
{
int s;
......@@ -255,22 +290,22 @@ void pp_servo_mpd_fltr(struct pp_instance *ppi, struct pp_avg_fltr *mpd_fltr,
/* add fltr->s_exp to ensure we are not trapped into 0 */
mpd->scaled_nsecs = mpd_fltr->y * 2 + mpd_fltr->s_exp + 1;
}
/* filter 'meanPathDelay' (running average) -- use an unsigned "y" */
/* filter 'meanDelay' (running average) -- use an unsigned "y" */
y = (mpd_fltr->y * (mpd_fltr->s_exp - 1) + mpd->scaled_nsecs);
__div64_32(&y, mpd_fltr->s_exp);
mpd->scaled_nsecs = mpd_fltr->y = y;
pp_diag(ppi, servo, 1, "After avg(%i), meanPathDelay: %i\n",
DSCUR(ppi)->meanDelay=pp_time_to_interval(mpd); /* Update meanDelay in CurrentDS */
pp_diag(ppi, servo, 1, "After avg(%i), meanDelay: %i\n",
(int)mpd_fltr->s_exp, (int)(mpd->scaled_nsecs >> 16));
}
static
int pp_servo_offset_master(struct pp_instance *ppi, struct pp_time *mpd,
struct pp_time *ofm, struct pp_time *m_to_s_dly)
static int pp_servo_offset_master(struct pp_instance *ppi, struct pp_time *mpd,
struct pp_time *ofm, struct pp_time *delayMS)
{
struct pp_time time_tmp;
*ofm = *m_to_s_dly;
*ofm = *delayMS;
pp_time_sub(ofm, mpd);
DSCUR(ppi)->offsetFromMaster=pp_time_to_interval(ofm);
pp_diag(ppi, servo, 1, "Offset from master: %s\n", fmt_ppt(ofm));
if (!ofm->secs)
......@@ -282,7 +317,7 @@ int pp_servo_offset_master(struct pp_instance *ppi, struct pp_time *mpd,
ppi->t_ops->get(ppi, &time_tmp);
pp_time_sub(&time_tmp, ofm);
ppi->t_ops->set(ppi, &time_tmp);
pp_servo_init(ppi);
_pp_servo_init(ppi);
return 1; /* done */
}
......
......@@ -40,7 +40,7 @@ int pp_initializing(struct pp_instance *ppi, void *buf, int len)
{
unsigned char *mac;
unsigned char mac_port1[6];
struct DSPort *port = DSPOR(ppi);
portDS_t *port = DSPOR(ppi);
struct pp_runtime_opts *opt = OPTS(ppi);
struct pp_globals *ppg = GLBS(ppi);
int ret = 0;
......@@ -99,9 +99,9 @@ int pp_initializing(struct pp_instance *ppi, void *buf, int len)
/* 1-based port number = index of this ppi in the global array */
port->portIdentity.portNumber = 1 + ppi - ppi->glbs->pp_instances;
port->logMinDelayReqInterval = PP_DEFAULT_DELAYREQ_INTERVAL;
port->logAnnounceInterval = opt->announce_intvl;
port->logAnnounceInterval = opt->logAnnounceInterval;
port->announceReceiptTimeout = PP_DEFAULT_ANNOUNCE_RECEIPT_TIMEOUT;
port->logSyncInterval = opt->sync_intvl;
port->logSyncInterval = opt->logSyncInterval;
port->versionNumber = PP_VERSION_PTP;
pp_timeout_init(ppi);
pp_timeout_setall(ppi);
......
......@@ -20,7 +20,7 @@ static pp_action *actions[] = {
[PPM_FOLLOW_UP] = 0,
[PPM_DELAY_RESP] = 0,
[PPM_ANNOUNCE] = st_com_handle_announce,
/* skip signaling and management, for binary size */
[PPM_SIGNALING] = st_com_handle_signaling,
};
int pp_listening(struct pp_instance *ppi, void *buf, int len)
......@@ -35,7 +35,7 @@ int pp_listening(struct pp_instance *ppi, void *buf, int len)
goto out;
/* when the clock is using peer-delay, listening must send it too */
if (CONFIG_HAS_P2P && ppi->mech == PP_P2P_MECH)
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P)
e = pp_lib_may_issue_request(ppi);
/*
* The management of messages is now table-driven
......@@ -58,7 +58,7 @@ out:
if (e != 0)
ppi->next_state = PPS_FAULTY;
if (CONFIG_HAS_P2P && ppi->mech == PP_P2P_MECH) {
if (CONFIG_HAS_P2P && ppi->delayMechanism == PP_P2P_MECH) {
ppi->next_delay = pp_next_delay_2(ppi,
PP_TO_ANN_RECEIPT, PP_TO_REQUEST);
} else {
......
......@@ -23,7 +23,8 @@ static pp_action *actions[] = {
[PPM_FOLLOW_UP] = 0,
[PPM_DELAY_RESP] = 0,
[PPM_ANNOUNCE] = st_com_handle_announce,
/* skip signaling and management, for binary size */
[PPM_SIGNALING] = st_com_handle_signaling,
/* skip management, for binary size */
};
static int master_handle_delay_request(struct pp_instance *ppi,
......@@ -67,7 +68,7 @@ int pp_master(struct pp_instance *ppi, void *buf, int len)
}
/* when the clock is using peer-delay, the master must send it too */
if (CONFIG_HAS_P2P && ppi->mech == PP_P2P_MECH)
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P)
pp_lib_may_issue_request(ppi);
/*
......@@ -117,7 +118,7 @@ out:
}
if (pre) {
if (CONFIG_HAS_P2P && ppi->mech == PP_P2P_MECH) {
if (CONFIG_HAS_P2P && ppi->delayMechanism == PP_P2P_MECH) {
ppi->next_delay = pp_next_delay_2(ppi,
PP_TO_QUALIFICATION, PP_TO_REQUEST);
} else {
......@@ -125,7 +126,7 @@ out:
PP_TO_QUALIFICATION);
}
} else {
if (CONFIG_HAS_P2P && ppi->mech == PP_P2P_MECH) {
if (CONFIG_HAS_P2P && ppi->delayMechanism == PP_P2P_MECH) {
ppi->next_delay = pp_next_delay_3(ppi,
PP_TO_ANN_SEND, PP_TO_SYNC_SEND, PP_TO_REQUEST);
} else {
......
......@@ -56,7 +56,7 @@ int pp_passive(struct pp_instance *ppi, void *buf, int len)
* passive */
/* when the clock is using peer-delay, passive must send it too */
if (CONFIG_HAS_P2P && ppi->mech == PP_P2P_MECH)
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P)
e = pp_lib_may_issue_request(ppi);
/*
......@@ -79,7 +79,7 @@ int pp_passive(struct pp_instance *ppi, void *buf, int len)
if (e != 0)
ppi->next_state = PPS_FAULTY;
if (CONFIG_HAS_P2P && ppi->mech == PP_P2P_MECH) {
if (CONFIG_HAS_P2P && ppi->delayMechanism == PP_P2P_MECH) {
ppi->next_delay = pp_next_delay_2(ppi,
PP_TO_ANN_RECEIPT, PP_TO_REQUEST);
} else {
......
......@@ -29,7 +29,8 @@ static pp_action *actions[] = {
[PPM_FOLLOW_UP] = slave_handle_followup,
[PPM_DELAY_RESP] = slave_handle_response,
[PPM_ANNOUNCE] = slave_handle_announce,
/* skip signaling and management, for binary size */
[PPM_SIGNALING] = st_com_handle_signaling,
/* skip management, for binary size */
};
static int slave_handle_sync(struct pp_instance *ppi, void *buf,
......@@ -57,7 +58,7 @@ static int slave_handle_sync(struct pp_instance *ppi, void *buf,
ppi->t1 = sync.originTimestamp;
pp_time_add(&ppi->t1, &hdr->cField);
ppi->syncCF = 0;
if (CONFIG_HAS_P2P && ppi->mech == PP_P2P_MECH)
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P)
pp_servo_got_psync(ppi);
else
pp_servo_got_sync(ppi);
......@@ -106,7 +107,7 @@ static int slave_handle_followup(struct pp_instance *ppi, void *buf,
if (ret < 0)
return ret;
if (CONFIG_HAS_P2P && ppi->mech == PP_P2P_MECH)
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P)
pp_servo_got_psync(ppi);
else
pp_servo_got_sync(ppi);
......
......@@ -39,7 +39,7 @@ static int wrpc_open_ch(struct pp_instance *ppi)
struct wr_sockaddr addr;
char *macaddr = PP_MCAST_MACADDRESS;
if (CONFIG_HAS_P2P && ppi->mech == PP_P2P_MECH)
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P)
macaddr = PP_PDELAY_MACADDRESS;
addr.ethertype = htons(ETH_P_1588);
memcpy(addr.mac, macaddr, sizeof(mac_addr_t));
......
......@@ -247,7 +247,7 @@ static int wrs_recv_msg(struct pp_instance *ppi, int fd, void *pkt, int len,
t->secs = sts->hwtimeraw.tv_sec & 0x7fffffff;
update_dmtd(s, ppi);
if (!WR_DSPOR(ppi)->wrModeOn) {
if ( WRH_DSPOR_HEAD(ppi)==NULL || !WRH_DSPOR_HEAD(ppi)->extModeOn) {
goto drop;
}
if (s->dmtd_phase_valid) {
......
......@@ -14,8 +14,9 @@
#include <sys/timex.h>
#include <ppsi/ppsi.h>
#include <ppsi-wrs.h>
#include <hal_exports.h>
#include "../include/hw-specific/wrh.h"
/* FIXME: these externs are needed here because we can not include
* hal_exports.h with HAL_EXPORT_STRUCTURES twice (the first is by
* arch-wrs/wrs-calibration.c): structs are declared and
......@@ -91,9 +92,9 @@ int wrs_enable_ptracker(struct pp_instance *ppi)
&rval, ppi->iface_name, HEXP_LOCK_CMD_ENABLE_TRACKING, 0);
if ((ret < 0) || (rval < 0))
return WR_SPLL_ERROR;
return WRH_SPLL_ERROR;
return WR_SPLL_OK;
return WRH_SPLL_OK;
}
int wrs_enable_timing_output(struct pp_instance *ppi, int enable)
......@@ -101,9 +102,9 @@ int wrs_enable_timing_output(struct pp_instance *ppi, int enable)
int ret, rval;
hexp_pps_params_t p;
if (enable == WR_DSPOR(ppi)->ppsOutputOn)
return WR_SPLL_OK;
WR_DSPOR(ppi)->ppsOutputOn = enable;
if (enable == WRH_DSPOR_HEAD(ppi)->ppsOutputOn)
return WRH_SPLL_OK;
WRH_DSPOR_HEAD(ppi)->ppsOutputOn = enable;
p.pps_valid = enable;
......@@ -111,14 +112,14 @@ int wrs_enable_timing_output(struct pp_instance *ppi, int enable)
&rval, HEXP_PPSG_CMD_SET_VALID, &p);
if ((ret < 0) || (rval < 0))
return WR_SPLL_ERROR;
return WRH_SPLL_ERROR;
return WR_SPLL_OK;
return WRH_SPLL_OK;
}
int wrs_locking_disable(struct pp_instance *ppi)
{
return WR_SPLL_OK;
return WRH_SPLL_OK;
}
int wrs_locking_enable(struct pp_instance *ppi)
......@@ -131,9 +132,9 @@ int wrs_locking_enable(struct pp_instance *ppi)
&rval, ppi->iface_name, HEXP_LOCK_CMD_START, 0);
if ((ret < 0) || (rval < 0))
return WR_SPLL_ERROR;
return WRH_SPLL_ERROR;
return WR_SPLL_OK;
return WRH_SPLL_OK;
}
int wrs_locking_reset(struct pp_instance *ppi)
......@@ -146,9 +147,9 @@ int wrs_locking_reset(struct pp_instance *ppi)
&rval, ppi->iface_name, HEXP_LOCK_CMD_RESET, 0);
if ((ret < 0) || (rval < 0))
return WR_SPLL_ERROR;
return WRH_SPLL_ERROR;
return WR_SPLL_OK;
return WRH_SPLL_OK;
}
int wrs_locking_poll(struct pp_instance *ppi, int grandmaster)
......@@ -156,16 +157,16 @@ int wrs_locking_poll(struct pp_instance *ppi, int grandmaster)
int ret, rval;
if (grandmaster) /* FIXME: check wrs grandmaster PLL */
return WR_SPLL_READY;
return WRH_SPLL_READY;
ret = minipc_call(hal_ch, DEFAULT_TO, &__rpcdef_lock_cmd,
&rval, ppi->iface_name, HEXP_LOCK_CMD_CHECK, 0);
if (ret != HEXP_LOCK_STATUS_LOCKED) {
pp_diag(ppi, time, 2, "PLL is not ready\n");
return WR_SPLL_ERROR; /* FIXME should be WR_SPLL_NOT_READY */
return WRH_SPLL_ERROR; /* FIXME should be WRH_SPLL_NOT_READY */
}
pp_diag(ppi, time, 2, "PLL is locked\n");
return WR_SPLL_READY;
return WRH_SPLL_READY;
}
/* This is a hack, but at least the year is 640bit clean */
......@@ -222,7 +223,7 @@ static int wrs_time_get_servo_state(struct pp_instance *ppi, int *state)
int locked;
locked = WRH_OPER()->locking_poll(ppi, 1);
if (locked == WR_SPLL_READY)
if (locked == WRH_SPLL_READY)
*state = PP_SERVO_LOCKED;
else
*state = PP_SERVO_UNLOCKED;
......
......@@ -26,14 +26,16 @@ static struct timeout_config to_configs[__PP_TO_ARRAY_SIZE] = {
[PP_TO_ANN_RECEIPT] = {"ANN_RECEIPT", RAND_NONE,},
[PP_TO_ANN_SEND] = {"ANN_SEND", RAND_70_130,},
[PP_TO_FAULT] = {"FAULT", RAND_NONE, 4000},
[PP_TO_QUALIFICATION] = {"QUAL", RAND_NONE,}
[PP_TO_QUALIFICATION] = {"QUAL", RAND_NONE,},
/* extension timeouts are explicitly set to a value */
[PP_TO_EXT_0]={"EXT_0", RAND_NONE,},
[PP_TO_EXT_1]={"EXT_1", RAND_NONE,}
};
/* Init fills the timeout values */
void pp_timeout_init(struct pp_instance *ppi)
{
struct DSPort *port = ppi->portDS;
portDS_t *port = ppi->portDS;
to_configs[PP_TO_REQUEST].value =
port->logMinDelayReqInterval;
......@@ -52,8 +54,8 @@ void pp_timeout_init(struct pp_instance *ppi)
void __pp_timeout_set(struct pp_instance *ppi, int index, int millisec)
{
ppi->timeouts[index] = ppi->t_ops->calc_timeout(ppi, millisec);
pp_diag(ppi, time, 3, "new timeout for %s: %i\n",
to_configs[index].name, millisec);
pp_diag(ppi, time, 3, "new timeout for %s : %i / %lu\n",
to_configs[index].name, millisec, ppi->timeouts[index]);
}
void pp_timeout_clear(struct pp_instance *ppi, int index)
......@@ -128,12 +130,12 @@ void pp_timeout_setall(struct pp_instance *ppi)
int pp_timeout(struct pp_instance *ppi, int index)
{
int ret = time_after_eq(ppi->t_ops->calc_timeout(ppi, 0),
ppi->timeouts[index]);
unsigned long now=ppi->t_ops->calc_timeout(ppi, 0);
int ret = time_after_eq(now,ppi->timeouts[index]);
if (ret)
pp_diag(ppi, time, 1, "timeout expired: %s\n",
to_configs[index].name);
pp_diag(ppi, time, 1, "timeout expired: %s / %lu\n",
to_configs[index].name,now);
return ret;
}
......
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