summaryrefslogtreecommitdiffstats
path: root/drivers/net/miidev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/miidev.c')
-rw-r--r--drivers/net/miidev.c63
1 files changed, 41 insertions, 22 deletions
diff --git a/drivers/net/miidev.c b/drivers/net/miidev.c
index d721aac9de..3b73133201 100644
--- a/drivers/net/miidev.c
+++ b/drivers/net/miidev.c
@@ -30,23 +30,37 @@
int miidev_restart_aneg(struct mii_device *mdev)
{
- uint16_t status;
- int timeout;
+ int status, timeout;
+ uint64_t start;
+
+ status = mii_write(mdev, mdev->address, MII_BMCR, BMCR_RESET);
+ if (status)
+ return status;
- /*
- * Reset PHY, then delay 300ns
- */
- mii_write(mdev, mdev->address, MII_BMCR, BMCR_RESET);
+ start = get_time_ns();
+ do {
+ status = mii_read(mdev, mdev->address, MII_BMCR);
+ if (status < 0)
+ return status;
+
+ if (is_timeout(start, SECOND))
+ return -ETIMEDOUT;
+
+ } while (status & BMCR_RESET);
if (mdev->flags & MIIDEV_FORCE_LINK)
return 0;
- udelay(1000);
-
if (mdev->flags & MIIDEV_FORCE_10) {
printf("Forcing 10 Mbps ethernet link... ");
+
status = mii_read(mdev, mdev->address, MII_BMSR);
- mii_write(mdev, mdev->address, MII_BMCR, BMCR_FULLDPLX | BMCR_CTST);
+ if (status < 0)
+ return status;
+
+ status = mii_write(mdev, mdev->address, MII_BMCR, BMCR_FULLDPLX | BMCR_CTST);
+ if (status)
+ return status;
timeout = 20;
do { /* wait for link status to go down */
@@ -56,6 +70,8 @@ int miidev_restart_aneg(struct mii_device *mdev)
break;
}
status = mii_read(mdev, mdev->address, MII_BMSR);
+ if (status < 0)
+ return status;
} while (status & BMSR_LSTATUS);
} else { /* MII100 */
@@ -63,10 +79,18 @@ int miidev_restart_aneg(struct mii_device *mdev)
* Set the auto-negotiation advertisement register bits
*/
status = mii_read(mdev, mdev->address, MII_ADVERTISE);
+ if (status < 0)
+ return status;
+
status |= ADVERTISE_ALL;
- mii_write(mdev, mdev->address, MII_ADVERTISE, status);
- mii_write(mdev, mdev->address, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
+ status = mii_write(mdev, mdev->address, MII_ADVERTISE, status);
+ if (status)
+ return status;
+
+ status = mii_write(mdev, mdev->address, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
+ if (status)
+ return status;
}
return 0;
@@ -74,27 +98,22 @@ int miidev_restart_aneg(struct mii_device *mdev)
int miidev_wait_aneg(struct mii_device *mdev)
{
- uint64_t start;
int status;
+ uint64_t start = get_time_ns();
if (mdev->flags & MIIDEV_FORCE_LINK)
return 0;
- /*
- * Wait for AN completion
- */
- start = get_time_ns();
do {
+ status = mii_read(mdev, mdev->address, MII_BMSR);
+ if (status < 0)
+ return status;
+
if (is_timeout(start, 5 * SECOND)) {
printf("%s: Autonegotiation timeout\n", mdev->cdev.name);
- return -1;
+ return -ETIMEDOUT;
}
- status = mii_read(mdev, mdev->address, MII_BMSR);
- if (status < 0) {
- printf("%s: Autonegotiation failed. status: 0x%04x\n", mdev->cdev.name, status);
- return -1;
- }
} while (!(status & BMSR_LSTATUS));
return 0;