[12/14] drivers: net: dsa: qca8k: clear MASTER_EN after phy read/write
diff mbox series

Message ID 20210423014741.11858-13-ansuelsmth@gmail.com
State New, archived
Headers show
Series
  • Multiple improvement to qca8k stability
Related show

Commit Message

Ansuel Smith April 23, 2021, 1:47 a.m. UTC
Clear MDIO_MASTER_EN bit from MDIO_MASTER_CTRL after read/write
operation. The MDIO_MASTER_EN bit is not reset after read/write
operation and the next operation can be wrongly interpreted by the
switch as a mdio operation. This cause a production of wrong/garbage
data from the switch and underfined bheavior. (random port drop,
unplugged port flagged with link up, wrong port speed)

Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
 drivers/net/dsa/qca8k.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

Patch
diff mbox series

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index 12d2c97d1417..88a0234f1a7b 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -613,6 +613,7 @@  static int
 qca8k_mdio_write(struct qca8k_priv *priv, int port, u32 regnum, u16 data)
 {
 	u32 phy, val;
+	int ret;
 
 	if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
 		return -EINVAL;
@@ -628,8 +629,13 @@  qca8k_mdio_write(struct qca8k_priv *priv, int port, u32 regnum, u16 data)
 
 	qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
 
-	return qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
-		QCA8K_MDIO_MASTER_BUSY);
+	ret = qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
+			      QCA8K_MDIO_MASTER_BUSY);
+
+	qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
+			QCA8K_MDIO_MASTER_EN);
+
+	return ret;
 }
 
 static int
@@ -657,6 +663,9 @@  qca8k_mdio_read(struct qca8k_priv *priv, int port, u32 regnum)
 	val = (qca8k_read(priv, QCA8K_MDIO_MASTER_CTRL) &
 		QCA8K_MDIO_MASTER_DATA_MASK);
 
+	qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL,
+			QCA8K_MDIO_MASTER_EN);
+
 	return val;
 }