summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2025-10-23 10:16:45 +0100
committerJakub Kicinski <kuba@kernel.org>2025-10-24 18:52:08 -0700
commitdc1a2a9ce5b2c80e02115ff6fb29b726ad9d7777 (patch)
tree9e3a16e25fe9aa6aa33c4da7511d912be73279d1
parentb79fbd86c84918790c128e6899b420de4667018e (diff)
net: phylink: add phylink managed wake-on-lan PHY speed control
Some drivers, e.g. stmmac, use the speed_up()/speed_down() APIs to gain additional power saving during Wake-on-LAN where the PHY is managing the state. Add support to phylink for this, which can be enabled by the MAC driver. Only change the PHY speed if the PHY is configured for wake-up, but without any wake-up on the MAC side, as MAC side means changing the configuration once the negotiation has completed. Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Link: https://patch.msgid.link/E1vBrR7-0000000BLza-2PjK@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--drivers/net/phy/phylink.c12
-rw-r--r--include/linux/phylink.h2
2 files changed, 14 insertions, 0 deletions
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index bec44ebdf80b..6e1243bf68aa 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -2576,6 +2576,12 @@ static bool phylink_phy_supports_wol(struct phylink *pl,
return phydev && (pl->config->wol_phy_legacy || phy_can_wakeup(phydev));
}
+static bool phylink_phy_pm_speed_ctrl(struct phylink *pl)
+{
+ return pl->config->wol_phy_speed_ctrl && !pl->wolopts_mac &&
+ pl->phydev && phy_may_wakeup(pl->phydev);
+}
+
/**
* phylink_suspend() - handle a network device suspend event
* @pl: a pointer to a &struct phylink returned from phylink_create()
@@ -2625,6 +2631,9 @@ void phylink_suspend(struct phylink *pl, bool mac_wol)
} else {
phylink_stop(pl);
}
+
+ if (phylink_phy_pm_speed_ctrl(pl))
+ phylink_speed_down(pl, false);
}
EXPORT_SYMBOL_GPL(phylink_suspend);
@@ -2664,6 +2673,9 @@ void phylink_resume(struct phylink *pl)
{
ASSERT_RTNL();
+ if (phylink_phy_pm_speed_ctrl(pl))
+ phylink_speed_up(pl);
+
if (test_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state)) {
/* Wake-on-Lan enabled, MAC handling */
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 59cb58b29d1d..38363e566ac3 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -157,6 +157,7 @@ enum phylink_op_type {
* @lpi_timer_default: Default EEE LPI timer setting.
* @eee_enabled_default: If set, EEE will be enabled by phylink at creation time
* @wol_phy_legacy: Use Wake-on-Lan with PHY even if phy_can_wakeup() is false
+ * @wol_phy_speed_ctrl: Use phy speed control on suspend/resume
* @wol_mac_support: Bitmask of MAC supported %WAKE_* options
*/
struct phylink_config {
@@ -178,6 +179,7 @@ struct phylink_config {
/* Wake-on-Lan support */
bool wol_phy_legacy;
+ bool wol_phy_speed_ctrl;
u32 wol_mac_support;
};