From mboxrd@z Thu Jan 1 00:00:00 1970 From: Vladimir Zapolskiy Date: Mon, 21 Dec 2015 20:55:30 +0200 Subject: [U-Boot] [PATCH] net: lpc32xx: Fix MDIO busy wait In-Reply-To: <1450291066-15805-1-git-send-email-amessier.tyco@gmail.com> References: <1450291066-15805-1-git-send-email-amessier.tyco@gmail.com> Message-ID: <56784B22.20105@mleia.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hi Alexandre, On 16.12.2015 20:37, amessier.tyco at gmail.com wrote: > From: Alexandre Messier > > The MDIO read function waits on the busy flag after issuing the read > command, that's correct, after issuing the read command and before register read. > while the MDIO write function waits on the busy flag before > issuing the write command. and that is not correct, I believe. >From the spec (MII Mgmt Indicators Register): For PHY Write if scan is not used: 1. Write 0 to MCMD 2. Write PHY address and register address to MADR 3. Write data to MWTD --> 4. Wait for busy bit to be cleared in MIND For PHY Read if scan is not used: 1. Write 1 to MCMD 2. Write PHY address and register address to MADR --> 3. Wait for busy bit to be cleared in MIND 4. Write 0 to MCMD 5. Read data from MRDD Could you please test/review an alternative fix? I believe it adds proper serialization of all command sequences (read/read, read/write, write/read and write/write). Thank you in advance. diff --git a/drivers/net/lpc32xx_eth.c b/drivers/net/lpc32xx_eth.c index e76e9bc..3ba5b4b 100644 --- a/drivers/net/lpc32xx_eth.c +++ b/drivers/net/lpc32xx_eth.c @@ -304,6 +304,13 @@ static int mii_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data) return -EFAULT; } + /* write the phy and reg addressse into the MII address reg */ + writel((phy_adr << MADR_PHY_OFFSET) | (reg_ofs << MADR_REG_OFFSET), + ®s->madr); + + /* write data to the MII write register */ + writel(data, ®s->mwtd); + /* wait till the MII is not busy */ timeout = MII_TIMEOUT; do { @@ -319,13 +326,6 @@ static int mii_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data) return -EFAULT; } - /* write the phy and reg addressse into the MII address reg */ - writel((phy_adr << MADR_PHY_OFFSET) | (reg_ofs << MADR_REG_OFFSET), - ®s->madr); - - /* write data to the MII write register */ - writel(data, ®s->mwtd); - /*debug("%s:(adr %d, off %d) <= %04x\n", __func__, phy_adr, reg_ofs, data);*/ > 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. -- With best wishes, Vladimir