phy: phy_start_aneg: Add an unlocked version
Split phy_start_aneg into a wrapper which takes the PHY lock, and a
helper doing the real work. This will be needed when
phy_ethtook_ksettings_set takes the lock.
Fixes: 2d55173e71b0 ("phy: add generic function to support ksetting support")
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index ee584fa..d845afa 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -700,6 +700,37 @@ static int phy_check_link_status(struct phy_device *phydev)
}
/**
+ * _phy_start_aneg - start auto-negotiation for this PHY device
+ * @phydev: the phy_device struct
+ *
+ * Description: Sanitizes the settings (if we're not autonegotiating
+ * them), and then calls the driver's config_aneg function.
+ * If the PHYCONTROL Layer is operating, we change the state to
+ * reflect the beginning of Auto-negotiation or forcing.
+ */
+static int _phy_start_aneg(struct phy_device *phydev)
+{
+ int err;
+
+ lockdep_assert_held(&phydev->lock);
+
+ if (!phydev->drv)
+ return -EIO;
+
+ if (AUTONEG_DISABLE == phydev->autoneg)
+ phy_sanitize_settings(phydev);
+
+ err = phy_config_aneg(phydev);
+ if (err < 0)
+ return err;
+
+ if (phy_is_started(phydev))
+ err = phy_check_link_status(phydev);
+
+ return err;
+}
+
+/**
* phy_start_aneg - start auto-negotiation for this PHY device
* @phydev: the phy_device struct
*
@@ -712,21 +743,8 @@ int phy_start_aneg(struct phy_device *phydev)
{
int err;
- if (!phydev->drv)
- return -EIO;
-
mutex_lock(&phydev->lock);
-
- if (AUTONEG_DISABLE == phydev->autoneg)
- phy_sanitize_settings(phydev);
-
- err = phy_config_aneg(phydev);
- if (err < 0)
- goto out_unlock;
-
- if (phy_is_started(phydev))
- err = phy_check_link_status(phydev);
-out_unlock:
+ err = _phy_start_aneg(phydev);
mutex_unlock(&phydev->lock);
return err;