Let a port become 'capable' according to 802.1AS.

This patch implements the capable flag as follows.

1. After calculating the neighbor rate, we are capable.
2. If we miss too many responses, we are incapable.
3. If we get multiple responses, we throw a fault,
   and so we are also incapable.

Signed-off-by: Richard Cochran <richardcochran@gmail.com>
master
Richard Cochran 2013-01-27 16:23:11 +01:00
parent ea833f3d6b
commit 285b88ade4
1 changed files with 20 additions and 7 deletions

27
port.c
View File

@ -515,6 +515,11 @@ static void port_nrate_calculate(struct port *p, tmv_t t3, tmv_t t4, tmv_t c)
n->ingress1 = t4; n->ingress1 = t4;
n->origin1 = origin2; n->origin1 = origin2;
n->count = 0; n->count = 0;
/*
* We experienced a successful series of exchanges of peer
* delay request and response, and so the port is now capable.
*/
p->pdr_missing = 0;
} }
static void port_nrate_initialize(struct port *p) static void port_nrate_initialize(struct port *p)
@ -650,9 +655,12 @@ static int port_pdelay_request(struct port *p)
goto out; goto out;
} }
if (p->peer_delay_req) if (p->peer_delay_req) {
if (port_capable(p)) {
p->pdr_missing++;
}
msg_put(p->peer_delay_req); msg_put(p->peer_delay_req);
}
p->peer_delay_req = msg; p->peer_delay_req = msg;
return 0; return 0;
out: out:
@ -1324,22 +1332,27 @@ calc:
if (p->state == PS_UNCALIBRATED || p->state == PS_SLAVE) { if (p->state == PS_UNCALIBRATED || p->state == PS_SLAVE) {
clock_peer_delay(p->clock, p->peer_delay, p->nrate.ratio); clock_peer_delay(p->clock, p->peer_delay, p->nrate.ratio);
} }
msg_put(p->peer_delay_req);
p->peer_delay_req = NULL;
} }
static int process_pdelay_resp(struct port *p, struct ptp_message *m) static int process_pdelay_resp(struct port *p, struct ptp_message *m)
{ {
if (!p->peer_delay_req) {
pr_err("port %hu: rogue peer delay response", portnum(p));
return -1;
}
if (p->peer_delay_resp) { if (p->peer_delay_resp) {
if (!source_pid_eq(p->peer_delay_resp, m)) { if (!source_pid_eq(p->peer_delay_resp, m)) {
pr_err("port %hu: multiple peer responses", portnum(p)); pr_err("port %hu: multiple peer responses", portnum(p));
return -1; return -1;
} }
msg_put(p->peer_delay_resp); }
if (!p->peer_delay_req) {
pr_err("port %hu: rogue peer delay response", portnum(p));
return -1;
} }
if (p->peer_delay_resp) {
msg_put(p->peer_delay_resp);
}
msg_get(m); msg_get(m);
p->peer_delay_resp = m; p->peer_delay_resp = m;
port_peer_delay(p); port_peer_delay(p);