Skip to content

Commit

Permalink
ethtool: netlink: do not return SQI value if link is down
Browse files Browse the repository at this point in the history
Do not attach SQI value if link is down. "SQI values are only valid if
link-up condition is present" per OpenAlliance specification of
100Base-T1 Interoperability Test suite [1]. The same rule would apply
for other link types.

[1] https://opensig.org/automotive-ethernet-specifications/#

Fixes: 8066021 ("ethtool: provide UAPI for PHY Signal Quality Index (SQI)")
Signed-off-by: Oleksij Rempel <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
Reviewed-by: Woojung Huh <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Paolo Abeni <[email protected]>
  • Loading branch information
olerem authored and Paolo Abeni committed Jul 11, 2024
1 parent f2aeb73 commit c184cf9
Showing 1 changed file with 28 additions and 13 deletions.
41 changes: 28 additions & 13 deletions net/ethtool/linkstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ static int linkstate_get_sqi(struct net_device *dev)
mutex_lock(&phydev->lock);
if (!phydev->drv || !phydev->drv->get_sqi)
ret = -EOPNOTSUPP;
else if (!phydev->link)
ret = -ENETDOWN;
else
ret = phydev->drv->get_sqi(phydev);
mutex_unlock(&phydev->lock);
Expand All @@ -55,13 +57,26 @@ static int linkstate_get_sqi_max(struct net_device *dev)
mutex_lock(&phydev->lock);
if (!phydev->drv || !phydev->drv->get_sqi_max)
ret = -EOPNOTSUPP;
else if (!phydev->link)
ret = -ENETDOWN;
else
ret = phydev->drv->get_sqi_max(phydev);
mutex_unlock(&phydev->lock);

return ret;
};

static bool linkstate_sqi_critical_error(int sqi)
{
return sqi < 0 && sqi != -EOPNOTSUPP && sqi != -ENETDOWN;
}

static bool linkstate_sqi_valid(struct linkstate_reply_data *data)
{
return data->sqi >= 0 && data->sqi_max >= 0 &&
data->sqi <= data->sqi_max;
}

static int linkstate_get_link_ext_state(struct net_device *dev,
struct linkstate_reply_data *data)
{
Expand Down Expand Up @@ -93,12 +108,12 @@ static int linkstate_prepare_data(const struct ethnl_req_info *req_base,
data->link = __ethtool_get_link(dev);

ret = linkstate_get_sqi(dev);
if (ret < 0 && ret != -EOPNOTSUPP)
if (linkstate_sqi_critical_error(ret))
goto out;
data->sqi = ret;

ret = linkstate_get_sqi_max(dev);
if (ret < 0 && ret != -EOPNOTSUPP)
if (linkstate_sqi_critical_error(ret))
goto out;
data->sqi_max = ret;

Expand Down Expand Up @@ -136,11 +151,10 @@ static int linkstate_reply_size(const struct ethnl_req_info *req_base,
len = nla_total_size(sizeof(u8)) /* LINKSTATE_LINK */
+ 0;

if (data->sqi != -EOPNOTSUPP)
len += nla_total_size(sizeof(u32));

if (data->sqi_max != -EOPNOTSUPP)
len += nla_total_size(sizeof(u32));
if (linkstate_sqi_valid(data)) {
len += nla_total_size(sizeof(u32)); /* LINKSTATE_SQI */
len += nla_total_size(sizeof(u32)); /* LINKSTATE_SQI_MAX */
}

if (data->link_ext_state_provided)
len += nla_total_size(sizeof(u8)); /* LINKSTATE_EXT_STATE */
Expand All @@ -164,13 +178,14 @@ static int linkstate_fill_reply(struct sk_buff *skb,
nla_put_u8(skb, ETHTOOL_A_LINKSTATE_LINK, !!data->link))
return -EMSGSIZE;

if (data->sqi != -EOPNOTSUPP &&
nla_put_u32(skb, ETHTOOL_A_LINKSTATE_SQI, data->sqi))
return -EMSGSIZE;
if (linkstate_sqi_valid(data)) {
if (nla_put_u32(skb, ETHTOOL_A_LINKSTATE_SQI, data->sqi))
return -EMSGSIZE;

if (data->sqi_max != -EOPNOTSUPP &&
nla_put_u32(skb, ETHTOOL_A_LINKSTATE_SQI_MAX, data->sqi_max))
return -EMSGSIZE;
if (nla_put_u32(skb, ETHTOOL_A_LINKSTATE_SQI_MAX,
data->sqi_max))
return -EMSGSIZE;
}

if (data->link_ext_state_provided) {
if (nla_put_u8(skb, ETHTOOL_A_LINKSTATE_EXT_STATE,
Expand Down

0 comments on commit c184cf9

Please sign in to comment.