214 lines
8.4 KiB
Diff
214 lines
8.4 KiB
Diff
From 95d8a3ff2989fc3b83d349b8b2ba6083f1224e79 Mon Sep 17 00:00:00 2001
|
|
From: Michal Kubecek <mkubecek@suse.cz>
|
|
Date: Wed, 11 Dec 2019 10:58:34 +0100
|
|
Subject: [PATCH 160/283] ethtool: provide link mode names as a string set
|
|
|
|
mainline inclusion
|
|
from mainline-v5.6-rc1
|
|
commit 428c122f5f6b54f40bd51c47495104b534b5a57c
|
|
category: feature
|
|
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EN3D
|
|
|
|
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=428c122f5f6b54f40bd51c47495104b534b5a57c
|
|
|
|
--------------------------------
|
|
|
|
Unlike e.g. netdev features, the ethtool ioctl interface requires link mode
|
|
table to be in sync between kernel and userspace for userspace to be able
|
|
to display and set all link modes supported by kernel. The way arbitrary
|
|
length bitsets are implemented in netlink interface, this will be no longer
|
|
needed.
|
|
|
|
To allow userspace to access all link modes running kernel supports, add
|
|
table of ethernet link mode names and make it available as a string set to
|
|
userspace GET_STRSET requests. Add build time check to make sure names
|
|
are defined for all modes declared in enum ethtool_link_mode_bit_indices.
|
|
|
|
Once the string set is available, make it also accessible via ioctl.
|
|
|
|
Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
|
|
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
|
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
|
|
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Signed-off-by: Xiaodong Li <lixiaodong67@huawei.com>
|
|
---
|
|
include/uapi/linux/ethtool.h | 4 +-
|
|
net/ethtool/common.c | 86 ++++++++++++++++++++++++++++++++++++
|
|
net/ethtool/common.h | 5 +++
|
|
net/ethtool/ioctl.c | 6 +++
|
|
4 files changed, 100 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
|
|
index 2574ceb9d2f3..e519138e2a38 100644
|
|
--- a/include/uapi/linux/ethtool.h
|
|
+++ b/include/uapi/linux/ethtool.h
|
|
@@ -641,6 +641,7 @@ enum ethtool_link_ext_substate_cable_issue {
|
|
* @ETH_SS_RSS_HASH_FUNCS: RSS hush function names
|
|
* @ETH_SS_PHY_STATS: Statistic names, for use with %ETHTOOL_GPHYSTATS
|
|
* @ETH_SS_PHY_TUNABLES: PHY tunable names
|
|
+ * @ETH_SS_LINK_MODES: link mode names
|
|
*/
|
|
enum ethtool_stringset {
|
|
ETH_SS_TEST = 0,
|
|
@@ -652,6 +653,7 @@ enum ethtool_stringset {
|
|
ETH_SS_TUNABLES,
|
|
ETH_SS_PHY_STATS,
|
|
ETH_SS_PHY_TUNABLES,
|
|
+ ETH_SS_LINK_MODES,
|
|
};
|
|
|
|
/**
|
|
@@ -1576,7 +1578,7 @@ enum ethtool_link_mode_bit_indices {
|
|
* macro for bits > 31. The only way to use indices > 31 is to
|
|
* use the new ETHTOOL_GLINKSETTINGS/ETHTOOL_SLINKSETTINGS API.
|
|
*/
|
|
-
|
|
+ __ETHTOOL_LINK_MODE_MASK_NBITS,
|
|
__ETHTOOL_LINK_MODE_LAST
|
|
= ETHTOOL_LINK_MODE_FEC_BASER_BIT,
|
|
};
|
|
diff --git a/net/ethtool/common.c b/net/ethtool/common.c
|
|
index 8b5e11e7e0a6..11a12af88165 100644
|
|
--- a/net/ethtool/common.c
|
|
+++ b/net/ethtool/common.c
|
|
@@ -83,3 +83,89 @@ phy_tunable_strings[__ETHTOOL_PHY_TUNABLE_COUNT][ETH_GSTRING_LEN] = {
|
|
[ETHTOOL_PHY_FAST_LINK_DOWN] = "phy-fast-link-down",
|
|
[ETHTOOL_PHY_EDPD] = "phy-energy-detect-power-down",
|
|
};
|
|
+
|
|
+#define __LINK_MODE_NAME(speed, type, duplex) \
|
|
+ (#speed "base" #type "/" #duplex)
|
|
+#define __DEFINE_LINK_MODE_NAME(speed, type, duplex) \
|
|
+ [ETHTOOL_LINK_MODE(speed, type, duplex)] = \
|
|
+ __LINK_MODE_NAME(speed, type, duplex)
|
|
+#define __DEFINE_SPECIAL_MODE_NAME(_mode, _name) \
|
|
+ [ETHTOOL_LINK_MODE_ ## _mode ## _BIT] = _name
|
|
+
|
|
+const char link_mode_names[][ETH_GSTRING_LEN] = {
|
|
+ __DEFINE_LINK_MODE_NAME(10, T, Half),
|
|
+ __DEFINE_LINK_MODE_NAME(10, T, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(100, T, Half),
|
|
+ __DEFINE_LINK_MODE_NAME(100, T, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(1000, T, Half),
|
|
+ __DEFINE_LINK_MODE_NAME(1000, T, Full),
|
|
+ __DEFINE_SPECIAL_MODE_NAME(Autoneg, "Autoneg"),
|
|
+ __DEFINE_SPECIAL_MODE_NAME(TP, "TP"),
|
|
+ __DEFINE_SPECIAL_MODE_NAME(AUI, "AUI"),
|
|
+ __DEFINE_SPECIAL_MODE_NAME(MII, "MII"),
|
|
+ __DEFINE_SPECIAL_MODE_NAME(FIBRE, "FIBRE"),
|
|
+ __DEFINE_SPECIAL_MODE_NAME(BNC, "BNC"),
|
|
+ __DEFINE_LINK_MODE_NAME(10000, T, Full),
|
|
+ __DEFINE_SPECIAL_MODE_NAME(Pause, "Pause"),
|
|
+ __DEFINE_SPECIAL_MODE_NAME(Asym_Pause, "Asym_Pause"),
|
|
+ __DEFINE_LINK_MODE_NAME(2500, X, Full),
|
|
+ __DEFINE_SPECIAL_MODE_NAME(Backplane, "Backplane"),
|
|
+ __DEFINE_LINK_MODE_NAME(1000, KX, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(10000, KX4, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(10000, KR, Full),
|
|
+ __DEFINE_SPECIAL_MODE_NAME(10000baseR_FEC, "10000baseR_FEC"),
|
|
+ __DEFINE_LINK_MODE_NAME(20000, MLD2, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(20000, KR2, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(40000, KR4, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(40000, CR4, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(40000, SR4, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(40000, LR4, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(56000, KR4, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(56000, CR4, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(56000, SR4, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(56000, LR4, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(25000, CR, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(25000, KR, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(25000, SR, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(50000, CR2, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(50000, KR2, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(100000, KR4, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(100000, SR4, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(100000, CR4, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(100000, LR4_ER4, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(50000, SR2, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(1000, X, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(10000, CR, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(10000, SR, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(10000, LR, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(10000, LRM, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(10000, ER, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(2500, T, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(5000, T, Full),
|
|
+ __DEFINE_SPECIAL_MODE_NAME(FEC_NONE, "None"),
|
|
+ __DEFINE_SPECIAL_MODE_NAME(FEC_RS, "RS"),
|
|
+ __DEFINE_SPECIAL_MODE_NAME(FEC_BASER, "BASER"),
|
|
+ __DEFINE_LINK_MODE_NAME(50000, KR, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(50000, SR, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(50000, CR, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(50000, LR_ER_FR, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(50000, DR, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(100000, KR2, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(100000, SR2, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(100000, CR2, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(100000, LR2_ER2_FR2, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(100000, DR2, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(200000, KR4, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(200000, SR4, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(200000, LR4_ER4_FR4, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(200000, DR4, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(200000, CR4, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(100, T1, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(1000, T1, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(400000, KR8, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(400000, SR8, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(400000, LR8_ER8_FR8, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(400000, DR8, Full),
|
|
+ __DEFINE_LINK_MODE_NAME(400000, CR8, Full),
|
|
+};
|
|
+static_assert(ARRAY_SIZE(link_mode_names) == ETHTOOL_LINK_MODE_FEC_LLRS_BIT);
|
|
diff --git a/net/ethtool/common.h b/net/ethtool/common.h
|
|
index 336566430be4..bbb788908cb1 100644
|
|
--- a/net/ethtool/common.h
|
|
+++ b/net/ethtool/common.h
|
|
@@ -5,6 +5,10 @@
|
|
|
|
#include <linux/ethtool.h>
|
|
|
|
+/* compose link mode index from speed, type and duplex */
|
|
+#define ETHTOOL_LINK_MODE(speed, type, duplex) \
|
|
+ ETHTOOL_LINK_MODE_ ## speed ## base ## type ## _ ## duplex ## _BIT
|
|
+
|
|
extern const char
|
|
netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN];
|
|
extern const char
|
|
@@ -13,5 +17,6 @@ extern const char
|
|
tunable_strings[__ETHTOOL_TUNABLE_COUNT][ETH_GSTRING_LEN];
|
|
extern const char
|
|
phy_tunable_strings[__ETHTOOL_PHY_TUNABLE_COUNT][ETH_GSTRING_LEN];
|
|
+extern const char link_mode_names[][ETH_GSTRING_LEN];
|
|
|
|
#endif /* _ETHTOOL_COMMON_H */
|
|
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
|
|
index fab4dae2da1b..7799062c2b97 100644
|
|
--- a/net/ethtool/ioctl.c
|
|
+++ b/net/ethtool/ioctl.c
|
|
@@ -155,6 +155,9 @@ static int __ethtool_get_sset_count(struct net_device *dev, int sset)
|
|
!ops->get_ethtool_phy_stats)
|
|
return phy_ethtool_get_sset_count(dev->phydev);
|
|
|
|
+ if (sset == ETH_SS_LINK_MODES)
|
|
+ return __ETHTOOL_LINK_MODE_MASK_NBITS;
|
|
+
|
|
if (ops->get_sset_count && ops->get_strings)
|
|
return ops->get_sset_count(dev, sset);
|
|
else
|
|
@@ -179,6 +182,9 @@ static void __ethtool_get_strings(struct net_device *dev,
|
|
else if (stringset == ETH_SS_PHY_STATS && dev->phydev &&
|
|
!ops->get_ethtool_phy_stats)
|
|
phy_ethtool_get_strings(dev->phydev, data);
|
|
+ else if (stringset == ETH_SS_LINK_MODES)
|
|
+ memcpy(data, link_mode_names,
|
|
+ __ETHTOOL_LINK_MODE_MASK_NBITS * ETH_GSTRING_LEN);
|
|
else
|
|
/* ops->get_strings is valid because checked earlier */
|
|
ops->get_strings(dev, stringset, data);
|
|
--
|
|
2.34.1
|
|
|