Skip to content

Commit

Permalink
net: phy: Add locks to ethtool functions
Browse files Browse the repository at this point in the history
The phydev lock should be held while accessing members of phydev,
or calling into the driver.

Signed-off-by: Andrew Lunn <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
lunn authored and davem330 committed Feb 20, 2023
1 parent 3365777 commit 2f987d4
Showing 1 changed file with 66 additions and 18 deletions.
84 changes: 66 additions & 18 deletions drivers/net/phy/phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -1069,27 +1069,35 @@ EXPORT_SYMBOL(phy_ethtool_ksettings_set);
int phy_speed_down(struct phy_device *phydev, bool sync)
{
__ETHTOOL_DECLARE_LINK_MODE_MASK(adv_tmp);
int ret;
int ret = 0;

mutex_lock(&phydev->lock);

if (phydev->autoneg != AUTONEG_ENABLE)
return 0;
goto out;

linkmode_copy(adv_tmp, phydev->advertising);

ret = phy_speed_down_core(phydev);
if (ret)
return ret;
goto out;

linkmode_copy(phydev->adv_old, adv_tmp);

if (linkmode_equal(phydev->advertising, adv_tmp))
return 0;
if (linkmode_equal(phydev->advertising, adv_tmp)) {
ret = 0;
goto out;
}

ret = phy_config_aneg(phydev);
if (ret)
return ret;
goto out;

ret = sync ? phy_poll_aneg_done(phydev) : 0;
out:
mutex_unlock(&phydev->lock);

return sync ? phy_poll_aneg_done(phydev) : 0;
return ret;
}
EXPORT_SYMBOL_GPL(phy_speed_down);

Expand All @@ -1102,21 +1110,28 @@ EXPORT_SYMBOL_GPL(phy_speed_down);
int phy_speed_up(struct phy_device *phydev)
{
__ETHTOOL_DECLARE_LINK_MODE_MASK(adv_tmp);
int ret = 0;

mutex_lock(&phydev->lock);

if (phydev->autoneg != AUTONEG_ENABLE)
return 0;
goto out;

if (linkmode_empty(phydev->adv_old))
return 0;
goto out;

linkmode_copy(adv_tmp, phydev->advertising);
linkmode_copy(phydev->advertising, phydev->adv_old);
linkmode_zero(phydev->adv_old);

if (linkmode_equal(phydev->advertising, adv_tmp))
return 0;
goto out;

ret = phy_config_aneg(phydev);
out:
mutex_unlock(&phydev->lock);

return phy_config_aneg(phydev);
return ret;
}
EXPORT_SYMBOL_GPL(phy_speed_up);

Expand Down Expand Up @@ -1500,10 +1515,16 @@ EXPORT_SYMBOL(phy_init_eee);
*/
int phy_get_eee_err(struct phy_device *phydev)
{
int ret;

if (!phydev->drv)
return -EIO;

return phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_WK_ERR);
mutex_lock(&phydev->lock);
ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_WK_ERR);
mutex_unlock(&phydev->lock);

return ret;
}
EXPORT_SYMBOL(phy_get_eee_err);

Expand All @@ -1517,10 +1538,16 @@ EXPORT_SYMBOL(phy_get_eee_err);
*/
int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data)
{
int ret;

if (!phydev->drv)
return -EIO;

return genphy_c45_ethtool_get_eee(phydev, data);
mutex_lock(&phydev->lock);
ret = genphy_c45_ethtool_get_eee(phydev, data);
mutex_unlock(&phydev->lock);

return ret;
}
EXPORT_SYMBOL(phy_ethtool_get_eee);

Expand All @@ -1533,10 +1560,16 @@ EXPORT_SYMBOL(phy_ethtool_get_eee);
*/
int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data)
{
int ret;

if (!phydev->drv)
return -EIO;

return genphy_c45_ethtool_set_eee(phydev, data);
mutex_lock(&phydev->lock);
ret = genphy_c45_ethtool_set_eee(phydev, data);
mutex_unlock(&phydev->lock);

return ret;
}
EXPORT_SYMBOL(phy_ethtool_set_eee);

Expand All @@ -1548,8 +1581,15 @@ EXPORT_SYMBOL(phy_ethtool_set_eee);
*/
int phy_ethtool_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)
{
if (phydev->drv && phydev->drv->set_wol)
return phydev->drv->set_wol(phydev, wol);
int ret;

if (phydev->drv && phydev->drv->set_wol) {
mutex_lock(&phydev->lock);
ret = phydev->drv->set_wol(phydev, wol);
mutex_unlock(&phydev->lock);

return ret;
}

return -EOPNOTSUPP;
}
Expand All @@ -1563,8 +1603,11 @@ EXPORT_SYMBOL(phy_ethtool_set_wol);
*/
void phy_ethtool_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)
{
if (phydev->drv && phydev->drv->get_wol)
if (phydev->drv && phydev->drv->get_wol) {
mutex_lock(&phydev->lock);
phydev->drv->get_wol(phydev, wol);
mutex_unlock(&phydev->lock);
}
}
EXPORT_SYMBOL(phy_ethtool_get_wol);

Expand Down Expand Up @@ -1601,13 +1644,18 @@ EXPORT_SYMBOL(phy_ethtool_set_link_ksettings);
int phy_ethtool_nway_reset(struct net_device *ndev)
{
struct phy_device *phydev = ndev->phydev;
int ret;

if (!phydev)
return -ENODEV;

if (!phydev->drv)
return -EIO;

return phy_restart_aneg(phydev);
mutex_lock(&phydev->lock);
ret = phy_restart_aneg(phydev);
mutex_unlock(&phydev->lock);

return ret;
}
EXPORT_SYMBOL(phy_ethtool_nway_reset);

0 comments on commit 2f987d4

Please sign in to comment.