[PATCH 6.12.y-cip 05/18] net: stmmac: address non-LPI resume failures properly
Cosmin Tanislav <[email protected]>
| Newsgroups | org.cip-project.lists.cip-dev |
|---|---|
| Message-ID | <[email protected]> |
From: "Russell King (Oracle)" <[email protected]> commit ef43e5132895ad59b45e38855d32e966bb7434d9 upstream. The Synopsys Designware GMAC core databook requires all clocks to be active in order to complete software reset, which we perform during resume. However, IEEE 802.3 allows a PHY to stop its clocks when placed in low-power mode, which happens when the system is suspended and WoL is not enabled. As an attempt to work around this, commit 36d18b5664ef ("net: stmmac: start phylink instance before stmmac_hw_setup()") started phylink early, but this has the side effect that the mac_link_up() method may be called before or during the initialisation of GMAC hardware. We also have the socfpga glue driver directly calling phy_resume() also as an attempt to work around this. In a previous commit, phylink_prepare_resume() has been introduced to give MAC drivers a way to ensure that the PHY is resumed prior to their initialisation of their MAC hardware. This commit adds the call, and moves the phylink_resume() call back to where it should be before the aforementioned commit. Signed-off-by: Russell King (Oracle) <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Cosmin Tanislav <[email protected]> --- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 8187e6934668..cccf44b47909 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -8044,12 +8044,12 @@ int stmmac_resume(struct device *dev) } rtnl_lock(); - phylink_resume(priv->phylink); - if (device_may_wakeup(priv->device) && !priv->plat->pmt) - phylink_speed_up(priv->phylink); - rtnl_unlock(); - rtnl_lock(); + /* Prepare the PHY to resume, ensuring that its clocks which are + * necessary for the MAC DMA reset to complete are running + */ + phylink_prepare_resume(priv->phylink); + mutex_lock(&priv->lock); stmmac_reset_queues_param(priv); @@ -8074,6 +8074,15 @@ int stmmac_resume(struct device *dev) stmmac_enable_all_dma_irq(priv); mutex_unlock(&priv->lock); + + /* phylink_resume() must be called after the hardware has been + * initialised because it may bring the link up immediately in a + * workqueue thread, which will race with initialisation. + */ + phylink_resume(priv->phylink); + if (device_may_wakeup(priv->device) && !priv->plat->pmt) + phylink_speed_up(priv->phylink); + rtnl_unlock(); netif_device_attach(ndev); -- 2.55.0