ag71xx: replace fixed PHY reset wait time in ar7240sw_setup
authorJohn Crispin <john@openwrt.org>
Sun, 7 Dec 2014 16:52:58 +0000 (16:52 +0000)
committerJohn Crispin <john@openwrt.org>
Sun, 7 Dec 2014 16:52:58 +0000 (16:52 +0000)
Replace the fixed wait time of 1s with polling for BMCR_RESET
to be cleared on all PHYs.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
SVN-Revision: 43538

target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c

index d4ccc02eb483f8e4cdac2fa41433075e4ecf6612..7f26196f3daa5e0ad4584e497a988696339a0939 100644 (file)
@@ -618,6 +618,31 @@ static void ar7240sw_setup(struct ar7240sw *as)
        ar7240sw_reg_rmw(mii, AR7240_REG_SERVICE_TAG, AR7240_SERVICE_TAG_M, 0);
 }
 
+/* inspired by phy_poll_reset in drivers/net/phy/phy_device.c */
+static int
+ar7240sw_phy_poll_reset(struct mii_bus *bus)
+{
+       const unsigned int sleep_msecs = 20;
+       int ret, elapsed, i;
+
+       for (elapsed = sleep_msecs; elapsed <= 600;
+            elapsed += sleep_msecs) {
+               msleep(sleep_msecs);
+               for (i = 0; i < AR7240_NUM_PHYS; i++) {
+                       ret = ar7240sw_phy_read(bus, i, MII_BMCR);
+                       if (ret < 0)
+                               return ret;
+                       if (ret & BMCR_RESET)
+                               break;
+                       if (i == AR7240_NUM_PHYS - 1) {
+                               usleep_range(1000, 2000);
+                               return 0;
+                       }
+               }
+       }
+       return -ETIMEDOUT;
+}
+
 static int ar7240sw_reset(struct ar7240sw *as)
 {
        struct mii_bus *mii = as->mii_bus;
@@ -646,7 +671,9 @@ static int ar7240sw_reset(struct ar7240sw *as)
                ar7240sw_phy_write(mii, i, MII_BMCR,
                                   BMCR_RESET | BMCR_ANENABLE);
        }
-       msleep(1000);
+       ret = ar7240sw_phy_poll_reset(mii);
+       if (ret)
+               return ret;
 
        ar7240sw_setup(as);
        return ret;