aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ar71xx/files/drivers/net
diff options
context:
space:
mode:
authorJohn Crispin <john@openwrt.org>2014-12-07 16:52:58 +0000
committerJohn Crispin <john@openwrt.org>2014-12-07 16:52:58 +0000
commit4caa8d50add5cf72f6e2d5caa3ebb6aa2b9ae443 (patch)
treebda32062bee14f24c99adbeddcb1c06ecfb83286 /target/linux/ar71xx/files/drivers/net
parent951866a8eb86e16c3de111dd84da5a1cfe1be152 (diff)
downloadupstream-4caa8d50add5cf72f6e2d5caa3ebb6aa2b9ae443.tar.gz
upstream-4caa8d50add5cf72f6e2d5caa3ebb6aa2b9ae443.tar.bz2
upstream-4caa8d50add5cf72f6e2d5caa3ebb6aa2b9ae443.zip
ag71xx: replace fixed PHY reset wait time in ar7240sw_setup
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
Diffstat (limited to 'target/linux/ar71xx/files/drivers/net')
-rw-r--r--target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c
index d4ccc02eb4..7f26196f3d 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c
@@ -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;