Re: [Linuxptp-devel] [PATCH 1/4] [Interface Rate TLV] function to support get interface speed via ethtool

2022-07-26 Thread Geva, Erez
Looking in the kernel code.

The link mode mask are mandatory for the get_link_ksettings() call-back, the 
driver is require to fill them.

The size is fixed to __ETHTOOL_LINK_MODE_MASK_NU32.

>From kernel net/ethtool/ioctl.c: 
>https://elixir.bootlin.com/linux/latest/source/net/ethtool/ioctl.c#L536

if (__ETHTOOL_LINK_MODE_MASK_NU32 != link_ksettings.base.link_mode_masks_nwords)
link_ksettings.base.link_mode_masks_nwords = 
-((s8)__ETHTOOL_LINK_MODE_MASK_NU32);
return  0;  // without information

link_ksettings.base.link_mode_masks_nwords = __ETHTOOL_LINK_MODE_MASK_NU32);
Call driver get_link_ksettings() and fill the link setting + link mode arrays.
Return 0;

As  __ETHTOOL_LINK_MODE_MASK_NU32 = 
DIV_ROUND_UP(__ETHTOOL_LINK_MODE_MASK_NBITS, 32)
And __ETHTOOL_LINK_MODE_MASK_ NBITS is defined in ethtool.h

We can start
ecmd.req.link_mode_masks_nwords = ceil(__ETHTOOL_LINK_MODE_MASK_NU32/32)

And check if the first return ecmd.req.link_mode_masks_nwords is negative, than 
we need a second call.
But if ecmd.req.link_mode_masks_nwords is positive. Than we should have the 
proper speed: ecmd.req.speed.

Please add a remark that the link_mode_data array contain 3 arrays: 
supported[], advertising[], lp_advertising[]

Another, good to know, the speed can be find in the sysfs:
/sys/class/net//speed
Though, the sysfs is not mandatory, and could be mount in a different mount 
point.

Erez


From: Devasish Dey 
Sent: Tuesday, 26 July 2022 18:38
To: Erez 
Cc: Leon Goldin ; 
linuxptp-devel@lists.sourceforge.net
Subject: Re: [Linuxptp-devel] [PATCH 1/4] [Interface Rate TLV] function to 
support get interface speed via ethtool

Hi Erez,


> I am confused.
> Why do you ask for the link_mode_data, if you do not use it?
> Wouldn't the ethtool_link_settings contain all the information we need here?

Unfortunately, the ioctl call returns speed as 0 with ethtool_link_settings. So 
we had to use ecmd.

Thanks,
Devasish Dey
SyncMonk Technologies,
www.syncmonk.net

On Tue, 26 Jul 2022 at 18:38, Erez 
mailto:erezge...@gmail.com>> wrote:


On Tue, 26 Jul 2022 at 14:27, SyncMonk Technologies 
mailto:servi...@syncmonk.net>> wrote:
When master and slave instance interacting with each other operating
at different interface speed, delay assymetry needs to be compensated
as described in G.8271 appendix V.

In this patch we are adding changes to get the interface speed using
ethtool.

Signed-off-by: Greg Armstrong 
mailto:greg.armstrong...@renesas.com>>
Signed-off-by: Leon Goldin 
mailto:leon.goldin...@renesas.com>>
Signed-off-by: Devasish Dey 
mailto:devasish@syncmonk.net>>
Signed-off-by: Vipin Sharma 
mailto:vipin.sha...@syncmonk.net>>
---
 sk.c | 65 
 sk.h | 18 +
 2 files changed, 83 insertions(+)

diff --git a/sk.c b/sk.c
index 80075be..7df14db 100644
--- a/sk.c
+++ b/sk.c
@@ -205,6 +205,71 @@ failed:
return -1;
 }

