Commit fe55b1d4 authored by Oleksij Rempel's avatar Oleksij Rempel Committed by Paolo Abeni
Browse files

ethtool: linkstate: migrate linkstate functions to support multi-PHY setups



Adapt linkstate_get_sqi() and linkstate_get_sqi_max() to take a
phy_device argument directly, enabling support for setups with
multiple PHYs. The previous assumption of a single PHY attached to
a net_device no longer holds.

Use ethnl_req_get_phydev() to identify the appropriate PHY device
for the operation. Update linkstate_prepare_data() and related
logic to accommodate this change, ensuring compatibility with
multi-PHY configurations.

Signed-off-by: default avatarOleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 6a46e3e8
Loading
Loading
Loading
Loading
+15 −8
Original line number Diff line number Diff line
@@ -26,9 +26,8 @@ const struct nla_policy ethnl_linkstate_get_policy[] = {
		NLA_POLICY_NESTED(ethnl_header_policy_stats),
};

static int linkstate_get_sqi(struct net_device *dev)
static int linkstate_get_sqi(struct phy_device *phydev)
{
	struct phy_device *phydev = dev->phydev;
	int ret;

	if (!phydev)
@@ -46,9 +45,8 @@ static int linkstate_get_sqi(struct net_device *dev)
	return ret;
}

static int linkstate_get_sqi_max(struct net_device *dev)
static int linkstate_get_sqi_max(struct phy_device *phydev)
{
	struct phy_device *phydev = dev->phydev;
	int ret;

	if (!phydev)
@@ -100,19 +98,28 @@ static int linkstate_prepare_data(const struct ethnl_req_info *req_base,
{
	struct linkstate_reply_data *data = LINKSTATE_REPDATA(reply_base);
	struct net_device *dev = reply_base->dev;
	struct nlattr **tb = info->attrs;
	struct phy_device *phydev;
	int ret;

	phydev = ethnl_req_get_phydev(req_base, tb[ETHTOOL_A_LINKSTATE_HEADER],
				      info->extack);
	if (IS_ERR(phydev)) {
		ret = PTR_ERR(phydev);
		goto out;
	}

	ret = ethnl_ops_begin(dev);
	if (ret < 0)
		return ret;
	data->link = __ethtool_get_link(dev);

	ret = linkstate_get_sqi(dev);
	ret = linkstate_get_sqi(phydev);
	if (linkstate_sqi_critical_error(ret))
		goto out;
	data->sqi = ret;

	ret = linkstate_get_sqi_max(dev);
	ret = linkstate_get_sqi_max(phydev);
	if (linkstate_sqi_critical_error(ret))
		goto out;
	data->sqi_max = ret;
@@ -127,9 +134,9 @@ static int linkstate_prepare_data(const struct ethnl_req_info *req_base,
			   sizeof(data->link_stats) / 8);

	if (req_base->flags & ETHTOOL_FLAG_STATS) {
		if (dev->phydev)
		if (phydev)
			data->link_stats.link_down_events =
				READ_ONCE(dev->phydev->link_down_events);
				READ_ONCE(phydev->link_down_events);

		if (dev->ethtool_ops->get_link_ext_stats)
			dev->ethtool_ops->get_link_ext_stats(dev,