[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210423014741.11858-13-ansuelsmth@gmail.com>
Date: Fri, 23 Apr 2021 03:47:38 +0200
From: Ansuel Smith <ansuelsmth@...il.com>
To: Florian Fainelli <f.fainelli@...il.com>
Cc: Ansuel Smith <ansuelsmth@...il.com>, Andrew Lunn <andrew@...n.ch>,
Vivien Didelot <vivien.didelot@...il.com>,
Vladimir Oltean <olteanv@...il.com>,
"David S. Miller" <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>,
Rob Herring <robh+dt@...nel.org>,
Heiner Kallweit <hkallweit1@...il.com>,
Russell King <linux@...linux.org.uk>, netdev@...r.kernel.org,
devicetree@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH 12/14] drivers: net: dsa: qca8k: clear MASTER_EN after phy read/write
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@...il.com>
---
drivers/net/dsa/qca8k.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
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;
}
--
2.30.2
Powered by blists - more mailing lists