[Linuxptp-devel] Reconfiguring sync direction with ts2phc
PTP IEEE 1588 stack for Linux
Brought to you by:
rcochran
From: Vladimir O. <ol...@gm...> - 2020-06-27 08:28:06
|
Hi Richard, I have a board with multiple DSA switches which I'm trying to make act as a single boundary clock. The overall design is that there's an SoC with an embedded DSA switch, and hanging off of 3 ports of that embedded switch are 3 external switches. Every networking device (the DSA master for the embedded switch, the embedded switch, as well as each individual external switch) has a PTP clock. The topology for PPS signal distribution is fixed - that is given by hardware ability - the /dev/ptp1 clock can emit a valid PPS, and all external switches can timestamp that PPS (it is connected in a sort-of simplex "bus" design), and it cannot be any other way around. It looks like this: +---------------------------------------------------------------+ | LS1028A /dev/ptp0 (unused) | | +------------------------------+ | | | DSA master for Felix | | | |(internal ENETC port 2: eno2))| | | +------------+------------------------------+-------------+ | | | Felix embedded L2 switch /dev/ptp1 | | | | PPS master, sync slave | | | | +--------------+ +--------------+ +--------------+ | | | | |DSA master for| |DSA master for| |DSA master for| | | | | | SJA1105 1 | | SJA1105 2 | | SJA1105 3 | | | | | |(Felix port 1)| |(Felix port 2)| |(Felix port 3)| | | +--+-+--------------+---+--------------+---+--------------+--+--+ /dev/ptp2 /dev/ptp3 /dev/ptp4 PPS slave, sync master PPS slave, sync slave PPS slave, sync slave +-----------------------+ +-----------------------+ +-----------------------+ | SJA1105 switch 1 | | SJA1105 switch 2 | | SJA1105 switch 3 | +-----+-----+-----+-----+ +-----+-----+-----+-----+ +-----+-----+-----+-----+ |sw1p0|sw1p1|sw1p2|sw1p3| |sw2p0|sw2p1|sw2p2|sw2p3| |sw3p0|sw3p1|sw3p2|sw3p3| +-----+-----+-----+-----+ +-----+-----+-----+-----+ +-----+-----+-----+-----+ ^ | GM connected here In text, it would be described as this: cat ts2phc.cfg [global] first_step_threshold 0.00002 step_threshold 0.00002 ts2phc.pulsewidth 500000000 # Felix [/dev/ptp1] ts2phc.master 1 # SJA1105 switch 1 [/dev/ptp2] ts2phc.channel 0 ts2phc.extts_polarity both # SJA1105 switch 2 [/dev/ptp3] ts2phc.channel 0 ts2phc.extts_polarity both # SJA1105 switch 3 [/dev/ptp4] ts2phc.channel 0 ts2phc.extts_polarity both But the point is that the synchronization might have a different hierarchy which is overlaid over the PPS master/slave hierarchy. For example, if I connect a GM to port sw1p0, then I want /dev/ptp2 to become the master clock for /dev/ptp1, /dev/ptp3 and /dev/ptp4. Similarly, when I unplug the cable from sw1p0 and I move it to sw2p0, I want /dev/ptp3 to become master clock for /dev/ptp1, /dev/ptp2 and /dev/ptp4. But looking at the current object model in ts2phc, I figured my changes would be rather intrusive to its current design, so I would like to have a discussion with you before I even start. Right off the bat, a distinction needs to be made between a "sync master"/"sync slave" and a "PPS master"/"PPS slave". We can play around with the terminology in various ways here, the idea is that right now in ts2phc, a PPS master _is_ also a sync master. But the fact whether a PHC should be a sync master or a sync slave should be given by which switch is the GM connected to - ptp4l tells you this, so I would need to introduce a pmc in ts2phc, that subscribes to port events, very similarly to what phc2sys does. I see some opportunity for code reuse here, but I don't exactly know which parts of "struct node" should be refactored into something common, and how to name that. The sync master is synchronized to the GM, so it doesn't need to be synchronized by ts2phc. Every extts event received by a PPS slave has a {sec, nsec} format. Because the PPS master emits PPS at integer times in its own time base {sec, 0}, this means that the PPS offset between the PPS master and each individual PPS slave is given by -nsec from its extts events. The synchronization algorithm would need to be generalized. In the case described above, the sync offset between the sync master (/dev/ptp2) and the sync slave /dev/ptp3 is actually the PPS offset of /dev/ptp2 (relative to the PPS master /dev/ptp1) + the PPS offset of /dev/ptp3 (again relative to /dev/ptp1). Note that my signs might be totally off... In my case, this would work because, as I said, PPS is laid out in hardware in a "simplex bus" topology, so all PPS slaves see and timestamp what is in fact the same event. I don't know how others do it in the general case, but to me something like this makes the most sense. Note that, even though ts2phc would need to subscribe to the port events from ptp4l, it will control more PHCs than just those involved in PTP synchronization. The Felix PHC (/dev/ptp1) is going to be pretty much absent from the boundary clock (which will only contain sja1105 ports sw1p0->sw1p3, sw2p0->sw2p3, sw3p0->sw3p3. But, it still needs to be driven by ts2phc, as a PPS master and a sync slave. PPS master, because that's what the board layout is, and sync slave, because /dev/ptp1 never has a port that faces the GM. Now, the pmc portion is not at all what's difficult. In fact, nothing is _really_ difficult, I just want to set the overall design straight with you so that there would be less rework when I present some initial patches. What do you think? Regards, -Vladimir |