Thread: [Linuxptp-devel] [PATCH v1 0/6] Adding support for Automotive Profile (Page 2)
PTP IEEE 1588 stack for Linux
Brought to you by:
rcochran
From: Vedang P. <ved...@in...> - 2018-08-30 23:56:08
|
Changes in this version: ~~~~~~~~~~~~~~~~~~~~~~~ Since the series has gone through some feedback and is mature now, it is being posted as PATCH series instead of RFC. This version incorporates feedback from the last version of this series. The changes include: - Remove AVnu keyword from all commit messages. - Instead of adding special checks for BMCA == ‘noop’ in port_p2p_transtion, we now transition to PS_LISTENING before going to PS_MASTER/PS_SLAVE for designated master or slave. - designated_{master/slave}_fsm() functions were moved to their own file. - Minor change in check_source_identity function. - In all the series adds functionality from Sections 6.2.1.1 and Section 6.3 (pts #1 and #2) of the Automotive Profile[1]. More information of intention of this and future series at: https://sourceforge.net/p/linuxptp/mailman/message/36369408/ Thanks, Vedang Patel [1] Automotive Ethernet AVB Functional and Interoperability Specification - http://avnu.org/wp-content/uploads/2014/05/ Automotive-Ethernet-AVB-Func-Interop-Spec-v1.5-Public.pdf Vedang Patel (6): port: Add condition to check fc. clock: Add NULL check for best clock in clock_update_slave() Add BMCA config option. Add inhibit_announce config option. Add ignore_source_id config option. Add example configuration for Automotive Profile. bmc.c | 11 ++++ clock.c | 24 +++++++- config.c | 9 +++ configs/automotive-master.cfg | 27 +++++++++ configs/automotive-slave.cfg | 30 ++++++++++ configs/default.cfg | 3 + designated_fsm.c | 133 ++++++++++++++++++++++++++++++++++++++++++ designated_fsm.h | 43 ++++++++++++++ fsm.h | 6 +- makefile | 11 ++-- port.c | 63 ++++++++++++++++---- port.h | 8 +++ port_private.h | 3 + ptp4l.8 | 31 ++++++++-- 14 files changed, 381 insertions(+), 21 deletions(-) create mode 100644 configs/automotive-master.cfg create mode 100644 configs/automotive-slave.cfg create mode 100644 designated_fsm.c create mode 100644 designated_fsm.h -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-08-30 23:56:31
|
If foreign clock is NULL, both the clocks are obviously not equal. So, return 0 in that case. The above condition (fc == NULL) is not currently encountered. It will be encoutered in the next few patches which implement static roles for master and slave. Signed-off-by: Vedang Patel <ved...@in...> --- port.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/port.c b/port.c index 5e0aed7df3cc..1a0e910a1151 100644 --- a/port.c +++ b/port.c @@ -144,6 +144,11 @@ static int msg_current(struct ptp_message *m, struct timespec now) static int msg_source_equal(struct ptp_message *m1, struct foreign_clock *fc) { struct PortIdentity *id1, *id2; + + if (!fc) { + return 0; + } + id1 = &m1->header.sourcePortIdentity; id2 = &fc->dataset.sender; return 0 == memcmp(id1, id2, sizeof(*id1)); -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-08-30 23:56:32
|
This scenario will only be encountered when the clock transitions to the slave state without knowing who the master is. This will result in a segfault for BMCA with designated master and slave states (to be added in upcoming patches). Signed-off-by: Vedang Patel <ved...@in...> --- clock.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/clock.c b/clock.c index faf2dea82a5b..0f2e319a19c7 100644 --- a/clock.c +++ b/clock.c @@ -635,7 +635,12 @@ static void clock_update_grandmaster(struct clock *c) static void clock_update_slave(struct clock *c) { struct parentDS *pds = &c->dad.pds; - struct ptp_message *msg = TAILQ_FIRST(&c->best->messages); + struct ptp_message *msg; + + if (!c->best) + return; + + msg = TAILQ_FIRST(&c->best->messages); c->cur.stepsRemoved = 1 + c->best->dataset.stepsRemoved; pds->parentPortIdentity = c->best->dataset.sender; pds->grandmasterIdentity = msg->announce.grandmasterIdentity; -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-08-30 23:56:35
|
This config option will skip the source port identity verification in the Sync and Follow_up messages. This option is needed when the announce messages are disabled because the slave cannot know the identity of master without announce messages. This is required by Automotive Profile as part of skipping the Best Master Clock Algorithm (BMCA). Signed-off-by: Vedang Patel <ved...@in...> --- config.c | 1 + configs/default.cfg | 1 + port.c | 22 ++++++++++++++++------ port_private.h | 1 + ptp4l.8 | 6 ++++++ 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/config.c b/config.c index 702ee1b4e52a..1e7734bc8607 100644 --- a/config.c +++ b/config.c @@ -223,6 +223,7 @@ struct config_item config_tab[] = { PORT_ITEM_INT("G.8275.portDS.localPriority", 128, 1, UINT8_MAX), GLOB_ITEM_INT("gmCapable", 1, 0, 1), PORT_ITEM_INT("hybrid_e2e", 0, 0, 1), + PORT_ITEM_INT("ignore_source_id", 0, 0, 1), PORT_ITEM_INT("ignore_transport_specific", 0, 0, 1), PORT_ITEM_INT("ingressLatency", 0, INT_MIN, INT_MAX), PORT_ITEM_INT("inhibit_announce", 0, 0, 1), diff --git a/configs/default.cfg b/configs/default.cfg index 56dfbe4aace1..3f18830f8d9f 100644 --- a/configs/default.cfg +++ b/configs/default.cfg @@ -33,6 +33,7 @@ masterOnly 0 G.8275.portDS.localPriority 128 BMCA ptp inhibit_announce 0 +ignore_source_id 0 # # Run time options # diff --git a/port.c b/port.c index 1c14a8da1970..b326b9c2fa51 100644 --- a/port.c +++ b/port.c @@ -1594,6 +1594,7 @@ int port_initialize(struct port *p) p->peerMeanPathDelay = 0; p->logAnnounceInterval = config_get_int(cfg, p->name, "logAnnounceInterval"); p->inhibit_announce = config_get_int(cfg, p->name, "inhibit_announce"); + p->ignore_source_id = config_get_int(cfg, p->name, "ignore_source_id"); p->announceReceiptTimeout = config_get_int(cfg, p->name, "announceReceiptTimeout"); p->syncReceiptTimeout = config_get_int(cfg, p->name, "syncReceiptTimeout"); p->transportSpecific = config_get_int(cfg, p->name, "transportSpecific"); @@ -1867,10 +1868,20 @@ void process_delay_resp(struct port *p, struct ptp_message *m) port_set_delay_tmo(p); } +static int check_source_identity(struct port *p, struct ptp_message *m) +{ + struct PortIdentity master; + + if (p->ignore_source_id) { + return 0; + } + master = clock_parent_identity(p->clock); + return pid_eq(&master, &m->header.sourcePortIdentity) ? 0 : -1; +} + void process_follow_up(struct port *p, struct ptp_message *m) { enum syfu_event event; - struct PortIdentity master; switch (p->state) { case PS_INITIALIZING: case PS_FAULTY: @@ -1885,8 +1896,8 @@ void process_follow_up(struct port *p, struct ptp_message *m) case PS_SLAVE: break; } - master = clock_parent_identity(p->clock); - if (!pid_eq(&master, &m->header.sourcePortIdentity)) { + + if (check_source_identity(p, m)) { return; } @@ -2175,7 +2186,6 @@ void process_pdelay_resp_fup(struct port *p, struct ptp_message *m) void process_sync(struct port *p, struct ptp_message *m) { enum syfu_event event; - struct PortIdentity master; switch (p->state) { case PS_INITIALIZING: case PS_FAULTY: @@ -2190,8 +2200,8 @@ void process_sync(struct port *p, struct ptp_message *m) case PS_SLAVE: break; } - master = clock_parent_identity(p->clock); - if (!pid_eq(&master, &m->header.sourcePortIdentity)) { + + if (check_source_identity(p, m)) { return; } diff --git a/port_private.h b/port_private.h index b454901f208d..55ce791f8494 100644 --- a/port_private.h +++ b/port_private.h @@ -98,6 +98,7 @@ struct port { enum fsm_event event, int mdiff); int bmca; int inhibit_announce; + int ignore_source_id; /* portDS */ struct PortIdentity portIdentity; enum port_state state; /*portState*/ diff --git a/ptp4l.8 b/ptp4l.8 index 902d7314db30..c66396601e97 100644 --- a/ptp4l.8 +++ b/ptp4l.8 @@ -678,6 +678,12 @@ by the Automotive profile as part of switching over to a static BMCA. if this option is enabled, ignore_source_id has to be enabled in the slave because it has no way to identify master identity in Sync and Follow_Up messages. The default is 0 (disabled). +.TP +.B ignore_source_port_id +This will disable source port identity checking for Sync and Follow_Up +messages. This is useful when the announce messages are disabled in the master +and the slave does not have any way to know it's identity. The default is 0 +(disabled). .SH UNICAST DISCOVERY OPTIONS -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-08-30 23:56:33
|
This option will accomplish 2 things. On the master, it will stop the announce messages being sent (by disabling FD_MANNO_TIMER timer). On slave, it will not configure announce message timeouts (by disabling FD_ANNOUNCE_TIMEOUT timer). This config option is needed for the Automotive profile as part of skipping the Best Master Clock Algorithm (BMCA). Signed-off-by: Vedang Patel <ved...@in...> --- config.c | 1 + configs/default.cfg | 1 + port.c | 13 +++++++++++-- port_private.h | 1 + ptp4l.8 | 8 ++++++++ 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/config.c b/config.c index 47cad7ab6632..702ee1b4e52a 100644 --- a/config.c +++ b/config.c @@ -225,6 +225,7 @@ struct config_item config_tab[] = { 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), + PORT_ITEM_INT("inhibit_announce", 0, 0, 1), PORT_ITEM_INT("inhibit_multicast_service", 0, 0, 1), GLOB_ITEM_INT("initial_delay", 0, 0, INT_MAX), GLOB_ITEM_INT("kernel_leap", 1, 0, 1), diff --git a/configs/default.cfg b/configs/default.cfg index 02714150fbab..56dfbe4aace1 100644 --- a/configs/default.cfg +++ b/configs/default.cfg @@ -32,6 +32,7 @@ neighborPropDelayThresh 20000000 masterOnly 0 G.8275.portDS.localPriority 128 BMCA ptp +inhibit_announce 0 # # Run time options # diff --git a/port.c b/port.c index 45e870fca69f..1c14a8da1970 100644 --- a/port.c +++ b/port.c @@ -1036,6 +1036,10 @@ static void port_nrate_initialize(struct port *p) int port_set_announce_tmo(struct port *p) { + if (p->inhibit_announce) { + return 0; + } + return set_tmo_random(p->fda.fd[FD_ANNOUNCE_TIMER], p->announceReceiptTimeout, p->announce_span, p->logAnnounceInterval); @@ -1589,6 +1593,7 @@ int port_initialize(struct port *p) p->logMinDelayReqInterval = config_get_int(cfg, p->name, "logMinDelayReqInterval"); p->peerMeanPathDelay = 0; p->logAnnounceInterval = config_get_int(cfg, p->name, "logAnnounceInterval"); + p->inhibit_announce = config_get_int(cfg, p->name, "inhibit_announce"); p->announceReceiptTimeout = config_get_int(cfg, p->name, "announceReceiptTimeout"); p->syncReceiptTimeout = config_get_int(cfg, p->name, "syncReceiptTimeout"); p->transportSpecific = config_get_int(cfg, p->name, "transportSpecific"); @@ -2296,7 +2301,9 @@ static void port_e2e_transition(struct port *p, enum port_state next) break; case PS_MASTER: case PS_GRAND_MASTER: - set_tmo_log(p->fda.fd[FD_MANNO_TIMER], 1, -10); /*~1ms*/ + if (!p->inhibit_announce) { + set_tmo_log(p->fda.fd[FD_MANNO_TIMER], 1, -10); /*~1ms*/ + } port_set_sync_tx_tmo(p); break; case PS_PASSIVE: @@ -2339,7 +2346,9 @@ static void port_p2p_transition(struct port *p, enum port_state next) break; case PS_MASTER: case PS_GRAND_MASTER: - set_tmo_log(p->fda.fd[FD_MANNO_TIMER], 1, -10); /*~1ms*/ + if (!p->inhibit_announce) { + set_tmo_log(p->fda.fd[FD_MANNO_TIMER], 1, -10); /*~1ms*/ + } port_set_sync_tx_tmo(p); break; case PS_PASSIVE: diff --git a/port_private.h b/port_private.h index 8b5525a2122a..b454901f208d 100644 --- a/port_private.h +++ b/port_private.h @@ -97,6 +97,7 @@ struct port { enum port_state (*state_machine)(enum port_state state, enum fsm_event event, int mdiff); int bmca; + int inhibit_announce; /* portDS */ struct PortIdentity portIdentity; enum port_state state; /*portState*/ diff --git a/ptp4l.8 b/ptp4l.8 index 786fc71ddf06..902d7314db30 100644 --- a/ptp4l.8 +++ b/ptp4l.8 @@ -670,6 +670,14 @@ assume the slave role. masterOnly (which is a per-port config option) can then be used to set individual ports to take master role. BMCA is used in the Automotive profile to speed up the start time for grand master and slaves. The default value is 'ptp' which runs the BMCA related state machines. +.TP +.B inhibit_announce +This will disable the timer for announce messages (i.e. FD_MANNO_TIMER) and +also the announce message timeout timer (i.e. FD_ANNOUNCE_TIMER). This is used +by the Automotive profile as part of switching over to a static BMCA. if this +option is enabled, ignore_source_id has to be enabled in the slave because it +has no way to identify master identity in Sync and Follow_Up messages. The +default is 0 (disabled). .SH UNICAST DISCOVERY OPTIONS -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-08-30 23:56:36
|
This commit adds example for configuring master and slave devices that support features from the Automotive Profile. Signed-off-by: Vedang Patel <ved...@in...> --- configs/automotive-master.cfg | 27 +++++++++++++++++++++++++++ configs/automotive-slave.cfg | 30 ++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 configs/automotive-master.cfg create mode 100644 configs/automotive-slave.cfg diff --git a/configs/automotive-master.cfg b/configs/automotive-master.cfg new file mode 100644 index 000000000000..ddd7fcf8e543 --- /dev/null +++ b/configs/automotive-master.cfg @@ -0,0 +1,27 @@ +# +# Automotive Profile example configuration for master containing those +# attributes which differ from the defaults. See the file, default.cfg, for +# the complete list of available options. +# +[global] +# Options carried over from gPTP. +gmCapable 1 +priority1 248 +priority2 248 +logSyncInterval -3 +syncReceiptTimeout 3 +neighborPropDelayThresh 800 +min_neighbor_prop_delay -20000000 +assume_two_step 1 +path_trace_enabled 1 +follow_up_info 1 +transportSpecific 0x1 +ptp_dst_mac 01:80:C2:00:00:0E +network_transport L2 +delay_mechanism P2P +# +# Automotive Profile specific options +# +BMCA noop +masterOnly 1 +inhibit_announce 1 diff --git a/configs/automotive-slave.cfg b/configs/automotive-slave.cfg new file mode 100644 index 000000000000..9cabe7aa9a24 --- /dev/null +++ b/configs/automotive-slave.cfg @@ -0,0 +1,30 @@ +# +# Automotive Profile example configuration for slaves containing those +# attributes which differ from the defaults. See the file, default.cfg, for +# the complete list of available options. +# +[global] +# +# Options carried over from gPTP. +# +gmCapable 1 +priority1 248 +priority2 248 +logSyncInterval -3 +syncReceiptTimeout 3 +neighborPropDelayThresh 800 +min_neighbor_prop_delay -20000000 +assume_two_step 1 +path_trace_enabled 1 +follow_up_info 1 +transportSpecific 0x1 +ptp_dst_mac 01:80:C2:00:00:0E +network_transport L2 +delay_mechanism P2P +# +# Automotive Profile specific options +# +BMCA noop +slaveOnly 1 +inhibit_announce 1 +ignore_source_id 1 -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-09-26 21:58:05
|
Changes in v2: ~~~~~~~~~~~ Following are the major changes in this patchset: - Do not use PS_LISTENING as a transitiory state. - Explicitly clear out the timer when inhibit_announce is set. - Expose asCapable as a config option. When the value is ‘true’, asCapable will be unconditionally set to true. - Add step_threshold in the example configuration for slave to reduce the time to get in sync with master after time jump. More information of intention of this and future series at: https://sourceforge.net/p/linuxptp/mailman/message/36369408/ Thanks, Vedang Patel Vedang Patel (7): port: Add condition to check fc. clock: Add NULL check for best clock in clock_update_slave() port: Add configurable option to set asCapable. Add BMCA config option. Add inhibit_announce config option. Add ignore_source_id config option. Add example configuration for Automotive Profile. as_capable.h | 45 ++++++++++++++++++ bmc.c | 11 +++++ clock.c | 7 ++- config.c | 17 +++++++ configs/automotive-master.cfg | 28 +++++++++++ configs/automotive-slave.cfg | 33 +++++++++++++ configs/default.cfg | 4 ++ designated_fsm.c | 107 ++++++++++++++++++++++++++++++++++++++++++ designated_fsm.h | 43 +++++++++++++++++ fsm.h | 5 ++ makefile | 11 +++-- port.c | 94 ++++++++++++++++++++++++++++++------- port.h | 8 ++++ port_private.h | 6 ++- ptp4l.8 | 37 +++++++++++++-- 15 files changed, 429 insertions(+), 27 deletions(-) create mode 100644 as_capable.h create mode 100644 configs/automotive-master.cfg create mode 100644 configs/automotive-slave.cfg create mode 100644 designated_fsm.c create mode 100644 designated_fsm.h -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-09-26 21:58:06
|
If foreign clock is NULL, both the clocks are obviously not equal. So, return 0 in that case. The above condition (fc == NULL) is not currently encountered. It will be encoutered in the next few patches which implement static roles for master and slave. Signed-off-by: Vedang Patel <ved...@in...> --- port.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/port.c b/port.c index 5e0aed7df3cc..1a0e910a1151 100644 --- a/port.c +++ b/port.c @@ -144,6 +144,11 @@ static int msg_current(struct ptp_message *m, struct timespec now) static int msg_source_equal(struct ptp_message *m1, struct foreign_clock *fc) { struct PortIdentity *id1, *id2; + + if (!fc) { + return 0; + } + id1 = &m1->header.sourcePortIdentity; id2 = &fc->dataset.sender; return 0 == memcmp(id1, id2, sizeof(*id1)); -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-09-26 21:58:08
|
This scenario will only be encountered when the clock transitions to the slave state without knowing who the master is. This will result in a segfault for BMCA with designated master and slave states (to be added in upcoming patches). Signed-off-by: Vedang Patel <ved...@in...> --- clock.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/clock.c b/clock.c index faf2dea82a5b..0f2e319a19c7 100644 --- a/clock.c +++ b/clock.c @@ -635,7 +635,12 @@ static void clock_update_grandmaster(struct clock *c) static void clock_update_slave(struct clock *c) { struct parentDS *pds = &c->dad.pds; - struct ptp_message *msg = TAILQ_FIRST(&c->best->messages); + struct ptp_message *msg; + + if (!c->best) + return; + + msg = TAILQ_FIRST(&c->best->messages); c->cur.stepsRemoved = 1 + c->best->dataset.stepsRemoved; pds->parentPortIdentity = c->best->dataset.sender; pds->grandmasterIdentity = msg->announce.grandmasterIdentity; -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-09-26 21:58:09
|
If set to 'true', this unconditionally sets the asCapable variable. The usual checks will be applied to asCapable if it is set to 'auto'. The default value is 'auto'. This config option is needed by the Automotive Profile. The master will be able to send out Sync Message as soon as the daemon is started. Signed-off-by: Vedang Patel <ved...@in...> --- as_capable.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ config.c | 8 ++++++++ configs/default.cfg | 1 + port.c | 17 +++++++++++++---- port_private.h | 3 ++- ptp4l.8 | 6 ++++++ 6 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 as_capable.h diff --git a/as_capable.h b/as_capable.h new file mode 100644 index 000000000000..fbd77b22e9ea --- /dev/null +++ b/as_capable.h @@ -0,0 +1,45 @@ +/** + * @file as_capable.h + * @brief Enumerates the states for asCapable. + * @note Copyright (C) 2018 Intel Corporation + * + * 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. + */ +#ifndef HAVE_AS_CAPABLE_H +#define HAVE_AS_CAPABLE_H + +/* Enum used by the asCapable config option. */ +enum as_capable_option { + AS_CAPABLE_TRUE, + AS_CAPABLE_AUTO, +}; + +/* + * Defines whether the device can interoperate with the device on other end via + * IEEE 802.1AS protocol. + * + * More information about this in Section 10.2.4.1 of IEEE 802.1AS standard. + */ +enum as_capable { + NOT_CAPABLE, + AS_CAPABLE, + /* + * Non-standard extension to support Automotive Profile. asCapable + * always set to true without checking the system at other end. + */ + ALWAYS_CAPABLE, +}; + +#endif diff --git a/config.c b/config.c index 7914ba4b5166..f4db05273f05 100644 --- a/config.c +++ b/config.c @@ -23,6 +23,7 @@ #include <stdlib.h> #include <string.h> +#include "as_capable.h" #include "bmc.h" #include "clock.h" #include "config.h" @@ -188,8 +189,15 @@ static struct config_enum tsproc_enu[] = { { NULL, 0 }, }; +static struct config_enum as_capable_enu[] = { + { "true", AS_CAPABLE_TRUE }, + { "auto", AS_CAPABLE_AUTO }, + { NULL, 0 }, +}; + struct config_item config_tab[] = { PORT_ITEM_INT("announceReceiptTimeout", 3, 2, UINT8_MAX), + PORT_ITEM_ENU("asCapable", AS_CAPABLE_AUTO, as_capable_enu), GLOB_ITEM_INT("assume_two_step", 0, 0, 1), PORT_ITEM_INT("boundary_clock_jbod", 0, 0, 1), GLOB_ITEM_INT("check_fup_sync", 0, 0, 1), diff --git a/configs/default.cfg b/configs/default.cfg index c5a8b57c9314..e9a62e73bc0d 100644 --- a/configs/default.cfg +++ b/configs/default.cfg @@ -31,6 +31,7 @@ fault_reset_interval 4 neighborPropDelayThresh 20000000 masterOnly 0 G.8275.portDS.localPriority 128 +asCapable auto # # Run time options # diff --git a/port.c b/port.c index 1a0e910a1151..aabbf7d83677 100644 --- a/port.c +++ b/port.c @@ -644,15 +644,16 @@ static int port_capable(struct port *p) } capable: - if (!p->asCapable) + if (p->asCapable == NOT_CAPABLE) { pr_debug("port %hu: setting asCapable", portnum(p)); - p->asCapable = 1; + p->asCapable = AS_CAPABLE; + } return 1; not_capable: if (p->asCapable) port_nrate_initialize(p); - p->asCapable = 0; + p->asCapable = NOT_CAPABLE; return 0; } @@ -742,6 +743,9 @@ static int port_sync_incapable(struct port *p) static int port_is_ieee8021as(struct port *p) { + if (p->asCapable == ALWAYS_CAPABLE) { + return 0; + } return p->follow_up_info ? 1 : 0; } @@ -1021,7 +1025,6 @@ static void port_nrate_initialize(struct port *p) /* We start in the 'incapable' state. */ p->pdr_missing = ALLOWED_LOST_RESPONSES + 1; - p->asCapable = 0; p->peer_portid_valid = 0; @@ -1600,6 +1603,12 @@ int port_initialize(struct port *p) p->neighborPropDelayThresh = config_get_int(cfg, p->name, "neighborPropDelayThresh"); p->min_neighbor_prop_delay = config_get_int(cfg, p->name, "min_neighbor_prop_delay"); + if (config_get_int(cfg, p->name, "asCapable") == AS_CAPABLE_TRUE) { + p->asCapable = ALWAYS_CAPABLE; + } else { + p->asCapable = NOT_CAPABLE; + } + for (i = 0; i < N_TIMER_FDS; i++) { fd[i] = -1; } diff --git a/port_private.h b/port_private.h index 19d1d7beaae8..91e79867bf38 100644 --- a/port_private.h +++ b/port_private.h @@ -21,6 +21,7 @@ #include <sys/queue.h> +#include "as_capable.h" #include "clock.h" #include "fsm.h" #include "msg.h" @@ -100,7 +101,7 @@ struct port { struct PortIdentity portIdentity; enum port_state state; /*portState*/ Integer64 asymmetry; - int asCapable; + enum as_capable asCapable; Integer8 logMinDelayReqInterval; TimeInterval peerMeanPathDelay; Integer8 logAnnounceInterval; diff --git a/ptp4l.8 b/ptp4l.8 index 10c5c2f967cb..e840e748fb42 100644 --- a/ptp4l.8 +++ b/ptp4l.8 @@ -661,6 +661,12 @@ The time source is a single byte code that gives an idea of the kind of local clock in use. The value is purely informational, having no effect on the outcome of the Best Master Clock algorithm, and is advertised when the clock becomes grand master. +.TP +.B asCapable +If set to 'true', all the checks which can unset asCapable variable (as +described in Section 10.2.4.1 of 802.1AS) are skipped. If set to 'auto', +asCapable is initialized to 'false' and will be set to 'true' after the +relevant checks have passed. The default value is 'auto'. .SH UNICAST DISCOVERY OPTIONS -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-09-26 21:58:11
|
This option will accomplish 2 things. On the master, it will stop the announce messages being sent (by disabling FD_MANNO_TIMER timer). On slave, it will not configure announce message timeouts (by disabling FD_ANNOUNCE_TIMEOUT timer). This config option is needed for the Automotive profile as part of skipping the Best Master Clock Algorithm (BMCA). Signed-off-by: Vedang Patel <ved...@in...> --- config.c | 1 + configs/default.cfg | 1 + port.c | 18 ++++++++++++++---- port_private.h | 1 + ptp4l.8 | 8 ++++++++ 5 files changed, 25 insertions(+), 4 deletions(-) diff --git a/config.c b/config.c index 9046cd84cd70..cac0a74683c6 100644 --- a/config.c +++ b/config.c @@ -233,6 +233,7 @@ struct config_item config_tab[] = { 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), + PORT_ITEM_INT("inhibit_announce", 0, 0, 1), PORT_ITEM_INT("inhibit_multicast_service", 0, 0, 1), GLOB_ITEM_INT("initial_delay", 0, 0, INT_MAX), GLOB_ITEM_INT("kernel_leap", 1, 0, 1), diff --git a/configs/default.cfg b/configs/default.cfg index dd9fa12db06e..c51da0345343 100644 --- a/configs/default.cfg +++ b/configs/default.cfg @@ -33,6 +33,7 @@ masterOnly 0 G.8275.portDS.localPriority 128 asCapable auto BMCA ptp +inhibit_announce 0 # # Run time options # diff --git a/port.c b/port.c index d55ff86f34f7..ea40b5c6a91a 100644 --- a/port.c +++ b/port.c @@ -1592,6 +1592,7 @@ int port_initialize(struct port *p) p->logMinDelayReqInterval = config_get_int(cfg, p->name, "logMinDelayReqInterval"); p->peerMeanPathDelay = 0; p->logAnnounceInterval = config_get_int(cfg, p->name, "logAnnounceInterval"); + p->inhibit_announce = config_get_int(cfg, p->name, "inhibit_announce"); p->announceReceiptTimeout = config_get_int(cfg, p->name, "announceReceiptTimeout"); p->syncReceiptTimeout = config_get_int(cfg, p->name, "syncReceiptTimeout"); p->transportSpecific = config_get_int(cfg, p->name, "transportSpecific"); @@ -2313,7 +2314,9 @@ static void port_e2e_transition(struct port *p, enum port_state next) break; case PS_MASTER: case PS_GRAND_MASTER: - set_tmo_log(p->fda.fd[FD_MANNO_TIMER], 1, -10); /*~1ms*/ + if (!p->inhibit_announce) { + set_tmo_log(p->fda.fd[FD_MANNO_TIMER], 1, -10); /*~1ms*/ + } port_set_sync_tx_tmo(p); break; case PS_PASSIVE: @@ -2356,7 +2359,9 @@ static void port_p2p_transition(struct port *p, enum port_state next) break; case PS_MASTER: case PS_GRAND_MASTER: - set_tmo_log(p->fda.fd[FD_MANNO_TIMER], 1, -10); /*~1ms*/ + if (!p->inhibit_announce) { + set_tmo_log(p->fda.fd[FD_MANNO_TIMER], 1, -10); /*~1ms*/ + } port_set_sync_tx_tmo(p); break; case PS_PASSIVE: @@ -2477,9 +2482,14 @@ static enum fsm_event bc_event(struct port *p, int fd_index) case FD_SYNC_RX_TIMER: pr_debug("port %hu: %s timeout", portnum(p), fd_index == FD_SYNC_RX_TIMER ? "rx sync" : "announce"); - if (p->best) + if (p->best) { fc_clear(p->best); - port_set_announce_tmo(p); + } + if (p->inhibit_announce) { + port_clr_tmo(p->fda.fd[FD_ANNOUNCE_TIMER]); + } else { + port_set_announce_tmo(p); + } port_clr_tmo(p->fda.fd[FD_SYNC_RX_TIMER]); delay_req_prune(p); if (clock_slave_only(p->clock) && p->delayMechanism != DM_P2P && diff --git a/port_private.h b/port_private.h index 4b22976b57eb..ca3c906a0006 100644 --- a/port_private.h +++ b/port_private.h @@ -98,6 +98,7 @@ struct port { enum port_state (*state_machine)(enum port_state state, enum fsm_event event, int mdiff); int bmca; + int inhibit_announce; /* portDS */ struct PortIdentity portIdentity; enum port_state state; /*portState*/ diff --git a/ptp4l.8 b/ptp4l.8 index 262fe2ed02bb..ee1d00b8bdd2 100644 --- a/ptp4l.8 +++ b/ptp4l.8 @@ -676,6 +676,14 @@ assume the slave role. masterOnly (which is a per-port config option) can then be used to set individual ports to take master role. BMCA is used in the Automotive profile to speed up the start time for grand master and slaves. The default value is 'ptp' which runs the BMCA related state machines. +.TP +.B inhibit_announce +This will disable the timer for announce messages (i.e. FD_MANNO_TIMER) and +also the announce message timeout timer (i.e. FD_ANNOUNCE_TIMER). This is used +by the Automotive profile as part of switching over to a static BMCA. if this +option is enabled, ignore_source_id has to be enabled in the slave because it +has no way to identify master identity in Sync and Follow_Up messages. The +default is 0 (disabled). .SH UNICAST DISCOVERY OPTIONS -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-09-26 21:58:11
|
This commit adds example for configuring master and slave devices that support features from the Automotive Profile. Signed-off-by: Vedang Patel <ved...@in...> --- configs/automotive-master.cfg | 28 ++++++++++++++++++++++++++++ configs/automotive-slave.cfg | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 configs/automotive-master.cfg create mode 100644 configs/automotive-slave.cfg diff --git a/configs/automotive-master.cfg b/configs/automotive-master.cfg new file mode 100644 index 000000000000..e3ad5a35ebe2 --- /dev/null +++ b/configs/automotive-master.cfg @@ -0,0 +1,28 @@ +# +# Automotive Profile example configuration for master containing those +# attributes which differ from the defaults. See the file, default.cfg, for +# the complete list of available options. +# +[global] +# Options carried over from gPTP. +gmCapable 1 +priority1 248 +priority2 248 +logSyncInterval -3 +syncReceiptTimeout 3 +neighborPropDelayThresh 800 +min_neighbor_prop_delay -20000000 +assume_two_step 1 +path_trace_enabled 1 +follow_up_info 1 +transportSpecific 0x1 +ptp_dst_mac 01:80:C2:00:00:0E +network_transport L2 +delay_mechanism P2P +# +# Automotive Profile specific options +# +BMCA noop +masterOnly 1 +inhibit_announce 1 +asCapable true diff --git a/configs/automotive-slave.cfg b/configs/automotive-slave.cfg new file mode 100644 index 000000000000..94d45b640ae5 --- /dev/null +++ b/configs/automotive-slave.cfg @@ -0,0 +1,33 @@ +# +# Automotive Profile example configuration for slaves containing those +# attributes which differ from the defaults. See the file, default.cfg, for +# the complete list of available options. +# +[global] +# +# Options carried over from gPTP. +# +gmCapable 1 +priority1 248 +priority2 248 +logSyncInterval -3 +syncReceiptTimeout 3 +neighborPropDelayThresh 800 +min_neighbor_prop_delay -20000000 +assume_two_step 1 +path_trace_enabled 1 +follow_up_info 1 +transportSpecific 0x1 +ptp_dst_mac 01:80:C2:00:00:0E +network_transport L2 +delay_mechanism P2P +# +# Automotive Profile specific options +# +BMCA noop +slaveOnly 1 +inhibit_announce 1 +asCapable true +ignore_source_id 1 +# Required to quickly correct Time Jumps in master +step_threshold 1 -- 2.7.3 |
From: Richard C. <ric...@gm...> - 2018-10-01 03:04:06
|
On Wed, Sep 26, 2018 at 02:57:32PM -0700, Vedang Patel wrote: > Changes in v2: > ~~~~~~~~~~~ > Following are the major changes in this patchset: > - Do not use PS_LISTENING as a transitiory state. > - Explicitly clear out the timer when inhibit_announce is set. > - Expose asCapable as a config option. When the value is ‘true’, asCapable will > be unconditionally set to true. > - Add step_threshold in the example configuration for slave to reduce the time > to get in sync with master after time jump. The series looks good to go, except for my one comment... Thanks, Richard |
From: Vedang P. <ved...@in...> - 2018-10-03 16:42:22
|
Changes in v3: ~~~~~~~~~~~ There is only a couple of changes in this version of the series. - We clear out the SYNC_RX_TIMER in bc_event() only when BMCA == 'noop'. - Fix typo in documentation of ignore_source_id. More information of intention of this and future series at: https://sourceforge.net/p/linuxptp/mailman/message/36369408/ Thanks, Vedang Patel Vedang Patel (7): port: Add condition to check fc. clock: Add NULL check for best clock in clock_update_slave() port: Add configurable option to set asCapable. Add BMCA config option. Add inhibit_announce config option. Add ignore_source_id config option. Add example configuration for Automotive Profile. as_capable.h | 45 ++++++++++++++++++ bmc.c | 11 +++++ clock.c | 7 ++- config.c | 17 +++++++ configs/automotive-master.cfg | 28 +++++++++++ configs/automotive-slave.cfg | 33 +++++++++++++ configs/default.cfg | 4 ++ designated_fsm.c | 107 ++++++++++++++++++++++++++++++++++++++++++ designated_fsm.h | 43 +++++++++++++++++ fsm.h | 5 ++ makefile | 11 +++-- port.c | 104 +++++++++++++++++++++++++++++++++------- port.h | 8 ++++ port_private.h | 6 ++- ptp4l.8 | 37 +++++++++++++-- 15 files changed, 439 insertions(+), 27 deletions(-) create mode 100644 as_capable.h create mode 100644 configs/automotive-master.cfg create mode 100644 configs/automotive-slave.cfg create mode 100644 designated_fsm.c create mode 100644 designated_fsm.h -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-10-03 16:43:22
|
This scenario will only be encountered when the clock transitions to the slave state without knowing who the master is. This will result in a segfault for BMCA with designated master and slave states (to be added in upcoming patches). Signed-off-by: Vedang Patel <ved...@in...> --- clock.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/clock.c b/clock.c index 0a000b958821..56bc79bf3454 100644 --- a/clock.c +++ b/clock.c @@ -636,7 +636,12 @@ static void clock_update_grandmaster(struct clock *c) static void clock_update_slave(struct clock *c) { struct parentDS *pds = &c->dad.pds; - struct ptp_message *msg = TAILQ_FIRST(&c->best->messages); + struct ptp_message *msg; + + if (!c->best) + return; + + msg = TAILQ_FIRST(&c->best->messages); c->cur.stepsRemoved = 1 + c->best->dataset.stepsRemoved; pds->parentPortIdentity = c->best->dataset.sender; pds->grandmasterIdentity = msg->announce.grandmasterIdentity; -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-10-03 16:43:24
|
If set to 'true', this unconditionally sets the asCapable variable. The usual checks will be applied to asCapable if it is set to 'auto'. The default value is 'auto'. This config option is needed by the Automotive Profile. The master will be able to send out Sync Message as soon as the daemon is started. Signed-off-by: Vedang Patel <ved...@in...> --- as_capable.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ config.c | 8 ++++++++ configs/default.cfg | 1 + port.c | 17 +++++++++++++---- port_private.h | 3 ++- ptp4l.8 | 6 ++++++ 6 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 as_capable.h diff --git a/as_capable.h b/as_capable.h new file mode 100644 index 000000000000..fbd77b22e9ea --- /dev/null +++ b/as_capable.h @@ -0,0 +1,45 @@ +/** + * @file as_capable.h + * @brief Enumerates the states for asCapable. + * @note Copyright (C) 2018 Intel Corporation + * + * 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. + */ +#ifndef HAVE_AS_CAPABLE_H +#define HAVE_AS_CAPABLE_H + +/* Enum used by the asCapable config option. */ +enum as_capable_option { + AS_CAPABLE_TRUE, + AS_CAPABLE_AUTO, +}; + +/* + * Defines whether the device can interoperate with the device on other end via + * IEEE 802.1AS protocol. + * + * More information about this in Section 10.2.4.1 of IEEE 802.1AS standard. + */ +enum as_capable { + NOT_CAPABLE, + AS_CAPABLE, + /* + * Non-standard extension to support Automotive Profile. asCapable + * always set to true without checking the system at other end. + */ + ALWAYS_CAPABLE, +}; + +#endif diff --git a/config.c b/config.c index ac082bf91a8f..c55bd51aaee6 100644 --- a/config.c +++ b/config.c @@ -23,6 +23,7 @@ #include <stdlib.h> #include <string.h> +#include "as_capable.h" #include "bmc.h" #include "clock.h" #include "config.h" @@ -195,8 +196,15 @@ static struct config_enum tsproc_enu[] = { { NULL, 0 }, }; +static struct config_enum as_capable_enu[] = { + { "true", AS_CAPABLE_TRUE }, + { "auto", AS_CAPABLE_AUTO }, + { NULL, 0 }, +}; + struct config_item config_tab[] = { PORT_ITEM_INT("announceReceiptTimeout", 3, 2, UINT8_MAX), + PORT_ITEM_ENU("asCapable", AS_CAPABLE_AUTO, as_capable_enu), GLOB_ITEM_INT("assume_two_step", 0, 0, 1), PORT_ITEM_INT("boundary_clock_jbod", 0, 0, 1), GLOB_ITEM_INT("check_fup_sync", 0, 0, 1), diff --git a/configs/default.cfg b/configs/default.cfg index 2ac6eb7d6e28..d2b8c8fb55cb 100644 --- a/configs/default.cfg +++ b/configs/default.cfg @@ -32,6 +32,7 @@ fault_reset_interval 4 neighborPropDelayThresh 20000000 masterOnly 0 G.8275.portDS.localPriority 128 +asCapable auto # # Run time options # diff --git a/port.c b/port.c index 303310f17911..cd875538bdbd 100644 --- a/port.c +++ b/port.c @@ -644,15 +644,16 @@ static int port_capable(struct port *p) } capable: - if (!p->asCapable) + if (p->asCapable == NOT_CAPABLE) { pr_debug("port %hu: setting asCapable", portnum(p)); - p->asCapable = 1; + p->asCapable = AS_CAPABLE; + } return 1; not_capable: if (p->asCapable) port_nrate_initialize(p); - p->asCapable = 0; + p->asCapable = NOT_CAPABLE; return 0; } @@ -742,6 +743,9 @@ static int port_sync_incapable(struct port *p) static int port_is_ieee8021as(struct port *p) { + if (p->asCapable == ALWAYS_CAPABLE) { + return 0; + } return p->follow_up_info ? 1 : 0; } @@ -1021,7 +1025,6 @@ static void port_nrate_initialize(struct port *p) /* We start in the 'incapable' state. */ p->pdr_missing = ALLOWED_LOST_RESPONSES + 1; - p->asCapable = 0; p->peer_portid_valid = 0; @@ -1600,6 +1603,12 @@ int port_initialize(struct port *p) p->neighborPropDelayThresh = config_get_int(cfg, p->name, "neighborPropDelayThresh"); p->min_neighbor_prop_delay = config_get_int(cfg, p->name, "min_neighbor_prop_delay"); + if (config_get_int(cfg, p->name, "asCapable") == AS_CAPABLE_TRUE) { + p->asCapable = ALWAYS_CAPABLE; + } else { + p->asCapable = NOT_CAPABLE; + } + for (i = 0; i < N_TIMER_FDS; i++) { fd[i] = -1; } diff --git a/port_private.h b/port_private.h index 19d1d7beaae8..91e79867bf38 100644 --- a/port_private.h +++ b/port_private.h @@ -21,6 +21,7 @@ #include <sys/queue.h> +#include "as_capable.h" #include "clock.h" #include "fsm.h" #include "msg.h" @@ -100,7 +101,7 @@ struct port { struct PortIdentity portIdentity; enum port_state state; /*portState*/ Integer64 asymmetry; - int asCapable; + enum as_capable asCapable; Integer8 logMinDelayReqInterval; TimeInterval peerMeanPathDelay; Integer8 logAnnounceInterval; diff --git a/ptp4l.8 b/ptp4l.8 index d1751df0d837..8e9b9a274daa 100644 --- a/ptp4l.8 +++ b/ptp4l.8 @@ -686,6 +686,12 @@ Check mode only check but do not set. Full mode set the receive filter to mark all packets with hardware time stamp, so all applications can get them. The default is normal. +.TP +.B asCapable +If set to 'true', all the checks which can unset asCapable variable (as +described in Section 10.2.4.1 of 802.1AS) are skipped. If set to 'auto', +asCapable is initialized to 'false' and will be set to 'true' after the +relevant checks have passed. The default value is 'auto'. .SH UNICAST DISCOVERY OPTIONS -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-10-03 16:43:25
|
If foreign clock is NULL, both the clocks are obviously not equal. So, return 0 in that case. The above condition (fc == NULL) is not currently encountered. It will be encoutered in the next few patches which implement static roles for master and slave. Signed-off-by: Vedang Patel <ved...@in...> --- port.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/port.c b/port.c index 01e99a266888..303310f17911 100644 --- a/port.c +++ b/port.c @@ -144,6 +144,11 @@ static int msg_current(struct ptp_message *m, struct timespec now) static int msg_source_equal(struct ptp_message *m1, struct foreign_clock *fc) { struct PortIdentity *id1, *id2; + + if (!fc) { + return 0; + } + id1 = &m1->header.sourcePortIdentity; id2 = &fc->dataset.sender; return 0 == memcmp(id1, id2, sizeof(*id1)); -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-10-03 16:43:55
|
This option will accomplish 2 things. On the master, it will stop the announce messages being sent (by disabling FD_MANNO_TIMER timer). On slave, it will not configure announce message timeouts (by disabling FD_ANNOUNCE_TIMEOUT timer). This config option is needed for the Automotive profile as part of skipping the Best Master Clock Algorithm (BMCA). Signed-off-by: Vedang Patel <ved...@in...> --- config.c | 1 + configs/default.cfg | 1 + port.c | 19 +++++++++++++++---- port_private.h | 1 + ptp4l.8 | 8 ++++++++ 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/config.c b/config.c index 78b578b8bc8c..a01806611bcc 100644 --- a/config.c +++ b/config.c @@ -242,6 +242,7 @@ struct config_item config_tab[] = { 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), + PORT_ITEM_INT("inhibit_announce", 0, 0, 1), PORT_ITEM_INT("inhibit_multicast_service", 0, 0, 1), GLOB_ITEM_INT("initial_delay", 0, 0, INT_MAX), GLOB_ITEM_INT("kernel_leap", 1, 0, 1), diff --git a/configs/default.cfg b/configs/default.cfg index de346a3741f2..b791ea383e27 100644 --- a/configs/default.cfg +++ b/configs/default.cfg @@ -34,6 +34,7 @@ masterOnly 0 G.8275.portDS.localPriority 128 asCapable auto BMCA ptp +inhibit_announce 0 # # Run time options # diff --git a/port.c b/port.c index 96e536f05d8c..bf6860cb0255 100644 --- a/port.c +++ b/port.c @@ -1592,6 +1592,7 @@ int port_initialize(struct port *p) p->logMinDelayReqInterval = config_get_int(cfg, p->name, "logMinDelayReqInterval"); p->peerMeanPathDelay = 0; p->logAnnounceInterval = config_get_int(cfg, p->name, "logAnnounceInterval"); + p->inhibit_announce = config_get_int(cfg, p->name, "inhibit_announce"); p->announceReceiptTimeout = config_get_int(cfg, p->name, "announceReceiptTimeout"); p->syncReceiptTimeout = config_get_int(cfg, p->name, "syncReceiptTimeout"); p->transportSpecific = config_get_int(cfg, p->name, "transportSpecific"); @@ -2310,7 +2311,9 @@ static void port_e2e_transition(struct port *p, enum port_state next) break; case PS_MASTER: case PS_GRAND_MASTER: - set_tmo_log(p->fda.fd[FD_MANNO_TIMER], 1, -10); /*~1ms*/ + if (!p->inhibit_announce) { + set_tmo_log(p->fda.fd[FD_MANNO_TIMER], 1, -10); /*~1ms*/ + } port_set_sync_tx_tmo(p); break; case PS_PASSIVE: @@ -2353,7 +2356,9 @@ static void port_p2p_transition(struct port *p, enum port_state next) break; case PS_MASTER: case PS_GRAND_MASTER: - set_tmo_log(p->fda.fd[FD_MANNO_TIMER], 1, -10); /*~1ms*/ + if (!p->inhibit_announce) { + set_tmo_log(p->fda.fd[FD_MANNO_TIMER], 1, -10); /*~1ms*/ + } port_set_sync_tx_tmo(p); break; case PS_PASSIVE: @@ -2474,9 +2479,9 @@ static enum fsm_event bc_event(struct port *p, int fd_index) case FD_SYNC_RX_TIMER: pr_debug("port %hu: %s timeout", portnum(p), fd_index == FD_SYNC_RX_TIMER ? "rx sync" : "announce"); - if (p->best) + if (p->best) { fc_clear(p->best); - port_set_announce_tmo(p); + } /* * Clear out the event returned by poll(). It is only cleared @@ -2487,6 +2492,12 @@ static enum fsm_event bc_event(struct port *p, int fd_index) port_clr_tmo(p->fda.fd[FD_SYNC_RX_TIMER]); } + if (p->inhibit_announce) { + port_clr_tmo(p->fda.fd[FD_ANNOUNCE_TIMER]); + } else { + port_set_announce_tmo(p); + } + delay_req_prune(p); if (clock_slave_only(p->clock) && p->delayMechanism != DM_P2P && port_renew_transport(p)) { diff --git a/port_private.h b/port_private.h index 4b22976b57eb..ca3c906a0006 100644 --- a/port_private.h +++ b/port_private.h @@ -98,6 +98,7 @@ struct port { enum port_state (*state_machine)(enum port_state state, enum fsm_event event, int mdiff); int bmca; + int inhibit_announce; /* portDS */ struct PortIdentity portIdentity; enum port_state state; /*portState*/ diff --git a/ptp4l.8 b/ptp4l.8 index a4a31a346b59..d4133a8900c6 100644 --- a/ptp4l.8 +++ b/ptp4l.8 @@ -701,6 +701,14 @@ assume the slave role. masterOnly (which is a per-port config option) can then be used to set individual ports to take master role. BMCA is used in the Automotive profile to speed up the start time for grand master and slaves. The default value is 'ptp' which runs the BMCA related state machines. +.TP +.B inhibit_announce +This will disable the timer for announce messages (i.e. FD_MANNO_TIMER) and +also the announce message timeout timer (i.e. FD_ANNOUNCE_TIMER). This is used +by the Automotive profile as part of switching over to a static BMCA. if this +option is enabled, ignore_source_id has to be enabled in the slave because it +has no way to identify master identity in Sync and Follow_Up messages. The +default is 0 (disabled). .SH UNICAST DISCOVERY OPTIONS -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-10-03 16:43:56
|
This config option will skip the source port identity verification in the Sync and Follow_up messages. This option is needed when the announce messages are disabled because the slave cannot know the identity of master without announce messages. This is required by Automotive Profile as part of skipping the Best Master Clock Algorithm (BMCA). Signed-off-by: Vedang Patel <ved...@in...> --- config.c | 1 + configs/default.cfg | 1 + port.c | 22 ++++++++++++++++------ port_private.h | 1 + ptp4l.8 | 6 ++++++ 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/config.c b/config.c index a01806611bcc..232131082b2e 100644 --- a/config.c +++ b/config.c @@ -240,6 +240,7 @@ struct config_item config_tab[] = { GLOB_ITEM_INT("gmCapable", 1, 0, 1), GLOB_ITEM_ENU("hwts_filter", HWTS_FILTER_NORMAL, hwts_filter_enu), PORT_ITEM_INT("hybrid_e2e", 0, 0, 1), + PORT_ITEM_INT("ignore_source_id", 0, 0, 1), PORT_ITEM_INT("ignore_transport_specific", 0, 0, 1), PORT_ITEM_INT("ingressLatency", 0, INT_MIN, INT_MAX), PORT_ITEM_INT("inhibit_announce", 0, 0, 1), diff --git a/configs/default.cfg b/configs/default.cfg index b791ea383e27..3ee3a9b57fed 100644 --- a/configs/default.cfg +++ b/configs/default.cfg @@ -35,6 +35,7 @@ G.8275.portDS.localPriority 128 asCapable auto BMCA ptp inhibit_announce 0 +ignore_source_id 0 # # Run time options # diff --git a/port.c b/port.c index bf6860cb0255..3e6117971299 100644 --- a/port.c +++ b/port.c @@ -1593,6 +1593,7 @@ int port_initialize(struct port *p) p->peerMeanPathDelay = 0; p->logAnnounceInterval = config_get_int(cfg, p->name, "logAnnounceInterval"); p->inhibit_announce = config_get_int(cfg, p->name, "inhibit_announce"); + p->ignore_source_id = config_get_int(cfg, p->name, "ignore_source_id"); p->announceReceiptTimeout = config_get_int(cfg, p->name, "announceReceiptTimeout"); p->syncReceiptTimeout = config_get_int(cfg, p->name, "syncReceiptTimeout"); p->transportSpecific = config_get_int(cfg, p->name, "transportSpecific"); @@ -1877,10 +1878,20 @@ void process_delay_resp(struct port *p, struct ptp_message *m) port_set_delay_tmo(p); } +static int check_source_identity(struct port *p, struct ptp_message *m) +{ + struct PortIdentity master; + + if (p->ignore_source_id) { + return 0; + } + master = clock_parent_identity(p->clock); + return pid_eq(&master, &m->header.sourcePortIdentity) ? 0 : -1; +} + void process_follow_up(struct port *p, struct ptp_message *m) { enum syfu_event event; - struct PortIdentity master; switch (p->state) { case PS_INITIALIZING: case PS_FAULTY: @@ -1895,8 +1906,8 @@ void process_follow_up(struct port *p, struct ptp_message *m) case PS_SLAVE: break; } - master = clock_parent_identity(p->clock); - if (!pid_eq(&master, &m->header.sourcePortIdentity)) { + + if (check_source_identity(p, m)) { return; } @@ -2185,7 +2196,6 @@ void process_pdelay_resp_fup(struct port *p, struct ptp_message *m) void process_sync(struct port *p, struct ptp_message *m) { enum syfu_event event; - struct PortIdentity master; switch (p->state) { case PS_INITIALIZING: case PS_FAULTY: @@ -2200,8 +2210,8 @@ void process_sync(struct port *p, struct ptp_message *m) case PS_SLAVE: break; } - master = clock_parent_identity(p->clock); - if (!pid_eq(&master, &m->header.sourcePortIdentity)) { + + if (check_source_identity(p, m)) { return; } diff --git a/port_private.h b/port_private.h index ca3c906a0006..593eb76fbe48 100644 --- a/port_private.h +++ b/port_private.h @@ -99,6 +99,7 @@ struct port { enum fsm_event event, int mdiff); int bmca; int inhibit_announce; + int ignore_source_id; /* portDS */ struct PortIdentity portIdentity; enum port_state state; /*portState*/ diff --git a/ptp4l.8 b/ptp4l.8 index d4133a8900c6..99b085c148c9 100644 --- a/ptp4l.8 +++ b/ptp4l.8 @@ -709,6 +709,12 @@ by the Automotive profile as part of switching over to a static BMCA. if this option is enabled, ignore_source_id has to be enabled in the slave because it has no way to identify master identity in Sync and Follow_Up messages. The default is 0 (disabled). +.TP +.B ignore_source_id +This will disable source port identity checking for Sync and Follow_Up +messages. This is useful when the announce messages are disabled in the master +and the slave does not have any way to know it's identity. The default is 0 +(disabled). .SH UNICAST DISCOVERY OPTIONS -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-10-03 16:43:58
|
This adds config option to specify static roles for master and slave in the Best Master Clock Algorithm. This is the case for Automotive Profile where networks are mostly static and role for each device is known in advance. masterOnly and slaveOnly will be used to determine the roles for the devices. Since masterOnly is a per-port config and slaveOnly is a global config option, role assignment will be slightly odd in case of bridges. If slaveOnly is set to 1, all the ports will be in slave roles except for the ones where masterOnly is set to 1. These ports will assume the master role. Two new FSMs which will be used for master and slave roles for this config option have also been added. Signed-off-by: Vedang Patel <ved...@in...> --- bmc.c | 11 ++++++ config.c | 7 ++++ configs/default.cfg | 1 + designated_fsm.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++ designated_fsm.h | 43 +++++++++++++++++++++ fsm.h | 5 +++ makefile | 11 +++--- port.c | 41 +++++++++++++++++++- port.h | 8 ++++ port_private.h | 1 + ptp4l.8 | 17 +++++++-- 11 files changed, 241 insertions(+), 11 deletions(-) create mode 100644 designated_fsm.c create mode 100644 designated_fsm.h diff --git a/bmc.c b/bmc.c index 3c3db828764b..6ac7aa0f4fe8 100644 --- a/bmc.c +++ b/bmc.c @@ -126,6 +126,17 @@ enum port_state bmc_state_decision(struct clock *c, struct port *r, port_best = port_best_foreign(r); ps = port_state(r); + /* + * This scenario is particularly important in the designated_slave_fsm + * when it is in PS_SLAVE state. In this scenario, there is no other + * foreign master and it will elect itself as master ultimately + * resulting in printing out some unnecessary warnings (see + * port_slave_priority_warning()). + */ + if (!port_best && port_bmca(r) == BMCA_NOOP) { + return ps; + } + if (!port_best && PS_LISTENING == ps) return ps; diff --git a/config.c b/config.c index c55bd51aaee6..78b578b8bc8c 100644 --- a/config.c +++ b/config.c @@ -202,11 +202,18 @@ static struct config_enum as_capable_enu[] = { { NULL, 0 }, }; +static struct config_enum bmca_enu[] = { + { "ptp", BMCA_PTP }, + { "noop", BMCA_NOOP }, + { NULL, 0 }, +}; + struct config_item config_tab[] = { PORT_ITEM_INT("announceReceiptTimeout", 3, 2, UINT8_MAX), PORT_ITEM_ENU("asCapable", AS_CAPABLE_AUTO, as_capable_enu), GLOB_ITEM_INT("assume_two_step", 0, 0, 1), PORT_ITEM_INT("boundary_clock_jbod", 0, 0, 1), + PORT_ITEM_ENU("BMCA", BMCA_PTP, bmca_enu), GLOB_ITEM_INT("check_fup_sync", 0, 0, 1), GLOB_ITEM_INT("clockAccuracy", 0xfe, 0, UINT8_MAX), GLOB_ITEM_INT("clockClass", 248, 0, UINT8_MAX), diff --git a/configs/default.cfg b/configs/default.cfg index d2b8c8fb55cb..de346a3741f2 100644 --- a/configs/default.cfg +++ b/configs/default.cfg @@ -33,6 +33,7 @@ neighborPropDelayThresh 20000000 masterOnly 0 G.8275.portDS.localPriority 128 asCapable auto +BMCA ptp # # Run time options # diff --git a/designated_fsm.c b/designated_fsm.c new file mode 100644 index 000000000000..d19158b0b8a1 --- /dev/null +++ b/designated_fsm.c @@ -0,0 +1,107 @@ +/** + * @file designated_fsm.c + * @brief Implements designated Finite State Machines. + * @note Copyright (C) 2018 Intel Corporation + * + * 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-1335 USA. + */ +#include "fsm.h" +#include "designated_fsm.h" + +enum port_state designated_master_fsm(enum port_state state, + enum fsm_event event, + int mdiff) +{ + enum port_state next = state; + + if (EV_INITIALIZE == event || EV_POWERUP == event) + return PS_INITIALIZING; + + switch (state) { + case PS_INITIALIZING: + switch (event) { + case EV_FAULT_DETECTED: + next = PS_FAULTY; + break; + case EV_INIT_COMPLETE: + next = PS_MASTER; + break; + default: + break; + } + break; + + case PS_FAULTY: + if (event == EV_FAULT_CLEARED) { + next = PS_INITIALIZING; + } + break; + + case PS_MASTER: + if (event == EV_FAULT_DETECTED) { + next = PS_FAULTY; + } + break; + + default: + break; + } + return next; +} + +enum port_state designated_slave_fsm(enum port_state state, + enum fsm_event event, + int mdiff) +{ + enum port_state next = state; + + if (EV_INITIALIZE == event || EV_POWERUP == event) + return PS_INITIALIZING; + + switch (state) { + case PS_INITIALIZING: + switch (event) { + case EV_FAULT_DETECTED: + next = PS_FAULTY; + break; + case EV_INIT_COMPLETE: + next = PS_SLAVE; + break; + default: + break; + } + break; + + case PS_FAULTY: + if (event == EV_FAULT_CLEARED) { + next = PS_INITIALIZING; + } + break; + + case PS_SLAVE: + switch (event) { + case EV_FAULT_DETECTED: + next = PS_FAULTY; + break; + default: + break; + } + break; + + default: + break; + } + return next; +} diff --git a/designated_fsm.h b/designated_fsm.h new file mode 100644 index 000000000000..b1c0eae06281 --- /dev/null +++ b/designated_fsm.h @@ -0,0 +1,43 @@ +/** + * @file designated_fsm.c + * @brief Implements designated Finite State Machines. + * @note Copyright (C) 2018 Intel Corporation + * + * 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-1335 USA. + */ +#ifndef HAVE_DESIGNATED_FSM_H +#define HAVE_DESIGNATED_FSM_H +/** + * Run the state machine for a clock which is designated as master port. + * @param state The current state of the port. + * @param event The event to be processed. + * @param mdiff This param is not used by this function. + * @return The new state for the port. + */ +enum port_state designated_master_fsm(enum port_state state, + enum fsm_event event, + int mdiff); + +/** + * Run the state machine for a clock designated as slave port. + * @param state The current state of the port. + * @param event The event to be processed. + * @param mdiff This param is not used by this function. + * @return The new state for the port. + */ +enum port_state designated_slave_fsm(enum port_state state, + enum fsm_event event, + int mdiff); +#endif diff --git a/fsm.h b/fsm.h index 0616daa2ab7b..857af0522c97 100644 --- a/fsm.h +++ b/fsm.h @@ -55,6 +55,11 @@ enum fsm_event { EV_RS_PASSIVE, }; +enum bmca_select { + BMCA_PTP, + BMCA_NOOP, +}; + /** * Run the state machine for a BC or OC port. * @param state The current state of the port. diff --git a/makefile b/makefile index 6995e70393ea..d09a4a9f56cc 100644 --- a/makefile +++ b/makefile @@ -23,11 +23,12 @@ VER = -DVER=$(version) CFLAGS = -Wall $(VER) $(incdefs) $(DEBUG) $(EXTRA_CFLAGS) LDLIBS = -lm -lrt $(EXTRA_LDFLAGS) PRG = ptp4l hwstamp_ctl nsm phc2sys phc_ctl pmc timemaster -OBJ = bmc.o clock.o clockadj.o clockcheck.o config.o e2e_tc.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 port_signaling.o pqueue.o print.o ptp4l.o p2p_tc.o raw.o rtnl.o \ - servo.o sk.o stats.o tc.o telecom.o tlv.o transport.o tsproc.o udp.o udp6.o \ - uds.o unicast_client.o unicast_fsm.o unicast_service.o util.o version.o +OBJ = bmc.o clock.o clockadj.o clockcheck.o config.o designated_fsm.o \ +e2e_tc.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 port_signaling.o pqueue.o print.o ptp4l.o p2p_tc.o \ +raw.o rtnl.o servo.o sk.o stats.o tc.o telecom.o tlv.o transport.o tsproc.o \ +udp.o udp6.o uds.o unicast_client.o unicast_fsm.o unicast_service.o util.o \ +version.o OBJECTS = $(OBJ) hwstamp_ctl.o nsm.o phc2sys.o phc_ctl.o pmc.o pmc_common.o \ sysoff.o timemaster.o diff --git a/port.c b/port.c index cd875538bdbd..96e536f05d8c 100644 --- a/port.c +++ b/port.c @@ -27,6 +27,7 @@ #include "bmc.h" #include "clock.h" +#include "designated_fsm.h" #include "filter.h" #include "missing.h" #include "msg.h" @@ -1596,7 +1597,6 @@ int port_initialize(struct port *p) 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->master_only = config_get_int(cfg, p->name, "masterOnly"); p->localPriority = config_get_int(cfg, p->name, "G.8275.portDS.localPriority"); p->logSyncInterval = config_get_int(cfg, p->name, "logSyncInterval"); p->logMinPdelayReqInterval = config_get_int(cfg, p->name, "logMinPdelayReqInterval"); @@ -1635,6 +1635,14 @@ int port_initialize(struct port *p) /* No need to open rtnl socket on UDS port. */ if (transport_type(p->trp) != TRANS_UDS) { + /* + * The delay timer is usually started when the device + * transitions to PS_LISTENING. But, we are skipping the state + * when BMCA == 'noop'. So, start the timer here. + */ + if (p->bmca == BMCA_NOOP) { + port_set_delay_tmo(p); + } if (p->fda.fd[FD_RTNL] == -1) p->fda.fd[FD_RTNL] = rtnl_open(); if (p->fda.fd[FD_RTNL] >= 0) @@ -2469,6 +2477,16 @@ static enum fsm_event bc_event(struct port *p, int fd_index) if (p->best) fc_clear(p->best); port_set_announce_tmo(p); + + /* + * Clear out the event returned by poll(). It is only cleared + * in port_*_transition(). But, when BMCA == 'noop', there is no + * state transition. So, it won't be cleared anywhere else. + */ + if (p->bmca == BMCA_NOOP) { + port_clr_tmo(p->fda.fd[FD_SYNC_RX_TIMER]); + } + delay_req_prune(p); if (clock_slave_only(p->clock) && p->delayMechanism != DM_P2P && port_renew_transport(p)) { @@ -2859,10 +2877,24 @@ struct port *port_open(int phc_index, goto err_port; } - p->state_machine = clock_slave_only(clock) ? ptp_slave_fsm : ptp_fsm; p->phc_index = phc_index; p->jbod = config_get_int(cfg, interface->name, "boundary_clock_jbod"); transport = config_get_int(cfg, interface->name, "network_transport"); + p->master_only = config_get_int(cfg, p->name, "masterOnly"); + p->bmca = config_get_int(cfg, p->name, "BMCA"); + + if (p->bmca == BMCA_NOOP && transport != TRANS_UDS) { + if (p->master_only) { + p->state_machine = designated_master_fsm; + } else if (clock_slave_only(clock)) { + p->state_machine = designated_slave_fsm; + } else { + pr_err("Please enable at least one of masterOnly or slaveOnly when BMCA == noop.\n"); + goto err_port; + } + } else { + p->state_machine = clock_slave_only(clock) ? ptp_slave_fsm : ptp_fsm; + } if (transport == TRANS_UDS) { ; /* UDS cannot have a PHC. */ @@ -3020,3 +3052,8 @@ int port_state_update(struct port *p, enum fsm_event event, int mdiff) return 0; } + +enum bmca_select port_bmca(struct port *p) +{ + return p->bmca; +} diff --git a/port.h b/port.h index 9639193d23d1..aa3b1ecf2529 100644 --- a/port.h +++ b/port.h @@ -323,6 +323,14 @@ void fault_interval(struct port *port, enum fault_type ft, struct fault_interval *i); /** + * Obtain the BMCA type of the port. + * + * @param port A port instance. + * @return bmca type. + */ +enum bmca_select port_bmca(struct port *p); + +/** * Release all of the memory in the TC transmit descriptor cache. */ void tc_cleanup(void); diff --git a/port_private.h b/port_private.h index 91e79867bf38..4b22976b57eb 100644 --- a/port_private.h +++ b/port_private.h @@ -97,6 +97,7 @@ struct port { unsigned int multiple_pdr_detected; enum port_state (*state_machine)(enum port_state state, enum fsm_event event, int mdiff); + int bmca; /* portDS */ struct PortIdentity portIdentity; enum port_state state; /*portState*/ diff --git a/ptp4l.8 b/ptp4l.8 index 8e9b9a274daa..a4a31a346b59 100644 --- a/ptp4l.8 +++ b/ptp4l.8 @@ -363,10 +363,7 @@ hardware time stamping. The default is 1 (enabled). .TP .B slaveOnly -The local clock is a slave-only clock if enabled. -This option is only for use with 1588 clocks and should not be enabled -for 802.1AS clocks. -The default is 0 (disabled). +The local clock is a slave-only clock if enabled. The default is 0 (disabled). .TP .B gmCapable If this option is enabled, then the local clock is able to become grand master. @@ -692,6 +689,18 @@ If set to 'true', all the checks which can unset asCapable variable (as described in Section 10.2.4.1 of 802.1AS) are skipped. If set to 'auto', asCapable is initialized to 'false' and will be set to 'true' after the relevant checks have passed. The default value is 'auto'. +.TP +.B BMCA +This option enables use of static roles for master and slave devices instead of +running the best master clock algorithm (BMCA) described in 1588 profile. This +is useful when you know the roles of the devices in advance. When set to +\'noop', the traditional BMCA algorithm used by 1588 is skipped. masterOnly and +slaveOnly will be used to determine master or slave role for the device. In a +bridge, slaveOnly (which is a global option) can be set to make all ports +assume the slave role. masterOnly (which is a per-port config option) can then +be used to set individual ports to take master role. BMCA is used in the +Automotive profile to speed up the start time for grand master and slaves. The +default value is 'ptp' which runs the BMCA related state machines. .SH UNICAST DISCOVERY OPTIONS -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-10-03 16:44:00
|
This commit adds example for configuring master and slave devices that support features from the Automotive Profile. Signed-off-by: Vedang Patel <ved...@in...> --- configs/automotive-master.cfg | 28 ++++++++++++++++++++++++++++ configs/automotive-slave.cfg | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 configs/automotive-master.cfg create mode 100644 configs/automotive-slave.cfg diff --git a/configs/automotive-master.cfg b/configs/automotive-master.cfg new file mode 100644 index 000000000000..e3ad5a35ebe2 --- /dev/null +++ b/configs/automotive-master.cfg @@ -0,0 +1,28 @@ +# +# Automotive Profile example configuration for master containing those +# attributes which differ from the defaults. See the file, default.cfg, for +# the complete list of available options. +# +[global] +# Options carried over from gPTP. +gmCapable 1 +priority1 248 +priority2 248 +logSyncInterval -3 +syncReceiptTimeout 3 +neighborPropDelayThresh 800 +min_neighbor_prop_delay -20000000 +assume_two_step 1 +path_trace_enabled 1 +follow_up_info 1 +transportSpecific 0x1 +ptp_dst_mac 01:80:C2:00:00:0E +network_transport L2 +delay_mechanism P2P +# +# Automotive Profile specific options +# +BMCA noop +masterOnly 1 +inhibit_announce 1 +asCapable true diff --git a/configs/automotive-slave.cfg b/configs/automotive-slave.cfg new file mode 100644 index 000000000000..94d45b640ae5 --- /dev/null +++ b/configs/automotive-slave.cfg @@ -0,0 +1,33 @@ +# +# Automotive Profile example configuration for slaves containing those +# attributes which differ from the defaults. See the file, default.cfg, for +# the complete list of available options. +# +[global] +# +# Options carried over from gPTP. +# +gmCapable 1 +priority1 248 +priority2 248 +logSyncInterval -3 +syncReceiptTimeout 3 +neighborPropDelayThresh 800 +min_neighbor_prop_delay -20000000 +assume_two_step 1 +path_trace_enabled 1 +follow_up_info 1 +transportSpecific 0x1 +ptp_dst_mac 01:80:C2:00:00:0E +network_transport L2 +delay_mechanism P2P +# +# Automotive Profile specific options +# +BMCA noop +slaveOnly 1 +inhibit_announce 1 +asCapable true +ignore_source_id 1 +# Required to quickly correct Time Jumps in master +step_threshold 1 -- 2.7.3 |
From: Richard C. <ric...@gm...> - 2018-10-05 03:21:00
|
On Wed, Oct 03, 2018 at 09:41:45AM -0700, Vedang Patel wrote: > Changes in v3: > ~~~~~~~~~~~ > > There is only a couple of changes in this version of the series. > > - We clear out the SYNC_RX_TIMER in bc_event() only when BMCA == 'noop'. > - Fix typo in documentation of ignore_source_id. > > More information of intention of this and future series at: > https://sourceforge.net/p/linuxptp/mailman/message/36369408/ Series applied. I appreciate your following through on this! Thanks, Richard |
From: Patel, V. <ved...@in...> - 2018-10-05 16:18:11
|
On Thu, 2018-10-04 at 20:20 -0700, Richard Cochran wrote: > On Wed, Oct 03, 2018 at 09:41:45AM -0700, Vedang Patel wrote: > > > > Changes in v3: > > ~~~~~~~~~~~ > > > > There is only a couple of changes in this version of the series. > > > > - We clear out the SYNC_RX_TIMER in bc_event() only when BMCA == > > 'noop'. > > - Fix typo in documentation of ignore_source_id. > > > > More information of intention of this and future series at: > > https://sourceforge.net/p/linuxptp/mailman/message/36369408/ > Series applied. I appreciate your following through on this! > Thanks Richard! I will be sending out the next series soon. :) > Thanks, > Richard |
From: Vedang P. <ved...@in...> - 2018-09-26 21:58:10
|
This adds config option to specify static roles for master and slave in the Best Master Clock Algorithm. This is the case for Automotive Profile where networks are mostly static and role for each device is known in advance. masterOnly and slaveOnly will be used to determine the roles for the devices. Since masterOnly is a per-port config and slaveOnly is a global config option, role assignment will be slightly odd in case of bridges. If slaveOnly is set to 1, all the ports will be in slave roles except for the ones where masterOnly is set to 1. These ports will assume the master role. Two new FSMs which will be used for master and slave roles for this config option have also been added. Signed-off-by: Vedang Patel <ved...@in...> --- bmc.c | 11 ++++++ config.c | 7 ++++ configs/default.cfg | 1 + designated_fsm.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++ designated_fsm.h | 43 +++++++++++++++++++++ fsm.h | 5 +++ makefile | 11 +++--- port.c | 32 +++++++++++++++- port.h | 8 ++++ port_private.h | 1 + ptp4l.8 | 17 +++++++-- 11 files changed, 232 insertions(+), 11 deletions(-) create mode 100644 designated_fsm.c create mode 100644 designated_fsm.h diff --git a/bmc.c b/bmc.c index 3c3db828764b..6ac7aa0f4fe8 100644 --- a/bmc.c +++ b/bmc.c @@ -126,6 +126,17 @@ enum port_state bmc_state_decision(struct clock *c, struct port *r, port_best = port_best_foreign(r); ps = port_state(r); + /* + * This scenario is particularly important in the designated_slave_fsm + * when it is in PS_SLAVE state. In this scenario, there is no other + * foreign master and it will elect itself as master ultimately + * resulting in printing out some unnecessary warnings (see + * port_slave_priority_warning()). + */ + if (!port_best && port_bmca(r) == BMCA_NOOP) { + return ps; + } + if (!port_best && PS_LISTENING == ps) return ps; diff --git a/config.c b/config.c index f4db05273f05..9046cd84cd70 100644 --- a/config.c +++ b/config.c @@ -195,11 +195,18 @@ static struct config_enum as_capable_enu[] = { { NULL, 0 }, }; +static struct config_enum bmca_enu[] = { + { "ptp", BMCA_PTP }, + { "noop", BMCA_NOOP }, + { NULL, 0 }, +}; + struct config_item config_tab[] = { PORT_ITEM_INT("announceReceiptTimeout", 3, 2, UINT8_MAX), PORT_ITEM_ENU("asCapable", AS_CAPABLE_AUTO, as_capable_enu), GLOB_ITEM_INT("assume_two_step", 0, 0, 1), PORT_ITEM_INT("boundary_clock_jbod", 0, 0, 1), + PORT_ITEM_ENU("BMCA", BMCA_PTP, bmca_enu), GLOB_ITEM_INT("check_fup_sync", 0, 0, 1), GLOB_ITEM_INT("clockAccuracy", 0xfe, 0, UINT8_MAX), GLOB_ITEM_INT("clockClass", 248, 0, UINT8_MAX), diff --git a/configs/default.cfg b/configs/default.cfg index e9a62e73bc0d..dd9fa12db06e 100644 --- a/configs/default.cfg +++ b/configs/default.cfg @@ -32,6 +32,7 @@ neighborPropDelayThresh 20000000 masterOnly 0 G.8275.portDS.localPriority 128 asCapable auto +BMCA ptp # # Run time options # diff --git a/designated_fsm.c b/designated_fsm.c new file mode 100644 index 000000000000..d19158b0b8a1 --- /dev/null +++ b/designated_fsm.c @@ -0,0 +1,107 @@ +/** + * @file designated_fsm.c + * @brief Implements designated Finite State Machines. + * @note Copyright (C) 2018 Intel Corporation + * + * 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-1335 USA. + */ +#include "fsm.h" +#include "designated_fsm.h" + +enum port_state designated_master_fsm(enum port_state state, + enum fsm_event event, + int mdiff) +{ + enum port_state next = state; + + if (EV_INITIALIZE == event || EV_POWERUP == event) + return PS_INITIALIZING; + + switch (state) { + case PS_INITIALIZING: + switch (event) { + case EV_FAULT_DETECTED: + next = PS_FAULTY; + break; + case EV_INIT_COMPLETE: + next = PS_MASTER; + break; + default: + break; + } + break; + + case PS_FAULTY: + if (event == EV_FAULT_CLEARED) { + next = PS_INITIALIZING; + } + break; + + case PS_MASTER: + if (event == EV_FAULT_DETECTED) { + next = PS_FAULTY; + } + break; + + default: + break; + } + return next; +} + +enum port_state designated_slave_fsm(enum port_state state, + enum fsm_event event, + int mdiff) +{ + enum port_state next = state; + + if (EV_INITIALIZE == event || EV_POWERUP == event) + return PS_INITIALIZING; + + switch (state) { + case PS_INITIALIZING: + switch (event) { + case EV_FAULT_DETECTED: + next = PS_FAULTY; + break; + case EV_INIT_COMPLETE: + next = PS_SLAVE; + break; + default: + break; + } + break; + + case PS_FAULTY: + if (event == EV_FAULT_CLEARED) { + next = PS_INITIALIZING; + } + break; + + case PS_SLAVE: + switch (event) { + case EV_FAULT_DETECTED: + next = PS_FAULTY; + break; + default: + break; + } + break; + + default: + break; + } + return next; +} diff --git a/designated_fsm.h b/designated_fsm.h new file mode 100644 index 000000000000..b1c0eae06281 --- /dev/null +++ b/designated_fsm.h @@ -0,0 +1,43 @@ +/** + * @file designated_fsm.c + * @brief Implements designated Finite State Machines. + * @note Copyright (C) 2018 Intel Corporation + * + * 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-1335 USA. + */ +#ifndef HAVE_DESIGNATED_FSM_H +#define HAVE_DESIGNATED_FSM_H +/** + * Run the state machine for a clock which is designated as master port. + * @param state The current state of the port. + * @param event The event to be processed. + * @param mdiff This param is not used by this function. + * @return The new state for the port. + */ +enum port_state designated_master_fsm(enum port_state state, + enum fsm_event event, + int mdiff); + +/** + * Run the state machine for a clock designated as slave port. + * @param state The current state of the port. + * @param event The event to be processed. + * @param mdiff This param is not used by this function. + * @return The new state for the port. + */ +enum port_state designated_slave_fsm(enum port_state state, + enum fsm_event event, + int mdiff); +#endif diff --git a/fsm.h b/fsm.h index 0616daa2ab7b..857af0522c97 100644 --- a/fsm.h +++ b/fsm.h @@ -55,6 +55,11 @@ enum fsm_event { EV_RS_PASSIVE, }; +enum bmca_select { + BMCA_PTP, + BMCA_NOOP, +}; + /** * Run the state machine for a BC or OC port. * @param state The current state of the port. diff --git a/makefile b/makefile index 6995e70393ea..d09a4a9f56cc 100644 --- a/makefile +++ b/makefile @@ -23,11 +23,12 @@ VER = -DVER=$(version) CFLAGS = -Wall $(VER) $(incdefs) $(DEBUG) $(EXTRA_CFLAGS) LDLIBS = -lm -lrt $(EXTRA_LDFLAGS) PRG = ptp4l hwstamp_ctl nsm phc2sys phc_ctl pmc timemaster -OBJ = bmc.o clock.o clockadj.o clockcheck.o config.o e2e_tc.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 port_signaling.o pqueue.o print.o ptp4l.o p2p_tc.o raw.o rtnl.o \ - servo.o sk.o stats.o tc.o telecom.o tlv.o transport.o tsproc.o udp.o udp6.o \ - uds.o unicast_client.o unicast_fsm.o unicast_service.o util.o version.o +OBJ = bmc.o clock.o clockadj.o clockcheck.o config.o designated_fsm.o \ +e2e_tc.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 port_signaling.o pqueue.o print.o ptp4l.o p2p_tc.o \ +raw.o rtnl.o servo.o sk.o stats.o tc.o telecom.o tlv.o transport.o tsproc.o \ +udp.o udp6.o uds.o unicast_client.o unicast_fsm.o unicast_service.o util.o \ +version.o OBJECTS = $(OBJ) hwstamp_ctl.o nsm.o phc2sys.o phc_ctl.o pmc.o pmc_common.o \ sysoff.o timemaster.o diff --git a/port.c b/port.c index aabbf7d83677..d55ff86f34f7 100644 --- a/port.c +++ b/port.c @@ -27,6 +27,7 @@ #include "bmc.h" #include "clock.h" +#include "designated_fsm.h" #include "filter.h" #include "missing.h" #include "msg.h" @@ -1596,7 +1597,6 @@ int port_initialize(struct port *p) 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->master_only = config_get_int(cfg, p->name, "masterOnly"); p->localPriority = config_get_int(cfg, p->name, "G.8275.portDS.localPriority"); p->logSyncInterval = config_get_int(cfg, p->name, "logSyncInterval"); p->logMinPdelayReqInterval = config_get_int(cfg, p->name, "logMinPdelayReqInterval"); @@ -1635,6 +1635,14 @@ int port_initialize(struct port *p) /* No need to open rtnl socket on UDS port. */ if (transport_type(p->trp) != TRANS_UDS) { + /* + * The delay timer is usually started when the device + * transitions to PS_LISTENING. But, we are skipping the state + * when BMCA == 'noop'. So, start the timer here. + */ + if (p->bmca == BMCA_NOOP) { + port_set_delay_tmo(p); + } if (p->fda.fd[FD_RTNL] == -1) p->fda.fd[FD_RTNL] = rtnl_open(); if (p->fda.fd[FD_RTNL] >= 0) @@ -2472,6 +2480,7 @@ static enum fsm_event bc_event(struct port *p, int fd_index) if (p->best) fc_clear(p->best); port_set_announce_tmo(p); + port_clr_tmo(p->fda.fd[FD_SYNC_RX_TIMER]); delay_req_prune(p); if (clock_slave_only(p->clock) && p->delayMechanism != DM_P2P && port_renew_transport(p)) { @@ -2862,10 +2871,24 @@ struct port *port_open(int phc_index, goto err_port; } - p->state_machine = clock_slave_only(clock) ? ptp_slave_fsm : ptp_fsm; p->phc_index = phc_index; p->jbod = config_get_int(cfg, interface->name, "boundary_clock_jbod"); transport = config_get_int(cfg, interface->name, "network_transport"); + p->master_only = config_get_int(cfg, p->name, "masterOnly"); + p->bmca = config_get_int(cfg, p->name, "BMCA"); + + if (p->bmca == BMCA_NOOP && transport != TRANS_UDS) { + if (p->master_only) { + p->state_machine = designated_master_fsm; + } else if (clock_slave_only(clock)) { + p->state_machine = designated_slave_fsm; + } else { + pr_err("Please enable at least one of masterOnly or slaveOnly when BMCA == noop.\n"); + goto err_port; + } + } else { + p->state_machine = clock_slave_only(clock) ? ptp_slave_fsm : ptp_fsm; + } if (transport == TRANS_UDS) { ; /* UDS cannot have a PHC. */ @@ -3023,3 +3046,8 @@ int port_state_update(struct port *p, enum fsm_event event, int mdiff) return 0; } + +enum bmca_select port_bmca(struct port *p) +{ + return p->bmca; +} diff --git a/port.h b/port.h index 9639193d23d1..aa3b1ecf2529 100644 --- a/port.h +++ b/port.h @@ -323,6 +323,14 @@ void fault_interval(struct port *port, enum fault_type ft, struct fault_interval *i); /** + * Obtain the BMCA type of the port. + * + * @param port A port instance. + * @return bmca type. + */ +enum bmca_select port_bmca(struct port *p); + +/** * Release all of the memory in the TC transmit descriptor cache. */ void tc_cleanup(void); diff --git a/port_private.h b/port_private.h index 91e79867bf38..4b22976b57eb 100644 --- a/port_private.h +++ b/port_private.h @@ -97,6 +97,7 @@ struct port { unsigned int multiple_pdr_detected; enum port_state (*state_machine)(enum port_state state, enum fsm_event event, int mdiff); + int bmca; /* portDS */ struct PortIdentity portIdentity; enum port_state state; /*portState*/ diff --git a/ptp4l.8 b/ptp4l.8 index e840e748fb42..262fe2ed02bb 100644 --- a/ptp4l.8 +++ b/ptp4l.8 @@ -363,10 +363,7 @@ hardware time stamping. The default is 1 (enabled). .TP .B slaveOnly -The local clock is a slave-only clock if enabled. -This option is only for use with 1588 clocks and should not be enabled -for 802.1AS clocks. -The default is 0 (disabled). +The local clock is a slave-only clock if enabled. The default is 0 (disabled). .TP .B gmCapable If this option is enabled, then the local clock is able to become grand master. @@ -667,6 +664,18 @@ If set to 'true', all the checks which can unset asCapable variable (as described in Section 10.2.4.1 of 802.1AS) are skipped. If set to 'auto', asCapable is initialized to 'false' and will be set to 'true' after the relevant checks have passed. The default value is 'auto'. +.TP +.B BMCA +This option enables use of static roles for master and slave devices instead of +running the best master clock algorithm (BMCA) described in 1588 profile. This +is useful when you know the roles of the devices in advance. When set to +\'noop', the traditional BMCA algorithm used by 1588 is skipped. masterOnly and +slaveOnly will be used to determine master or slave role for the device. In a +bridge, slaveOnly (which is a global option) can be set to make all ports +assume the slave role. masterOnly (which is a per-port config option) can then +be used to set individual ports to take master role. BMCA is used in the +Automotive profile to speed up the start time for grand master and slaves. The +default value is 'ptp' which runs the BMCA related state machines. .SH UNICAST DISCOVERY OPTIONS -- 2.7.3 |
From: Vedang P. <ved...@in...> - 2018-09-26 21:58:11
|
This config option will skip the source port identity verification in the Sync and Follow_up messages. This option is needed when the announce messages are disabled because the slave cannot know the identity of master without announce messages. This is required by Automotive Profile as part of skipping the Best Master Clock Algorithm (BMCA). Signed-off-by: Vedang Patel <ved...@in...> --- config.c | 1 + configs/default.cfg | 1 + port.c | 22 ++++++++++++++++------ port_private.h | 1 + ptp4l.8 | 6 ++++++ 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/config.c b/config.c index cac0a74683c6..639ddc1290de 100644 --- a/config.c +++ b/config.c @@ -231,6 +231,7 @@ struct config_item config_tab[] = { PORT_ITEM_INT("G.8275.portDS.localPriority", 128, 1, UINT8_MAX), GLOB_ITEM_INT("gmCapable", 1, 0, 1), PORT_ITEM_INT("hybrid_e2e", 0, 0, 1), + PORT_ITEM_INT("ignore_source_id", 0, 0, 1), PORT_ITEM_INT("ignore_transport_specific", 0, 0, 1), PORT_ITEM_INT("ingressLatency", 0, INT_MIN, INT_MAX), PORT_ITEM_INT("inhibit_announce", 0, 0, 1), diff --git a/configs/default.cfg b/configs/default.cfg index c51da0345343..77b6e546de38 100644 --- a/configs/default.cfg +++ b/configs/default.cfg @@ -34,6 +34,7 @@ G.8275.portDS.localPriority 128 asCapable auto BMCA ptp inhibit_announce 0 +ignore_source_id 0 # # Run time options # diff --git a/port.c b/port.c index ea40b5c6a91a..f6266062619a 100644 --- a/port.c +++ b/port.c @@ -1593,6 +1593,7 @@ int port_initialize(struct port *p) p->peerMeanPathDelay = 0; p->logAnnounceInterval = config_get_int(cfg, p->name, "logAnnounceInterval"); p->inhibit_announce = config_get_int(cfg, p->name, "inhibit_announce"); + p->ignore_source_id = config_get_int(cfg, p->name, "ignore_source_id"); p->announceReceiptTimeout = config_get_int(cfg, p->name, "announceReceiptTimeout"); p->syncReceiptTimeout = config_get_int(cfg, p->name, "syncReceiptTimeout"); p->transportSpecific = config_get_int(cfg, p->name, "transportSpecific"); @@ -1880,10 +1881,20 @@ void process_delay_resp(struct port *p, struct ptp_message *m) port_set_delay_tmo(p); } +static int check_source_identity(struct port *p, struct ptp_message *m) +{ + struct PortIdentity master; + + if (p->ignore_source_id) { + return 0; + } + master = clock_parent_identity(p->clock); + return pid_eq(&master, &m->header.sourcePortIdentity) ? 0 : -1; +} + void process_follow_up(struct port *p, struct ptp_message *m) { enum syfu_event event; - struct PortIdentity master; switch (p->state) { case PS_INITIALIZING: case PS_FAULTY: @@ -1898,8 +1909,8 @@ void process_follow_up(struct port *p, struct ptp_message *m) case PS_SLAVE: break; } - master = clock_parent_identity(p->clock); - if (!pid_eq(&master, &m->header.sourcePortIdentity)) { + + if (check_source_identity(p, m)) { return; } @@ -2188,7 +2199,6 @@ void process_pdelay_resp_fup(struct port *p, struct ptp_message *m) void process_sync(struct port *p, struct ptp_message *m) { enum syfu_event event; - struct PortIdentity master; switch (p->state) { case PS_INITIALIZING: case PS_FAULTY: @@ -2203,8 +2213,8 @@ void process_sync(struct port *p, struct ptp_message *m) case PS_SLAVE: break; } - master = clock_parent_identity(p->clock); - if (!pid_eq(&master, &m->header.sourcePortIdentity)) { + + if (check_source_identity(p, m)) { return; } diff --git a/port_private.h b/port_private.h index ca3c906a0006..593eb76fbe48 100644 --- a/port_private.h +++ b/port_private.h @@ -99,6 +99,7 @@ struct port { enum fsm_event event, int mdiff); int bmca; int inhibit_announce; + int ignore_source_id; /* portDS */ struct PortIdentity portIdentity; enum port_state state; /*portState*/ diff --git a/ptp4l.8 b/ptp4l.8 index ee1d00b8bdd2..804e12cb7b61 100644 --- a/ptp4l.8 +++ b/ptp4l.8 @@ -684,6 +684,12 @@ by the Automotive profile as part of switching over to a static BMCA. if this option is enabled, ignore_source_id has to be enabled in the slave because it has no way to identify master identity in Sync and Follow_Up messages. The default is 0 (disabled). +.TP +.B ignore_source_port_id +This will disable source port identity checking for Sync and Follow_Up +messages. This is useful when the announce messages are disabled in the master +and the slave does not have any way to know it's identity. The default is 0 +(disabled). .SH UNICAST DISCOVERY OPTIONS -- 2.7.3 |