aboutsummaryrefslogtreecommitdiffstats
path: root/netlink
diff options
context:
space:
mode:
authorIdo Schimmel <idosch@nvidia.com>2022-09-14 10:25:47 +0300
committerMichal Kubecek <mkubecek@suse.cz>2022-10-06 12:33:53 +0200
commit174e2b8fc95fd3e30a5dd49e3389202495e58b64 (patch)
tree5f7c53194c979136b27d2d31a02c2b1a45ab338f /netlink
parent7ce2855030441166a4fed101ff68f8aa564e827f (diff)
downloadethtool-174e2b8fc95fd3e30a5dd49e3389202495e58b64.tar.gz
netlink: settings: Enable link modes advertisement according to lanes
When user space does not pass link modes to advertise (via 'ETHTOOL_A_LINKMODES_OURS'), but enables auto-negotiation (via 'ETHTOOL_A_LINKMODES_AUTONEG'), the kernel will instruct the underlying device driver to advertise link modes according to passed speed (via 'ETHTOOL_A_LINKMODES_SPEED'), duplex (via 'ETHTOOL_A_LINKMODES_DUPLEX') or lanes (via 'ETHTOOL_A_LINKMODES_LANES'). It is not currently possible to have ethtool instruct the kernel to perform advertisement solely based on lanes, as ethtool incorrectly instructs the kernel to simply advertise all the "real" link modes [1]. This is caused by ethtool treating both of these commands as equivalent: # ethtool -s swp1 autoneg on # ethtool -s swp1 autoneg on lanes 1 Address this by having ethtool recognize that it should not advertise all the "real" link modes when only "lanes" parameter is specified. Before: # ethtool -s swp1 autoneg on lanes 1 # ethtool swp1 [...] Advertised link modes: 1000baseT/Full 10000baseT/Full 1000baseKX/Full 10000baseKR/Full 10000baseR_FEC 40000baseKR4/Full 40000baseCR4/Full 40000baseSR4/Full 40000baseLR4/Full 25000baseCR/Full 25000baseKR/Full 25000baseSR/Full 50000baseCR2/Full 50000baseKR2/Full 100000baseKR4/Full 100000baseSR4/Full 100000baseCR4/Full 100000baseLR4_ER4/Full [...] After: # ethtool -s swp1 autoneg on lanes 1 # ethtool swp1 [...] Advertised link modes: 1000baseT/Full 10000baseT/Full 1000baseKX/Full 10000baseKR/Full 10000baseR_FEC 25000baseCR/Full 25000baseKR/Full 25000baseSR/Full 10000baseCR/Full 10000baseSR/Full 10000baseLR/Full 10000baseER/Full 50000baseKR/Full 50000baseSR/Full 50000baseCR/Full 50000baseLR_ER_FR/Full 50000baseDR/Full [1] # ethtool --debug 0xff -s swp1 autoneg on lanes 1 [...] sending genetlink packet (96 bytes): msg length 96 ethool ETHTOOL_MSG_LINKMODES_SET ETHTOOL_MSG_LINKMODES_SET ETHTOOL_A_LINKMODES_HEADER ETHTOOL_A_HEADER_DEV_NAME = "swp1" ETHTOOL_A_LINKMODES_AUTONEG = on ETHTOOL_A_LINKMODES_LANES = 1 ETHTOOL_A_LINKMODES_OURS ETHTOOL_A_BITSET_SIZE = 93 ETHTOOL_A_BITSET_VALUE = 20:10:9a:87 ff:5d:f0:ff e7:03:00:00 ETHTOOL_A_BITSET_MASK = 20:10:9a:87 ff:5d:f0:ff e7:03:00:00 [...] Reported-by: Maksym Yaremchuk <maksymy@nvidia.com> Tested-by: Maksym Yaremchuk <maksymy@nvidia.com> Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Diffstat (limited to 'netlink')
-rw-r--r--netlink/settings.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/netlink/settings.c b/netlink/settings.c
index 3cf816f..dda4ac9 100644
--- a/netlink/settings.c
+++ b/netlink/settings.c
@@ -1193,8 +1193,9 @@ static int linkmodes_reply_advert_all_cb(const struct nlmsghdr *nlhdr,
}
/* For compatibility reasons with ioctl-based ethtool, when "autoneg on" is
- * specified without "advertise", "speed" and "duplex", we need to query the
- * supported link modes from the kernel and advertise all the "real" ones.
+ * specified without "advertise", "speed", "duplex" and "lanes", we need to
+ * query the supported link modes from the kernel and advertise all the "real"
+ * ones.
*/
static int nl_sset_compat_linkmodes(struct nl_context *nlctx,
struct nl_msg_buff *msgbuff)
@@ -1208,7 +1209,8 @@ static int nl_sset_compat_linkmodes(struct nl_context *nlctx,
if (ret < 0)
return ret;
if (!tb[ETHTOOL_A_LINKMODES_AUTONEG] || tb[ETHTOOL_A_LINKMODES_OURS] ||
- tb[ETHTOOL_A_LINKMODES_SPEED] || tb[ETHTOOL_A_LINKMODES_DUPLEX])
+ tb[ETHTOOL_A_LINKMODES_SPEED] || tb[ETHTOOL_A_LINKMODES_DUPLEX] ||
+ tb[ETHTOOL_A_LINKMODES_LANES])
return 0;
if (!mnl_attr_get_u8(tb[ETHTOOL_A_LINKMODES_AUTONEG]))
return 0;