You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
3.4 KiB
97 lines
3.4 KiB
From: Russell King <rmk+kernel@armlinux.org.uk>
|
|
Date: Wed, 4 Jan 2017 19:20:21 +0000
|
|
Subject: [PATCH] net: phy: make phy_(read|write)_mmd() generic MMD
|
|
accessors
|
|
|
|
Make phy_(read|write)_mmd() generic 802.3 clause 45 register accessors
|
|
for both Clause 22 and Clause 45 PHYs, using either the direct register
|
|
reading for Clause 45, or the indirect method for Clause 22 PHYs.
|
|
Allow this behaviour to be overriden by PHY drivers where necessary.
|
|
|
|
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
|
|
---
|
|
|
|
--- a/drivers/net/phy/phy-core.c
|
|
+++ b/drivers/net/phy/phy-core.c
|
|
@@ -69,11 +69,18 @@ EXPORT_SYMBOL(phy_read_mmd_indirect);
|
|
*/
|
|
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);
|
|
|
|
@@ -125,11 +132,21 @@ EXPORT_SYMBOL(phy_write_mmd_indirect);
|
|
*/
|
|
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);
|
|
--- a/include/linux/phy.h
|
|
+++ b/include/linux/phy.h
|
|
@@ -570,6 +570,30 @@ struct phy_driver {
|
|
*/
|
|
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
|
|
|