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/<if name>/speed Though, the sysfs is not mandatory, and could be mount in a different mount point. Erez From: Devasish Dey <devasish....@syncmonk.net> Sent: Tuesday, 26 July 2022 18:38 To: Erez <erezge...@gmail.com> Cc: Leon Goldin <leon.goldin...@renesas.com>; 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<https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.syncmonk.net%2F&data=05%7C01%7Cerez.geva.ext%40siemens.com%7C0db1a0e4541245cbc1ff08da6f258135%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637944504118891260%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=mzPN6%2FW0aXRVdI2fBIk81IGRy7BS7I05Ccey0y1t9gk%3D&reserved=0> On Tue, 26 Jul 2022 at 18:38, Erez <erezge...@gmail.com<mailto:erezge...@gmail.com>> wrote: On Tue, 26 Jul 2022 at 14:27, SyncMonk Technologies <servi...@syncmonk.net<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 <greg.armstrong...@renesas.com<mailto:greg.armstrong...@renesas.com>> Signed-off-by: Leon Goldin <leon.goldin...@renesas.com<mailto:leon.goldin...@renesas.com>> Signed-off-by: Devasish Dey <devasish....@syncmonk.net<mailto:devasish....@syncmonk.net>> Signed-off-by: Vipin Sharma <vipin.sha...@syncmonk.net<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(&ifr, 0, sizeof(ifr)); + memset(&ecmd, 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 *) &ecmd; + + /* 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, &ifr); + 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, &ifr); + 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<mailto:Linuxptp-devel@lists.sourceforge.net> https://lists.sourceforge.net/lists/listinfo/linuxptp-devel<https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.sourceforge.net%2Flists%2Flistinfo%2Flinuxptp-devel&data=05%7C01%7Cerez.geva.ext%40siemens.com%7C0db1a0e4541245cbc1ff08da6f258135%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637944504118891260%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=BQ1MZ9hrGGEBwpyJ0%2FBkywzHRks%2FTFG8Pp3x7NpLJ8k%3D&reserved=0> _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net<mailto:Linuxptp-devel@lists.sourceforge.net> https://lists.sourceforge.net/lists/listinfo/linuxptp-devel<https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.sourceforge.net%2Flists%2Flistinfo%2Flinuxptp-devel&data=05%7C01%7Cerez.geva.ext%40siemens.com%7C0db1a0e4541245cbc1ff08da6f258135%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637944504118891260%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=BQ1MZ9hrGGEBwpyJ0%2FBkywzHRks%2FTFG8Pp3x7NpLJ8k%3D&reserved=0>
_______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel