Add converters between hardware timestamps and the internal
representation, and remove code that directly manipulates the timespec
within a hardware timestamp.

This is a prerequisite for the use of hardware timestamps with
sub-nanosecond granularity.

Signed-off-by: Michael Brown <[email protected]>
---
 clock.c |  6 ++----
 clock.h |  2 +-
 msg.h   |  1 +
 port.c  | 69 ++++++++++++++++++++++++-----------------------------------------
 tmv.c   | 21 ++++++++++++++++++++
 tmv.h   |  5 +++++
 6 files changed, 55 insertions(+), 49 deletions(-)

diff --git a/clock.c b/clock.c
index 92adea8..f1f1f39 100644
--- a/clock.c
+++ b/clock.c
@@ -1764,11 +1764,9 @@ enum clock_type clock_type(struct clock *c)
        return c->type;
 }
 
-void clock_check_ts(struct clock *c, struct timespec ts)
+void clock_check_ts(struct clock *c, uint64_t ts)
 {
-       if (c->sanity_check &&
-           clockcheck_sample(c->sanity_check,
-                             ts.tv_sec * NS_PER_SEC + ts.tv_nsec)) {
+       if (c->sanity_check && clockcheck_sample(c->sanity_check, ts)) {
                servo_reset(c->servo);
        }
 }
diff --git a/clock.h b/clock.h
index 986d363..72d8a7a 100644
--- a/clock.h
+++ b/clock.h
@@ -302,7 +302,7 @@ enum clock_type clock_type(struct clock *c);
  * @param c  The clock instance.
  * @param ts The time stamp.
  */
-void clock_check_ts(struct clock *c, struct timespec ts);
+void clock_check_ts(struct clock *c, uint64_t ts);
 
 /**
  * Obtain ratio between master's frequency and current clock frequency.
diff --git a/msg.h b/msg.h
index 12e6ce8..ce8094a 100644
--- a/msg.h
+++ b/msg.h
@@ -66,6 +66,7 @@ struct hw_timestamp {
        enum timestamp_type type;
        struct timespec ts;
        struct timespec sw;
+       int latency;
 };
 
 enum controlField {
diff --git a/port.c b/port.c
index ee09b5c..1c562fb 100644
--- a/port.c
+++ b/port.c
@@ -352,29 +352,6 @@ static void fc_prune(struct foreign_clock *fc)
        }
 }
 
-static void ts_add(struct timespec *ts, int ns)
-{
-       if (!ns) {
-               return;
-       }
-       ts->tv_nsec += ns;
-       while (ts->tv_nsec < 0) {
-               ts->tv_nsec += (long) NS_PER_SEC;
-               ts->tv_sec--;
-       }
-       while (ts->tv_nsec >= (long) NS_PER_SEC) {
-               ts->tv_nsec -= (long) NS_PER_SEC;
-               ts->tv_sec++;
-       }
-}
-
-static void ts_to_timestamp(struct timespec *src, struct Timestamp *dst)
-{
-       dst->seconds_lsb = src->tv_sec;
-       dst->seconds_msb = 0;
-       dst->nanoseconds = src->tv_nsec;
-}
-
 /*
  * Returns non-zero if the announce message is different than last.
  */
@@ -470,14 +447,14 @@ static void free_foreign_masters(struct port *p)
 
 static int fup_sync_ok(struct ptp_message *fup, struct ptp_message *sync)
 {
-       int64_t tfup, tsync;
-       tfup = tmv_to_nanoseconds(timespec_to_tmv(fup->hwts.sw));
-       tsync = tmv_to_nanoseconds(timespec_to_tmv(sync->hwts.sw));
+       tmv_t tfup, tsync;
+       tfup = hwts_sw_to_tmv(&fup->hwts);
+       tsync = hwts_sw_to_tmv(&sync->hwts);
        /*
         * NB - If the sk_check_fupsync option is not enabled, then
         * both of these time stamps will be zero.
         */
-       if (tfup < tsync) {
+       if (tmv_cmp(tfup, tsync) < 0) {
                return 0;
        }
        return 1;
@@ -552,7 +529,7 @@ static int peer_prepare_and_send(struct port *p, struct 
ptp_message *msg,
                return -1;
        }
        if (msg_sots_valid(msg)) {
-               ts_add(&msg->hwts.ts, p->tx_timestamp_offset);
+               msg->hwts.latency = p->tx_timestamp_offset;
        }
        return 0;
 }
@@ -1037,7 +1014,7 @@ static void port_slave_priority_warning(struct port *p)
 }
 
 static void port_synchronize(struct port *p,
-                            struct timespec ingress_ts,
+                            const struct hw_timestamp *ingress_ts,
                             struct timestamp origin_ts,
                             Integer64 correction1, Integer64 correction2)
 {
@@ -1047,7 +1024,7 @@ static void port_synchronize(struct port *p,
        port_set_sync_rx_tmo(p);
 
        t1 = timestamp_to_tmv(origin_ts);
-       t2 = timespec_to_tmv(ingress_ts);
+       t2 = hwts_to_tmv(ingress_ts);
        c1 = correction_to_tmv(correction1);
        c2 = correction_to_tmv(correction2);
        t1c = tmv_add(t1, tmv_add(c1, c2));
@@ -1122,7 +1099,7 @@ static void port_syfufsm(struct port *p, enum syfu_event 
event,
                        break;
                case FUP_MATCH:
                        syn = p->last_syncfup;
-                       port_synchronize(p, syn->hwts.ts, m->ts.pdu,
+                       port_synchronize(p, &syn->hwts, m->ts.pdu,
                                         syn->header.correction,
                                         m->header.correction);
                        msg_put(p->last_syncfup);
@@ -1141,7 +1118,7 @@ static void port_syfufsm(struct port *p, enum syfu_event 
event,
                        break;
                case SYNC_MATCH:
                        fup = p->last_syncfup;
-                       port_synchronize(p, m->hwts.ts, fup->ts.pdu,
+                       port_synchronize(p, &m->hwts, fup->ts.pdu,
                                         m->header.correction,
                                         fup->header.correction);
                        msg_put(p->last_syncfup);
@@ -1380,7 +1357,8 @@ static int port_tx_sync(struct port *p)
        fup->header.control            = CTL_FOLLOW_UP;
        fup->header.logMessageInterval = p->logSyncInterval;
 
-       ts_to_timestamp(&msg->hwts.ts, &fup->follow_up.preciseOriginTimestamp);
+       tmv_to_Timestamp(hwts_to_tmv(&msg->hwts),
+                        &fup->follow_up.preciseOriginTimestamp);
 
        err = port_prepare_and_send(p, fup, 0);
        if (err)
@@ -1661,7 +1639,8 @@ static int process_delay_req(struct port *p, struct 
ptp_message *m)
        msg->header.control            = CTL_DELAY_RESP;
        msg->header.logMessageInterval = p->logMinDelayReqInterval;
 
-       ts_to_timestamp(&m->hwts.ts, &msg->delay_resp.receiveTimestamp);
+       tmv_to_Timestamp(hwts_to_tmv(&m->hwts),
+                        &msg->delay_resp.receiveTimestamp);
 
        msg->delay_resp.requestingPortIdentity = m->header.sourcePortIdentity;
 
@@ -1701,7 +1680,7 @@ static void process_delay_resp(struct port *p, struct 
ptp_message *m)
                return;
 
        c3 = correction_to_tmv(m->header.correction);
-       t3 = timespec_to_tmv(p->delay_req->hwts.ts);
+       t3 = hwts_to_tmv(&p->delay_req->hwts);
        t4 = timestamp_to_tmv(m->ts.pdu);
        t4c = tmv_sub(t4, c3);
 
@@ -1823,7 +1802,8 @@ static int process_pdelay_req(struct port *p, struct 
ptp_message *m)
         * NB - We do not have any fraction nanoseconds for the correction
         * fields, neither in the response or the follow up.
         */
-       ts_to_timestamp(&m->hwts.ts, &rsp->pdelay_resp.requestReceiptTimestamp);
+       tmv_to_Timestamp(hwts_to_tmv(&m->hwts),
+                        &rsp->pdelay_resp.requestReceiptTimestamp);
        rsp->pdelay_resp.requestingPortIdentity = m->header.sourcePortIdentity;
 
        fup->hwts.type = p->timestamping;
@@ -1850,8 +1830,8 @@ static int process_pdelay_req(struct port *p, struct 
ptp_message *m)
                goto out;
        }
 
-       ts_to_timestamp(&rsp->hwts.ts,
-                       &fup->pdelay_resp_fup.responseOriginTimestamp);
+       tmv_to_Timestamp(hwts_to_tmv(&rsp->hwts),
+                        &fup->pdelay_resp_fup.responseOriginTimestamp);
 
        err = peer_prepare_and_send(p, fup, 0);
        if (err)
@@ -1881,8 +1861,8 @@ static void port_peer_delay(struct port *p)
        if (rsp->header.sequenceId != ntohs(req->header.sequenceId))
                return;
 
-       t1 = timespec_to_tmv(req->hwts.ts);
-       t4 = timespec_to_tmv(rsp->hwts.ts);
+       t1 = hwts_to_tmv(&req->hwts);
+       t4 = hwts_to_tmv(&rsp->hwts);
        c1 = correction_to_tmv(rsp->header.correction + p->asymmetry);
 
        /* Process one-step response immediately. */
@@ -2023,7 +2003,7 @@ static void process_sync(struct port *p, struct 
ptp_message *m)
        m->header.correction += p->asymmetry;
 
        if (one_step(m)) {
-               port_synchronize(p, m->hwts.ts, m->ts.pdu,
+               port_synchronize(p, &m->hwts, m->ts.pdu,
                                 m->header.correction, 0);
                flush_last_sync(p);
                return;
@@ -2366,8 +2346,9 @@ enum fsm_event port_event(struct port *p, int fd_index)
                return EV_NONE;
        }
        if (msg_sots_valid(msg)) {
-               ts_add(&msg->hwts.ts, -p->rx_timestamp_offset);
-               clock_check_ts(p->clock, msg->hwts.ts);
+               msg->hwts.latency = -p->rx_timestamp_offset;
+               clock_check_ts(p->clock,
+                              tmv_to_nanoseconds(hwts_to_tmv(&msg->hwts)));
        }
        if (port_ignore(p, msg)) {
                msg_put(msg);
@@ -2444,7 +2425,7 @@ int port_prepare_and_send(struct port *p, struct 
ptp_message *msg, int event)
                return -1;
        }
        if (msg_sots_valid(msg)) {
-               ts_add(&msg->hwts.ts, p->tx_timestamp_offset);
+               msg->hwts.latency = p->tx_timestamp_offset;
        }
        return 0;
 }
diff --git a/tmv.c b/tmv.c
index f2d36a3..eb2f7f1 100644
--- a/tmv.c
+++ b/tmv.c
@@ -22,6 +22,7 @@
 
 #include "ddt.h"
 #include "pdt.h"
+#include "msg.h"
 #include "tmv.h"
 
 #define NS_FRAC 0x10000
@@ -114,6 +115,14 @@ int64_t tmv_to_nanoseconds(tmv_t x)
        return x.ns;
 }
 
+void tmv_to_Timestamp(tmv_t x, struct Timestamp *ts)
+{
+       uint64_t seconds = x.ns / NS_PER_SEC;
+       ts->seconds_lsb = seconds;
+       ts->seconds_msb = (seconds >> 32);
+       ts->nanoseconds = (x.ns % NS_PER_SEC);
+}
+
 TimeInterval tmv_to_TimeInterval(tmv_t x)
 {
        return x.ns * NS_FRAC + x.frac;
@@ -134,3 +143,15 @@ tmv_t timestamp_to_tmv(struct timestamp ts)
        t.frac = 0;
        return t;
 }
+
+tmv_t hwts_to_tmv(const struct hw_timestamp *hwts)
+{
+       tmv_t t = timespec_to_tmv(hwts->ts);
+       t.ns += hwts->latency;
+       return t;
+}
+
+tmv_t hwts_sw_to_tmv(const struct hw_timestamp *hwts)
+{
+       return timespec_to_tmv(hwts->sw);
+}
diff --git a/tmv.h b/tmv.h
index 425a35e..d2a11b6 100644
--- a/tmv.h
+++ b/tmv.h
@@ -27,6 +27,8 @@
 
 #define NS_PER_SEC 1000000000LL
 
+struct hw_timestamp;
+
 /**
  * We implement the time value as a 64 bit signed integer containing
  * integer nanoseconds and a 32 bit signed integer containing
@@ -50,8 +52,11 @@ extern tmv_t correction_to_tmv(Integer64 c);
 extern double tmv_dbl(tmv_t x);
 extern tmv_t dbl_tmv(double x);
 extern int64_t tmv_to_nanoseconds(tmv_t x);
+extern void tmv_to_Timestamp(tmv_t x, struct Timestamp *ts);
 extern TimeInterval tmv_to_TimeInterval(tmv_t x);
 extern tmv_t timespec_to_tmv(struct timespec ts);
 extern tmv_t timestamp_to_tmv(struct timestamp ts);
+extern tmv_t hwts_to_tmv(const struct hw_timestamp *hwts);
+extern tmv_t hwts_sw_to_tmv(const struct hw_timestamp *hwts);
 
 #endif
-- 
2.9.5


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Linuxptp-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to