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@xxxxxxxxx> --- 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