On Thu, 23 Nov 2023 at 04:26, Chwee-Lin Choong <chwee.lin.cho...@intel.com>
wrote:

> 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.
>

It might be an error, but we do not change a public API.
As some users might depend on it.
You can add a new management TLV if you find it drastic.
Or just add an explanation in the header where the TLV is defined.

Erez



>
> 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   |  4 ++--
>  port.c  |  5 +++--
>  tlv.c   |  8 ++++----
>  tlv.h   |  4 ++--
>  6 files changed, 73 insertions(+), 14 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..97ea3d2 100644
> --- a/pmc.c
> +++ b/pmc.c
> @@ -404,7 +404,7 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
>                         IFMT "master_offset              %" PRId64
>                         IFMT "ingress_time               %" PRId64
>                         IFMT "cumulativeScaledRateOffset %+.9f"
> -                       IFMT "scaledLastGmPhaseChange    %d"
> +                       IFMT "scaledLastGmFreqChange     %d"
>                         IFMT "gmTimeBaseIndicator        %hu"
>                         IFMT "lastGmPhaseChange          0x%04hx'%016"
> PRIx64 ".%04hx"
>                         IFMT "gmPresent                  %s"
> @@ -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 61d03d4..f99ef4c 100644
> --- a/port.c
> +++ b/port.c
> @@ -432,7 +432,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;
> @@ -446,6 +446,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;
>  }
> @@ -1782,7 +1783,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
>
_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to