e1000: Make PHY powerup/down a function
authorAuke Kok <auke-jan.h.kok@intel.com>
Tue, 27 Jun 2006 16:06:32 +0000 (09:06 -0700)
committerAuke Kok <juke-jan.h.kok@intel.com>
Tue, 27 Jun 2006 16:06:32 +0000 (09:06 -0700)
In relation to the irq work done earlier we also move the PHY powerup
and powerdown functions into separate functions and move the calls to
_close and _open, making the PHY stay in it's power state as long as
the device is _up.

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
drivers/net/e1000/e1000_main.c

index 52d698b..813d5e0 100644 (file)
@@ -428,14 +428,6 @@ e1000_up(struct e1000_adapter *adapter)
 
        /* hardware has been reset, we need to reload some things */
 
-       /* Reset the PHY if it was previously powered down */
-       if (adapter->hw.media_type == e1000_media_type_copper) {
-               uint16_t mii_reg;
-               e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
-               if (mii_reg & MII_CR_POWER_DOWN)
-                       e1000_phy_hw_reset(&adapter->hw);
-       }
-
        e1000_set_multi(netdev);
 
        e1000_restore_vlan(adapter);
@@ -464,12 +456,56 @@ e1000_up(struct e1000_adapter *adapter)
        return 0;
 }
 
+/**
+ * e1000_power_up_phy - restore link in case the phy was powered down
+ * @adapter: address of board private structure
+ *
+ * The phy may be powered down to save power and turn off link when the
+ * driver is unloaded and wake on lan is not enabled (among others)
+ * *** this routine MUST be followed by a call to e1000_reset ***
+ *
+ **/
+
+static void e1000_power_up_phy(struct e1000_adapter *adapter)
+{
+       uint16_t mii_reg = 0;
+
+       /* Just clear the power down bit to wake the phy back up */
+       if (adapter->hw.media_type == e1000_media_type_copper) {
+               /* according to the manual, the phy will retain its
+                * settings across a power-down/up cycle */
+               e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
+               mii_reg &= ~MII_CR_POWER_DOWN;
+               e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
+       }
+}
+
+static void e1000_power_down_phy(struct e1000_adapter *adapter)
+{
+       boolean_t mng_mode_enabled = (adapter->hw.mac_type >= e1000_82571) &&
+                                     e1000_check_mng_mode(&adapter->hw);
+       /* Power down the PHY so no link is implied when interface is down
+        * The PHY cannot be powered down if any of the following is TRUE
+        * (a) WoL is enabled
+        * (b) AMT is active
+        * (c) SoL/IDER session is active */
+       if (!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
+           adapter->hw.media_type == e1000_media_type_copper &&
+           !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN) &&
+           !mng_mode_enabled &&
+           !e1000_check_phy_reset_block(&adapter->hw)) {
+               uint16_t mii_reg = 0;
+               e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
+               mii_reg |= MII_CR_POWER_DOWN;
+               e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
+               mdelay(1);
+       }
+}
+
 void
 e1000_down(struct e1000_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
-       boolean_t mng_mode_enabled = (adapter->hw.mac_type >= e1000_82571) &&
-                                     e1000_check_mng_mode(&adapter->hw);
 
        e1000_irq_disable(adapter);
 
@@ -489,23 +525,6 @@ e1000_down(struct e1000_adapter *adapter)
        e1000_reset(adapter);
        e1000_clean_all_tx_rings(adapter);
        e1000_clean_all_rx_rings(adapter);
-
-       /* Power down the PHY so no link is implied when interface is down *
-        * The PHY cannot be powered down if any of the following is TRUE *
-        * (a) WoL is enabled
-        * (b) AMT is active
-        * (c) SoL/IDER session is active */
-       if (!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
-          adapter->hw.media_type == e1000_media_type_copper &&
-          !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN) &&
-          !mng_mode_enabled &&
-          !e1000_check_phy_reset_block(&adapter->hw)) {
-               uint16_t mii_reg;
-               e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
-               mii_reg |= MII_CR_POWER_DOWN;
-               e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
-               mdelay(1);
-       }
 }
 
 void
@@ -1117,6 +1136,8 @@ e1000_open(struct net_device *netdev)
        if (err)
                goto err_up;
 
+       e1000_power_up_phy(adapter);
+
        if ((err = e1000_up(adapter)))
                goto err_up;
        adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
@@ -1162,6 +1183,7 @@ e1000_close(struct net_device *netdev)
 
        WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
        e1000_down(adapter);
+       e1000_power_down_phy(adapter);
        e1000_free_irq(adapter);
 
        e1000_free_all_tx_resources(adapter);