Commit Graph

11 Commits (master)

Author SHA1 Message Date
Vladimir Oltean f078f19339 ts2phc_phc_master: make use of new kernel API for perout waveform
This API was introduced for 2 reasons:

1. Some hardware can emit PPS signals but not starting from arbitrary
   absolute times, but rather phase-aligned to the beginning of a
   second. We _could_ patch ts2phc to always specify a start time of
   0.000000000 to PTP_PEROUT_REQUEST, but in practice, we would never
   know whether that would actually work with all in-tree PHC drivers.
   So there was a need for a new flag that only specifies the phase of
   the periodic signal, and not the absolute start time.

2. Some hardware can, rather unfortunately, not distinguish between a
   rising and a falling extts edge. And, since whatever rises also has
   to fall before rising again, the strategy in ts2phc is to set a
   'large' pulse width (half the period) and ignore the extts event
   corresponding to the mid-way between one second and another. This is
   all fine, but currently, ts2phc.pulsewidth is a read-only property in
   the config file. The kernel is not instructed in any way to use this
   value, it is simply that must be configured based on prior knowledge
   of the PHC's implementation. This API changes that.

The introduction of a phase adjustment for the master PHC means we have
to adjust our approximation of the precise perout timestamp. We put that
code into a common function and convert all call sites to call that. We
also need to do the same thing for the edge ignoring logic.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-08-30 02:56:49 +03:00
Vladimir Oltean 3045a49855 ts2phc: reconfigure sync direction by subscribing to ptp4l port events
Monitor the port state change events from ptp4l, and use that
information to determine the "source" clock.

Then synchronize all other clocks in our list to that source, by feeding
into their respective servo loop an offset equal to the delta between
their timestamp and the timestamp of the source clock. All timestamps
are representative of the same event, which is the most recent perout
pulse of the ts2phc master.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-08-30 02:56:49 +03:00
Vladimir Oltean a6c19b7154 ts2phc: split slave poll from servo loop
Since it has been argued that:

- a ts2phc slave deals with extts events
- a clock deals with synchronization via a servo loop

then the code for synchronization should not be part of the
implementation of a ts2phc slave. Move it to the main ts2phc.c.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-08-30 02:56:49 +03:00
Vladimir Oltean 1441562149 ts2phc_slave: print master offset
Make this information more visible by default, since it is the key
output of this program.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
2020-08-30 02:56:49 +03:00
Vladimir Oltean 3f2e73e91b ts2phc: instantiate a full clock structure for every PHC master
This propagates the use of "struct ts2phc_private" all the way into the
master API, in preparation of a new use case that will be supported
soon: some PPS masters (to be precise, the "PHC" kind) instantiate a
struct clock which could be disciplined by ts2phc.

When a PHC A emits a pulse and another PHC B timestamps it, the offset
between their precise timestamps can be used to synchronize either one
of them. So far in ts2phc, only the slave PHC (the one using extts) has
been synchronized to the master (the one using perout).

This is partly because there is no proper kernel API to report the
precise timestamp of a perout pulse. We only have the periodic API, and
that doesn't report precise timestamps either; we just use vague
approximations of what the PPS master PHC's time was, based on reading
that PHC immediately after a slave extts event was received by the
application. While this is far from ideal, it does work, and does allow
PHC A to be synchronized to B.

This is particularly useful with the yet-to-be-introduced "automatic"
mode of ts2phc (similar to '-a' of phc2sys), and the PPS distribution
tree is fixed in hardware (as opposed to port states, which in
"automatic" mode are dynamic, as the name suggests).

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-08-30 02:56:13 +03:00
Vladimir Oltean 1967a5fc26 ts2phc: instantiate a full clock structure for every slave PHC
Slaves in ts2phc are PHC devices that implement the extts kernel API.
They are slaves just in the sense that they timestamp a pulse emitted by
somebody else.

Currently in ts2phc, PPS slaves are also the only candidates for the
clocks that get synchronized. There are 2 aspects that make this too
restrictive:

