From aa63217916e1818a28b711384a9340d965ad073f Mon Sep 17 00:00:00 2001 From: Ciprian Regus Date: Wed, 8 Jul 2026 01:33:38 +0300 Subject: [PATCH] net: phy: add generic helpers for direct C45 MMD access Some PHYs support direct C45 register access but not C22 indirect MMD access (registers 0xD and 0xE). When discovered via C22, phylib routes MMD access through the indirect path, which won't work on these devices. Add genphy_read_mmd_c45() and genphy_write_mmd_c45() as read_mmd/ write_mmd callbacks that bypass the C22 indirect path and use the bus C45 accessors directly. Reviewed-by: Andrew Lunn Signed-off-by: Ciprian Regus Link: https://patch.msgid.link/20260708-adin1140-driver-v5-10-4aca7b51a58b@analog.com Signed-off-by: Paolo Abeni --- drivers/net/phy/phy_device.c | 25 +++++++++++++++++++++++++ include/linux/phy.h | 3 +++ 2 files changed, 28 insertions(+) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 0615228459ef..94b2e85e00a3 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -2770,6 +2770,31 @@ int genphy_read_abilities(struct phy_device *phydev) } EXPORT_SYMBOL(genphy_read_abilities); +/* Some PHYs support direct C45 register access but not C22 indirect + * MMD access (registers 13 and 14). When discovered via C22, phylib + * routes MMD access through the indirect path, which won't work on + * these devices. These helpers bypass indirect access and use the bus + * C45 accessors directly. + */ +int genphy_read_mmd_c45(struct phy_device *phydev, int devnum, u16 regnum) +{ + struct mii_bus *bus = phydev->mdio.bus; + int addr = phydev->mdio.addr; + + return __mdiobus_c45_read(bus, addr, devnum, regnum); +} +EXPORT_SYMBOL(genphy_read_mmd_c45); + +int genphy_write_mmd_c45(struct phy_device *phydev, int devnum, u16 regnum, + u16 val) +{ + struct mii_bus *bus = phydev->mdio.bus; + int addr = phydev->mdio.addr; + + return __mdiobus_c45_write(bus, addr, devnum, regnum, val); +} +EXPORT_SYMBOL(genphy_write_mmd_c45); + /* This is used for the phy device which doesn't support the MMD extended * register access, but it does have side effect when we are trying to access * the MMD register via indirect method. diff --git a/include/linux/phy.h b/include/linux/phy.h index beff1d6fcc7c..11092c3175b3 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -2302,6 +2302,9 @@ static inline int genphy_no_config_intr(struct phy_device *phydev) { return 0; } +int genphy_read_mmd_c45(struct phy_device *phydev, int devnum, u16 regnum); +int genphy_write_mmd_c45(struct phy_device *phydev, int devnum, u16 regnum, + u16 val); int genphy_read_mmd_unsupported(struct phy_device *phdev, int devad, u16 regnum); int genphy_write_mmd_unsupported(struct phy_device *phdev, int devnum,