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/net/e1000e/netdev.c | |
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/net/e1000e/netdev.c')
-rw-r--r-- | drivers/net/e1000e/netdev.c | 29 |
1 files changed, 24 insertions, 5 deletions
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) |