Commit c54106bb authored by Alexander Duyck's avatar Alexander Duyck Committed by Jeff Garzik

igb: fix tx data corruption with transition to L0s on 82575

The 82575 has an issue in which the DMA will go out of sync if the link
partner goes into an L0s state.  To prevent this we set the pci-e link
partner capability bits to disable the L0s transition on the hw.
Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent d4f12daf
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/pci-aspm.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/if_ether.h> #include <linux/if_ether.h>
...@@ -966,10 +967,11 @@ static int __devinit igb_probe(struct pci_dev *pdev, ...@@ -966,10 +967,11 @@ static int __devinit igb_probe(struct pci_dev *pdev,
struct net_device *netdev; struct net_device *netdev;
struct igb_adapter *adapter; struct igb_adapter *adapter;
struct e1000_hw *hw; struct e1000_hw *hw;
struct pci_dev *us_dev;
const struct e1000_info *ei = igb_info_tbl[ent->driver_data]; const struct e1000_info *ei = igb_info_tbl[ent->driver_data];
unsigned long mmio_start, mmio_len; unsigned long mmio_start, mmio_len;
int i, err, pci_using_dac; int i, err, pci_using_dac, pos;
u16 eeprom_data = 0; u16 eeprom_data = 0, state = 0;
u16 eeprom_apme_mask = IGB_EEPROM_APME; u16 eeprom_apme_mask = IGB_EEPROM_APME;
u32 part_num; u32 part_num;
int bars, need_ioport; int bars, need_ioport;
...@@ -1004,6 +1006,28 @@ static int __devinit igb_probe(struct pci_dev *pdev, ...@@ -1004,6 +1006,28 @@ static int __devinit igb_probe(struct pci_dev *pdev,
} }
} }
/* 82575 requires that the pci-e link partner disable the L0s state */
switch (pdev->device) {
case E1000_DEV_ID_82575EB_COPPER:
case E1000_DEV_ID_82575EB_FIBER_SERDES:
case E1000_DEV_ID_82575GB_QUAD_COPPER:
us_dev = pdev->bus->self;
pos = pci_find_capability(us_dev, PCI_CAP_ID_EXP);
if (pos) {
pci_read_config_word(us_dev, pos + PCI_EXP_LNKCTL,
&state);
state &= ~PCIE_LINK_STATE_L0S;
pci_write_config_word(us_dev, pos + PCI_EXP_LNKCTL,
state);
printk(KERN_INFO "Disabling ASPM L0s upstream switch "
"port %x:%x.%x\n", us_dev->bus->number,
PCI_SLOT(us_dev->devfn),
PCI_FUNC(us_dev->devfn));
}
default:
break;
}
err = pci_request_selected_regions(pdev, bars, igb_driver_name); err = pci_request_selected_regions(pdev, bars, igb_driver_name);
if (err) if (err)
goto err_pci_reg; goto err_pci_reg;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment