]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: stmmac: resume PHY before hardware setup when opening the interface
authorStefan Agner <stefan@agner.ch>
Mon, 3 Aug 2026 09:51:56 +0000 (11:51 +0200)
committerJakub Kicinski <kuba@kernel.org>
Wed, 5 Aug 2026 01:09:58 +0000 (18:09 -0700)
Since the referenced commit, changing the MTU on a running interface no
longer disconnects and reconnects the PHY; __stmmac_release() merely
stops phylink, which also suspends the PHY (BMCR power-down) when WoL
is not enabled. __stmmac_open() then performs the DMA software reset in
stmmac_hw_setup() before phylink_start() resumes the PHY again.

IEEE 802.3 22.2.4.1.5 allows a PHY to stop its receive clock while
powered down, and stmmac requires a running receive clock for the DMA
software reset to complete (the phylink config sets mac_requires_rxc).
On such setups, e.g. the RK3566-based Home Assistant Green with an
RTL8211F-VD PHY in RGMII mode, any runtime MTU change now times out and
leaves the interface dead:

  rk_gmac-dwmac fe010000.ethernet end0: Failed to reset the dma
  rk_gmac-dwmac fe010000.ethernet end0: stmmac_hw_setup: DMA engine initialization failed
  rk_gmac-dwmac fe010000.ethernet end0: __stmmac_open: Hw setup failed
  rk_gmac-dwmac fe010000.ethernet end0: failed reopening the interface after MTU change

In the field this is triggered by NetworkManager applying an MTU while
activating the connection, breaking networking entirely. The same
regression has also been reported on i.MX8MP and reproduced on SoCFPGA
based systems.

Resume the PHY in __stmmac_open() before the hardware setup, making it
the counterpart of the phylink_stop() in __stmmac_release(), like
stmmac_resume() already does for the same reason. phylink_start() also
resumes the PHY, but only after stmmac_hw_setup(), and it cannot be
moved before the hardware setup since it may bring the link up
immediately from a workqueue, racing with the initialization (see the
comment in stmmac_resume()). For the regular ndo_open path the PHY has
just been attached and is not suspended, in which case
phylink_prepare_resume() does nothing.

Fixes: db299a0c09e9 ("net: stmmac: move PHY handling out of __stmmac_open()/release()")
Link: https://github.com/home-assistant/operating-system/issues/4858
Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com>
Signed-off-by: Stefan Agner <stefan@agner.ch>
Tested-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20260803095156.132827-1-stefan@agner.ch
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

index 97b28cfa14c268b566516fdb9f1c4c67542bce82..a71f0df263785dd8badc45292ca3067ab33bda05 100644 (file)
@@ -4134,6 +4134,15 @@ static int __stmmac_open(struct net_device *dev,
                        dma_conf->tx_queue[i].tbs = priv->dma_conf.tx_queue[i].tbs;
        memcpy(&priv->dma_conf, dma_conf, sizeof(*dma_conf));
 
+       /* The PHY is suspended when the interface is reopened without
+        * disconnecting the PHY, e.g. on MTU change. IEEE 802.3 allows PHYs
+        * to stop their receive clock while powered down, but the DMA
+        * software reset in stmmac_hw_setup() requires a running receive
+        * clock, and phylink_start() below resumes the PHY only after the
+        * hardware setup. Resume a suspended PHY here first.
+        */
+       phylink_prepare_resume(priv->phylink);
+
        stmmac_reset_queues_param(priv);
 
        ret = stmmac_hw_setup(dev);