From: Harini Katakam <hari...@xilinx.com>

Replace the while loop in MDIO read/write functions with a timeout.
In addition, add a check for MDIO bus busy before initiating a new
operation as well to make sure there is no ongoing MDIO operation.

Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.da...@xilinx.com>
Signed-off-by: Harini Katakam <hari...@xilinx.com>
---
 drivers/net/ethernet/cadence/macb_main.c | 54 ++++++++++++++++++++++++++++++--
 1 file changed, 52 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb_main.c 
b/drivers/net/ethernet/cadence/macb_main.c
index d09bd43..f4030c1 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -321,6 +321,21 @@ static int macb_mdio_read(struct mii_bus *bus, int mii_id, 
int regnum)
 {
        struct macb *bp = bus->priv;
        int value;
+       ulong timeout;
+
+       timeout = jiffies + msecs_to_jiffies(1000);
+       /* wait for end of transfer */
+       do {
+               if (MACB_BFEXT(IDLE, macb_readl(bp, NSR)))
+                       break;
+
+               cpu_relax();
+       } while (!time_after_eq(jiffies, timeout));
+
+       if (time_after_eq(jiffies, timeout)) {
+               netdev_err(bp->dev, "wait for end of transfer timed out\n");
+               return -ETIMEDOUT;
+       }
 
        macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF)
                              | MACB_BF(RW, MACB_MAN_READ)
@@ -328,9 +343,19 @@ static int macb_mdio_read(struct mii_bus *bus, int mii_id, 
int regnum)
                              | MACB_BF(REGA, regnum)
                              | MACB_BF(CODE, MACB_MAN_CODE)));
 
+       timeout = jiffies + msecs_to_jiffies(1000);
        /* wait for end of transfer */
-       while (!MACB_BFEXT(IDLE, macb_readl(bp, NSR)))
+       do {
+               if (MACB_BFEXT(IDLE, macb_readl(bp, NSR)))
+                       break;
+
                cpu_relax();
+       } while (!time_after_eq(jiffies, timeout));
+
+       if (time_after_eq(jiffies, timeout)) {
+               netdev_err(bp->dev, "wait for end of transfer timed out\n");
+               return -ETIMEDOUT;
+       }
 
        value = MACB_BFEXT(DATA, macb_readl(bp, MAN));
 
@@ -341,6 +366,21 @@ static int macb_mdio_write(struct mii_bus *bus, int 
mii_id, int regnum,
                           u16 value)
 {
        struct macb *bp = bus->priv;
+       ulong timeout;
+
+       timeout = jiffies + msecs_to_jiffies(1000);
+       /* wait for end of transfer */
+       do {
+               if (MACB_BFEXT(IDLE, macb_readl(bp, NSR)))
+                       break;
+
+               cpu_relax();
+       } while (!time_after_eq(jiffies, timeout));
+
+       if (time_after_eq(jiffies, timeout)) {
+               netdev_err(bp->dev, "wait for end of transfer timed out\n");
+               return -ETIMEDOUT;
+       }
 
        macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF)
                              | MACB_BF(RW, MACB_MAN_WRITE)
@@ -349,9 +389,19 @@ static int macb_mdio_write(struct mii_bus *bus, int 
mii_id, int regnum,
                              | MACB_BF(CODE, MACB_MAN_CODE)
                              | MACB_BF(DATA, value)));
 
+       timeout = jiffies + msecs_to_jiffies(1000);
        /* wait for end of transfer */
-       while (!MACB_BFEXT(IDLE, macb_readl(bp, NSR)))
+       do {
+               if (MACB_BFEXT(IDLE, macb_readl(bp, NSR)))
+                       break;
+
                cpu_relax();
+       } while (!time_after_eq(jiffies, timeout));
+
+       if (time_after_eq(jiffies, timeout)) {
+               netdev_err(bp->dev, "wait for end of transfer timed out\n");
+               return -ETIMEDOUT;
+       }
 
        return 0;
 }
-- 
2.7.4

Reply via email to