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 <richardcochran@gmail.com>
master
Richard Cochran 2013-08-26 14:25:58 +02:00
parent 329e4a2fff
commit 7eef4101c9
2 changed files with 18 additions and 2 deletions

3
fd.h
View File

@ -20,12 +20,13 @@
#ifndef HAVE_FD_H #ifndef HAVE_FD_H
#define HAVE_FD_H #define HAVE_FD_H
#define N_TIMER_FDS 5 #define N_TIMER_FDS 6
enum { enum {
FD_EVENT, FD_EVENT,
FD_GENERAL, FD_GENERAL,
FD_ANNOUNCE_TIMER, FD_ANNOUNCE_TIMER,
FD_SYNC_RX_TIMER,
FD_DELAY_TIMER, FD_DELAY_TIMER,
FD_QUALIFICATION_TIMER, FD_QUALIFICATION_TIMER,
FD_MANNO_TIMER, FD_MANNO_TIMER,

17
port.c
View File

@ -97,6 +97,7 @@ struct port {
TimeInterval peerMeanPathDelay; TimeInterval peerMeanPathDelay;
Integer8 logAnnounceInterval; Integer8 logAnnounceInterval;
UInteger8 announceReceiptTimeout; UInteger8 announceReceiptTimeout;
UInteger8 syncReceiptTimeout;
UInteger8 transportSpecific; UInteger8 transportSpecific;
Integer8 logSyncInterval; Integer8 logSyncInterval;
Enumeration8 delayMechanism; Enumeration8 delayMechanism;
@ -800,6 +801,12 @@ static int port_set_qualification_tmo(struct port *p)
1+clock_steps_removed(p->clock), p->logAnnounceInterval); 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) static int port_set_sync_tx_tmo(struct port *p)
{ {
return set_tmo_log(p->fda.fd[FD_SYNC_TX_TIMER], 1, p->logSyncInterval); 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; enum servo_state state;
port_set_sync_rx_tmo(p);
state = clock_synchronize(p->clock, ingress_ts, origin_ts, state = clock_synchronize(p->clock, ingress_ts, origin_ts,
correction1, correction2); correction1, correction2);
switch (state) { 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) 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_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_DELAY_TIMER]);
port_clr_tmo(p->fda.fd[FD_QUALIFICATION_TIMER]); port_clr_tmo(p->fda.fd[FD_QUALIFICATION_TIMER]);
port_clr_tmo(p->fda.fd[FD_MANNO_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 */ /* fall through */
case PS_SLAVE: case PS_SLAVE:
port_set_announce_tmo(p); port_set_announce_tmo(p);
port_set_sync_rx_tmo(p);
port_set_delay_tmo(p); port_set_delay_tmo(p);
break; 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) 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_ANNOUNCE_TIMER]);
port_clr_tmo(p->fda.fd[FD_SYNC_RX_TIMER]);
/* Leave FD_DELAY_TIMER running. */ /* Leave FD_DELAY_TIMER running. */
port_clr_tmo(p->fda.fd[FD_QUALIFICATION_TIMER]); port_clr_tmo(p->fda.fd[FD_QUALIFICATION_TIMER]);
port_clr_tmo(p->fda.fd[FD_MANNO_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 */ /* fall through */
case PS_SLAVE: case PS_SLAVE:
port_set_announce_tmo(p); port_set_announce_tmo(p);
port_set_sync_rx_tmo(p);
break; break;
}; };
} }
@ -1987,7 +2000,9 @@ enum fsm_event port_event(struct port *p, int fd_index)
switch (fd_index) { switch (fd_index) {
case FD_ANNOUNCE_TIMER: 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) if (p->best)
fc_clear(p->best); fc_clear(p->best);
port_set_announce_tmo(p); port_set_announce_tmo(p);