I vote to fix also pmc (that is just a tool) output. Also adding a new PUSH we break the pmc tools...
ciao luigi Il giorno ven 1 dic 2023 alle ore 09:03 Chwee-Lin Choong < chwee.lin.cho...@intel.com> ha scritto: > Add the computation for scaledLastGmFreqChange, as specified in > IEEE 802.1AS-2020, clause 11.4.4.3.9. This incorporates the > necessary logic to calculate scaledLastGmFreqChange and > appends the result to the follow-up TLV. > > In addition, a naming error has been rectified from > scaledLastGmPhaseChange to scaledLastGmFreqChange. > > v2: Maintain existing printed name 'scaledLastGmPhaseChange' > in pmc.c to avoid potential disruptions to users' setups. > > Signed-off-by: Tan Tee Min <tee.min....@linux.intel.com> > Signed-off-by: Chwee-Lin Choong <chwee.lin.cho...@intel.com> > --- > clock.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- > clock.h | 7 +++++++ > pmc.c | 2 +- > port.c | 5 +++-- > tlv.c | 8 ++++---- > tlv.h | 4 ++-- > 6 files changed, 72 insertions(+), 13 deletions(-) > > diff --git a/clock.c b/clock.c > index b66dda5..c24d496 100644 > --- a/clock.c > +++ b/clock.c > @@ -148,6 +148,7 @@ struct clock { > int step_window_counter; > int step_window; > struct time_zone tz[MAX_TIME_ZONES]; > + struct follow_up_info_tlv clksrc_fup_info; > }; > > struct clock the_clock; > @@ -544,13 +545,15 @@ static int clock_management_fill_response(struct > clock *c, struct port *p, > tsn->cumulativeScaledRateOffset = > (Integer32) (c->status.cumulativeScaledRateOffset + > c->nrr * POW2_41 - POW2_41); > - tsn->scaledLastGmPhaseChange = > c->status.scaledLastGmPhaseChange; > tsn->gmTimeBaseIndicator = c->status.gmTimeBaseIndicator; > tsn->lastGmPhaseChange = c->status.lastGmPhaseChange; > - if (cid_eq(&c->dad.pds.grandmasterIdentity, > &c->dds.clockIdentity)) > + if (cid_eq(&c->dad.pds.grandmasterIdentity, > &c->dds.clockIdentity)) { > tsn->gmPresent = 0; > - else > + tsn->scaledLastGmFreqChange = > c->clksrc_fup_info.scaledLastGmFreqChange; > + } else { > tsn->gmPresent = 1; > + tsn->scaledLastGmFreqChange = > c->status.scaledLastGmFreqChange; > + } > tsn->gmIdentity = c->dad.pds.grandmasterIdentity; > datalen = sizeof(*tsn); > break; > @@ -1289,6 +1292,7 @@ struct clock *clock_create(enum clock_type type, > struct config *config, > c->utc_offset = config_get_int(config, NULL, "utc_offset"); > c->time_source = config_get_int(config, NULL, "timeSource"); > c->step_window = config_get_int(config, NULL, "step_window"); > + memset(&c->clksrc_fup_info, 0 , sizeof(c->clksrc_fup_info)); > > if (c->free_running) { > c->clkid = CLOCK_INVALID; > @@ -1482,12 +1486,21 @@ struct port *clock_first_port(struct clock *c) > void clock_follow_up_info(struct clock *c, struct follow_up_info_tlv *f) > { > c->status.cumulativeScaledRateOffset = > f->cumulativeScaledRateOffset; > - c->status.scaledLastGmPhaseChange = f->scaledLastGmPhaseChange; > + c->status.scaledLastGmFreqChange = f->scaledLastGmFreqChange; > c->status.gmTimeBaseIndicator = f->gmTimeBaseIndicator; > memcpy(&c->status.lastGmPhaseChange, &f->lastGmPhaseChange, > sizeof(c->status.lastGmPhaseChange)); > } > > +void clock_set_follow_up_info(struct clock *c, struct follow_up_info_tlv > *f) > +{ > + if (cid_eq(&c->dad.pds.grandmasterIdentity, > &c->dds.clockIdentity)) { > + f->scaledLastGmFreqChange = > c->clksrc_fup_info.scaledLastGmFreqChange; > + } else { > + f->scaledLastGmFreqChange = > c->status.scaledLastGmFreqChange; > + } > +} > + > int clock_free_running(struct clock *c) > { > return c->free_running ? 1 : 0; > @@ -1991,6 +2004,42 @@ static int clock_synchronize_locked(struct clock > *c, double adj) > return 0; > } > > +void calculate_freq_change(struct clock *c, tmv_t ingress, tmv_t origin) > +{ > + struct freq_estimator *f = &c->fest; > + double ratio; > + > + /* > + * The ratio of the local clock freqency to the master clock > + * is estimated by: > + * > + * (origin_2 - origin_1) / (ingress_2 - ingress_1) > + * > + * Both of the origin time estimates include the path delay, > + * but we assume that the path delay is in fact constant. > + * By leaving out the path delay altogther, we can avoid the > + * error caused by our imperfect path delay measurement. > + */ > + if (tmv_is_zero(f->ingress1)) { > + f->ingress1 = ingress; > + f->origin1 = origin; > + return; > + } > + > + if (tmv_cmp(ingress, f->ingress1) == 0) { > + pr_warning("bad timestamps in rate ratio calculation"); > + return; > + } > + > + ratio = tmv_dbl(tmv_sub(origin, f->origin1)) / > + tmv_dbl(tmv_sub(ingress, f->ingress1)); > + > + c->clksrc_fup_info.scaledLastGmFreqChange = (Integer32)((ratio - > 1.0) * POW2_41); > + > + f->ingress1 = ingress; > + f->origin1 = origin; > +} > + > enum servo_state clock_synchronize(struct clock *c, tmv_t ingress, tmv_t > origin) > { > enum servo_state state = SERVO_UNLOCKED; > @@ -2023,6 +2072,8 @@ enum servo_state clock_synchronize(struct clock *c, > tmv_t ingress, tmv_t origin) > > c->cur.offsetFromMaster = tmv_to_TimeInterval(c->master_offset); > > + calculate_freq_change(c, ingress, origin); > + > if (c->free_running) { > state = clock_no_adjust(c, ingress, origin); > clock_notify_event(c, NOTIFY_TIME_SYNC); > diff --git a/clock.h b/clock.h > index ce9ae91..f17bea9 100644 > --- a/clock.h > +++ b/clock.h > @@ -150,6 +150,13 @@ struct port *clock_first_port(struct clock *c); > */ > void clock_follow_up_info(struct clock *c, struct follow_up_info_tlv *f); > > +/** > + * Set the follow_up info TLV for a slave port. > + * @param c The clock instance. > + * @param f Pointer to the TLV. > + */ > +void clock_set_follow_up_info(struct clock *c, struct follow_up_info_tlv > *f); > + > /** > * Determine if a clock is free running or not. > * @param c The clock instance. > diff --git a/pmc.c b/pmc.c > index 9faf790..b4b146f 100644 > --- a/pmc.c > +++ b/pmc.c > @@ -412,7 +412,7 @@ static void pmc_show(struct ptp_message *msg, FILE *fp) > tsn->master_offset, > tsn->ingress_time, > (tsn->cumulativeScaledRateOffset + 0.0) / P41, > - tsn->scaledLastGmPhaseChange, > + tsn->scaledLastGmFreqChange, > tsn->gmTimeBaseIndicator, > tsn->lastGmPhaseChange.nanoseconds_msb, > tsn->lastGmPhaseChange.nanoseconds_lsb, > diff --git a/port.c b/port.c > index 136d036..f94789b 100644 > --- a/port.c > +++ b/port.c > @@ -431,7 +431,7 @@ static int add_foreign_master(struct port *p, struct > ptp_message *m) > return broke_threshold || diff; > } > > -static int follow_up_info_append(struct ptp_message *m) > +static int follow_up_info_append(struct port *p, struct ptp_message *m) > { > struct follow_up_info_tlv *fui; > struct tlv_extra *extra; > @@ -445,6 +445,7 @@ static int follow_up_info_append(struct ptp_message *m) > fui->length = sizeof(*fui) - sizeof(fui->type) - > sizeof(fui->length); > memcpy(fui->id, ieee8021_id, sizeof(ieee8021_id)); > fui->subtype[2] = 1; > + clock_set_follow_up_info(p->clock, fui); > > return 0; > } > @@ -1781,7 +1782,7 @@ int port_tx_sync(struct port *p, struct address > *dst, uint16_t sequence_id) > fup->address = *dst; > fup->header.flagField[0] |= UNICAST; > } > - if (p->follow_up_info && follow_up_info_append(fup)) { > + if (p->follow_up_info && follow_up_info_append(p, fup)) { > pr_err("%s: append fup info failed", p->log_name); > err = -1; > goto out; > diff --git a/tlv.c b/tlv.c > index 9b82bd9..71619f0 100644 > --- a/tlv.c > +++ b/tlv.c > @@ -362,7 +362,7 @@ static int mgt_post_recv(struct management_tlv *m, > uint16_t data_len, > tsn->master_offset = net2host64(tsn->master_offset); > tsn->ingress_time = net2host64(tsn->ingress_time); > tsn->cumulativeScaledRateOffset = > ntohl(tsn->cumulativeScaledRateOffset); > - tsn->scaledLastGmPhaseChange = > ntohl(tsn->scaledLastGmPhaseChange); > + tsn->scaledLastGmFreqChange = > ntohl(tsn->scaledLastGmFreqChange); > tsn->gmTimeBaseIndicator = ntohs(tsn->gmTimeBaseIndicator); > scaled_ns_n2h(&tsn->lastGmPhaseChange); > tsn->gmPresent = ntohl(tsn->gmPresent); > @@ -582,7 +582,7 @@ static void mgt_pre_send(struct management_tlv *m, > struct tlv_extra *extra) > tsn->master_offset = host2net64(tsn->master_offset); > tsn->ingress_time = host2net64(tsn->ingress_time); > tsn->cumulativeScaledRateOffset = > htonl(tsn->cumulativeScaledRateOffset); > - tsn->scaledLastGmPhaseChange = > htonl(tsn->scaledLastGmPhaseChange); > + tsn->scaledLastGmFreqChange = > htonl(tsn->scaledLastGmFreqChange); > tsn->gmTimeBaseIndicator = htons(tsn->gmTimeBaseIndicator); > scaled_ns_h2n(&tsn->lastGmPhaseChange); > tsn->gmPresent = htonl(tsn->gmPresent); > @@ -798,7 +798,7 @@ static int org_post_recv(struct organization_tlv *org) > f->cumulativeScaledRateOffset = > ntohl(f->cumulativeScaledRateOffset); > f->gmTimeBaseIndicator = > ntohs(f->gmTimeBaseIndicator); > scaled_ns_n2h(&f->lastGmPhaseChange); > - f->scaledLastGmPhaseChange = > ntohl(f->scaledLastGmPhaseChange); > + f->scaledLastGmFreqChange = > ntohl(f->scaledLastGmFreqChange); > break; > > case 2: > @@ -860,7 +860,7 @@ static void org_pre_send(struct organization_tlv *org) > f->cumulativeScaledRateOffset = > htonl(f->cumulativeScaledRateOffset); > f->gmTimeBaseIndicator = > htons(f->gmTimeBaseIndicator); > scaled_ns_h2n(&f->lastGmPhaseChange); > - f->scaledLastGmPhaseChange = > htonl(f->scaledLastGmPhaseChange); > + f->scaledLastGmFreqChange = > htonl(f->scaledLastGmFreqChange); > break; > } > } else if (0 == memcmp(org->id, itu_t_id, sizeof(itu_t_id))) { > diff --git a/tlv.h b/tlv.h > index 8b51ffd..ce87c72 100644 > --- a/tlv.h > +++ b/tlv.h > @@ -331,7 +331,7 @@ struct follow_up_info_tlv { > Integer32 cumulativeScaledRateOffset; > UInteger16 gmTimeBaseIndicator; > ScaledNs lastGmPhaseChange; > - Integer32 scaledLastGmPhaseChange; > + Integer32 scaledLastGmFreqChange; > } PACKED; > > struct ieee_c37_238_2011_tlv { > @@ -380,7 +380,7 @@ struct time_status_np { > int64_t master_offset; /*nanoseconds*/ > int64_t ingress_time; /*nanoseconds*/ > Integer32 cumulativeScaledRateOffset; > - Integer32 scaledLastGmPhaseChange; > + Integer32 scaledLastGmFreqChange; > UInteger16 gmTimeBaseIndicator; > ScaledNs lastGmPhaseChange; > Integer32 gmPresent; > -- > 2.42.0 > > > > _______________________________________________ > Linuxptp-devel mailing list > Linuxptp-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/linuxptp-devel > -- *Luigi 'Comio' Mantellini* My Professional Profile <http://www.linkedin.com/in/comio> *"UNIX is very simple, it just needs a genius to understand its simplicity." [cit.]*
_______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel