diff mbox series

[net-next,1/3] net: phy: broadcom: add helper to write/read RDB registers

Message ID 20200417192858.6997-1-michael@walle.cc
State Changes Requested
Delegated to: David Miller
Headers show
Series [net-next,1/3] net: phy: broadcom: add helper to write/read RDB registers | expand

Commit Message

Michael Walle April 17, 2020, 7:28 p.m. UTC
RDB regsiters are used on newer Broadcom PHYs. Add helper to read, write
and modify these registers.

Signed-off-by: Michael Walle <michael@walle.cc>
---
 drivers/net/phy/bcm-phy-lib.c | 80 +++++++++++++++++++++++++++++++++++
 drivers/net/phy/bcm-phy-lib.h |  9 ++++
 include/linux/brcmphy.h       |  3 ++
 3 files changed, 92 insertions(+)

Comments

Florian Fainelli April 17, 2020, 7:34 p.m. UTC | #1
On 4/17/2020 12:28 PM, Michael Walle wrote:
> RDB regsiters are used on newer Broadcom PHYs. Add helper to read, write
> and modify these registers.

Only if you have to respin: please correct the typo above: regsiters vs. 
registers.

> 
> Signed-off-by: Michael Walle <michael@walle.cc>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Andrew Lunn April 18, 2020, 2:13 p.m. UTC | #2
On Fri, Apr 17, 2020 at 09:28:56PM +0200, Michael Walle wrote:
> RDB regsiters are used on newer Broadcom PHYs. Add helper to read, write
> and modify these registers.

It would be nice to give a hint what RDB means?

Thanks
	Andrew
Florian Fainelli April 18, 2020, 3:55 p.m. UTC | #3
On 4/18/2020 7:13 AM, Andrew Lunn wrote:
> On Fri, Apr 17, 2020 at 09:28:56PM +0200, Michael Walle wrote:
>> RDB regsiters are used on newer Broadcom PHYs. Add helper to read, write
>> and modify these registers.
> 
> It would be nice to give a hint what RDB means?

It means Register Data Base, it is meant to be a linear register offset 
as opposed to the more convulated shadow 18, 1c or other expansion 
registers.
Michael Walle April 18, 2020, 8:09 p.m. UTC | #4
Am 2020-04-18 17:55, schrieb Florian Fainelli:
> On 4/18/2020 7:13 AM, Andrew Lunn wrote:
>> On Fri, Apr 17, 2020 at 09:28:56PM +0200, Michael Walle wrote:
>>> RDB regsiters are used on newer Broadcom PHYs. Add helper to read, 
>>> write
>>> and modify these registers.
>> 
>> It would be nice to give a hint what RDB means?
> 
> It means Register Data Base, it is meant to be a linear register
> offset as opposed to the more convulated shadow 18, 1c or other
> expansion registers.

Oh I just found some comment to another linux patch explaining this.
Because there is no trace what RDB actually means in the datasheets
from Broadcom I've seen so far.

-michael
diff mbox series

Patch

diff --git a/drivers/net/phy/bcm-phy-lib.c b/drivers/net/phy/bcm-phy-lib.c
index e77b274a09fd..d5f9a2701989 100644
--- a/drivers/net/phy/bcm-phy-lib.c
+++ b/drivers/net/phy/bcm-phy-lib.c
@@ -155,6 +155,86 @@  int bcm_phy_write_shadow(struct phy_device *phydev, u16 shadow,
 }
 EXPORT_SYMBOL_GPL(bcm_phy_write_shadow);
 
