aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e/netdev.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-05-14 09:29:52 -0400
committerSteven Rostedt <rostedt@goodmis.org>2010-05-14 09:29:52 -0400
commit23e117fa44429cc054cb27d5621d64e4ced91e52 (patch)
treea4b9d0902b9c6f009b2c297515221c1b9bed3af8 /drivers/net/e1000e/netdev.c
parent668eb65f092902eb7dd526af73d4a7f025a94612 (diff)
parenta93d2f1744206827ccf416e2cdc5018aa503314e (diff)
Merge branch 'sched/core' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip into trace/tip/tracing/core-4
Diffstat (limited to 'drivers/net/e1000e/netdev.c')
-rw-r--r--drivers/net/e1000e/netdev.c70
1 files changed, 42 insertions, 28 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 73d43c53015a..fb8fc7d1b50d 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -4283,6 +4283,14 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
4283 return -EINVAL; 4283 return -EINVAL;
4284 } 4284 }
4285 4285
4286 /* 82573 Errata 17 */
4287 if (((adapter->hw.mac.type == e1000_82573) ||
4288 (adapter->hw.mac.type == e1000_82574)) &&
4289 (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN)) {
4290 adapter->flags2 |= FLAG2_DISABLE_ASPM_L1;
4291 e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L1);
4292 }
4293
4286 while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) 4294 while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
4287 msleep(1); 4295 msleep(1);
4288 /* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */ 4296 /* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
@@ -4605,29 +4613,39 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
4605 } 4613 }
4606} 4614}
4607 4615
4608static void e1000e_disable_l1aspm(struct pci_dev *pdev) 4616#ifdef CONFIG_PCIEASPM
4617static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
4618{
4619 pci_disable_link_state(pdev, state);
4620}
4621#else
4622static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
4609{ 4623{
4610 int pos; 4624 int pos;
4611 u16 val; 4625 u16 reg16;
4612 4626
4613 /* 4627 /*
4614 * 82573 workaround - disable L1 ASPM on mobile chipsets 4628 * Both device and parent should have the same ASPM setting.
4615 * 4629 * Disable ASPM in downstream component first and then upstream.
4616 * L1 ASPM on various mobile (ich7) chipsets do not behave properly
4617 * resulting in lost data or garbage information on the pci-e link
4618 * level. This could result in (false) bad EEPROM checksum errors,
4619 * long ping times (up to 2s) or even a system freeze/hang.
4620 *
4621 * Unfortunately this feature saves about 1W power consumption when
4622 * active.
4623 */ 4630 */
4624 pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); 4631 pos = pci_pcie_cap(pdev);
4625 pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val); 4632 pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
4626 if (val & 0x2) { 4633 reg16 &= ~state;
4627 dev_warn(&pdev->dev, "Disabling L1 ASPM\n"); 4634 pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
4628 val &= ~0x2; 4635
4629 pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, val); 4636 pos = pci_pcie_cap(pdev->bus->self);
4630 } 4637 pci_read_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, &reg16);
4638 reg16 &= ~state;
4639 pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16);
4640}
4641#endif
4642void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
4643{
4644 dev_info(&pdev->dev, "Disabling ASPM %s %s\n",
4645 (state & PCIE_LINK_STATE_L0S) ? "L0s" : "",
4646 (state & PCIE_LINK_STATE_L1) ? "L1" : "");
4647
4648 __e1000e_disable_aspm(pdev, state);
4631} 4649}
4632 4650
4633#ifdef CONFIG_PM 4651#ifdef CONFIG_PM
@@ -4653,7 +4671,8 @@ static int e1000_resume(struct pci_dev *pdev)
4653 pci_set_power_state(pdev, PCI_D0); 4671 pci_set_power_state(pdev, PCI_D0);
4654 pci_restore_state(pdev); 4672 pci_restore_state(pdev);
4655 pci_save_state(pdev); 4673 pci_save_state(pdev);
4656 e1000e_disable_l1aspm(pdev); 4674 if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
4675 e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
4657 4676
4658 err = pci_enable_device_mem(pdev); 4677 err = pci_enable_device_mem(pdev);
4659 if (err) { 4678 if (err) {
@@ -4795,7 +4814,8 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
4795 int err; 4814 int err;
4796 pci_ers_result_t result; 4815 pci_ers_result_t result;
4797 4816
4798 e1000e_disable_l1aspm(pdev); 4817 if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
4818 e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
4799 err = pci_enable_device_mem(pdev); 4819 err = pci_enable_device_mem(pdev);
4800 if (err) { 4820 if (err) {
4801 dev_err(&pdev->dev, 4821 dev_err(&pdev->dev,
@@ -4889,13 +4909,6 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter)
4889 dev_warn(&adapter->pdev->dev, 4909 dev_warn(&adapter->pdev->dev,
4890 "Warning: detected DSPD enabled in EEPROM\n"); 4910 "Warning: detected DSPD enabled in EEPROM\n");
4891 } 4911 }
4892
4893 ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf);
4894 if (!ret_val && (le16_to_cpu(buf) & (3 << 2))) {
4895 /* ASPM enable */
4896 dev_warn(&adapter->pdev->dev,
4897 "Warning: detected ASPM enabled in EEPROM\n");
4898 }
4899} 4912}
4900 4913
4901static const struct net_device_ops e1000e_netdev_ops = { 4914static const struct net_device_ops e1000e_netdev_ops = {
@@ -4944,7 +4957,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
4944 u16 eeprom_data = 0; 4957 u16 eeprom_data = 0;
4945 u16 eeprom_apme_mask = E1000_EEPROM_APME; 4958 u16 eeprom_apme_mask = E1000_EEPROM_APME;
4946 4959
4947 e1000e_disable_l1aspm(pdev); 4960 if (ei->flags2 & FLAG2_DISABLE_ASPM_L1)
4961 e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
4948 4962
4949 err = pci_enable_device_mem(pdev); 4963 err = pci_enable_device_mem(pdev);
4950 if (err) 4964 if (err)