Blob Blame History Raw
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Sun, 5 Jul 2020 21:27:56 -0700
Subject: net: ethtool: Introduce ethtool_phy_ops
Patch-mainline: v5.9-rc1
Git-commit: 4895d7808e7030c831f2ef83a3cc6ec0d46c30b1
References: bsc#1176447

In order to decouple ethtool from its PHY library dependency, define an
ethtool_phy_ops singleton which can be overriden by the PHY library when
it loads with an appropriate set of function pointers.

SUSE: Moved EXPORT_SYMBOL early in the file to work around a genksyms
      bug, which stumbles over the static_assert for sof_timestamping_names
      and doesn't detect the EXPORT_SYMBOL at the end of the file

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
 include/linux/ethtool.h |   25 +++++++++++++++++++++++++
 net/ethtool/common.c    |   12 ++++++++++++
 net/ethtool/common.h    |    2 ++
 3 files changed, 39 insertions(+)

--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -492,5 +492,30 @@ int ethtool_virtdev_set_link_ksettings(s
 				       const struct ethtool_link_ksettings *cmd,
 				       u32 *dev_speed, u8 *dev_duplex);
 
+struct netlink_ext_ack;
+struct phy_device;
+struct phy_tdr_config;
+
+/**
+ * struct ethtool_phy_ops - Optional PHY device options
+ * @start_cable_test - Start a cable test
+ * @start_cable_test_tdr - Start a Time Domain Reflectometry cable test
+ *
+ * All operations are optional (i.e. the function pointer may be set to %NULL)
+ * and callers must take this into account. Callers must hold the RTNL lock.
+ */
+struct ethtool_phy_ops {
+	int (*start_cable_test)(struct phy_device *phydev,
+				struct netlink_ext_ack *extack);
+	int (*start_cable_test_tdr)(struct phy_device *phydev,
+				    struct netlink_ext_ack *extack,
+				    const struct phy_tdr_config *config);
+};
+
+/**
+ * ethtool_set_ethtool_phy_ops - Set the ethtool_phy_ops singleton
+ * @ops: Ethtool PHY operations to set
+ */
+void ethtool_set_ethtool_phy_ops(const struct ethtool_phy_ops *ops);
 
 #endif /* _LINUX_ETHTOOL_H */
--- a/net/ethtool/common.c
+++ b/net/ethtool/common.c
@@ -2,9 +2,12 @@
 
 #include <linux/net_tstamp.h>
 #include <linux/phy.h>
+#include <linux/rtnetlink.h>
 
 #include "common.h"
 
+EXPORT_SYMBOL_GPL(ethtool_set_ethtool_phy_ops);
+
 const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] = {
 	[NETIF_F_SG_BIT] =               "tx-scatter-gather",
 	[NETIF_F_IP_CSUM_BIT] =          "tx-checksum-ipv4",
@@ -362,3 +365,12 @@ int __ethtool_get_ts_info(struct net_dev
 
 	return 0;
 }
+
+const struct ethtool_phy_ops *ethtool_phy_ops;
+
+void ethtool_set_ethtool_phy_ops(const struct ethtool_phy_ops *ops)
+{
+	rtnl_lock();
+	ethtool_phy_ops = ops;
+	rtnl_unlock();
+}
--- a/net/ethtool/common.h
+++ b/net/ethtool/common.h
@@ -37,4 +37,6 @@ bool convert_legacy_settings_to_link_kse
 int ethtool_get_max_rxfh_channel(struct net_device *dev, u32 *max);
 int __ethtool_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info);
 
+extern const struct ethtool_phy_ops *ethtool_phy_ops;
+
 #endif /* _ETHTOOL_COMMON_H */