Hi Richard, Regarding to the time-aware bridge support, I have 4 patches in using now. (This one is the main one of them.)
https://github.com/openil/linuxptp/commit/087580e4ae3d3e8cd57c8cb5c990baf4bfec7011 https://github.com/openil/linuxptp/commit/a616939fd0f46f84a270503ac8482e69279f7814 https://github.com/openil/linuxptp/commit/babe7c8dc4875bb9cedc04f499c9395436ec2729 https://github.com/openil/linuxptp/commit/eee6d0fb995dddf27acde2addfb1fe89b71ab82d May I know your opinion on time-aware bridge support? So that I can know whether I should improve them and send new version for reviewing. Thanks a lot. Best regards, Yangbo Lu > -----Original Message----- > From: Yangbo Lu <yangbo...@nxp.com> > Sent: Monday, October 14, 2019 6:27 PM > To: linuxptp-devel@lists.sourceforge.net; Rodney Cummings > <rodney.cummi...@ni.com>; Richard Cochran <richardcoch...@gmail.com>; > Erik Hons <erik.h...@ni.com> > Cc: Y.b. Lu <yangbo...@nxp.com> > Subject: [RFC V2] Add IEEE 802.1AS-2011 time-aware bridge support > > This patch is to add IEEE 802.1AS-2011 time-aware bridge support > based on current BC clock type. It implements only time information > relay, and BMCA was not touched. To run it, the profile gPTP.cfg could > be used with multiple interfaces specified using -i option. > > The main code changes are, > - Create syfu_relay_info structure for time information relay. > - Implement port_syfu_relay_info_insert() to update follow_up (with TLV) > message with time information for relay. > > Signed-off-by: Yangbo Lu <yangbo...@nxp.com> > --- > Changes for v2: > - Implemented based on BC instead of TC. > --- > clock.c | 43 ++++++++++++++++++++++++++++++++++++- > clock.h | 45 +++++++++++++++++++++++++++++++++++++++ > port.c | 75 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- > 3 files changed, 158 insertions(+), 5 deletions(-) > > diff --git a/clock.c b/clock.c > index 146576a..1865ecb 100644 > --- a/clock.c > +++ b/clock.c > @@ -45,7 +45,6 @@ > #include "util.h" > > #define N_CLOCK_PFD (N_POLLFD + 1) /* one extra per port, for the fault > timer */ > -#define POW2_41 ((double)(1ULL << 41)) > > struct port { > LIST_ENTRY(port) list; > @@ -123,6 +122,7 @@ struct clock { > int stats_interval; > struct clockcheck *sanity_check; > struct interface uds_interface; > + struct syfu_relay_info syfu_relay; > LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers; > }; > > @@ -1117,6 +1117,8 @@ struct clock *clock_create(enum clock_type type, > struct config *config, > } > } > > + memset(&c->syfu_relay, 0, sizeof(struct syfu_relay_info)); > + > /* Initialize the parentDS. */ > clock_update_grandmaster(c); > c->dad.pds.parentStats = 0; > @@ -1208,6 +1210,15 @@ void clock_follow_up_info(struct clock *c, struct > follow_up_info_tlv *f) > sizeof(c->status.lastGmPhaseChange)); > } > > +static void clock_get_follow_up_info(struct clock *c, struct > follow_up_info_tlv *f) > +{ > + f->cumulativeScaledRateOffset = c->status.cumulativeScaledRateOffset; > + f->scaledLastGmPhaseChange = c->status.scaledLastGmPhaseChange; > + f->gmTimeBaseIndicator = c->status.gmTimeBaseIndicator; > + memcpy(&f->lastGmPhaseChange, &c->status.lastGmPhaseChange, > + sizeof(f->lastGmPhaseChange)); > +} > + > int clock_free_running(struct clock *c) > { > return c->free_running ? 1 : 0; > @@ -1583,6 +1594,16 @@ void clock_peer_delay(struct clock *c, tmv_t ppd, > tmv_t req, tmv_t rx, > stats_add_value(c->stats.delay, tmv_dbl(ppd)); > } > > +tmv_t clock_get_path_delay(struct clock *c) > +{ > + return c->path_delay; > +} > + > +double clock_get_nrr(struct clock *c) > +{ > + return c->nrr; > +} > + > int clock_slave_only(struct clock *c) > { > return c->dds.flags & DDS_SLAVE_ONLY; > @@ -1776,6 +1797,7 @@ static void handle_state_decision_event(struct > clock *c) > c->path_delay = c->initial_delay; > c->nrr = 1.0; > fresh_best = 1; > + clock_disable_syfu_relay(c); > } > > c->best = best; > @@ -1847,3 +1869,22 @@ enum servo_state clock_servo_state(struct clock > *c) > { > return c->servo_state; > } > + > +void clock_prepare_syfu_relay(struct clock *c, struct ptp_message *sync, > + struct ptp_message *fup) > +{ > + c->syfu_relay.precise_origin_ts = timestamp_to_tmv(fup->ts.pdu); > + c->syfu_relay.correction = fup->header.correction; > + clock_get_follow_up_info(c, &c->syfu_relay.fup_info_tlv); > + c->syfu_relay.avail = 1; > +} > + > +void clock_disable_syfu_relay(struct clock *c) > +{ > + c->syfu_relay.avail = 0; > +} > + > +struct syfu_relay_info *clock_get_syfu_relay(struct clock *c) > +{ > + return &c->syfu_relay; > +} > diff --git a/clock.h b/clock.h > index 9d3133a..8ff1181 100644 > --- a/clock.h > +++ b/clock.h > @@ -29,8 +29,18 @@ > #include "tmv.h" > #include "transport.h" > > +#define POW2_41 ((double)(1ULL << 41)) > + > struct ptp_message; /*forward declaration*/ > > +struct syfu_relay_info { > + tmv_t precise_origin_ts; > + Integer64 correction; > + struct follow_up_info_tlv fup_info_tlv; > + /* Auxiliary info */ > + int avail; > +}; > + > /** Opaque type. */ > struct clock; > > @@ -240,6 +250,20 @@ void clock_peer_delay(struct clock *c, tmv_t ppd, > tmv_t req, tmv_t rx, > double nrr); > > /** > + * Get the path delay as measured on a slave port. > + * @param c The clock instance. > + * @return The path delay as measured on a slave port. > + */ > +tmv_t clock_get_path_delay(struct clock *c); > + > +/** > + * Get the neighbor rate ratio as measured on a slave port. > + * @param c The clock instance. > + * @return The neighbor rate ratio as measured on a slave port. > + */ > +double clock_get_nrr(struct clock *c); > + > +/** > * Set clock sde > * @param c A pointer to a clock instance obtained with clock_create(). > * @param sde Pass one (1) if need a decision event and zero if not. > @@ -359,4 +383,25 @@ void clock_check_ts(struct clock *c, uint64_t ts); > */ > double clock_rate_ratio(struct clock *c); > > +/** > + * Prepare sync/follow_up relay. > + * @param c The clock instance. > + * @param sync The sync message. > + * @param fup The follow_up message. > + */ > +void clock_prepare_syfu_relay(struct clock *c, struct ptp_message *sync, > + struct ptp_message *fup); > + > +/** > + * Disable sync/follow_up relay. > + * @param c The clock instance. > + */ > +void clock_disable_syfu_relay(struct clock *c); > + > +/** > + * Get sync/follow_up relay information. > + * @param c The clock instance. > + * @return The sync/follow_up relay information. > + */ > +struct syfu_relay_info *clock_get_syfu_relay(struct clock *c); > #endif > diff --git a/port.c b/port.c > index 07ad3f0..073e71a 100644 > --- a/port.c > +++ b/port.c > @@ -1241,6 +1241,10 @@ static void port_syfufsm(struct port *p, enum > syfu_event event, > break; > case FUP_MATCH: > syn = p->last_syncfup; > + if (p->follow_up_info) > + clock_prepare_syfu_relay(p->clock, syn, m); > + else > + clock_disable_syfu_relay(p->clock); > port_synchronize(p, syn->hwts.ts, m->ts.pdu, > syn->header.correction, > m->header.correction, > @@ -1261,6 +1265,10 @@ static void port_syfufsm(struct port *p, enum > syfu_event event, > break; > case SYNC_MATCH: > fup = p->last_syncfup; > + if (p->follow_up_info) > + clock_prepare_syfu_relay(p->clock, m, fup); > + else > + clock_disable_syfu_relay(p->clock); > port_synchronize(p, m->hwts.ts, fup->ts.pdu, > m->header.correction, > fup->header.correction, > @@ -1450,6 +1458,60 @@ int port_tx_announce(struct port *p, struct > address *dst) > return err; > } > > +static void port_syfu_relay_info_insert(struct port *p, > + struct ptp_message *sync, > + struct ptp_message *fup) > +{ > + struct syfu_relay_info *syfu_relay = clock_get_syfu_relay(p->clock); > + struct follow_up_info_tlv *fui_relay = &syfu_relay->fup_info_tlv; > + struct follow_up_info_tlv *fui = follow_up_info_extract(fup); > + tmv_t ingress, egress, residence, path_delay; > + double gm_rr, nrr, rr; > + struct timestamp ts; > + > + if (syfu_relay->avail == 0) > + return; > + > + fup->follow_up.preciseOriginTimestamp = > + tmv_to_Timestamp(syfu_relay->precise_origin_ts); > + fup->header.correction = syfu_relay->correction; > + > + /* Calculate residence time. */ > + ingress = clock_ingress_time(p->clock); > + egress = sync->hwts.ts; > + residence = tmv_sub(egress, ingress); > + rr = clock_rate_ratio(p->clock); > + if (rr != 1.0) { > + residence = dbl_tmv(tmv_dbl(residence) * rr); > + } > + > + gm_rr = 1.0 + (fui_relay->cumulativeScaledRateOffset + 0.0) / POW2_41; > + nrr = clock_get_nrr(p->clock); > + > + /* Add corrected residence time into correction. */ > + fup->header.correction += tmv_to_TimeInterval(residence) * gm_rr * nrr; > + > + /* Add corrected path delay into correction. */ > + path_delay = clock_get_path_delay(p->clock); > + fup->header.correction += tmv_to_TimeInterval(path_delay) * gm_rr; > + > + /* Update follow_up TLV */ > + gm_rr *= nrr; > + fui->cumulativeScaledRateOffset = gm_rr * POW2_41 - POW2_41; > + fui->scaledLastGmPhaseChange = fui_relay->scaledLastGmPhaseChange; > + fui->gmTimeBaseIndicator = fui_relay->gmTimeBaseIndicator; > + memcpy(&fui->lastGmPhaseChange, &fui_relay->lastGmPhaseChange, > + sizeof(fui->lastGmPhaseChange)); > + > + ts.sec = fup->follow_up.preciseOriginTimestamp.seconds_msb; > + ts.sec = ts.sec << 32 | > fup->follow_up.preciseOriginTimestamp.seconds_lsb; > + ts.nsec = fup->follow_up.preciseOriginTimestamp.nanoseconds; > + pr_debug("port %hu: syfu_relay info:", portnum(p)); > + pr_debug("port %hu: precise_origin_ts %" PRIu64 ".%u", portnum(p), > ts.sec, ts.nsec); > + pr_debug("port %hu: correction %" PRId64, portnum(p), > fup->header.correction >> 16); > + pr_debug("port %hu: fup_info %.9f", portnum(p), gm_rr); > +} > + > int port_tx_sync(struct port *p, struct address *dst) > { > struct ptp_message *msg, *fup; > @@ -1543,10 +1605,15 @@ int port_tx_sync(struct port *p, struct address > *dst) > fup->address = *dst; > fup->header.flagField[0] |= UNICAST; > } > - if (p->follow_up_info && follow_up_info_append(fup)) { > - pr_err("port %hu: append fup info failed", portnum(p)); > - err = -1; > - goto out; > + > + if (p->follow_up_info) { > + if (follow_up_info_append(fup)) { > + pr_err("port %hu: append fup info failed", portnum(p)); > + err = -1; > + goto out; > + } > + > + port_syfu_relay_info_insert(p, msg, fup); > } > > err = port_prepare_and_send(p, fup, TRANS_GENERAL); > -- > 2.7.4 _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel