Commit a7e34480 authored by Florian Fainelli's avatar Florian Fainelli Committed by David S. Miller

net: phy: Allow drivers to always call into ->suspend()

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: default avatarSimon Horman <simon.horman@corigine.com>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ba79e9a7
...@@ -1860,9 +1860,10 @@ int phy_suspend(struct phy_device *phydev) ...@@ -1860,9 +1860,10 @@ int phy_suspend(struct phy_device *phydev)
if (phydev->suspended) if (phydev->suspended)
return 0; return 0;
/* If the device has WOL enabled, we cannot suspend the PHY */
phy_ethtool_get_wol(phydev, &wol); 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; return -EBUSY;
if (!phydrv || !phydrv->suspend) if (!phydrv || !phydrv->suspend)
......
...@@ -86,6 +86,7 @@ extern const int phy_10gbit_features_array[1]; ...@@ -86,6 +86,7 @@ extern const int phy_10gbit_features_array[1];
#define PHY_IS_INTERNAL 0x00000001 #define PHY_IS_INTERNAL 0x00000001
#define PHY_RST_AFTER_CLK_EN 0x00000002 #define PHY_RST_AFTER_CLK_EN 0x00000002
#define PHY_POLL_CABLE_TEST 0x00000004 #define PHY_POLL_CABLE_TEST 0x00000004
#define PHY_ALWAYS_CALL_SUSPEND 0x00000008
#define MDIO_DEVICE_IS_PHY 0x80000000 #define MDIO_DEVICE_IS_PHY 0x80000000
/** /**
...@@ -548,6 +549,8 @@ struct macsec_ops; ...@@ -548,6 +549,8 @@ struct macsec_ops;
* @downshifted_rate: Set true if link speed has been downshifted. * @downshifted_rate: Set true if link speed has been downshifted.
* @is_on_sfp_module: Set true if PHY is located on an SFP module. * @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 * @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 * @state: State of the PHY for management purposes
* @dev_flags: Device-specific flags used by the PHY driver. * @dev_flags: Device-specific flags used by the PHY driver.
* *
...@@ -644,6 +647,7 @@ struct phy_device { ...@@ -644,6 +647,7 @@ struct phy_device {
unsigned downshifted_rate:1; unsigned downshifted_rate:1;
unsigned is_on_sfp_module:1; unsigned is_on_sfp_module:1;
unsigned mac_managed_pm:1; unsigned mac_managed_pm:1;
unsigned wol_enabled:1;
unsigned autoneg:1; unsigned autoneg:1;
/* The most recently read link state */ /* The most recently read link state */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment