From: Greg Kroah-Hartman Date: Wed, 22 Sep 2021 09:01:25 +0000 (+0200) Subject: 5.14-stable patches X-Git-Tag: v4.4.284~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=54e508f1f650c4a46fca44de8b2ca4f5be897238;p=thirdparty%2Fkernel%2Fstable-queue.git 5.14-stable patches added patches: net-stmmac-fix-mac-not-working-when-system-resume-back-with-wol-active.patch --- diff --git a/queue-5.14/net-stmmac-fix-mac-not-working-when-system-resume-back-with-wol-active.patch b/queue-5.14/net-stmmac-fix-mac-not-working-when-system-resume-back-with-wol-active.patch new file mode 100644 index 00000000000..c8367d37d10 --- /dev/null +++ b/queue-5.14/net-stmmac-fix-mac-not-working-when-system-resume-back-with-wol-active.patch @@ -0,0 +1,132 @@ +From 90702dcd19c093621b422ba16fcfd870afe2552f Mon Sep 17 00:00:00 2001 +From: Joakim Zhang +Date: Tue, 7 Sep 2021 18:56:47 +0800 +Subject: net: stmmac: fix MAC not working when system resume back with WoL active + +From: Joakim Zhang + +commit 90702dcd19c093621b422ba16fcfd870afe2552f upstream. + +We can reproduce this issue with below steps: +1) enable WoL on the host +2) host system suspended +3) remote client send out wakeup packets +We can see that host system resume back, but can't work, such as ping failed. + +After a bit digging, this issue is introduced by the commit 46f69ded988d +("net: stmmac: Use resolved link config in mac_link_up()"), which use +the finalised link parameters in mac_link_up() rather than the +parameters in mac_config(). + +There are two scenarios for MAC suspend/resume in STMMAC driver: + +1) MAC suspend with WoL inactive, stmmac_suspend() call +phylink_mac_change() to notify phylink machine that a change in MAC +state, then .mac_link_down callback would be invoked. Further, it will +call phylink_stop() to stop the phylink instance. When MAC resume back, +firstly phylink_start() is called to start the phylink instance, then +call phylink_mac_change() which will finally trigger phylink machine to +invoke .mac_config and .mac_link_up callback. All is fine since +configuration in these two callbacks will be initialized, that means MAC +can restore the state. + +2) MAC suspend with WoL active, phylink_mac_change() will put link +down, but there is no phylink_stop() to stop the phylink instance, so it +will link up again, that means .mac_config and .mac_link_up would be +invoked before system suspended. After system resume back, it will do +DMA initialization and SW reset which let MAC lost the hardware setting +(i.e MAC_Configuration register(offset 0x0) is reset). Since link is up +before system suspended, so .mac_link_up would not be invoked after +system resume back, lead to there is no chance to initialize the +configuration in .mac_link_up callback, as a result, MAC can't work any +longer. + +After discussed with Russell King [1], we confirm that phylink framework +have not take WoL into consideration yet. This patch calls +phylink_suspend()/phylink_resume() functions which is newly introduced +by Russell King to fix this issue. + +[1] https://lore.kernel.org/netdev/20210901090228.11308-1-qiangqing.zhang@nxp.com/ + +Fixes: 46f69ded988d ("net: stmmac: Use resolved link config in mac_link_up()") +Signed-off-by: Joakim Zhang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 36 +++++++++++----------- + 1 file changed, 18 insertions(+), 18 deletions(-) + +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -7118,8 +7118,6 @@ int stmmac_suspend(struct device *dev) + if (!ndev || !netif_running(ndev)) + return 0; + +- phylink_mac_change(priv->phylink, false); +- + mutex_lock(&priv->lock); + + netif_device_detach(ndev); +@@ -7145,14 +7143,6 @@ int stmmac_suspend(struct device *dev) + 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); +- + stmmac_mac_set(priv, priv->ioaddr, false); + pinctrl_pm_select_sleep_state(priv->device); + /* Disable clock in case of PWM is off */ +@@ -7166,6 +7156,16 @@ int stmmac_suspend(struct device *dev) + + mutex_unlock(&priv->lock); + ++ rtnl_lock(); ++ if (device_may_wakeup(priv->device) && priv->plat->pmt) { ++ phylink_suspend(priv->phylink, true); ++ } else { ++ if (device_may_wakeup(priv->device)) ++ phylink_speed_down(priv->phylink, false); ++ phylink_suspend(priv->phylink, false); ++ } ++ rtnl_unlock(); ++ + if (priv->dma_cap.fpesel) { + /* Disable FPE */ + stmmac_fpe_configure(priv, priv->ioaddr, +@@ -7256,13 +7256,15 @@ int stmmac_resume(struct device *dev) + return ret; + } + +- 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(); ++ rtnl_lock(); ++ if (device_may_wakeup(priv->device) && priv->plat->pmt) { ++ phylink_resume(priv->phylink); ++ } else { ++ phylink_resume(priv->phylink); ++ if (device_may_wakeup(priv->device)) ++ phylink_speed_up(priv->phylink); + } ++ rtnl_unlock(); + + rtnl_lock(); + mutex_lock(&priv->lock); +@@ -7283,8 +7285,6 @@ int stmmac_resume(struct device *dev) + mutex_unlock(&priv->lock); + rtnl_unlock(); + +- phylink_mac_change(priv->phylink, true); +- + netif_device_attach(ndev); + + return 0; diff --git a/queue-5.14/series b/queue-5.14/series index d8a6d307e46..918e6a108e6 100644 --- a/queue-5.14/series +++ b/queue-5.14/series @@ -1,3 +1,4 @@ +net-stmmac-fix-mac-not-working-when-system-resume-back-with-wol-active.patch io_uring-ensure-symmetry-in-handling-iter-types-in-loop_rw_iter.patch swiotlb-xen-avoid-double-free.patch swiotlb-xen-fix-late-init-retry.patch