@@ -790,6 +790,12 @@ int __mdiobus_read(struct mii_bus *bus, int addr, u32 regnum)
WARN_ON_ONCE(!mutex_is_locked(&bus->mdio_lock));
retval = bus->read(bus, addr, regnum);
+ if (retval == -EOPNOTSUPP && regnum & MII_ADDR_C45) {
+ int c45_devad = (regnum >> 16) & 0x1f;
+
+ mmd_phy_indirect(bus, addr, c45_devad, regnum & 0xfff);
+ retval = bus->read(bus, addr, MII_MMD_DATA);
+ }
trace_mdio_access(bus, 1, addr, regnum, retval, retval);
mdiobus_stats_acct(&bus->stats[addr], true, retval);
@@ -816,6 +822,12 @@ int __mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val)
WARN_ON_ONCE(!mutex_is_locked(&bus->mdio_lock));
err = bus->write(bus, addr, regnum, val);
+ if (err == -EOPNOTSUPP && regnum & MII_ADDR_C45) {
+ int c45_devad = (regnum >> 16) & 0x1f;
+
+ mmd_phy_indirect(bus, addr, c45_devad, regnum & 0xfff);
+ err = bus->write(bus, addr, MII_MMD_DATA, val);
+ }
trace_mdio_access(bus, 0, addr, regnum, val, err);
mdiobus_stats_acct(&bus->stats[addr], false, err);
@@ -395,7 +395,7 @@ int phy_speed_down_core(struct phy_device *phydev)
return __set_linkmode_max_speed(min_common_speed, phydev->advertising);
}
-static void mmd_phy_indirect(struct mii_bus *bus, int phy_addr, int devad,
+void mmd_phy_indirect(struct mii_bus *bus, int phy_addr, int devad,
u16 regnum)
{
/* Write the desired MMD Devad */
@@ -864,6 +864,8 @@ int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
u16 mask, u16 set);
int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
u16 mask, u16 set);
+void mmd_phy_indirect(struct mii_bus *bus, int phy_addr, int devad,
+ u16 regnum);
/**
* __phy_set_bits - Convenience function for setting bits in a PHY register
When the MDIO bus does not support directly clause 45 access, fallback to indirect registers access method to read/write clause 45 registers using clause 22 registers. Signed-off-by: Baruch Siach <baruch@tkos.co.il> --- Is that the right course? Currently, this does not really work on the my target machine, which is using the Armada 385 native MDIO bus (mvmdio) connected to clause 45 Marvell 88E2110 PHY. Registers MDIO_DEVS1 and MDIO_DEVS1 read bogus values which breaks PHY identification. However, the phytool utility reads the same registers correctly: phytool eth1/2:1/5 ieee-phy: reg:0x05 val:0x008a eth1 is connected to another PHY (clause 22) on the same MDIO bus. The same hardware works nicely with the mdio-gpio bus implementation, when mdio pins are muxed as GPIOs. --- drivers/net/phy/mdio_bus.c | 12 ++++++++++++ drivers/net/phy/phy-core.c | 2 +- include/linux/phy.h | 2 ++ 3 files changed, 15 insertions(+), 1 deletion(-)