net: phy: make PHY PM ops a no-op if MAC driver manages PHY PM
authorHeiner Kallweit <hkallweit1@gmail.com>
Wed, 7 Apr 2021 15:51:56 +0000 (17:51 +0200)
committerJakub Kicinski <kuba@kernel.org>
Fri, 9 Apr 2021 23:37:04 +0000 (16:37 -0700)
Resume callback of the PHY driver is called after the one for the MAC
driver. The PHY driver resume callback calls phy_init_hw(), and this is
potentially problematic if the MAC driver calls phy_start() in its resume
callback. One issue was reported with the fec driver and a KSZ8081 PHY
which seems to become unstable if a soft reset is triggered during aneg.

The new flag allows MAC drivers to indicate that they take care of
suspending/resuming the PHY. Then the MAC PM callbacks can handle
any dependency between MAC and PHY PM.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/phy/phy_device.c
include/linux/phy.h

index a009d17..73d29fd 100644 (file)
@@ -273,6 +273,9 @@ static __maybe_unused int mdio_bus_phy_suspend(struct device *dev)
 {
        struct phy_device *phydev = to_phy_device(dev);
 
+       if (phydev->mac_managed_pm)
+               return 0;
+
        /* We must stop the state machine manually, otherwise it stops out of
         * control, possibly with the phydev->lock held. Upon resume, netdev
         * may call phy routines that try to grab the same lock, and that may
@@ -294,6 +297,9 @@ static __maybe_unused int mdio_bus_phy_resume(struct device *dev)
        struct phy_device *phydev = to_phy_device(dev);
        int ret;
 
+       if (phydev->mac_managed_pm)
+               return 0;
+
        if (!phydev->suspended_by_mdio_bus)
                goto no_resume;
 
index 8e2cf84..98fb441 100644 (file)
@@ -493,6 +493,7 @@ struct macsec_ops;
  * @loopback_enabled: Set true if this PHY has been loopbacked successfully.
  * @downshifted_rate: Set true if link speed has been downshifted.
  * @is_on_sfp_module: Set true if PHY is located on an SFP module.
+ * @mac_managed_pm: Set true if MAC driver takes of suspending/resuming PHY
  * @state: State of the PHY for management purposes
  * @dev_flags: Device-specific flags used by the PHY driver.
  * @irq: IRQ number of the PHY's interrupt (-1 if none)
@@ -567,6 +568,7 @@ struct phy_device {
        unsigned loopback_enabled:1;
        unsigned downshifted_rate:1;
        unsigned is_on_sfp_module:1;
+       unsigned mac_managed_pm:1;
 
        unsigned autoneg:1;
        /* The most recently read link state */