From: devasishsyncmonk <devasish....@syncmonk.net>

Delay asymmetry calculation based on the PTP port interface speed of
master obtained from TLV and the slave interface rate obtained by ethtool.

Signed-off-by: Greg Armstrong <greg.armstrong...@renesas.com>
Signed-off-by: Leon Goldin <leon.goldin...@renesas.com>
Signed-off-by: Devasish Dey <devasish....@syncmonk.net>
Signed-off-by: Vipin Sharma <vipin.sha...@syncmonk.net>
---
 interface.c       |  9 +++++++++
 interface.h       |  7 +++++++
 port_private.h    |  1 +
 port_signaling.c  | 32 ++++++++++++++++++++++++++++++++
 ptp4l.8           |  7 +++++++
 unicast_service.c | 35 +++++++++++++++++++++++++++++++++++
 6 files changed, 91 insertions(+)

diff --git a/interface.c b/interface.c
index 9c30499..6237e88 100644
--- a/interface.c
+++ b/interface.c
@@ -93,3 +93,12 @@ int interface_get_vclock(struct interface *iface)
 {
        return iface->vclock;
 }
+
+uint64_t interface_bitperiod(struct interface *iface)
+{
+       if (!iface->if_info.valid)
+               return 0;
+
+       /* Megabits per secon converted to attoseconds per bit. */
+       return 1000000000000ULL/ iface->if_info.speed;
+}
diff --git a/interface.h b/interface.h
index 5289a7f..e1dc0e8 100644
--- a/interface.h
+++ b/interface.h
@@ -113,4 +113,11 @@ void interface_set_vclock(struct interface *iface, int 
vclock);
  */
 int interface_get_vclock(struct interface *iface);
 
+/**
+ * Obtains the interface bit period based on the speed.
+ * @param iface  The interface of interest.
+ * @return       if valid speed return interface bitperiod in atto seconds.
+ */
+uint64_t interface_bitperiod(struct interface *iface);
+
 #endif
