Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
[linux-2.6-microblaze.git] / drivers / net / phy / phy_device.c
index b13c528..94961e7 100644 (file)
@@ -1770,6 +1770,36 @@ int genphy_restart_aneg(struct phy_device *phydev)
 }
 EXPORT_SYMBOL(genphy_restart_aneg);
 
+/**
+ * genphy_check_and_restart_aneg - Enable and restart auto-negotiation
+ * @phydev: target phy_device struct
+ * @restart: whether aneg restart is requested
+ *
+ * Check, and restart auto-negotiation if needed.
+ */
+int genphy_check_and_restart_aneg(struct phy_device *phydev, bool restart)
+{
+       int ret = 0;
+
+       if (!restart) {
+               /* Advertisement hasn't changed, but maybe aneg was never on to
+                * begin with?  Or maybe phy was isolated?
+                */
+               ret = phy_read(phydev, MII_BMCR);
+               if (ret < 0)
+                       return ret;
+
+               if (!(ret & BMCR_ANENABLE) || (ret & BMCR_ISOLATE))
+                       restart = true;
+       }
+
+       if (restart)
+               ret = genphy_restart_aneg(phydev);
+
+       return ret;
+}
+EXPORT_SYMBOL(genphy_check_and_restart_aneg);
+
 /**
  * __genphy_config_aneg - restart auto-negotiation or write BMCR
  * @phydev: target phy_device struct
@@ -1795,23 +1825,7 @@ int __genphy_config_aneg(struct phy_device *phydev, bool changed)
        else if (err)
                changed = true;
 
-       if (!changed) {
-               /* Advertisement hasn't changed, but maybe aneg was never on to
-                * begin with?  Or maybe phy was isolated?
-                */
-               int ctl = phy_read(phydev, MII_BMCR);
-
-               if (ctl < 0)
-                       return ctl;
-
-               if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE))
-                       changed = true; /* do restart aneg */
-       }
-
-       /* Only restart aneg if we are advertising something different
-        * than we were before.
-        */
-       return changed ? genphy_restart_aneg(phydev) : 0;
+       return genphy_check_and_restart_aneg(phydev, changed);
 }
 EXPORT_SYMBOL(__genphy_config_aneg);
 
@@ -1978,6 +1992,36 @@ int genphy_read_lpa(struct phy_device *phydev)
 }
 EXPORT_SYMBOL(genphy_read_lpa);
 
+/**
+ * genphy_read_status_fixed - read the link parameters for !aneg mode
+ * @phydev: target phy_device struct
+ *
+ * Read the current duplex and speed state for a PHY operating with
+ * autonegotiation disabled.
+ */
+int genphy_read_status_fixed(struct phy_device *phydev)
+{
+       int bmcr = phy_read(phydev, MII_BMCR);
+
+       if (bmcr < 0)
+               return bmcr;
+
+       if (bmcr & BMCR_FULLDPLX)
+               phydev->duplex = DUPLEX_FULL;
+       else
+               phydev->duplex = DUPLEX_HALF;
+
+       if (bmcr & BMCR_SPEED1000)
+               phydev->speed = SPEED_1000;
+       else if (bmcr & BMCR_SPEED100)
+               phydev->speed = SPEED_100;
+       else
+               phydev->speed = SPEED_10;
+
+       return 0;
+}
+EXPORT_SYMBOL(genphy_read_status_fixed);
+
 /**
  * genphy_read_status - check the link status and update current link state
  * @phydev: target phy_device struct
@@ -2012,22 +2056,9 @@ int genphy_read_status(struct phy_device *phydev)
        if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) {
                phy_resolve_aneg_linkmode(phydev);
        } else if (phydev->autoneg == AUTONEG_DISABLE) {
-               int bmcr = phy_read(phydev, MII_BMCR);
-
-               if (bmcr < 0)
-                       return bmcr;
-
-               if (bmcr & BMCR_FULLDPLX)
-                       phydev->duplex = DUPLEX_FULL;
-               else
-                       phydev->duplex = DUPLEX_HALF;
-
-               if (bmcr & BMCR_SPEED1000)
-                       phydev->speed = SPEED_1000;
-               else if (bmcr & BMCR_SPEED100)
-                       phydev->speed = SPEED_100;
-               else
-                       phydev->speed = SPEED_10;
+               err = genphy_read_status_fixed(phydev);
+               if (err < 0)
+                       return err;
        }
 
        return 0;
@@ -2575,7 +2606,6 @@ static struct phy_driver genphy_driver = {
        .name           = "Generic PHY",
        .soft_reset     = genphy_no_soft_reset,
        .get_features   = genphy_read_abilities,
-       .aneg_done      = genphy_aneg_done,
        .suspend        = genphy_suspend,
        .resume         = genphy_resume,
        .set_loopback   = genphy_loopback,