Commit ab3d3253 authored by Sven Meier's avatar Sven Meier Committed by Adam Wujek

bmc: fixed announce timeout dataset update and initializing dataset update

For the announce receipt timeout the datasets shall be updated depending on the other ports states, only if no other in slave update parent dataset.
when a link was connected it runs through initializing which was wrongly updating the parent dataset which caused a short masterchange condition an resyncing.
parent 84c4984a
......@@ -56,24 +56,39 @@ static inline UInteger16 get_be16(void *ptr)
void msg_pack_announce_wr_tlv(struct pp_instance *ppi)
{
void *buf;
int i;
UInteger16 wr_flags = 0;
int locked, class = DSDEF(ppi)->clockQuality.clockClass;
struct wr_dsport *wrp = WR_DSPOR(ppi);
struct pp_globals *ppg = GLBS(ppi);
int is_gm = 1;
buf = ppi->tx_ptp;
/* GM: update clock Class, according to whether we are locked or not */
if (class < PP_CLASS_DEFAULT) {
locked = wrp->ops->locking_poll(ppi, 1);
if (locked == WR_SPLL_READY)
class = PP_CLASS_WR_GM_LOCKED;
else
class = PP_CLASS_WR_GM_UNLOCKED;
bmc_m1(ppi);
if (class != DSDEF(ppi)->clockQuality.clockClass) {
pp_error("New class %i\n", class);
DSDEF(ppi)->clockQuality.clockClass = class;
*(UInteger8 *) (buf + 48) = class;
if (DSDEF(ppi)->numberPorts > 1) {
for (i = 0; i < ppg->defaultDS->numberPorts; i++) {
if ((INST(ppg, i)->state == PPS_UNCALIBRATED) ||
(INST(ppg, i)->state == PPS_SLAVE))
is_gm = 0;
}
}
if (is_gm) {
locked = wrp->ops->locking_poll(ppi, 1);
if (locked == WR_SPLL_READY)
class = PP_CLASS_WR_GM_LOCKED;
else
class = PP_CLASS_WR_GM_UNLOCKED;
bmc_m1(ppi);
if (class != DSDEF(ppi)->clockQuality.clockClass) {
pp_error("New class %i\n", class);
DSDEF(ppi)->clockQuality.clockClass = class;
*(UInteger8 *) (buf + 48) = class;
}
}
}
......
......@@ -599,7 +599,7 @@ slave_s1:
&ebest->hdr.sourcePortIdentity);
bmc_s1(ppi, &ebest->hdr, &ebest->ann);
} else {
/* set that to zero in the case we don't have the master master
/* set that to zero in the case we don't have the master
* on that port */
cmpres = 0;
}
......
......@@ -87,6 +87,39 @@ static int presp_call_servo(struct pp_instance *ppi)
return ret;
}
int st_com_check_announce_receive_timeout(struct pp_instance *ppi)
{
struct pp_globals *ppg = GLBS(ppi);
int is_gm = 1;
int i;
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
&& (ppi->role != PPSI_ROLE_SLAVE)) {
if (DSDEF(ppi)->numberPorts > 1) {
for (i = 0; i < ppg->defaultDS->numberPorts; i++) {
if ((INST(ppg, i)->state == PPS_UNCALIBRATED) ||
(INST(ppg, i)->state == PPS_SLAVE))
is_gm = 0;
}
if (is_gm)
bmc_m1(ppi);
else
bmc_m3(ppi);
} else
bmc_m1(ppi);
ppi->next_state = PPS_MASTER;
} else {
ppi->next_state = PPS_LISTENING;
}
}
return 0;
}
int st_com_peer_handle_pres(struct pp_instance *ppi, unsigned char *buf,
int len)
{
......
......@@ -12,6 +12,8 @@
#include <ppsi/ppsi.h>
/* Contains all functions common to more than one state */
int st_com_check_announce_receive_timeout(struct pp_instance *ppi);
int st_com_peer_handle_preq(struct pp_instance *ppi, unsigned char *buf,
int len);
......
......@@ -243,7 +243,7 @@ int pp_lib_handle_announce(struct pp_instance *ppi, unsigned char *buf, int len)
{
__lib_add_foreign(ppi, buf);
pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
//TODO pp_timeout_set(ppi, PP_TO_ANN_RECEIPT);
if (pp_hooks.handle_announce)
return pp_hooks.handle_announce(ppi);
......
......@@ -184,7 +184,9 @@ static int msg_pack_announce(struct pp_instance *ppi)
*(UInteger8 *) (buf + 52) = DSPAR(ppi)->grandmasterPriority2;
memcpy((buf + 53), &DSPAR(ppi)->grandmasterIdentity,
PP_CLOCK_IDENTITY_LENGTH);
*(UInteger16 *) (buf + 61) = htons(DSCUR(ppi)->stepsRemoved);
/* WORKAROUND 16bit casting doesn't seem to work on unaligned addresses */
*(UInteger8 *) (buf + 61) = (UInteger8)(DSCUR(ppi)->stepsRemoved >> 8);
*(UInteger8 *) (buf + 62) = (UInteger8)DSCUR(ppi)->stepsRemoved;
*(Enumeration8 *) (buf + 63) = DSPRO(ppi)->timeSource;
if (pp_hooks.pack_announce)
......
......@@ -12,7 +12,7 @@
* Initialize parentDS
*/
static void init_parent_ds(struct pp_instance *ppi)
{
{
/* 8.2.3.2 */
DSPAR(ppi)->parentPortIdentity.clockIdentity =
DSDEF(ppi)->clockIdentity;
......@@ -41,12 +41,24 @@ int pp_initializing(struct pp_instance *ppi, unsigned char *pkt, int plen)
unsigned char *id, *mac;
struct DSPort *port = DSPOR(ppi);
struct pp_runtime_opts *opt = OPTS(ppi);
struct pp_globals *ppg = GLBS(ppi);
int init_dspar = 1;
int ret = 0;
int i;
if (ppi->n_ops->init(ppi) < 0) /* it must handle being called twice */
goto failure;
init_parent_ds(ppi);
/* only fill in the parent data set when initializing */
if (DSDEF(ppi)->numberPorts > 1) {
for (i = 0; i < ppg->defaultDS->numberPorts; i++) {
if (INST(ppg, i)->state != PPS_INITIALIZING)
init_dspar = 0;
}
}
if (init_dspar)
init_parent_ds(ppi);
/* Clock identity comes from mac address with 0xff:0xfe intermixed */
id = (unsigned char *)&DSDEF(ppi)->clockIdentity;
......@@ -63,7 +75,8 @@ int pp_initializing(struct pp_instance *ppi, unsigned char *pkt, int plen)
/*
* Initialize parent data set
*/
init_parent_ds(ppi);
if (init_dspar)
init_parent_ds(ppi);
/*
* Initialize port data set
......
......@@ -49,16 +49,7 @@ int pp_listening(struct pp_instance *ppi, unsigned char *pkt, int plen)
hdr->messageType);
}
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
&& (ppi->role != PPSI_ROLE_SLAVE)) {
ppi->next_state = PPS_MASTER;
} else {
ppi->next_state = PPS_LISTENING;
}
}
st_com_check_announce_receive_timeout(ppi);
if (pp_timeout(ppi, PP_TO_FAULT))
ppi->next_state = PPS_FAULTY;
......
......@@ -72,16 +72,7 @@ int pp_passive(struct pp_instance *ppi, unsigned char *pkt, int plen)
hdr->messageType);
}
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
&& (ppi->role != PPSI_ROLE_SLAVE)) {
ppi->next_state = PPS_MASTER;
} else {
ppi->next_state = PPS_LISTENING;
}
}
st_com_check_announce_receive_timeout(ppi);
if (pp_timeout(ppi, PP_TO_FAULT))
ppi->next_state = PPS_FAULTY;
......
......@@ -219,6 +219,7 @@ int pp_slave(struct pp_instance *ppi, unsigned char *pkt, int plen)
/* when entering uncalibrated init servo */
if ((ppi->state == PPS_UNCALIBRATED) && (ppi->is_new_state)) {
memset(&ppi->t1, 0, sizeof(ppi->t1));
pp_diag(ppi, bmc, 2, "Entered to uncalibrated, reset servo\n");
pp_servo_init(ppi);
if (pp_hooks.new_slave)
......@@ -246,18 +247,9 @@ int pp_slave(struct pp_instance *ppi, unsigned char *pkt, int plen)
* This function, common to uncalibrated and slave,
* is the core of the slave: hook
*/
e = slave_execute(ppi);
e = slave_execute(ppi);
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
&& (ppi->role != PPSI_ROLE_SLAVE)) {
ppi->next_state = PPS_MASTER;
} else {
ppi->next_state = PPS_LISTENING;
}
}
st_com_check_announce_receive_timeout(ppi);
out:
switch(e) {
......@@ -272,11 +264,6 @@ out:
break;
}
if ((ppi->next_state == PPS_UNCALIBRATED)
&& (ppi->next_state != ppi->state)) {
pp_servo_init(ppi);
return e;
}
ppi->next_delay = pp_next_delay_2(ppi,
PP_TO_ANN_RECEIPT, PP_TO_REQUEST);
return e;
......
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