net: stmmac: improve WOL
Subsystems (4)
cover net: stmmac: improve WOL
Currently, stmmac driver relies on the HW PMT to support WOL. We want to support phy based WOL.
patch1 is a small improvement to disable WAKE_MAGIC for PMT case if no pmt_magic_frame.
patch2 and patch3 are two prepation patches.
patch4 implement the phy based WOL
patch5 tries to save a bit energy if WOL is enabled.
Jisheng Zhang (5):
net: stmmac: Remove WAKE_MAGIC if HW shows no pmt_magic_frame
net: stmmac: Move device_can_wakeup() check earlier in set_wol
net: stmmac: only call pmt() during suspend/resume if HW enables PMT
net: stmmac: Support WOL with phy
net: stmmac: speed down the PHY, if WoL used, to save energy
.../ethernet/stmicro/stmmac/stmmac_ethtool.c | 19 ++++++++++++++++--- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 18 +++++++++++++++--- 2 files changed, 31 insertions(+), 6 deletions(-)
Signature · 1 line
2.28.0.rc0
PATCH 1/5 net: stmmac: Remove WAKE_MAGIC if HW shows no pmt_magic_frame
Remove WAKE_MAGIC from supported modes if the HW capability register shows no support for pmt_magic_frame.
--- drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +2 -0
@@ -603,6 +603,8 @@ static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)mutex_lock (&priv->lock);if (device_can_wakeup (priv->device)) { wol->supported =WAKE_MAGIC |WAKE_UCAST ; +if (priv->hw_cap_support && !priv->dma_cap.pmt_magic_frame) + wol->supported &= ~WAKE_MAGIC ; wol->wolopts = priv->wolopts; }mutex_unlock (&priv->lock);
Signature · 1 line
2.28.0.rc0
PATCH 2/5 net: stmmac: Move device_can_wakeup() check earlier in set_wol
In reply to Jisheng ZhangIf !device_can_wakeup(), there's no need to futher check. And return -EOPNOTSUPP rather than -EINVAL if !device_can_wakeup().
--- drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +3 -3
@@ -615,15 +615,15 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)struct stmmac_priv *priv =netdev_priv (dev);u32 support =WAKE_MAGIC |WAKE_UCAST ; +if (!device_can_wakeup (priv->device)) +return -EOPNOTSUPP ; +/* By default almost all GMAC devices support the WoL via * magic frame but we can disable it if the HW capability * register shows no support for pmt_magic_frame. */ if ((priv->hw_cap_support) && (!priv->dma_cap.pmt_magic_frame)) wol->wolopts &= ~WAKE_MAGIC ; -if (!device_can_wakeup (priv->device)) -return -EINVAL ; -if (wol->wolopts & ~support)return -EINVAL ;
Signature · 1 line
2.28.0.rc0
PATCH 3/5 net: stmmac: only call pmt() during suspend/resume if HW enables PMT
In reply to Jisheng ZhangThis is to prepare WOL support with phy. Compared with WOL implementation which relies on the MAC's PMT features, in phy supported WOL case, device_may_wakeup() may also be true, but we should not call mac's pmt() function if HW doesn't enable PMT.
And during resume, we should call phylink_start() if PMT is disabled.
--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +3 -3
@@ -5085,7 +5085,7 @@ int stmmac_suspend(struct device *dev) priv->plat->serdes_powerdown (ndev, priv->plat->bsp_priv);/* Enable Power down mode by programming the PMT regs */ -if (device_may_wakeup (priv->device)) { +if (device_may_wakeup (priv->device) && priv->plat->pmt) {stmmac_pmt (priv, priv->hw, priv->wolopts); priv->irq_wake =1 ; }else {
@@ -5157,7 +5157,7 @@ int stmmac_resume(struct device *dev)* this bit because it can generate problems while resuming * from another devices (e.g. serial console). */ -if (device_may_wakeup (priv->device)) { +if (device_may_wakeup (priv->device) && priv->plat->pmt) {mutex_lock (&priv->lock);stmmac_pmt (priv, priv->hw,0 );mutex_unlock (&priv->lock);
@@ -5200,7 +5200,7 @@ int stmmac_resume(struct device *dev)mutex_unlock (&priv->lock); -if (!device_may_wakeup (priv->device)) { +if (!device_may_wakeup (priv->device) || !priv->plat->pmt) {rtnl_lock ();phylink_start (priv->phylink);rtnl_unlock ();
Signature · 1 line
2.28.0.rc0
PATCH 4/5 net: stmmac: Support WOL with phy
In reply to Jisheng ZhangCurrently, the stmmac driver WOL implementation relies on MAC's PMT feature. We have a case: the MAC HW doesn't enable PMT, instead, we rely on the phy to support WOL. Implement the support for this case.
--- drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 11 +++++++++++ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++++ 2 files changed, 15 insertions(+)
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +11 -0
@@ -600,6 +600,9 @@ static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) {struct stmmac_priv *priv =netdev_priv (dev); +if (!priv->plat->pmt) +return phylink_ethtool_get_wol (priv->phylink, wol); +mutex_lock (&priv->lock);if (device_can_wakeup (priv->device)) { wol->supported =WAKE_MAGIC |WAKE_UCAST ;
@@ -618,6 +621,14 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)if (!device_can_wakeup (priv->device))return -EOPNOTSUPP ; +if (!priv->plat->pmt) { +int ret =phylink_ethtool_set_wol (priv->phylink, wol); + +if (!ret) +device_set_wakeup_enable (&dev->dev, !!wol->wolopts); +return ret; + } +/* By default almost all GMAC devices support the WoL via * magic frame but we can disable it if the HW capability * register shows no support for pmt_magic_frame. */
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +4 -0
@@ -1075,6 +1075,7 @@ static void stmmac_check_pcs_mode(struct stmmac_priv *priv)*/ static int stmmac_init_phy (struct net_device *dev) { +struct ethtool_wolinfo wol = { .cmd =ETHTOOL_GWOL };struct stmmac_priv *priv =netdev_priv (dev);struct device_node *node;int ret;
@@ -1100,6 +1101,9 @@ static int stmmac_init_phy(struct net_device *dev) ret =phylink_connect_phy (priv->phylink, phydev); } +phylink_ethtool_get_wol (priv->phylink, &wol); +device_set_wakeup_capable (priv->device, !!wol.supported); +return ret; }
Signature · 1 line
2.28.0.rc0
PATCH 5/5 net: stmmac: Speed down the PHY if WoL to save energy
In reply to Jisheng ZhangWhen WoL is enabled and the machine is powered off, the PHY remains waiting for wakeup events at max speed, which is a waste of energy.
Slow down the PHY speed before stopping the ethernet if WoL is enabled,
--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +8 -0
@@ -2823,6 +2823,8 @@ static int stmmac_open(struct net_device *dev)stmmac_init_coalesce (priv);phylink_start (priv->phylink); +/* We may have called phylink_speed_down before */ +phylink_speed_up (priv->phylink);/* Request the IRQ lines */ ret = request_irq(dev->irq, stmmac_interrupt,
@@ -2896,6 +2898,8 @@ static int stmmac_release(struct net_device *dev)if (priv->eee_enabled)del_timer_sync (&priv->eee_ctrl_timer); +if (device_may_wakeup (priv->device)) +phylink_speed_down (priv->phylink, false);/* Stop and disconnect the PHY */ phylink_stop (priv->phylink);phylink_disconnect_phy (priv->phylink);
@@ -5095,6 +5099,8 @@ int stmmac_suspend(struct device *dev) }else {mutex_unlock (&priv->lock);rtnl_lock (); +if (device_may_wakeup (priv->device)) +phylink_speed_down (priv->phylink, false);phylink_stop (priv->phylink);rtnl_unlock ();mutex_lock (&priv->lock);
@@ -5207,6 +5213,8 @@ int stmmac_resume(struct device *dev)if (!device_may_wakeup (priv->device) || !priv->plat->pmt) {rtnl_lock ();phylink_start (priv->phylink); +/* We may have called phylink_speed_down before */ +phylink_speed_up (priv->phylink);rtnl_unlock (); }
Signature · 1 line
2.28.0.rc0
David Miller
maintainerFrom: Jisheng Zhang <[email protected]>
Date: Mon, 27 Jul 2020 19:01:07 +0800
Quoted 8 lines
Currently, stmmac driver relies on the HW PMT to support WOL. We want to support phy based WOL.
patch1 is a small improvement to disable
WAKE_MAGICfor PMT case if nopmt_magic_frame.
patch2 and patch3 are two prepation patches.
patch4 implement the phy based WOL
patch5 tries to save a bit energy if WOL is enabled.
Series applied to net-next, thanks.