* [PATCH net v13 0/4] net: phy: keep a PHY interrupt across a generic bind cycle
@ 2026-10-01 13:02 Aleksei Sviridkin
2026-10-01 13:02 ` [PATCH net v13 1/4] net: usb: lan78xx: register the PHY interrupt with the MDIO bus Aleksei Sviridkin
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Aleksei Sviridkin @ 2026-10-01 13:02 UTC (permalink / raw)
To: netdev
Cc: andrew, andrew+netdev, hkallweit1, linux, davem, edumazet, kuba,
pabeni, horms, olteanv, Thangaraj.S, UNGLinuxDriver,
steve.glendinning, f.fainelli, linux-usb, linux-kernel,
Aleksei Sviridkin
On a Keenetic KN-1012 the EN8811H PHY behind lan4 has its driver as a
module on the root filesystem, so it binds to the generic driver first.
phy_probe() replaces its interrupt with PHY_POLL, and nothing puts it
back when the real driver takes over, so the PHY is polled for the rest
of the uptime.
Patches 1 and 2 put the lan78xx and smsc95xx PHY interrupts into the
MDIO bus table entry of the PHY each driver uses, so there is a number
to restore for them too. Patch 3 restores the interrupt from that table
in phy_detach(). Patch 4 restores it when the generic bind fails inside
phy_attach_direct().
Not covered: a driver without interrupt support that is bound or
unbound through sysfs still leaves PHY_POLL behind. Removing the
substitution from phy_probe() would fix that too, and belongs in
net-next.
Patches 1 and 2 are compile-tested only; a Tested-by from someone with
a LAN78xx or LAN95xx device would help. Patch 4 touches lines that
patch 2 of the attach guard series [3] also changes, so whichever lands
second needs a trivial rebase.
Other drivers that write phydev->irq outside the bus table, checked
against net/main:
- ixp4xx_eth, ax88796c and emac-mac force PHY_POLL themselves, and
none of them attaches again after a detach without forcing it again.
- stmmac and mlxbf_gige already write mdiobus->irq[] as well.
- bcmasp for an internal PHY, genet for an internal PHY before v5,
and tsnep set PHY_MAC_INTERRUPT again after each connect, so a
restore does not last. icplus sets it on every status read of a
switch port.
- sxgbe does it only from probed_phy_irq, which nothing in tree sets.
- ucc_geth only reads the field.
Changes in v13 (since v12) [1]:
- Patches 1 and 2 write only the table entry of the PHY the driver
uses. v12 filled every entry, which gave the one interrupt to every
PHY on a LAN7801 bus. Andrew's Reviewed-by is dropped from both.
- Patches 3 and 4 touch only the PHY being detached or attached, and
keep their code. Patch 4 stays separate: its Fixes: tag differs, and
with patch 3 alone the failed bind behaves as it did before the
series.
Older changelogs are in the v12 cover [1] and the v11 cover [2].
[1] https://lore.kernel.org/r/20260927235733.2619081-1-f@lex.la/
[2] https://lore.kernel.org/r/20260926235024.705646-1-f@lex.la/
[3] https://lore.kernel.org/r/20260924215951.2127682-1-f@lex.la/
Aleksei Sviridkin (4):
net: usb: lan78xx: register the PHY interrupt with the MDIO bus
net: usb: smsc95xx: register the PHY interrupt with the MDIO bus
net: phy: take the interrupt back from the bus on detach
net: phy: restore the interrupt when the generic bind cycle fails
drivers/net/phy/phy_device.c | 4 ++++
drivers/net/usb/lan78xx.c | 1 +
drivers/net/usb/smsc95xx.c | 1 +
3 files changed, 6 insertions(+)
base-commit: a7bfaba4823e3c165bb2004c74eff7c096672bc7
--
2.53.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH net v13 1/4] net: usb: lan78xx: register the PHY interrupt with the MDIO bus
2026-10-01 13:02 [PATCH net v13 0/4] net: phy: keep a PHY interrupt across a generic bind cycle Aleksei Sviridkin
@ 2026-10-01 13:02 ` Aleksei Sviridkin
2026-10-05 16:52 ` Andrew Lunn
2026-10-01 13:02 ` [PATCH net v13 2/4] net: usb: smsc95xx: " Aleksei Sviridkin
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: Aleksei Sviridkin @ 2026-10-01 13:02 UTC (permalink / raw)
To: netdev
Cc: andrew, andrew+netdev, hkallweit1, linux, davem, edumazet, kuba,
pabeni, horms, olteanv, Thangaraj.S, UNGLinuxDriver,
steve.glendinning, f.fainelli, linux-usb, linux-kernel,
Aleksei Sviridkin
The interrupt this driver maps for its PHY is written only into
phydev->irq, while the bus table mdiobus->irq[] keeps reading PHY_POLL
for the same address. That table is where phylib records what the bus
described - phy_device_create() seeds phydev->irq from it - so the
number lives only as long as nothing else writes that one field.
Copy the number into the table entry of the PHY this driver attaches,
and into no other. The chip has one PHY interrupt, and on 7801
phy_mask is 0, so other PHYs on the bus keep what the bus gave them.
The address is known only after the scan, so the write to phydev->irq
stays.
Found going through the drivers that keep a PHY interrupt outside the
bus table, so that the restore on detach later in this series has a
number to hand back here as well.
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
---
Notes:
v13: write only the table entry of the attached PHY, after the scan,
instead of every entry before registration. The driver's number again
wins over a devicetree PHY interrupt, as it did before this series.
Andrew's Reviewed-by is dropped since the code changed.
The PHY_POLL branch is not reached: lan78xx_bind() fails earlier when
the interrupt mapping cannot be created.
Compile-tested only; I have no LAN78xx device. No Fixes: tag, since
nothing reads the bus table back until patch 3.
drivers/net/usb/lan78xx.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index 5655941f1478..babd34cda374 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -2897,6 +2897,7 @@ static int lan78xx_phy_init(struct lan78xx_net *dev)
phydev->irq = dev->domain_data.phyirq;
else
phydev->irq = PHY_POLL;
+ dev->mdiobus->irq[phydev->mdio.addr] = phydev->irq;
netdev_dbg(dev->net, "phydev->irq = %d\n", phydev->irq);
ret = phylink_connect_phy(dev->phylink, phydev);
--
2.53.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH net v13 2/4] net: usb: smsc95xx: register the PHY interrupt with the MDIO bus
2026-10-01 13:02 [PATCH net v13 0/4] net: phy: keep a PHY interrupt across a generic bind cycle Aleksei Sviridkin
2026-10-01 13:02 ` [PATCH net v13 1/4] net: usb: lan78xx: register the PHY interrupt with the MDIO bus Aleksei Sviridkin
@ 2026-10-01 13:02 ` Aleksei Sviridkin
2026-10-05 16:53 ` Andrew Lunn
2026-10-01 13:02 ` [PATCH net v13 3/4] net: phy: take the interrupt back from the bus on detach Aleksei Sviridkin
2026-10-01 13:02 ` [PATCH net v13 4/4] net: phy: restore the interrupt when the generic bind cycle fails Aleksei Sviridkin
3 siblings, 1 reply; 9+ messages in thread
From: Aleksei Sviridkin @ 2026-10-01 13:02 UTC (permalink / raw)
To: netdev
Cc: andrew, andrew+netdev, hkallweit1, linux, davem, edumazet, kuba,
pabeni, horms, olteanv, Thangaraj.S, UNGLinuxDriver,
steve.glendinning, f.fainelli, linux-usb, linux-kernel,
Aleksei Sviridkin
The interrupt this driver maps for its PHY is written only into
phydev->irq, while the bus table mdiobus->irq[] keeps reading PHY_POLL
for the same address. That table is where phylib records what the bus
described - phy_device_create() seeds phydev->irq from it - so the
number lives only as long as nothing else writes that one field.
Copy the number into the table entry of the PHY this driver found, and
into no other. With an external PHY phy_mask is 0, so other PHYs on the
bus keep polling. The address is known only after the scan, so the
write to phydev->irq stays.
Found going through the drivers that keep a PHY interrupt outside the
bus table, so that the restore on detach later in this series has a
number to hand back here as well.
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
---
Notes:
v13: write only the table entry of the PHY found by the scan, instead
of every entry before registration. Andrew's Reviewed-by is dropped
since the code changed.
Compile-tested only; I have no LAN95xx device. No Fixes: tag, for the
same reason as patch 1.
drivers/net/usb/smsc95xx.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 42e4048b574b..130a460c1f54 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -1252,6 +1252,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
goto unregister_mdio;
}
+ pdata->mdiobus->irq[pdata->phydev->mdio.addr] = phy_irq;
pdata->phydev->irq = phy_irq;
pdata->phydev->is_internal = pdata->is_internal_phy;
--
2.53.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH net v13 3/4] net: phy: take the interrupt back from the bus on detach
2026-10-01 13:02 [PATCH net v13 0/4] net: phy: keep a PHY interrupt across a generic bind cycle Aleksei Sviridkin
2026-10-01 13:02 ` [PATCH net v13 1/4] net: usb: lan78xx: register the PHY interrupt with the MDIO bus Aleksei Sviridkin
2026-10-01 13:02 ` [PATCH net v13 2/4] net: usb: smsc95xx: " Aleksei Sviridkin
@ 2026-10-01 13:02 ` Aleksei Sviridkin
2026-10-05 13:26 ` netdev-bot+sashiko
2026-10-05 16:55 ` Andrew Lunn
2026-10-01 13:02 ` [PATCH net v13 4/4] net: phy: restore the interrupt when the generic bind cycle fails Aleksei Sviridkin
3 siblings, 2 replies; 9+ messages in thread
From: Aleksei Sviridkin @ 2026-10-01 13:02 UTC (permalink / raw)
To: netdev
Cc: andrew, andrew+netdev, hkallweit1, linux, davem, edumazet, kuba,
pabeni, horms, olteanv, Thangaraj.S, UNGLinuxDriver,
steve.glendinning, f.fainelli, linux-usb, linux-kernel,
Aleksei Sviridkin
When a PHY's driver is a module that is not loaded yet when the MAC
connects, the PHY gets the generic driver first. phy_probe() then
replaces phydev->irq with PHY_POLL, because genphy has no interrupt
support. Nothing puts the number back, so after the real driver binds
the PHY is polled for the rest of the uptime.
Seen on a Keenetic KN-1012: the Airoha EN8811H behind an MT7531 port
has its driver on the root filesystem. Its devicetree interrupt maps to
irq 15, and after the real driver binds phydev->irq reads -1.
Restore the number when the PHY detaches. It comes from the bus table,
mdiobus->irq[], where the bus or the MAC driver recorded it. Do it only
when phy_attach_direct() bound the generic driver, since that is the
substitution being undone; otherwise the field belongs to whoever wrote
it. Do it before device_release_driver(), because after the release a
probing driver can write the same field.
The store is ordered before the release rather than locked against it:
device_release_driver() takes the device lock itself. A MAC that sets
phydev->irq before phy_start(), as phy.rst describes, is not affected,
since the restore runs on detach, between connections.
Tested on the KN-1012 with a 6.18 distribution kernel: phydev->irq
reads 15 after the real driver binds, and -1 without this patch.
Fixes: 00db8189d984 ("This patch adds a PHY Abstraction Layer to the Linux Kernel, enabling ethernet drivers to remain as ignorant as is reasonable of the connected PHY's design and operation details.")
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
---
Notes:
v13: the commit message no longer says the PHY got the table entry at
creation; after patches 1 and 2 that is not true for those drivers. No
code change.
The PHY module was made to load after the root filesystem, and the
distribution's own late-PHY patch was removed. The value was read with a
debug-only module parameter; the three switch ports read 79, 80 and 81
in both runs.
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 94b2e85e00a3..a9c71a286118 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1965,6 +1965,8 @@ void phy_detach(struct phy_device *phydev)
* real driver could be loaded
*/
if (phydev->is_genphy_driven) {
+ /* The release below lets phy_probe() write this field. */
+ phydev->irq = phydev->mdio.bus->irq[phydev->mdio.addr];
device_release_driver(&phydev->mdio.dev);
phydev->is_genphy_driven = 0;
}
--
2.53.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH net v13 4/4] net: phy: restore the interrupt when the generic bind cycle fails
2026-10-01 13:02 [PATCH net v13 0/4] net: phy: keep a PHY interrupt across a generic bind cycle Aleksei Sviridkin
` (2 preceding siblings ...)
2026-10-01 13:02 ` [PATCH net v13 3/4] net: phy: take the interrupt back from the bus on detach Aleksei Sviridkin
@ 2026-10-01 13:02 ` Aleksei Sviridkin
3 siblings, 0 replies; 9+ messages in thread
From: Aleksei Sviridkin @ 2026-10-01 13:02 UTC (permalink / raw)
To: netdev
Cc: andrew, andrew+netdev, hkallweit1, linux, davem, edumazet, kuba,
pabeni, horms, olteanv, Thangaraj.S, UNGLinuxDriver,
steve.glendinning, f.fainelli, linux-usb, linux-kernel,
Aleksei Sviridkin
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 <f@lex.la>
---
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
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net v13 3/4] net: phy: take the interrupt back from the bus on detach
2026-10-01 13:02 ` [PATCH net v13 3/4] net: phy: take the interrupt back from the bus on detach Aleksei Sviridkin
@ 2026-10-05 13:26 ` netdev-bot+sashiko
2026-10-05 16:55 ` Andrew Lunn
1 sibling, 0 replies; 9+ messages in thread
From: netdev-bot+sashiko @ 2026-10-05 13:26 UTC (permalink / raw)
To: f
Cc: netdev, andrew, andrew+netdev, hkallweit1, linux, davem,
edumazet, kuba, pabeni, horms, olteanv, Thangaraj.S,
UNGLinuxDriver, steve.glendinning, f.fainelli, linux-usb,
linux-kernel
Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider.
Critical: 0 · High: 0 · Medium: 1 · Low: 0
If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).
- [Medium] In this commit only, the interrupt restore lives only in
phy_detach() (drivers/net/phy/phy_device.c:1969).
--
net: phy: take the interrupt back from the bus on detach
This commit makes phy_detach() restore phydev->irq from the bus table
(mdio.bus->irq[]) when the generic driver was bound by
phy_attach_direct(). It undoes the PHY_POLL substitution done by
phy_probe() for genphy, so that a real driver bound later can use the
interrupt.
> diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
> index 94b2e85e00a37..a9c71a2861186 100644
> --- a/drivers/net/phy/phy_device.c
> +++ b/drivers/net/phy/phy_device.c
> @@ -1965,6 +1965,8 @@ void phy_detach(struct phy_device *phydev)
> * real driver could be loaded
> */
> if (phydev->is_genphy_driven) {
> + /* The release below lets phy_probe() write this field. */
> + phydev->irq = phydev->mdio.bus->irq[phydev->mdio.addr];
[Severity: Medium]
This patch only restores the irq in phy_detach(). Is there a second way
out of the genphy bind cycle that still leaves phydev->irq at PHY_POLL?
In phy_attach_direct(), the generic probe and bind failures go straight
to error_module_put. That path never reaches the error label that calls
phy_detach():
drivers/net/phy/phy_device.c:phy_attach_direct() {
...
if (phydev->is_genphy_driven) {
err = d->driver->probe(d);
if (err >= 0)
err = device_bind_driver(d);
if (err)
goto error_module_put;
}
...
error_module_put:
module_put(d->driver->owner);
phydev->is_genphy_driven = 0;
d->driver = NULL;
...
}
phy_probe() overwrites the irq before any of its steps that can fail:
drivers/net/phy/phy_device.c:phy_probe() {
...
if (!phy_drv_supports_irq(phydrv) && phy_interrupt_is_valid(phydev))
phydev->irq = PHY_POLL;
...
}
The later steps include get_features, genphy_read_abilities() and
genphy_c45_pma_read_abilities() (all MDIO reads), phy_setup_ports() and
genphy_c45_read_eee_adv(). If one of them fails, or device_bind_driver()
fails, error_module_put clears is_genphy_driven and d->driver but does
not touch phydev->irq. A real driver that binds later would then still
poll, which is the symptom the commit message describes.
The last patch of this series, "net: phy: restore the interrupt when the
generic bind cycle fails", appears to close this gap. It saves
phydev->irq at the start of phy_attach_direct() and restores it under
error_module_put. At this commit on its own, though, the restore covers
only the phy_detach() path.
> device_release_driver(&phydev->mdio.dev);
> phydev->is_genphy_driven = 0;
> }
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261001130236.106059-1-f%40lex.la
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net v13 1/4] net: usb: lan78xx: register the PHY interrupt with the MDIO bus
2026-10-01 13:02 ` [PATCH net v13 1/4] net: usb: lan78xx: register the PHY interrupt with the MDIO bus Aleksei Sviridkin
@ 2026-10-05 16:52 ` Andrew Lunn
0 siblings, 0 replies; 9+ messages in thread
From: Andrew Lunn @ 2026-10-05 16:52 UTC (permalink / raw)
To: Aleksei Sviridkin
Cc: netdev, andrew+netdev, hkallweit1, linux, davem, edumazet, kuba,
pabeni, horms, olteanv, Thangaraj.S, UNGLinuxDriver,
steve.glendinning, f.fainelli, linux-usb, linux-kernel
On Thu, Oct 01, 2026 at 04:02:33PM +0300, Aleksei Sviridkin wrote:
> The interrupt this driver maps for its PHY is written only into
> phydev->irq, while the bus table mdiobus->irq[] keeps reading PHY_POLL
> for the same address. That table is where phylib records what the bus
> described - phy_device_create() seeds phydev->irq from it - so the
> number lives only as long as nothing else writes that one field.
>
> Copy the number into the table entry of the PHY this driver attaches,
> and into no other. The chip has one PHY interrupt, and on 7801
> phy_mask is 0, so other PHYs on the bus keep what the bus gave them.
> The address is known only after the scan, so the write to phydev->irq
> stays.
>
> Found going through the drivers that keep a PHY interrupt outside the
> bus table, so that the restore on detach later in this series has a
> number to hand back here as well.
>
> Assisted-by: LLM
> Signed-off-by: Aleksei Sviridkin <f@lex.la>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net v13 2/4] net: usb: smsc95xx: register the PHY interrupt with the MDIO bus
2026-10-01 13:02 ` [PATCH net v13 2/4] net: usb: smsc95xx: " Aleksei Sviridkin
@ 2026-10-05 16:53 ` Andrew Lunn
0 siblings, 0 replies; 9+ messages in thread
From: Andrew Lunn @ 2026-10-05 16:53 UTC (permalink / raw)
To: Aleksei Sviridkin
Cc: netdev, andrew+netdev, hkallweit1, linux, davem, edumazet, kuba,
pabeni, horms, olteanv, Thangaraj.S, UNGLinuxDriver,
steve.glendinning, f.fainelli, linux-usb, linux-kernel
On Thu, Oct 01, 2026 at 04:02:34PM +0300, Aleksei Sviridkin wrote:
> The interrupt this driver maps for its PHY is written only into
> phydev->irq, while the bus table mdiobus->irq[] keeps reading PHY_POLL
> for the same address. That table is where phylib records what the bus
> described - phy_device_create() seeds phydev->irq from it - so the
> number lives only as long as nothing else writes that one field.
>
> Copy the number into the table entry of the PHY this driver found, and
> into no other. With an external PHY phy_mask is 0, so other PHYs on the
> bus keep polling. The address is known only after the scan, so the
> write to phydev->irq stays.
>
> Found going through the drivers that keep a PHY interrupt outside the
> bus table, so that the restore on detach later in this series has a
> number to hand back here as well.
>
> Assisted-by: LLM
> Signed-off-by: Aleksei Sviridkin <f@lex.la>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net v13 3/4] net: phy: take the interrupt back from the bus on detach
2026-10-01 13:02 ` [PATCH net v13 3/4] net: phy: take the interrupt back from the bus on detach Aleksei Sviridkin
2026-10-05 13:26 ` netdev-bot+sashiko
@ 2026-10-05 16:55 ` Andrew Lunn
1 sibling, 0 replies; 9+ messages in thread
From: Andrew Lunn @ 2026-10-05 16:55 UTC (permalink / raw)
To: Aleksei Sviridkin
Cc: netdev, andrew+netdev, hkallweit1, linux, davem, edumazet, kuba,
pabeni, horms, olteanv, Thangaraj.S, UNGLinuxDriver,
steve.glendinning, f.fainelli, linux-usb, linux-kernel
On Thu, Oct 01, 2026 at 04:02:35PM +0300, Aleksei Sviridkin wrote:
> When a PHY's driver is a module that is not loaded yet when the MAC
> connects, the PHY gets the generic driver first. phy_probe() then
> replaces phydev->irq with PHY_POLL, because genphy has no interrupt
> support. Nothing puts the number back, so after the real driver binds
> the PHY is polled for the rest of the uptime.
>
> Seen on a Keenetic KN-1012: the Airoha EN8811H behind an MT7531 port
> has its driver on the root filesystem. Its devicetree interrupt maps to
> irq 15, and after the real driver binds phydev->irq reads -1.
>
> Restore the number when the PHY detaches. It comes from the bus table,
> mdiobus->irq[], where the bus or the MAC driver recorded it. Do it only
> when phy_attach_direct() bound the generic driver, since that is the
> substitution being undone; otherwise the field belongs to whoever wrote
> it. Do it before device_release_driver(), because after the release a
> probing driver can write the same field.
>
> The store is ordered before the release rather than locked against it:
> device_release_driver() takes the device lock itself. A MAC that sets
> phydev->irq before phy_start(), as phy.rst describes, is not affected,
> since the restore runs on detach, between connections.
>
> Tested on the KN-1012 with a 6.18 distribution kernel: phydev->irq
> reads 15 after the real driver binds, and -1 without this patch.
>
> Fixes: 00db8189d984 ("This patch adds a PHY Abstraction Layer to the Linux Kernel, enabling ethernet drivers to remain as ignorant as is reasonable of the connected PHY's design and operation details.")
> Assisted-by: LLM
> Signed-off-by: Aleksei Sviridkin <f@lex.la>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-10-05 16:55 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-01 13:02 [PATCH net v13 0/4] net: phy: keep a PHY interrupt across a generic bind cycle Aleksei Sviridkin
2026-10-01 13:02 ` [PATCH net v13 1/4] net: usb: lan78xx: register the PHY interrupt with the MDIO bus Aleksei Sviridkin
2026-10-05 16:52 ` Andrew Lunn
2026-10-01 13:02 ` [PATCH net v13 2/4] net: usb: smsc95xx: " Aleksei Sviridkin
2026-10-05 16:53 ` Andrew Lunn
2026-10-01 13:02 ` [PATCH net v13 3/4] net: phy: take the interrupt back from the bus on detach Aleksei Sviridkin
2026-10-05 13:26 ` netdev-bot+sashiko
2026-10-05 16:55 ` Andrew Lunn
2026-10-01 13:02 ` [PATCH net v13 4/4] net: phy: restore the interrupt when the generic bind cycle fails Aleksei Sviridkin
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®