[PATCH net v3 0/2] net: fix a stale phylink PHY pointer and a lost PHY interrupt

From: Aleksei Sviridkin

Date: Thu Aug 27 2026 - 17:16:50 EST


Two independent fixes, both found while chasing a PHY whose driver is a
module on a rootfs that is not mounted yet when a DSA switch probes.
Neither one depends on that setup, and neither depends on the other.

Patch 1: phylink_bringup_phy() records the PHY in pl->phydev before its
last fallible step, so a failure there leaves a pointer to a PHY the
caller has already detached. A later phylink_disconnect_phy() detaches
it a second time and drops references the first detach already
released.

Patch 2: a PHY that goes through a generic-driver bind cycle comes out
of it in polling mode for good. The specific driver that binds
afterwards never sees the interrupt the firmware node declared.

Tested on an MT7981B board: an Airoha EN8811H on an MT7531 switch port,
its interrupt declared in the device tree, its driver a module on the
rootfs. lan4 attaches with irq=15 rather than irq=POLL, the line is
claimed as mt-eint 0 in /proc/interrupts, and its counter goes 1 -> 3
-> 5 across two forced aneg restarts, matching the link dropping and
coming back each time, and holding steady in between. wan, whose
internal PHY has no interrupt in the device tree, still attaches with
irq=POLL: that is the observation which says the bus table cannot hand
back an interrupt the device never had. Patch 2's other exit, the one
in phy_attach_direct(), needs a generic probe to fail and is
compile-tested only.

---
Changes in v3:
- retargeted at net (Andrew Lunn, Paolo Abeni)
- patch 2: added a Fixes: tag naming the commit that introduced
phylib, where both halves of the cycle arrived together; the commit
message drops the phrase Andrew flagged and says what
mdiobus_alloc() does to bus->irq[] instead, and answers why the
restore is conditional; the analysis below the scissors is replaced
by a link to v2 (Andrew Lunn, Paolo Abeni)
- patch 2: reword the new helper's comment to the mdiobus_alloc()
form (Andrew Lunn)
- patch 1: carries Andrew's Reviewed-by, otherwise untouched
- that comment is the only diff change since v2; no code flow
changed, so the test results above still describe this code
- v2: https://lore.kernel.org/netdev/20260824024029.41310-1-f@xxxxxx/
- v1: https://lore.kernel.org/netdev/20260822155259.87146-1-f@xxxxxx/

Aleksei Sviridkin (2):
net: phylink: unwind the PHY binding when bringup fails late
net: phy: restore the interrupt after a generic-driver bind cycle

drivers/net/phy/phy_device.c | 14 ++++++++++++++
drivers/net/phy/phylink.c | 29 ++++++++++++++++++++---------
2 files changed, 34 insertions(+), 9 deletions(-)

--
2.55.0