aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2011-03-23 23:09:03 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-04-13 22:19:22 -0400
commit78cd29d5a92ae5067377ad42089f2c8781312f4a (patch)
treefb9845f2fdb6c28890478c7fa8fbcfec79e4543d /drivers
parent2084b114e3fb0d84e5882f5ee6c7039be52da715 (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.c10
-rw-r--r--drivers/net/e1000e/e1000.h2
-rw-r--r--drivers/net/e1000e/netdev.c29
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);
504extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter); 505extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter);
505extern void e1000e_get_hw_control(struct e1000_adapter *adapter); 506extern void e1000e_get_hw_control(struct e1000_adapter *adapter);
506extern void e1000e_release_hw_control(struct e1000_adapter *adapter); 507extern void e1000e_release_hw_control(struct e1000_adapter *adapter);
507extern void e1000e_disable_aspm(struct pci_dev *pdev, u16 state);
508 508
509extern unsigned int copybreak; 509extern 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 @@
58char e1000e_driver_name[] = "e1000e"; 58char e1000e_driver_name[] = "e1000e";
59const char e1000e_driver_version[] = DRV_VERSION; 59const char e1000e_driver_version[] = DRV_VERSION;
60 60
61static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state);
62
61static const struct e1000_info *e1000_info_tbl[] = { 63static 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
5387void e1000e_disable_aspm(struct pci_dev *pdev, u16 state) 5389static 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)