]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net: phy: micrel: Fix concurrent register access
authorDivya Koppera <Divya.Koppera@microchip.com>
Fri, 4 Mar 2022 09:34:16 +0000 (15:04 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 8 Apr 2022 12:06:13 +0000 (14:06 +0200)
[ Upstream commit 4488f6b6148045424459ef1d5b153c6895ee1dbb ]

Make Extended page register accessing atomic,
to overcome unexpected output from register
reads/writes.

Fixes: 7c2dcfa295b1 ("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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/phy/micrel.c

index 76ef4e019ca92e55fb27f79454e1bf83d27605d0..15fe0fa78092f164e89f3006072a25899972eeed 100644 (file)
@@ -1575,11 +1575,13 @@ 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;
 }
@@ -1587,18 +1589,18 @@ static int lanphy_read_page_reg(struct phy_device *phydev, int page, u32 addr)
 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));
-
-       val = phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, val);
-       if (val) {
+       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 != 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 lan8804_config_init(struct phy_device *phydev)