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

Reply via email to