[Linuxptp-devel] [PATCH RFC] Introduce an option to ignore the transport specific field.

2018-02-28 Thread Richard Cochran
Up until now the transportSpecific field has been treated according to
802.1AS, namely as a field that must match exactly on receive.
However, 1588 mandates ignoring this field for some transports, and
there is equipment in the wild that does in fact set the reserved
bits.

This patch adds an option to ignore the field on receive completely.

Signed-off-by: Richard Cochran 
Reported-by: Petr Kulhavy 
---
 config.c | 1 +
 port.c   | 5 -
 ptp4l.8  | 8 
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/config.c b/config.c
index 56d1556..86ea354 100644
--- a/config.c
+++ b/config.c
@@ -192,6 +192,7 @@ struct config_item config_tab[] = {
PORT_ITEM_INT("freq_est_interval", 1, 0, INT_MAX),
GLOB_ITEM_INT("gmCapable", 1, 0, 1),
PORT_ITEM_INT("hybrid_e2e", 0, 0, 1),
+   PORT_ITEM_INT("ignore_transport_specific", 0, 0, 1),
PORT_ITEM_INT("ingressLatency", 0, INT_MIN, INT_MAX),
GLOB_ITEM_INT("initial_delay", 0, 0, INT_MAX),
GLOB_ITEM_INT("kernel_leap", 1, 0, 1),
diff --git a/port.c b/port.c
index 6cc5dd0..c69363c 100644
--- a/port.c
+++ b/port.c
@@ -125,6 +125,7 @@ struct port {
int follow_up_info;
int freq_est_interval;
int hybrid_e2e;
+   int match_transport_specific;
int min_neighbor_prop_delay;
int path_trace_enabled;
int rx_timestamp_offset;
@@ -641,7 +642,8 @@ static int port_ignore(struct port *p, struct ptp_message 
*m)
if (path_trace_ignore(p, m)) {
return 1;
}
-   if (msg_transport_specific(m) != p->transportSpecific) {
+   if (p->match_transport_specific &&
+   msg_transport_specific(m) != p->transportSpecific) {
return 1;
}
if (pid_eq(>header.sourcePortIdentity, >portIdentity)) {
@@ -1489,6 +1491,7 @@ static int port_initialize(struct port *p)
p->syncReceiptTimeout  = config_get_int(cfg, p->name, 
"syncReceiptTimeout");
p->transportSpecific   = config_get_int(cfg, p->name, 
"transportSpecific");
p->transportSpecific <<= 4;
+   p->match_transport_specific = !config_get_int(cfg, p->name, 
"ignore_transport_specific");
p->logSyncInterval = config_get_int(cfg, p->name, 
"logSyncInterval");
p->logMinPdelayReqInterval = config_get_int(cfg, p->name, 
"logMinPdelayReqInterval");
p->neighborPropDelayThresh = config_get_int(cfg, p->name, 
"neighborPropDelayThresh");
diff --git a/ptp4l.8 b/ptp4l.8
index 4cf0b0c..9a7701d 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -176,6 +176,14 @@ The default is 0 or disabled.
 The transport specific field. Must be in the range 0 to 255.
 The default is 0.
 .TP
+.B ignore_transport_specific
+By default, incoming messages are dropped if their transportSpecific
+field does not match the configured value.  However, many of
+transports specified in the 1588 standard mandate ignoring this field.
+Moreover, some equipment is known to set the reserved bits.
+Configuring this option as 1 causes this field to be ignored
+completely on receive.  The default is 0.
+.TP
 .B path_trace_enabled
 Enable the mechanism used to trace the route of the Announce messages.
 The default is 0 (disabled).
-- 
2.11.0


--
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
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] [PATCH 00/13] Prepare for sub-nanosecond timestamps

2018-02-28 Thread Richard Cochran
On Thu, Mar 01, 2018 at 01:21:35AM +, Michael Brown wrote:
> The following series of patches adds support required for
> sub-nanosecond timestamps in ptp4l.  The kernel-to-userspace API data
> structures for reporting such timestamps are not yet defined, but this
> code is verified to achieve sub-nanosecond synchronisation over IPv6
> (6LoWPAN) using a DecaWave DW1000 UWB radio transceiver with one
> temporary hack (not included in this series) to allow the kernel
> driver to report timestamps with ~16ps granularity.

At first glance this series looks good.  I expect to merge the first
half or so, because we really do want the tmv_t operations to be used
consistently.

Regarding changing the implementation, I think we'll want to hold off
on that until kernel support for high resolution time stamps becomes
available.  Merging this bit right away makes the computations slower
and benefits very few users!
 
> I have tried to structure the patches to maximise ease of code review.

Yes, well done.  I appreciate that.

Thanks,
Richard

PS  We'll see whether my reply makes it to the list or not...

--
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
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 13/13] servo: Include fractional nanoseconds within clock offset

2018-02-28 Thread Michael Brown
Pass the clock offset to servo_sample() as a floating point value,
allowing the servo to take fractional nanoseconds into account.

Note that a floating point value can sensibly hold a clock offset, but
cannot sensibly hold an absolute time due to its limited range.
Servos that perform calculations on absolute times therefore cannot
make use of fractional nanoseconds.  At present, only the PI servo is
structured in a way that allows fractional nanoseconds to be used.

Signed-off-by: Michael Brown 
---
 clock.c | 2 +-
 linreg.c| 3 ++-
 ntpshm.c| 3 ++-
 nullf.c | 2 +-
 pi.c| 4 ++--
 servo.c | 2 +-
 servo.h | 2 +-
 servo_private.h | 2 +-
 8 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/clock.c b/clock.c
index d72efb2..121d9fb 100644
--- a/clock.c
+++ b/clock.c
@@ -1606,7 +1606,7 @@ enum servo_state clock_synchronize(struct clock *c, tmv_t 
ingress, tmv_t origin)
if (c->free_running)
return clock_no_adjust(c, ingress, origin);
 
-   adj = servo_sample(c->servo, tmv_to_nanoseconds(c->master_offset),
+   adj = servo_sample(c->servo, tmv_dbl(c->master_offset),
   tmv_to_nanoseconds(ingress), weight, );
c->servo_state = state;
 
diff --git a/linreg.c b/linreg.c
index 8f354f4..163f573 100644
--- a/linreg.c
+++ b/linreg.c
@@ -214,7 +214,7 @@ static void update_size(struct linreg_servo *s)
 }
 
 static double linreg_sample(struct servo *servo,
-   int64_t offset,
+   double xoffset,
uint64_t local_ts,
double weight,
enum servo_state *state)
@@ -222,6 +222,7 @@ static double linreg_sample(struct servo *servo,
struct linreg_servo *s = container_of(servo, struct linreg_servo, 
servo);
struct result *res;
int corr_interval;
+   int64_t offset = (int64_t) xoffset;
 
/*
 * The current time and the time when will be the frequency of the
diff --git a/ntpshm.c b/ntpshm.c
index 3b62a3f..53f8a6e 100644
--- a/ntpshm.c
+++ b/ntpshm.c
@@ -74,12 +74,13 @@ static void ntpshm_destroy(struct servo *servo)
 }
 
 static double ntpshm_sample(struct servo *servo,
-   int64_t offset,
+   double xoffset,
uint64_t local_ts,
double weight,
enum servo_state *state)
 {
struct ntpshm_servo *s = container_of(servo, struct ntpshm_servo, 
servo);
+   int64_t offset = (int64_t) xoffset;
uint64_t clock_ts = local_ts - offset;
 
s->shm->mode = 1;
diff --git a/nullf.c b/nullf.c
index 5512837..f934459 100644
--- a/nullf.c
+++ b/nullf.c
@@ -34,7 +34,7 @@ static void nullf_destroy(struct servo *servo)
free(s);
 }
 
-static double nullf_sample(struct servo *servo, int64_t offset,
+static double nullf_sample(struct servo *servo, double offset,
   uint64_t local_ts, double weight,
   enum servo_state *state)
 {
diff --git a/pi.c b/pi.c
index 35556e1..831a2dc 100644
--- a/pi.c
+++ b/pi.c
@@ -37,7 +37,7 @@
 
 struct pi_servo {
struct servo servo;
-   int64_t offset[2];
+   double offset[2];
uint64_t local[2];
double drift;
double kp;
@@ -62,7 +62,7 @@ static void pi_destroy(struct servo *servo)
 }
 
 static double pi_sample(struct servo *servo,
-   int64_t offset,
+   double offset,
uint64_t local_ts,
double weight,
enum servo_state *state)
diff --git a/servo.c b/servo.c
index 8be4b92..2912608 100644
--- a/servo.c
+++ b/servo.c
@@ -89,7 +89,7 @@ void servo_destroy(struct servo *servo)
 }
 
 double servo_sample(struct servo *servo,
-   int64_t offset,
+   double offset,
uint64_t local_ts,
double weight,
enum servo_state *state)
diff --git a/servo.h b/servo.h
index f90befd..236afb5 100644
--- a/servo.h
+++ b/servo.h
@@ -90,7 +90,7 @@ void servo_destroy(struct servo *servo);
  * @return The clock adjustment in parts per billion.
  */
 double servo_sample(struct servo *servo,
-   int64_t offset,
+   double offset,
uint64_t local_ts,
double weight,
enum servo_state *state);
diff --git a/servo_private.h b/servo_private.h
index b8c3c98..3787f80 100644
--- a/servo_private.h
+++ b/servo_private.h
@@ -30,7 +30,7 @@ struct servo {
void (*destroy)(struct servo *servo);
 
double (*sample)(struct servo *servo,
-int64_t offset, uint64_t local_ts, double weight,
+double offset, uint64_t local_ts, double weight,
 

[Linuxptp-devel] [PATCH 11/13] clock: Print statistics as floating point values

2018-02-28 Thread Michael Brown
Signed-off-by: Michael Brown 
---
 clock.c | 24 +++-
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/clock.c b/clock.c
index c887a11..d72efb2 100644
--- a/clock.c
+++ b/clock.c
@@ -545,15 +545,15 @@ static void clock_stats_update(struct clock_stats *s,
 
/* Path delay stats are updated separately, they may be empty. */
if (!stats_get_result(s->delay, _stats)) {
-   pr_info("rms %4.0f max %4.0f "
-   "freq %+6.0f +/- %3.0f "
-   "delay %5.0f +/- %3.0f",
+   pr_info("rms %4.3f max %4.3f "
+   "freq %+6.3f +/- %3.3f "
+   "delay %5.3f +/- %3.3f",
offset_stats.rms, offset_stats.max_abs,
freq_stats.mean, freq_stats.stddev,
delay_stats.mean, delay_stats.stddev);
} else {
-   pr_info("rms %4.0f max %4.0f "
-   "freq %+6.0f +/- %3.0f",
+   pr_info("rms %4.3f max %4.3f "
+   "freq %+6.3f +/- %3.3f",
offset_stats.rms, offset_stats.max_abs,
freq_stats.mean, freq_stats.stddev);
}
@@ -602,10 +602,9 @@ static enum servo_state clock_no_adjust(struct clock *c, 
tmv_t ingress,
if (c->stats.max_count > 1) {
clock_stats_update(>stats, tmv_dbl(c->master_offset), freq);
} else {
-   pr_info("master offset %10" PRId64 " s%d freq %+7.0f "
-   "path delay %9" PRId64,
-   tmv_to_nanoseconds(c->master_offset), state, freq,
-   tmv_to_nanoseconds(c->path_delay));
+   pr_info("master offset %10.3f s%d freq %+7.3f path delay %9.3f",
+   tmv_dbl(c->master_offset), state, freq,
+   tmv_dbl(c->path_delay));
}
 
fui = 1.0 + (c->status.cumulativeScaledRateOffset + 0.0) / POW2_41;
@@ -1614,10 +1613,9 @@ enum servo_state clock_synchronize(struct clock *c, 
tmv_t ingress, tmv_t origin)
if (c->stats.max_count > 1) {
clock_stats_update(>stats, tmv_dbl(c->master_offset), adj);
} else {
-   pr_info("master offset %10" PRId64 " s%d freq %+7.0f "
-   "path delay %9" PRId64,
-   tmv_to_nanoseconds(c->master_offset), state, adj,
-   tmv_to_nanoseconds(c->path_delay));
+   pr_info("master offset %10.3f s%d freq %+7.3f path delay %9.3f",
+   tmv_dbl(c->master_offset), state, adj,
+   tmv_dbl(c->path_delay));
}
 
tsproc_set_clock_rate_ratio(c->tsproc, clock_rate_ratio(c));
-- 
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
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 03/13] tmv: Add missing uses of tmv_dbl()

2018-02-28 Thread Michael Brown
Signed-off-by: Michael Brown 
---
 tsproc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tsproc.c b/tsproc.c
index 06c0184..b50c8e5 100644
--- a/tsproc.c
+++ b/tsproc.c
@@ -214,7 +214,7 @@ int tsproc_update_offset(struct tsproc *tsp, tmv_t *offset, 
double *weight)
return 0;
 
if (weighting(tsp) && tsp->filtered_delay > 0 && raw_delay > 0) {
-   *weight = (double)tsp->filtered_delay / raw_delay;
+   *weight = tmv_dbl(tsp->filtered_delay) / tmv_dbl(raw_delay);
if (*weight > 1.0)
*weight = 1.0;
} else {
-- 
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
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 00/13] Prepare for sub-nanosecond timestamps

2018-02-28 Thread Michael Brown
The following series of patches adds support required for
sub-nanosecond timestamps in ptp4l.  The kernel-to-userspace API data
structures for reporting such timestamps are not yet defined, but this
code is verified to achieve sub-nanosecond synchronisation over IPv6
(6LoWPAN) using a DecaWave DW1000 UWB radio transceiver with one
temporary hack (not included in this series) to allow the kernel
driver to report timestamps with ~16ps granularity.

I have tried to structure the patches to maximise ease of code review.
Please let me know if there are any changes required, and many thanks
for your excellent work on linuxptp!

Michael Brown (13):
  tmv: Add missing uses of tmv_zero()
  tmv: Add missing uses of tmv_is_zero()
  tmv: Add missing uses of tmv_dbl()
  tmv: Add missing uses of tmv_to_nanoseconds()
  tmv: Generalise tmv_eq() to tmv_cmp()
  tmv: Add tmv_sign()
  tmv: Convert tmv_t to a non-scalar type
  tmv: Include fractional nanoseconds within internal representation
  tmv: Add converters for hardware timestamps
  clock: Pass floating point values to stats_add_value()
  clock: Print statistics as floating point values
  tsproc: Print statistics as floating point values
  servo: Include fractional nanoseconds within clock offset

 clock.c |  53 +--
 clock.h |   2 +-
 linreg.c|   3 +-
 makefile|   2 +-
 mave.c  |   2 +-
 mmedian.c   |   3 +-
 msg.h   |   1 +
 ntpshm.c|   3 +-
 nullf.c |   2 +-
 pi.c|   4 +-
 port.c  |  73 ++
 servo.c |   2 +-
 servo.h |   2 +-
 servo_private.h |   2 +-
 tmv.c   | 157 
 tmv.h   | 103 ++---
 tsproc.c|  19 +++
 17 files changed, 261 insertions(+), 172 deletions(-)
 create mode 100644 tmv.c

-- 
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
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 08/13] tmv: Include fractional nanoseconds within internal representation

2018-02-28 Thread Michael Brown
Signed-off-by: Michael Brown 
---
 makefile |   2 +-
 tmv.c| 136 +++
 tmv.h| 112 +---
 3 files changed, 156 insertions(+), 94 deletions(-)
 create mode 100644 tmv.c

diff --git a/makefile b/makefile
index f898336..8ccc322 100644
--- a/makefile
+++ b/makefile
@@ -25,7 +25,7 @@ LDLIBS= -lm -lrt $(EXTRA_LDFLAGS)
 PRG= ptp4l pmc phc2sys hwstamp_ctl phc_ctl timemaster
 OBJ = bmc.o clock.o clockadj.o clockcheck.o config.o fault.o \
  filter.o fsm.o hash.o linreg.o mave.o mmedian.o msg.o ntpshm.o nullf.o phc.o \
- pi.o port.o print.o ptp4l.o raw.o rtnl.o servo.o sk.o stats.o tlv.o \
+ pi.o port.o print.o ptp4l.o raw.o rtnl.o servo.o sk.o stats.o tlv.o tmv.o \
  transport.o tsproc.o udp.o udp6.o uds.o util.o version.o
 
 OBJECTS= $(OBJ) hwstamp_ctl.o phc2sys.o phc_ctl.o pmc.o pmc_common.o \
diff --git a/tmv.c b/tmv.c
new file mode 100644
index 000..f2d36a3
--- /dev/null
+++ b/tmv.c
@@ -0,0 +1,136 @@
+/**
+ * @file tmv.c
+ * @brief Implements an abstract time value type.
+ * @note Copyright (C) 2018 Michael Brown 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include 
+#include 
+
+#include "ddt.h"
+#include "pdt.h"
+#include "tmv.h"
+
+#define NS_FRAC 0x1
+
+static tmv_t tmv_normalize(int64_t ns, int32_t frac)
+{
+   tmv_t t;
+
+   while ((frac > NS_FRAC) || (frac > 0 && ns < 0)) {
+   frac -= NS_FRAC;
+   ns++;
+   }
+   while ((frac < -NS_FRAC) || (frac < 0 && ns > 0)) {
+   frac += NS_FRAC;
+   ns--;
+   }
+   t.ns = ns;
+   t.frac = frac;
+   return t;
+}
+
+tmv_t tmv_add(tmv_t a, tmv_t b)
+{
+   return tmv_normalize(a.ns + b.ns, a.frac + b.frac);
+}
+
+tmv_t tmv_div(tmv_t a, int divisor)
+{
+   int64_t q;
+   int64_t r;
+   q = a.ns / divisor;
+   r = a.ns % divisor;
+   return tmv_normalize(q, (r * NS_FRAC + a.frac) / divisor);
+}
+
+int tmv_cmp(tmv_t a, tmv_t b)
+{
+   if (a.ns == b.ns) {
+   return a.frac == b.frac ? 0 : a.frac > b.frac ? +1 : -1;
+   } else {
+   return a.ns > b.ns ? +1 : -1;
+   }
+}
+
+int tmv_sign(tmv_t x)
+{
+   if (x.ns == 0) {
+   return x.frac == 0 ? 0 : x.frac > 0 ? +1 : -1;
+   } else {
+   return x.ns > 0 ? +1 : -1;
+   }
+}
+
+int tmv_is_zero(tmv_t x)
+{
+   return x.ns == 0 && x.frac == 0 ? 1 : 0;
+}
+
+tmv_t tmv_sub(tmv_t a, tmv_t b)
+{
+   return tmv_normalize(a.ns - b.ns, a.frac - b.frac);
+}
+
+tmv_t tmv_zero(void)
+{
+   tmv_t t = { 0, 0 };
+   return t;
+}
+
+tmv_t correction_to_tmv(Integer64 c)
+{
+   return tmv_normalize(c / NS_FRAC, c % NS_FRAC);
+}
+
+double tmv_dbl(tmv_t x)
+{
+   return (double) x.ns + (double) x.frac / NS_FRAC;
+}
+
+tmv_t dbl_tmv(double x)
+{
+   double ns;
+   double frac;
+   frac = modf(x, );
+   return tmv_normalize(ns, frac * NS_FRAC);
+}
+
+int64_t tmv_to_nanoseconds(tmv_t x)
+{
+   return x.ns;
+}
+
+TimeInterval tmv_to_TimeInterval(tmv_t x)
+{
+   return x.ns * NS_FRAC + x.frac;
+}
+
+tmv_t timespec_to_tmv(struct timespec ts)
+{
+   tmv_t t;
+   t.ns = ts.tv_sec * NS_PER_SEC + ts.tv_nsec;
+   t.frac = 0;
+   return t;
+}
+
+tmv_t timestamp_to_tmv(struct timestamp ts)
+{
+   tmv_t t;
+   t.ns = ts.sec * NS_PER_SEC + ts.nsec;
+   t.frac = 0;
+   return t;
+}
diff --git a/tmv.h b/tmv.h
index 72f2d51..425a35e 100644
--- a/tmv.h
+++ b/tmv.h
@@ -29,103 +29,29 @@
 
 /**
  * We implement the time value as a 64 bit signed integer containing
- * nanoseconds. Using this representation, we could really spare the
- * arithmetic functions such as @ref tmv_add() and the like, and just
- * use plain old math operators in the code.
- *
- * However, we are going to be a bit pedantic here and enforce the
- * use of the these functions, so that we can easily upgrade the code
- * to a finer representation later on. In that way, we can make use of
- * the fractional nanosecond parts of the correction fields, if and
- * when people start asking for them.
+ * integer nanoseconds and a 32 bit signed integer containing
+ * fractional 

[Linuxptp-devel] [PATCH 09/13] tmv: Add converters for hardware timestamps

2018-02-28 Thread Michael Brown
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 
---
 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(>hwts);
+   tsync = hwts_sw_to_tmv(>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(>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, >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,
  

[Linuxptp-devel] [PATCH 12/13] tsproc: Print statistics as floating point values

2018-02-28 Thread Michael Brown
Signed-off-by: Michael Brown 
---
 tsproc.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/tsproc.c b/tsproc.c
index a871049..0597f40 100644
--- a/tsproc.c
+++ b/tsproc.c
@@ -134,11 +134,10 @@ tmv_t get_raw_delay(struct tsproc *tsp)
delay = tmv_div(tmv_add(t23, t41), 2);
 
if (tmv_sign(delay) < 0) {
-   pr_debug("negative delay %10" PRId64,
-tmv_to_nanoseconds(delay));
+   pr_debug("negative delay %10.3f", tmv_dbl(delay));
pr_debug("delay = (t2 - t3) * rr + (t4 - t1)");
-   pr_debug("t2 - t3 = %+10" PRId64, tmv_to_nanoseconds(t23));
-   pr_debug("t4 - t1 = %+10" PRId64, tmv_to_nanoseconds(t41));
+   pr_debug("t2 - t3 = %+10.3f", tmv_dbl(t23));
+   pr_debug("t4 - t1 = %+10.3f", tmv_dbl(t41));
pr_debug("rr = %.9f", tsp->clock_rate_ratio);
}
 
@@ -156,9 +155,8 @@ int tsproc_update_delay(struct tsproc *tsp, tmv_t *delay)
tsp->filtered_delay = filter_sample(tsp->delay_filter, raw_delay);
tsp->filtered_delay_valid = 1;
 
-   pr_debug("delay   filtered %10" PRId64 "   raw %10" PRId64,
-tmv_to_nanoseconds(tsp->filtered_delay),
-tmv_to_nanoseconds(raw_delay));
+   pr_debug("delay   filtered %10.3f   raw %10.3f",
+tmv_dbl(tsp->filtered_delay), tmv_dbl(raw_delay));
 
if (!delay) {
return 0;
-- 
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
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 04/13] tmv: Add missing uses of tmv_to_nanoseconds()

2018-02-28 Thread Michael Brown
Signed-off-by: Michael Brown 
---
 clock.c  |  2 +-
 tsproc.c | 10 ++
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/clock.c b/clock.c
index 7af87fc..e9e5d74 100644
--- a/clock.c
+++ b/clock.c
@@ -419,7 +419,7 @@ static int clock_management_fill_response(struct clock *c, 
struct port *p,
break;
case TLV_TIME_STATUS_NP:
tsn = (struct time_status_np *) tlv->data;
-   tsn->master_offset = c->master_offset;
+   tsn->master_offset = tmv_to_nanoseconds(c->master_offset);
tsn->ingress_time = tmv_to_nanoseconds(c->ingress_ts);
tsn->cumulativeScaledRateOffset =
(Integer32) (c->status.cumulativeScaledRateOffset +
diff --git a/tsproc.c b/tsproc.c
index b50c8e5..91bae37 100644
--- a/tsproc.c
+++ b/tsproc.c
@@ -134,10 +134,11 @@ tmv_t get_raw_delay(struct tsproc *tsp)
delay = tmv_div(tmv_add(t23, t41), 2);
 
if (delay < 0) {
-   pr_debug("negative delay %10" PRId64, delay);
+   pr_debug("negative delay %10" PRId64,
+tmv_to_nanoseconds(delay));
pr_debug("delay = (t2 - t3) * rr + (t4 - t1)");
-   pr_debug("t2 - t3 = %+10" PRId64, t23);
-   pr_debug("t4 - t1 = %+10" PRId64, t41);
+   pr_debug("t2 - t3 = %+10" PRId64, tmv_to_nanoseconds(t23));
+   pr_debug("t4 - t1 = %+10" PRId64, tmv_to_nanoseconds(t41));
pr_debug("rr = %.9f", tsp->clock_rate_ratio);
}
 
@@ -156,7 +157,8 @@ int tsproc_update_delay(struct tsproc *tsp, tmv_t *delay)
tsp->filtered_delay_valid = 1;
 
pr_debug("delay   filtered %10" PRId64 "   raw %10" PRId64,
-tsp->filtered_delay, raw_delay);
+tmv_to_nanoseconds(tsp->filtered_delay),
+tmv_to_nanoseconds(raw_delay));
 
if (!delay) {
return 0;
-- 
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
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 06/13] tmv: Add tmv_sign()

2018-02-28 Thread Michael Brown
The sign of time values is tested in tsproc.c.  Add an abstraction
tmv_sign() to return the sign of a time value.

Signed-off-by: Michael Brown 
---
 tmv.h| 5 +
 tsproc.c | 5 +++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/tmv.h b/tmv.h
index 5717846..eff172f 100644
--- a/tmv.h
+++ b/tmv.h
@@ -56,6 +56,11 @@ static inline int tmv_cmp(tmv_t a, tmv_t b)
return a == b ? 0 : a > b ? +1 : -1;
 }
 
+static inline int tmv_sign(tmv_t x)
+{
+   return x == 0 ? 0 : x > 0 ? +1 : -1;
+}
+
 static inline int tmv_is_zero(tmv_t x)
 {
return x == ((tmv_t) 0) ? 1 : 0;
diff --git a/tsproc.c b/tsproc.c
index 91bae37..a871049 100644
--- a/tsproc.c
+++ b/tsproc.c
@@ -133,7 +133,7 @@ tmv_t get_raw_delay(struct tsproc *tsp)
t41 = tmv_sub(tsp->t4, tsp->t1);
delay = tmv_div(tmv_add(t23, t41), 2);
 
-   if (delay < 0) {
+   if (tmv_sign(delay) < 0) {
pr_debug("negative delay %10" PRId64,
 tmv_to_nanoseconds(delay));
pr_debug("delay = (t2 - t3) * rr + (t4 - t1)");
@@ -215,7 +215,8 @@ int tsproc_update_offset(struct tsproc *tsp, tmv_t *offset, 
double *weight)
if (!weight)
return 0;
 
-   if (weighting(tsp) && tsp->filtered_delay > 0 && raw_delay > 0) {
+   if (weighting(tsp) && tmv_sign(tsp->filtered_delay) > 0 &&
+   tmv_sign(raw_delay) > 0) {
*weight = tmv_dbl(tsp->filtered_delay) / tmv_dbl(raw_delay);
if (*weight > 1.0)
*weight = 1.0;
-- 
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
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 05/13] tmv: Generalise tmv_eq() to tmv_cmp()

2018-02-28 Thread Michael Brown
Time values are compared using an inequality test in mmedian.c
Generalise tmv_eq() to tmv_cmp() (by analogy with memcmp()) and
replace existing uses of tmv_eq().

Signed-off-by: Michael Brown 
---
 clock.c   | 2 +-
 mmedian.c | 3 ++-
 port.c| 2 +-
 tmv.h | 4 ++--
 4 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/clock.c b/clock.c
index e9e5d74..92adea8 100644
--- a/clock.c
+++ b/clock.c
@@ -590,7 +590,7 @@ static enum servo_state clock_no_adjust(struct clock *c, 
tmv_t ingress,
if (f->count < f->max_count) {
return state;
}
-   if (tmv_eq(ingress, f->ingress1)) {
+   if (tmv_cmp(ingress, f->ingress1) == 0) {
pr_warning("bad timestamps in rate ratio calculation");
return state;
}
diff --git a/mmedian.c b/mmedian.c
index 1d15789..2383467 100644
--- a/mmedian.c
+++ b/mmedian.c
@@ -60,7 +60,8 @@ static tmv_t mmedian_sample(struct filter *filter, tmv_t 
sample)
 
/* Insert index of the new value to order. */
for (i = m->cnt - 1; i > 0; i--) {
-   if (m->samples[m->order[i - 1]] <= m->samples[m->index])
+   if (tmv_cmp(m->samples[m->order[i - 1]],
+   m->samples[m->index]) <= 0)
break;
m->order[i] = m->order[i - 1];
}
diff --git a/port.c b/port.c
index 6f91320..ee09b5c 100644
--- a/port.c
+++ b/port.c
@@ -938,7 +938,7 @@ static void port_nrate_calculate(struct port *p, tmv_t 
origin, tmv_t ingress)
if (n->count < n->max_count) {
return;
}
-   if (tmv_eq(ingress, n->ingress1)) {
+   if (tmv_cmp(ingress, n->ingress1) == 0) {
pr_warning("bad timestamps in nrate calculation");
return;
}
diff --git a/tmv.h b/tmv.h
index 30b41ee..5717846 100644
--- a/tmv.h
+++ b/tmv.h
@@ -51,9 +51,9 @@ static inline tmv_t tmv_div(tmv_t a, int divisor)
return a / divisor;
 }
 
-static inline int tmv_eq(tmv_t a, tmv_t b)
+static inline int tmv_cmp(tmv_t a, tmv_t b)
 {
-   return a == b ? 1 : 0;
+   return a == b ? 0 : a > b ? +1 : -1;
 }
 
 static inline int tmv_is_zero(tmv_t x)
-- 
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
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 07/13] tmv: Convert tmv_t to a non-scalar type

2018-02-28 Thread Michael Brown
Enforce the use of the tmv_t wrapper functions by converting tmv_t
from an int64_t to a struct containing an int64_t.

Signed-off-by: Michael Brown 
---
 tmv.h | 47 ---
 1 file changed, 32 insertions(+), 15 deletions(-)

diff --git a/tmv.h b/tmv.h
index eff172f..72f2d51 100644
--- a/tmv.h
+++ b/tmv.h
@@ -39,76 +39,93 @@
  * the fractional nanosecond parts of the correction fields, if and
  * when people start asking for them.
  */
-typedef int64_t tmv_t;
+typedef struct {
+   int64_t ns;
+} tmv_t;
 
 static inline tmv_t tmv_add(tmv_t a, tmv_t b)
 {
-   return a + b;
+   tmv_t t;
+   t.ns = a.ns + b.ns;
+   return t;
 }
 
 static inline tmv_t tmv_div(tmv_t a, int divisor)
 {
-   return a / divisor;
+   tmv_t t;
+   t.ns = a.ns / divisor;
+   return t;
 }
 
 static inline int tmv_cmp(tmv_t a, tmv_t b)
 {
-   return a == b ? 0 : a > b ? +1 : -1;
+   return a.ns == b.ns ? 0 : a.ns > b.ns ? +1 : -1;
 }
 
 static inline int tmv_sign(tmv_t x)
 {
-   return x == 0 ? 0 : x > 0 ? +1 : -1;
+   return x.ns == 0 ? 0 : x.ns > 0 ? +1 : -1;
 }
 
 static inline int tmv_is_zero(tmv_t x)
 {
-   return x == ((tmv_t) 0) ? 1 : 0;
+   return x.ns == 0 ? 1 : 0;
 }
 
 static inline tmv_t tmv_sub(tmv_t a, tmv_t b)
 {
-   return a - b;
+   tmv_t t;
+   t.ns = a.ns - b.ns;
+   return t;
 }
 
 static inline tmv_t tmv_zero(void)
 {
-   return (tmv_t) 0;
+   tmv_t t = { 0 };
+   return t;
 }
 
 static inline tmv_t correction_to_tmv(Integer64 c)
 {
-   return c >> 16;
+   tmv_t t;
+   t.ns = (c >> 16);
+   return t;
 }
 
 static inline double tmv_dbl(tmv_t x)
 {
-   return (double) x;
+   return (double) x.ns;
 }
 
 static inline tmv_t dbl_tmv(double x)
 {
-   return (tmv_t) x;
+   tmv_t t;
+   t.ns = x;
+   return t;
 }
 
 static inline int64_t tmv_to_nanoseconds(tmv_t x)
 {
-   return x;
+   return x.ns;
 }
 
 static inline TimeInterval tmv_to_TimeInterval(tmv_t x)
 {
-   return x << 16;
+   return x.ns << 16;
 }
 
 static inline tmv_t timespec_to_tmv(struct timespec ts)
 {
-   return ts.tv_sec * NS_PER_SEC + ts.tv_nsec;
+   tmv_t t;
+   t.ns = ts.tv_sec * NS_PER_SEC + ts.tv_nsec;
+   return t;
 }
 
 static inline tmv_t timestamp_to_tmv(struct timestamp ts)
 {
-   return ts.sec * NS_PER_SEC + ts.nsec;
+   tmv_t t;
+   t.ns = ts.sec * NS_PER_SEC + ts.nsec;
+   return t;
 }
 
 #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
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 01/13] tmv: Add missing uses of tmv_zero()

2018-02-28 Thread Michael Brown
Signed-off-by: Michael Brown 
---
 mave.c   | 2 +-
 tsproc.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/mave.c b/mave.c
index fd09e5a..1a64f79 100644
--- a/mave.c
+++ b/mave.c
@@ -58,7 +58,7 @@ static void mave_reset(struct filter *filter)
 
m->cnt = 0;
m->index = 0;
-   m->sum = 0;
+   m->sum = tmv_zero();
memset(m->val, 0, m->len * sizeof(*m->val));
 }
 
diff --git a/tsproc.c b/tsproc.c
index 63c989d..06c0184 100644
--- a/tsproc.c
+++ b/tsproc.c
@@ -178,7 +178,7 @@ int tsproc_update_delay(struct tsproc *tsp, tmv_t *delay)
 
 int tsproc_update_offset(struct tsproc *tsp, tmv_t *offset, double *weight)
 {
-   tmv_t delay = 0, raw_delay = 0;
+   tmv_t delay = tmv_zero(), raw_delay = tmv_zero();
 
if (tmv_is_zero(tsp->t1) || tmv_is_zero(tsp->t2))
return -1;
-- 
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
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 02/13] tmv: Add missing uses of tmv_is_zero()

2018-02-28 Thread Michael Brown
Signed-off-by: Michael Brown 
---
 clock.c | 4 ++--
 port.c  | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/clock.c b/clock.c
index 4532664..7af87fc 100644
--- a/clock.c
+++ b/clock.c
@@ -581,7 +581,7 @@ static enum servo_state clock_no_adjust(struct clock *c, 
tmv_t ingress,
 * By leaving out the path delay altogther, we can avoid the
 * error caused by our imperfect path delay measurement.
 */
-   if (!f->ingress1) {
+   if (tmv_is_zero(f->ingress1)) {
f->ingress1 = ingress;
f->origin1 = origin;
return state;
@@ -1712,7 +1712,7 @@ static void handle_state_decision_event(struct clock *c)
if (!cid_eq(_id, >best_id)) {
clock_freq_est_reset(c);
tsproc_reset(c->tsproc, 1);
-   if (c->initial_delay)
+   if (!tmv_is_zero(c->initial_delay))
tsproc_set_delay(c->tsproc, c->initial_delay);
c->ingress_ts = tmv_zero();
c->path_delay = c->initial_delay;
diff --git a/port.c b/port.c
index 6cc5dd0..6f91320 100644
--- a/port.c
+++ b/port.c
@@ -929,7 +929,7 @@ static void port_nrate_calculate(struct port *p, tmv_t 
origin, tmv_t ingress)
 */
p->pdr_missing = 0;
 
-   if (!n->ingress1) {
+   if (tmv_is_zero(n->ingress1)) {
n->ingress1 = ingress;
n->origin1 = origin;
return;
-- 
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
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] connecting two devices clock via GPIO

2018-02-28 Thread Frantisek Rysanek
Just a short update along the lines of this thread:

On top of the previous work on PPS input to i210,
I've cobbled together a simple PLL synth with a 25MHz VCXO,
good enough to take an external 10 MHz reference 
and "influence" the crystal on an i210 to run in step with the PPS.
(I could as well just desolder the original crystal, but ahh well.)
I'm attaching the resulting output of "my" i210 PPS proggie :-)
(again based heavily on Mr. Cochran's example.)

As for the capturing side of things, both TCPDUMP (PCAP file format)
and T-Shark (PCAP-NG file format) work for nanosecond-level 
capturing. I'm working on a crude analyzer of PTP traffic. 
I've given up tapping into the Wireshark dissector framework or using 
raw libpcap (and writing my own PTP dissector from scratch). 
Instead, I tend to run tshark -V and parse what I need from its 
textual output. I got through the text parsing and transaction 
recombination/inference, I have yet to write the output side (dump 
per-transaction timing data into CSV files suitable for gnuplot). 

The key bit I'm still looking forward to is the decoding of various 
timing deltas. I have a "time of capture" timestamp, and the PTP's 
own payload timestamps, and the correction value... If I understand 
correctly, the slave will tell me in PDelay Response (+FollowUp, if 
2-step) its own timestamp, which should give me a clue about *the 
slave's* performance...

I got this far using a DIY powered tap for metallic 100Mb Ethernet.
And then there's the hope that I'd be able to convert (reconfigure) 
the DeLock gigabit i210 with SFP from SERDES mode into SGMII mode...
That's coming up. The 100Mb SGMII SFP's seem quite exotic.

If you care, keep your fingers crossed :-)

Frank Rysanek
The following section of this message contains a file attachment
prepared for transmission using the Internet MIME message format.
If you are using Pegasus Mail, or any other MIME-compliant system,
you should be able to save it or view it from within your mailer.
If you cannot, please ask your system administrator for assistance.

    File information ---
 File:  i210_ext_pps.txt
 Date:  28 Feb 2018, 14:16
 Size:  5795 bytes.
 Type:  Text


i210_ext_pps.txt
Description: Binary data
The following section of this message contains a file attachment
prepared for transmission using the Internet MIME message format.
If you are using Pegasus Mail, or any other MIME-compliant system,
you should be able to save it or view it from within your mailer.
If you cannot, please ask your system administrator for assistance.

    File information ---
 File:  capture_parser.txt
 Date:  28 Feb 2018, 14:24
 Size:  2285 bytes.
 Type:  Text


capture_parser.txt
Description: Binary data
--
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
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel