Commit c81db09e authored by baujc's avatar baujc

Big update ...

- New L1Sync and PTP servo calculation (delayAsym,...)
- Make function calls more uniforms between extensions
- refactoring
- Add a new state machine to enable/disable an extension and provide
only PTP support: New timer, new hooks, ...
- Fix bug in time format conversion
- Code removed when an extension is not required (#ifdef XXX )
- Align the PTP and L1Sync servo calculation (shared fct, same
calculation,...)
- Force only one servo running at a given time for a given instance
- New servo reset hook : called by main loop
- Add function to converte a time into a string
- Force to stay in FAULTY state during 60s
- Optimise function wrs_enable_timing_output()
parent d456d2fd
...@@ -69,7 +69,8 @@ static int run_all_state_machines(struct pp_globals *ppg) ...@@ -69,7 +69,8 @@ static int run_all_state_machines(struct pp_globals *ppg)
ppi->frgn_rec_num = 0; ppi->frgn_rec_num = 0;
ppi->frgn_rec_best = -1; ppi->frgn_rec_best = -1;
if (ppg->ebest_idx == ppi->port_idx) if (ppg->ebest_idx == ppi->port_idx)
wr_servo_reset(ppi); if( ppi->ext_hooks->servo_reset)
(*ppi->ext_hooks->servo_reset)(ppi);
} }
} }
......
...@@ -35,9 +35,13 @@ int wrs_read_calibration_data(struct pp_instance *ppi, ...@@ -35,9 +35,13 @@ int wrs_read_calibration_data(struct pp_instance *ppi,
* way as the HAL itself was doing to fill the RPC structure. * way as the HAL itself was doing to fill the RPC structure.
* Formulas copied from libwr/hal_shmem.c (get_exported_state). * Formulas copied from libwr/hal_shmem.c (get_exported_state).
*/ */
#if CONFIG_PROFILE_WR == 1
port_fix_alpha = FIX_ALPHA_TWO_POW_FRACBITS * port_fix_alpha = FIX_ALPHA_TWO_POW_FRACBITS *
((p->calib.sfp.alpha + 1.0) / (p->calib.sfp.alpha + 2.0) ((p->calib.sfp.alpha + 1.0) / (p->calib.sfp.alpha + 2.0)
- 0.5); - 0.5);
#else
port_fix_alpha =0;
#endif
if ( delta_tx || delta_rx) { if ( delta_tx || delta_rx) {
port_delta_tx = p->calib.delta_tx_phy port_delta_tx = p->calib.delta_tx_phy
...@@ -64,15 +68,20 @@ int wrs_read_calibration_data(struct pp_instance *ppi, ...@@ -64,15 +68,20 @@ int wrs_read_calibration_data(struct pp_instance *ppi,
int wrs_read_correction_data(struct pp_instance *ppi, int64_t *fiber_fix_alpha, int wrs_read_correction_data(struct pp_instance *ppi, int64_t *fiber_fix_alpha,
int32_t *clock_period_ps, uint32_t *bit_slide_ps) { int32_t *clock_period_ps, uint32_t *bit_slide_ps) {
double alpha;
int32_t port_cP; int32_t port_cP;
wrs_read_calibration_data(ppi, NULL, NULL,NULL, &port_cP, bit_slide_ps); wrs_read_calibration_data(ppi, NULL, NULL,NULL, &port_cP, bit_slide_ps);
if(fiber_fix_alpha) { if(fiber_fix_alpha) {
#if CONFIG_PROFILE_WR == 1
double alpha;
alpha = ((double) ppi->asymmetryCorrectionPortDS.scaledDelayCoefficient)/REL_DIFF_TWO_POW_FRACBITS; alpha = ((double) ppi->asymmetryCorrectionPortDS.scaledDelayCoefficient)/REL_DIFF_TWO_POW_FRACBITS;
*fiber_fix_alpha = FIX_ALPHA_TWO_POW_FRACBITS * ((alpha + 1.0) / (alpha + 2.0) - 0.5); *fiber_fix_alpha = FIX_ALPHA_TWO_POW_FRACBITS * ((alpha + 1.0) / (alpha + 2.0) - 0.5);
#else
*fiber_fix_alpha=0;
#endif
} }
if(clock_period_ps) if(clock_period_ps)
*clock_period_ps = port_cP; /* REF_CLOCK_PERIOD_PS */ *clock_period_ps = port_cP; /* REF_CLOCK_PERIOD_PS */
return WRH_HW_CALIB_OK; return WRH_HW_CALIB_OK;
......
...@@ -102,15 +102,18 @@ static __inline__ double calculateDelayAsymCoefficient(double delayCoefficient ...@@ -102,15 +102,18 @@ static __inline__ double calculateDelayAsymCoefficient(double delayCoefficient
static void enable_asymmetryCorrection(struct pp_instance *ppi, Boolean enable ) { static void enable_asymmetryCorrection(struct pp_instance *ppi, Boolean enable ) {
if ( (ppi->asymmetryCorrectionPortDS.enable=enable)==TRUE ) { if ( (ppi->asymmetryCorrectionPortDS.enable=enable)==TRUE ) {
/* Enabled: The delay asymmetry will be calculated */ /* Enabled: The delay asymmetry will be calculated */
ppi->asymmetryCorrectionPortDS.scaledDelayCoefficient= double delayCoefficient;
ppi->cfg.scaledDelayCoefficient != 0 ?
ppi->cfg.scaledDelayCoefficient : if ( ppi->cfg.scaledDelayCoefficient != 0) {
(RelativeDifference)(ppi->cfg.delayCoefficient * REL_DIFF_TWO_POW_FRACBITS); ppi->asymmetryCorrectionPortDS.scaledDelayCoefficient=ppi->cfg.scaledDelayCoefficient;
ppi->portDS->delayAsymCoeff=(RelativeDifference)(calculateDelayAsymCoefficient(ppi->cfg.delayCoefficient) * REL_DIFF_TWO_POW_FRACBITS); delayCoefficient=ppi->cfg.scaledDelayCoefficient/REL_DIFF_TWO_POW_FRACBITS;
} else { } else {
/* Disabled: The delay asymmetry will be provided by the config (constantAsymmetry) */ ppi->asymmetryCorrectionPortDS.scaledDelayCoefficient=(RelativeDifference)(ppi->cfg.delayCoefficient * REL_DIFF_TWO_POW_FRACBITS);
ppi->asymmetryCorrectionPortDS.constantAsymmetry=picos_to_interval(ppi->cfg.constantAsymmetry_ps); delayCoefficient=ppi->cfg.delayCoefficient;
}
ppi->portDS->delayAsymCoeff=(RelativeDifference)(calculateDelayAsymCoefficient(delayCoefficient) * REL_DIFF_TWO_POW_FRACBITS);
} }
ppi->asymmetryCorrectionPortDS.constantAsymmetry=picos_to_interval(ppi->cfg.constantAsymmetry_ps);
} }
int main(int argc, char **argv) int main(int argc, char **argv)
...@@ -266,9 +269,9 @@ int main(int argc, char **argv) ...@@ -266,9 +269,9 @@ int main(int argc, char **argv)
Boolean configured=FALSE; Boolean configured=FALSE;
#if CONFIG_PROFILE_HA == 1 #if CONFIG_PROFILE_HA == 1
sprintf(s, "port %i; iface wri%i; proto raw; profile ha", i + 1, i + 1); sprintf(s, "port %i; iface wri%i; proto raw; profile ha", i + 1, i + 1);
configured=TRUE;
#endif #endif
#if CONFIG_PROFILE_WR == 1 #if CONFIG_PROFILE_WR == 1
configured=TRUE;
if ( ! configured ) if ( ! configured )
sprintf(s, "port %i; iface wri%i; proto raw; profile wr", i + 1, i + 1); sprintf(s, "port %i; iface wri%i; proto raw; profile wr", i + 1, i + 1);
#endif #endif
...@@ -288,6 +291,7 @@ int main(int argc, char **argv) ...@@ -288,6 +291,7 @@ int main(int argc, char **argv)
ppi->portDS = wrs_shm_alloc(ppsi_head, sizeof(*ppi->portDS)); ppi->portDS = wrs_shm_alloc(ppsi_head, sizeof(*ppi->portDS));
ppi->servo = wrs_shm_alloc(ppsi_head, sizeof(*ppi->servo)); ppi->servo = wrs_shm_alloc(ppsi_head, sizeof(*ppi->servo));
ppi->ext_hooks=&pp_hooks; /* Default value. Can be overwritten by an extension */ ppi->ext_hooks=&pp_hooks; /* Default value. Can be overwritten by an extension */
ppi->ptp_support=FALSE;
if (ppi->portDS) { if (ppi->portDS) {
switch (ppi->cfg.profile) { switch (ppi->cfg.profile) {
#if CONFIG_PROFILE_WR == 1 #if CONFIG_PROFILE_WR == 1
...@@ -324,9 +328,11 @@ int main(int argc, char **argv) ...@@ -324,9 +328,11 @@ int main(int argc, char **argv)
case PPSI_PROFILE_PTP : case PPSI_PROFILE_PTP :
/* Do not take care of L1SYNC */ /* Do not take care of L1SYNC */
enable_asymmetryCorrection(ppi,ppi->cfg.asymmetryCorrectionEnable); enable_asymmetryCorrection(ppi,ppi->cfg.asymmetryCorrectionEnable);
ppi->protocol_extension=PPSI_EXT_NONE;
break; break;
#if CONFIG_PROFILE_CUSTOM == 1 #if CONFIG_PROFILE_CUSTOM == 1
case PPSI_PROFILE_CUSTOM : case PPSI_PROFILE_CUSTOM :
ppi->protocol_extension=PPSI_EXT_NONE; /* can be changed ...*/
#if CONFIG_EXT_L1SYNC #if CONFIG_EXT_L1SYNC
if (ppi->cfg.l1SyncEnabled ) { if (ppi->cfg.l1SyncEnabled ) {
if ( !enable_l1Sync(ppi,TRUE) ) if ( !enable_l1Sync(ppi,TRUE) )
......
...@@ -276,7 +276,25 @@ int pp_state_machine(struct pp_instance *ppi, void *buf, int len) ...@@ -276,7 +276,25 @@ int pp_state_machine(struct pp_instance *ppi, void *buf, int len)
if (ppi->state != ppi->next_state) if (ppi->state != ppi->next_state)
return pp_leave_current_state(ppi); return pp_leave_current_state(ppi);
if (!len) if (len) {
if ( ppi->link_state == PP_LSTATE_PROTOCOL_DETECTION ) {
if ( ppi->ptp_msg_received==FALSE ) {
/* First frame received since instance initialization */
int tmo;
ppi->ptp_msg_received=TRUE;
if ( ppi->ext_hooks->get_tmo_lstate_detection!=NULL)
tmo=(*ppi->ext_hooks->get_tmo_lstate_detection)(ppi);
else
tmo= ppi->timeouts[PP_TO_ANN_RECEIPT].initValueMs;
__pp_timeout_set(ppi,PP_TO_PROT_STATE, tmo);
}
}
if ( !ppi->ext_enabled && ppi->link_state==PP_LSTATE_PROTOCOL_DETECTION) {
/* Ptp protocol only */
ppi->link_state= PP_LSTATE_IN_PROGRESS;
}
} else
ppi->received_ptp_header.messageType = PPM_NO_MESSAGE; ppi->received_ptp_header.messageType = PPM_NO_MESSAGE;
err = ip->f1(ppi, buf, len); err = ip->f1(ppi, buf, len);
...@@ -288,6 +306,19 @@ int pp_state_machine(struct pp_instance *ppi, void *buf, int len) ...@@ -288,6 +306,19 @@ int pp_state_machine(struct pp_instance *ppi, void *buf, int len)
if (ppi->state != ppi->next_state) if (ppi->state != ppi->next_state)
return pp_leave_current_state(ppi); return pp_leave_current_state(ppi);
/* Check protocol state */
if ( ppi->link_state==PP_LSTATE_PROTOCOL_DETECTION ) {
if ( ppi->ptp_msg_received && pp_timeout(ppi, PP_TO_PROT_STATE) ) {
if ( ppi->ptp_support && ppi->ext_enabled ) {
ppi->ext_enabled=FALSE;
ppi->ptp_msg_received=FALSE;
} else
ppi->link_state=PP_LSTATE_FAILURE;
}
}
if (ppi->link_state==PP_LSTATE_FAILURE ) {
}
/* run bmc independent of state, and since not message driven do this /* run bmc independent of state, and since not message driven do this
* here 9.2.6.8 */ * here 9.2.6.8 */
if (pp_timeout(ppi, PP_TO_BMC)) { if (pp_timeout(ppi, PP_TO_BMC)) {
...@@ -307,6 +338,11 @@ int pp_state_machine(struct pp_instance *ppi, void *buf, int len) ...@@ -307,6 +338,11 @@ int pp_state_machine(struct pp_instance *ppi, void *buf, int len)
/* Run the extension state machine. The extension can provide its own time-out */ /* Run the extension state machine. The extension can provide its own time-out */
if ( ppi->ext_hooks->run_ext_state_machine) { if ( ppi->ext_hooks->run_ext_state_machine) {
int delay = ppi->ext_hooks->run_ext_state_machine(ppi); int delay = ppi->ext_hooks->run_ext_state_machine(ppi);
if ( ppi->link_state==PP_LSTATE_FAILURE && ppi->ptp_support && ppi->ext_enabled ) {
ppi->ext_enabled=FALSE;
ppi->link_state=PP_LSTATE_PROTOCOL_DETECTION;
}
ppi->next_delay= (delay < ppi->next_delay) ? delay : ppi->next_delay; ppi->next_delay= (delay < ppi->next_delay) ? delay : ppi->next_delay;
} }
......
...@@ -29,12 +29,6 @@ ...@@ -29,12 +29,6 @@
#define WRH_HW_CALIB_ERROR -1 #define WRH_HW_CALIB_ERROR -1
#define WRH_HW_CALIB_NOT_FOUND -3 #define WRH_HW_CALIB_NOT_FOUND -3
enum {
WRH_SERVO_ENTER, WRH_SERVO_LEAVE
};
#define FIX_ALPHA_FRACBITS 40 #define FIX_ALPHA_FRACBITS 40
#define FIX_ALPHA_FRACBITS_AS_FLOAT 40.0 #define FIX_ALPHA_FRACBITS_AS_FLOAT 40.0
...@@ -70,7 +64,6 @@ struct wrh_operations { ...@@ -70,7 +64,6 @@ struct wrh_operations {
unsigned int calibrationPatternLen); unsigned int calibrationPatternLen);
int (*calib_pattern_disable)(struct pp_instance *ppi); int (*calib_pattern_disable)(struct pp_instance *ppi);
int (*enable_timing_output)(struct pp_instance *ppi, int enable); int (*enable_timing_output)(struct pp_instance *ppi, int enable);
int (*servo_hook)(struct pp_instance *ppi, int action);
int (*read_corr_data)(struct pp_instance *ppi, int64_t *fixAlpha, int (*read_corr_data)(struct pp_instance *ppi, int64_t *fixAlpha,
int32_t *clock_period, uint32_t *bit_slide_ps); int32_t *clock_period, uint32_t *bit_slide_ps);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
/* general purpose constants */ /* general purpose constants */
#define PP_NSEC_PER_SEC (1000*1000*1000) #define PP_NSEC_PER_SEC (1000*1000*1000)
#define PP_PSEC_PER_SEC ((int64_t)1000*(int64_t)PP_NSEC_PER_SEC)
/* implementation specific constants */ /* implementation specific constants */
#define PP_MAX_LINKS 64 #define PP_MAX_LINKS 64
...@@ -112,6 +113,7 @@ enum pp_timeouts { ...@@ -112,6 +113,7 @@ enum pp_timeouts {
PP_TO_ANN_SEND, PP_TO_ANN_SEND,
PP_TO_FAULT, PP_TO_FAULT,
PP_TO_QUALIFICATION, PP_TO_QUALIFICATION,
PP_TO_PROT_STATE,
/* Two timeouts for the protocol extension */ /* Two timeouts for the protocol extension */
PP_TO_EXT_0, PP_TO_EXT_0,
PP_TO_EXT_1, PP_TO_EXT_1,
......
...@@ -52,7 +52,9 @@ typedef struct _UInteger64 { /*/* TODO : Should be replaced by UInteger64 */ ...@@ -52,7 +52,9 @@ typedef struct _UInteger64 { /*/* TODO : Should be replaced by UInteger64 */
/* Page 19 :the time interval is expressed in units of nanoseconds and multiplied by 2 +16 */ /* 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 16
#define TIME_INTERVAL_FRACMASK 0xFFFF
#define TIME_INTERVAL_FRACBITS_AS_FLOAT 16.0 #define TIME_INTERVAL_FRACBITS_AS_FLOAT 16.0
#define TIME_INTERVAL_ROUNDING_VALUE (1<<(TIME_INTERVAL_FRACBITS-1))
/* Min/max value expressed in picos (int64_t) which can be stored in a TimeInterval type */ /* Min/max value expressed in picos (int64_t) which can be stored in a TimeInterval type */
#define TIME_INTERVAL_MIN_PICOS_VALUE_AS_INT64 ((int64_t) 0xFE0C000000000000) #define TIME_INTERVAL_MIN_PICOS_VALUE_AS_INT64 ((int64_t) 0xFE0C000000000000)
...@@ -74,6 +76,7 @@ typedef struct Timestamp { /* page 13 (33) -- no typedef expected */ ...@@ -74,6 +76,7 @@ typedef struct Timestamp { /* page 13 (33) -- no typedef expected */
#define REL_DIFF_FRACBITS 62 #define REL_DIFF_FRACBITS 62
#define REL_DIFF_FRACBITS_AS_FLOAT 62.0 #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) */ #define REL_DIFF_TWO_POW_FRACBITS ((double)4.611686018427388E18) /* double value returned by pow(2.0,62.0) */
#define REL_DIFF_FRACMASK 0x3fffffffffffffff
/* Min/max values for RelativeDifference type */ /* Min/max values for RelativeDifference type */
#define RELATIVE_DIFFERENCE_MIN_VALUE INT64_MIN #define RELATIVE_DIFFERENCE_MIN_VALUE INT64_MIN
......
...@@ -105,21 +105,38 @@ struct pp_avg_fltr { ...@@ -105,21 +105,38 @@ struct pp_avg_fltr {
#define PP_SERVO_FLAG_VALID (1<<0) #define PP_SERVO_FLAG_VALID (1<<0)
#define PP_SERVO_FLAG_WAIT_HW (1<<1) #define PP_SERVO_FLAG_WAIT_HW (1<<1)
struct pp_servo { #define PP_SERVO_RESET_DATA_SIZE (sizeof(struct pp_servo)-offsetof(struct pp_servo,reset_address))
int state; #define PP_SERVO_RESET_DATA(servo) memset(&servo->reset_address,0,PP_SERVO_RESET_DATA_SIZE);
struct pp_time delayMS; struct pp_servo {
struct pp_time delaySM; /* ptp servo specific data */
long long obs_drift; long long obs_drift;
struct pp_avg_fltr mpd_fltr; struct pp_avg_fltr mpd_fltr;
struct pp_time meanDelay;
struct pp_time offsetFromMaster;
/* diagnostic data */ /* Data shared with extension servo */
struct pp_time delayMM; /* Shared with extension servo */
struct pp_time delayMS; /* Shared with extension servo */
struct pp_time meanDelay; /* Shared with extension servo */
struct pp_time offsetFromMaster; /* Shared with extension servo */
unsigned long flags; /* PP_SERVO_FLAG_INVALID, PP_SERVO_FLAG_VALID, ...*/ unsigned long flags; /* PP_SERVO_FLAG_INVALID, PP_SERVO_FLAG_VALID, ...*/
uint32_t update_count; /* incremented each time the servo is running */
/* Data used only by extensions */
int state;
char servo_state_name[32]; /* Updated by the servo itself */ char servo_state_name[32]; /* Updated by the servo itself */
/*
* ----- All data after this line will be cleared during by a servo initialization
*/
int reset_address;
/* Data shared with extension servo */
uint32_t update_count; /* incremented each time the servo is running */
struct pp_time update_time; /* Last updated time of the servo */
struct pp_time t1, t2, t3, t4, t5, t6;
/* ptp servo specific data */
int servo_locked; /* TRUE when servo is locked. This info can be used by HAL */ int servo_locked; /* TRUE when servo is locked. This info can be used by HAL */
int got_sync; /* True when T1/T2 are available */
}; };
enum { /* The two sockets. They are called "net path" for historical reasons */ enum { /* The two sockets. They are called "net path" for historical reasons */
...@@ -177,6 +194,17 @@ typedef struct { ...@@ -177,6 +194,17 @@ typedef struct {
unsigned long tmo; unsigned long tmo;
} t_timeOutConfig; } t_timeOutConfig;
/*
* This enumeration correspond to the protocol state of a pp_instance.
* It is used to decide which instance must be active on a given port.
*/
typedef enum {
PP_LSTATE_PROTOCOL_DETECTION, /* Checking if the peer instance is using the same protocol */
PP_LSTATE_IN_PROGRESS, /* Right protocol detected. Try to establish the link with peer instance */
PP_LSTATE_LINKED, /* Link with peer well established */
PP_LSTATE_FAILURE /* Impossible to connect correctly to a peer instance */
} pp_link_state;
/* /*
* Structure for the individual ppsi link * Structure for the individual ppsi link
*/ */
...@@ -258,7 +286,10 @@ struct pp_instance { ...@@ -258,7 +286,10 @@ struct pp_instance {
Boolean received_dresp; /* Count the number of delay response messages received for a given delay request */ Boolean received_dresp; /* Count the number of delay response messages received for a given delay request */
Boolean received_dresp_fup; /* Count the number of delay response follow up messages received for a given delay request */ Boolean received_dresp_fup; /* Count the number of delay response follow up messages received for a given delay request */
#endif #endif
Boolean ptp_msg_received; /* Use to detect reception of a ptp message after an ppsi instance initialization */
Boolean ptp_support; /* True if allow pure PTP support */
Boolean ext_enabled; /* True if the extension is enabled */
pp_link_state link_state;
}; };
/* The following things used to be bit fields. Other flags are now enums */ /* The following things used to be bit fields. Other flags are now enums */
......
#ifndef __PPSI_PP_TIME_H__ #ifndef __PPSI_PP_TIME_H__
#define __PPSI_PP_TIME_H__ #define __PPSI_PP_TIME_H__
#define TIME_FRACBITS 16
#define TIME_FRACMASK 0xFFFF
#define TIME_FRACBITS_AS_FLOAT 16.0
#define TIME_ROUNDING_VALUE (1<<(TIME_FRACBITS-1))
/* Everything internally uses this time format, *signed* */ /* Everything internally uses this time format, *signed* */
struct pp_time { struct pp_time {
int64_t secs; int64_t secs;
......
...@@ -213,8 +213,8 @@ struct pp_ext_hooks { ...@@ -213,8 +213,8 @@ struct pp_ext_hooks {
void (*s1)(struct pp_instance *ppi, struct pp_frgn_master *frgn_master); void (*s1)(struct pp_instance *ppi, struct pp_frgn_master *frgn_master);
int (*execute_slave)(struct pp_instance *ppi); int (*execute_slave)(struct pp_instance *ppi);
int (*handle_announce)(struct pp_instance *ppi); int (*handle_announce)(struct pp_instance *ppi);
int (*handle_sync)(struct pp_instance *ppi, struct pp_time *orig); int (*handle_sync)(struct pp_instance *ppi);
int (*handle_followup)(struct pp_instance *ppi, struct pp_time *orig); int (*handle_followup)(struct pp_instance *ppi);
int (*handle_preq) (struct pp_instance * ppi); int (*handle_preq) (struct pp_instance * ppi);
int (*handle_presp) (struct pp_instance * ppi); int (*handle_presp) (struct pp_instance * ppi);
int (*handle_signaling) (struct pp_instance * ppi, void *buf, int len); int (*handle_signaling) (struct pp_instance * ppi, void *buf, int len);
...@@ -224,8 +224,14 @@ struct pp_ext_hooks { ...@@ -224,8 +224,14 @@ struct pp_ext_hooks {
int (*state_decision)(struct pp_instance *ppi, int next_state); int (*state_decision)(struct pp_instance *ppi, int next_state);
void (*state_change)(struct pp_instance *ppi); void (*state_change)(struct pp_instance *ppi);
int (*run_ext_state_machine) (struct pp_instance *ppi); int (*run_ext_state_machine) (struct pp_instance *ppi);
void (*servo_reset)(struct pp_instance *ppi);
/* If the extension requires hardware support for precise time stamp, returns 1 */
int (*require_precise_timestamp)(struct pp_instance *ppi);
int (*get_tmo_lstate_detection) (struct pp_instance *ppi);
}; };
#define is_ext_hook_available(p, c) ( /*p->ext_enabled && */ p->ext_hooks->c)
/* /*
* Network methods are encapsulated in a structure, so each arch only needs * Network methods are encapsulated in a structure, so each arch only needs
* to provide that structure. This simplifies management overall. * to provide that structure. This simplifies management overall.
...@@ -508,9 +514,12 @@ extern int f_simple_int(struct pp_argline *l, int lineno, ...@@ -508,9 +514,12 @@ extern int f_simple_int(struct pp_argline *l, int lineno,
/* Servo */ /* Servo */
extern void pp_servo_init(struct pp_instance *ppi); extern void pp_servo_init(struct pp_instance *ppi);
extern void pp_servo_got_sync(struct pp_instance *ppi); /* got t1 and t2 */ extern void pp_servo_got_sync(struct pp_instance *ppi); /* got t1 and t2 */
extern void pp_servo_got_resp(struct pp_instance *ppi); /* got all t1..t4 */ extern int pp_servo_got_resp(struct pp_instance *ppi); /* got all t1..t4 */
extern void pp_servo_got_psync(struct pp_instance *ppi); /* got t1 and t2 */ extern void pp_servo_got_psync(struct pp_instance *ppi); /* got t1 and t2 */
extern void pp_servo_got_presp(struct pp_instance *ppi); /* got all t3..t6 */ extern int pp_servo_got_presp(struct pp_instance *ppi); /* got all t3..t6 */
extern int pp_servo_calculate_delays(struct pp_instance *ppi);
extern void pp_servo_apply_faulty_stamp(struct pp_servo *s, struct pp_time *faulty_stamps, int index);
/* bmc.c */ /* bmc.c */
extern void bmc_m1(struct pp_instance *ppi); extern void bmc_m1(struct pp_instance *ppi);
...@@ -554,11 +563,13 @@ extern void msg_unpack_pdelay_resp(void *buf, MsgPDelayResp * presp); ...@@ -554,11 +563,13 @@ extern void msg_unpack_pdelay_resp(void *buf, MsgPDelayResp * presp);
extern void msg_unpack_pdelay_req(void *buf, MsgPDelayReq * pdelay_req); extern void msg_unpack_pdelay_req(void *buf, MsgPDelayReq * pdelay_req);
/* each of them returns 0 if ok, -1 in case of error in send, 1 if stamp err */ /* each of them returns 0 if ok, -1 in case of error in send, 1 if stamp err */
#define PP_SEND_OK 0 typedef enum {
#define PP_SEND_ERROR -1 PP_SEND_OK=0,
#define PP_SEND_NO_STAMP 1 PP_SEND_ERROR=-1,
#define PP_SEND_DROP -2 PP_SEND_NO_STAMP=1,
#define PP_RECV_DROP PP_SEND_DROP PP_SEND_DROP=-2,
PP_RECV_DROP=PP_SEND_DROP
}pp_send_status;
extern void *msg_copy_header(MsgHeader *dest, MsgHeader *src); /* REMOVE ME!! */ extern void *msg_copy_header(MsgHeader *dest, MsgHeader *src); /* REMOVE ME!! */
extern int msg_issue_announce(struct pp_instance *ppi); extern int msg_issue_announce(struct pp_instance *ppi);
...@@ -587,7 +598,9 @@ extern void picos_to_pp_time(int64_t picos, struct pp_time *ts); ...@@ -587,7 +598,9 @@ 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 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); extern int64_t interval_to_picos(TimeInterval interval);
extern int is_timestamps_incorrect(struct pp_instance *ppsi, int *err_count, int ts_mask); extern int is_timestamps_incorrect(struct pp_instance *ppsi, int *err_count, int ts_mask);
extern char *time_to_string(struct pp_time *t);
extern char *interval_to_string(TimeInterval time);
extern char *relative_interval_to_string(TimeInterval time);
/* /*
* The state machine itself is an array of these structures. * The state machine itself is an array of these structures.
......
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
*/ */
#include <limits.h> #include <limits.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <ppsi/ppsi.h> #include <ppsi/ppsi.h>
void normalize_pp_time(struct pp_time *t) void normalize_pp_time(struct pp_time *t)
...@@ -38,17 +41,30 @@ void normalize_pp_time(struct pp_time *t) ...@@ -38,17 +41,30 @@ void normalize_pp_time(struct pp_time *t)
/* Add a TimeInterval to a pp_time */ /* Add a TimeInterval to a pp_time */
void pp_time_add_interval(struct pp_time *t1, TimeInterval t2) void pp_time_add_interval(struct pp_time *t1, TimeInterval t2)
{ {
t1->scaled_nsecs += t2; struct pp_time t = {
normalize_pp_time(t1); .secs=0,
.scaled_nsecs=t2
};
normalize_pp_time(&t);
pp_time_add(t1,&t);
} }
/* Substract a TimeInterval to a pp_time */ /* Substract a TimeInterval to a pp_time */
void pp_time_sub_interval(struct pp_time *t1, TimeInterval t2) void pp_time_sub_interval(struct pp_time *t1, TimeInterval t2)
{ {
t1->scaled_nsecs -= t2; struct pp_time t = {
normalize_pp_time(t1); .secs=0,
.scaled_nsecs=t2
};
normalize_pp_time(&t);
pp_time_sub(t1,&t);
} }
#define IS_ADD_WILL_OVERFLOW(a,b) \
( (((a > 0) && (b > INT64_MAX - a))) ||\
(((a < 0) && (b < INT64_MIN - a))) \
)
void pp_time_add(struct pp_time *t1, struct pp_time *t2) void pp_time_add(struct pp_time *t1, struct pp_time *t2)
{ {
t1->secs += t2->secs; t1->secs += t2->secs;
...@@ -56,6 +72,11 @@ void pp_time_add(struct pp_time *t1, struct pp_time *t2) ...@@ -56,6 +72,11 @@ void pp_time_add(struct pp_time *t1, struct pp_time *t2)
normalize_pp_time(t1); normalize_pp_time(t1);
} }
#define IS_SUB_WILL_OVERFLOW(a,b) \
( ((b < 0) && (a > INT64_MAX + b)) ||\
((b > 0) && (a < INT64_MIN + b)) \
)
void pp_time_sub(struct pp_time *t1, struct pp_time *t2) void pp_time_sub(struct pp_time *t1, struct pp_time *t2)
{ {
t1->secs -= t2->secs; t1->secs -= t2->secs;
...@@ -76,28 +97,28 @@ void pp_time_div2(struct pp_time *t) ...@@ -76,28 +97,28 @@ void pp_time_div2(struct pp_time *t)
int64_t pp_time_to_picos(struct pp_time *ts) int64_t pp_time_to_picos(struct pp_time *ts)
{ {
return ts->secs * PP_NSEC_PER_SEC return ts->secs * PP_PSEC_PER_SEC
+ ((ts->scaled_nsecs * 1000 + 0x8000) >> TIME_INTERVAL_FRACBITS); + ((ts->scaled_nsecs * 1000 + TIME_ROUNDING_VALUE) >> TIME_FRACBITS);
} }
void picos_to_pp_time(int64_t picos, struct pp_time *ts) void picos_to_pp_time(int64_t picos, struct pp_time *ts)
{ {
uint64_t sec, nsec; uint64_t sec, nsec;
int phase;
int sign = (picos < 0 ? -1 : 1); int sign = (picos < 0 ? -1 : 1);
picos *= sign; picos *= sign;
nsec = picos; sec=picos/PP_PSEC_PER_SEC;
phase = __div64_32(&nsec, 1000); picos-=sec*PP_PSEC_PER_SEC;
sec = nsec; nsec = picos/1000;
picos-=nsec*1000;
ts->scaled_nsecs = ((int64_t)__div64_32(&sec, PP_NSEC_PER_SEC)) << TIME_INTERVAL_FRACBITS; ts->scaled_nsecs = nsec << TIME_FRACBITS;
ts->scaled_nsecs += (phase << TIME_INTERVAL_FRACBITS) / 1000; ts->scaled_nsecs += (picos << TIME_FRACBITS) / 1000;
ts->scaled_nsecs *= sign; ts->scaled_nsecs *= sign;
ts->secs = sec * sign; ts->secs = sec * sign;
} }
#if 0
/* "Hardwarizes" the timestamp - e.g. makes the nanosecond field a multiple /* "Hardwarizes" the timestamp - e.g. makes the nanosecond field a multiple
* of 8/16ns cycles and puts the extra nanoseconds in the picos result */ * 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, void pp_time_hardwarize(struct pp_time *time, int clock_period_ps,
...@@ -105,6 +126,10 @@ void pp_time_hardwarize(struct pp_time *time, int clock_period_ps, ...@@ -105,6 +126,10 @@ void pp_time_hardwarize(struct pp_time *time, int clock_period_ps,
{ {
int32_t s, ns, ps, clock_ns; int32_t s, ns, ps, clock_ns;
if ( clock_period_ps <= 0 ) {
pp_error("%s : Invalid clock period %d\n",__func__, clock_period_ps);
exit(-1);
}
/* clock_period_ps *must* be a multiple of 1000 -- assert()? */ /* clock_period_ps *must* be a multiple of 1000 -- assert()? */
clock_ns = clock_period_ps / 1000; clock_ns = clock_period_ps / 1000;
...@@ -139,7 +164,26 @@ void pp_time_hardwarize(struct pp_time *time, int clock_period_ps, ...@@ -139,7 +164,26 @@ void pp_time_hardwarize(struct pp_time *time, int clock_period_ps,
*ticks = ns; *ticks = ns;
*picos = ps; *picos = ps;
} }
#else
/* "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)
{
int64_t ps, adj_ps;
int32_t sign=(time->scaled_nsecs<0) ? -1 : 1;
int64_t scaled_nsecs=time->scaled_nsecs*sign;
if ( clock_period_ps <= 0 ) {
pp_error("%s : Invalid clock period %d\n",__func__, clock_period_ps);
return;
}
ps = (scaled_nsecs * 1000L+TIME_INTERVAL_ROUNDING_VALUE) >> TIME_INTERVAL_FRACBITS; /* now picoseconds 0..999 -- positive*/
adj_ps=ps - ps%clock_period_ps;
*picos=(int32_t)(ps-adj_ps)*sign;
*ticks = (int32_t)(adj_ps/1000)*sign;
}
#endif
TimeInterval pp_time_to_interval(struct pp_time *ts) TimeInterval pp_time_to_interval(struct pp_time *ts)
{ {
...@@ -165,7 +209,7 @@ TimeInterval picos_to_interval(int64_t picos) ...@@ -165,7 +209,7 @@ TimeInterval picos_to_interval(int64_t picos)
int sign = (picos < 0 ? -1 : 1); int sign = (picos < 0 ? -1 : 1);
picos *= sign; picos *= sign;
scaled_ns=(picos/1000) << TIME_INTERVAL_FRACBITS; /* Calculate nanos */ scaled_ns=(picos/1000) << TIME_INTERVAL_FRACBITS; /* Calculate nanos */
scaled_ns|=((picos%1000) << TIME_INTERVAL_FRACBITS)/1000; /* Add picos */ scaled_ns+=((picos%1000) << TIME_INTERVAL_FRACBITS)/1000; /* Add picos */
return scaled_ns*sign; return scaled_ns*sign;
} }
...@@ -214,3 +258,65 @@ int is_timestamps_incorrect(struct pp_instance *ppsi, int *err_count, int ts_mas ...@@ -214,3 +258,65 @@ int is_timestamps_incorrect(struct pp_instance *ppsi, int *err_count, int ts_mas
} }
return *err_count=0; return *err_count=0;
} }
static char time_as_string[32];
/* Convert pp_time to string */
char *time_to_string(struct pp_time *t)
{
struct pp_time time=*t;
int picos;
char *sign;
if (t->secs < 0 || (t->secs == 0 && t->scaled_nsecs < 0) ) {
sign="-";
time.scaled_nsecs=-t->scaled_nsecs;
time.secs=-t->secs;
} else {
sign="";
time=*t;
}
picos=((int)(time.scaled_nsecs&TIME_FRACMASK)*1000+TIME_ROUNDING_VALUE)>>TIME_FRACBITS;
pp_sprintf(time_as_string, "%s%d.%09d%03d",
sign,
(int)time.secs,
(int)(time.scaled_nsecs >> TIME_FRACBITS),
picos);
return time_as_string;
}
/* Convert TimeInterval to string */
char *interval_to_string(TimeInterval time)
{
int64_t sign,nanos,picos;
if ( time<0 && time !=INT64_MIN) {
sign=-1;
time=-time;
} else {
sign=1;
}
nanos = time >> TIME_INTERVAL_FRACBITS;
picos = (((time & TIME_INTERVAL_FRACMASK) * 1000) + TIME_INTERVAL_ROUNDING_VALUE ) >> TIME_INTERVAL_FRACBITS;
sprintf(time_as_string,"%" PRId64 ".%03" PRId64, sign*nanos,picos);
return time_as_string;
}
/* Convert RelativeInterval to string */
char *relative_interval_to_string(TimeInterval time) {
int32_t nsecs=time >> REL_DIFF_FRACBITS;
uint64_t sub_yocto=0;
int64_t fraction;
uint64_t bitWeight=500000000000000000;
uint64_t mask;
fraction=time & REL_DIFF_FRACMASK;
for (mask=(uint64_t) 1<< (REL_DIFF_FRACBITS-1);mask!=0; mask>>=1 ) {
if ( mask & fraction )
sub_yocto+=bitWeight;
bitWeight/=2;
}
sprintf(time_as_string,"%"PRId32".%018"PRIu64, nsecs, sub_yocto);
return time_as_string;
}
...@@ -101,11 +101,8 @@ typedef struct { /*draft P1588_v_29: page 101 and 340-341 */ ...@@ -101,11 +101,8 @@ typedef struct { /*draft P1588_v_29: page 101 and 340-341 */
/* Add all extension port DS related structure must be store here */ /* Add all extension port DS related structure must be store here */
typedef struct { typedef struct {
wrh_portds_head_t head; /* Must be always at the first place */
L1SyncBasicPortDS_t basic; L1SyncBasicPortDS_t basic;
L1SyncOptParamsPortDS_t opt_params; L1SyncOptParamsPortDS_t opt_params;
Boolean parentExtModeOn;
}l1e_ext_portDS_t; }l1e_ext_portDS_t;
static inline l1e_ext_portDS_t *L1E_DSPOR(struct pp_instance *ppi) static inline l1e_ext_portDS_t *L1E_DSPOR(struct pp_instance *ppi)
...@@ -127,13 +124,23 @@ static inline L1SyncOptParamsPortDS_t *L1E_DSPOR_OP(struct pp_instance *ppi) ...@@ -127,13 +124,23 @@ static inline L1SyncOptParamsPortDS_t *L1E_DSPOR_OP(struct pp_instance *ppi)
/****************************************************************************************/ /****************************************************************************************/
/* l1e_servo interface */ /* l1e_servo interface */
#define L1E_SERVO_RESET_DATA_SIZE (sizeof(struct l1e_servo_state)-offsetof(struct l1e_servo_state,reset_address))
#define L1E_SERVO_RESET_DATA(servo) memset(&servo->reset_address,0,L1E_SERVO_RESET_DATA_SIZE);
struct l1e_servo_state { struct l1e_servo_state {
/* Values used by snmp. Values are increased at servo update when
* erroneous condition occurs. */
uint32_t n_err_state;
uint32_t n_err_offset;
uint32_t n_err_delta_rtt;
/* ----- All data after this line will cleared during a servo reset */
int reset_address;
/* These fields are used by servo code, after setting at init time */ /* These fields are used by servo code, after setting at init time */
int32_t clock_period_ps; int32_t clock_period_ps;
/* Following fields are for monitoring/diagnostics (use w/ shmem) */ /* Following fields are for monitoring/diagnostics (use w/ shmem) */
struct pp_time delayMM;
int64_t delayMM_ps; int64_t delayMM_ps;
int32_t cur_setpoint_ps; int32_t cur_setpoint_ps;
int64_t delayMS_ps; int64_t delayMS_ps;
...@@ -141,15 +148,7 @@ struct l1e_servo_state { ...@@ -141,15 +148,7 @@ struct l1e_servo_state {
int64_t skew_ps; int64_t skew_ps;
int64_t offsetMS_ps; int64_t offsetMS_ps;
/* Values used by snmp. Values are increased at servo update when
* erroneous condition occurs. */
uint32_t n_err_state;
uint32_t n_err_offset;
uint32_t n_err_delta_rtt;
struct pp_time update_time;
/* These fields are used by servo code, across iterations */ /* These fields are used by servo code, across iterations */
struct pp_time t1, t2, t3, t4, t5, t6;
int64_t prev_delayMS_ps; int64_t prev_delayMS_ps;
int missed_iters; int missed_iters;
}; };
...@@ -158,9 +157,9 @@ struct l1e_servo_state { ...@@ -158,9 +157,9 @@ struct l1e_servo_state {
int l1e_servo_init(struct pp_instance *ppi); int l1e_servo_init(struct pp_instance *ppi);
void l1e_servo_reset(struct pp_instance *ppi); void l1e_servo_reset(struct pp_instance *ppi);
void l1e_servo_enable_tracking(int enable); void l1e_servo_enable_tracking(int enable);
int l1e_servo_got_sync(struct pp_instance *ppi, struct pp_time *t1, int l1e_servo_got_sync(struct pp_instance *ppi);
struct pp_time *t2); int l1e_servo_got_resp(struct pp_instance *ppi);
int l1e_servo_got_delay(struct pp_instance *ppi); int l1e_servo_got_presp(struct pp_instance *ppi);
int l1e_servo_update(struct pp_instance *ppi); int l1e_servo_update(struct pp_instance *ppi);
uint8_t l1e_creat_L1Sync_bitmask(int tx_coh, int rx_coh, int congru); uint8_t l1e_creat_L1Sync_bitmask(int tx_coh, int rx_coh, int congru);
void l1e_print_L1Sync_basic_bitmaps(struct pp_instance *ppi, void l1e_print_L1Sync_basic_bitmaps(struct pp_instance *ppi,
...@@ -180,6 +179,9 @@ static inline struct l1e_servo_state *L1E_SRV(struct pp_instance *ppi) ...@@ -180,6 +179,9 @@ static inline struct l1e_servo_state *L1E_SRV(struct pp_instance *ppi)
} }
static inline int l1e_get_rx_tmo_ms(L1SyncBasicPortDS_t * bds) {
return (4 << (bds->logL1SyncInterval + 8)) * bds->L1SyncReceiptTimeout;
}
extern struct pp_ext_hooks l1e_ext_hooks; extern struct pp_ext_hooks l1e_ext_hooks;
......
...@@ -19,7 +19,6 @@ char *l1e_state_name[] = { ...@@ -19,7 +19,6 @@ char *l1e_state_name[] = {
[L1SYNC_UP] = "L1SYNC_UP", [L1SYNC_UP] = "L1SYNC_UP",
}; };
void l1e_print_L1Sync_basic_bitmaps(struct pp_instance *ppi, uint8_t configed, void l1e_print_L1Sync_basic_bitmaps(struct pp_instance *ppi, uint8_t configed,
uint8_t active, char* text) uint8_t active, char* text)
{ {
...@@ -100,6 +99,7 @@ static int l1e_init(struct pp_instance *ppi, void *buf, int len) ...@@ -100,6 +99,7 @@ static int l1e_init(struct pp_instance *ppi, void *buf, int len)
/* Init configuration members of L1SyncOptParamsPortDS */ /* Init configuration members of L1SyncOptParamsPortDS */
L1E_DSPOR_OP(ppi)->timestampsCorrectedTx=TRUE; L1E_DSPOR_OP(ppi)->timestampsCorrectedTx=TRUE;
ppi->ext_enabled=TRUE;
return 0; return 0;
} }
...@@ -112,13 +112,16 @@ static int l1e_handle_signaling(struct pp_instance * ppi, void *buf, int len) ...@@ -112,13 +112,16 @@ static int l1e_handle_signaling(struct pp_instance * ppi, void *buf, int len)
if ( l1e_unpack_signal(ppi, buf, len)==0 ) { if ( l1e_unpack_signal(ppi, buf, len)==0 ) {
/* Valid Sync message */ /* Valid Sync message */
int timeout_tx_sync;
/* Reset reception timeout */ /* Reset reception timeout */
timeout_tx_sync = (4 << (bds->logL1SyncInterval + 8)) * bds->L1SyncReceiptTimeout; __pp_timeout_set(ppi, L1E_TIMEOUT_RX_SYNC, l1e_get_rx_tmo_ms(bds));
__pp_timeout_set(ppi, L1E_TIMEOUT_RX_SYNC, timeout_tx_sync);
bds->L1SyncLinkAlive = TRUE; bds->L1SyncLinkAlive = TRUE;
if ( ppi->link_state==PP_LSTATE_PROTOCOL_DETECTION ||
ppi->link_state==PP_LSTATE_FAILURE) {
ppi->link_state=PP_LSTATE_IN_PROGRESS;
ppi->ext_enabled=TRUE; // Force L1SYNC extension as L1SYNC messages are received
}
} }
return 0; return 0;
} }
...@@ -135,102 +138,64 @@ uint8_t l1e_creat_L1Sync_bitmask(int tx_coh, int rx_coh, int congru) ...@@ -135,102 +138,64 @@ uint8_t l1e_creat_L1Sync_bitmask(int tx_coh, int rx_coh, int congru)
static int l1e_handle_resp(struct pp_instance *ppi) static int l1e_handle_resp(struct pp_instance *ppi)
{ {
struct pp_time *ofm = &SRV(ppi)->offsetFromMaster;
l1e_ext_portDS_t *l1epds = L1E_DSPOR(ppi);
pp_diag(ppi, ext, 2, "hook: %s\n", __func__); pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
if ( l1epds->basic.L1SyncState != L1SYNC_UP )
return 0;
/* This correction_field we received is already part of t4 */ /* This correction_field we received is already part of t4 */
if ( ppi->ext_enabled ) {
/* l1e_servo_got_resp(ppi);
* If no WR mode is on, run normal code, if T2/T3 are valid. }
* After we adjusted the pps counter, stamps are invalid, so else {
* we'll have the Unix time instead, marked by "correct"
*/
if (!l1epds->head.extModeOn) {
if ( is_timestamps_incorrect(ppi, NULL, 0x6 /* mask=t2&t3 */) ) {
pp_diag(ppi, servo, 1,"T2 or T3 incorrect, discarding tuple\n");
return 0;
}
pp_servo_got_resp(ppi); pp_servo_got_resp(ppi);
/* WRH_OPER()->enable_timing_output(ppi,
* pps always on if offset less than 1 second, ppi->state==PPS_SLAVE &&
* until we have a configurable threshold */ SRV(ppi)->offsetFromMaster.secs==0 &&
WRH_OPER()->enable_timing_output(ppi, ofm->secs==0); SRV(ppi)->offsetFromMaster.scaled_nsecs!=0);
} }
l1e_servo_got_delay(ppi);
l1e_servo_update(ppi);
return 0; return 0;
} }
static int l1e_sync_followup(struct pp_instance *ppi, struct pp_time *t1) { static int l1e_sync_followup(struct pp_instance *ppi) {
l1e_ext_portDS_t *pds=L1E_DSPOR(ppi); if ( ppi->ext_enabled ) {
l1e_servo_got_sync(ppi);
if ((pds->basic.L1SyncState != L1SYNC_UP) || !pds->head.extModeOn ) }
return 0; else {
pp_servo_got_sync(ppi);
l1e_servo_got_sync(ppi, t1, &ppi->t2); if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P ) {
/* pps always on if offset less than 1 second,
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P) * until ve have a configurable threshold
l1e_servo_update(ppi); */
WRH_OPER()->enable_timing_output(ppi,
ppi->state==PPS_SLAVE &&
SRV(ppi)->offsetFromMaster.secs==0 &&
SRV(ppi)->offsetFromMaster.scaled_nsecs!=0);
}
}
return 1; /* the caller returns too */ return 1; /* the caller returns too */
} }
/* Hmm... "execute_slave" should look for errors; but it's off in WR too */ /* Hmm... "execute_slave" should look for errors; but it's off in WR too */
static int l1e_handle_followup(struct pp_instance *ppi, static int l1e_handle_followup(struct pp_instance *ppi)
struct pp_time *t1)
{ {
/* This handle is called in case of two step clock */ /* This handle is called in case of two step clock */
pp_diag(ppi, ext, 2, "hook: %s\n", __func__); pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
return l1e_sync_followup(ppi,t1); return l1e_sync_followup(ppi);
} }
static int l1e_handle_sync(struct pp_instance *ppi, static int l1e_handle_sync(struct pp_instance *ppi)
struct pp_time *t1)
{ {
/* This handle is called in case of one step clock */ /* This handle is called in case of one step clock */
pp_diag(ppi, ext, 2, "hook: %s\n", __func__); pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
return l1e_sync_followup(ppi,t1); return l1e_sync_followup(ppi);
} }
static __attribute__((used)) int l1e_handle_presp(struct pp_instance *ppi) static __attribute__((used)) int l1e_handle_presp(struct pp_instance *ppi)
{ {
struct pp_time *ofm = &SRV(ppi)->offsetFromMaster;
l1e_ext_portDS_t *pds=L1E_DSPOR(ppi);
/* Servo is active only when the state is UP */
if ( pds->basic.L1SyncState != L1SYNC_UP )
return 0;
/*
* If no WR mode is on, run normal code, if T2/T3 are valid.
* After we adjusted the pps counter, stamps are invalid, so
* we'll have the Unix time instead, marked by "correct"
*/
if (!WRH_DSPOR_HEAD(ppi)->extModeOn) {
if ( is_timestamps_incorrect(ppi, NULL, 0x24 /* mask=t3&t6 */) ) {
pp_diag(ppi, servo, 1,
"T3 or T6 incorrect, discarding tuple\n");
return 0;
}
pp_servo_got_presp(ppi);
/*
* pps always on if offset less than 1 second,
* until ve have a configurable threshold */
WRH_OPER()->enable_timing_output(ppi, ofm->secs==0);
return 0;
}
/* FIXME: verify that last-received cField is already accounted for */ /* FIXME: verify that last-received cField is already accounted for */
l1e_servo_got_delay(ppi); if ( ppi->ext_enabled )
l1e_servo_got_presp(ppi);
else
pp_servo_got_presp(ppi);
return 0; return 0;
} }
...@@ -244,8 +209,9 @@ static int l1e_ready_for_slave(struct pp_instance *ppi) ...@@ -244,8 +209,9 @@ static int l1e_ready_for_slave(struct pp_instance *ppi)
return 1; /* Ready for slave */ return 1; /* Ready for slave */
} }
static void l1e_state_change(struct pp_instance *ppi) { static void l1e_state_change(struct pp_instance *ppi) {
if ( !ppi->ext_enabled)
return;
switch (ppi->next_state) { switch (ppi->next_state) {
case PPS_DISABLED : case PPS_DISABLED :
/* In PPSI we go to DISABLE state when the link is down */ /* In PPSI we go to DISABLE state when the link is down */
...@@ -259,6 +225,20 @@ static void l1e_state_change(struct pp_instance *ppi) { ...@@ -259,6 +225,20 @@ static void l1e_state_change(struct pp_instance *ppi) {
} }
} }
static int l1e_new_slave (struct pp_instance *ppi, void *buf, int len) {
if ( ppi->ext_enabled )
l1e_servo_init(ppi);
return 0;
}
static int l1e_require_precise_timestamp(struct pp_instance *ppi) {
return ppi->ext_enabled ? L1E_DSPOR_BS(ppi)->L1SyncState==L1SYNC_UP : 0;
}
static int l1e_get_tmo_lstate_detection(struct pp_instance *ppi) {
return l1e_get_rx_tmo_ms(L1E_DSPOR_BS(ppi));
}
/* The global structure used by ppsi */ /* The global structure used by ppsi */
struct pp_ext_hooks l1e_ext_hooks = { struct pp_ext_hooks l1e_ext_hooks = {
.open = l1e_open, .open = l1e_open,
...@@ -269,9 +249,13 @@ struct pp_ext_hooks l1e_ext_hooks = { ...@@ -269,9 +249,13 @@ struct pp_ext_hooks l1e_ext_hooks = {
.handle_resp = l1e_handle_resp, .handle_resp = l1e_handle_resp,
.handle_sync = l1e_handle_sync, .handle_sync = l1e_handle_sync,
.handle_followup = l1e_handle_followup, .handle_followup = l1e_handle_followup,
.new_slave = l1e_new_slave,
#if CONFIG_HAS_P2P #if CONFIG_HAS_P2P
.handle_presp = l1e_handle_presp, .handle_presp = l1e_handle_presp,
#endif #endif
.state_change = l1e_state_change, .state_change = l1e_state_change,
.servo_reset= l1e_servo_reset,
.require_precise_timestamp=l1e_require_precise_timestamp,
.get_tmo_lstate_detection=l1e_get_tmo_lstate_detection
}; };
This diff is collapsed.
...@@ -47,7 +47,6 @@ static l1e_state_machine_t le1_state_actions[] ={ ...@@ -47,7 +47,6 @@ static l1e_state_machine_t le1_state_actions[] ={
}, },
}; };
/* /*
* This hook is called by fsm to run the extension state machine. * This hook is called by fsm to run the extension state machine.
* It is used to send signaling messages. * It is used to send signaling messages.
...@@ -60,6 +59,9 @@ int l1e_run_state_machine(struct pp_instance *ppi) { ...@@ -60,6 +59,9 @@ int l1e_run_state_machine(struct pp_instance *ppi) {
Boolean newState=nextState!=basicDS->L1SyncState; Boolean newState=nextState!=basicDS->L1SyncState;
int delay; int delay;
if ( !ppi->ext_enabled )
return INT_MAX; /* Return a big delay. fsm will then not use it */
if ( nextState>=MAX_STATE_ACTIONS) if ( nextState>=MAX_STATE_ACTIONS)
return pp_next_delay_2(ppi,L1E_TIMEOUT_TX_SYNC, L1E_TIMEOUT_RX_SYNC); return pp_next_delay_2(ppi,L1E_TIMEOUT_TX_SYNC, L1E_TIMEOUT_RX_SYNC);
...@@ -74,8 +76,7 @@ int l1e_run_state_machine(struct pp_instance *ppi) { ...@@ -74,8 +76,7 @@ int l1e_run_state_machine(struct pp_instance *ppi) {
/* Check L1SYNC reception Time-out */ /* Check L1SYNC reception Time-out */
if ( pp_timeout(ppi, L1E_TIMEOUT_RX_SYNC) ) { if ( pp_timeout(ppi, L1E_TIMEOUT_RX_SYNC) ) {
/* Time-out detected */ /* Time-out detected */
int timeout_tx_sync = (4 << (basicDS->logL1SyncInterval + 8)) * basicDS->L1SyncReceiptTimeout; __pp_timeout_set(ppi, L1E_TIMEOUT_RX_SYNC, l1e_get_rx_tmo_ms(basicDS));
__pp_timeout_set(ppi, L1E_TIMEOUT_RX_SYNC, timeout_tx_sync);
basicDS->L1SyncLinkAlive = FALSE; basicDS->L1SyncLinkAlive = FALSE;
execute_state_machine=TRUE; execute_state_machine=TRUE;
} }
...@@ -248,8 +249,6 @@ static int l1e_handle_state_disabled(struct pp_instance *ppi, Boolean new_state) ...@@ -248,8 +249,6 @@ static int l1e_handle_state_disabled(struct pp_instance *ppi, Boolean new_state)
l1e_portDS->basic.peerIsRxCoherent = l1e_portDS->basic.peerIsRxCoherent =
l1e_portDS->basic.peerIsCongruent = l1e_portDS->basic.peerIsCongruent =
FALSE; FALSE;
/* Set extension mode disabled */
l1e_portDS->head.extModeOn = l1e_portDS->parentExtModeOn = 0;
} }
/* Check if state transition needed */ /* Check if state transition needed */
if ( le1_evt_L1_SYNC_ENABLED(ppi) && !le1_evt_L1_SYNC_RESET(ppi) ) { if ( le1_evt_L1_SYNC_ENABLED(ppi) && !le1_evt_L1_SYNC_RESET(ppi) ) {
...@@ -276,8 +275,6 @@ static int l1e_handle_state_idle(struct pp_instance *ppi, Boolean new_state){ ...@@ -276,8 +275,6 @@ static int l1e_handle_state_idle(struct pp_instance *ppi, Boolean new_state){
l1e_portDS->basic.peerIsTxCoherent = l1e_portDS->basic.peerIsTxCoherent =
l1e_portDS->basic.peerIsRxCoherent= l1e_portDS->basic.peerIsRxCoherent=
l1e_portDS->basic.peerIsCongruent = FALSE; l1e_portDS->basic.peerIsCongruent = FALSE;
/* Set extension mode disabled */
l1e_portDS->head.extModeOn = l1e_portDS->parentExtModeOn = 0;
l1e_send_sync_msg(ppi,1); /* Send immediately a message */ l1e_send_sync_msg(ppi,1); /* Send immediately a message */
} }
...@@ -285,6 +282,7 @@ static int l1e_handle_state_idle(struct pp_instance *ppi, Boolean new_state){ ...@@ -285,6 +282,7 @@ static int l1e_handle_state_idle(struct pp_instance *ppi, Boolean new_state){
if ( !le1_evt_L1_SYNC_ENABLED(ppi) || le1_evt_L1_SYNC_RESET(ppi) ) { if ( !le1_evt_L1_SYNC_ENABLED(ppi) || le1_evt_L1_SYNC_RESET(ppi) ) {
/* Go to DISABLE state */ /* Go to DISABLE state */
l1e_portDS->basic.next_state=L1SYNC_DISABLED; l1e_portDS->basic.next_state=L1SYNC_DISABLED;
ppi->link_state=PP_LSTATE_FAILURE;
return 0; /* Treatment required asap */ return 0; /* Treatment required asap */
} }
if ( le1_evt_LINK_OK(ppi) ) { if ( le1_evt_LINK_OK(ppi) ) {
...@@ -303,8 +301,7 @@ static int l1e_handle_state_link_alive(struct pp_instance *ppi, Boolean new_stat ...@@ -303,8 +301,7 @@ static int l1e_handle_state_link_alive(struct pp_instance *ppi, Boolean new_stat
/* State initialization */ /* State initialization */
if ( new_state ) { if ( new_state ) {
/* Initialize time-out peer L1SYNC reception */ /* Initialize time-out peer L1SYNC reception */
int timeout_tx_sync = (4 << (basic->logL1SyncInterval + 8)) * basic->L1SyncReceiptTimeout; __pp_timeout_set(ppi, L1E_TIMEOUT_RX_SYNC, l1e_get_rx_tmo_ms(basic));
__pp_timeout_set(ppi, L1E_TIMEOUT_RX_SYNC, timeout_tx_sync);
} }
/* Check if state transition needed */ /* Check if state transition needed */
...@@ -374,9 +371,9 @@ static int l1e_handle_state_up(struct pp_instance *ppi, Boolean new_state){ ...@@ -374,9 +371,9 @@ static int l1e_handle_state_up(struct pp_instance *ppi, Boolean new_state){
/* State initialization */ /* State initialization */
if ( new_state ) { if ( new_state ) {
l1e_servo_init(ppi); /* The servo can be initialized because the PPL is locked */ // JCB - test one servo
l1e_portDS->head.extModeOn = // l1e_servo_init(ppi); /* The servo can be initialized because the PPL is locked */
l1e_portDS->parentExtModeOn = 1;
WRH_OPER()->enable_ptracker(ppi); WRH_OPER()->enable_ptracker(ppi);
} }
...@@ -384,6 +381,7 @@ static int l1e_handle_state_up(struct pp_instance *ppi, Boolean new_state){ ...@@ -384,6 +381,7 @@ static int l1e_handle_state_up(struct pp_instance *ppi, Boolean new_state){
if ( !le1_evt_LINK_OK(ppi) ) { if ( !le1_evt_LINK_OK(ppi) ) {
/* Go to IDLE state */ /* Go to IDLE state */
next_state=L1SYNC_IDLE; next_state=L1SYNC_IDLE;
ppi->link_state=PP_LSTATE_FAILURE;
} }
if ( !le1_evt_CONFIG_OK(ppi) ) { if ( !le1_evt_CONFIG_OK(ppi) ) {
/* Return to LINK_ALIVE state */ /* Return to LINK_ALIVE state */
...@@ -395,14 +393,13 @@ static int l1e_handle_state_up(struct pp_instance *ppi, Boolean new_state){ ...@@ -395,14 +393,13 @@ static int l1e_handle_state_up(struct pp_instance *ppi, Boolean new_state){
} }
if (next_state!=0 ) { if (next_state!=0 ) {
l1e_portDS->basic.next_state=next_state; l1e_portDS->basic.next_state=next_state;
l1e_portDS->head.extModeOn =
l1e_portDS->parentExtModeOn = 0;
WRH_OPER()->locking_disable(ppi); /* Unlock the PLL */ WRH_OPER()->locking_disable(ppi); /* Unlock the PLL */
l1e_servo_reset(ppi); l1e_servo_reset(ppi);
return 0; /* Treat the next state asap */ return 0; /* Treat the next state asap */
} }
/* Iterative treatment */ /* Iterative treatment */
ppi->link_state=PP_LSTATE_LINKED;
l1e_update_correction_values(ppi); l1e_update_correction_values(ppi);
l1e_send_sync_msg(ppi,0); l1e_send_sync_msg(ppi,0);
return pp_next_delay_2(ppi,L1E_TIMEOUT_TX_SYNC, L1E_TIMEOUT_RX_SYNC); /* Return the shorter timeout */ return pp_next_delay_2(ppi,L1E_TIMEOUT_TX_SYNC, L1E_TIMEOUT_RX_SYNC); /* Return the shorter timeout */
......
...@@ -187,12 +187,12 @@ static int wr_handle_announce(struct pp_instance *ppi) ...@@ -187,12 +187,12 @@ static int wr_handle_announce(struct pp_instance *ppi)
return 0; return 0;
} }
static int wr_sync_followup(struct pp_instance *ppi, struct pp_time *t1) { static int wr_sync_followup(struct pp_instance *ppi) {
if (!WR_DSPOR(ppi)->wrModeOn) if (!WR_DSPOR(ppi)->wrModeOn)
return 0; return 0;
wr_servo_got_sync(ppi, t1, &ppi->t2); wr_servo_got_sync(ppi);
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P) if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P)
wr_servo_update(ppi); wr_servo_update(ppi);
...@@ -200,18 +200,18 @@ static int wr_sync_followup(struct pp_instance *ppi, struct pp_time *t1) { ...@@ -200,18 +200,18 @@ static int wr_sync_followup(struct pp_instance *ppi, struct pp_time *t1) {
return 1; /* the caller returns too */ return 1; /* the caller returns too */
} }
static int wr_handle_sync(struct pp_instance *ppi, struct pp_time *t1) static int wr_handle_sync(struct pp_instance *ppi)
{ {
/* This handle is called in case of one step clock */ /* This handle is called in case of one step clock */
pp_diag(ppi, ext, 2, "hook: %s\n", __func__); pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
return wr_sync_followup(ppi,t1); return wr_sync_followup(ppi);
} }
static int wr_handle_followup(struct pp_instance *ppi, struct pp_time *t1) static int wr_handle_followup(struct pp_instance *ppi)
{ {
/* This handle is called in case of two step clock */ /* This handle is called in case of two step clock */
pp_diag(ppi, ext, 2, "hook: %s\n", __func__); pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
return wr_sync_followup(ppi,t1); return wr_sync_followup(ppi);
} }
static __attribute__((used)) int wr_handle_presp(struct pp_instance *ppi) static __attribute__((used)) int wr_handle_presp(struct pp_instance *ppi)
...@@ -328,6 +328,10 @@ static void wr_state_change(struct pp_instance *ppi) ...@@ -328,6 +328,10 @@ static void wr_state_change(struct pp_instance *ppi)
} }
} }
static int wr_require_precise_timestamp(struct pp_instance *ppi) {
return WR_DSPOR(ppi)->wrModeOn;
}
struct pp_ext_hooks wr_ext_hooks = { struct pp_ext_hooks wr_ext_hooks = {
.init = wr_init, .init = wr_init,
.open = wr_open, .open = wr_open,
...@@ -347,4 +351,6 @@ struct pp_ext_hooks wr_ext_hooks = { ...@@ -347,4 +351,6 @@ struct pp_ext_hooks wr_ext_hooks = {
.unpack_announce = wr_unpack_announce, .unpack_announce = wr_unpack_announce,
.state_decision = wr_state_decision, .state_decision = wr_state_decision,
.state_change = wr_state_change, .state_change = wr_state_change,
.servo_reset= wr_servo_reset,
.require_precise_timestamp=wr_require_precise_timestamp,
}; };
...@@ -110,8 +110,7 @@ int wr_execute_slave(struct pp_instance *ppi); ...@@ -110,8 +110,7 @@ int wr_execute_slave(struct pp_instance *ppi);
int wr_servo_init(struct pp_instance *ppi); int wr_servo_init(struct pp_instance *ppi);
void wr_servo_reset(struct pp_instance *ppi); void wr_servo_reset(struct pp_instance *ppi);
void wr_servo_enable_tracking(int enable); void wr_servo_enable_tracking(int enable);
int wr_servo_got_sync(struct pp_instance *ppi, struct pp_time *t1, int wr_servo_got_sync(struct pp_instance *ppi);
struct pp_time *t2);
int wr_servo_got_delay(struct pp_instance *ppi); int wr_servo_got_delay(struct pp_instance *ppi);
int wr_servo_update(struct pp_instance *ppi); int wr_servo_update(struct pp_instance *ppi);
......
...@@ -181,7 +181,7 @@ int msg_pack_wrsig(struct pp_instance *ppi, Enumeration16 wr_msg_id) ...@@ -181,7 +181,7 @@ int msg_pack_wrsig(struct pp_instance *ppi, Enumeration16 wr_msg_id)
put_be32(buf+68, wrp->deltaRx.scaledPicoseconds.lsb); put_be32(buf+68, wrp->deltaRx.scaledPicoseconds.lsb);
len = 24; len = 24;
/*JCB: Hack. serrvo_init() called too early. PTP state machine must be modify. */ /*JCB: Hack. servo_init() called too early. PTP state machine must be modify. */
/* We should stay in UNCALIBRATED state during WR protocol */ /* We should stay in UNCALIBRATED state during WR protocol */
s->delta_txm_ps = delta_to_ps(wrp->otherNodeDeltaTx); s->delta_txm_ps = delta_to_ps(wrp->otherNodeDeltaTx);
s->delta_rxm_ps = delta_to_ps(wrp->otherNodeDeltaRx); s->delta_rxm_ps = delta_to_ps(wrp->otherNodeDeltaRx);
......
...@@ -150,14 +150,13 @@ int wr_servo_init(struct pp_instance *ppi) ...@@ -150,14 +150,13 @@ int wr_servo_init(struct pp_instance *ppi)
return 0; return 0;
} }
int wr_servo_got_sync(struct pp_instance *ppi, struct pp_time *t1, int wr_servo_got_sync(struct pp_instance *ppi)
struct pp_time *t2)
{ {
struct wr_servo_state *s = struct wr_servo_state *s =
&((struct wr_data *)ppi->ext_data)->servo_state; &((struct wr_data *)ppi->ext_data)->servo_state;
s->t1 = *t1; apply_faulty_stamp(s, 1); s->t1 = ppi->t1; apply_faulty_stamp(s, 1);
s->t2 = *t2; apply_faulty_stamp(s, 2); s->t2 = ppi->t2; apply_faulty_stamp(s, 2);
got_sync = 1; got_sync = 1;
return 0; return 0;
} }
...@@ -222,8 +221,6 @@ static int wr_p2p_delay(struct pp_instance *ppi, struct wr_servo_state *s) ...@@ -222,8 +221,6 @@ static int wr_p2p_delay(struct pp_instance *ppi, struct wr_servo_state *s)
} }
if (__PP_DIAG_ALLOW(ppi, pp_dt_servo, 1)) { if (__PP_DIAG_ALLOW(ppi, pp_dt_servo, 1)) {
dump_timestamp(ppi, "servo:t1", s->t1);
dump_timestamp(ppi, "servo:t2", s->t2);
dump_timestamp(ppi, "servo:t3", s->t3); dump_timestamp(ppi, "servo:t3", s->t3);
dump_timestamp(ppi, "servo:t4", s->t4); dump_timestamp(ppi, "servo:t4", s->t4);
dump_timestamp(ppi, "servo:t5", s->t5); dump_timestamp(ppi, "servo:t5", s->t5);
...@@ -285,9 +282,6 @@ static int wr_e2e_offset(struct pp_instance *ppi, ...@@ -285,9 +282,6 @@ static int wr_e2e_offset(struct pp_instance *ppi,
if ( is_timestamps_incorrect(ppi,&errcount, 0xF /* mask=t1&t2&t3&t4 */)) if ( is_timestamps_incorrect(ppi,&errcount, 0xF /* mask=t1&t2&t3&t4 */))
return 0; return 0;
if (WRH_OPER()->servo_hook) /* FIXME: check this, missing in p2p */
WRH_OPER()->servo_hook(ppi, WRH_SERVO_ENTER);
SRV(ppi)->update_count++; SRV(ppi)->update_count++;
ppi->t_ops->get(ppi, &s->update_time); ppi->t_ops->get(ppi, &s->update_time);
...@@ -523,8 +517,5 @@ out: ...@@ -523,8 +517,5 @@ out:
/* shmem unlock */ /* shmem unlock */
wrs_shm_write(ppsi_head, WRS_SHM_WRITE_END); wrs_shm_write(ppsi_head, WRS_SHM_WRITE_END);
if (WRH_OPER()->servo_hook)
WRH_OPER()->servo_hook(ppi, WRH_SERVO_LEAVE);
return 0; return 0;
} }
...@@ -284,7 +284,7 @@ void bmc_s1(struct pp_instance *ppi, ...@@ -284,7 +284,7 @@ void bmc_s1(struct pp_instance *ppi,
prop->ptpTimescale = ((frgn_master->flagField[1] & FFB_PTP) != 0); prop->ptpTimescale = ((frgn_master->flagField[1] & FFB_PTP) != 0);
prop->timeSource = frgn_master->timeSource; prop->timeSource = frgn_master->timeSource;
if (ppi->ext_hooks->s1) if (is_ext_hook_available(ppi,s1))
ppi->ext_hooks->s1(ppi, frgn_master); ppi->ext_hooks->s1(ppi, frgn_master);
} }
...@@ -1509,7 +1509,7 @@ int bmc(struct pp_instance *ppi) ...@@ -1509,7 +1509,7 @@ int bmc(struct pp_instance *ppi)
} }
/* Extra states handled here */ /* Extra states handled here */
if (ppi->ext_hooks->state_decision) if (is_ext_hook_available(ppi,state_decision))
next_state = ppi->ext_hooks->state_decision(ppi, next_state); next_state = ppi->ext_hooks->state_decision(ppi, next_state);
return next_state; return next_state;
......
...@@ -21,11 +21,20 @@ static int presp_call_servo(struct pp_instance *ppi) ...@@ -21,11 +21,20 @@ static int presp_call_servo(struct pp_instance *ppi)
return 0; /* not an error, just no data */ return 0; /* not an error, just no data */
pp_timeout_set(ppi, PP_TO_FAULT); pp_timeout_set(ppi, PP_TO_FAULT);
if (ppi->ext_hooks->handle_presp) if (is_ext_hook_available(ppi,handle_presp))
ret = ppi->ext_hooks->handle_presp(ppi); ret = ppi->ext_hooks->handle_presp(ppi);
else else {
pp_servo_got_presp(ppi); if ( pp_servo_got_presp(ppi) && !ppi->ext_enabled ) {
ppi->link_state=PP_LSTATE_LINKED;
}
}
if ( ppi->state==PPS_MASTER) {
/* Called to update meanLinkDelay
* No risk of interaction with the slave servo.
* Each instance has its own servo structure
*/
pp_servo_calculate_delays(ppi);
}
return ret; return ret;
} }
...@@ -146,13 +155,17 @@ int st_com_peer_handle_preq(struct pp_instance *ppi, void *buf, ...@@ -146,13 +155,17 @@ int st_com_peer_handle_preq(struct pp_instance *ppi, void *buf,
if (ppi->delayMechanism != P2P) if (ppi->delayMechanism != P2P)
return 0; return 0;
if (ppi->ext_hooks->handle_preq) if (is_ext_hook_available(ppi,handle_preq))
e = ppi->ext_hooks->handle_preq(ppi); e = ppi->ext_hooks->handle_preq(ppi);
if (e) if (e)
return e; return e;
msg_issue_pdelay_resp(ppi, &ppi->last_rcv_time); msg_issue_pdelay_resp(ppi, &ppi->last_rcv_time);
msg_issue_pdelay_resp_followup(ppi, &ppi->last_snt_time); msg_issue_pdelay_resp_followup(ppi, &ppi->last_snt_time);
if ( !ppi->ext_enabled ) {
ppi->link_state=PP_LSTATE_LINKED;
}
return 0; return 0;
} }
......
...@@ -122,14 +122,14 @@ int st_com_handle_announce(struct pp_instance *ppi, void *buf, int len) ...@@ -122,14 +122,14 @@ int st_com_handle_announce(struct pp_instance *ppi, void *buf, int len)
if ( ! DSPOR(ppi)->masterOnly ) { if ( ! DSPOR(ppi)->masterOnly ) {
bmc_add_frgn_master(ppi, buf, len); bmc_add_frgn_master(ppi, buf, len);
} }
if (ppi->ext_hooks->handle_announce) if (is_ext_hook_available(ppi,handle_announce))
return ppi->ext_hooks->handle_announce(ppi); return ppi->ext_hooks->handle_announce(ppi);
return 0; return 0;
} }
int st_com_handle_signaling(struct pp_instance *ppi, void *buf, int len) int st_com_handle_signaling(struct pp_instance *ppi, void *buf, int len)
{ {
if (ppi->ext_hooks->handle_signaling) if (is_ext_hook_available(ppi,handle_signaling))
return ppi->ext_hooks->handle_signaling(ppi,buf,len); return ppi->ext_hooks->handle_signaling(ppi,buf,len);
return 0; return 0;
} }
...@@ -173,5 +173,3 @@ int __send_and_log(struct pp_instance *ppi, int msglen, int chtype,enum pp_msg_f ...@@ -173,5 +173,3 @@ int __send_and_log(struct pp_instance *ppi, int msglen, int chtype,enum pp_msg_f
void __attribute__((weak)) update_meanDelay(struct pp_instance *ppi, TimeInterval meanDelay) { void __attribute__((weak)) update_meanDelay(struct pp_instance *ppi, TimeInterval meanDelay) {
DSCUR(ppi)->meanDelay=meanDelay; DSCUR(ppi)->meanDelay=meanDelay;
} }
...@@ -237,7 +237,7 @@ static int msg_pack_announce(struct pp_instance *ppi) ...@@ -237,7 +237,7 @@ static int msg_pack_announce(struct pp_instance *ppi)
*(UInteger8 *) (buf + 62) = (UInteger8)DSCUR(ppi)->stepsRemoved; *(UInteger8 *) (buf + 62) = (UInteger8)DSCUR(ppi)->stepsRemoved;
*(Enumeration8 *) (buf + 63) = DSPRO(ppi)->timeSource; *(Enumeration8 *) (buf + 63) = DSPRO(ppi)->timeSource;
if (ppi->ext_hooks->pack_announce) if (is_ext_hook_available(ppi,pack_announce))
len = ppi->ext_hooks->pack_announce(ppi); len = ppi->ext_hooks->pack_announce(ppi);
return len; return len;
} }
...@@ -263,7 +263,7 @@ void msg_unpack_announce(struct pp_instance *ppi, void *buf, MsgAnnounce *ann) ...@@ -263,7 +263,7 @@ void msg_unpack_announce(struct pp_instance *ppi, void *buf, MsgAnnounce *ann)
ann->timeSource = *(Enumeration8 *) (buf + 63); ann->timeSource = *(Enumeration8 *) (buf + 63);
/* this can fill in extention specific flags otherwise just zero them*/ /* this can fill in extention specific flags otherwise just zero them*/
if (ppi->ext_hooks->unpack_announce) if (is_ext_hook_available(ppi,unpack_announce))
ppi->ext_hooks->unpack_announce(buf, ann); ppi->ext_hooks->unpack_announce(buf, ann);
else else
ann->ext_specific = 0; ann->ext_specific = 0;
......
...@@ -158,7 +158,7 @@ int pp_init_globals(struct pp_globals *ppg, struct pp_runtime_opts *pp_rt_opts) ...@@ -158,7 +158,7 @@ int pp_init_globals(struct pp_globals *ppg, struct pp_runtime_opts *pp_rt_opts)
struct pp_instance *ppi = INST(ppg, i); struct pp_instance *ppi = INST(ppg, i);
int r; int r;
if (ppi->ext_hooks->open) { if (is_ext_hook_available(ppi,open)) {
ret=(r=ppi->ext_hooks->open(ppi, rt_opts))==0 ? ret : r; ret=(r=ppi->ext_hooks->open(ppi, rt_opts))==0 ? ret : r;
} }
} }
...@@ -174,7 +174,7 @@ int pp_close_globals(struct pp_globals *ppg) ...@@ -174,7 +174,7 @@ int pp_close_globals(struct pp_globals *ppg)
struct pp_instance *ppi = INST(ppg, i); struct pp_instance *ppi = INST(ppg, i);
int r; int r;
if (ppi->ext_hooks->close) { if (is_ext_hook_available(ppi,close) ){
ret=(r=ppi->ext_hooks->close(ppi))==0 ? ret : r; ret=(r=ppi->ext_hooks->close(ppi))==0 ? ret : r;
} }
} }
......
This diff is collapsed.
...@@ -103,7 +103,11 @@ int pp_initializing(struct pp_instance *ppi, void *buf, int len) ...@@ -103,7 +103,11 @@ int pp_initializing(struct pp_instance *ppi, void *buf, int len)
pp_timeout_setall(ppi);/* PP_TO_BMC is not set by default */ pp_timeout_setall(ppi);/* PP_TO_BMC is not set by default */
pp_timeout_set(ppi, PP_TO_BMC); pp_timeout_set(ppi, PP_TO_BMC);
if (ppi->ext_hooks->init) ppi->link_state=PP_LSTATE_PROTOCOL_DETECTION;
ppi->ptp_msg_received=FALSE;
ppi->ext_enabled=(ppi->protocol_extension!=PPSI_EXT_NONE);
if (is_ext_hook_available(ppi,init))
ret = ppi->ext_hooks->init(ppi, buf, len); ret = ppi->ext_hooks->init(ppi, buf, len);
if (ret) { if (ret) {
pp_diag(ppi, ext, 1, "%s: can't init extension\n", __func__); pp_diag(ppi, ext, 1, "%s: can't init extension\n", __func__);
......
...@@ -29,7 +29,7 @@ int pp_listening(struct pp_instance *ppi, void *buf, int len) ...@@ -29,7 +29,7 @@ int pp_listening(struct pp_instance *ppi, void *buf, int len)
MsgHeader *hdr = &ppi->received_ptp_header; MsgHeader *hdr = &ppi->received_ptp_header;
pp_timeout_set(ppi, PP_TO_FAULT); /* no fault as long as we listen */ pp_timeout_set(ppi, PP_TO_FAULT); /* no fault as long as we listen */
if (ppi->ext_hooks->listening) if (is_ext_hook_available(ppi,listening))
e = ppi->ext_hooks->listening(ppi, buf, len); e = ppi->ext_hooks->listening(ppi, buf, len);
if (e) if (e)
goto out; goto out;
......
...@@ -31,7 +31,9 @@ static int master_handle_delay_request(struct pp_instance *ppi, ...@@ -31,7 +31,9 @@ static int master_handle_delay_request(struct pp_instance *ppi,
void *buf, int len) void *buf, int len)
{ {
if (ppi->state == PPS_MASTER) /* not pre-master */ if (ppi->state == PPS_MASTER) /* not pre-master */
msg_issue_delay_resp(ppi, &ppi->last_rcv_time); if ( msg_issue_delay_resp(ppi, &ppi->last_rcv_time)==0 && !ppi->ext_enabled ) {
ppi->link_state=PP_LSTATE_LINKED;
}
return 0; return 0;
} }
...@@ -79,7 +81,7 @@ int pp_master(struct pp_instance *ppi, void *buf, int len) ...@@ -79,7 +81,7 @@ int pp_master(struct pp_instance *ppi, void *buf, int len)
* PPM_NO_MESSAGE * PPM_NO_MESSAGE
*/ */
msgtype = ppi->received_ptp_header.messageType; msgtype = ppi->received_ptp_header.messageType;
if (ppi->ext_hooks->master_msg) if (is_ext_hook_available(ppi,master_msg))
msgtype = ppi->ext_hooks->master_msg(ppi, buf, len, msgtype); msgtype = ppi->ext_hooks->master_msg(ppi, buf, len, msgtype);
if (msgtype < 0) { if (msgtype < 0) {
e = msgtype; e = msgtype;
......
...@@ -36,6 +36,7 @@ static pp_action *actions[] = { ...@@ -36,6 +36,7 @@ static pp_action *actions[] = {
static int slave_handle_sync(struct pp_instance *ppi, void *buf, static int slave_handle_sync(struct pp_instance *ppi, void *buf,
int len) int len)
{ {
static int errcount=0;
MsgHeader *hdr = &ppi->received_ptp_header; MsgHeader *hdr = &ppi->received_ptp_header;
MsgSync sync; MsgSync sync;
...@@ -64,18 +65,19 @@ static int slave_handle_sync(struct pp_instance *ppi, void *buf, ...@@ -64,18 +65,19 @@ static int slave_handle_sync(struct pp_instance *ppi, void *buf,
ppi->t1 = sync.originTimestamp; ppi->t1 = sync.originTimestamp;
pp_time_add(&ppi->t1, &hdr->cField); pp_time_add(&ppi->t1, &hdr->cField);
ppi->syncCF = 0; ppi->syncCF = 0;
/* t1 & t2 are saved in the instance. Check if they are correct */
if ( is_timestamps_incorrect(ppi,&errcount,3 /* mask=t1&t2 */) )
return 0;
/* Call the extension; it may do it all and ask to return */ /* Call the extension; it may do it all and ask to return */
if (ppi->ext_hooks->handle_sync) { if ( is_ext_hook_available(ppi,handle_sync) ) {
int ret = ppi->ext_hooks->handle_sync(ppi, &ppi->t1); int ret = ppi->ext_hooks->handle_sync(ppi);
if (ret == 1) if (ret == 1)
return 0; return 0;
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P) pp_servo_got_sync(ppi);
pp_servo_got_psync(ppi);
else
pp_servo_got_sync(ppi);
} }
return 0; return 0;
} }
...@@ -83,8 +85,8 @@ static int slave_handle_sync(struct pp_instance *ppi, void *buf, ...@@ -83,8 +85,8 @@ static int slave_handle_sync(struct pp_instance *ppi, void *buf,
static int slave_handle_followup(struct pp_instance *ppi, void *buf, static int slave_handle_followup(struct pp_instance *ppi, void *buf,
int len) int len)
{ {
static int errcount=0;
MsgFollowUp follow; MsgFollowUp follow;
int ret = 0;
MsgHeader *hdr = &ppi->received_ptp_header; MsgHeader *hdr = &ppi->received_ptp_header;
...@@ -113,19 +115,19 @@ static int slave_handle_followup(struct pp_instance *ppi, void *buf, ...@@ -113,19 +115,19 @@ static int slave_handle_followup(struct pp_instance *ppi, void *buf,
pp_time_add(&ppi->t1, &follow.preciseOriginTimestamp); pp_time_add(&ppi->t1, &follow.preciseOriginTimestamp);
pp_time_add(&ppi->t1, &hdr->cField); pp_time_add(&ppi->t1, &hdr->cField);
ppi->syncCF = hdr->cField.scaled_nsecs; /* for diag about TC */ ppi->syncCF = hdr->cField.scaled_nsecs; /* for diag about TC */
/* t1 & t2 are saved in the instance. Check if they are correct */
/* Call the extension; it may do it all and ask to return */ if ( is_timestamps_incorrect(ppi,&errcount,3 /* mask=t1&t2 */) )
if (ppi->ext_hooks->handle_followup)
ret = ppi->ext_hooks->handle_followup(ppi, &ppi->t1);
if (ret == 1)
return 0; return 0;
if (ret < 0) /* Call the extension; it may do it all and ask to return */
return ret; if (is_ext_hook_available(ppi,handle_followup) ){
int ret = ppi->ext_hooks->handle_followup(ppi);
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P) if (ret == 1)
pp_servo_got_psync(ppi); return 0;
else if (ret < 0)
pp_servo_got_sync(ppi); return ret;
}
/* default servo action */
pp_servo_got_sync(ppi);
return 0; return 0;
} }
...@@ -133,9 +135,9 @@ static int slave_handle_followup(struct pp_instance *ppi, void *buf, ...@@ -133,9 +135,9 @@ static int slave_handle_followup(struct pp_instance *ppi, void *buf,
static int slave_handle_response(struct pp_instance *ppi, void *buf, static int slave_handle_response(struct pp_instance *ppi, void *buf,
int len) int len)
{ {
int e = 0;
MsgHeader *hdr = &ppi->received_ptp_header; MsgHeader *hdr = &ppi->received_ptp_header;
MsgDelayResp resp; MsgDelayResp resp;
int ret;
msg_unpack_delay_resp(buf, &resp); msg_unpack_delay_resp(buf, &resp);
...@@ -155,15 +157,17 @@ static int slave_handle_response(struct pp_instance *ppi, void *buf, ...@@ -155,15 +157,17 @@ static int slave_handle_response(struct pp_instance *ppi, void *buf,
/* WARNING: should be "sub" (see README-cfield::BUG) */ /* WARNING: should be "sub" (see README-cfield::BUG) */
pp_timeout_set(ppi, PP_TO_FAULT); pp_timeout_set(ppi, PP_TO_FAULT);
if (ppi->ext_hooks->handle_resp) if (is_ext_hook_available(ppi,handle_resp)) {
e = ppi->ext_hooks->handle_resp(ppi); ret=ppi->ext_hooks->handle_resp(ppi);
else }
pp_servo_got_resp(ppi); else {
if (e) if ( (ret=pp_servo_got_resp(ppi)) && !ppi->ext_enabled ) {
return e; ppi->link_state=PP_LSTATE_LINKED;
}
if (DSPOR(ppi)->logMinDelayReqInterval != }
hdr->logMessageInterval) {
if ( ret &&
DSPOR(ppi)->logMinDelayReqInterval !=hdr->logMessageInterval) {
DSPOR(ppi)->logMinDelayReqInterval = DSPOR(ppi)->logMinDelayReqInterval =
hdr->logMessageInterval; hdr->logMessageInterval;
/* new value for logMin */ /* new value for logMin */
...@@ -200,7 +204,7 @@ static int slave_execute(struct pp_instance *ppi) ...@@ -200,7 +204,7 @@ static int slave_execute(struct pp_instance *ppi)
{ {
int ret = 0; int ret = 0;
if (ppi->ext_hooks->execute_slave) if (is_ext_hook_available(ppi,execute_slave))
ret = ppi->ext_hooks->execute_slave(ppi); ret = ppi->ext_hooks->execute_slave(ppi);
if (ret == 1) /* done: just return */ if (ret == 1) /* done: just return */
return 0; return 0;
...@@ -216,13 +220,13 @@ static int slave_execute(struct pp_instance *ppi) ...@@ -216,13 +220,13 @@ static int slave_execute(struct pp_instance *ppi)
*/ */
int pp_slave(struct pp_instance *ppi, void *buf, int len) int pp_slave(struct pp_instance *ppi, void *buf, int len)
{ {
int e = 0; /* error var, to check errors in msg handling */ int ret = PP_SEND_OK; /* error var, to check errors in msg handling */
int uncalibrated = (ppi->state == PPS_UNCALIBRATED); int uncalibrated = (ppi->state == PPS_UNCALIBRATED);
MsgHeader *hdr = &ppi->received_ptp_header; MsgHeader *hdr = &ppi->received_ptp_header;
/* upgrade from uncalibrated to slave or back*/ /* upgrade from uncalibrated to slave or back*/
if (uncalibrated) { if (uncalibrated) {
if ( ppi->ext_hooks->ready_for_slave != NULL ) { if ( is_ext_hook_available(ppi,ready_for_slave) ) {
if ( (*ppi->ext_hooks->ready_for_slave)(ppi) ) { if ( (*ppi->ext_hooks->ready_for_slave)(ppi) ) {
ppi->next_state = PPS_SLAVE; ppi->next_state = PPS_SLAVE;
} }
...@@ -244,9 +248,9 @@ int pp_slave(struct pp_instance *ppi, void *buf, int len) ...@@ -244,9 +248,9 @@ int pp_slave(struct pp_instance *ppi, void *buf, int len)
pp_diag(ppi, bmc, 2, "Entered to uncalibrated, reset servo\n"); pp_diag(ppi, bmc, 2, "Entered to uncalibrated, reset servo\n");
pp_servo_init(ppi); pp_servo_init(ppi);
if (ppi->ext_hooks->new_slave) if (is_ext_hook_available(ppi,new_slave))
e = ppi->ext_hooks->new_slave(ppi, buf, len); ret = ppi->ext_hooks->new_slave(ppi, buf, len);
if (e) if (ret!=PP_SEND_OK)
goto out; goto out;
} }
...@@ -258,7 +262,7 @@ int pp_slave(struct pp_instance *ppi, void *buf, int len) ...@@ -258,7 +262,7 @@ int pp_slave(struct pp_instance *ppi, void *buf, int len)
*/ */
if (hdr->messageType < ARRAY_SIZE(actions) if (hdr->messageType < ARRAY_SIZE(actions)
&& actions[hdr->messageType]) { && actions[hdr->messageType]) {
e = actions[hdr->messageType](ppi, buf, len); ret = actions[hdr->messageType](ppi, buf, len);
} else { } else {
if (len) if (len)
pp_diag(ppi, frames, 1, "Ignored frame %i\n", pp_diag(ppi, frames, 1, "Ignored frame %i\n",
...@@ -269,25 +273,17 @@ int pp_slave(struct pp_instance *ppi, void *buf, int len) ...@@ -269,25 +273,17 @@ int pp_slave(struct pp_instance *ppi, void *buf, int len)
* This function, common to uncalibrated and slave, * This function, common to uncalibrated and slave,
* is the core of the slave: hook * is the core of the slave: hook
*/ */
e = slave_execute(ppi); ret = slave_execute(ppi);
st_com_check_announce_receive_timeout(ppi); st_com_check_announce_receive_timeout(ppi);
out: out:
switch(e) { if ( ret==PP_SEND_NO_STAMP ) {
case PP_SEND_OK: /* 0 */ ret = PP_SEND_OK;/* nothing, just keep the ball rolling */
break;
case PP_SEND_ERROR:
/* ignore: a lost frame is not the end of the world */
break;
case PP_SEND_NO_STAMP:
/* nothing, just keep the ball rolling */
e = 0;
break;
} }
ppi->next_delay = pp_next_delay_2(ppi, ppi->next_delay = pp_next_delay_2(ppi,
PP_TO_ANN_RECEIPT, PP_TO_REQUEST); PP_TO_ANN_RECEIPT, PP_TO_REQUEST);
return e; return ret;
} }
...@@ -193,28 +193,28 @@ static int unix_time_set(struct pp_instance *ppi, const struct pp_time *t) ...@@ -193,28 +193,28 @@ static int unix_time_set(struct pp_instance *ppi, const struct pp_time *t)
struct timespec tp; struct timespec tp;
if (!t) { /* Change the network notion of the utc/tai offset */ if (!t) { /* Change the network notion of the utc/tai offset */
struct timex t; struct timex tmx;
t.modes = MOD_TAI; tmx.modes = MOD_TAI;
t.constant = DSPRO(ppi)->currentUtcOffset; tmx.constant = DSPRO(ppi)->currentUtcOffset;
if (adjtimex(&t) < 0) if (adjtimex(&tmx) < 0)
clock_fatal_error("change TAI offset"); clock_fatal_error("change TAI offset");
pp_diag(ppi, time, 1, "New TAI offset: %i\n", pp_diag(ppi, time, 1, "New TAI offset: %i\n",
DSPRO(ppi)->currentUtcOffset); DSPRO(ppi)->currentUtcOffset);
return 0;
}
/* UTC = TAI - 35 */
tp.tv_sec = t->secs - DSPRO(ppi)->currentUtcOffset;
tp.tv_nsec = t->scaled_nsecs >> 16;
if ( tp.tv_sec < 0 || tp.tv_nsec<0) {
pp_error("%s: Cannot set clock time with negative values: %lisec %lins\n", __func__,(long int) tp.tv_sec,tp.tv_nsec );
} else { } else {
if (clock_settime(CLOCK_REALTIME, &tp) < 0) {
clock_fatal_error("clock_settime"); /* UTC = TAI - 35 */
tp.tv_sec = t->secs - DSPRO(ppi)->currentUtcOffset;
tp.tv_nsec = t->scaled_nsecs >> 16;
if ( tp.tv_sec < 0 || tp.tv_nsec<0) {
pp_error("%s: Cannot set clock time with negative values: %lisec %lins\n", __func__,(long int) tp.tv_sec,tp.tv_nsec );
} else {
if (clock_settime(CLOCK_REALTIME, &tp) < 0) {
clock_fatal_error("clock_settime");
}
pp_diag(ppi, time, 1, "%s: %9li.%09li\n", __func__,
tp.tv_sec, tp.tv_nsec);
} }
pp_diag(ppi, time, 1, "%s: %9li.%09li\n", __func__,
tp.tv_sec, tp.tv_nsec);
} }
return 0; return 0;
} }
......
...@@ -239,27 +239,28 @@ static int wrs_recv_msg(struct pp_instance *ppi, int fd, void *pkt, int len, ...@@ -239,27 +239,28 @@ static int wrs_recv_msg(struct pp_instance *ppi, int fd, void *pkt, int len,
aux = (struct tpacket_auxdata *)dp; aux = (struct tpacket_auxdata *)dp;
} }
if(sts && t) if ( t ) {
{ if (sts) {
int cntr_ahead = sts->hwtimeraw.tv_sec & 0x80000000 ? 1: 0; int cntr_ahead = sts->hwtimeraw.tv_sec & 0x80000000 ? 1: 0;
t->scaled_nsecs = (long long)sts->hwtimeraw.tv_nsec << 16; t->scaled_nsecs = (long long)sts->hwtimeraw.tv_nsec << 16;
t->secs = sts->hwtimeraw.tv_sec & 0x7fffffff; t->secs = sts->hwtimeraw.tv_sec & 0x7fffffff;
update_dmtd(s, ppi); update_dmtd(s, ppi);
if ( WRH_DSPOR_HEAD(ppi)==NULL || !WRH_DSPOR_HEAD(ppi)->extModeOn) { if ( ppi->ext_hooks->require_precise_timestamp!=NULL &&
goto drop; (*ppi->ext_hooks->require_precise_timestamp)(ppi)) {
} /* Precise time stamp required */
if (s->dmtd_phase_valid) { if (s->dmtd_phase_valid) {
wrs_linearize_rx_timestamp(t, s->dmtd_phase, wrs_linearize_rx_timestamp(t, s->dmtd_phase,
cntr_ahead, s->phase_transition, s->clock_period); cntr_ahead, s->phase_transition, s->clock_period);
} else {
mark_incorrect(t);
}
}
} else { } else {
mark_incorrect(t); mark_incorrect(t);
} }
} else {
mark_incorrect(t);
} }
drop:
/* For UDP, avoid all of the following, as we don't have vlans */ /* For UDP, avoid all of the following, as we don't have vlans */
if (ppi->proto == PPSI_PROTO_UDP) if (ppi->proto == PPSI_PROTO_UDP)
goto out; goto out;
......
...@@ -101,10 +101,10 @@ int wrs_enable_timing_output(struct pp_instance *ppi, int enable) ...@@ -101,10 +101,10 @@ int wrs_enable_timing_output(struct pp_instance *ppi, int enable)
{ {
int ret, rval; int ret, rval;
hexp_pps_params_t p; hexp_pps_params_t p;
static int ppsOutputOn=-1; /* -1 means we don't know the state */
if (enable == WRH_DSPOR_HEAD(ppi)->ppsOutputOn) if (enable == ppsOutputOn)
return WRH_SPLL_OK; return WRH_SPLL_OK;
WRH_DSPOR_HEAD(ppi)->ppsOutputOn = enable;
p.pps_valid = enable; p.pps_valid = enable;
...@@ -113,6 +113,7 @@ int wrs_enable_timing_output(struct pp_instance *ppi, int enable) ...@@ -113,6 +113,7 @@ int wrs_enable_timing_output(struct pp_instance *ppi, int enable)
if ((ret < 0) || (rval < 0)) if ((ret < 0) || (rval < 0))
return WRH_SPLL_ERROR; return WRH_SPLL_ERROR;
ppsOutputOn = enable;
return WRH_SPLL_OK; return WRH_SPLL_OK;
} }
......
...@@ -15,10 +15,11 @@ static const char *timeOutNames[__PP_TO_ARRAY_SIZE]={ ...@@ -15,10 +15,11 @@ static const char *timeOutNames[__PP_TO_ARRAY_SIZE]={
"ANN_SEND", "ANN_SEND",
"FAULT", "FAULT",
"QUAL", "QUAL",
"PROT_STATE",
"EXT_0", "EXT_0",
"EXT_1" "EXT_1"
}; };
#define TIMEOUT_FAULTY_STATE_MS (60*1000) /* define the time to stay on faulty state before to go to initializing state */
#define TIMEOUT_MAX_LOG_VALUE 21 /* 2^21 * 1000 =2097152000ms is the maximum value that can be stored in an integer */ #define TIMEOUT_MAX_LOG_VALUE 21 /* 2^21 * 1000 =2097152000ms is the maximum value that can be stored in an integer */
#define TIMEOUT_MIN_LOG_VALUE -9 /* 2^-9 = 1ms is the minimum value that can be stored in an integer */ #define TIMEOUT_MIN_LOG_VALUE -9 /* 2^-9 = 1ms is the minimum value that can be stored in an integer */
#define TIMEOUT_MAX_VALUE_MS ((1<< TIMEOUT_MAX_LOG_VALUE)*1000) #define TIMEOUT_MAX_VALUE_MS ((1<< TIMEOUT_MAX_LOG_VALUE)*1000)
...@@ -59,14 +60,17 @@ void pp_timeout_init(struct pp_instance *ppi) ...@@ -59,14 +60,17 @@ void pp_timeout_init(struct pp_instance *ppi)
timeouts[PP_TO_QUALIFICATION].which_rand = timeouts[PP_TO_QUALIFICATION].which_rand =
timeouts[PP_TO_ANN_RECEIPT].which_rand = timeouts[PP_TO_ANN_RECEIPT].which_rand =
timeouts[PP_TO_FAULT].which_rand = timeouts[PP_TO_FAULT].which_rand =
timeouts[PP_TO_PROT_STATE].which_rand =
timeouts[PP_TO_EXT_0].which_rand = timeouts[PP_TO_EXT_0].which_rand =
timeouts[PP_TO_EXT_1].which_rand = TO_RAND_NONE; timeouts[PP_TO_EXT_1].which_rand = TO_RAND_NONE;
timeouts[PP_TO_REQUEST].initValueMs= pp_timeout_log_to_ms(logDelayRequest); timeouts[PP_TO_REQUEST].initValueMs= pp_timeout_log_to_ms(logDelayRequest);
/* fault timeout is 4 avg request intervals, not randomized */ /* fault timeout is 4 avg request intervals, not randomized */
timeouts[PP_TO_FAULT].initValueMs = pp_timeout_log_to_ms(logDelayRequest); timeouts[PP_TO_FAULT].initValueMs = pp_timeout_log_to_ms(logDelayRequest);
if ( timeouts[PP_TO_FAULT].initValueMs < (TIMEOUT_MAX_VALUE_MS>>2)) if ( timeouts[PP_TO_FAULT].initValueMs < (TIMEOUT_MAX_VALUE_MS>>2))
timeouts[PP_TO_FAULT].initValueMs<<=2; /* We can multiply by 4. No risk of overload */ timeouts[PP_TO_FAULT].initValueMs<<=2; /* We can multiply by 4. No risk of overload */
timeouts[PP_TO_SYNC_SEND].initValueMs = pp_timeout_log_to_ms(port->logSyncInterval); timeouts[PP_TO_SYNC_SEND].initValueMs = pp_timeout_log_to_ms(port->logSyncInterval);
timeouts[PP_TO_BMC].initValueMs = pp_timeout_log_to_ms(port->logAnnounceInterval); timeouts[PP_TO_BMC].initValueMs = pp_timeout_log_to_ms(port->logAnnounceInterval);
timeouts[PP_TO_ANN_RECEIPT].initValueMs = 1000 * ( timeouts[PP_TO_ANN_RECEIPT].initValueMs = 1000 * (
...@@ -145,9 +149,13 @@ void pp_timeout_setall(struct pp_instance *ppi) ...@@ -145,9 +149,13 @@ void pp_timeout_setall(struct pp_instance *ppi)
{ {
int i; int i;
for (i = 0; i < __PP_TO_ARRAY_SIZE; i++) { for (i = 0; i < __PP_TO_ARRAY_SIZE; i++) {
/* keep BMC timeout */ if ( i==PP_TO_FAULT && ppi->next_state==PPS_FAULTY ){
if (i!=PP_TO_BMC) { __pp_timeout_set(ppi,PP_TO_FAULT,TIMEOUT_FAULTY_STATE_MS);
pp_timeout_set(ppi, i); } else {
/* keep BMC timeout */
if (i!=PP_TO_BMC) {
pp_timeout_set(ppi, i);
}
} }
} }
/* but announce_send must be send soon */ /* but announce_send must be send soon */
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#define CALIBRATED_MASK 0x4 #define CALIBRATED_MASK 0x4
#define WR_CONFIG_MASK 0x3 #define WR_CONFIG_MASK 0x3
#if CONFIG_PROFILE_WR == 1
static char *wr_message_name[] = { static char *wr_message_name[] = {
"SLAVE_PRESENT", "SLAVE_PRESENT",
"LOCK", "LOCK",
...@@ -22,6 +23,7 @@ static char *wr_message_name[] = { ...@@ -22,6 +23,7 @@ static char *wr_message_name[] = {
"CALIBRATED", "CALIBRATED",
"WR_MODE_ON", "WR_MODE_ON",
}; };
#endif
static int dump_vlan(char *prefix, int vlan); static int dump_vlan(char *prefix, int vlan);
...@@ -165,6 +167,8 @@ static void dump_msg_resp_etc(char *prefix, char *s, struct ptp_sync_etc *p) ...@@ -165,6 +167,8 @@ static void dump_msg_resp_etc(char *prefix, char *s, struct ptp_sync_etc *p)
dump_1port(prefix, s, p->port); dump_1port(prefix, s, p->port);
} }
#if CONFIG_PROFILE_WR == 1
/* TLV dumper, now white-rabbit aware */ /* TLV dumper, now white-rabbit aware */
static int wr_dump_tlv(char *prefix, struct ptp_tlv *tlv, int totallen) static int wr_dump_tlv(char *prefix, struct ptp_tlv *tlv, int totallen)
{ {
...@@ -275,6 +279,9 @@ static int wr_dump_tlv(char *prefix, struct ptp_tlv *tlv, int totallen) ...@@ -275,6 +279,9 @@ static int wr_dump_tlv(char *prefix, struct ptp_tlv *tlv, int totallen)
return explen; return explen;
} }
#endif
#if CONFIG_EXT_L1SYNC == 1
static int l1sync_dump_tlv(char *prefix, struct l1sync_tlv *tlv, int totallen) static int l1sync_dump_tlv(char *prefix, struct l1sync_tlv *tlv, int totallen)
{ {
...@@ -299,6 +306,7 @@ static int l1sync_dump_tlv(char *prefix, struct l1sync_tlv *tlv, int totallen) ...@@ -299,6 +306,7 @@ static int l1sync_dump_tlv(char *prefix, struct l1sync_tlv *tlv, int totallen)
explen - sizeof(*tlv)); explen - sizeof(*tlv));
return explen; return explen;
} }
#endif
/* A big function to dump the ptp information */ /* A big function to dump the ptp information */
static void dump_payload(char *prefix, void *pl, int len) static void dump_payload(char *prefix, void *pl, int len)
...@@ -396,12 +404,16 @@ static void dump_payload(char *prefix, void *pl, int len) ...@@ -396,12 +404,16 @@ static void dump_payload(char *prefix, void *pl, int len)
break; break;
} }
switch ( messageType) { switch ( messageType) {
#if CONFIG_PROFILE_WR == 1
case PPM_ANNOUNCE : case PPM_ANNOUNCE :
donelen += wr_dump_tlv(prefix, pl + donelen, n); donelen += wr_dump_tlv(prefix, pl + donelen, n);
break; break;
#endif
#if CONFIG_EXT_L1SYNC == 1
case PPM_SIGNALING : case PPM_SIGNALING :
donelen += l1sync_dump_tlv(prefix, pl + donelen, n); donelen += l1sync_dump_tlv(prefix, pl + donelen, n);
break; break;
#endif
default : default :
goto out; goto out;
} }
......
...@@ -82,8 +82,8 @@ struct dump_info dstp_info [] = { ...@@ -82,8 +82,8 @@ struct dump_info dstp_info [] = {
#define DUMP_STRUCT struct pp_servo #define DUMP_STRUCT struct pp_servo
struct dump_info servo_state_info [] = { struct dump_info servo_state_info [] = {
DUMP_FIELD(int , state), DUMP_FIELD(int , state),
DUMP_FIELD(time, delayMM),
DUMP_FIELD(time, delayMS), DUMP_FIELD(time, delayMS),
DUMP_FIELD(time, delaySM),
DUMP_FIELD(long_long, obs_drift), DUMP_FIELD(long_long, obs_drift),
DUMP_FIELD(Integer64, mpd_fltr.m), DUMP_FIELD(Integer64, mpd_fltr.m),
DUMP_FIELD(Integer64, mpd_fltr.y), DUMP_FIELD(Integer64, mpd_fltr.y),
...@@ -91,7 +91,14 @@ struct dump_info servo_state_info [] = { ...@@ -91,7 +91,14 @@ struct dump_info servo_state_info [] = {
DUMP_FIELD(time, meanDelay), DUMP_FIELD(time, meanDelay),
DUMP_FIELD(time, offsetFromMaster), DUMP_FIELD(time, offsetFromMaster),
DUMP_FIELD(unsigned_long, flags), DUMP_FIELD(unsigned_long, flags),
DUMP_FIELD(time, update_time),
DUMP_FIELD(UInteger32, update_count), DUMP_FIELD(UInteger32, update_count),
DUMP_FIELD(time, t1),
DUMP_FIELD(time, t2),
DUMP_FIELD(time, t3),
DUMP_FIELD(time, t4),
DUMP_FIELD(time, t5),
DUMP_FIELD(time, t6),
DUMP_FIELD_SIZE(char, servo_state_name,32), DUMP_FIELD_SIZE(char, servo_state_name,32),
DUMP_FIELD(int, servo_locked), DUMP_FIELD(int, servo_locked),
}; };
...@@ -101,7 +108,6 @@ struct dump_info servo_state_info [] = { ...@@ -101,7 +108,6 @@ struct dump_info servo_state_info [] = {
#define DUMP_STRUCT struct l1e_servo_state #define DUMP_STRUCT struct l1e_servo_state
struct dump_info l1e_servo_state_info [] = { struct dump_info l1e_servo_state_info [] = {
DUMP_FIELD(Integer32, clock_period_ps), DUMP_FIELD(Integer32, clock_period_ps),
DUMP_FIELD(time, delayMM),
DUMP_FIELD(Integer64, delayMM_ps), DUMP_FIELD(Integer64, delayMM_ps),
DUMP_FIELD(Integer32, cur_setpoint_ps), DUMP_FIELD(Integer32, cur_setpoint_ps),
DUMP_FIELD(Integer64, delayMS_ps), DUMP_FIELD(Integer64, delayMS_ps),
...@@ -111,13 +117,6 @@ struct dump_info l1e_servo_state_info [] = { ...@@ -111,13 +117,6 @@ struct dump_info l1e_servo_state_info [] = {
DUMP_FIELD(UInteger32, n_err_state), DUMP_FIELD(UInteger32, n_err_state),
DUMP_FIELD(UInteger32, n_err_offset), DUMP_FIELD(UInteger32, n_err_offset),
DUMP_FIELD(UInteger32, n_err_delta_rtt), DUMP_FIELD(UInteger32, n_err_delta_rtt),
DUMP_FIELD(time, update_time),
DUMP_FIELD(time, t1),
DUMP_FIELD(time, t2),
DUMP_FIELD(time, t3),
DUMP_FIELD(time, t4),
DUMP_FIELD(time, t5),
DUMP_FIELD(time, t6),
DUMP_FIELD(Integer64, prev_delayMS_ps), DUMP_FIELD(Integer64, prev_delayMS_ps),
DUMP_FIELD(int, missed_iters), DUMP_FIELD(int, missed_iters),
}; };
...@@ -125,7 +124,6 @@ struct dump_info l1e_servo_state_info [] = { ...@@ -125,7 +124,6 @@ struct dump_info l1e_servo_state_info [] = {
#undef DUMP_STRUCT #undef DUMP_STRUCT
#define DUMP_STRUCT l1e_ext_portDS_t #define DUMP_STRUCT l1e_ext_portDS_t
struct dump_info l1e_ext_portDS_info [] = { struct dump_info l1e_ext_portDS_info [] = {
DUMP_FIELD(Boolean, parentExtModeOn),
DUMP_FIELD(Boolean, basic.L1SyncEnabled), DUMP_FIELD(Boolean, basic.L1SyncEnabled),
DUMP_FIELD(Boolean, basic.txCoherentIsRequired), DUMP_FIELD(Boolean, basic.txCoherentIsRequired),
DUMP_FIELD(Boolean, basic.rxCoherentIsRequired), DUMP_FIELD(Boolean, basic.rxCoherentIsRequired),
......
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