Commit 25692a35 authored by baujc's avatar baujc

Code optimization

- Make externalPortConfiguration compliant with the PTP specifications
- Optimize code for externalPortConfiguration
- Optimize code for slaveOnly
- Replace "CONFIG_HAS_P2P && ppi->delayMechanism==P2P" by an inline
function
parent 9c5b584f
......@@ -252,7 +252,9 @@ config NR_FOREIGN_RECORDS
default 1 if ARCH_WRPC
default 5
help
Size of foreignMasterDS data set (Clause 9.3.2.4.5)
Size of foreignMasterDS data set (Clause 9.3.2.4.5).
If the code is optimized with externalPortConfiguration.enable forced to true,
the NR_FOREIGN_RECORDS should be set to 1
config SINGLE_FMASTER
boolean
......
......@@ -120,6 +120,21 @@ static void enable_asymmetryCorrection(struct pp_instance *ppi, Boolean enable )
ppi->asymmetryCorrectionPortDS.constantAsymmetry=picos_to_interval(ppi->cfg.constantAsymmetry_ps);
}
static char *strCodeOpt="CODEOPT=("
#if CONFIG_HAS_CODEOPT_EPC_ENABLED
" EPC"
#endif
#if CONFIG_HAS_CODEOPT_SO_ENABLED
" SO"
#endif
#if CONFIG_HAS_CODEOPT_SINGLE_FMASTER
" SFM"
#endif
#if CONFIG_HAS_CODEOPT_SINGLE_PORT
" SP"
#endif
")";
int main(int argc, char **argv)
{
struct pp_globals *ppg;
......@@ -132,9 +147,9 @@ int main(int argc, char **argv)
setbuf(stdout, NULL);
pp_printf("PPSi. Commit %s, built on " __DATE__ "\n",
PPSI_VERSION);
pp_printf("PPSi. Commit %s, built on " __DATE__ ", %s\n",
PPSI_VERSION,
strCodeOpt);
/* check if there is another instance of PPSi already running */
ppsi_head = wrs_shm_get(wrs_shm_ptp, "", WRS_SHM_READ);
if (!ppsi_head) {
......
......@@ -286,7 +286,9 @@ int pp_state_machine(struct pp_instance *ppi, void *buf, int len)
if ( ppi->ext_hooks->get_tmo_lstate_detection!=NULL)
tmo=(*ppi->ext_hooks->get_tmo_lstate_detection)(ppi);
else
tmo= pp_timeout_get(ppi,PP_TO_ANN_RECEIPT);
tmo= is_externalPortConfigurationEnabled(DSDEF(ppi)) ?
6000 /* JCB: Default value. Is it correct ? */
: pp_timeout_get(ppi,PP_TO_ANN_RECEIPT);
pp_timeout_set(ppi,PP_TO_PROT_STATE, tmo);
}
}
......
......@@ -355,7 +355,7 @@ typedef struct {/*draft P1588_v_29: Clause 17.6.3 */
/** ************************************************************************/
/* Enumeration States (table 8, page 73) */
enum pp_std_states {
typedef enum {
PPS_END_OF_TABLE = 0,
PPS_INITIALIZING,
PPS_FAULTY,
......@@ -367,9 +367,9 @@ enum pp_std_states {
PPS_UNCALIBRATED,
PPS_SLAVE,
PPS_LAST_STATE=PPS_SLAVE
};
}pp_std_states;
enum pp_std_messages {
typedef enum {
PPM_SYNC = 0x0,
PPM_DELAY_REQ,
PPM_PDELAY_REQ,
......@@ -385,7 +385,7 @@ enum pp_std_messages {
PPM_NO_MESSAGE,
PPM_NOTHING_TO_DO = 0x100, /* for hooks.master_msg() */
};
}pp_std_messages;
/* Enumeration Domain Number (table 2, page 41) */
enum ENDomainNumber {
......
......@@ -273,10 +273,8 @@ struct pp_instance {
unsigned long ptp_tx_count;
unsigned long ptp_rx_count;
#if CONFIG_HAS_P2P
Boolean received_dresp; /* Count the number of delay response messages received for a given delay request */
Boolean received_dresp_fup; /* Count the number of delay response follow up messages received for a given delay request */
#endif
Boolean ptp_msg_received; /* Use to detect reception of a ptp message after an ppsi instance initialization */
Boolean ptp_support; /* True if allow pure PTP support */
Boolean ext_enabled; /* True if the extension is enabled */
......
......@@ -54,7 +54,7 @@ struct pp_vlanhdr {
/* Factorize some random information in this table */
struct pp_msgtype_info {
enum pp_std_messages msg_type;
pp_std_messages msg_type;
uint16_t msglen;
unsigned char chtype;
unsigned char is_pdelay;
......@@ -161,6 +161,14 @@ static inline int is_externalPortConfigurationEnabled (defaultDS_t *def) {
return CONFIG_HAS_CODEOPT_EPC_ENABLED || def->externalPortConfigurationEnabled;
}
static inline int is_delayMechanismP2P(struct pp_instance *ppi) {
return CONFIG_HAS_P2P && ppi->delayMechanism == P2P;
}
static inline int is_delayMechanismE2E(struct pp_instance *ppi) {
return CONFIG_HAS_P2P==0 || ppi->delayMechanism == E2E;
}
static inline int is_slaveOnly(defaultDS_t *def) {
return CONFIG_HAS_CODEOPT_SINGLE_PORT && (CONFIG_HAS_CODEOPT_SO_ENABLED || def->slaveOnly);
}
......
......@@ -106,7 +106,7 @@ int l1e_servo_got_sync(struct pp_instance *ppi)
gs->t2=ppi->t2;apply_faulty_stamp(ppi,2);
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P && gs->got_sync) {
if ( is_delayMechanismP2P(ppi) && gs->got_sync) {
gs->got_sync=0;
__l1e_servo_update(ppi);
}else {
......
......@@ -128,8 +128,10 @@ int wr_execute_slave(struct pp_instance *ppi)
{
pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
if (pp_timeout(ppi, PP_TO_FAULT))
wr_servo_reset(ppi); /* the caller handles ptp state machine */
if ( !is_externalPortConfigurationEnabled(DSDEF(ppi)) ) {
if (pp_timeout(ppi, PP_TO_FAULT))
wr_servo_reset(ppi); /* the caller handles ptp state machine */
}
if ((ppi->state == PPS_SLAVE) &&
(WR_DSPOR(ppi)->wrConfig & WR_S_ONLY) &&
......@@ -151,18 +153,22 @@ static int wr_handle_announce(struct pp_instance *ppi)
{
pp_diag(ppi, ext, 2, "hook: %s\n", __func__);
switch (ppi->state) {
case WRS_PRESENT:
case WRS_S_LOCK :
case WRS_LOCKED :
case WRS_CALIBRATION :
case WRS_CALIBRATED :
case WRS_RESP_CALIB_REQ :
case WRS_WR_LINK_ON :
/* reset announce timeout when in the WR slave states */
pp_timeout_reset(ppi, PP_TO_ANN_RECEIPT);
/* Clause 17.6.5.3 : ExternalPortConfiguration enabled
* - The Announce receipt timeout mechanism (see 9.2.6.12) shall not be active.
*/
if ( !is_externalPortConfigurationEnabled(DSDEF(ppi)) ) {
switch (ppi->state) {
case WRS_PRESENT:
case WRS_S_LOCK :
case WRS_LOCKED :
case WRS_CALIBRATION :
case WRS_CALIBRATED :
case WRS_RESP_CALIB_REQ :
case WRS_WR_LINK_ON :
/* reset announce timeout when in the WR slave states */
pp_timeout_reset(ppi, PP_TO_ANN_RECEIPT);
}
}
/* handshake is started in slave mode */
return 0;
}
......@@ -171,7 +177,7 @@ static int wr_sync_followup(struct pp_instance *ppi) {
if ( ppi->ext_enabled ) {
wr_servo_got_sync(ppi);
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P)
if (is_delayMechanismP2P(ppi))
wr_servo_update(ppi);
}
else {
......
......@@ -157,7 +157,7 @@ int wr_servo_got_delay(struct pp_instance *ppi)
s->t3 = ppi->t3; apply_faulty_stamp(ppi, 3);
s->t4 = ppi->t4; apply_faulty_stamp(ppi, 4);
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P) {
if ( is_delayMechanismP2P(ppi) ) {
s->t5 = ppi->t5; apply_faulty_stamp(ppi, 5);
s->t6 = ppi->t6; apply_faulty_stamp(ppi, 6);
......@@ -349,7 +349,7 @@ int wr_servo_update(struct pp_instance *ppi)
wrs_shm_write(ppsi_head, WRS_SHM_WRITE_BEGIN);
prev_delayMM_ps = s->delayMM_ps;
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P) {
if ( is_delayMechanismP2P(ppi) ) {
if (!wr_p2p_offset(ppi, s, &offset))
goto out;
} else {
......
......@@ -330,12 +330,13 @@ void bmc_p2(struct pp_instance *ppi)
static void bmc_setup_local_frgn_master(struct pp_instance *ppi,
struct pp_frgn_master *frgn_master)
{
int i;
/* this shall be always qualified */
for (i = 0; i < PP_FOREIGN_MASTER_TIME_WINDOW; i++)
frgn_master->foreignMasterAnnounceMessages[i] = 1;
if ( !is_externalPortConfigurationEnabled(DSDEF(ppi)) ) {
/* this shall be always qualified */
int i;
for (i = 0; i < PP_FOREIGN_MASTER_TIME_WINDOW; i++)
frgn_master->foreignMasterAnnounceMessages[i] = 1;
}
memcpy(&frgn_master->receivePortIdentity,
&DSPOR(ppi)->portIdentity, sizeof(PortIdentity));
frgn_master->sequenceId = 0;
......@@ -605,6 +606,8 @@ static int bmc_dataset_cmp(struct pp_instance *ppi,
/* State decision algorithm 9.3.3 Fig 26 */
/* Never called if externalPortConfigurationEnabled==TRUE */
static int bmc_state_decision(struct pp_instance *ppi)
{
static struct pp_frgn_master empty_frn_master;
......@@ -621,43 +624,6 @@ static int bmc_state_decision(struct pp_instance *ppi)
* level 2 */
pp_diag(ppi, bmc, 2, "%s\n", __func__);
/* Clause 17.6.5.3: The state machines of Figure 30 or Figure 31 shall not be used */
if ( is_externalPortConfigurationEnabled(DSDEF(ppi))) {
/* Qualification of the foreign master is not checked */
int dstate=ppi->externalPortConfigurationPortDS.desiredState;
/* Update the data set: Table 137 */
switch (ppi->state){
case PPS_SLAVE:
case PPS_UNCALIBRATED:
if ( (ppi->port_idx == ppg->ebest_idx) && erbestValid) {
/* if this configured port is ebest it will be taken as parent */
bmc_s1(ppi, erbest);
}
break;
case PPS_MASTER:
case PPS_PRE_MASTER:
case PPS_PASSIVE:
{
int i=0;
int exec_m2=1;
for (i=(get_numberPorts(DSDEF(ppi))-1); i>=0;i--) {
if ( INST(ppg,i)->state==PPS_SLAVE || INST(ppg,i)->state==PPS_UNCALIBRATED ) {
/* Clause 17.6.5.4 a) if none of the PTP Instance’s PTP Ports are in the
* SLAVE or UNCALIBRATED state and at least one PTP Port is in the MASTER, PRE_MASTER,
* or PASSIVE state, ...
*/
exec_m2=0;
break;
}
}
if ( exec_m2)
bmc_m2(ppi);
}
break;
}
return dstate;
}
if (is_slaveOnly(DSDEF(ppi))) {
if ( !erbestValid )
......@@ -928,10 +894,7 @@ void bmc_store_frgn_master(struct pp_instance *ppi,
void bmc_add_frgn_master(struct pp_instance *ppi, struct pp_frgn_master *frgn_master)
{
int cmpres;
int i, j, worst, sel;
struct pp_frgn_master worst_frgn_master;
struct pp_frgn_master temp_frgn_master;
int sel;
MsgHeader *hdr = &ppi->received_ptp_header;
struct PortIdentity *pid = &hdr->sourcePortIdentity;
......@@ -949,155 +912,163 @@ void bmc_add_frgn_master(struct pp_instance *ppi, struct pp_frgn_master *frgn_m
pid->clockIdentity.id[6], pid->clockIdentity.id[7],
pid->portNumber);
if (get_numberPorts(DSDEF(ppi)) > 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
* states something different in IEEE1588 because in 9.5.2.3
* there is a special handling described for boundary clocks
* which is done in the BMC
if (is_externalPortConfigurationEnabled(DSDEF(ppi)) ) {
/* Clause 17.6.5.3 : 9.5 shall continue to be in effect
* with the exception of the specifications of 9.5.2.3 and 9.5.3
* - per 9.5.2.2, PTP implementation ignores any message received from the same port
* that transmitted this message
* - because 9.5.2.3 is ignored, PTP implementation accepts any message received
* from another "PTP Port" (ppsi instance) on the same "PTP Instance" (wr switch)
*/
if (!bmc_idcmp(&pid->clockIdentity,
&DSDEF(ppi)->clockIdentity)) {
cmpres = bmc_pidcmp(pid, &DSPOR(ppi)->portIdentity);
if (!bmc_idcmp(&pid->clockIdentity, &DSDEF(ppi)->clockIdentity) &&
pid->portNumber==ppi->port_idx) {
pp_diag(ppi, bmc, 2, "Announce frame from same port\n");
return;
}
sel = 0;
ppi->frgn_rec_num=1;
pp_diag(ppi, bmc, 2, "Announce frame from this clock\n");
} else {
int cmpres;
int i, j, worst;
struct pp_frgn_master worst_frgn_master;
struct pp_frgn_master temp_frgn_master;
if (get_numberPorts(DSDEF(ppi)) > 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
* states something different in IEEE1588 because in 9.5.2.3
* there is a special handling described for boundary clocks
* which is done in the BMC
*/
if (!bmc_idcmp(&pid->clockIdentity,
&DSDEF(ppi)->clockIdentity)) {
cmpres = bmc_pidcmp(pid, &DSPOR(ppi)->portIdentity);
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_reset(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");
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_reset(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(&pid->clockIdentity,
&DSDEF(ppi)->clockIdentity)) {
pp_diag(ppi, bmc, 2, "Announce frame from this clock\n");
return;
}
}
} else {
/* Check if announce from a port from this clock 9.3.2.5 a) */
if (!bmc_idcmp(&pid->clockIdentity,
&DSDEF(ppi)->clockIdentity)) {
pp_diag(ppi, bmc, 2, "Announce frame from this clock\n");
/* Check if announce has steps removed larger than 255 9.3.2.5 d) */
if (frgn_master->stepsRemoved >= 255) {
pp_diag(ppi, bmc, 2, "Announce frame steps removed"
"larger or equal 255: %i\n",
frgn_master->stepsRemoved);
return;
}
}
/* Check if announce has steps removed larger than 255 9.3.2.5 d) */
if (frgn_master->stepsRemoved >= 255) {
pp_diag(ppi, bmc, 2, "Announce frame steps removed"
"larger or equal 255: %i\n",
frgn_master->stepsRemoved);
return;
}
/* Check if foreign master is already known */
for (i=0;i < ppi->frgn_rec_num; i++)
{
if (!bmc_pidcmp(pid,
&ppi->frgn_master[i].sourcePortIdentity)) {
/* External Port Configuration */
if ( is_externalPortConfigurationEnabled(DSDEF(ppi))) {
/* Clear all other foreign masters. The last foreign master is always the one to be used */
/* If externalPortConfigurationEnabled is set, foreign master qualification will be not checked */
ppi->frgn_rec_num=0;
}
pp_diag(ppi, bmc, 2, "Foreign Master %i updated\n", i);
/* Check if foreign master is already known */
i=0;
#if !CONFIG_HAS_CODEOPT_SINGLE_FMASTER
/* If only one foreign master is declared, the loop become useless and can be optimized */
for (;i < ppi->frgn_rec_num; i++)
#else
if ( i < ppi->frgn_rec_num )
#endif
{
if (!bmc_pidcmp(pid,
&ppi->frgn_master[i].sourcePortIdentity)) {
pp_diag(ppi, bmc, 2, "Foreign Master %i updated\n", i);
/* fill in number of announce received */
for (j = 0; j < PP_FOREIGN_MASTER_TIME_WINDOW; j++) {
frgn_master->foreignMasterAnnounceMessages[j] =
ppi->frgn_master[i].foreignMasterAnnounceMessages[j];
/* fill in number of announce received */
for (j = 0; j < PP_FOREIGN_MASTER_TIME_WINDOW; j++) {
frgn_master->foreignMasterAnnounceMessages[j] =
ppi->frgn_master[i].foreignMasterAnnounceMessages[j];
}
/* update the number of announce received if correct
* sequence number 9.3.2.5 b) */
if (hdr->sequenceId
== (ppi->frgn_master[i].sequenceId + 1))
frgn_master->foreignMasterAnnounceMessages[0]++;
/* already in Foreign master data set, update info */
memcpy(&ppi->frgn_master[i], frgn_master,
sizeof(struct pp_frgn_master));
return;
}
/* update the number of announce received if correct
* sequence number 9.3.2.5 b) */
if (hdr->sequenceId
== (ppi->frgn_master[i].sequenceId + 1))
frgn_master->foreignMasterAnnounceMessages[0]++;
/* already in Foreign master data set, update info */
memcpy(&ppi->frgn_master[i], &frgn_master,
sizeof(frgn_master));
return;
}
}
/* set qualification timeouts as valid to compare against worst*/
for (i = 0; i < PP_FOREIGN_MASTER_TIME_WINDOW; i++)
frgn_master->foreignMasterAnnounceMessages[i] = 1;
/* set qualification timeouts as valid to compare against worst*/
for (i = 0; i < PP_FOREIGN_MASTER_TIME_WINDOW; i++)
frgn_master->foreignMasterAnnounceMessages[i] = 1;
/* New foreign master */
if ( !CONFIG_HAS_CODEOPT_SINGLE_FMASTER ) {
/* Code optimization if only one foreign master */
if (ppi->frgn_rec_num < PP_NR_FOREIGN_RECORDS) {
/* there is space for a new one */
sel = ppi->frgn_rec_num;
ppi->frgn_rec_num++;
/* New foreign master */
if ( !CONFIG_HAS_CODEOPT_SINGLE_FMASTER ) {
/* Code optimization if only one foreign master */
if (ppi->frgn_rec_num < PP_NR_FOREIGN_RECORDS) {
/* there is space for a new one */
sel = ppi->frgn_rec_num;
ppi->frgn_rec_num++;
} else {
/* find the worst to replace */
for (i = 1, worst = 0; i < ppi->frgn_rec_num; i++) {
/* qualify them for this check */
memcpy(&temp_frgn_master, &ppi->frgn_master[i],
sizeof(temp_frgn_master));
} else {
/* find the worst to replace */
for (i = 1, worst = 0; i < ppi->frgn_rec_num; i++) {
/* qualify them for this check */
memcpy(&temp_frgn_master, &ppi->frgn_master[i],
sizeof(struct pp_frgn_master));
memcpy(&worst_frgn_master, &ppi->frgn_master[worst],
sizeof(struct pp_frgn_master));
for (j = 0; j < PP_FOREIGN_MASTER_TIME_WINDOW; j++) {
temp_frgn_master.foreignMasterAnnounceMessages[j] = 1;
worst_frgn_master.foreignMasterAnnounceMessages[j] = 1;
}
if (bmc_dataset_cmp(ppi, &temp_frgn_master,
&worst_frgn_master) > 0)
worst = i;
}
/* copy the worst again and qualify it */
memcpy(&worst_frgn_master, &ppi->frgn_master[worst],
sizeof(worst_frgn_master));
for (j = 0; j < PP_FOREIGN_MASTER_TIME_WINDOW; j++) {
temp_frgn_master.foreignMasterAnnounceMessages[j] = 1;
worst_frgn_master.foreignMasterAnnounceMessages[j] = 1;
sizeof(struct pp_frgn_master));
for (i = 0; i < PP_FOREIGN_MASTER_TIME_WINDOW; i++) {
worst_frgn_master.foreignMasterAnnounceMessages[i] = 1;
}
if (bmc_dataset_cmp(ppi, &temp_frgn_master,
&worst_frgn_master) > 0)
worst = i;
}
/* check if worst is better than the new one, and skip the new
* one if so */
if (bmc_dataset_cmp(ppi, &worst_frgn_master, frgn_master)
< 0) {
pp_diag(ppi, bmc, 1, "%s:%i: New foreign "
"master worse than worst in the full "
"table, skipping\n",
__func__, __LINE__);
return;
}
/* copy the worst again and qualify it */
memcpy(&worst_frgn_master, &ppi->frgn_master[worst],
sizeof(worst_frgn_master));
for (i = 0; i < PP_FOREIGN_MASTER_TIME_WINDOW; i++) {
worst_frgn_master.foreignMasterAnnounceMessages[i] = 1;
}
/* check if worst is better than the new one, and skip the new
* one if so */
if (bmc_dataset_cmp(ppi, &worst_frgn_master, frgn_master)
< 0) {
pp_diag(ppi, bmc, 1, "%s:%i: New foreign "
"master worse than worst in the full "
"table, skipping\n",
__func__, __LINE__);
return;
sel = worst;
}
sel = worst;
} else {
sel = 0;
ppi->frgn_rec_num=1;
}
} else {
sel = 0;
ppi->frgn_rec_num=1;
}
/* clear qualification timeouts */
for (i = 0; i < PP_FOREIGN_MASTER_TIME_WINDOW; i++)
frgn_master->foreignMasterAnnounceMessages[i] = 0;
/* This is the first one qualified 9.3.2.5 e)*/
frgn_master->foreignMasterAnnounceMessages[0] = 1;
/* clear qualification timeouts */
for (i = 0; i < PP_FOREIGN_MASTER_TIME_WINDOW; i++)
frgn_master->foreignMasterAnnounceMessages[i] = 0;
/* This is the first one qualified 9.3.2.5 e)*/
frgn_master->foreignMasterAnnounceMessages[0] = 1;
}
/* Copy the temporary foreign master entry */
memcpy(&ppi->frgn_master[sel], &frgn_master,
sizeof(frgn_master));
memcpy(&ppi->frgn_master[sel], frgn_master,
sizeof(struct pp_frgn_master));
pp_diag(ppi, bmc, 1, "New foreign Master %i added\n", sel);
}
......@@ -1147,13 +1118,8 @@ static void bmc_age_frgn_master(struct pp_instance *ppi)
int i, j;
int qualified;
i=0;
#if !CONFIG_HAS_CODEOPT_SINGLE_FMASTER
/* If only one foreign master is declared, the loop become useless and can be optimized */
for (;i < ppi->frgn_rec_num; i++)
#else
if ( i < ppi->frgn_rec_num )
#endif
for (i=0;i < ppi->frgn_rec_num; i++)
{
/* get qualification */
if ( !(qualified=is_ebest(GLBS(ppi),&ppi->frgn_master[i])) ) {
......@@ -1259,38 +1225,39 @@ static void bmc_update_erbest_inst(struct pp_instance *ppi) {
frgn_master = ppi->frgn_master;
if ((ppi->state != PPS_FAULTY) && (ppi->state != PPS_DISABLED)) {
best=0;
if ( !CONFIG_HAS_CODEOPT_SINGLE_FMASTER ) {
/* Code optimization if only one foreign master. The loop becomes obsolete */
for (j = 1; j < ppi->frgn_rec_num;
j++)
if (bmc_dataset_cmp(ppi,
&frgn_master[j],
&frgn_master[best]
) < 0)
best = j;
}
pp_diag(ppi, bmc, 1, "Best foreign master is "
"at index %i/%i\n", best,
ppi->frgn_rec_num);
frgn_master_pid = &frgn_master[best].sourcePortIdentity;
pp_diag(ppi, bmc, 3, fmt_clock_identity_id,
"SourcePortId",
frgn_master_pid->clockIdentity.id[0], frgn_master_pid->clockIdentity.id[1],
frgn_master_pid->clockIdentity.id[2], frgn_master_pid->clockIdentity.id[3],
frgn_master_pid->clockIdentity.id[4], frgn_master_pid->clockIdentity.id[5],
frgn_master_pid->clockIdentity.id[6], frgn_master_pid->clockIdentity.id[7],
frgn_master_pid->portNumber);
if ( !is_externalPortConfigurationEnabled(DSDEF(ppi)) ) {
if ( !CONFIG_HAS_CODEOPT_SINGLE_FMASTER ) {
/* Code optimization if only one foreign master. The loop becomes obsolete */
for (j = 1; j < ppi->frgn_rec_num;
j++)
if (bmc_dataset_cmp(ppi,
&frgn_master[j],
&frgn_master[best]
) < 0)
best = j;
}
pp_diag(ppi, bmc, 1, "Best foreign master is "
"at index %i/%i\n", best,
ppi->frgn_rec_num);
frgn_master_pid = &frgn_master[best].sourcePortIdentity;
pp_diag(ppi, bmc, 3, fmt_clock_identity_id,
"SourcePortId",
frgn_master_pid->clockIdentity.id[0], frgn_master_pid->clockIdentity.id[1],
frgn_master_pid->clockIdentity.id[2], frgn_master_pid->clockIdentity.id[3],
frgn_master_pid->clockIdentity.id[4], frgn_master_pid->clockIdentity.id[5],
frgn_master_pid->clockIdentity.id[6], frgn_master_pid->clockIdentity.id[7],
frgn_master_pid->portNumber);
}
ppi->frgn_rec_best = best;
} else {
} else { //if ((ppi->state != ...
ppi->frgn_rec_num = 0;
ppi->frgn_rec_best = -1;
memset(&ppi->frgn_master, 0,
sizeof(ppi->frgn_master));
}
} else {
} else { // if (ppi->frgn_rec_num > 0)
ppi->frgn_rec_best = -1;
}
......@@ -1507,8 +1474,9 @@ void bmc_calculate_ebest(struct pp_globals *ppg)
/* check if we shall update the clock qualities */
bmc_update_clock_quality(ppg);
/* Age foreign masters */
bmc_age_frgn_masters(ppg);
if ( !is_externalPortConfigurationEnabled(GDSDEF(ppg)) )
/* Age foreign masters */
bmc_age_frgn_masters(ppg);
/* Only if port is not any port is in the INITIALIZING state 9.2.6.8 */
{
......@@ -1523,12 +1491,13 @@ void bmc_calculate_ebest(struct pp_globals *ppg)
/* Calculate Erbest of all ports Figure 25 */
bmc_update_erbest(ppg);
/* Calulate Ebest Figure 25 */
/* ebest shall be calculated only once after the calculation of the erbest on all ports
* See Figure 25 STATE_DECISION_EVENT logic
*/
bmc_update_ebest(ppg);
if ( !is_externalPortConfigurationEnabled(GDSDEF(ppg)) ) {
/* Calculate Ebest Figure 25 */
/* ebest shall be calculated only once after the calculation of the erbest on all ports
* See Figure 25 STATE_DECISION_EVENT logic
*/
bmc_update_ebest(ppg);
}
/* Set triggers for PPSi instances to execute
* bmc_apply_state_descision()
*/
......@@ -1536,14 +1505,55 @@ void bmc_calculate_ebest(struct pp_globals *ppg)
INST(ppg,i)->bmca_execute=1;
}
/*
* Clause 17.6.5.4: Updating data sets when external port configuration is enabled
*/
static int bmc_state_descision_epc(struct pp_instance *ppi) {
switch (ppi->state){
case PPS_SLAVE:
case PPS_UNCALIBRATED:
/* Update the data set: Table 137 */
if ( ppi->frgn_rec_num>0 ) {
bmc_s1(ppi,&ppi->frgn_master[0]);
}
break;
case PPS_MASTER:
case PPS_PRE_MASTER:
case PPS_PASSIVE:
{
/* Update the data set: Table 136 */
int i;
int exec_m2=1;
for (i=get_numberPorts(DSDEF(ppi)-1); i>=0;i--) {
pp_std_states state=INST(GLBS(ppi),i)->state;
if ( state==PPS_SLAVE || state==PPS_UNCALIBRATED ) {
/* Clause 17.6.5.4 a) if none of the PTP Instance’s PTP Ports are in the
* SLAVE or UNCALIBRATED state and at least one PTP Port is in the MASTER, PRE_MASTER,
* or PASSIVE state, ...
*/
exec_m2=0;
break;
}
}
if ( exec_m2)
bmc_m2(ppi);
}
break;
}
return ppi->externalPortConfigurationPortDS.desiredState;
}
int bmc_apply_state_descision(struct pp_instance *ppi) {
int next_state=-1;
/* Clause 17.6.5.3: The state machines of Figure 30 or Figure 31 shall not be used */
if ( !is_externalPortConfigurationEnabled(DSDEF(ppi)) ) {
if (!ppi->link_up) {
/* Set it back to initializing */
next_state=PPS_INITIALIZING;
if (!ppi->link_up) {
/* Set it back to initializing */
next_state=PPS_INITIALIZING;
} else {
if ( is_externalPortConfigurationEnabled(DSDEF(ppi)) ) {
/* Clause 17.6.5.3: The state machines of Figure 30 or Figure 31 shall not be used */
next_state=bmc_state_descision_epc(ppi);
} else {
if ( get_numberPorts(DSDEF(ppi)) > 1 ) {
if ( bmc_check_frgn_master(ppi) ) {
......@@ -1554,7 +1564,7 @@ int bmc_apply_state_descision(struct pp_instance *ppi) {
}
}
if ( next_state == -1 ) {
if ( !is_externalPortConfigurationEnabled(DSDEF(ppi)) && next_state == -1 ) {
/* Make state decision */
next_state= bmc_state_decision(ppi);
}
......@@ -1562,5 +1572,5 @@ int bmc_apply_state_descision(struct pp_instance *ppi) {
/* Extra states handled here */
if (is_ext_hook_available(ppi,state_decision))
next_state = ppi->ext_hooks->state_decision(ppi, ppi->next_state);
return next_state;
return is_externalPortConfigurationEnabled(DSDEF(ppi)) ? ppi->state : next_state;
}
......@@ -20,7 +20,9 @@ static int presp_call_servo(struct pp_instance *ppi)
if (is_incorrect(&ppi->t4))
return 0; /* not an error, just no data */
pp_timeout_reset(ppi, PP_TO_FAULT);
if ( !is_externalPortConfigurationEnabled(DSDEF(ppi)) )
pp_timeout_reset(ppi, PP_TO_FAULT);
if (is_ext_hook_available(ppi,handle_presp))
ret = ppi->ext_hooks->handle_presp(ppi);
else {
......
......@@ -84,27 +84,29 @@ static int is_grand_master(struct pp_instance *ppi) {
return has_master && !has_slave;
}
/* This function should not be called when externalPortConfiguration is enabled */
int st_com_check_announce_receive_timeout(struct pp_instance *ppi)
{
if (pp_timeout(ppi, PP_TO_ANN_RECEIPT)) {
/* 9.2.6.11 b) reset timeout when an announce timeout happened */
pp_timeout_reset(ppi, PP_TO_ANN_RECEIPT);
if ( !is_slaveOnly(DSDEF(ppi)) ) {
if ( is_grand_master(ppi) ) {
bmc_m1(ppi);
/* Clause 17.6.5.3 : ExternalPortConfiguration enabled
* - The Announce receipt timeout mechanism (see 9.2.6.12) shall not be active.
*/
if ( !is_externalPortConfigurationEnabled(DSDEF(ppi))) {
if (pp_timeout(ppi, PP_TO_ANN_RECEIPT)) {
/* 9.2.6.11 b) reset timeout when an announce timeout happened */
pp_timeout_reset(ppi, PP_TO_ANN_RECEIPT);
if ( !is_slaveOnly(DSDEF(ppi)) ) {
if ( is_grand_master(ppi) ) {
bmc_m1(ppi);
} else {
bmc_m3(ppi);
}
ppi->next_state = PPS_MASTER;
} else {
bmc_m3(ppi);
}
if ( is_externalPortConfigurationEnabled(DSDEF(ppi)) ) {
/* Clause 17.6.5.3 : The announce receipt timeout mechanism shall not be active */
return 0;
ppi->next_state = PPS_LISTENING;
}
ppi->next_state = PPS_MASTER;
} else {
ppi->next_state = PPS_LISTENING;
bmc_flush_erbest(ppi); /* ErBest is removed from the foreign master list and ErBest need to be re-computed */
}
bmc_flush_erbest(ppi); /* ErBest is removed from the foreign master list and ErBest need to be re-computed */
}
return 0;
}
......
......@@ -402,10 +402,8 @@ static int msg_issue_delay_req(struct pp_instance *ppi)
int msg_issue_request(struct pp_instance *ppi)
{
#if CONFIG_HAS_P2P
if (ppi->delayMechanism == P2P)
if ( is_delayMechanismP2P(ppi) )
return msg_issue_pdelay_req(ppi);
#endif
return msg_issue_delay_req(ppi);
}
......
......@@ -97,9 +97,11 @@ int pp_init_globals(struct pp_globals *ppg, struct pp_runtime_opts *pp_rt_opts)
*/
def->externalPortConfigurationEnabled=pp_rt_opts->externalPortConfigurationEnabled;
def->slaveOnly=rt_opts->slaveOnly;
if ( is_slaveOnly(def) && is_externalPortConfigurationEnabled(def) ) {
pp_printf("ppsi: Incompatible configuration: SlaveOnly and externalPortConfigurationEnabled\n");
def->slaveOnly=FALSE;
if ( is_externalPortConfigurationEnabled(def) ) {
if ( def->slaveOnly ) {
pp_printf("ppsi: Incompatible configuration: SlaveOnly and externalPortConfigurationEnabled\n");
def->slaveOnly=FALSE;
}
}
......
......@@ -57,7 +57,8 @@ static void _pp_servo_init(struct pp_instance *ppi)
servo->flags |= PP_SERVO_FLAG_VALID;
pp_timeout_reset(ppi, PP_TO_FAULT);
if ( !is_externalPortConfigurationEnabled(DSDEF(ppi)) )
pp_timeout_reset(ppi, PP_TO_FAULT);
pp_diag(ppi, servo, 1, "Initialized: obs_drift %lli\n",
servo->obs_drift);
}
......@@ -167,10 +168,9 @@ int pp_servo_calculate_delays(struct pp_instance *ppi) {
if ( is_timestamps_incorrect(ppi,&errcount, 0x3 /* mask=t1&t2 */))
return 0; /* Error. Invalid timestamps */
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P)
ret=calculate_p2p_delayMM(ppi);
else
ret=calculate_e2e_delayMM(ppi);
ret= is_delayMechanismP2P(ppi) ?
calculate_p2p_delayMM(ppi)
: calculate_e2e_delayMM(ppi);
if ( !ret)
return 0; /* delays cannot be calculated */
......@@ -250,7 +250,7 @@ void pp_servo_got_sync(struct pp_instance *ppi, int allowTimingOutput)
servo->t1=ppi->t1;
servo->t2=ppi->t2;
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P && servo->got_sync) {
if ( is_delayMechanismP2P(ppi) && servo->got_sync) {
/* P2P mechanism */
servo->got_sync=0;
__pp_servo_update(ppi);
......
......@@ -51,14 +51,21 @@ int pp_listening(struct pp_instance *ppi, void *buf, int len)
int e = 0; /* error var, to check errors in msg handling */
MsgHeader *hdr = &ppi->received_ptp_header;
pp_timeout_reset(ppi, PP_TO_FAULT); /* no fault as long as we listen */
if (is_ext_hook_available(ppi,listening))
e = ppi->ext_hooks->listening(ppi, buf, len);
if (e)
goto out;
if ( is_externalPortConfigurationEnabled(DSDEF(ppi)) ) {
if (is_ext_hook_available(ppi,listening))
e=ppi->ext_hooks->listening(ppi, buf, len);
if ( e )
goto epc_out;
} else {
pp_timeout_reset(ppi, PP_TO_FAULT); /* no fault as long as we listen */
if (is_ext_hook_available(ppi,listening))
e = ppi->ext_hooks->listening(ppi, buf, len);
if ( e )
goto out;
}
/* when the clock is using peer-delay, listening must send it too */
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P)
if ( is_delayMechanismP2P(ppi) )
e = pp_lib_may_issue_request(ppi);
/*
* The management of messages is now table-driven
......@@ -72,22 +79,29 @@ int pp_listening(struct pp_instance *ppi, void *buf, int len)
hdr->messageType);
}
st_com_check_announce_receive_timeout(ppi);
/* Clause 17.6.5.3 : ExternalPortConfiguration enabled
* - The Announce receipt timeout mechanism (see 9.2.6.12) shall not be active.
*/
if ( ! is_externalPortConfigurationEnabled(DSDEF(ppi))) {
st_com_check_announce_receive_timeout(ppi);
if (pp_timeout(ppi, PP_TO_FAULT))
ppi->next_state = PPS_FAULTY;
if (pp_timeout(ppi, PP_TO_FAULT))
ppi->next_state = PPS_FAULTY;
out:
if (e != 0)
ppi->next_state = PPS_FAULTY;
out:;
if (e != 0)
ppi->next_state = PPS_FAULTY;
if (CONFIG_HAS_P2P && ppi->delayMechanism ==P2P) {
ppi->next_delay = pp_next_delay_2(ppi,
PP_TO_ANN_RECEIPT, PP_TO_REQUEST);
} else {
ppi->next_delay = pp_next_delay_1(ppi,
PP_TO_ANN_RECEIPT);
ppi->next_delay = is_delayMechanismP2P(ppi) ?
pp_next_delay_2(ppi,PP_TO_ANN_RECEIPT, PP_TO_REQUEST) :
pp_next_delay_1(ppi, PP_TO_ANN_RECEIPT);
return e;
}
epc_out:;
ppi->next_delay = is_delayMechanismP2P(ppi) ?
pp_next_delay_1(ppi, PP_TO_REQUEST) :
INT_MAX;
return e;
}
......@@ -69,13 +69,16 @@ int pp_master(struct pp_instance *ppi, void *buf, int len)
int pre = (ppi->state == PPS_PRE_MASTER);
int e = 0; /* error var, to check errors in msg handling */
/* no fault as long as we are master */
pp_timeout_reset(ppi, PP_TO_FAULT);
if ( !is_externalPortConfigurationEnabled(DSDEF(ppi))) {
/* no fault as long as we are master */
pp_timeout_reset(ppi, PP_TO_FAULT);
}
/* upgrade from pre-master to master */
if (pre &&
pp_timeout(ppi, PP_TO_QUALIFICATION) &&
!is_externalPortConfigurationEnabled(DSDEF(ppi))) {
if (!is_externalPortConfigurationEnabled(DSDEF(ppi)) &&
pre &&
pp_timeout(ppi, PP_TO_QUALIFICATION)
) {
ppi->next_state = PPS_MASTER;
/* start sending immediately and reenter */
pp_timeout_reset_N(ppi, PP_TO_SYNC_SEND,0);
......@@ -94,7 +97,7 @@ int pp_master(struct pp_instance *ppi, void *buf, int len)
}
/* when the clock is using peer-delay, the master must send it too */
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P)
if ( is_delayMechanismP2P(ppi) )
pp_lib_may_issue_request(ppi);
/*
......@@ -124,42 +127,49 @@ int pp_master(struct pp_instance *ppi, void *buf, int len)
msgtype);
}
if (pp_timeout(ppi, PP_TO_FAULT))
ppi->next_state = PPS_FAULTY;
out:
switch(e) {
case PP_SEND_OK: /* 0 */
/* Why should we switch to slave? Remove this code? */
if (is_slaveOnly(DSDEF(ppi)))
ppi->next_state = PPS_LISTENING;
break;
case PP_SEND_ERROR:
/* fall through: a lost frame is not the end of the world */
case PP_SEND_NO_STAMP:
/* nothing, just keep the ball rolling */
e = 0;
break;
if ( !is_externalPortConfigurationEnabled(DSDEF(ppi))) {
if (pp_timeout(ppi, PP_TO_FAULT))
ppi->next_state = PPS_FAULTY;
}
if (pre) {
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P) {
ppi->next_delay = pp_next_delay_2(ppi,
PP_TO_QUALIFICATION, PP_TO_REQUEST);
out:
if ( is_externalPortConfigurationEnabled(DSDEF(ppi))) {
if ( e==PP_SEND_ERROR || e==PP_SEND_NO_STAMP )
e=0;
if (pre) {
ppi->next_delay = is_delayMechanismP2P(ppi) ?
pp_next_delay_1(ppi,PP_TO_REQUEST) :
INT_MAX;
} else {
ppi->next_delay = pp_next_delay_1(ppi,
PP_TO_QUALIFICATION);
}
ppi->next_delay = is_delayMechanismP2P(ppi) ?
pp_next_delay_3(ppi,PP_TO_ANN_SEND, PP_TO_SYNC_SEND, PP_TO_REQUEST) :
pp_next_delay_2(ppi,PP_TO_ANN_SEND, PP_TO_SYNC_SEND);
}
} else {
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P) {
ppi->next_delay = pp_next_delay_3(ppi,
PP_TO_ANN_SEND, PP_TO_SYNC_SEND, PP_TO_REQUEST);
switch(e) {
case PP_SEND_OK: /* 0 */
/* Why should we switch to slave? Remove this code? */
if ( is_slaveOnly(DSDEF(ppi)) )
ppi->next_state = PPS_LISTENING;
break;
case PP_SEND_ERROR:
/* fall through: a lost frame is not the end of the world */
case PP_SEND_NO_STAMP:
/* nothing, just keep the ball rolling */
e = 0;
break;
}
if (pre) {
ppi->next_delay = is_delayMechanismP2P(ppi) ?
pp_next_delay_2(ppi,PP_TO_QUALIFICATION, PP_TO_REQUEST) :
pp_next_delay_1(ppi,PP_TO_QUALIFICATION);
} else {
ppi->next_delay = pp_next_delay_2(ppi,
PP_TO_ANN_SEND, PP_TO_SYNC_SEND);
}
ppi->next_delay = is_delayMechanismP2P(ppi) ?
pp_next_delay_3(ppi,PP_TO_ANN_SEND, PP_TO_SYNC_SEND, PP_TO_REQUEST) :
pp_next_delay_2(ppi,PP_TO_ANN_SEND, PP_TO_SYNC_SEND);
}
}
return e;
}
......@@ -46,13 +46,18 @@ static int passive_handle_announce(struct pp_instance *ppi, void *buf, int len)
bmc_add_frgn_master(ppi, &frgn_master);
}
if (erbest!=NULL && !bmc_pidcmp(&hdr->sourcePortIdentity,
&erbest->sourcePortIdentity)) {
/*
* 9.2.6.11 d) reset timeout when an announce
* is received from the clock putting it into passive (erbest)
*/
pp_timeout_reset(ppi, PP_TO_ANN_RECEIPT);
/* Clause 17.6.5.3 : ExternalPortConfiguration enabled
* - The Announce receipt timeout mechanism (see 9.2.6.12) shall not be active.
*/
if (! is_externalPortConfigurationEnabled(DSDEF(ppi))) {
if (erbest!=NULL && !bmc_pidcmp(&hdr->sourcePortIdentity,
&erbest->sourcePortIdentity)) {
/*
* 9.2.6.11 d) reset timeout when an announce
* is received from the clock putting it into passive (erbest)
*/
pp_timeout_reset(ppi, PP_TO_ANN_RECEIPT);
}
}
return 0;
......@@ -63,11 +68,13 @@ int pp_passive(struct pp_instance *ppi, void *buf, int len)
int e = 0; /* error var, to check errors in msg handling */
MsgHeader *hdr = &ppi->received_ptp_header;
pp_timeout_reset(ppi, PP_TO_FAULT); /* no fault as long as we are
* passive */
if ( ! is_externalPortConfigurationEnabled(DSDEF(ppi)) ) {
/* no fault as long as we are passive */
pp_timeout_reset(ppi, PP_TO_FAULT);
}
/* when the clock is using peer-delay, passive must send it too */
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P)
if ( is_delayMechanismP2P(ppi) )
e = pp_lib_may_issue_request(ppi);
/*
......@@ -82,21 +89,22 @@ int pp_passive(struct pp_instance *ppi, void *buf, int len)
hdr->messageType);
}
st_com_check_announce_receive_timeout(ppi);
if (pp_timeout(ppi, PP_TO_FAULT))
ppi->next_state = PPS_FAULTY;
if (e != 0)
ppi->next_state = PPS_FAULTY;
if (CONFIG_HAS_P2P && ppi->delayMechanism == P2P) {
ppi->next_delay = pp_next_delay_2(ppi,
PP_TO_ANN_RECEIPT, PP_TO_REQUEST);
/* Clause 17.6.5.3 : ExternalPortConfiguration enabled
* - The Announce receipt timeout mechanism (see 9.2.6.12) shall not be active.
*/
if ( is_externalPortConfigurationEnabled(DSDEF(ppi))) {
ppi->next_delay = is_delayMechanismP2P(ppi) ?
pp_next_delay_1(ppi,PP_TO_REQUEST) :
INT_MAX;
} else {
ppi->next_delay = pp_next_delay_1(ppi,
PP_TO_ANN_RECEIPT);
st_com_check_announce_receive_timeout(ppi);
ppi->next_delay = is_delayMechanismP2P(ppi) ?
pp_next_delay_2(ppi,PP_TO_ANN_RECEIPT, PP_TO_REQUEST) :
pp_next_delay_1(ppi,PP_TO_ANN_RECEIPT);
if (pp_timeout(ppi, PP_TO_FAULT) || e !=0 )
ppi->next_state = PPS_FAULTY;
}
return e;
}
......@@ -46,7 +46,7 @@ static int slave_handle_sync(struct pp_instance *ppi, void *buf,
return 0;
}
if ( ppi->delayMechanism==E2E && ppi->t1.scaled_nsecs==0 && ppi->t1.secs==0 ) {
if ( is_delayMechanismE2E(ppi) && ppi->t1.scaled_nsecs==0 && ppi->t1.secs==0 ) {
/* First time we receive the SYNC message in uncalib/slave state
* We set the REQUEST time-out to the minDelayReqInterval/2 value (500ms)
* in order to provide quickly a DelayReq message
......@@ -159,7 +159,9 @@ static int slave_handle_response(struct pp_instance *ppi, void *buf,
pp_time_add(&ppi->t4, &hdr->cField);
/* WARNING: should be "sub" (see README-cfield::BUG) */
pp_timeout_reset(ppi, PP_TO_FAULT);
if ( !is_externalPortConfigurationEnabled(DSDEF(ppi)) )
pp_timeout_reset(ppi, PP_TO_FAULT);
if (is_ext_hook_available(ppi,handle_resp)) {
ret=ppi->ext_hooks->handle_resp(ppi);
}
......@@ -192,6 +194,10 @@ static int slave_handle_announce(struct pp_instance *ppi, void *buf, int len)
*/
bmc_store_frgn_master(ppi, &frgn_master, buf, len);
/* Clause 17.6.5.3 : ExternalPortConfiguration enabled
* - The Announce receipt timeout mechanism (see 9.2.6.12) shall not be active.
* - The specifications of 9.5.3 shall be replaced by the specifications of 17.6.5.5
*/
if (!is_externalPortConfigurationEnabled(DSDEF(ppi)) ) {
if ( !msg_from_current_master(ppi) ) {
pp_error("%s: Announce message is not from current parent\n",
......@@ -207,13 +213,13 @@ static int slave_handle_announce(struct pp_instance *ppi, void *buf, int len)
return 0;
}
/* 9.2.6.11 a) reset timeout */
pp_timeout_reset(ppi, PP_TO_ANN_RECEIPT);
}
/* Add foreign master: Figure 36 & 54 */
bmc_add_frgn_master(ppi, &frgn_master);
/* 9.2.6.11 a) reset timeout */
pp_timeout_reset(ppi, PP_TO_ANN_RECEIPT);
/* 9.5.3 Figure 29 update data set if announce from current master */
bmc_s1(ppi, &frgn_master);
......@@ -254,9 +260,11 @@ int pp_slave(struct pp_instance *ppi, void *buf, int len)
ppi->next_state = PPS_SLAVE;
}
} else {
/* TODO add implementation specific SYNCHRONIZATION event */
if ( !is_externalPortConfigurationEnabled(DSDEF(ppi)) ) {
/* TODO add implementation specific SYNCHRONIZATION event */
if (pp_timeout(ppi, PP_TO_FAULT))
ppi->next_state = PPS_UNCALIBRATED;
}
}
/* Force to stay on desired state if externalPortConfiguration option is enabled */
if (is_externalPortConfigurationEnabled(DSDEF(ppi)) )
......@@ -295,15 +303,20 @@ int pp_slave(struct pp_instance *ppi, void *buf, int len)
*/
ret = slave_execute(ppi);
st_com_check_announce_receive_timeout(ppi);
/* Clause 17.6.5.3 : ExternalPortConfiguration enabled
* - The Announce receipt timeout mechanism (see 9.2.6.12) shall not be active.
*/
if ( !is_externalPortConfigurationEnabled(DSDEF(ppi)))
st_com_check_announce_receive_timeout(ppi);
out:
if ( ret==PP_SEND_NO_STAMP ) {
ret = PP_SEND_OK;/* nothing, just keep the ball rolling */
}
ppi->next_delay = pp_next_delay_2(ppi,
PP_TO_ANN_RECEIPT, PP_TO_REQUEST);
ppi->next_delay = is_externalPortConfigurationEnabled(DSDEF(ppi)) ?
pp_next_delay_1(ppi,PP_TO_REQUEST) :
pp_next_delay_2(ppi,PP_TO_ANN_RECEIPT, PP_TO_REQUEST);
return ret;
}
......@@ -123,7 +123,7 @@ void pp_timeout_init(struct pp_instance *ppi)
{
portDS_t *port = ppi->portDS;
timeOutInstCnt_t *tmoCnt=ppi->tmo_cfg;
Boolean p2p=CONFIG_HAS_P2P && ppi->delayMechanism == P2P;
Boolean p2p=is_delayMechanismP2P(ppi);
Integer8 logDelayRequest=p2p ?
port->logMinPdelayReqInterval : port->logMinDelayReqInterval;
......@@ -135,12 +135,6 @@ void pp_timeout_init(struct pp_instance *ppi)
tmoCnt[PP_TO_ANN_SEND].which_rand=TO_RAND_70_130;
tmoCnt[PP_TO_REQUEST].initValueMs= pp_timeout_log_to_ms(logDelayRequest);
/* fault timeout is 4 avg request intervals, not randomized */
tmoCnt[PP_TO_FAULT].initValueMs = pp_timeout_log_to_ms(logDelayRequest);
if ( tmoCnt[PP_TO_FAULT].initValueMs < (TIMEOUT_MAX_VALUE_MS>>2))
tmoCnt[PP_TO_FAULT].initValueMs<<=2; /* We can multiply by 4. No risk of overload */
tmoCnt[PP_TO_SYNC_SEND].initValueMs = pp_timeout_log_to_ms(port->logSyncInterval);
// Initialize BMCA timer (Independent Timer)
......@@ -151,11 +145,23 @@ void pp_timeout_init(struct pp_instance *ppi)
if (gtmoCnt->initValueMs==TIMEOUT_DISABLE_VALUE || ms<gtmoCnt->initValueMs)
gtmoCnt->initValueMs=ms;
}
tmoCnt[PP_TO_ANN_RECEIPT].initValueMs = 1000 * (
port->announceReceiptTimeout << port->logAnnounceInterval);
/* Clause 17.6.5.3 : ExternalPortConfiguration enabled
* - The Announce receipt timeout mechanism (see 9.2.6.12) shall not be active.
*/
if ( is_externalPortConfigurationEnabled(DSDEF(ppi)) ) {
tmoCnt[PP_TO_ANN_RECEIPT].initValueMs =
tmoCnt[PP_TO_FAULT].initValueMs=
tmoCnt[PP_TO_QUALIFICATION].initValueMs =TIMEOUT_DISABLE_VALUE;
} else {
tmoCnt[PP_TO_ANN_RECEIPT].initValueMs=1000 * (port->announceReceiptTimeout << port->logAnnounceInterval);
/* fault timeout is 4 avg request intervals, not randomized */
tmoCnt[PP_TO_FAULT].initValueMs = pp_timeout_log_to_ms(logDelayRequest);
if ( tmoCnt[PP_TO_FAULT].initValueMs < (TIMEOUT_MAX_VALUE_MS>>2))
tmoCnt[PP_TO_FAULT].initValueMs<<=2; /* We can multiply by 4. No risk of overload */
tmoCnt[PP_TO_QUALIFICATION].initValueMs =
(1000 << port->logAnnounceInterval)*(DSCUR(ppi)->stepsRemoved + 1);
}
tmoCnt[PP_TO_ANN_SEND].initValueMs = pp_timeout_log_to_ms(port->logAnnounceInterval);
tmoCnt[PP_TO_QUALIFICATION].initValueMs =
(1000 << port->logAnnounceInterval)*(DSCUR(ppi)->stepsRemoved + 1);
}
int pp_timeout_get(struct pp_instance *ppi, int index) {
......
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