The MDIO write callback reports success even if the controller stays busy and no write is issued. Propagate timeout errors and wait for write completion so failure of the final transaction is reported to phylib as well. Return ETIMEDOUT for read timeouts too. Fixes: 0638dec01e89 ("[PATCH] net: au1000_eth: PHY framework conversion") Signed-off-by: Florian Fainelli --- drivers/net/ethernet/amd/au1000_eth.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c index 70319b432182..a507a524370f 100644 --- a/drivers/net/ethernet/amd/au1000_eth.c +++ b/drivers/net/ethernet/amd/au1000_eth.c @@ -278,7 +278,7 @@ static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg) mdelay(1); if (--timedout == 0) { netdev_err(dev, "read_MII busy timeout!!\n"); - return -1; + return -ETIMEDOUT; } } @@ -292,14 +292,14 @@ static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg) mdelay(1); if (--timedout == 0) { netdev_err(dev, "mdio_read busy timeout!!\n"); - return -1; + return -ETIMEDOUT; } } return readl(mii_data_reg); } -static void au1000_mdio_write(struct net_device *dev, int phy_addr, - int reg, u16 value) +static int au1000_mdio_write(struct net_device *dev, int phy_addr, + int reg, u16 value) { struct au1000_private *aup = netdev_priv(dev); u32 *const mii_control_reg = &aup->mac->mii_control; @@ -311,7 +311,7 @@ static void au1000_mdio_write(struct net_device *dev, int phy_addr, mdelay(1); if (--timedout == 0) { netdev_err(dev, "mdio_write busy timeout!!\n"); - return; + return -ETIMEDOUT; } } @@ -320,6 +320,17 @@ static void au1000_mdio_write(struct net_device *dev, int phy_addr, writel(value, mii_data_reg); writel(mii_control, mii_control_reg); + + timedout = 20; + while (readl(mii_control_reg) & MAC_MII_BUSY) { + mdelay(1); + if (--timedout == 0) { + netdev_err(dev, "mdio_write busy timeout!!\n"); + return -ETIMEDOUT; + } + } + + return 0; } static int au1000_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) @@ -344,8 +355,7 @@ static int au1000_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum, */ au1000_enable_mac(dev, 0); - au1000_mdio_write(dev, phy_addr, regnum, value); - return 0; + return au1000_mdio_write(dev, phy_addr, regnum, value); } static int au1000_mdiobus_reset(struct mii_bus *bus) -- 2.53.0