aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e/netdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/e1000e/netdev.c')
-rw-r--r--drivers/net/e1000e/netdev.c73
1 files changed, 45 insertions, 28 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index e1cceb60657..fb8fc7d1b50 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -36,6 +36,7 @@
36#include <linux/netdevice.h> 36#include <linux/netdevice.h>
37#include <linux/tcp.h> 37#include <linux/tcp.h>
38#include <linux/ipv6.h> 38#include <linux/ipv6.h>
39#include <linux/slab.h>
39#include <net/checksum.h> 40#include <net/checksum.h>
40#include <net/ip6_checksum.h> 41#include <net/ip6_checksum.h>
41#include <linux/mii.h> 42#include <linux/mii.h>
@@ -660,6 +661,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
660 i = 0; 661 i = 0;
661 } 662 }
662 663
664 if (i == tx_ring->next_to_use)
665 break;
663 eop = tx_ring->buffer_info[i].next_to_watch; 666 eop = tx_ring->buffer_info[i].next_to_watch;
664 eop_desc = E1000_TX_DESC(*tx_ring, eop); 667 eop_desc = E1000_TX_DESC(*tx_ring, eop);
665 } 668 }
@@ -4280,6 +4283,14 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
4280 return -EINVAL; 4283 return -EINVAL;
4281 } 4284 }
4282 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
4283 while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) 4294 while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
4284 msleep(1); 4295 msleep(1);
4285 /* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */ 4296 /* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
@@ -4602,29 +4613,39 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
4602 } 4613 }
4603} 4614}
4604 4615
4605static 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)
4606{ 4623{
4607 int pos; 4624 int pos;
4608 u16 val; 4625 u16 reg16;
4609 4626
4610 /* 4627 /*
4611 * 82573 workaround - disable L1 ASPM on mobile chipsets 4628 * Both device and parent should have the same ASPM setting.
4612 * 4629 * Disable ASPM in downstream component first and then upstream.
4613 * L1 ASPM on various mobile (ich7) chipsets do not behave properly
4614 * resulting in lost data or garbage information on the pci-e link
4615 * level. This could result in (false) bad EEPROM checksum errors,
4616 * long ping times (up to 2s) or even a system freeze/hang.
4617 *
4618 * Unfortunately this feature saves about 1W power consumption when
4619 * active.
4620 */ 4630 */
4621 pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); 4631 pos = pci_pcie_cap(pdev);
4622 pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val); 4632 pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
4623 if (val & 0x2) { 4633 reg16 &= ~state;
4624 dev_warn(&pdev->dev, "Disabling L1 ASPM\n"); 4634 pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
4625 val &= ~0x2; 4635
4626 pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, val); 4636 pos = pci_pcie_cap(pdev->bus->self);
4627 } 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);
4628} 4649}
4629 4650
4630#ifdef CONFIG_PM 4651#ifdef CONFIG_PM
@@ -4650,7 +4671,8 @@ static int e1000_resume(struct pci_dev *pdev)
4650 pci_set_power_state(pdev, PCI_D0); 4671 pci_set_power_state(pdev, PCI_D0);
4651 pci_restore_state(pdev); 4672 pci_restore_state(pdev);
4652 pci_save_state(pdev); 4673 pci_save_state(pdev);
4653 e1000e_disable_l1aspm(pdev); 4674 if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
4675 e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
4654 4676
4655 err = pci_enable_device_mem(pdev); 4677 err = pci_enable_device_mem(pdev);
4656 if (err) { 4678 if (err) {
@@ -4792,7 +4814,8 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
4792 int err; 4814 int err;
4793 pci_ers_result_t result; 4815 pci_ers_result_t result;
4794 4816
4795 e1000e_disable_l1aspm(pdev); 4817 if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
4818 e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
4796 err = pci_enable_device_mem(pdev); 4819 err = pci_enable_device_mem(pdev);
4797 if (err) { 4820 if (err) {
4798 dev_err(&pdev->dev, 4821 dev_err(&pdev->dev,
@@ -4886,13 +4909,6 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter)
4886 dev_warn(&adapter->pdev->dev, 4909 dev_warn(&adapter->pdev->dev,
4887 "Warning: detected DSPD enabled in EEPROM\n"); 4910 "Warning: detected DSPD enabled in EEPROM\n");
4888 } 4911 }
4889
4890 ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf);
4891 if (!ret_val && (le16_to_cpu(buf) & (3 << 2))) {
4892 /* ASPM enable */
4893 dev_warn(&adapter->pdev->dev,
4894 "Warning: detected ASPM enabled in EEPROM\n");
4895 }
4896} 4912}
4897 4913
4898static const struct net_device_ops e1000e_netdev_ops = { 4914static const struct net_device_ops e1000e_netdev_ops = {
@@ -4941,7 +4957,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
4941 u16 eeprom_data = 0; 4957 u16 eeprom_data = 0;
4942 u16 eeprom_apme_mask = E1000_EEPROM_APME; 4958 u16 eeprom_apme_mask = E1000_EEPROM_APME;
4943 4959
4944 e1000e_disable_l1aspm(pdev); 4960 if (ei->flags2 & FLAG2_DISABLE_ASPM_L1)
4961 e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
4945 4962
4946 err = pci_enable_device_mem(pdev); 4963 err = pci_enable_device_mem(pdev);
4947 if (err) 4964 if (err)