+int sk_get_if_info(const char *name, struct sk_if_info *if_info)
+{
+#ifdef ETHTOOL_GLINKSETTINGS
+   struct ifreq ifr;
+   int fd, err;
+
+   struct {
+   struct ethtool_link_settings req;
+   __u32 link_mode_data[3 * 127];

Although __ETHTOOL_LINK_MODE_MASK_NBITS = 92.
I understand you roundup to 0x7f, for future use.

Please add a proper remark about `link_mode_data` size.
Say it consists of supported[], advertising[], lp_advertising[] with size up to 
127 ech.
The actual size is provided by the kernel.


+   } ecmd;
+
+   memset(, 0, sizeof(ifr));
+   memset(, 0, sizeof(ecmd));

Though sk_get_ts_info() uses the same order.
The memset can be after calling socket, in case of error.

+
+   fd = socket(AF_INET, SOCK_DGRAM, 0);
+   if (fd < 0) {
+   goto failed;
+   }
+
+   ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
+
+   strncpy(ifr.ifr_name, name, IFNAMSIZ - 1);
+   ifr.ifr_data = (char *) 
+
+   /* Handshake with kernel to determine number of words for link
+* mode bitmaps. When requested number of bitmap words is not
+* the one expected by kernel, the latter returns the integer
+* opposite of what it is expecting. We request length 0 below
+* (aka. invalid bitmap length) to get this info.
+*/
+   err = ioctl(fd, SIOCETHTOOL, );
+   if (err < 0) {
+   pr_err("ioctl SIOCETHTOOL failed: %m");
+   close(fd);
+   goto failed;
+   }
+
+   if (ecmd.req.link_mode_masks_nwords >= 0 ||
+   ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) {
+   

Re: [Linuxptp-devel] [PATCH 1/4] [Interface Rate TLV] function to support get interface speed via ethtool

2022-07-26 Thread Devasish Dey
Hi Erez,


> I am confused.
> Why do you ask for the link_mode_data, if you do not use it?
> Wouldn't the ethtool_link_settings contain all the information we need
here?

Unfortunately, the ioctl call returns speed as 0 with
ethtool_link_settings. So we had to use ecmd.

Thanks,
Devasish Dey
SyncMonk Technologies,
www.syncmonk.net

On Tue, 26 Jul 2022 at 18:38, Erez  wrote:

>
>
> On Tue, 26 Jul 2022 at 14:27, SyncMonk Technologies 
> wrote:
>
>> When master and slave instance interacting with each other operating
>> at different interface speed, delay assymetry needs to be compensated
>> as described in G.8271 appendix V.
>>
>> In this patch we are adding changes to get the interface speed using
>> ethtool.
>>
>> Signed-off-by: Greg Armstrong 
>> Signed-off-by: Leon Goldin 
>> Signed-off-by: Devasish Dey 
>> Signed-off-by: Vipin Sharma 
>> ---
>>  sk.c | 65 
>>  sk.h | 18 +
>>  2 files changed, 83 insertions(+)
>>
>> diff --git a/sk.c b/sk.c
>> index 80075be..7df14db 100644
>> --- a/sk.c
>> +++ b/sk.c
>> @@ -205,6 +205,71 @@ failed:
>> return -1;
>>  }
>>
>> +int sk_get_if_info(const char *name, struct sk_if_info *if_info)
>> +{
>> +#ifdef ETHTOOL_GLINKSETTINGS
>> +   struct ifreq ifr;
>> +   int fd, err;
>> +
>> +   struct {
>> +   struct ethtool_link_settings req;
>> +   __u32 link_mode_data[3 * 127];
>>
>
> Although __ETHTOOL_LINK_MODE_MASK_NBITS = 92.
> I understand you roundup to 0x7f, for future use.
>
> Please add a proper remark about `link_mode_data` size.
> Say it consists of supported[], advertising[], lp_advertising[] with size
> up to 127 ech.
> The actual size is provided by the kernel.
>
>
> +   } ecmd;
>> +
>> +   memset(, 0, sizeof(ifr));
>> +   memset(, 0, sizeof(ecmd));
>>
>
> Though sk_get_ts_info() uses the same order.
> The memset can be after calling socket, in case of error.
>
>
>> +
>> +   fd = socket(AF_INET, SOCK_DGRAM, 0);
>> +   if (fd < 0) {
>> +   goto failed;
>> +   }
>> +
>> +   ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
>> +
>> +   strncpy(ifr.ifr_name, name, IFNAMSIZ - 1);
>> +   ifr.ifr_data = (char *) 
>> +
>> +   /* Handshake with kernel to determine number of words for link
>> +* mode bitmaps. When requested number of bitmap words is not
>> +* the one expected by kernel, the latter returns the integer
>> +* opposite of what it is expecting. We request length 0 below
>> +* (aka. invalid bitmap length) to get this info.
>> +*/
>> +   err = ioctl(fd, SIOCETHTOOL, );
>> +   if (err < 0) {
>> +   pr_err("ioctl SIOCETHTOOL failed: %m");
>> +   close(fd);
>> +   goto failed;
>> +   }
>> +
>> +   if (ecmd.req.link_mode_masks_nwords >= 0 ||
>> +   ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) {
>> +   return 1;
>> +   }
>> +   ecmd.req.link_mode_masks_nwords =
>> -ecmd.req.link_mode_masks_nwords;
>>
>
> I am confused.
> Why do you ask for the link_mode_data, if you do not use it?
> Wouldn't the ethtool_link_settings contain all the information we need
> here?
>
>
>> +
>> +   err = ioctl(fd, SIOCETHTOOL, );
>> +   if (err < 0) {
>> +   pr_err("ioctl SIOCETHTOOL failed: %m");
>> +   close(fd);
>> +   goto failed;
>> +   }
>> +
>> +   close(fd);
>> +
>> +   /* copy the necessary data to sk_info */
>> +   memset(if_info, 0, sizeof(struct sk_if_info));
>> +   if_info->valid = 1;
>> +   if_info->speed = ecmd.req.speed;
>> +
>> +   return 0;
>> +failed:
>> +#endif
>> +   /* clear data and ensure it is not marked valid */
>> +   memset(if_info, 0, sizeof(struct sk_if_info));
>> +   return -1;
>> +}
>> +
>>  static int sk_interface_guidaddr(const char *name, unsigned char *guid)
>>  {
>> char file_name[64], buf[64], addr[8];
>> diff --git a/sk.h b/sk.h
>> index 486dbc4..853aadf 100644
>> --- a/sk.h
>> +++ b/sk.h
>> @@ -49,6 +49,16 @@ struct sk_ts_info {
>> unsigned int rx_filters;
>>  };
>>
>> +/**
>> + * Contains interface information returned by theGLINKSETTINGS ioctl.
>> + * @valid:set to non-zero when the info struct contains
>> valid data.
>> + * @speed:interface speed.
>> + */
>> +struct sk_if_info {
>> +   int valid;
>> +   int speed;
>> +};
>> +
>>  /**
>>   * Obtains a socket suitable for use with sk_interface_index().
>>   * @return  An open socket on success, -1 otherwise.
>> @@ -78,6 +88,14 @@ int sk_general_init(int fd);
>>   */
>>  int sk_get_ts_info(const char *name, struct sk_ts_info *sk_info);
>>
>> +/**
>> + * Obtain supporte interface information
>> + * @param name The name of the interface
>> + * @param info  Struct containing obtained interface information.
>> + * @return  zero on success, negative on failure.
>> + */
>> +int 

Re: [Linuxptp-devel] [PATCH 1/4] [Interface Rate TLV] function to support get interface speed via ethtool

2022-07-26 Thread Erez
On Tue, 26 Jul 2022 at 14:27, SyncMonk Technologies 
wrote:

> When master and slave instance interacting with each other operating
> at different interface speed, delay assymetry needs to be compensated
> as described in G.8271 appendix V.
>
> In this patch we are adding changes to get the interface speed using
> ethtool.
>
> Signed-off-by: Greg Armstrong 
> Signed-off-by: Leon Goldin 
> Signed-off-by: Devasish Dey 
> Signed-off-by: Vipin Sharma 
> ---
>  sk.c | 65 
>  sk.h | 18 +
>  2 files changed, 83 insertions(+)
>
> diff --git a/sk.c b/sk.c
> index 80075be..7df14db 100644
> --- a/sk.c
> +++ b/sk.c
> @@ -205,6 +205,71 @@ failed:
> return -1;
>  }
>
> +int sk_get_if_info(const char *name, struct sk_if_info *if_info)
> +{
> +#ifdef ETHTOOL_GLINKSETTINGS
> +   struct ifreq ifr;
> +   int fd, err;
> +
> +   struct {
> +   struct ethtool_link_settings req;
> +   __u32 link_mode_data[3 * 127];
>

Although __ETHTOOL_LINK_MODE_MASK_NBITS = 92.
I understand you roundup to 0x7f, for future use.

Please add a proper remark about `link_mode_data` size.
Say it consists of supported[], advertising[], lp_advertising[] with size
up to 127 ech.
The actual size is provided by the kernel.


+   } ecmd;
> +
> +   memset(, 0, sizeof(ifr));
> +   memset(, 0, sizeof(ecmd));
>

Though sk_get_ts_info() uses the same order.
The memset can be after calling socket, in case of error.


> +
> +   fd = socket(AF_INET, SOCK_DGRAM, 0);
> +   if (fd < 0) {
> +   goto failed;
> +   }
> +
> +   ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
> +
> +   strncpy(ifr.ifr_name, name, IFNAMSIZ - 1);
> +   ifr.ifr_data = (char *) 
> +
> +   /* Handshake with kernel to determine number of words for link
> +* mode bitmaps. When requested number of bitmap words is not
> +* the one expected by kernel, the latter returns the integer
> +* opposite of what it is expecting. We request length 0 below
> +* (aka. invalid bitmap length) to get this info.
> +*/
> +   err = ioctl(fd, SIOCETHTOOL, );
> +   if (err < 0) {
> +   pr_err("ioctl SIOCETHTOOL failed: %m");
> +   close(fd);
> +   goto failed;
> +   }
> +
> +   if (ecmd.req.link_mode_masks_nwords >= 0 ||
> +   ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) {
> +   return 1;
> +   }
> +   ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords;
>

I am confused.
Why do you ask for the link_mode_data, if you do not use it?
Wouldn't the ethtool_link_settings contain all the information we need here?


> +
> +   err = ioctl(fd, SIOCETHTOOL, );
> +   if (err < 0) {
> +   pr_err("ioctl SIOCETHTOOL failed: %m");
> +   close(fd);
> +   goto failed;
> +   }
> +
> +   close(fd);
> +
> +   /* copy the necessary data to sk_info */
> +   memset(if_info, 0, sizeof(struct sk_if_info));
> +   if_info->valid = 1;
> +   if_info->speed = ecmd.req.speed;
> +
> +   return 0;
> +failed:
> +#endif
> +   /* clear data and ensure it is not marked valid */
> +   memset(if_info, 0, sizeof(struct sk_if_info));
> +   return -1;
> +}
> +
>  static int sk_interface_guidaddr(const char *name, unsigned char *guid)
>  {
> char file_name[64], buf[64], addr[8];
> diff --git a/sk.h b/sk.h
> index 486dbc4..853aadf 100644
> --- a/sk.h
> +++ b/sk.h
> @@ -49,6 +49,16 @@ struct sk_ts_info {
> unsigned int rx_filters;
>  };
>
> +/**
> + * Contains interface information returned by theGLINKSETTINGS ioctl.
> + * @valid:set to non-zero when the info struct contains valid
> data.
> + * @speed:interface speed.
> + */
> +struct sk_if_info {
> +   int valid;
> +   int speed;
> +};
> +
>  /**
>   * Obtains a socket suitable for use with sk_interface_index().
>   * @return  An open socket on success, -1 otherwise.
> @@ -78,6 +88,14 @@ int sk_general_init(int fd);
>   */
>  int sk_get_ts_info(const char *name, struct sk_ts_info *sk_info);
>
> +/**
> + * Obtain supporte interface information
> + * @param name The name of the interface
> + * @param info  Struct containing obtained interface information.
> + * @return  zero on success, negative on failure.
> + */
> +int sk_get_if_info(const char *name, struct sk_if_info *sk_info);
> +
>  /**
>   * Obtain the MAC address of a network interface.
>   * @param name  The name of the interface
> --
> 2.17.1
>
>
>
> ___
> 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


Re: [Linuxptp-devel] [PATCH 3/3] [Interface Rate TLV] adding TLV support

2022-07-26 Thread Devasish Dey
Hi Miroslav,

Please find the answers to the queries.

Thanks,
Devasish Dey
SyncMonk Technologies.
www.syncmonk.net



> > --- a/config.c
> > +++ b/config.c
> > @@ -240,6 +240,7 @@ struct config_item config_tab[] = {
> >   GLOB_ITEM_ENU("clock_type", CLOCK_TYPE_ORDINARY, clock_type_enu),
> >   GLOB_ITEM_ENU("dataset_comparison", DS_CMP_IEEE1588,
> dataset_comp_enu),
> >   PORT_ITEM_INT("delayAsymmetry", 0, INT_MIN, INT_MAX),
> > + GLOB_ITEM_INT("interface_rate_tlv", 0, 0, 1),
>
> Why is it not a port-specific option? If you reject a suggestion, it's
> a good practice to explain your reasoning.
>
[Devasish]:  It is for TLV support and this seems to me as a device
feature.
Anyways if the peer device or port doesn't support the TLV it gets ignored.


>
> > + if (delayAsymmetry != p->portAsymmetry) {
> > + /* Updating the nanosecond part */
>
> This comment is confusing to me.
>
 [Devasish]: This was meant for the correction field updation, which
consists of
nanosecond and sub-nanosecond parts. Since the delay was in ns the comment
was
for LSH 16. Removed it now.

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


[Linuxptp-devel] [PATCH 3/4] [Interface Rate TLV] organization TLV support for interface rate

2022-07-26 Thread SyncMonk Technologies
adding interface rate TLV as defined by ITU-T G.8275.2 Annex D to
enable master to communicate PTP port interface rate to slave.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 clock.c  |  7 +++
 clock.h  |  7 +++
 config.c |  1 +
 pdt.h|  1 +
 tlv.c|  1 +
 tlv.h| 14 ++
 6 files changed, 31 insertions(+)

diff --git a/clock.c b/clock.c
index de69c52..cee469b 100644
--- a/clock.c
+++ b/clock.c
@@ -137,6 +137,7 @@ struct clock {
struct monitor *slave_event_monitor;
int step_window_counter;
int step_window;
+   bool iface_rate_tlv;
 };
 
 struct clock the_clock;
@@ -1106,6 +1107,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");
+   c->iface_rate_tlv = config_get_int(config, NULL, "interface_rate_tlv");
 
if (c->free_running) {
c->clkid = CLOCK_INVALID;
@@ -2087,3 +2089,8 @@ enum servo_state clock_servo_state(struct clock *c)
 {
return c->servo_state;
 }
+
+bool clock_interface_rate_tlv (struct clock *c)
+{
+   return c->iface_rate_tlv;
+}
diff --git a/clock.h b/clock.h
index 0534f21..b393c3e 100644
--- a/clock.h
+++ b/clock.h
@@ -388,4 +388,11 @@ void clock_check_ts(struct clock *c, uint64_t ts);
  */
 double clock_rate_ratio(struct clock *c);
 
+/**
+ * Obtain interface rate tlv support configuration.
+ * @param c  The clock instance.
+ * @return   The interface_rate_supoort config true if supported, else false.
+ */
+bool clock_interface_rate_tlv(struct clock *c);
+
 #endif
diff --git a/config.c b/config.c
index b5cf397..76dd755 100644
--- a/config.c
+++ b/config.c
@@ -241,6 +241,7 @@ struct config_item config_tab[] = {
GLOB_ITEM_ENU("clock_type", CLOCK_TYPE_ORDINARY, clock_type_enu),
GLOB_ITEM_ENU("dataset_comparison", DS_CMP_IEEE1588, dataset_comp_enu),
PORT_ITEM_INT("delayAsymmetry", 0, INT_MIN, INT_MAX),
+   GLOB_ITEM_INT("interface_rate_tlv", 0, 0, 1),
PORT_ITEM_ENU("delay_filter", FILTER_MOVING_MEDIAN, delay_filter_enu),
PORT_ITEM_INT("delay_filter_length", 10, 1, INT_MAX),
PORT_ITEM_ENU("delay_mechanism", DM_E2E, delay_mech_enu),
diff --git a/pdt.h b/pdt.h
index e46b218..1ad23d4 100644
--- a/pdt.h
+++ b/pdt.h
@@ -39,6 +39,7 @@ typedef uint16_t  UInteger16;
 typedef int32_t   Integer32;
 typedef uint32_t  UInteger32;
 typedef int64_t   Integer64;
+typedef uint64_t  UInteger64;
 typedef uint8_t   Octet;
 
 #endif
diff --git a/tlv.c b/tlv.c
index 1c13460..35bee4f 100644
--- a/tlv.c
+++ b/tlv.c
@@ -35,6 +35,7 @@
(tlv->length < sizeof(struct type) - sizeof(struct TLV))
 
 uint8_t ieee8021_id[3] = { IEEE_802_1_COMMITTEE };
+uint8_t itu_t_id[3] = { ITU_T_COMMITTEE };
 
 static TAILQ_HEAD(tlv_pool, tlv_extra) tlv_pool =
TAILQ_HEAD_INITIALIZER(tlv_pool);
diff --git a/tlv.h b/tlv.h
index 8966696..ec22e2f 100644
--- a/tlv.h
+++ b/tlv.h
@@ -395,6 +395,20 @@ struct tlv_extra {
};
 };
 
+/* Organizationally Unique Identifiers */
+#define ITU_T_COMMITTEE 0x00, 0x19, 0xA7
+extern uint8_t itu_t_id[3];
+
+struct msg_interface_rate_tlv {
+   Enumeration16 type;
+   UInteger16length;
+   Octet id[3];
+   Octet subtype[3];
+   UInteger64interfaceBitPeriod;
+   UInteger16numberOfBitsBeforeTimestamp;
+   UInteger16numberOfBitsAfterTimestamp;
+} PACKED;
+
 /**
  * Allocates a new tlv_extra structure.
  * @return  Pointer to a new structure on success or NULL otherwise.
-- 
2.17.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 4/4] [Interface Rate TLV] adding delay asymmetry calculation

2022-07-26 Thread SyncMonk Technologies
Delay asymmetry calculation based on the PTP port interface speed of
master obtained from TLV and the slave interface rate obtained by ethtool.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 interface.c   |  9 +
 interface.h   |  7 +++
 port_private.h|  1 +
 port_signaling.c  | 33 -
 ptp4l.8   |  6 ++
 unicast_service.c | 34 ++
 6 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/interface.c b/interface.c
index 9bcb343..ec8964c 100644
--- a/interface.c
+++ b/interface.c
@@ -93,3 +93,12 @@ int interface_get_vclock(struct interface *iface)
 {
return iface->vclock;
 }
+
+uint64_t interface_bitperiod(struct interface *iface)
+{
+   if (!iface->if_info.valid)
+   return 0;
+
+   /* Megabits per secon converted to attoseconds per bit. */
+   return 1/ iface->if_info.speed;
+}
diff --git a/interface.h b/interface.h
index 5289a7f..e1dc0e8 100644
--- a/interface.h
+++ b/interface.h
@@ -113,4 +113,11 @@ void interface_set_vclock(struct interface *iface, int 
vclock);
  */
 int interface_get_vclock(struct interface *iface);
 
+/**
+ * Obtains the interface bit period based on the speed.
+ * @param iface  The interface of interest.
+ * @return   if valid speed return interface bitperiod in atto seconds.
+ */
+uint64_t interface_bitperiod(struct interface *iface);
+
 #endif
diff --git a/port_private.h b/port_private.h
index d27dceb..d1a1e76 100644
--- a/port_private.h
+++ b/port_private.h
@@ -145,6 +145,7 @@ struct port {
UInteger8   versionNumber; /* UInteger4 */
UInteger8   delay_response_counter;
UInteger8   delay_response_timeout;
+   Integer64   portAsymmetry;
struct PortStatsstats;
struct PortServiceStatsservice_stats;
/* foreignMasterDS */
diff --git a/port_signaling.c b/port_signaling.c
index ed217c0..4b86b7e 100644
--- a/port_signaling.c
+++ b/port_signaling.c
@@ -103,10 +103,38 @@ static int process_interval_request(struct port *p,
return 0;
 }
 
+static int process_interface_rate(struct port *p,
+ struct msg_interface_rate_tlv *r)
+{
+   Integer64 delayAsymmetry;
+   doublensDelay;
+   Integer64 slaveBitPeriod;
+   Integer64 masterBitPeriod;
+
+   if (clock_interface_rate_tlv (p->clock) &&
+   interface_ifinfo_valid(p->iface)) {
+   slaveBitPeriod = interface_bitperiod(p->iface);
+   masterBitPeriod = r->interfaceBitPeriod;
+
+   /* Delay Asymmetry Calculation */
+   nsDelay = (masterBitPeriod - slaveBitPeriod) / (2 * 1.0e9);
+   delayAsymmetry =
+   (r->numberOfBitsAfterTimestamp - 
r->numberOfBitsBeforeTimestamp)  * nsDelay;
+
+   if (delayAsymmetry != p->portAsymmetry) {
+   p->asymmetry += ((delayAsymmetry - p->portAsymmetry) << 
16);
+   p->portAsymmetry = delayAsymmetry;
+   }
+   }
+   return 0;
+}
+
+
 int process_signaling(struct port *p, struct ptp_message *m)
 {
struct tlv_extra *extra;
struct msg_interval_req_tlv *r;
+   struct msg_interface_rate_tlv *rate;
int err = 0, result;
 
switch (p->state) {
@@ -161,10 +189,13 @@ int process_signaling(struct port *p, struct ptp_message 
*m)
 
case TLV_ORGANIZATION_EXTENSION:
r = (struct msg_interval_req_tlv *) extra->tlv;
-
+   rate = (struct msg_interface_rate_tlv *) extra->tlv;
if (0 == memcmp(r->id, ieee8021_id, 
sizeof(ieee8021_id)) &&
r->subtype[0] == 0 && r->subtype[1] == 0 && 
r->subtype[2] == 2)
err = process_interval_request(p, r);
+   else if (0 == memcmp(r->id, itu_t_id, sizeof(itu_t_id)) 
&&
+   r->subtype[0] == 0 && r->subtype[1] == 0 && 
r->subtype[2] == 2)
+   err = process_interface_rate(p, rate);
break;
}
}
diff --git a/ptp4l.8 b/ptp4l.8
index 1268802..140523c 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -705,6 +705,12 @@ the interval, the sample will be printed instead of the 
statistics. The
 messages are printed at the LOG_INFO level.
 The default is 0 (1 second).
 .TP
+.B interface_rate_tlv
+When master and slave instances are operating at different interface rate,
+delay asymmetry caused due to different interface rate needs to be compensated.
+The master and slave exhanges their interface rate based on interface rate TLV
+as per G.8275.2 Annex D.
+The default is 0 (does not support interface rate tlv).
 .B time_stamping
 The time stamping method to be used.  The allowed values are hardware,
 software, 

[Linuxptp-devel] [PATCH 1/4] [Interface Rate TLV] function to support get interface speed via ethtool

2022-07-26 Thread SyncMonk Technologies
When master and slave instance interacting with each other operating
at different interface speed, delay assymetry needs to be compensated
as described in G.8271 appendix V.

In this patch we are adding changes to get the interface speed using
ethtool.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 sk.c | 65 
 sk.h | 18 +
 2 files changed, 83 insertions(+)

diff --git a/sk.c b/sk.c
index 80075be..7df14db 100644
--- a/sk.c
+++ b/sk.c
@@ -205,6 +205,71 @@ failed:
return -1;
 }
 
+int sk_get_if_info(const char *name, struct sk_if_info *if_info)
+{
+#ifdef ETHTOOL_GLINKSETTINGS
+   struct ifreq ifr;
+   int fd, err;
+
+   struct {
+   struct ethtool_link_settings req;
+   __u32 link_mode_data[3 * 127];
+   } ecmd;
+
+   memset(, 0, sizeof(ifr));
+   memset(, 0, sizeof(ecmd));
+
+   fd = socket(AF_INET, SOCK_DGRAM, 0);
+   if (fd < 0) {
+   goto failed;
+   }
+
+   ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
+
+   strncpy(ifr.ifr_name, name, IFNAMSIZ - 1);
+   ifr.ifr_data = (char *) 
+
+   /* Handshake with kernel to determine number of words for link
+* mode bitmaps. When requested number of bitmap words is not
+* the one expected by kernel, the latter returns the integer
+* opposite of what it is expecting. We request length 0 below
+* (aka. invalid bitmap length) to get this info.
+*/
+   err = ioctl(fd, SIOCETHTOOL, );
+   if (err < 0) {
+   pr_err("ioctl SIOCETHTOOL failed: %m");
+   close(fd);
+   goto failed;
+   }
+
+   if (ecmd.req.link_mode_masks_nwords >= 0 ||
+   ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) {
+   return 1;
+   }
+   ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords;
+
+   err = ioctl(fd, SIOCETHTOOL, );
+   if (err < 0) {
+   pr_err("ioctl SIOCETHTOOL failed: %m");
+   close(fd);
+   goto failed;
+   }
+
+   close(fd);
+
+   /* copy the necessary data to sk_info */
+   memset(if_info, 0, sizeof(struct sk_if_info));
+   if_info->valid = 1;
+   if_info->speed = ecmd.req.speed;
+
+   return 0;
+failed:
+#endif
+   /* clear data and ensure it is not marked valid */
+   memset(if_info, 0, sizeof(struct sk_if_info));
+   return -1;
+}
+
 static int sk_interface_guidaddr(const char *name, unsigned char *guid)
 {
char file_name[64], buf[64], addr[8];
diff --git a/sk.h b/sk.h
index 486dbc4..853aadf 100644
--- a/sk.h
+++ b/sk.h
@@ -49,6 +49,16 @@ struct sk_ts_info {
unsigned int rx_filters;
 };
 
+/**
+ * Contains interface information returned by theGLINKSETTINGS ioctl.
+ * @valid:set to non-zero when the info struct contains valid data.
+ * @speed:interface speed.
+ */
+struct sk_if_info {
+   int valid;
+   int speed;
+};
+
 /**
  * Obtains a socket suitable for use with sk_interface_index().
  * @return  An open socket on success, -1 otherwise.
@@ -78,6 +88,14 @@ int sk_general_init(int fd);
  */
 int sk_get_ts_info(const char *name, struct sk_ts_info *sk_info);
 
+/**
+ * Obtain supporte interface information
+ * @param name The name of the interface
+ * @param info  Struct containing obtained interface information.
+ * @return  zero on success, negative on failure.
+ */
+int sk_get_if_info(const char *name, struct sk_if_info *sk_info);
+
 /**
  * Obtain the MAC address of a network interface.
  * @param name  The name of the interface
-- 
2.17.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 2/4] [Interface Rate TLV] adding speed field information for interface

2022-07-26 Thread SyncMonk Technologies
Get the interface speed related information using ethtool

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 clock.c |  2 ++
 interface.c | 11 +++
 interface.h | 14 ++
 port.c  |  5 +
 4 files changed, 32 insertions(+)

diff --git a/clock.c b/clock.c
index d37bb87..de69c52 100644
--- a/clock.c
+++ b/clock.c
@@ -1004,6 +1004,8 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
memset(ts_label, 0, sizeof(ts_label));
if (!rtnl_get_ts_device(interface_name(iface), ts_label))
interface_set_label(iface, ts_label);
+   /* Interface speed information */
+   interface_get_ifinfo(iface);
interface_get_tsinfo(iface);
if (interface_tsinfo_valid(iface) &&
!interface_tsmodes_supported(iface, required_modes)) {
diff --git a/interface.c b/interface.c
index 6c2630c..9bcb343 100644
--- a/interface.c
+++ b/interface.c
@@ -12,6 +12,7 @@ struct interface {
char name[MAX_IFNAME_SIZE + 1];
char ts_label[MAX_IFNAME_SIZE + 1];
struct sk_ts_info ts_info;
+   struct sk_if_info if_info;
int vclock;
 };
 
@@ -40,6 +41,11 @@ int interface_get_tsinfo(struct interface *iface)
return sk_get_ts_info(iface->ts_label, >ts_info);
 }
 
+int interface_get_ifinfo(struct interface *iface)
+{
+   return sk_get_if_info(iface->ts_label, >if_info);
+}
+
 const char *interface_label(struct interface *iface)
 {
return iface->ts_label;
@@ -65,6 +71,11 @@ bool interface_tsinfo_valid(struct interface *iface)
return iface->ts_info.valid ? true : false;
 }
 
+bool interface_ifinfo_valid(struct interface *iface)
+{
+   return iface->if_info.valid ? true : false;
+}
+
 bool interface_tsmodes_supported(struct interface *iface, int modes)
 {
if ((iface->ts_info.so_timestamping & modes) == modes) {
diff --git a/interface.h b/interface.h
index 5fc7836..5289a7f 100644
--- a/interface.h
+++ b/interface.h
@@ -40,6 +40,13 @@ void interface_destroy(struct interface *iface);
  */
 int interface_get_tsinfo(struct interface *iface);
 
+/**
+ * Populate the time stamping information of a given interface.
+ * @param iface  The interface of interest.
+ * @return   zero on success, negative on failure.
+ */
+int interface_get_ifinfo(struct interface *iface);
+
 /**
  * Obtain the time stamping label of a network interface.  This can be
  * different from the name of the interface when bonding is in effect.
@@ -77,6 +84,13 @@ void interface_set_label(struct interface *iface, const char 
*label);
  */
 bool interface_tsinfo_valid(struct interface *iface);
 
+/**
+ * Tests whether an interface's interface information is valid or not.
+ * @param iface  The interface of interest.
+ * @return   True if the interface information is valid, false otherwise.
+ */
+bool interface_ifinfo_valid(struct interface *iface);
+
 /**
  * Tests whether an interface supports a set of given time stamping modes.
  * @param iface  The interface of interest.
diff --git a/port.c b/port.c
index 871ad68..2232b69 100644
--- a/port.c
+++ b/port.c
@@ -2726,6 +2726,11 @@ void port_link_status(void *ctx, int linkup, int 
ts_index)
p->link_status = link_state;
} else {
p->link_status = link_state | LINK_STATE_CHANGED;
+   /* Update Interface speed information on Link up*/
+   if (linkup) {
+   interface_get_ifinfo(p->iface);
+   }
+
pr_notice("%s: link %s", p->log_name, linkup ? "up" : "down");
}
 
-- 
2.17.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel