aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2008-10-17 00:26:57 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-10-22 06:53:59 -0400
commitc54106bb3856a7726a814d54aa0eb32f5419a743 (patch)
tree717fb190cc5782f5aa9f9dee5e80267f9a5f0380 /drivers
parentd4f12daf7ba4efc506c377a9591ecdb692641fe5 (diff)
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: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/igb/igb_main.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 93d02efa9a0a..33bd7bb0aacd 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -38,6 +38,7 @@
38#include <linux/ethtool.h> 38#include <linux/ethtool.h>
39#include <linux/if_vlan.h> 39#include <linux/if_vlan.h>
40#include <linux/pci.h> 40#include <linux/pci.h>
41#include <linux/pci-aspm.h>
41#include <linux/delay.h> 42#include <linux/delay.h>
42#include <linux/interrupt.h> 43#include <linux/interrupt.h>
43#include <linux/if_ether.h> 44#include <linux/if_ether.h>
@@ -966,10 +967,11 @@ static int __devinit igb_probe(struct pci_dev *pdev,
966 struct net_device *netdev; 967 struct net_device *netdev;
967 struct igb_adapter *adapter; 968 struct igb_adapter *adapter;
968 struct e1000_hw *hw; 969 struct e1000_hw *hw;
970 struct pci_dev *us_dev;
969 const struct e1000_info *ei = igb_info_tbl[ent->driver_data]; 971 const struct e1000_info *ei = igb_info_tbl[ent->driver_data];
970 unsigned long mmio_start, mmio_len; 972 unsigned long mmio_start, mmio_len;
971 int i, err, pci_using_dac; 973 int i, err, pci_using_dac, pos;
972 u16 eeprom_data = 0; 974 u16 eeprom_data = 0, state = 0;
973 u16 eeprom_apme_mask = IGB_EEPROM_APME; 975 u16 eeprom_apme_mask = IGB_EEPROM_APME;
974 u32 part_num; 976 u32 part_num;
975 int bars, need_ioport; 977 int bars, need_ioport;
@@ -1004,6 +1006,28 @@ static int __devinit igb_probe(struct pci_dev *pdev,
1004 } 1006 }
1005 } 1007 }
1006 1008
1009 /* 82575 requires that the pci-e link partner disable the L0s state */
1010 switch (pdev->device) {
1011 case E1000_DEV_ID_82575EB_COPPER:
1012 case E1000_DEV_ID_82575EB_FIBER_SERDES:
1013 case E1000_DEV_ID_82575GB_QUAD_COPPER:
1014 us_dev = pdev->bus->self;
1015 pos = pci_find_capability(us_dev, PCI_CAP_ID_EXP);
1016 if (pos) {
1017 pci_read_config_word(us_dev, pos + PCI_EXP_LNKCTL,
1018 &state);
1019 state &= ~PCIE_LINK_STATE_L0S;
1020 pci_write_config_word(us_dev, pos + PCI_EXP_LNKCTL,
1021 state);
1022 printk(KERN_INFO "Disabling ASPM L0s upstream switch "
1023 "port %x:%x.%x\n", us_dev->bus->number,
1024 PCI_SLOT(us_dev->devfn),
1025 PCI_FUNC(us_dev->devfn));
1026 }
1027 default:
1028 break;
1029 }
1030
1007 err = pci_request_selected_regions(pdev, bars, igb_driver_name); 1031 err = pci_request_selected_regions(pdev, bars, igb_driver_name);
1008 if (err) 1032 if (err)
1009 goto err_pci_reg; 1033 goto err_pci_reg;