*/
 int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
 {
-       if (!phydev->is_c45)
-               return -EOPNOTSUPP;
+       if (regnum > (u16)~0 || devad > 32)
+               return -EINVAL;
 
-       return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
-                           MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff));
+       if (phydev->drv->read_mmd)
+               return phydev->drv->read_mmd(phydev, devad, regnum);
+
+       if (phydev->is_c45) {
+               u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);
+               return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, addr);
+       }
+
+       return phy_read_mmd_indirect(phydev, regnum, devad);
 }
 EXPORT_SYMBOL(phy_read_mmd);
 
  */
 int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
 {
-       if (!phydev->is_c45)
-               return -EOPNOTSUPP;
+       if (regnum > (u16)~0 || devad > 32)
+               return -EINVAL;
+
+       if (phydev->drv->read_mmd)
+               return phydev->drv->write_mmd(phydev, devad, regnum, val);
+
+       if (phydev->is_c45) {
+               u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);
+
+               return mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
+                                    addr, val);
+       }
 
-       regnum = MII_ADDR_C45 | ((devad & 0x1f) << 16) | (regnum & 0xffff);
+       phy_write_mmd_indirect(phydev, regnum, devad, val);
 
-       return mdiobus_write(phydev->mdio.bus, phydev->mdio.addr, regnum, val);
+       return 0;
 }
 EXPORT_SYMBOL(phy_write_mmd);
 
         */
        void (*link_change_notify)(struct phy_device *dev);
 
+       /*
+        * Phy specific driver override for reading a MMD register.
+        * This function is optional for PHY specific drivers.  When
+        * not provided, the default MMD read function will be used
+        * by phy_read_mmd(), which will use either a direct read for
+        * Clause 45 PHYs or an indirect read for Clause 22 PHYs.
+        *  devnum is the MMD device number within the PHY device,
+        *  regnum is the register within the selected MMD device.
+        */
+       int (*read_mmd)(struct phy_device *dev, int devnum, u16 regnum);
+
+       /*
+        * Phy specific driver override for writing a MMD register.
+        * This function is optional for PHY specific drivers.  When
+        * not provided, the default MMD write function will be used
+        * by phy_write_mmd(), which will use either a direct write for
+        * Clause 45 PHYs, or an indirect write for Clause 22 PHYs.
+        *  devnum is the MMD device number within the PHY device,
+        *  regnum is the register within the selected MMD device.
+        *  val is the value to be written.
+        */
+       int (*write_mmd)(struct phy_device *dev, int devnum, u16 regnum,
+                        u16 val);
+
        /* A function provided by a phy specific driver to override the
         * the PHY driver framework support for reading a MMD register
         * from the PHY. If not supported, return -1. This function is