diff mbox series

[net,v2,2/2] ethtool: Derive parameters from link_mode in ioctl path

Message ID 20210404081433.1260889-3-danieller@nvidia.com
State New
Headers show
Series Fix link_mode derived params functionality | expand

Commit Message

Danielle Ratson April 4, 2021, 8:14 a.m. UTC
Currently, some ethtool link parameters, like speed, lanes and duplex, are
derived from the link_mode parameter. These link parameters are only
derived in __ethtool_get_link_ksettings(), but the ioctl path does not go
through this function. This means that old ethtool (w/o netlink) won't get
any reasonable values.

Add a function that derives the parameters from link_mode and use it in
ioctl paths as well.

Output before:

$ ethtool --version
ethtool version 5.4
$ ethtool swp13
Settings for swp13:
        Supported ports: [ FIBRE Backplane ]
        Supported link modes:   1000baseKX/Full
                                10000baseKR/Full
                                25000baseCR/Full
                                25000baseKR/Full
                                25000baseSR/Full
        Supported pause frame use: Symmetric Receive-only
        Supports auto-negotiation: Yes
        Supported FEC modes: Not reported
        Advertised link modes:  1000baseKX/Full
                                10000baseKR/Full
                                25000baseCR/Full
                                25000baseKR/Full
                                25000baseSR/Full
        Advertised pause frame use: No
        Advertised auto-negotiation: Yes
        Advertised FEC modes: Not reported
        Speed: Unknown!
        Duplex: Half
        Port: Direct Attach Copper
        PHYAD: 0
        Transceiver: internal
        Auto-negotiation: on
        Link detected: yes

Output after:

$ ethtool swp13
Settings for swp13:
        Supported ports: [ FIBRE Backplane ]
        Supported link modes:   1000baseKX/Full
                                10000baseKR/Full
                                25000baseCR/Full
                                25000baseKR/Full
                                25000baseSR/Full
        Supported pause frame use: Symmetric Receive-only
        Supports auto-negotiation: Yes
        Supported FEC modes: Not reported
        Advertised link modes:  1000baseKX/Full
                                10000baseKR/Full
                                25000baseCR/Full
                                25000baseKR/Full
                                25000baseSR/Full
        Advertised pause frame use: No
        Advertised auto-negotiation: Yes
        Advertised FEC modes: Not reported
        Speed: 25000Mb/s
        Duplex: Full
        Port: Direct Attach Copper
        PHYAD: 0
        Transceiver: internal
        Auto-negotiation: on
        Link detected: yes

Fixes: c8907043c6ac9 ("ethtool: Get link mode in use instead of speed and duplex parameters")
Signed-off-by: Danielle Ratson <danieller@nvidia.com>
Reported-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
---
 net/ethtool/ioctl.c | 38 ++++++++++++++++++++++++++------------
 1 file changed, 26 insertions(+), 12 deletions(-)
diff mbox series

Patch

diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index cebbf93b27a7..943162ef080c 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -422,11 +422,31 @@  struct ethtool_link_usettings {
 	} link_modes;
 };
 
+static int
+ethtool_params_from_link_mode(const struct net_device *dev,
+			      struct ethtool_link_ksettings *link_ksettings)
+{
+	const struct link_mode_info *link_info;
+
+	if (dev->ethtool_ops->cap_link_mode_supported &&
+	    link_ksettings->link_mode != -1) {
+		if (WARN_ON_ONCE(link_ksettings->link_mode >=
+				 __ETHTOOL_LINK_MODE_MASK_NBITS))
+			return -EINVAL;
+
+		link_info = &link_mode_params[link_ksettings->link_mode];
+		link_ksettings->base.speed = link_info->speed;
+		link_ksettings->lanes = link_info->lanes;
+		link_ksettings->base.duplex = link_info->duplex;
+	}
+
+	return 0;
+}
+
 /* Internal kernel helper to query a device ethtool_link_settings. */
 int __ethtool_get_link_ksettings(struct net_device *dev,
 				 struct ethtool_link_ksettings *link_ksettings)
 {
-	const struct link_mode_info *link_info;
 	int err;
 
 	ASSERT_RTNL();
@@ -440,17 +460,7 @@  int __ethtool_get_link_ksettings(struct net_device *dev,
 	if (err)
 		return err;
 
-	if (dev->ethtool_ops->cap_link_mode_supported &&
-	    link_ksettings->link_mode != -1) {
-		if (WARN_ON_ONCE(link_ksettings->link_mode >=
-				 __ETHTOOL_LINK_MODE_MASK_NBITS))
-			return -EINVAL;
-
-		link_info = &link_mode_params[link_ksettings->link_mode];
-		link_ksettings->base.speed = link_info->speed;
-		link_ksettings->lanes = link_info->lanes;
-		link_ksettings->base.duplex = link_info->duplex;
-	}
+	ethtool_params_from_link_mode(dev, link_ksettings);
 
 	return 0;
 }
@@ -572,6 +582,8 @@  static int ethtool_get_link_ksettings(struct net_device *dev,
 	if (err < 0)
 		return err;
 
+	ethtool_params_from_link_mode(dev, &link_ksettings);
+
 	/* make sure we tell the right values to user */
 	link_ksettings.base.cmd = ETHTOOL_GLINKSETTINGS;
 	link_ksettings.base.link_mode_masks_nwords
@@ -673,6 +685,8 @@  static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
 		return err;
 	convert_link_ksettings_to_legacy_settings(&cmd, &link_ksettings);
 
+	ethtool_params_from_link_mode(dev, &link_ksettings);
+
 	/* send a sensible cmd tag back to user */
 	cmd.cmd = ETHTOOL_GSET;