+int __bcm_phy_read_rdb(struct phy_device *phydev, u16 rdb)
+{
+	int val;
+
+	val = __phy_write(phydev, MII_BCM54XX_RDB_ADDR, rdb);
+	if (val < 0)
+		return val;
+
+	return __phy_read(phydev, MII_BCM54XX_RDB_DATA);
+}
+EXPORT_SYMBOL_GPL(__bcm_phy_read_rdb);
+
+int bcm_phy_read_rdb(struct phy_device *phydev, u16 rdb)
+{
+	int ret;
+
+	phy_lock_mdio_bus(phydev);
+	ret = __bcm_phy_read_rdb(phydev, rdb);
+	phy_unlock_mdio_bus(phydev);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(bcm_phy_read_rdb);
+
+int __bcm_phy_write_rdb(struct phy_device *phydev, u16 rdb, u16 val)
+{
+	int ret;
+
+	ret = __phy_write(phydev, MII_BCM54XX_RDB_ADDR, rdb);
+	if (ret < 0)
+		return ret;
+
+	return __phy_write(phydev, MII_BCM54XX_RDB_DATA, val);
+}
+EXPORT_SYMBOL_GPL(__bcm_phy_write_rdb);
+
+int bcm_phy_write_rdb(struct phy_device *phydev, u16 rdb, u16 val)
+{
+	int ret;
+
+	phy_lock_mdio_bus(phydev);
+	ret = __bcm_phy_write_rdb(phydev, rdb, val);
+	phy_unlock_mdio_bus(phydev);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(bcm_phy_write_rdb);
+
+int __bcm_phy_modify_rdb(struct phy_device *phydev, u16 rdb, u16 mask, u16 set)
+{
+	int new, ret;
+
+	ret = __phy_write(phydev, MII_BCM54XX_RDB_ADDR, rdb);
+	if (ret < 0)
+		return ret;
+
+	ret = __phy_read(phydev, MII_BCM54XX_RDB_DATA);
+	if (ret < 0)
+		return ret;
+
+	new = (ret & ~mask) | set;
+	if (new == ret)
+		return 0;
+
+	return __phy_write(phydev, MII_BCM54XX_RDB_DATA, new);
+}
+EXPORT_SYMBOL_GPL(__bcm_phy_modify_rdb);
+
+int bcm_phy_modify_rdb(struct phy_device *phydev, u16 rdb, u16 mask, u16 set)
+{
+	int ret;
+
+	phy_lock_mdio_bus(phydev);
+	ret = __bcm_phy_modify_rdb(phydev, rdb, mask, set);
+	phy_unlock_mdio_bus(phydev);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(bcm_phy_modify_rdb);
+
 int bcm_phy_enable_apd(struct phy_device *phydev, bool dll_pwr_down)
 {
 	int val;
diff --git a/drivers/net/phy/bcm-phy-lib.h b/drivers/net/phy/bcm-phy-lib.h
index 129df819be8c..4d3de91cda6c 100644
--- a/drivers/net/phy/bcm-phy-lib.h
+++ b/drivers/net/phy/bcm-phy-lib.h
@@ -48,6 +48,15 @@  int bcm_phy_write_shadow(struct phy_device *phydev, u16 shadow,
 			 u16 val);
 int bcm_phy_read_shadow(struct phy_device *phydev, u16 shadow);
 
+int __bcm_phy_write_rdb(struct phy_device *phydev, u16 rdb, u16 val);
+int bcm_phy_write_rdb(struct phy_device *phydev, u16 rdb, u16 val);
+int __bcm_phy_read_rdb(struct phy_device *phydev, u16 rdb);
+int bcm_phy_read_rdb(struct phy_device *phydev, u16 rdb);
+int __bcm_phy_modify_rdb(struct phy_device *phydev, u16 rdb, u16 mask,
+			 u16 set);
+int bcm_phy_modify_rdb(struct phy_device *phydev, u16 rdb, u16 mask,
+		       u16 set);
+
 int bcm_phy_ack_intr(struct phy_device *phydev);
 int bcm_phy_config_intr(struct phy_device *phydev);
 
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index 6462c5447872..e14f78b3c8a4 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -114,6 +114,9 @@ 
 #define MII_BCM54XX_SHD_VAL(x)	((x & 0x1f) << 10)
 #define MII_BCM54XX_SHD_DATA(x)	((x & 0x3ff) << 0)
 
+#define MII_BCM54XX_RDB_ADDR	0x1e
+#define MII_BCM54XX_RDB_DATA	0x1f
+
 /*
  * AUXILIARY CONTROL SHADOW ACCESS REGISTERS.  (PHY REG 0x18)
  */