diff options
author | David S. Miller <davem@davemloft.net> | 2020-07-28 17:48:20 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-07-28 17:48:20 -0700 |
commit | 490ed0b908d371cd9ab63fc142213e5d02d810ee (patch) | |
tree | 4f87b2fa3a9e7c7abc9a8fa8e13c05999206f6d5 /drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |
parent | f11df0454f8ed6a83641c0dc1a9f6e9609516216 (diff) | |
parent | 77b2898394e3bb843228ee6f90066a23cf67e8a1 (diff) | |
download | linux-490ed0b908d371cd9ab63fc142213e5d02d810ee.tar.bz2 |
Merge branch 'net-stmmac-improve-WOL'
Jisheng Zhang says:
====================
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.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/stmmac_main.c')
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 73677c3b33b6..89b2b3472852 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -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; } @@ -2819,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, @@ -2892,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); @@ -5085,12 +5093,14 @@ 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 { 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); @@ -5157,7 +5167,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,9 +5210,11 @@ 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); + /* We may have called phylink_speed_down before */ + phylink_speed_up(priv->phylink); rtnl_unlock(); } |