Commit b93c9fba authored by Sven Meier's avatar Sven Meier

bmc & default dataset: Handle passive for loopbacke frames correctly, take…

bmc & default dataset: Handle passive for loopbacke frames correctly, take Clockid only from MAC of Port1

The switsch was getting the Clockid for the default datset for each port which has a different MAC on each port, this is wrong, now the Clockid is always fetched only from Port1 for all other ports.
parent bc586acd
......@@ -385,6 +385,8 @@ extern void bmc_store_frgn_master(struct pp_instance *ppi,
struct pp_frgn_master *frgn_master, void *buf, int len);
extern void bmc_add_frgn_master(struct pp_instance *ppi, void *buf,
int len);
extern int bmc_check_frgn_master(struct pp_instance *ppi);
/* msg.c */
extern void msg_init_header(struct pp_instance *ppi, void *buf);
extern int msg_from_current_master(struct pp_instance *ppi);
......
......@@ -270,7 +270,7 @@ static void wr_unpack_announce(void *buf, MsgAnnounce *ann)
int msg_len = htons(*(UInteger16 *) (buf + 2));
pp_diag(NULL, ext, 2, "hook: %s\n", __func__);
if (msg_len > PP_ANNOUNCE_LENGTH)
if (msg_len >= WR_ANNOUNCE_LENGTH)
msg_unpack_announce_wr_tlv(buf, ann);
}
......@@ -299,7 +299,6 @@ static int wr_state_decision(struct pp_instance *ppi, int next_state)
static void wr_state_change(struct pp_instance *ppi)
{
struct pp_globals *ppg = GLBS(ppi);
struct wr_dsport *wrp = WR_DSPOR(ppi);
pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
......
......@@ -474,8 +474,16 @@ static int bmc_state_decision(struct pp_instance *ppi)
ebest = erbest;
goto slave_s1;
}
/* check if the erbest is qualified */
if (ppi->frgn_rec_num)
{
for (i = 0; i < PP_FOREIGN_MASTER_TIME_WINDOW; i++)
qualified += erbest->foreignMasterAnnounceMessages[i];
}
if ((!ppi->frgn_rec_num) && (ppi->state == PPS_LISTENING))
if (((!ppi->frgn_rec_num) || (qualified < PP_FOREIGN_MASTER_THRESHOLD))&& (ppi->state == PPS_LISTENING))
return PPS_LISTENING;
/* copy local information to a foreign_master structure */
......@@ -514,22 +522,6 @@ static int bmc_state_decision(struct pp_instance *ppi)
if (cmpres > 0)
goto passive_p1;
} else {
/* when a boundary clock, check if from own port
* and set into passive mode according to 9.5.2.3
*/
if (DSDEF(ppi)->numberPorts > 1) {
/* message received from the own clock */
if ((ppi->frgn_rec_num > 0) && (!bmc_idcmp(&erbest->sourcePortIdentity.clockIdentity, &DSDEF(ppi)->clockIdentity))) {
for (i = 0; i < PP_FOREIGN_MASTER_TIME_WINDOW; i++)
qualified += erbest->foreignMasterAnnounceMessages[i];
/* is this port worse than the other */
cmpres = bmc_pidcmp(&erbest->sourcePortIdentity, &DSPOR(ppi)->portIdentity);
if ((qualified >= PP_FOREIGN_MASTER_THRESHOLD) && (cmpres < 0))
goto passive_p1;
}
}
/* dataset_cmp D0 with Ebest */
cmpres = bmc_dataset_cmp(ppi, &d0, ebest);
if (cmpres < 0)
......@@ -741,10 +733,12 @@ void bmc_store_frgn_master(struct pp_instance *ppi,
void bmc_add_frgn_master(struct pp_instance *ppi, void *buf,
int len)
{
int cmpres;
int i, j, worst, sel;
struct pp_frgn_master frgn_master;
MsgHeader *hdr = &ppi->received_ptp_header;
struct PortIdentity *pid = &hdr->sourcePortIdentity;
pp_diag(ppi, bmc, 2, "%s\n", __func__);
/* if we are a configured master don't add*/
......@@ -763,6 +757,14 @@ void bmc_add_frgn_master(struct pp_instance *ppi, void *buf,
*/
bmc_store_frgn_master(ppi, &frgn_master, buf, len);
pp_diag(ppi, bmc, 3, "Foreign Master Port Id: "
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x.%04x,\n",
pid->clockIdentity.id[0], pid->clockIdentity.id[1],
pid->clockIdentity.id[2], pid->clockIdentity.id[3],
pid->clockIdentity.id[4], pid->clockIdentity.id[5],
pid->clockIdentity.id[6], pid->clockIdentity.id[7],
pid->portNumber);
if (DSDEF(ppi)->numberPorts > 1) {
/* Check if announce from the same port from this clock 9.3.2.5 a)
* from another port of this clock we still handle even though it
......@@ -770,14 +772,29 @@ void bmc_add_frgn_master(struct pp_instance *ppi, void *buf,
* there is a special handling described for boundary clocks
* which is done in the BMC
*/
if (!bmc_pidcmp(&hdr->sourcePortIdentity,
&DSPOR(ppi)->portIdentity)) {
pp_diag(ppi, bmc, 2, "Announce frame from this port\n");
return;
if (!bmc_idcmp(&pid->clockIdentity,
&DSDEF(ppi)->clockIdentity)) {
cmpres = bmc_pidcmp(pid, &DSPOR(ppi)->portIdentity);
pp_diag(ppi, bmc, 2, "Announce frame from this clock\n");
if (cmpres < 0) {
pp_diag(ppi, bmc, 2, "Announce frame from a better port on this clock\n");
bmc_p1(ppi);
ppi->next_state = PPS_PASSIVE;
/* as long as we receive that reset the announce timeout */
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
} else if (cmpres > 0) {
pp_diag(ppi, bmc, 2, "Announce frame from a worse port on this clock\n");
return;
} else {
pp_diag(ppi, bmc, 2, "Announce frame from this port\n");
return;
}
}
} else {
/* Check if announce from a port from this clock 9.3.2.5 a) */
if (!bmc_idcmp(&hdr->sourcePortIdentity.clockIdentity,
if (!bmc_idcmp(&pid->clockIdentity,
&DSDEF(ppi)->clockIdentity)) {
pp_diag(ppi, bmc, 2, "Announce frame from this clock\n");
return;
......@@ -794,7 +811,7 @@ void bmc_add_frgn_master(struct pp_instance *ppi, void *buf,
/* Check if foreign master is already known */
for (i = 0; i < ppi->frgn_rec_num; i++) {
if (!bmc_pidcmp(&hdr->sourcePortIdentity,
if (!bmc_pidcmp(pid,
&ppi->frgn_master[i].sourcePortIdentity)) {
pp_diag(ppi, bmc, 2, "Foreign Master %i updated\n", i);
......@@ -922,6 +939,41 @@ static void bmc_age_frgn_master(struct pp_instance *ppi)
}
}
/* returns 0 if erbest is not from another port of the device,
* 1 if the port shall go to passive
*/
int bmc_check_frgn_master(struct pp_instance *ppi)
{
int i;
struct PortIdentity *pid;
/* bmc is called several times, so report only at level 2 */
pp_diag(ppi, bmc, 1, "%s\n", __func__);
if (ppi->frgn_rec_num > 0) {
for (i =0; i < ppi->frgn_rec_num; i++) {
/* from the same clock */
if (!bmc_idcmp(&ppi->frgn_master[i].sourcePortIdentity.clockIdentity,
&DSDEF(ppi)->clockIdentity)) {
/* from a better port */
if(0 > bmc_pidcmp(&ppi->frgn_master[i].sourcePortIdentity,
&DSPOR(ppi)->portIdentity)) {
pid = &ppi->frgn_master[i].sourcePortIdentity;
pp_diag(ppi, bmc, 3, "Better Master on same Clock Port Id:"
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x.%04x,\n",
pid->clockIdentity.id[0], pid->clockIdentity.id[1],
pid->clockIdentity.id[2], pid->clockIdentity.id[3],
pid->clockIdentity.id[4], pid->clockIdentity.id[5],
pid->clockIdentity.id[6], pid->clockIdentity.id[7],
pid->portNumber);
return 1;
}
}
}
}
return 0;
}
/* Check if any port is in initilaizing state */
static int bmc_any_port_initializing(struct pp_globals *ppg)
{
......@@ -1057,6 +1109,7 @@ int bmc(struct pp_instance *ppi)
{
struct pp_globals *ppg = GLBS(ppi);
int next_state;
int ret = 0;
/* bmc is called several times, so report only at level 2 */
pp_diag(ppi, bmc, 2, "%s\n", __func__);
......@@ -1075,19 +1128,26 @@ int bmc(struct pp_instance *ppi)
pp_diag(ppi, bmc, 2, "A Port is in intializing\n");
return ppi->state;
}
/* Calculate Erbest of all ports Figure 25 */
bmc_update_erbest(ppg);
if (DSDEF(ppi)->numberPorts > 1) {
ret = bmc_check_frgn_master(ppi);
}
/* Calulate Ebest Figure 25 */
bmc_update_ebest(ppg);
if (ppi->linkUP) {
/* Make state decision */
next_state = bmc_state_decision(ppi);
} else {
if (!ppi->linkUP) {
/* Set it back to initializing */
next_state = PPS_INITIALIZING;
} else if (ret == 1) {
bmc_p1(ppi);
next_state = PPS_PASSIVE;
} else {
/* Make state decision */
next_state = bmc_state_decision(ppi);
}
/* Extra states handled here */
......
......@@ -62,7 +62,8 @@ int pp_initializing(struct pp_instance *ppi, void *buf, int len)
/* Clock identity comes from mac address with 0xff:0xfe intermixed */
id = (unsigned char *)&DSDEF(ppi)->clockIdentity;
mac = ppi->ch[PP_NP_GEN].addr;
/* we always take the one from the first port */
mac = INST(ppg, 0)->ch[PP_NP_GEN].addr;
id[0] = mac[0];
id[1] = mac[1];
id[2] = mac[2];
......
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