mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Florian Fainelli <f.fainelli@gmail.com>
To: netdev@vger.kernel.org
Cc: Florian Fainelli <f.fainelli@gmail.com>,
	Andrew Lunn <andrew+netdev@lunn.ch>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@kernel.org>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Heiner Kallweit <hkallweit1@gmail.com>,
	Russell King <linux@armlinux.org.uk>,
	Jijie Shao <shaojijie@huawei.com>,
	Simon Horman <horms@kernel.org>,
	Runyu Xiao <runyu.xiao@seu.edu.cn>,
	David Yang <mmyangfl@gmail.com>,
	Herbert Valerio Riedel <hvr@gnu.org>,
	Jeff Garzik <jeff@garzik.org>,
	Danny Kukawka <danny.kukawka@bisect.de>,
	Mugunthan V N <mugunthanvnm@ti.com>,
	Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>,
	linux-kernel@vger.kernel.org (open list),
	Manuel Lauss <manuel.lauss@gmail.com>
Subject: [PATCH net v2 11/12] net: au1000: keep the MAC stopped until the PHY link is ready
Date: Wed, 11 Nov 2026 20:52:53 -0800	[thread overview]
Message-ID: <20261112045301.3669532-12-f.fainelli@gmail.com> (raw)
In-Reply-To: <20261112045301.3669532-1-f.fainelli@gmail.com>

phy_stop() powers down the PHY when the interface is closed. The driver
leaves MAC receive/transmit enabled on link-down and enables them during
initialization before the PHY resumes. MTX-1 can hang when the MAC runs
while its MII clocks are absent or still recovering.

Stop the MAC on link-down before phylib suspends the PHY. On open, clear
the driver's acknowledged link cache and synchronously resume the PHY
to restore its MII clocks and honor its recovery delay. Initialize the
MAC before phy_start() so the PHY worker cannot access MDIO or enable
traffic during setup. Leave RX/TX stopped until a link-up callback
configures duplex and enables traffic.

Use the acknowledged link and duplex cache under the device lock during
initialization, retaining it for watchdog recovery. Keep the reset-time
hard stop for paths without a preceding link-down callback. On resume
failure reset the MAC and release the IRQ; if initialization fails,
suspend the PHY again before cleanup.

Fixes: be9dad1f9f26 ("net: phy: suspend phydev when going to HALTED")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/ethernet/amd/au1000_eth.c | 39 ++++++++++++++++++++++-----
 1 file changed, 32 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c
index 8b7a88ceb3c5..d60430a3795e 100644
--- a/drivers/net/ethernet/amd/au1000_eth.c
+++ b/drivers/net/ethernet/amd/au1000_eth.c
@@ -456,7 +456,8 @@ au1000_adjust_link(struct net_device *dev)
 		/* link state changed */
 
 		if (!phydev->link) {
-			/* link went down */
+			/* Stop the MAC before the PHY can remove its clocks. */
+			au1000_hard_stop(dev);
 			aup->old_speed = 0;
 			aup->old_duplex = -1;
 		}
@@ -691,8 +692,8 @@ static u32 au1000_rx_mode(struct net_device *dev, u32 reg);
  * When the device powers up, the clocks are disabled and the
  * mac is in reset state.  When the interface is closed, we
  * do the same -- reset the device and disable the clocks to