diff --git a/port_private.h b/port_private.h
index d27dceb..d1a1e76 100644
--- a/port_private.h
+++ b/port_private.h
@@ -145,6 +145,7 @@ struct port {
        UInteger8           versionNumber; /* UInteger4 */
        UInteger8           delay_response_counter;
        UInteger8           delay_response_timeout;
+       Integer64           portAsymmetry;
        struct PortStats    stats;
        struct PortServiceStats    service_stats;
        /* foreignMasterDS */
diff --git a/port_signaling.c b/port_signaling.c
index ed217c0..d78acb6 100644
--- a/port_signaling.c
+++ b/port_signaling.c
@@ -103,10 +103,38 @@ static int process_interval_request(struct port *p,
        return 0;
 }
 
+static int process_interface_rate(struct port *p,
+                                 struct msg_interface_rate_tlv *r)
+{
+       Integer64 delayAsymmetry;
+       double    nsDelay;
+       Integer64 slaveBitPeriod;
+       Integer64 masterBitPeriod;
+
+       if (clock_interface_rate_tlv (p->clock) &&
+                       interface_ifinfo_valid(p->iface)) {
+               slaveBitPeriod = interface_bitperiod(p->iface);
+               masterBitPeriod = r->interfaceBitPeriod;
+
+               /* Delay Asymmetry Calculation */
+               nsDelay = (masterBitPeriod - slaveBitPeriod) / (2 * 1.0e9);
+               delayAsymmetry =
+                       (r->numberOfBitsAfterTimestamp - 
r->numberOfBitsBeforeTimestamp)  * nsDelay;
+
+               if (delayAsymmetry != p->portAsymmetry) {
+                       p->asymmetry += ((delayAsymmetry - p->portAsymmetry) << 
16);
+                       p->portAsymmetry = delayAsymmetry;
+               }
+       }
+       return 0;
+}
+
+
 int process_signaling(struct port *p, struct ptp_message *m)
 {
        struct tlv_extra *extra;
        struct msg_interval_req_tlv *r;
+       struct msg_interface_rate_tlv *rate;
        int err = 0, result;
 
        switch (p->state) {
@@ -161,10 +189,14 @@ int process_signaling(struct port *p, struct ptp_message 
*m)
 
                case TLV_ORGANIZATION_EXTENSION:
                        r = (struct msg_interval_req_tlv *) extra->tlv;
+                       rate = (struct msg_interface_rate_tlv *) extra->tlv;
 
                        if (0 == memcmp(r->id, ieee8021_id, 
sizeof(ieee8021_id)) &&
                            r->subtype[0] == 0 && r->subtype[1] == 0 && 
r->subtype[2] == 2)
                                err = process_interval_request(p, r);
+                       else if (0 == memcmp(r->id, itu_t_id, sizeof(itu_t_id)) 
&&
+                               r->subtype[0] == 0 && r->subtype[1] == 0 && 
r->subtype[2] == 2)
+                               err = process_interface_rate(p, rate);
                        break;
                }
        }
diff --git a/ptp4l.8 b/ptp4l.8
index 1268802..eab4b47 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -695,6 +695,13 @@ The default is 0 (disabled).
 Print messages to the system log if enabled.
 The default is 1 (enabled).
 .TP
+.B interface_rate_tlv
+When the client and server are operating are operating at different interface 
rate,
+delay asymmetry caused due to different interface rate needs to be compensated.
+The server sends its interface rate using interface rate TLV
+as per G.8275.2 Annex D.
+The default is 0 (does not support interface rate tlv).
+
 .B summary_interval
 The time interval in which are printed summary statistics of the clock. It is
 specified as a power of two in seconds. The statistics include offset root mean
diff --git a/unicast_service.c b/unicast_service.c
index 3154894..959caee 100644
--- a/unicast_service.c
+++ b/unicast_service.c
@@ -84,6 +84,32 @@ static int attach_grant(struct ptp_message *msg,
        return 0;
 }
 
+static int attach_interface_rate(struct ptp_message *msg,
+                                uint64_t iface_bit_period,
+                                uint16_t  no_of_bits_before_ts,
+                                uint16_t  no_of_bits_after_ts)
+{
+       struct msg_interface_rate_tlv *mir;
+       struct tlv_extra *extra;
+
+       extra = msg_tlv_append(msg, sizeof(*mir));
+       if (!extra) {
+               return -1;
+       }
+       mir = (struct msg_interface_rate_tlv *) extra->tlv;
+       mir->type = TLV_ORGANIZATION_EXTENSION;
+       mir->length = sizeof(*mir) - sizeof(mir->type) - sizeof(mir->length);
+       memcpy(mir->id, itu_t_id, sizeof(itu_t_id));
+       mir->subtype[2] = 2;
+       mir->interfaceBitPeriod = iface_bit_period;
+       mir->numberOfBitsBeforeTimestamp = no_of_bits_before_ts;
+       mir->numberOfBitsAfterTimestamp = no_of_bits_after_ts;
+
+       return 0;
+}
+
+
+
 static int compare_timeout(void *ain, void *bin)
 {
        struct unicast_service_interval *a, *b;
@@ -256,6 +282,15 @@ static int unicast_service_reply(struct port *p, struct 
ptp_message *dst,
        if (err) {
                goto out;
        }
+       if (clock_interface_rate_tlv (p->clock) &&
+           duration > 0 && interface_ifinfo_valid(p->iface)) {
+               err = attach_interface_rate(msg,
+                               interface_bitperiod(p->iface), 64, 720);
+               if (err) {
+                       goto out;
+               }
+       }
+
        err = port_prepare_and_send(p, msg, TRANS_GENERAL);
        if (err) {
                pr_err("%s: signaling message failed", p->log_name);
-- 
2.34.1



_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to