AR8216: improve mmd register access

Combine all bus operations for one MMD access in one function.
Protecting all these bus operations with one lock also helps
to avoid potential issues due to bus operations intercepting
the register and data write.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>

SVN-Revision: 48914
This commit is contained in:
John Crispin 2016-03-04 08:33:33 +00:00
parent d3776bdfc9
commit 3a03c08c82
3 changed files with 17 additions and 13 deletions

View file

@ -308,25 +308,33 @@ ar8xxx_phy_dbg_write(struct ar8xxx_priv *priv, int phy_addr,
mutex_unlock(&bus->mdio_lock); mutex_unlock(&bus->mdio_lock);
} }
static inline void
ar8xxx_phy_mmd_prep(struct mii_bus *bus, int phy_addr, u16 addr, u16 reg)
{
bus->write(bus, phy_addr, MII_ATH_MMD_ADDR, addr);
bus->write(bus, phy_addr, MII_ATH_MMD_DATA, reg);
bus->write(bus, phy_addr, MII_ATH_MMD_ADDR, addr | 0x4000);
}
void void
ar8xxx_phy_mmd_write(struct ar8xxx_priv *priv, int phy_addr, u16 addr, u16 data) ar8xxx_phy_mmd_write(struct ar8xxx_priv *priv, int phy_addr, u16 addr, u16 reg, u16 data)
{ {
struct mii_bus *bus = priv->mii_bus; struct mii_bus *bus = priv->mii_bus;
mutex_lock(&bus->mdio_lock); mutex_lock(&bus->mdio_lock);
bus->write(bus, phy_addr, MII_ATH_MMD_ADDR, addr); ar8xxx_phy_mmd_prep(bus, phy_addr, addr, reg);
bus->write(bus, phy_addr, MII_ATH_MMD_DATA, data); bus->write(bus, phy_addr, MII_ATH_MMD_DATA, data);
mutex_unlock(&bus->mdio_lock); mutex_unlock(&bus->mdio_lock);
} }
u16 u16
ar8xxx_phy_mmd_read(struct ar8xxx_priv *priv, int phy_addr, u16 addr) ar8xxx_phy_mmd_read(struct ar8xxx_priv *priv, int phy_addr, u16 addr, u16 reg)
{ {
struct mii_bus *bus = priv->mii_bus; struct mii_bus *bus = priv->mii_bus;
u16 data; u16 data;
mutex_lock(&bus->mdio_lock); mutex_lock(&bus->mdio_lock);
bus->write(bus, phy_addr, MII_ATH_MMD_ADDR, addr); ar8xxx_phy_mmd_prep(bus, phy_addr, addr, reg);
data = bus->read(bus, phy_addr, MII_ATH_MMD_DATA); data = bus->read(bus, phy_addr, MII_ATH_MMD_DATA);
mutex_unlock(&bus->mdio_lock); mutex_unlock(&bus->mdio_lock);

View file

@ -478,9 +478,9 @@ void
ar8xxx_phy_dbg_write(struct ar8xxx_priv *priv, int phy_addr, ar8xxx_phy_dbg_write(struct ar8xxx_priv *priv, int phy_addr,
u16 dbg_addr, u16 dbg_data); u16 dbg_addr, u16 dbg_data);
void void
ar8xxx_phy_mmd_write(struct ar8xxx_priv *priv, int phy_addr, u16 addr, u16 data); ar8xxx_phy_mmd_write(struct ar8xxx_priv *priv, int phy_addr, u16 addr, u16 reg, u16 data);
u16 u16
ar8xxx_phy_mmd_read(struct ar8xxx_priv *priv, int phy_addr, u16 addr); ar8xxx_phy_mmd_read(struct ar8xxx_priv *priv, int phy_addr, u16 addr, u16 reg);
void void
ar8xxx_phy_init(struct ar8xxx_priv *priv); ar8xxx_phy_init(struct ar8xxx_priv *priv);
int int

View file

@ -139,13 +139,10 @@ ar8327_phy_fixup(struct ar8xxx_priv *priv, int phy)
break; break;
case 2: case 2:
ar8xxx_phy_mmd_write(priv, phy, 0x7, 0x3c); ar8xxx_phy_mmd_write(priv, phy, 0x7, 0x3c, 0x0);
ar8xxx_phy_mmd_write(priv, phy, 0x4007, 0x0);
/* fallthrough */ /* fallthrough */
case 4: case 4:
ar8xxx_phy_mmd_write(priv, phy, 0x3, 0x800d); ar8xxx_phy_mmd_write(priv, phy, 0x3, 0x800d, 0x803f);
ar8xxx_phy_mmd_write(priv, phy, 0x4003, 0x803f);
ar8xxx_phy_dbg_write(priv, phy, 0x3d, 0x6860); ar8xxx_phy_dbg_write(priv, phy, 0x3d, 0x6860);
ar8xxx_phy_dbg_write(priv, phy, 0x5, 0x2c46); ar8xxx_phy_dbg_write(priv, phy, 0x5, 0x2c46);
ar8xxx_phy_dbg_write(priv, phy, 0x3c, 0x6000); ar8xxx_phy_dbg_write(priv, phy, 0x3c, 0x6000);
@ -744,8 +741,7 @@ ar8327_read_port_eee_status(struct ar8xxx_priv *priv, int port)
phy = port - 1; phy = port - 1;
/* EEE Ability Auto-negotiation Result */ /* EEE Ability Auto-negotiation Result */
ar8xxx_phy_mmd_write(priv, phy, 0x7, 0x8000); t = ar8xxx_phy_mmd_read(priv, phy, 0x7, 0x8000);
t = ar8xxx_phy_mmd_read(priv, phy, 0x4007);
return mmd_eee_adv_to_ethtool_adv_t(t); return mmd_eee_adv_to_ethtool_adv_t(t);
} }