net: phy: Allow drivers to always call into ->suspend()
authorFlorian Fainelli <f.fainelli@gmail.com>
Thu, 11 May 2023 17:21:08 +0000 (10:21 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sat, 13 May 2023 15:56:29 +0000 (16:56 +0100)
A few PHY drivers are currently attempting to not suspend the PHY when
Wake-on-LAN is enabled, however that code is not currently executing at
all due to an early check in phy_suspend().

This prevents PHY drivers from making an appropriate decisions and put
the hardware into a low power state if desired.

In order to allow the PHY drivers to opt into getting their ->suspend
routine to be called, add a PHY_ALWAYS_CALL_SUSPEND bit which can be
set. A boolean that tracks whether the PHY or the attached MAC has
Wake-on-LAN enabled is also provided for convenience.

If phydev::wol_enabled then the PHY shall not prevent its own
Wake-on-LAN detection logic from working and shall not prevent the
Ethernet MAC from receiving packets for matching.

Reviewed-by: Simon Horman <simon.horman@corigine.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/phy/phy_device.c
include/linux/phy.h

index 17d0d05..8852b0c 100644 (file)
@@ -1860,9 +1860,10 @@ int phy_suspend(struct phy_device *phydev)
        if (phydev->suspended)
                return 0;
 
-       /* If the device has WOL enabled, we cannot suspend the PHY */
        phy_ethtool_get_wol(phydev, &wol);
-       if (wol.wolopts || (netdev && netdev->wol_enabled))
+       phydev->wol_enabled = wol.wolopts || (netdev && netdev->wol_enabled);
+       /* If the device has WOL enabled, we cannot suspend the PHY */
+       if (phydev->wol_enabled && !(phydrv->flags & PHY_ALWAYS_CALL_SUSPEND))
                return -EBUSY;
 
        if (!phydrv || !phydrv->suspend)
index c5a0dc8..e0df8b3 100644 (file)
@@ -86,6 +86,7 @@ extern const int phy_10gbit_features_array[1];
 #define PHY_IS_INTERNAL                0x00000001
 #define PHY_RST_AFTER_CLK_EN   0x00000002
 #define PHY_POLL_CABLE_TEST    0x00000004
+#define PHY_ALWAYS_CALL_SUSPEND        0x00000008
 #define MDIO_DEVICE_IS_PHY     0x80000000
 
 /**
@@ -548,6 +549,8 @@ struct macsec_ops;
  * @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
+ * @wol_enabled: Set to true if the PHY or the attached MAC have Wake-on-LAN
+ *              enabled.
  * @state: State of the PHY for management purposes
  * @dev_flags: Device-specific flags used by the PHY driver.
  *
@@ -644,6 +647,7 @@ struct phy_device {
        unsigned downshifted_rate:1;
        unsigned is_on_sfp_module:1;
        unsigned mac_managed_pm:1;
+       unsigned wol_enabled:1;
 
        unsigned autoneg:1;
        /* The most recently read link state */