[U-Boot] [PATCH] net: lpc32xx: Fix MDIO busy wait

amessier.tyco at gmail.com amessier.tyco at gmail.com
Wed Dec 16 19:37:46 CET 2015


From: Alexandre Messier <amessier at tycoint.com>

The MDIO read function waits on the busy flag after issuing the read
command, while the MDIO write function waits on the busy flag before
issuing the write command.

This causes an issue when writing then immediately reading. As the MDIO
module is still busy, the read command is not processed. The wait on
busy flag in the read command passes because the previous write command
finishes. In the end, the value returned by the read function is
whatever was present in the MDIO data register.

Fix the issue by making sure the busy flag is cleared before issuing a
read command. This way, it is still possible to issue a write command
and continue executing u-boot code while the command is processed by
the hardware. Any following MDIO read/write commands after a write
command will wait for a cleared busy flag.

Signed-off-by: Alexandre Messier <amessier at tycoint.com>
---
 drivers/net/lpc32xx_eth.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/drivers/net/lpc32xx_eth.c b/drivers/net/lpc32xx_eth.c
index e76e9bc..25629a9 100644
--- a/drivers/net/lpc32xx_eth.c
+++ b/drivers/net/lpc32xx_eth.c
@@ -246,6 +246,20 @@ static int mii_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 *data)
 		return -EFAULT;
 	}
 
+	/* wait till the MII is not busy */
+	timeout = MII_TIMEOUT;
+	do {
+		/* read MII indicators register */
+		mind_reg = readl(&regs->mind);
+		if (--timeout == 0)
+			break;
+	} while (mind_reg & MIND_BUSY);
+
+	if (timeout == 0) {
+		printf("%s:%u: MII busy timeout\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+
 	/* write the phy and reg addressse into the MII address reg */
 	writel((phy_adr << MADR_PHY_OFFSET) | (reg_ofs << MADR_REG_OFFSET),
 	       &regs->madr);
-- 
1.7.1



More information about the U-Boot mailing list