diff options
author | Ansuel Smith <ansuelsmth@gmail.com> | 2021-05-15 00:00:07 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-05-15 01:30:22 +0300 |
commit | 63c33bbfeb6842a956a0eb12901e28eb335bdb18 (patch) | |
tree | d625ecad77a0d596333b1e4c911fc4ac9397e221 | |
parent | e4b9977cee1583da38a6e9118078bb728aaccf7b (diff) | |
download | linux-63c33bbfeb6842a956a0eb12901e28eb335bdb18.tar.xz |
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)
Also on driver remove the MASTER_CTRL can be left set and cause the
malfunction of any next driver using the mdio device.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/dsa/qca8k.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index dedbc6565516..a2b4d5097868 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -649,8 +649,14 @@ qca8k_mdio_write(struct qca8k_priv *priv, int port, u32 regnum, u16 data) if (ret) return ret; - 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); + + /* even if the busy_wait timeouts try to clear the MASTER_EN */ + qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL, + QCA8K_MDIO_MASTER_EN); + + return ret; } static int @@ -685,6 +691,10 @@ qca8k_mdio_read(struct qca8k_priv *priv, int port, u32 regnum) val &= QCA8K_MDIO_MASTER_DATA_MASK; + /* even if the busy_wait timeouts try to clear the MASTER_EN */ + qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL, + QCA8K_MDIO_MASTER_EN); + return val; } |