In a setup with multiple gPTP domains, the Common Mean Link Delay Service (CMLDS) (IEEE 1588/16.6.3) performs link delay measurements in a single domain and must (somehow) convey those to other domains. IEEE 1588 does not specify this interface and flags it as an implementation detail (IEEE 1588/16.6.1). Accordningly, this change introduces a new TLV to convey link delay measurements by the CMLDS over the management interface.
In addition to the parameters suggested in IEEE 1588/16.6.3.2, the TLV also conveys the latest 'up measurements' (req and rx timestamps) recorded in the CMLDS. These values collectively aid other gPTP domains to complete their delay/offset computations via the COMMON_P2P delay mechanism. Updated 'pmc' to support the new MID, MID_CMLDS_INFO_NP. Co-authored-by: Andrew Zaborowski <andrew.zaborow...@intel.com> Signed-off-by: Kishen Maloor <kishen.mal...@intel.com> --- clock.c | 1 - msg.h | 2 ++ pmc.c | 13 +++++++++++++ pmc_common.c | 1 + port.c | 22 ++++++++++++++++++++++ port_private.h | 2 ++ tlv.c | 18 ++++++++++++++++++ tlv.h | 11 +++++++++++ 8 files changed, 69 insertions(+), 1 deletion(-) diff --git a/clock.c b/clock.c index fe08d48ed8f8..c74a6baa9f61 100644 --- a/clock.c +++ b/clock.c @@ -47,7 +47,6 @@ #include "util.h" #define N_CLOCK_PFD (N_POLLFD + 1) /* one extra per port, for the fault timer */ -#define POW2_41 ((double)(1ULL << 41)) struct interface { STAILQ_ENTRY(interface) list; diff --git a/msg.h b/msg.h index cbd09e75a2aa..db12e249f89f 100644 --- a/msg.h +++ b/msg.h @@ -69,6 +69,8 @@ #define SIGNAL_NO_CHANGE -128 #define SIGNAL_SET_INITIAL 126 +#define POW2_41 ((double)(1ULL << 41)) + enum timestamp_type { TS_SOFTWARE, TS_HARDWARE, diff --git a/pmc.c b/pmc.c index 00e691f0c244..cac06fb5b41d 100644 --- a/pmc.c +++ b/pmc.c @@ -169,6 +169,7 @@ static void pmc_show(struct ptp_message *msg, FILE *fp) struct subscribe_events_np *sen; struct port_properties_np *ppn; struct port_hwclock_np *phn; + struct cmlds_info_np *cmlds; struct timePropertiesDS *tp; struct management_tlv *mgt; struct time_status_np *tsn; @@ -651,6 +652,18 @@ static void pmc_show(struct ptp_message *msg, FILE *fp) fprintf(fp, "LOG_MIN_PDELAY_REQ_INTERVAL " IFMT "logMinPdelayReqInterval %hhd", mtd->val); break; + case MID_CMLDS_INFO_NP: + cmlds = (struct cmlds_info_np *) mgt->data; + fprintf(fp, "CMLDS INFO " + IFMT "serviceMeasurementValid %i" + IFMT "meanLinkDelay %" PRId64 + IFMT "scaledNeighborRateRatio %" PRId32 + IFMT "egress_ts %" PRId64 + IFMT "rx_ts %" PRId64, + cmlds->serviceMeasurementValid, cmlds->meanLinkDelay, + cmlds->scaledNeighborRateRatio, + cmlds->egress_ts, cmlds->rx_ts); + break; } out: fprintf(fp, "\n"); diff --git a/pmc_common.c b/pmc_common.c index 9e251c43e95b..d7a6114dcd62 100644 --- a/pmc_common.c +++ b/pmc_common.c @@ -156,6 +156,7 @@ struct management_id idtab[] = { { "UNICAST_MASTER_TABLE_NP", MID_UNICAST_MASTER_TABLE_NP, do_get_action }, { "PORT_HWCLOCK_NP", MID_PORT_HWCLOCK_NP, do_get_action }, { "POWER_PROFILE_SETTINGS_NP", MID_POWER_PROFILE_SETTINGS_NP, do_set_action }, + { "CMLDS_INFO_NP", MID_CMLDS_INFO_NP, do_get_action }, }; static void do_get_action(struct pmc *pmc, int action, int index, char *str) diff --git a/port.c b/port.c index 8b2eb04a855a..d467a69e519a 100644 --- a/port.c +++ b/port.c @@ -887,6 +887,7 @@ static int port_management_fill_response(struct port *target, struct clock_description *desc; struct port_properties_np *ppn; struct port_hwclock_np *phn; + struct cmlds_info_np *cmlds; struct management_tlv *tlv; struct port_stats_np *psn; struct foreign_clock *fc; @@ -1129,6 +1130,27 @@ static int port_management_fill_response(struct port *target, memcpy(pwr, &target->pwr, sizeof(*pwr)); datalen = sizeof(*pwr); 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 = + target->peer_portid_valid && !target->pdr_missing && + !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); + break; default: /* The caller should *not* respond to this message. */ tlv_extra_recycle(extra); diff --git a/port_private.h b/port_private.h index 3b02d2fe45c4..c9b02bc799f5 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 79400126cbc4..8b97d2cfc9f5 100644 --- a/tlv.c +++ b/tlv.c @@ -176,6 +176,7 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len, struct port_properties_np *ppn; struct port_hwclock_np *phn; struct timePropertiesDS *tp; + struct cmlds_info_np *cmlds; struct time_status_np *tsn; struct port_stats_np *psn; int extra_len = 0, i, len; @@ -490,6 +491,15 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len, if (data_len != 0) goto bad_length; break; + case MID_CMLDS_INFO_NP: + if (data_len < sizeof(struct cmlds_info_np)) + goto bad_length; + 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) { if (extra_len % 2) @@ -514,6 +524,7 @@ static void mgt_pre_send(struct management_tlv *m, struct tlv_extra *extra) struct subscribe_events_np *sen; struct port_properties_np *ppn; struct port_hwclock_np *phn; + struct cmlds_info_np *cmlds; struct timePropertiesDS *tp; struct time_status_np *tsn; struct port_stats_np *psn; @@ -672,6 +683,13 @@ static void mgt_pre_send(struct management_tlv *m, struct tlv_extra *extra) HTONL(pwr->networkTimeInaccuracy); HTONL(pwr->totalTimeInaccuracy); break; + case MID_CMLDS_INFO_NP: + 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 8b51ffd88816..6446fc068488 100644 --- a/tlv.h +++ b/tlv.h @@ -130,6 +130,9 @@ enum management_action { #define MID_PORT_HWCLOCK_NP 0xC009 #define MID_POWER_PROFILE_SETTINGS_NP 0xC00A +/* CMLDS management ID values */ +#define MID_CMLDS_INFO_NP 0xC00B + /* Management error ID values */ #define MID_RESPONSE_TOO_BIG 0x0001 #define MID_NO_SUCH_ID 0x0002 @@ -473,6 +476,14 @@ struct msg_interface_rate_tlv { UInteger16 numberOfBitsAfterTimestamp; } PACKED; +struct cmlds_info_np { + Integer8 serviceMeasurementValid; + TimeInterval meanLinkDelay; + Integer32 scaledNeighborRateRatio; + Integer64 egress_ts; + Integer64 rx_ts; +} PACKED; + /** * Allocates a new tlv_extra structure. * @return Pointer to a new structure on success or NULL otherwise. -- 2.31.1 _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel