From 7eef4101c9fb27272ca769d78fc12dc4bd0cd39f Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Mon, 26 Aug 2013 14:25:58 +0200 Subject: [PATCH] Add a timer implementing the sync receive timeout. This patch adds a new timer for use in 802.1AS-2011 applications. When running as a slave in gPTP mode, the program must monitor both announce and sync messages from the master. If either one goes missing, then we trigger a BMC election. The sync timeout is actually reset by a valid sync/follow up pair of messages. Signed-off-by: Richard Cochran --- fd.h | 3 ++- port.c | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/fd.h b/fd.h index 88f3903..e328e98 100644 --- a/fd.h +++ b/fd.h @@ -20,12 +20,13 @@ #ifndef HAVE_FD_H #define HAVE_FD_H -#define N_TIMER_FDS 5 +#define N_TIMER_FDS 6 enum { FD_EVENT, FD_GENERAL, FD_ANNOUNCE_TIMER, + FD_SYNC_RX_TIMER, FD_DELAY_TIMER, FD_QUALIFICATION_TIMER, FD_MANNO_TIMER, diff --git a/port.c b/port.c index 18197c2..2276ea5 100644 --- a/port.c +++ b/port.c @@ -97,6 +97,7 @@ struct port { TimeInterval peerMeanPathDelay; Integer8 logAnnounceInterval; UInteger8 announceReceiptTimeout; + UInteger8 syncReceiptTimeout; UInteger8 transportSpecific; Integer8 logSyncInterval; Enumeration8 delayMechanism; @@ -800,6 +801,12 @@ static int port_set_qualification_tmo(struct port *p) 1+clock_steps_removed(p->clock), p->logAnnounceInterval); } +static int port_set_sync_rx_tmo(struct port *p) +{ + return set_tmo_log(p->fda.fd[FD_SYNC_RX_TIMER], + p->syncReceiptTimeout, p->logSyncInterval); +} + static int port_set_sync_tx_tmo(struct port *p) { return set_tmo_log(p->fda.fd[FD_SYNC_TX_TIMER], 1, p->logSyncInterval); @@ -832,6 +839,8 @@ static void port_synchronize(struct port *p, { enum servo_state state; + port_set_sync_rx_tmo(p); + state = clock_synchronize(p->clock, ingress_ts, origin_ts, correction1, correction2); switch (state) { @@ -1851,6 +1860,7 @@ struct foreign_clock *port_compute_best(struct port *p) static void port_e2e_transition(struct port *p, enum port_state next) { port_clr_tmo(p->fda.fd[FD_ANNOUNCE_TIMER]); + port_clr_tmo(p->fda.fd[FD_SYNC_RX_TIMER]); port_clr_tmo(p->fda.fd[FD_DELAY_TIMER]); port_clr_tmo(p->fda.fd[FD_QUALIFICATION_TIMER]); port_clr_tmo(p->fda.fd[FD_MANNO_TIMER]); @@ -1883,6 +1893,7 @@ static void port_e2e_transition(struct port *p, enum port_state next) /* fall through */ case PS_SLAVE: port_set_announce_tmo(p); + port_set_sync_rx_tmo(p); port_set_delay_tmo(p); break; }; @@ -1891,6 +1902,7 @@ static void port_e2e_transition(struct port *p, enum port_state next) static void port_p2p_transition(struct port *p, enum port_state next) { port_clr_tmo(p->fda.fd[FD_ANNOUNCE_TIMER]); + port_clr_tmo(p->fda.fd[FD_SYNC_RX_TIMER]); /* Leave FD_DELAY_TIMER running. */ port_clr_tmo(p->fda.fd[FD_QUALIFICATION_TIMER]); port_clr_tmo(p->fda.fd[FD_MANNO_TIMER]); @@ -1923,6 +1935,7 @@ static void port_p2p_transition(struct port *p, enum port_state next) /* fall through */ case PS_SLAVE: port_set_announce_tmo(p); + port_set_sync_rx_tmo(p); break; }; } @@ -1987,7 +2000,9 @@ enum fsm_event port_event(struct port *p, int fd_index) switch (fd_index) { case FD_ANNOUNCE_TIMER: - pr_debug("port %hu: announce timeout", portnum(p)); + case FD_SYNC_RX_TIMER: + pr_debug("port %hu: %s timeout", portnum(p), + fd_index == FD_SYNC_RX_TIMER ? "rx sync" : "announce"); if (p->best) fc_clear(p->best); port_set_announce_tmo(p);