Skip to content

Commit

Permalink
net: phy: broadcom: add exp register access methods without buslock
Browse files Browse the repository at this point in the history
Add helper to read and write expansion registers without taking the mdio
lock.

Please note, that this changes the semantics of the read and write.
Before there was no lock between selecting the expansion register and
the actual read/write. This may lead to access failures if there are
parallel accesses. Instead take the bus lock during the whole access
cycle.

Signed-off-by: Michael Walle <michael@walle.cc>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Michael Walle authored and David S. Miller committed May 13, 2020
1 parent ea13d71 commit 7d7e7bc
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 7 deletions.
38 changes: 31 additions & 7 deletions drivers/net/phy/bcm-phy-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,57 @@
#define MII_BCM_CHANNEL_WIDTH 0x2000
#define BCM_CL45VEN_EEE_ADV 0x3c

int bcm_phy_write_exp(struct phy_device *phydev, u16 reg, u16 val)
int __bcm_phy_write_exp(struct phy_device *phydev, u16 reg, u16 val)
{
int rc;

rc = phy_write(phydev, MII_BCM54XX_EXP_SEL, reg);
rc = __phy_write(phydev, MII_BCM54XX_EXP_SEL, reg);
if (rc < 0)
return rc;

return phy_write(phydev, MII_BCM54XX_EXP_DATA, val);
return __phy_write(phydev, MII_BCM54XX_EXP_DATA, val);
}
EXPORT_SYMBOL_GPL(__bcm_phy_write_exp);

int bcm_phy_write_exp(struct phy_device *phydev, u16 reg, u16 val)
{
int rc;

phy_lock_mdio_bus(phydev);
rc = __bcm_phy_write_exp(phydev, reg, val);
phy_unlock_mdio_bus(phydev);

return rc;
}
EXPORT_SYMBOL_GPL(bcm_phy_write_exp);

int bcm_phy_read_exp(struct phy_device *phydev, u16 reg)
int __bcm_phy_read_exp(struct phy_device *phydev, u16 reg)
{
int val;

val = phy_write(phydev, MII_BCM54XX_EXP_SEL, reg);
val = __phy_write(phydev, MII_BCM54XX_EXP_SEL, reg);
if (val < 0)
return val;

val = phy_read(phydev, MII_BCM54XX_EXP_DATA);
val = __phy_read(phydev, MII_BCM54XX_EXP_DATA);

/* Restore default value. It's O.K. if this write fails. */
phy_write(phydev, MII_BCM54XX_EXP_SEL, 0);
__phy_write(phydev, MII_BCM54XX_EXP_SEL, 0);

return val;
}
EXPORT_SYMBOL_GPL(__bcm_phy_read_exp);

int bcm_phy_read_exp(struct phy_device *phydev, u16 reg)
{
int rc;

phy_lock_mdio_bus(phydev);
rc = __bcm_phy_read_exp(phydev, reg);
phy_unlock_mdio_bus(phydev);

return rc;
}
EXPORT_SYMBOL_GPL(bcm_phy_read_exp);

int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum)
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/phy/bcm-phy-lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#define AFE_HPF_TRIM_OTHERS MISC_ADDR(0x3a, 0)


int __bcm_phy_write_exp(struct phy_device *phydev, u16 reg, u16 val);
int __bcm_phy_read_exp(struct phy_device *phydev, u16 reg);
int bcm_phy_write_exp(struct phy_device *phydev, u16 reg, u16 val);
int bcm_phy_read_exp(struct phy_device *phydev, u16 reg);

Expand Down

0 comments on commit 7d7e7bc

Please sign in to comment.