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