Skip to content

Commit

Permalink
net: phy: micrel: Fix concurrent register access
Browse files Browse the repository at this point in the history
Make Extended page register accessing atomic,
to overcome unexpected output from register
reads/writes.

Fixes: 7c2dcfa ("net: phy: micrel: Add support for LAN8804 PHY")
Signed-off-by: Divya Koppera<Divya.Koppera@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Divya Koppera authored and David S. Miller committed Mar 4, 2022
1 parent 6af3b42 commit 4488f6b
Showing 1 changed file with 16 additions and 14 deletions.
30 changes: 16 additions & 14 deletions drivers/net/phy/micrel.c
Original file line number Diff line number Diff line change
Expand Up @@ -1596,30 +1596,32 @@ static int lanphy_read_page_reg(struct phy_device *phydev, int page, u32 addr)
{
u32 data;

phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL, page);
phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, addr);
phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL,
(page | LAN_EXT_PAGE_ACCESS_CTRL_EP_FUNC));
data = phy_read(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA);
phy_lock_mdio_bus(phydev);
__phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL, page);
__phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, addr);
__phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL,
(page | LAN_EXT_PAGE_ACCESS_CTRL_EP_FUNC));
data = __phy_read(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA);
phy_unlock_mdio_bus(phydev);

return data;
}

static int lanphy_write_page_reg(struct phy_device *phydev, int page, u16 addr,
u16 val)
{
phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL, page);
phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, addr);
phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL,
(page | LAN_EXT_PAGE_ACCESS_CTRL_EP_FUNC));
phy_lock_mdio_bus(phydev);
__phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL, page);
__phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, addr);
__phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL,
page | LAN_EXT_PAGE_ACCESS_CTRL_EP_FUNC);

val = phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, val);
if (val) {
val = __phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, val);
if (val != 0)
phydev_err(phydev, "Error: phy_write has returned error %d\n",
val);
return val;
}
return 0;
phy_unlock_mdio_bus(phydev);
return val;
}

static int lan8814_config_init(struct phy_device *phydev)
Expand Down

0 comments on commit 4488f6b

Please sign in to comment.