[Linuxptp-devel] [RFC PATCH v1 7/8] Implement the COMMON_P2P delay mechanism
PTP IEEE 1588 stack for Linux
Brought to you by:
rcochran
|
From: Kishen M. <kis...@in...> - 2023-03-20 02:37:23
|
From: Andrew Zaborowski <and...@in...>
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 <and...@in...>
---
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
|