- * conserve power. Thus, whenever au1000_init() is called,
- * the device should already be in reset state.
+ * conserve power. The device must be stopped before au1000_init() is
+ * called, but may be out of reset for MDIO accesses while resuming the PHY.
  */
 static int au1000_init(struct net_device *dev)
 {
@@ -727,12 +728,12 @@ static int au1000_init(struct net_device *dev)
 
 	wmb(); /* drain writebuffer */
 
-	control = MAC_RX_ENABLE | MAC_TX_ENABLE;
+	control = 0;
 #ifndef CONFIG_CPU_LITTLE_ENDIAN
 	control |= MAC_BIG_ENDIAN;
 #endif
 	if (dev->phydev) {
-		if (dev->phydev->link && (DUPLEX_FULL == dev->phydev->duplex))
+		if (aup->old_link && aup->old_duplex == DUPLEX_FULL)
 			control |= MAC_FULL_DUPLEX;
 		else
 			control |= MAC_DISABLE_RX_OWN;
@@ -742,6 +743,10 @@ static int au1000_init(struct net_device *dev)
 
 	control = au1000_rx_mode(dev, control);
 
+	/* Only use link state acknowledged by au1000_adjust_link(). */
+	if (!dev->phydev || aup->old_link)
+		control |= MAC_RX_ENABLE | MAC_TX_ENABLE;
+
 	writel(control, &aup->mac->control);
 	writel(0x8100, &aup->mac->vlan1_tag); /* activate vlan support */
 	wmb(); /* drain writebuffer */
@@ -916,6 +921,7 @@ static irqreturn_t au1000_interrupt(int irq, void *dev_id)
 
 static int au1000_open(struct net_device *dev)
 {
+	unsigned long flags;
 	int retval;
 	struct au1000_private *aup = netdev_priv(dev);
 
@@ -928,11 +934,25 @@ static int au1000_open(struct net_device *dev)
 		return retval;
 	}
 
+	spin_lock_irqsave(&aup->lock, flags);
+	aup->old_link = 0;
+	aup->old_speed = 0;
+	aup->old_duplex = -1;
+	spin_unlock_irqrestore(&aup->lock, flags);
+
+	/* Restore the MII clocks without starting the PHY state machine. */
+	if (dev->phydev) {
+		retval = phy_resume(dev->phydev);
+		if (retval)
+			goto err_reset;
+	}
+
 	retval = au1000_init(dev);
 	if (retval) {
 		netdev_err(dev, "error in au1000_init\n");
-		free_irq(dev->irq, dev);
-		return retval;
+		if (dev->phydev)
+			phy_suspend(dev->phydev);
+		goto err_reset;
 	}
 
 	if (dev->phydev)
@@ -943,6 +963,11 @@ static int au1000_open(struct net_device *dev)
 	netif_dbg(aup, drv, dev, "open: Initialization done.\n");
 
 	return 0;
+
+err_reset:
+	au1000_reset_mac(dev);
+	free_irq(dev->irq, dev);
+	return retval;
 }
 
 static int au1000_close(struct net_device *dev)
-- 
2.53.0


  parent reply	other threads:[~2026-11-12  4:54 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-12  4:52 [PATCH net v2 00/12] net: au1000: Bug fixes Florian Fainelli
2026-11-12  4:52 ` [PATCH net v2 01/12] net: au1000: recycle RX descriptors on allocation failure Florian Fainelli
2026-11-12  4:52 ` [PATCH net v2 02/12] net: au1000: clear all-multicast mode when restoring hash filtering Florian Fainelli
2026-11-12  4:52 ` [PATCH net v2 03/12] net: au1000: disconnect the PHY before freeing the MDIO bus Florian Fainelli
2026-11-12  4:52 ` [PATCH net v2 04/12] net: au1000: report MDIO transaction timeouts Florian Fainelli
2026-11-12  4:52 ` [PATCH net v2 05/12] net: au1000: serialize TX completion with packet submission Florian Fainelli
2026-11-12  4:52 ` [PATCH net v2 06/12] net: au1000: assign a valid MAC address without platform data Florian Fainelli
2026-11-12  4:52 ` [PATCH net v2 07/12] net: au1000: fix buffer descriptor free list insertion Florian Fainelli
2026-11-12  4:52 ` [PATCH net v2 08/12] net: au1000: restore receive filtering before enabling RX Florian Fainelli
2026-11-12  4:52 ` [PATCH net v2 09/12] net: au1000: restore RX buffer addresses when restarting the MAC Florian Fainelli
2026-11-12  4:52 ` [PATCH net v2 10/12] net: phy: smsc: wait for LAN83C183 power-down recovery Florian Fainelli
2026-11-12  4:52 ` Florian Fainelli [this message]
2026-11-12  4:52 ` [PATCH net v2 12/12] net: au1000: reject frames larger than the TX bounce buffer Florian Fainelli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261112045301.3669532-12-f.fainelli@gmail.com \
    --to=f.fainelli@gmail.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=danny.kukawka@bisect.de \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=hkallweit1@gmail.com \
    --cc=horms@kernel.org \
    --cc=hvr@gnu.org \
    --cc=jeff@garzik.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=manuel.lauss@gmail.com \
    --cc=mmyangfl@gmail.com \
    --cc=mugunthanvnm@ti.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=runyu.xiao@seu.edu.cn \
    --cc=sebastian.hesselbarth@gmail.com \
    --cc=shaojijie@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®