diff options
author | Bruce Allan <bruce.w.allan@intel.com> | 2011-03-23 23:09:03 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-04-13 22:19:22 -0400 |
commit | 78cd29d5a92ae5067377ad42089f2c8781312f4a (patch) | |
tree | fb9845f2fdb6c28890478c7fa8fbcfec79e4543d /drivers | |
parent | 2084b114e3fb0d84e5882f5ee6c7039be52da715 (diff) |
e1000e: If ASPM L0s needs to be disabled, do it prior to enabling device
Based on a patch from Naga Chumbalkar <nagananda.chumbalkar@hp.com>:
If ASPM L0s needs to be disabled due to HW errata, do it prior to
"enabling" the device. This way if the kernel ever defaults its
aspm_policy to POLICY_POWERSAVE, then the e1000e driver will get a
chance to disable ASPM on the misbehaving device *prior* to calling
pci_enable_device_mem(). This will be useful in situations
where the BIOS indicates ASPM support on the server by clearing the
ACPI FADT "ASPM Controls" bit.
Note:
The kernel (2.6.38) currently uses the BIOS "default" as its aspm_policy.
However, Linux distros can diverge from that and set the default to
"powersave".
v2: o cleanup namespace pollution of e1000e_disable_aspm(),
o fix type and initialization of the new aspm_disable_flag in a few
functions, and
o redefine FLAG2_DISABLE_ASPM_L0S to the first unused bit in
adapter->flags2.
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Cc: Naga Chumbalkar <nagananda.chumbalkar@hp.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/e1000e/82571.c | 10 | ||||
-rw-r--r-- | drivers/net/e1000e/e1000.h | 2 | ||||
-rw-r--r-- | drivers/net/e1000e/netdev.c | 29 |
3 files changed, 30 insertions, 11 deletions
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 9fedbca66dfd..ae07d37903ba 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c | |||
@@ -431,9 +431,6 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter) | |||
431 | case e1000_82573: | 431 | case e1000_82573: |
432 | case e1000_82574: | 432 | case e1000_82574: |
433 | case e1000_82583: | 433 | case e1000_82583: |
434 | /* Disable ASPM L0s due to hardware errata */ | ||
435 | e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L0S); | ||
436 | |||
437 | if (pdev->device == E1000_DEV_ID_82573L) { | 434 | if (pdev->device == E1000_DEV_ID_82573L) { |
438 | adapter->flags |= FLAG_HAS_JUMBO_FRAMES; | 435 | adapter->flags |= FLAG_HAS_JUMBO_FRAMES; |
439 | adapter->max_hw_frame_size = DEFAULT_JUMBO; | 436 | adapter->max_hw_frame_size = DEFAULT_JUMBO; |
@@ -2066,7 +2063,8 @@ struct e1000_info e1000_82573_info = { | |||
2066 | | FLAG_HAS_SMART_POWER_DOWN | 2063 | | FLAG_HAS_SMART_POWER_DOWN |
2067 | | FLAG_HAS_AMT | 2064 | | FLAG_HAS_AMT |
2068 | | FLAG_HAS_SWSM_ON_LOAD, | 2065 | | FLAG_HAS_SWSM_ON_LOAD, |
2069 | .flags2 = FLAG2_DISABLE_ASPM_L1, | 2066 | .flags2 = FLAG2_DISABLE_ASPM_L1 |
2067 | | FLAG2_DISABLE_ASPM_L0S, | ||
2070 | .pba = 20, | 2068 | .pba = 20, |
2071 | .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, | 2069 | .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, |
2072 | .get_variants = e1000_get_variants_82571, | 2070 | .get_variants = e1000_get_variants_82571, |
@@ -2086,7 +2084,8 @@ struct e1000_info e1000_82574_info = { | |||
2086 | | FLAG_HAS_SMART_POWER_DOWN | 2084 | | FLAG_HAS_SMART_POWER_DOWN |
2087 | | FLAG_HAS_AMT | 2085 | | FLAG_HAS_AMT |
2088 | | FLAG_HAS_CTRLEXT_ON_LOAD, | 2086 | | FLAG_HAS_CTRLEXT_ON_LOAD, |
2089 | .flags2 = FLAG2_CHECK_PHY_HANG, | 2087 | .flags2 = FLAG2_CHECK_PHY_HANG |
2088 | | FLAG2_DISABLE_ASPM_L0S, | ||
2090 | .pba = 32, | 2089 | .pba = 32, |
2091 | .max_hw_frame_size = DEFAULT_JUMBO, | 2090 | .max_hw_frame_size = DEFAULT_JUMBO, |
2092 | .get_variants = e1000_get_variants_82571, | 2091 | .get_variants = e1000_get_variants_82571, |
@@ -2104,6 +2103,7 @@ struct e1000_info e1000_82583_info = { | |||
2104 | | FLAG_HAS_SMART_POWER_DOWN | 2103 | | FLAG_HAS_SMART_POWER_DOWN |
2105 | | FLAG_HAS_AMT | 2104 | | FLAG_HAS_AMT |
2106 | | FLAG_HAS_CTRLEXT_ON_LOAD, | 2105 | | FLAG_HAS_CTRLEXT_ON_LOAD, |
2106 | .flags2 = FLAG2_DISABLE_ASPM_L0S, | ||
2107 | .pba = 32, | 2107 | .pba = 32, |
2108 | .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, | 2108 | .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, |
2109 | .get_variants = e1000_get_variants_82571, | 2109 | .get_variants = e1000_get_variants_82571, |
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 500896e42206..3be5478dfdf1 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h | |||
@@ -458,6 +458,7 @@ struct e1000_info { | |||
458 | #define FLAG2_HAS_PHY_STATS (1 << 4) | 458 | #define FLAG2_HAS_PHY_STATS (1 << 4) |
459 | #define FLAG2_HAS_EEE (1 << 5) | 459 | #define FLAG2_HAS_EEE (1 << 5) |
460 | #define FLAG2_DMA_BURST (1 << 6) | 460 | #define FLAG2_DMA_BURST (1 << 6) |
461 | #define FLAG2_DISABLE_ASPM_L0S (1 << 7) | ||
461 | #define FLAG2_DISABLE_AIM (1 << 8) | 462 | #define FLAG2_DISABLE_AIM (1 << 8) |
462 | #define FLAG2_CHECK_PHY_HANG (1 << 9) | 463 | #define FLAG2_CHECK_PHY_HANG (1 << 9) |
463 | 464 | ||
@@ -504,7 +505,6 @@ extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter); | |||
504 | extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter); | 505 | extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter); |
505 | extern void e1000e_get_hw_control(struct e1000_adapter *adapter); | 506 | extern void e1000e_get_hw_control(struct e1000_adapter *adapter); |
506 | extern void e1000e_release_hw_control(struct e1000_adapter *adapter); | 507 | extern void e1000e_release_hw_control(struct e1000_adapter *adapter); |
507 | extern void e1000e_disable_aspm(struct pci_dev *pdev, u16 state); | ||
508 | 508 | ||
509 | extern unsigned int copybreak; | 509 | extern unsigned int copybreak; |
510 | 510 | ||
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 8a3145e9aa3e..4deb67d98e36 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -58,6 +58,8 @@ | |||
58 | char e1000e_driver_name[] = "e1000e"; | 58 | char e1000e_driver_name[] = "e1000e"; |
59 | const char e1000e_driver_version[] = DRV_VERSION; | 59 | const char e1000e_driver_version[] = DRV_VERSION; |
60 | 60 | ||
61 | static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state); | ||
62 | |||
61 | static const struct e1000_info *e1000_info_tbl[] = { | 63 | static const struct e1000_info *e1000_info_tbl[] = { |
62 | [board_82571] = &e1000_82571_info, | 64 | [board_82571] = &e1000_82571_info, |
63 | [board_82572] = &e1000_82572_info, | 65 | [board_82572] = &e1000_82572_info, |
@@ -5384,7 +5386,7 @@ static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state) | |||
5384 | pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16); | 5386 | pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16); |
5385 | } | 5387 | } |
5386 | #endif | 5388 | #endif |
5387 | void e1000e_disable_aspm(struct pci_dev *pdev, u16 state) | 5389 | static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state) |
5388 | { | 5390 | { |
5389 | dev_info(&pdev->dev, "Disabling ASPM %s %s\n", | 5391 | dev_info(&pdev->dev, "Disabling ASPM %s %s\n", |
5390 | (state & PCIE_LINK_STATE_L0S) ? "L0s" : "", | 5392 | (state & PCIE_LINK_STATE_L0S) ? "L0s" : "", |
@@ -5404,13 +5406,19 @@ static int __e1000_resume(struct pci_dev *pdev) | |||
5404 | struct net_device *netdev = pci_get_drvdata(pdev); | 5406 | struct net_device *netdev = pci_get_drvdata(pdev); |
5405 | struct e1000_adapter *adapter = netdev_priv(netdev); | 5407 | struct e1000_adapter *adapter = netdev_priv(netdev); |
5406 | struct e1000_hw *hw = &adapter->hw; | 5408 | struct e1000_hw *hw = &adapter->hw; |
5409 | u16 aspm_disable_flag = 0; | ||
5407 | u32 err; | 5410 | u32 err; |
5408 | 5411 | ||
5412 | if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S) | ||
5413 | aspm_disable_flag = PCIE_LINK_STATE_L0S; | ||
5414 | if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1) | ||
5415 | aspm_disable_flag |= PCIE_LINK_STATE_L1; | ||
5416 | if (aspm_disable_flag) | ||
5417 | e1000e_disable_aspm(pdev, aspm_disable_flag); | ||
5418 | |||
5409 | pci_set_power_state(pdev, PCI_D0); | 5419 | pci_set_power_state(pdev, PCI_D0); |
5410 | pci_restore_state(pdev); | 5420 | pci_restore_state(pdev); |
5411 | pci_save_state(pdev); | 5421 | pci_save_state(pdev); |
5412 | if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1) | ||
5413 | e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1); | ||
5414 | 5422 | ||
5415 | e1000e_set_interrupt_capability(adapter); | 5423 | e1000e_set_interrupt_capability(adapter); |
5416 | if (netif_running(netdev)) { | 5424 | if (netif_running(netdev)) { |
@@ -5654,11 +5662,17 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) | |||
5654 | struct net_device *netdev = pci_get_drvdata(pdev); | 5662 | struct net_device *netdev = pci_get_drvdata(pdev); |
5655 | struct e1000_adapter *adapter = netdev_priv(netdev); | 5663 | struct e1000_adapter *adapter = netdev_priv(netdev); |
5656 | struct e1000_hw *hw = &adapter->hw; | 5664 | struct e1000_hw *hw = &adapter->hw; |
5665 | u16 aspm_disable_flag = 0; | ||
5657 | int err; | 5666 | int err; |
5658 | pci_ers_result_t result; | 5667 | pci_ers_result_t result; |
5659 | 5668 | ||
5669 | if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S) | ||
5670 | aspm_disable_flag = PCIE_LINK_STATE_L0S; | ||
5660 | if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1) | 5671 | if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1) |
5661 | e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1); | 5672 | aspm_disable_flag |= PCIE_LINK_STATE_L1; |
5673 | if (aspm_disable_flag) | ||
5674 | e1000e_disable_aspm(pdev, aspm_disable_flag); | ||
5675 | |||
5662 | err = pci_enable_device_mem(pdev); | 5676 | err = pci_enable_device_mem(pdev); |
5663 | if (err) { | 5677 | if (err) { |
5664 | dev_err(&pdev->dev, | 5678 | dev_err(&pdev->dev, |
@@ -5799,12 +5813,17 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
5799 | resource_size_t flash_start, flash_len; | 5813 | resource_size_t flash_start, flash_len; |
5800 | 5814 | ||
5801 | static int cards_found; | 5815 | static int cards_found; |
5816 | u16 aspm_disable_flag = 0; | ||
5802 | int i, err, pci_using_dac; | 5817 | int i, err, pci_using_dac; |
5803 | u16 eeprom_data = 0; | 5818 | u16 eeprom_data = 0; |
5804 | u16 eeprom_apme_mask = E1000_EEPROM_APME; | 5819 | u16 eeprom_apme_mask = E1000_EEPROM_APME; |
5805 | 5820 | ||
5821 | if (ei->flags2 & FLAG2_DISABLE_ASPM_L0S) | ||
5822 | aspm_disable_flag = PCIE_LINK_STATE_L0S; | ||
5806 | if (ei->flags2 & FLAG2_DISABLE_ASPM_L1) | 5823 | if (ei->flags2 & FLAG2_DISABLE_ASPM_L1) |
5807 | e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1); | 5824 | aspm_disable_flag |= PCIE_LINK_STATE_L1; |
5825 | if (aspm_disable_flag) | ||
5826 | e1000e_disable_aspm(pdev, aspm_disable_flag); | ||
5808 | 5827 | ||
5809 | err = pci_enable_device_mem(pdev); | 5828 | err = pci_enable_device_mem(pdev); |
5810 | if (err) | 5829 | if (err) |