From: Andrew Zaborowski <andrew.zaborow...@intel.com> This change implements the COMMON_P2P DM by issuing a request to the CMLDS for CommonMeanLinkDelayInformation upon expiry of the delay timer and handles the response to assimilate the received meanPathDelay and NRR.
Signed-off-by: Andrew Zaborowski <andrew.zaborow...@intel.com> --- pmc.c | 7 +++++-- port.c | 57 +++++++++++++++++++++++++++++++++++++++++++++----- port_private.h | 2 ++ tlv.c | 4 ++++ tlv.h | 2 ++ 5 files changed, 65 insertions(+), 7 deletions(-) diff --git a/pmc.c b/pmc.c index fbf312cb6c53..cac06fb5b41d 100644 --- a/pmc.c +++ b/pmc.c @@ -657,9 +657,12 @@ static void pmc_show(struct ptp_message *msg, FILE *fp) fprintf(fp, "CMLDS INFO " IFMT "serviceMeasurementValid %i" IFMT "meanLinkDelay %" PRId64 - IFMT "scaledNeighborRateRatio %" PRId32, + IFMT "scaledNeighborRateRatio %" PRId32 + IFMT "egress_ts %" PRId64 + IFMT "rx_ts %" PRId64, cmlds->serviceMeasurementValid, cmlds->meanLinkDelay, - cmlds->scaledNeighborRateRatio); + cmlds->scaledNeighborRateRatio, + cmlds->egress_ts, cmlds->rx_ts); break; } out: diff --git a/port.c b/port.c index 14d2b71d0d73..072ddffd9049 100644 --- a/port.c +++ b/port.c @@ -1198,13 +1198,23 @@ static int port_management_fill_response(struct port *target, break; case MID_CMLDS_INFO_NP: cmlds = (struct cmlds_info_np *)tlv->data; + /* IEEE1588-2019 16.6.3.2 h) 1) && nrate.ratio_valid because + * we have no extra field to convey that separately. + */ cmlds->serviceMeasurementValid = - /* IEEE1588-2019 16.6.3.2 h) 1) */ target->peer_portid_valid && !target->pdr_missing && - !target->multiple_pdr_detected; + !target->multiple_pdr_detected && + target->nrate.ratio_valid; cmlds->meanLinkDelay = target->peerMeanPathDelay; cmlds->scaledNeighborRateRatio = (Integer32) (target->nrate.ratio * POW2_41 - POW2_41); + /* 16.6.3.2: "Upon receipt of a request for information, the + * Common Mean Link Delay Service may in addition return the + * raw measurement data gathered by the service for use in + * estimating the <meanLinkDelay> and <neighborRateRatio>." + */ + cmlds->egress_ts = tmv_to_nanoseconds(target->peer_delay_t1); + cmlds->rx_ts = tmv_to_nanoseconds(target->peer_delay_t2); datalen = sizeof(*cmlds); /* Reflect the CMLDS sdoid/domainNumber/port id in * MID_CMLDS_INFO_NP responses @@ -1676,6 +1686,10 @@ int port_delay_request(struct port *p) { struct ptp_message *msg; + if (p->delayMechanism == DM_COMMON_P2P) { + return port_request_cmlds_info(p); + } + /* Time to send a new request, forget current pdelay resp and fup */ if (p->peer_delay_resp) { msg_put(p->peer_delay_resp); @@ -2594,6 +2608,9 @@ calc: p->nrate.ratio); } + p->peer_delay_t1 = t1; + p->peer_delay_t2 = t2; + msg_put(p->peer_delay_req); p->peer_delay_req = NULL; } @@ -3757,11 +3774,41 @@ int process_cmlds_response(struct port *p, pr_debug("CMLDS INFO\n" "\tserviceMeasurementValid %i\n" "\tmeanLinkDelay %" PRId64 "\n" - "\tscaledNeighborRateRatio %" PRId32, + "\tscaledNeighborRateRatio %" PRId32 "\n" + "\tegress_ts %" PRId64 "\n" + "\trx_ts %" PRId64, cmlds->serviceMeasurementValid, cmlds->meanLinkDelay, - cmlds->scaledNeighborRateRatio); + cmlds->scaledNeighborRateRatio, cmlds->egress_ts, + cmlds->rx_ts); - /* COMMON_P2P DM implementation goes here */ + if (!cmlds->serviceMeasurementValid) { + p->pdr_missing++; + p->peer_portid_valid = false; + p->nrate.ratio_valid = false; + return 0; + } + + /* Note: the CMLDS may be using a different local clock. Do not track + * the CMLDS-clock-to-local-clock rate ratio at this time as the + * difference should be small, or nul with vclocks. + */ + p->pdr_missing = 0; + p->peerMeanPathDelay = cmlds->meanLinkDelay; + p->peer_delay = nanoseconds_to_tmv(p->peerMeanPathDelay >> 16); + p->nrate.ratio = 1.0 + (double) cmlds->scaledNeighborRateRatio / POW2_41; + + /* Note: this determines the value of port_capable(p), however + * p->peer_portid itself is not actually used outside of the Pdelay FSM. + */ + p->peer_portid_valid = true; + p->nrate.ratio_valid = true; + + if (p->state == PS_UNCALIBRATED || p->state == PS_SLAVE) { + clock_peer_delay(p->clock, p->peer_delay, + nanoseconds_to_tmv(cmlds->egress_ts), + nanoseconds_to_tmv(cmlds->rx_ts), + p->nrate.ratio); + } return 0; } diff --git a/port_private.h b/port_private.h index 10ce05f3a895..664d14944919 100644 --- a/port_private.h +++ b/port_private.h @@ -99,6 +99,8 @@ struct port { unsigned int pdr_missing; unsigned int multiple_seq_pdr_count; unsigned int multiple_pdr_detected; + tmv_t peer_delay_t1; + tmv_t peer_delay_t2; enum port_state (*state_machine)(enum port_state state, enum fsm_event event, int mdiff); int bmca; diff --git a/tlv.c b/tlv.c index aefbcb9f744e..8b97d2cfc9f5 100644 --- a/tlv.c +++ b/tlv.c @@ -497,6 +497,8 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len, cmlds = (struct cmlds_info_np *)m->data; net2host64_unaligned(&cmlds->meanLinkDelay); NTOHL(cmlds->scaledNeighborRateRatio); + net2host64_unaligned(&cmlds->egress_ts); + net2host64_unaligned(&cmlds->rx_ts); break; } if (extra_len) { @@ -685,6 +687,8 @@ static void mgt_pre_send(struct management_tlv *m, struct tlv_extra *extra) cmlds = (struct cmlds_info_np *)m->data; host2net64_unaligned(&cmlds->meanLinkDelay); HTONL(cmlds->scaledNeighborRateRatio); + host2net64_unaligned(&cmlds->egress_ts); + host2net64_unaligned(&cmlds->rx_ts); break; } } diff --git a/tlv.h b/tlv.h index 73b6078e2efd..6446fc068488 100644 --- a/tlv.h +++ b/tlv.h @@ -480,6 +480,8 @@ struct cmlds_info_np { Integer8 serviceMeasurementValid; TimeInterval meanLinkDelay; Integer32 scaledNeighborRateRatio; + Integer64 egress_ts; + Integer64 rx_ts; } PACKED; /** -- 2.31.1 _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel