aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAuke Kok <auke-jan.h.kok@intel.com>2006-06-27 12:06:32 -0400
committerAuke Kok <juke-jan.h.kok@intel.com>2006-06-27 12:06:32 -0400
commit79f05bf0ba9b41561600f3cdfdf86b5184fc6675 (patch)
tree74530615703e52b238ec38c2fac2670a2493113e
parent2db10a081c5c1082d58809a1bcf1a6073f4db160 (diff)
e1000: Make PHY powerup/down a function
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>
-rw-r--r--drivers/net/e1000/e1000_main.c76
1 files changed, 49 insertions, 27 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 52d698bb2595..813d5e0e458d 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -428,14 +428,6 @@ e1000_up(struct e1000_adapter *adapter)
428 428
429 /* hardware has been reset, we need to reload some things */ 429 /* hardware has been reset, we need to reload some things */
430 430
431 /* Reset the PHY if it was previously powered down */
432 if (adapter->hw.media_type == e1000_media_type_copper) {
433 uint16_t mii_reg;
434 e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
435 if (mii_reg & MII_CR_POWER_DOWN)
436 e1000_phy_hw_reset(&adapter->hw);
437 }
438
439 e1000_set_multi(netdev); 431 e1000_set_multi(netdev);
440 432
441 e1000_restore_vlan(adapter); 433 e1000_restore_vlan(adapter);
@@ -464,12 +456,56 @@ e1000_up(struct e1000_adapter *adapter)
464 return 0; 456 return 0;
465} 457}
466 458
459/**
460 * e1000_power_up_phy - restore link in case the phy was powered down
461 * @adapter: address of board private structure
462 *
463 * The phy may be powered down to save power and turn off link when the
464 * driver is unloaded and wake on lan is not enabled (among others)
465 * *** this routine MUST be followed by a call to e1000_reset ***
466 *
467 **/
468
469static void e1000_power_up_phy(struct e1000_adapter *adapter)
470{
471 uint16_t mii_reg = 0;
472
473 /* Just clear the power down bit to wake the phy back up */
474 if (adapter->hw.media_type == e1000_media_type_copper) {
475 /* according to the manual, the phy will retain its
476 * settings across a power-down/up cycle */
477 e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
478 mii_reg &= ~MII_CR_POWER_DOWN;
479 e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
480 }
481}
482
483static void e1000_power_down_phy(struct e1000_adapter *adapter)
484{
485 boolean_t mng_mode_enabled = (adapter->hw.mac_type >= e1000_82571) &&
486 e1000_check_mng_mode(&adapter->hw);
487 /* Power down the PHY so no link is implied when interface is down
488 * The PHY cannot be powered down if any of the following is TRUE
489 * (a) WoL is enabled
490 * (b) AMT is active
491 * (c) SoL/IDER session is active */
492 if (!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
493 adapter->hw.media_type == e1000_media_type_copper &&
494 !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN) &&
495 !mng_mode_enabled &&
496 !e1000_check_phy_reset_block(&adapter->hw)) {
497 uint16_t mii_reg = 0;
498 e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
499 mii_reg |= MII_CR_POWER_DOWN;
500 e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
501 mdelay(1);
502 }
503}
504
467void 505void
468e1000_down(struct e1000_adapter *adapter) 506e1000_down(struct e1000_adapter *adapter)
469{ 507{
470 struct net_device *netdev = adapter->netdev; 508 struct net_device *netdev = adapter->netdev;
471 boolean_t mng_mode_enabled = (adapter->hw.mac_type >= e1000_82571) &&
472 e1000_check_mng_mode(&adapter->hw);
473 509
474 e1000_irq_disable(adapter); 510 e1000_irq_disable(adapter);
475 511
@@ -489,23 +525,6 @@ e1000_down(struct e1000_adapter *adapter)
489 e1000_reset(adapter); 525 e1000_reset(adapter);
490 e1000_clean_all_tx_rings(adapter); 526 e1000_clean_all_tx_rings(adapter);
491 e1000_clean_all_rx_rings(adapter); 527 e1000_clean_all_rx_rings(adapter);
492
493 /* Power down the PHY so no link is implied when interface is down *
494 * The PHY cannot be powered down if any of the following is TRUE *
495 * (a) WoL is enabled
496 * (b) AMT is active
497 * (c) SoL/IDER session is active */
498 if (!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
499 adapter->hw.media_type == e1000_media_type_copper &&
500 !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN) &&
501 !mng_mode_enabled &&
502 !e1000_check_phy_reset_block(&adapter->hw)) {
503 uint16_t mii_reg;
504 e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
505 mii_reg |= MII_CR_POWER_DOWN;
506 e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
507 mdelay(1);
508 }
509} 528}
510 529
511void 530void
@@ -1117,6 +1136,8 @@ e1000_open(struct net_device *netdev)
1117 if (err) 1136 if (err)
1118 goto err_up; 1137 goto err_up;
1119 1138
1139 e1000_power_up_phy(adapter);
1140
1120 if ((err = e1000_up(adapter))) 1141 if ((err = e1000_up(adapter)))
1121 goto err_up; 1142 goto err_up;
1122 adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; 1143 adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
@@ -1162,6 +1183,7 @@ e1000_close(struct net_device *netdev)
1162 1183
1163 WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags)); 1184 WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
1164 e1000_down(adapter); 1185 e1000_down(adapter);
1186 e1000_power_down_phy(adapter);
1165 e1000_free_irq(adapter); 1187 e1000_free_irq(adapter);
1166 1188
1167 e1000_free_all_tx_resources(adapter); 1189 e1000_free_all_tx_resources(adapter);