- Not all PPS slaves may be synchronization slaves. Consider a dynamic
  environment of multiple DSA switches using boundary_clock_jbod, and
  only one port is in the PS_SLAVE state. In that case, the clock of
  that port should be the synchronization master (called the "source
  clock" from now on, as far as ts2phc is concerned), regardless of
  whether it supports the extts API or not.

- Not all synchronization slaves may be PPS slaves. Specifically, the
  "PHC" type of PPS master in ts2phc can also be, fundamentally,
  disciplined. The code should be prepared to handle this by recognizing
  that things that can be disciplined by a servo should be represented
  by a "struct clock", and things that can timestamp external events
  should be represented by a "struct ts2phc_slave".

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
2020-08-30 02:56:10 +03:00
Vladimir Oltean 703c3c7bc7 ts2phc: create a private data structure
Eliminate the ad-hoc use of global variables in the ts2phc program by
introducing one data structure that incorporates them. This might make
the code more understandable to people coming from a kernel background,
since it resembles the type of data organization used there. It is also
now closer to the data organization of phc2sys, a similar program in
both purpose and implementation.

The reason why this is needed has to do with the ts2phc polymorphism for
a PPS master.

In the next patches, PPS masters will expose a struct clock, which will
be synchronized from the main ts2phc.c.

Not all PPS masters will expose a clock, only the PHC kind will. So the
current object encapsulation model needs to be loosened up little bit,
because the main ts2phc.c needs to synchronize a list of clocks, list
which is populated by the slaves and the masters which are capable of
being synchronized.

So instead of having the translation modules of ts2phc communicate
through global variables, let's make struct ts2phc_private the common
working space for the entire program, which is a paradigm that is more
natural.

Signed-off-by: Vladimir Oltean <olteanv@gmail.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
2020-08-30 02:28:04 +03:00
Richard Cochran 1335db3bde ts2phc: Ignore pulses with invalid time stamps.
The API to obtain the time stamp of a PPS source indicates the validity of
the returned value.  However, the current code does not ever test the
validity information in any way.  This patch lets the clients ignore PPS
values that lack a valid time stamp.

Signed-off-by: Richard Cochran <richardcochran@gmail.com>
2020-07-22 14:56:36 -07:00
Richard Cochran 70c32043a5 ts2phc: Fix memory leak.
Each slave creates an instance of a servo.  However, when cleaning up, the
code neglected to free the servo, resulting in a memory leak.  This patch
fixes the issue by calling the appropriate method to destroy the servo.

Signed-off-by: Richard Cochran <richardcochran@gmail.com>
2020-07-22 14:52:48 -07:00
Richard Cochran 278d9f45ab ts2phc: Use proper close method on the error path.
When creating a ts2phc slave, a clock is obtained by invoking the
posix_clock_open() method.  However, in case of an error, the same clock
is closed again by calling close(2) on the associated file descriptor
directly.  While not incorrect, still the code should instead use the
close function that matches the open method.

Signed-off-by: Richard Cochran <richardcochran@gmail.com>
2020-07-22 14:49:05 -07:00
Richard Cochran 1bdc9143aa Introduce the ts2phc program.
Some PTP Hardware Clocks have input pins that can generate time stamps
on the edges of external signals.  This functionality can be used in
various ways.  For example, one can synchronize a PHC device to a
global time source by taking a Pulse Per Second signal from the source
into the PHC.  This patch adds support for synchronizing one or more
PHC slaves to a given master clock.

The implementation follows a modular design that allows adding
different kinds of master clocks in the future.  This patch starts off
with a single "generic" PPS master, meaning a PPS signal that lacks
and time or date information.  The generic master assumes that the
Linux system time is approximately correct (by NTP or RTC for example)
in order to calculate the time of the incoming PPS edges.

Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Balint Ferencz <fernya@gmail.com>
2020-05-07 14:57:47 -07:00