summaryrefslogtreecommitdiff
path: root/drivers/net/phy/phylink.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy/phylink.c')
-rw-r--r--drivers/net/phy/phylink.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index f180b947d090..b4c384cffdef 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -554,7 +554,9 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy)
"PHY [%s] driver [%s]\n", dev_name(&phy->mdio.dev),
phy->drv->name);
+ mutex_lock(&phy->lock);
mutex_lock(&pl->state_mutex);
+ pl->netdev->phydev = phy;
pl->phydev = phy;
linkmode_copy(pl->supported, mask);
@@ -564,6 +566,7 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy)
ethtool_convert_legacy_u32_to_link_mode(pl->link_config.advertising,
phy->advertising);
mutex_unlock(&pl->state_mutex);
+ mutex_unlock(&phy->lock);
netdev_dbg(pl->netdev,
"phy: setting supported %*pb advertising 0x%08x\n",
@@ -639,14 +642,17 @@ void phylink_disconnect_phy(struct phylink *pl)
WARN_ON(!lockdep_rtnl_is_held());
phy = pl->phydev;
+ if (phy) {
+ mutex_lock(&phy->lock);
+ mutex_lock(&pl->state_mutex);
+ pl->netdev->phydev = NULL;
+ pl->phydev = NULL;
+ mutex_unlock(&pl->state_mutex);
+ mutex_unlock(&phy->lock);
+ flush_work(&pl->resolve);
- mutex_lock(&pl->state_mutex);
- pl->phydev = NULL;
- mutex_unlock(&pl->state_mutex);
- flush_work(&pl->resolve);
-
- if (phy)
phy_disconnect(phy);
+ }
}
EXPORT_SYMBOL_GPL(phylink_disconnect_phy);