[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210414222841.82548-1-mail@david-bauer.net>
Date: Thu, 15 Apr 2021 00:28:40 +0200
From: David Bauer <mail@...id-bauer.net>
To: netdev@...r.kernel.org
Cc: andrew@...n.ch
Subject: [PATCH net-next 1/2] net: phy: at803x: use paged reads
Refactor the page-switching in at803x_aneg_done to use
paged reads as suggested by Andrew Lunn.
This way, potential race conditions are avoided, as the
MDIO lock was previously not taken.
Suggested-by: Andrew Lunn <andrew@...n.ch>
Signed-off-by: David Bauer <mail@...id-bauer.net>
---
drivers/net/phy/at803x.c | 42 +++++++++++++++++++++++++++++++++++-----
1 file changed, 37 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index c2aa4c92edde..b3243ad570c7 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -144,6 +144,9 @@
#define ATH8035_PHY_ID 0x004dd072
#define AT8030_PHY_ID_MASK 0xffffffef
+#define AT803X_PAGE_FIBER 0
+#define AT803X_PAGE_COPPER 1
+
MODULE_DESCRIPTION("Qualcomm Atheros AR803x PHY driver");
MODULE_AUTHOR("Matus Ujhelyi");
MODULE_LICENSE("GPL");
@@ -198,6 +201,35 @@ static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
return phy_write(phydev, AT803X_DEBUG_DATA, val);
}
+static int at803x_write_page(struct phy_device *phydev, int page)
+{
+ int mask;
+ int set;
+
+ if (page == AT803X_PAGE_COPPER) {
+ set = AT803X_BT_BX_REG_SEL;
+ mask = 0;
+ } else {
+ set = 0;
+ mask = AT803X_BT_BX_REG_SEL;
+ }
+
+ return __phy_modify(phydev, AT803X_REG_CHIP_CONFIG, mask, set);
+}
+
+static int at803x_read_page(struct phy_device *phydev)
+{
+ int ccr = __phy_read(phydev, AT803X_REG_CHIP_CONFIG);
+
+ if (ccr < 0)
+ return ccr;
+
+ if (ccr & AT803X_BT_BX_REG_SEL)
+ return AT803X_PAGE_COPPER;
+
+ return AT803X_PAGE_FIBER;
+}
+
static int at803x_enable_rx_delay(struct phy_device *phydev)
{
return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0,
@@ -753,6 +785,7 @@ static void at803x_link_change_notify(struct phy_device *phydev)
static int at803x_aneg_done(struct phy_device *phydev)
{
+ int pssr;
int ccr;
int aneg_done = genphy_aneg_done(phydev);
@@ -767,16 +800,13 @@ static int at803x_aneg_done(struct phy_device *phydev)
if ((ccr & AT803X_MODE_CFG_MASK) != AT803X_MODE_CFG_SGMII)
return aneg_done;
- /* switch to SGMII/fiber page */
- phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr & ~AT803X_BT_BX_REG_SEL);
+ pssr = phy_read_paged(phydev, AT803X_PAGE_FIBER, AT803X_PSSR);
/* check if the SGMII link is OK. */
- if (!(phy_read(phydev, AT803X_PSSR) & AT803X_PSSR_MR_AN_COMPLETE)) {
+ if (!(pssr & AT803X_PSSR_MR_AN_COMPLETE)) {
phydev_warn(phydev, "803x_aneg_done: SGMII link is not ok\n");
aneg_done = 0;
}
- /* switch back to copper page */
- phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr | AT803X_BT_BX_REG_SEL);
return aneg_done;
}
@@ -1196,6 +1226,8 @@ static struct phy_driver at803x_driver[] = {
.get_wol = at803x_get_wol,
.suspend = at803x_suspend,
.resume = at803x_resume,
+ .read_page = at803x_read_page,
+ .write_page = at803x_write_page,
/* PHY_GBIT_FEATURES */
.read_status = at803x_read_status,
.aneg_done = at803x_aneg_done,
--
2.31.1
Powered by blists - more mailing lists