Thread (10 messages) 10 messages, 4 authors, 6d ago

[PATCH net v13 4/4] net: phy: restore the interrupt when the generic bind cycle fails

flat view
COOLING6d IN NET-NEXT

From: Aleksei Sviridkin <hidden>
Date: 2026-10-01 13:02:51
Also in: linux-usb, lkml
Subsystem: ethernet phy library, networking drivers, the rest · Maintainers: Andrew Lunn, Heiner Kallweit, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

Revision v13 of 6 in this series; queued in net-next as 4719b69bb66b on 2026-10-07.

Revisions (6)
  1. v8 [diff vs current]
  2. v9 [diff vs current]
  3. v10 [diff vs current]
  4. v11 [diff vs current]
  5. v12 [diff vs current]
  6. v13 current
When phy_attach_direct() binds the generic driver itself and the bind
fails, the PHY is left with polling in place of its interrupt.
phy_probe() has already replaced phydev->irq with PHY_POLL by then. The
unwind does not go through phy_detach(), so the restore there does not
run, and a later attach finds a PHY that can only be polled.

Found on a Keenetic KN-1012 while adding the restore in phy_detach(),
as the other way out of the same bind cycle.

Save the interrupt number on entry and put it back on the error path.
The bus table is not the right source here. The same label is reached
when a second attach of a PHY already attached through the generic
driver fails, and there the field is live. The table also misses a
PHY_MAC_INTERRUPT that a MAC wrote into phydev->irq.

Tested on the KN-1012 with a 6.18 distribution kernel and an injected
failure of the generic probe: phydev->irq reads 15 afterwards, and -1
with only the restore in phy_detach().

Fixes: 6d9f66ac7fec ("net: phy: Fix PHY module checks and NULL deref in phy_attach_direct()")
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <redacted>
---

Notes:
    v13: the commit message says who binds the generic driver, and which
    second attach reaches the label. No code change.
    
    The Fixes: tag differs from patch 3 because 6d9f66ac7fec split this
    failure off the label that calls phy_detach(). The failure was injected
    with a debug-only module parameter, once for one MDIO address.

 drivers/net/phy/phy_device.c | 2 ++
 1 file changed, 2 insertions(+)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index a9c71a286118..8bfb154402ad 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1755,6 +1755,7 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
 	struct mii_bus *bus = phydev->mdio.bus;
 	struct device *d = &phydev->mdio.dev;
 	struct module *ndev_owner = NULL;
+	int irq = phydev->irq;
 	int err;
 
 	/* For Ethernet device drivers that register their own MDIO bus, we
@@ -1896,6 +1897,7 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
 
 error_module_put:
 	module_put(d->driver->owner);
+	phydev->irq = irq;
 	phydev->is_genphy_driven = 0;
 	d->driver = NULL;
 error_put_device:
-- 
2.53.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help