}
 EXPORT_SYMBOL_GPL(__mdiobus_modify_changed);
 
+/**
+ * __mdiobus_c45_read - Unlocked version of the mdiobus_c45_read function
+ * @bus: the mii_bus struct
+ * @addr: the phy address
+ * @devad: device address to read
+ * @regnum: register number to read
+ *
+ * Read a MDIO bus register. Caller must hold the mdio bus lock.
+ *
+ * NOTE: MUST NOT be called from interrupt context.
+ */
+int __mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum)
+{
+       int retval;
+
+       lockdep_assert_held_once(&bus->mdio_lock);
+
+       if (bus->read_c45)
+               retval = bus->read_c45(bus, addr, devad, regnum);
+       else
+               retval = bus->read(bus, addr, mdiobus_c45_addr(devad, regnum));
+
+       trace_mdio_access(bus, 1, addr, regnum, retval, retval);
+       mdiobus_stats_acct(&bus->stats[addr], true, retval);
+
+       return retval;
+}
+EXPORT_SYMBOL(__mdiobus_c45_read);
+
+/**
+ * __mdiobus_c45_write - Unlocked version of the mdiobus_write function
+ * @bus: the mii_bus struct
+ * @addr: the phy address
+ * @devad: device address to read
+ * @regnum: register number to write
+ * @val: value to write to @regnum
+ *
+ * Write a MDIO bus register. Caller must hold the mdio bus lock.
+ *
+ * NOTE: MUST NOT be called from interrupt context.
+ */
+int __mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum,
+                       u16 val)
+{
+       int err;
+
+       lockdep_assert_held_once(&bus->mdio_lock);
+
+       if (bus->write_c45)
+               err = bus->write_c45(bus, addr, devad, regnum, val);
+       else
+               err = bus->write(bus, addr, mdiobus_c45_addr(devad, regnum),
+                                val);
+
+       trace_mdio_access(bus, 0, addr, regnum, val, err);
+       mdiobus_stats_acct(&bus->stats[addr], false, err);
+
+       return err;
+}
+EXPORT_SYMBOL(__mdiobus_c45_write);
+
+/**
+ * __mdiobus_c45_modify_changed - Unlocked version of the mdiobus_modify function
+ * @bus: the mii_bus struct
+ * @addr: the phy address
+ * @devad: device address to read
+ * @regnum: register number to modify
+ * @mask: bit mask of bits to clear
+ * @set: bit mask of bits to set
+ *
+ * Read, modify, and if any change, write the register value back to the
+ * device. Any error returns a negative number.
+ *
+ * NOTE: MUST NOT be called from interrupt context.
+ */
+static int __mdiobus_c45_modify_changed(struct mii_bus *bus, int addr,
+                                       int devad, u32 regnum, u16 mask,
+                                       u16 set)
+{
+       int new, ret;
+
+       ret = __mdiobus_c45_read(bus, addr, devad, regnum);
+       if (ret < 0)
+               return ret;
+
+       new = (ret & ~mask) | set;
+       if (new == ret)
+               return 0;
+
+       ret = __mdiobus_c45_write(bus, addr, devad, regnum, new);
+
+       return ret < 0 ? ret : 1;
+}
+
 /**
  * mdiobus_read_nested - Nested version of the mdiobus_read function
  * @bus: the mii_bus struct
 }
 EXPORT_SYMBOL(mdiobus_read);
 
+/**
+ * mdiobus_c45_read - Convenience function for reading a given MII mgmt register
+ * @bus: the mii_bus struct
+ * @addr: the phy address
+ * @devad: device address to read
+ * @regnum: register number to read
+ *
+ * NOTE: MUST NOT be called from interrupt context,
+ * because the bus read/write functions may wait for an interrupt
+ * to conclude the operation.
+ */
+int mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum)
+{
+       int retval;
+
+       mutex_lock(&bus->mdio_lock);
+       retval = __mdiobus_c45_read(bus, addr, devad, regnum);
+       mutex_unlock(&bus->mdio_lock);
+
+       return retval;
+}
+EXPORT_SYMBOL(mdiobus_c45_read);
+
 /**
  * mdiobus_write_nested - Nested version of the mdiobus_write function
  * @bus: the mii_bus struct
 }
 EXPORT_SYMBOL(mdiobus_write);
 
+/**
+ * mdiobus_c45_write - Convenience function for writing a given MII mgmt register
+ * @bus: the mii_bus struct
+ * @addr: the phy address
+ * @devad: device address to read
+ * @regnum: register number to write
+ * @val: value to write to @regnum
+ *
+ * NOTE: MUST NOT be called from interrupt context,
+ * because the bus read/write functions may wait for an interrupt
+ * to conclude the operation.
+ */
+int mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum,
+                     u16 val)
+{
+       int err;
+
+       mutex_lock(&bus->mdio_lock);
+       err = __mdiobus_c45_write(bus, addr, devad, regnum, val);
+       mutex_unlock(&bus->mdio_lock);
+
+       return err;
+}
+EXPORT_SYMBOL(mdiobus_c45_write);
+
 /**
  * mdiobus_modify - Convenience function for modifying a given mdio device
  *     register
 }
 EXPORT_SYMBOL_GPL(mdiobus_modify);
 
+/**
+ * mdiobus_c45_modify - Convenience function for modifying a given mdio device
+ *     register
+ * @bus: the mii_bus struct
+ * @addr: the phy address
+ * @devad: device address to read
+ * @regnum: register number to write
+ * @mask: bit mask of bits to clear
+ * @set: bit mask of bits to set
+ */
+int mdiobus_c45_modify(struct mii_bus *bus, int addr, int devad, u32 regnum,
+                      u16 mask, u16 set)
+{
+       int err;
+
+       mutex_lock(&bus->mdio_lock);
+       err = __mdiobus_c45_modify_changed(bus, addr, devad, regnum,
+                                          mask, set);
+       mutex_unlock(&bus->mdio_lock);
+
+       return err < 0 ? err : 0;
+}
+EXPORT_SYMBOL_GPL(mdiobus_c45_modify);
+
 /**
  * mdiobus_modify_changed - Convenience function for modifying a given mdio
  *     device register and returning if it changed
 }
 EXPORT_SYMBOL_GPL(mdiobus_modify_changed);
 
+/**
+ * mdiobus_c45_modify_changed - Convenience function for modifying a given mdio
+ *     device register and returning if it changed
+ * @bus: the mii_bus struct
+ * @addr: the phy address
+ * @devad: device address to read
+ * @regnum: register number to write
+ * @mask: bit mask of bits to clear
+ * @set: bit mask of bits to set
+ */
+int mdiobus_c45_modify_changed(struct mii_bus *bus, int devad, int addr,
+                              u32 regnum, u16 mask, u16 set)
+{
+       int err;
+
+       mutex_lock(&bus->mdio_lock);
+       err = __mdiobus_c45_modify_changed(bus, addr, devad, regnum, mask, set);
+       mutex_unlock(&bus->mdio_lock);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(mdiobus_c45_modify_changed);
+
 /**
  * mdio_bus_match - determine if given MDIO driver supports the given
  *                 MDIO device
 
                   u16 set);
 int mdiobus_modify_changed(struct mii_bus *bus, int addr, u32 regnum,
                           u16 mask, u16 set);
+int __mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum);
+int mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum);
+int __mdiobus_c45_write(struct mii_bus *bus, int addr,  int devad, u32 regnum,
+                       u16 val);
+int mdiobus_c45_write(struct mii_bus *bus, int addr,  int devad, u32 regnum,
+                     u16 val);
+int mdiobus_c45_modify(struct mii_bus *bus, int addr, int devad, u32 regnum,
+                      u16 mask, u16 set);
+
+int mdiobus_c45_modify_changed(struct mii_bus *bus, int addr, int devad,
+                              u32 regnum, u16 mask, u16 set);
 
 static inline int mdiodev_read(struct mdio_device *mdiodev, u32 regnum)
 {
        return FIELD_GET(MII_DEVADDR_C45_MASK, regnum);
 }
 
-static inline int __mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad,
-                                    u16 regnum)
+static inline int mdiodev_c45_modify(struct mdio_device *mdiodev, int devad,
+                                    u32 regnum, u16 mask, u16 set)
 {
-       return __mdiobus_read(bus, prtad, mdiobus_c45_addr(devad, regnum));
+       return mdiobus_c45_modify(mdiodev->bus, mdiodev->addr, devad, regnum,
+                                 mask, set);
 }
 
-static inline int __mdiobus_c45_write(struct mii_bus *bus, int prtad, int devad,
-                                     u16 regnum, u16 val)
+static inline int mdiodev_c45_modify_changed(struct mdio_device *mdiodev,
+                                            int devad, u32 regnum, u16 mask,
+                                            u16 set)
 {
-       return __mdiobus_write(bus, prtad, mdiobus_c45_addr(devad, regnum),
-                              val);
-}
-
-static inline int mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad,
-                                  u16 regnum)
-{
-       return mdiobus_read(bus, prtad, mdiobus_c45_addr(devad, regnum));
-}
-
-static inline int mdiobus_c45_write(struct mii_bus *bus, int prtad, int devad,
-                                   u16 regnum, u16 val)
-{
-       return mdiobus_write(bus, prtad, mdiobus_c45_addr(devad, regnum), val);
+       return mdiobus_c45_modify_changed(mdiodev->bus, mdiodev->addr, devad,
+                                         regnum, mask, set);
 }
 
 static inline int mdiodev_c45_read(struct mdio_device *mdiodev, int devad,