Commit 53cb49ff authored by Sven Meier's avatar Sven Meier Committed by Adam Wujek

bmc: timeouts fixe and announce handling changed

Message handling for the case of received back frames changed and timeouts for announces reset according to standard
parent e1e3935d
...@@ -138,22 +138,21 @@ static int pp_packet_prefilter(struct pp_instance *ppi) ...@@ -138,22 +138,21 @@ static int pp_packet_prefilter(struct pp_instance *ppi)
} }
/* /*
* 9.5.2.3: if an announce message comes from another port of the same * 9.5.2.3 & 9.5.2.2: For BCs the BMC (an extention to it)
* clock, switch all the ports but the lowest numbered one to * handles the Announce (go to Passive), other messages are dropped
* PASSIVE. Since all involved ports will see each other's announce, */
* we just switch __this__ instance's port's status to PASSIVE if we if (!memcmp(&hdr->sourcePortIdentity.clockIdentity,
* need to. &DSPOR(ppi)->portIdentity.clockIdentity,
*/ sizeof(ClockIdentity))) {
if (hdr->messageType == PPM_ANNOUNCE && if (DSDEF(ppi)->numberPorts > 1) {
!memcmp(&hdr->sourcePortIdentity.clockIdentity, /* Announces are handled by the BMC, since otherwise the state is overwritten */
&DSPOR(ppi)->portIdentity.clockIdentity, if (hdr->messageType != PPM_ANNOUNCE) {
sizeof(ClockIdentity))) { /* ignore messages, except announce coming from its own clock */
if (hdr->sourcePortIdentity.portNumber < return -1;
DSPOR(ppi)->portIdentity.portNumber) }
ppi->next_state = PPS_PASSIVE; }
return -1;
} }
return 0; return 0;
} }
......
...@@ -190,6 +190,17 @@ static int wr_handle_announce(struct pp_instance *ppi) ...@@ -190,6 +190,17 @@ static int wr_handle_announce(struct pp_instance *ppi)
{ {
pp_diag(ppi, ext, 2, "hook: %s\n", __func__); pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
if ((ppi->state == WRS_PRESENT) ||
(ppi->state == WRS_S_LOCK) ||
(ppi->state == WRS_LOCKED) ||
(ppi->state == WRS_CALIBRATION) ||
(ppi->state == WRS_CALIBRATED) ||
(ppi->state == WRS_RESP_CALIB_REQ) ||
(ppi->state == WRS_WR_LINK_ON)) {
/* reset announce timeout when in the WR slave states */
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
}
/* handshake is started in slave mode */ /* handshake is started in slave mode */
return 0; return 0;
} }
......
...@@ -460,7 +460,7 @@ static int bmc_state_decision(struct pp_instance *ppi) ...@@ -460,7 +460,7 @@ static int bmc_state_decision(struct pp_instance *ppi)
if (!bmc_idcmp(&erbest->hdr.sourcePortIdentity.clockIdentity, &DSDEF(ppi)->clockIdentity)) { if (!bmc_idcmp(&erbest->hdr.sourcePortIdentity.clockIdentity, &DSDEF(ppi)->clockIdentity)) {
/* is this port worse than the other */ /* is this port worse than the other */
cmpres = bmc_pidcmp(&erbest->hdr.sourcePortIdentity, &DSPOR(ppi)->portIdentity); cmpres = bmc_pidcmp(&erbest->hdr.sourcePortIdentity, &DSPOR(ppi)->portIdentity);
if (cmpres > 0) if (cmpres < 0)
goto passive_p1; goto passive_p1;
} }
} }
...@@ -505,27 +505,45 @@ check_boundary_clk: ...@@ -505,27 +505,45 @@ check_boundary_clk:
passive_p1: passive_p1:
pp_diag(ppi, bmc, 1, "%s: passive p1\n", __func__); pp_diag(ppi, bmc, 1, "%s: passive p1\n", __func__);
if (DSDEF(ppi)->clockQuality.clockClass == PP_CLASS_SLAVE_ONLY) if (DSDEF(ppi)->clockQuality.clockClass == PP_CLASS_SLAVE_ONLY) {
/* 9.2.6.11 c) reset ANNOUNCE RECEIPT timeout when entering*/
if (ppi->state != PPS_LISTENING)
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
return PPS_LISTENING; return PPS_LISTENING;
}
/* 9.2.6.11 c) reset ANNOUNCE RECEIPT timeout when entering*/
if (ppi->state != PPS_PASSIVE)
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
bmc_p1(ppi); bmc_p1(ppi);
return PPS_PASSIVE; return PPS_PASSIVE;
passive_p2: passive_p2:
pp_diag(ppi, bmc, 1, "%s: passive p2\n", __func__); pp_diag(ppi, bmc, 1, "%s: passive p2\n", __func__);
if (DSDEF(ppi)->clockQuality.clockClass == PP_CLASS_SLAVE_ONLY) if (DSDEF(ppi)->clockQuality.clockClass == PP_CLASS_SLAVE_ONLY) {
/* 9.2.6.11 c) reset ANNOUNCE RECEIPT timeout when entering*/
if (ppi->state != PPS_LISTENING)
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
return PPS_LISTENING; return PPS_LISTENING;
}
/* 9.2.6.11 c) reset ANNOUNCE RECEIPT timeout when entering*/
if (ppi->state != PPS_PASSIVE)
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
bmc_p2(ppi); bmc_p2(ppi);
return PPS_PASSIVE; return PPS_PASSIVE;
master_m1: master_m1:
pp_diag(ppi, bmc, 1, "%s: master m1\n", __func__); pp_diag(ppi, bmc, 1, "%s: master m1\n", __func__);
if (DSDEF(ppi)->clockQuality.clockClass == PP_CLASS_SLAVE_ONLY) if (DSDEF(ppi)->clockQuality.clockClass == PP_CLASS_SLAVE_ONLY) {
/* 9.2.6.11 c) reset ANNOUNCE RECEIPT timeout when entering*/
if (ppi->state != PPS_LISTENING)
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
return PPS_LISTENING; return PPS_LISTENING;
}
bmc_m1(ppi); bmc_m1(ppi);
if (ppi->state != PPS_MASTER) { if (ppi->state != PPS_MASTER) {
/* if not already in pre master state start qualification */ /* if not already in pre master state start qualification */
if (ppi->state != PPS_PRE_MASTER) { if (ppi->state != PPS_PRE_MASTER) {
/* 9.2.6.11 a) timeout 0 */ /* 9.2.6.10 a) timeout 0 */
pp_timeout_clear(ppi, PP_TO_QUALIFICATION); pp_timeout_clear(ppi, PP_TO_QUALIFICATION);
} }
return PPS_PRE_MASTER; return PPS_PRE_MASTER;
...@@ -534,13 +552,17 @@ master_m1: ...@@ -534,13 +552,17 @@ master_m1:
master_m2: master_m2:
pp_diag(ppi, bmc, 1, "%s: master m2\n", __func__); pp_diag(ppi, bmc, 1, "%s: master m2\n", __func__);
if (DSDEF(ppi)->clockQuality.clockClass == PP_CLASS_SLAVE_ONLY) if (DSDEF(ppi)->clockQuality.clockClass == PP_CLASS_SLAVE_ONLY) {
/* 9.2.6.11 c) reset ANNOUNCE RECEIPT timeout when entering*/
if (ppi->state != PPS_LISTENING)
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
return PPS_LISTENING; return PPS_LISTENING;
}
bmc_m2(ppi); bmc_m2(ppi);
if (ppi->state != PPS_MASTER) { if (ppi->state != PPS_MASTER) {
/* if not already in pre master state start qualification */ /* if not already in pre master state start qualification */
if (ppi->state != PPS_PRE_MASTER) { if (ppi->state != PPS_PRE_MASTER) {
/* 9.2.6.11 a) timeout 0 */ /* 9.2.6.10 a) timeout 0 */
pp_timeout_clear(ppi, PP_TO_QUALIFICATION); pp_timeout_clear(ppi, PP_TO_QUALIFICATION);
} }
return PPS_PRE_MASTER; return PPS_PRE_MASTER;
...@@ -549,13 +571,19 @@ master_m2: ...@@ -549,13 +571,19 @@ master_m2:
master_m3: master_m3:
pp_diag(ppi, bmc, 1, "%s: master m3\n", __func__); pp_diag(ppi, bmc, 1, "%s: master m3\n", __func__);
if (DSDEF(ppi)->clockQuality.clockClass == PP_CLASS_SLAVE_ONLY) if (DSDEF(ppi)->clockQuality.clockClass == PP_CLASS_SLAVE_ONLY) {
/* 9.2.6.11 c) reset ANNOUNCE RECEIPT timeout when entering*/
if (ppi->state != PPS_LISTENING)
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
return PPS_LISTENING; return PPS_LISTENING;
}
bmc_m3(ppi); bmc_m3(ppi);
if (ppi->state != PPS_MASTER) { if (ppi->state != PPS_MASTER) {
/* if not already in pre master state start qualification */ /* if not already in pre master state start qualification */
if (ppi->state != PPS_PRE_MASTER) { if (ppi->state != PPS_PRE_MASTER) {
/* 9.2.6.11 b) timeout steps removed+1 */ /* timeout reinit */
pp_timeout_init(ppi);
/* 9.2.6.11 b) timeout steps removed+1*/
pp_timeout_set(ppi, PP_TO_QUALIFICATION); pp_timeout_set(ppi, PP_TO_QUALIFICATION);
} }
return PPS_PRE_MASTER; return PPS_PRE_MASTER;
...@@ -577,16 +605,26 @@ slave_s1: ...@@ -577,16 +605,26 @@ slave_s1:
} }
/* if we are not comming from the slave state we go to uncalibrated /* if we are not comming from the slave state we go to uncalibrated
* first */ * first */
if (ppi->state != PPS_SLAVE) { if ((ppi->state != PPS_SLAVE) &&
(ppi->state != PPS_UNCALIBRATED)) {
/* 9.2.6.11 c) reset ANNOUNCE RECEIPT timeout when entering*/
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
return PPS_UNCALIBRATED; return PPS_UNCALIBRATED;
} else { } else {
/* if the master changed we go to uncalibrated*/ /* if the master changed we go to uncalibrated*/
if (cmpres) { if (cmpres) {
pp_diag(ppi, bmc, 1, pp_diag(ppi, bmc, 1,
"new master, change to uncalibrated\n"); "new master, change to uncalibrated\n");
/* 9.2.6.11 c) reset ANNOUNCE RECEIPT timeout when entering*/
if (ppi->state != PPS_UNCALIBRATED)
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
return PPS_UNCALIBRATED; return PPS_UNCALIBRATED;
} else } else {
/* 9.2.6.11 c) reset ANNOUNCE RECEIPT timeout when entering*/
if (ppi->state != PPS_SLAVE)
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
return PPS_SLAVE; return PPS_SLAVE;
}
} }
} }
......
...@@ -120,6 +120,13 @@ static void __lib_add_foreign(struct pp_instance *ppi, unsigned char *buf) ...@@ -120,6 +120,13 @@ static void __lib_add_foreign(struct pp_instance *ppi, unsigned char *buf)
/* if we are a configured master don't add*/ /* if we are a configured master don't add*/
if (ppi->role == PPSI_ROLE_MASTER) if (ppi->role == PPSI_ROLE_MASTER)
return; return;
/* if in DISABLED, INITIALIZING or FAULTY ignore announce */
if ((ppi->state == PPS_DISABLED) ||
(ppi->state == PPS_FAULTY) ||
(ppi->state == PPS_INITIALIZING))
return;
/* /*
* header and announce field of each Foreign Master are * header and announce field of each Foreign Master are
* useful to run Best Master Clock Algorithm * useful to run Best Master Clock Algorithm
...@@ -144,7 +151,7 @@ static void __lib_add_foreign(struct pp_instance *ppi, unsigned char *buf) ...@@ -144,7 +151,7 @@ static void __lib_add_foreign(struct pp_instance *ppi, unsigned char *buf)
*/ */
if (!memcmp(&hdr->sourcePortIdentity, if (!memcmp(&hdr->sourcePortIdentity,
&DSPOR(ppi)->portIdentity, &DSPOR(ppi)->portIdentity,
sizeof(DSPOR(ppi)->portIdentity))) { sizeof(PortIdentity))) {
pp_diag(ppi, bmc, 2, "Announce frame from this port\n"); pp_diag(ppi, bmc, 2, "Announce frame from this port\n");
return; return;
} }
...@@ -152,7 +159,7 @@ static void __lib_add_foreign(struct pp_instance *ppi, unsigned char *buf) ...@@ -152,7 +159,7 @@ static void __lib_add_foreign(struct pp_instance *ppi, unsigned char *buf)
/* Check if announce from a port from this clock 9.3.2.5 a) */ /* Check if announce from a port from this clock 9.3.2.5 a) */
if (!memcmp(&hdr->sourcePortIdentity.clockIdentity, if (!memcmp(&hdr->sourcePortIdentity.clockIdentity,
&DSDEF(ppi)->clockIdentity, &DSDEF(ppi)->clockIdentity,
sizeof(DSDEF(ppi)->clockIdentity))) { sizeof(ClockIdentity))) {
pp_diag(ppi, bmc, 2, "Announce frame from this clock\n"); pp_diag(ppi, bmc, 2, "Announce frame from this clock\n");
return; return;
} }
...@@ -170,7 +177,7 @@ static void __lib_add_foreign(struct pp_instance *ppi, unsigned char *buf) ...@@ -170,7 +177,7 @@ static void __lib_add_foreign(struct pp_instance *ppi, unsigned char *buf)
for (i = 0; i < ppi->frgn_rec_num; i++) { for (i = 0; i < ppi->frgn_rec_num; i++) {
if (!memcmp(&hdr->sourcePortIdentity, if (!memcmp(&hdr->sourcePortIdentity,
&ppi->frgn_master[i].port_id, &ppi->frgn_master[i].port_id,
sizeof(hdr->sourcePortIdentity))) { sizeof(PortIdentity))) {
pp_diag(ppi, bmc, 2, "Foreign Master %i updated\n", i); pp_diag(ppi, bmc, 2, "Foreign Master %i updated\n", i);
......
...@@ -47,12 +47,13 @@ int pp_listening(struct pp_instance *ppi, unsigned char *pkt, int plen) ...@@ -47,12 +47,13 @@ int pp_listening(struct pp_instance *ppi, unsigned char *pkt, int plen)
} }
if (pp_timeout(ppi, PP_TO_ANN_RECEIPT)) { if (pp_timeout(ppi, PP_TO_ANN_RECEIPT)) {
/* 9.2.6.11 b) reset timeout when an announce timeout happended */
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
if (DSDEF(ppi)->clockQuality.clockClass != PP_CLASS_SLAVE_ONLY if (DSDEF(ppi)->clockQuality.clockClass != PP_CLASS_SLAVE_ONLY
&& (ppi->role != PPSI_ROLE_SLAVE)) { && (ppi->role != PPSI_ROLE_SLAVE)) {
ppi->next_state = PPS_MASTER; ppi->next_state = PPS_MASTER;
} else { } else {
ppi->next_state = PPS_LISTENING; ppi->next_state = PPS_LISTENING;
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
} }
} }
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include <ppsi/ppsi.h> #include <ppsi/ppsi.h>
#include "common-fun.h" #include "common-fun.h"
static int passive_handle_announce(struct pp_instance *ppi, unsigned char *buf, int len);
static pp_action *actions[] = { static pp_action *actions[] = {
[PPM_SYNC] = 0, [PPM_SYNC] = 0,
[PPM_DELAY_REQ] = 0, [PPM_DELAY_REQ] = 0,
...@@ -19,10 +21,33 @@ static pp_action *actions[] = { ...@@ -19,10 +21,33 @@ static pp_action *actions[] = {
#endif #endif
[PPM_FOLLOW_UP] = 0, [PPM_FOLLOW_UP] = 0,
[PPM_DELAY_RESP] = 0, [PPM_DELAY_RESP] = 0,
[PPM_ANNOUNCE] = pp_lib_handle_announce, [PPM_ANNOUNCE] = passive_handle_announce,
/* skip signaling and management, for binary size */ /* skip signaling and management, for binary size */
}; };
static int passive_handle_announce(struct pp_instance *ppi, unsigned char *buf, int len)
{
int ret = 0;
MsgHeader *hdr = &ppi->received_ptp_header;
struct pp_frgn_master *erbest = &ppi->frgn_master[ppi->frgn_rec_best];
ret = pp_lib_handle_announce(ppi, buf, len);
if (ret)
return ret;
if (!memcmp(&hdr->sourcePortIdentity,
&erbest->port_id,
sizeof(PortIdentity))) {
/*
* 9.2.6.11 d) reset timeout when an announce
* is received from the clock putting it into passive (erbest)
*/
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
}
return 0;
}
int pp_passive(struct pp_instance *ppi, unsigned char *pkt, int plen) int pp_passive(struct pp_instance *ppi, unsigned char *pkt, int plen)
{ {
int e = 0; /* error var, to check errors in msg handling */ int e = 0; /* error var, to check errors in msg handling */
...@@ -48,12 +73,13 @@ int pp_passive(struct pp_instance *ppi, unsigned char *pkt, int plen) ...@@ -48,12 +73,13 @@ int pp_passive(struct pp_instance *ppi, unsigned char *pkt, int plen)
} }
if (pp_timeout(ppi, PP_TO_ANN_RECEIPT)) { if (pp_timeout(ppi, PP_TO_ANN_RECEIPT)) {
/* 9.2.6.11 b) reset timeout when an announce timeout happended */
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
if (DSDEF(ppi)->clockQuality.clockClass != PP_CLASS_SLAVE_ONLY if (DSDEF(ppi)->clockQuality.clockClass != PP_CLASS_SLAVE_ONLY
&& (ppi->role != PPSI_ROLE_SLAVE)) { && (ppi->role != PPSI_ROLE_SLAVE)) {
ppi->next_state = PPS_MASTER; ppi->next_state = PPS_MASTER;
} else { } else {
ppi->next_state = PPS_LISTENING; ppi->next_state = PPS_LISTENING;
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
} }
} }
......
...@@ -14,8 +14,9 @@ ...@@ -14,8 +14,9 @@
static int slave_handle_sync(struct pp_instance *ppi, unsigned char *buf, int len); static int slave_handle_sync(struct pp_instance *ppi, unsigned char *buf, int len);
static int slave_handle_followup(struct pp_instance *ppi, unsigned char *buf, static int slave_handle_followup(struct pp_instance *ppi, unsigned char *buf,
int len); int len);
static int slave_handle_response(struct pp_instance *ppi, unsigned char *pkt, static int slave_handle_response(struct pp_instance *ppi, unsigned char *buf,
int plen); int len);
static int slave_handle_announce(struct pp_instance *ppi, unsigned char *buf, int len);
static pp_action *actions[] = { static pp_action *actions[] = {
[PPM_SYNC] = slave_handle_sync, [PPM_SYNC] = slave_handle_sync,
...@@ -27,7 +28,7 @@ static pp_action *actions[] = { ...@@ -27,7 +28,7 @@ static pp_action *actions[] = {
#endif #endif
[PPM_FOLLOW_UP] = slave_handle_followup, [PPM_FOLLOW_UP] = slave_handle_followup,
[PPM_DELAY_RESP] = slave_handle_response, [PPM_DELAY_RESP] = slave_handle_response,
[PPM_ANNOUNCE] = pp_lib_handle_announce, [PPM_ANNOUNCE] = slave_handle_announce,
/* skip signaling and management, for binary size */ /* skip signaling and management, for binary size */
}; };
...@@ -113,14 +114,14 @@ static int slave_handle_followup(struct pp_instance *ppi, unsigned char *buf, ...@@ -113,14 +114,14 @@ static int slave_handle_followup(struct pp_instance *ppi, unsigned char *buf,
return 0; return 0;
} }
static int slave_handle_response(struct pp_instance *ppi, unsigned char *pkt, static int slave_handle_response(struct pp_instance *ppi, unsigned char *buf,
int plen) int len)
{ {
int e = 0; int e = 0;
MsgHeader *hdr = &ppi->received_ptp_header; MsgHeader *hdr = &ppi->received_ptp_header;
MsgDelayResp resp; MsgDelayResp resp;
msg_unpack_delay_resp(pkt, &resp); msg_unpack_delay_resp(buf, &resp);
if ((memcmp(&DSPOR(ppi)->portIdentity.clockIdentity, if ((memcmp(&DSPOR(ppi)->portIdentity.clockIdentity,
&resp.requestingPortIdentity.clockIdentity, &resp.requestingPortIdentity.clockIdentity,
...@@ -158,6 +159,27 @@ static int slave_handle_response(struct pp_instance *ppi, unsigned char *pkt, ...@@ -158,6 +159,27 @@ static int slave_handle_response(struct pp_instance *ppi, unsigned char *pkt,
return 0; return 0;
} }
static int slave_handle_announce(struct pp_instance *ppi, unsigned char *buf, int len)
{
int ret = 0;
MsgHeader *hdr = &ppi->received_ptp_header;
MsgAnnounce ann;
ret = pp_lib_handle_announce(ppi, buf, len);
if (ret)
return ret;
if (ppi->flags & PPI_FLAG_FROM_CURRENT_PARENT) {
/* 9.2.6.11 a) reset timeout */
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
/* 9.5.3 Figure 29 update data set if announce from current master */
msg_unpack_announce(buf, &ann);
bmc_s1(ppi, hdr, &ann);
}
return 0;
}
static int slave_execute(struct pp_instance *ppi) static int slave_execute(struct pp_instance *ppi)
{ {
int ret = 0; int ret = 0;
...@@ -206,7 +228,7 @@ int pp_slave(struct pp_instance *ppi, unsigned char *pkt, int plen) ...@@ -206,7 +228,7 @@ int pp_slave(struct pp_instance *ppi, unsigned char *pkt, int plen)
} }
pp_lib_may_issue_request(ppi); pp_lib_may_issue_request(ppi);
/* /*
* The management of messages is now table-driven * The management of messages is now table-driven
*/ */
...@@ -226,12 +248,13 @@ int pp_slave(struct pp_instance *ppi, unsigned char *pkt, int plen) ...@@ -226,12 +248,13 @@ int pp_slave(struct pp_instance *ppi, unsigned char *pkt, int plen)
e = slave_execute(ppi); e = slave_execute(ppi);
if (pp_timeout(ppi, PP_TO_ANN_RECEIPT)) { if (pp_timeout(ppi, PP_TO_ANN_RECEIPT)) {
/* 9.2.6.11 b) reset timeout when an announce timeout happended */
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
if (DSDEF(ppi)->clockQuality.clockClass != PP_CLASS_SLAVE_ONLY if (DSDEF(ppi)->clockQuality.clockClass != PP_CLASS_SLAVE_ONLY
&& (ppi->role != PPSI_ROLE_SLAVE)) { && (ppi->role != PPSI_ROLE_SLAVE)) {
ppi->next_state = PPS_MASTER; ppi->next_state = PPS_MASTER;
} else { } else {
ppi->next_state = PPS_LISTENING; ppi->next_state = PPS_LISTENING;
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
} }
} }
......
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