Thread (17 messages) 17 messages, 2 authors, 4d ago
COOLING4d

[PATCH net-next v5 3/8] net: phy: add (*notify_phy_attach/detach)() hooks to struct mii_bus

From: Markus Stockhausen <hidden>
Date: 2026-07-22 06:24:14
Also in: linux-devicetree
Subsystem: ethernet phy library, networking drivers, the rest · Maintainers: Andrew Lunn, Heiner Kallweit, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

From: Daniel Golle <daniel@makrotopia.org>

Some MDIO buses require to program PHY polling registers depending on
the PHY type. RealTek switch SoCs are the most prominent example of a
DSA switch which doesn't allow to program MAC speed, duplex and
flow-control settings without using PHY polling to do so [1].

Avoid a half-baked solution in the MDIO bus driver because

- it must reinvent the bus scanning to determine the PHYs and
- it must anticipate the right point in time (e.g. deferred PHYs).

Hence there is a need to inform the MDIO bus driver that a PHY is
being attached or detached. Provide two simple hooks in struct
mii_bus which are called

- right after a PHY has been attached
- just before the PHY is going to be detached

The implementation is symmetric so that the detach notifier is only
called when the attach notification succeeded.

Remark! A slightly different version of this patch was part of a
former series [2]. The discussion already showed that an initialization
hook should be placed somewhere late during the whole setup. This
commit implants it right after phy_init_hw() as suggested. On top of
this it adds the detach hook.

[1] https://github.com/openwrt/openwrt/pull/21515#discussion_r2714069716
[2] https://lore.kernel.org/netdev/cover.1769053496.git.daniel@makrotopia.org/ (local)

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Signed-off-by: Markus Stockhausen <redacted>
---
 drivers/net/phy/phy_device.c | 11 +++++++++++
 include/linux/phy.h          | 19 +++++++++++++++++++
 2 files changed, 30 insertions(+)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 94b2e85e00a3..a62c2ff6c2aa 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1876,6 +1876,13 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
 	if (err)
 		goto error;
 
+	if (phydev->mdio.bus->notify_phy_attach) {
+		err = phydev->mdio.bus->notify_phy_attach(phydev);
+		if (err)
+			goto error;
+		phydev->mdio_bus_notified = true;
+	}
+
 	phy_resume(phydev);
 
 	/**
@@ -1919,6 +1926,10 @@ void phy_detach(struct phy_device *phydev)
 	struct module *ndev_owner = NULL;
 	struct mii_bus *bus;
 
+	if (phydev->mdio_bus_notified && phydev->mdio.bus->notify_phy_detach)
+		phydev->mdio.bus->notify_phy_detach(phydev);
+	phydev->mdio_bus_notified = false;
+
 	if (phydev->devlink) {
 		device_link_del(phydev->devlink);
 		phydev->devlink = NULL;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 11092c3175b3..2d30e087a233 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -376,6 +376,23 @@ struct mii_bus {
 			 int regnum, u16 val);
 	/** @reset: Perform a reset of the bus */
 	int (*reset)(struct mii_bus *bus);
+	/**
+	 * @notify_phy_attach: Perform post-attach handling for MDIO bus
+	 *   drivers. Called in phy_attach_direct() right after phy_init_hw()
+	 *   and before phy_resume(). At this point, the PHY is still
+	 *   suspended, and @phydev->attached_dev may be NULL (e.g. for
+	 *   standalone PHYs). Runs in process context and may sleep. Return
+	 *   0 on success or a negative errno on failure (which aborts the
+	 *   attach sequence).
+	 */
+	int (*notify_phy_attach)(struct phy_device *phydev);
+	/**
+	 * @notify_phy_detach: Perform pre-detach handling for MDIO bus
+	 *   drivers. Called in phy_detach() before device links and resources
+	 *   are cleaned up. Runs in process context and may sleep. Only
+	 *   invoked if @notify_phy_attach was previously called and succeeded.
+	 */
+	void (*notify_phy_detach)(struct phy_device *phydev);
 
 	/** @stats: Statistic counters per device on the bus */
 	struct mdio_bus_stats stats[PHY_MAX_ADDR];
@@ -574,6 +591,7 @@ struct phy_oatc14_sqi_capability {
  * @has_fixups: Set to true if this PHY has fixups/quirks.
  * @suspended: Set to true if this PHY has been suspended successfully.
  * @suspended_by_mdio_bus: Set to true if this PHY was suspended by MDIO bus.
+ * @mdio_bus_notified: Set to true if post-attach bus notificaton succeeded.
  * @sysfs_links: Internal boolean tracking sysfs symbolic links setup/removal.
  * @loopback_enabled: Set true if this PHY has been loopbacked successfully.
  * @downshifted_rate: Set true if link speed has been downshifted.
@@ -685,6 +703,7 @@ struct phy_device {
 	unsigned has_fixups:1;
 	unsigned suspended:1;
 	unsigned suspended_by_mdio_bus:1;
+	unsigned mdio_bus_notified:1;
 	unsigned sysfs_links:1;
 	unsigned loopback_enabled:1;
 	unsigned downshifted_rate:1;
-- 
2.55.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