Commit 417e19d1 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-ethtool-Untangle-PHYLIB-dependency'



Florian Fainelli says:

====================
net: ethtool: Untangle PHYLIB dependency

This patch series untangles the ethtool netlink dependency with PHYLIB
which exists because the cable test feature calls directly into PHY
library functions. The approach taken here is to introduce
ethtool_phy_ops function pointers which can be dynamically registered
when PHYLIB loads.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 1a4d6816 f3631ab0
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -3027,6 +3027,11 @@ static struct phy_driver genphy_driver = {
	.set_loopback   = genphy_loopback,
};

static const struct ethtool_phy_ops phy_ethtool_phy_ops = {
	.start_cable_test	= phy_start_cable_test,
	.start_cable_test_tdr	= phy_start_cable_test_tdr,
};

static int __init phy_init(void)
{
	int rc;
@@ -3035,6 +3040,7 @@ static int __init phy_init(void)
	if (rc)
		return rc;

	ethtool_set_ethtool_phy_ops(&phy_ethtool_phy_ops);
	features_init();

	rc = phy_driver_register(&genphy_c45_driver, THIS_MODULE);
@@ -3056,6 +3062,7 @@ static void __exit phy_exit(void)
	phy_driver_unregister(&genphy_c45_driver);
	phy_driver_unregister(&genphy_driver);
	mdio_bus_exit();
	ethtool_set_ethtool_phy_ops(NULL);
}

subsys_initcall(phy_init);
+25 −0
Original line number Diff line number Diff line
@@ -502,5 +502,30 @@ int ethtool_virtdev_set_link_ksettings(struct net_device *dev,
				       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 */
+0 −1
Original line number Diff line number Diff line
@@ -455,7 +455,6 @@ config FAILOVER
config ETHTOOL_NETLINK
	bool "Netlink interface for ethtool"
	default y
	depends on PHYLIB=y || PHYLIB=n
	help
	  An alternative userspace interface for ethtool based on generic
	  netlink. It provides better extensibility and some new features,
+16 −2
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info)
{
	struct nlattr *tb[ETHTOOL_A_CABLE_TEST_MAX + 1];
	struct ethnl_req_info req_info = {};
	const struct ethtool_phy_ops *ops;
	struct net_device *dev;
	int ret;

@@ -81,11 +82,17 @@ int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info)
	}

	rtnl_lock();
	ops = ethtool_phy_ops;
	if (!ops || !ops->start_cable_test) {
		ret = -EOPNOTSUPP;
		goto out_rtnl;
	}

	ret = ethnl_ops_begin(dev);
	if (ret < 0)
		goto out_rtnl;

	ret = phy_start_cable_test(dev->phydev, info->extack);
	ret = ops->start_cable_test(dev->phydev, info->extack);

	ethnl_ops_complete(dev);

@@ -308,6 +315,7 @@ int ethnl_act_cable_test_tdr(struct sk_buff *skb, struct genl_info *info)
{
	struct nlattr *tb[ETHTOOL_A_CABLE_TEST_TDR_MAX + 1];
	struct ethnl_req_info req_info = {};
	const struct ethtool_phy_ops *ops;
	struct phy_tdr_config cfg;
	struct net_device *dev;
	int ret;
@@ -337,11 +345,17 @@ int ethnl_act_cable_test_tdr(struct sk_buff *skb, struct genl_info *info)
		goto out_dev_put;

	rtnl_lock();
	ops = ethtool_phy_ops;
	if (!ops || !ops->start_cable_test_tdr) {
		ret = -EOPNOTSUPP;
		goto out_rtnl;
	}

	ret = ethnl_ops_begin(dev);
	if (ret < 0)
		goto out_rtnl;

	ret = phy_start_cable_test_tdr(dev->phydev, info->extack, &cfg);
	ret = ops->start_cable_test_tdr(dev->phydev, info->extack, &cfg);

	ethnl_ops_complete(dev);

+11 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@

#include <linux/net_tstamp.h>
#include <linux/phy.h>
#include <linux/rtnetlink.h>

#include "common.h"

@@ -373,3 +374,13 @@ int __ethtool_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)

	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();
}
EXPORT_SYMBOL_GPL(ethtool_set_ethtool_phy_ops);
Loading