diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2009-07-23 14:08:35 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-07-26 12:46:49 -0400 |
commit | 009bc06e5311b48c77b7708d9e226ae0f110373a (patch) | |
tree | fceeade485befdbda8047d14bb59c9c0b0b0dad8 /drivers/net/igb | |
parent | 12645a196eccb9209f88915f56a686086dea1a16 (diff) |
igb: add completion timeout workaround for 82575/82576
The 82575 and 82576 hardware can both experience data corruption issues if
a pci-e completion arrives after the timeout value. In order to avoid this
we need to increase the timeout value while pci-e master is disabled.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/igb')
-rw-r--r-- | drivers/net/igb/e1000_82575.c | 58 | ||||
-rw-r--r-- | drivers/net/igb/e1000_defines.h | 8 | ||||
-rw-r--r-- | drivers/net/igb/e1000_hw.h | 4 | ||||
-rw-r--r-- | drivers/net/igb/e1000_mac.c | 14 | ||||
-rw-r--r-- | drivers/net/igb/e1000_regs.h | 1 | ||||
-rw-r--r-- | drivers/net/igb/igb_main.c | 28 |
6 files changed, 98 insertions, 15 deletions
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 606c25c56a01..c4506bf1fca2 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c | |||
@@ -61,6 +61,7 @@ static void igb_release_swfw_sync_82575(struct e1000_hw *, u16); | |||
61 | static bool igb_sgmii_active_82575(struct e1000_hw *); | 61 | static bool igb_sgmii_active_82575(struct e1000_hw *); |
62 | static s32 igb_reset_init_script_82575(struct e1000_hw *); | 62 | static s32 igb_reset_init_script_82575(struct e1000_hw *); |
63 | static s32 igb_read_mac_addr_82575(struct e1000_hw *); | 63 | static s32 igb_read_mac_addr_82575(struct e1000_hw *); |
64 | static s32 igb_set_pcie_completion_timeout(struct e1000_hw *hw); | ||
64 | 65 | ||
65 | static s32 igb_get_invariants_82575(struct e1000_hw *hw) | 66 | static s32 igb_get_invariants_82575(struct e1000_hw *hw) |
66 | { | 67 | { |
@@ -909,6 +910,12 @@ static s32 igb_reset_hw_82575(struct e1000_hw *hw) | |||
909 | if (ret_val) | 910 | if (ret_val) |
910 | hw_dbg("PCI-E Master disable polling has failed.\n"); | 911 | hw_dbg("PCI-E Master disable polling has failed.\n"); |
911 | 912 | ||
913 | /* set the completion timeout for interface */ | ||
914 | ret_val = igb_set_pcie_completion_timeout(hw); | ||
915 | if (ret_val) { | ||
916 | hw_dbg("PCI-E Set completion timeout has failed.\n"); | ||
917 | } | ||
918 | |||
912 | hw_dbg("Masking off all interrupts\n"); | 919 | hw_dbg("Masking off all interrupts\n"); |
913 | wr32(E1000_IMC, 0xffffffff); | 920 | wr32(E1000_IMC, 0xffffffff); |
914 | 921 | ||
@@ -1408,6 +1415,57 @@ void igb_rx_fifo_flush_82575(struct e1000_hw *hw) | |||
1408 | } | 1415 | } |
1409 | 1416 | ||
1410 | /** | 1417 | /** |
1418 | * igb_set_pcie_completion_timeout - set pci-e completion timeout | ||
1419 | * @hw: pointer to the HW structure | ||
1420 | * | ||
1421 | * The defaults for 82575 and 82576 should be in the range of 50us to 50ms, | ||
1422 | * however the hardware default for these parts is 500us to 1ms which is less | ||
1423 | * than the 10ms recommended by the pci-e spec. To address this we need to | ||
1424 | * increase the value to either 10ms to 200ms for capability version 1 config, | ||
1425 | * or 16ms to 55ms for version 2. | ||
1426 | **/ | ||
1427 | static s32 igb_set_pcie_completion_timeout(struct e1000_hw *hw) | ||
1428 | { | ||
1429 | u32 gcr = rd32(E1000_GCR); | ||
1430 | s32 ret_val = 0; | ||
1431 | u16 pcie_devctl2; | ||
1432 | |||
1433 | /* only take action if timeout value is defaulted to 0 */ | ||
1434 | if (gcr & E1000_GCR_CMPL_TMOUT_MASK) | ||
1435 | goto out; | ||
1436 | |||
1437 | /* | ||
1438 | * if capababilities version is type 1 we can write the | ||
1439 | * timeout of 10ms to 200ms through the GCR register | ||
1440 | */ | ||
1441 | if (!(gcr & E1000_GCR_CAP_VER2)) { | ||
1442 | gcr |= E1000_GCR_CMPL_TMOUT_10ms; | ||
1443 | goto out; | ||
1444 | } | ||
1445 | |||
1446 | /* | ||
1447 | * for version 2 capabilities we need to write the config space | ||
1448 | * directly in order to set the completion timeout value for | ||
1449 | * 16ms to 55ms | ||
1450 | */ | ||
1451 | ret_val = igb_read_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2, | ||
1452 | &pcie_devctl2); | ||
1453 | if (ret_val) | ||
1454 | goto out; | ||
1455 | |||
1456 | pcie_devctl2 |= PCIE_DEVICE_CONTROL2_16ms; | ||
1457 | |||
1458 | ret_val = igb_write_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2, | ||
1459 | &pcie_devctl2); | ||
1460 | out: | ||
1461 | /* disable completion timeout resend */ | ||
1462 | gcr &= ~E1000_GCR_CMPL_TMOUT_RESEND; | ||
1463 | |||
1464 | wr32(E1000_GCR, gcr); | ||
1465 | return ret_val; | ||
1466 | } | ||
1467 | |||
1468 | /** | ||
1411 | * igb_vmdq_set_loopback_pf - enable or disable vmdq loopback | 1469 | * igb_vmdq_set_loopback_pf - enable or disable vmdq loopback |
1412 | * @hw: pointer to the hardware struct | 1470 | * @hw: pointer to the hardware struct |
1413 | * @enable: state to enter, either enabled or disabled | 1471 | * @enable: state to enter, either enabled or disabled |
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index 3bda3db73f1f..c85829355d50 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h | |||
@@ -435,6 +435,12 @@ | |||
435 | /* Flow Control */ | 435 | /* Flow Control */ |
436 | #define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */ | 436 | #define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */ |
437 | 437 | ||
438 | /* PCI Express Control */ | ||
439 | #define E1000_GCR_CMPL_TMOUT_MASK 0x0000F000 | ||
440 | #define E1000_GCR_CMPL_TMOUT_10ms 0x00001000 | ||
441 | #define E1000_GCR_CMPL_TMOUT_RESEND 0x00010000 | ||
442 | #define E1000_GCR_CAP_VER2 0x00040000 | ||
443 | |||
438 | /* PHY Control Register */ | 444 | /* PHY Control Register */ |
439 | #define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ | 445 | #define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ |
440 | #define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ | 446 | #define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ |
@@ -569,9 +575,11 @@ | |||
569 | 575 | ||
570 | /* PCI/PCI-X/PCI-EX Config space */ | 576 | /* PCI/PCI-X/PCI-EX Config space */ |
571 | #define PCIE_LINK_STATUS 0x12 | 577 | #define PCIE_LINK_STATUS 0x12 |
578 | #define PCIE_DEVICE_CONTROL2 0x28 | ||
572 | 579 | ||
573 | #define PCIE_LINK_WIDTH_MASK 0x3F0 | 580 | #define PCIE_LINK_WIDTH_MASK 0x3F0 |
574 | #define PCIE_LINK_WIDTH_SHIFT 4 | 581 | #define PCIE_LINK_WIDTH_SHIFT 4 |
582 | #define PCIE_DEVICE_CONTROL2_16ms 0x0005 | ||
575 | 583 | ||
576 | #define PHY_REVISION_MASK 0xFFFFFFF0 | 584 | #define PHY_REVISION_MASK 0xFFFFFFF0 |
577 | #define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ | 585 | #define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ |
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h index f096ddd84293..eb41f3b8234f 100644 --- a/drivers/net/igb/e1000_hw.h +++ b/drivers/net/igb/e1000_hw.h | |||
@@ -494,5 +494,7 @@ extern char *igb_get_hw_dev_name(struct e1000_hw *hw); | |||
494 | #else | 494 | #else |
495 | #define hw_dbg(format, arg...) | 495 | #define hw_dbg(format, arg...) |
496 | #endif | 496 | #endif |
497 | |||
498 | #endif | 497 | #endif |
498 | /* These functions must be implemented by drivers */ | ||
499 | s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value); | ||
500 | s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value); | ||
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c index 34f1a370b068..60343b58364d 100644 --- a/drivers/net/igb/e1000_mac.c +++ b/drivers/net/igb/e1000_mac.c | |||
@@ -37,20 +37,6 @@ | |||
37 | static s32 igb_set_default_fc(struct e1000_hw *hw); | 37 | static s32 igb_set_default_fc(struct e1000_hw *hw); |
38 | static s32 igb_set_fc_watermarks(struct e1000_hw *hw); | 38 | static s32 igb_set_fc_watermarks(struct e1000_hw *hw); |
39 | 39 | ||
40 | static s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value) | ||
41 | { | ||
42 | struct igb_adapter *adapter = hw->back; | ||
43 | u16 cap_offset; | ||
44 | |||
45 | cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP); | ||
46 | if (!cap_offset) | ||
47 | return -E1000_ERR_CONFIG; | ||
48 | |||
49 | pci_read_config_word(adapter->pdev, cap_offset + reg, value); | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | /** | 40 | /** |
55 | * igb_get_bus_info_pcie - Get PCIe bus information | 41 | * igb_get_bus_info_pcie - Get PCIe bus information |
56 | * @hw: pointer to the HW structure | 42 | * @hw: pointer to the HW structure |
diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h index 6e5924511e40..345d1442d6d6 100644 --- a/drivers/net/igb/e1000_regs.h +++ b/drivers/net/igb/e1000_regs.h | |||
@@ -305,6 +305,7 @@ enum { | |||
305 | #define E1000_CCMCTL 0x05B48 /* CCM Control Register */ | 305 | #define E1000_CCMCTL 0x05B48 /* CCM Control Register */ |
306 | #define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */ | 306 | #define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */ |
307 | #define E1000_SCCTL 0x05B4C /* PCIc PLL Configuration Register */ | 307 | #define E1000_SCCTL 0x05B4C /* PCIc PLL Configuration Register */ |
308 | #define E1000_GCR 0x05B00 /* PCI-Ex Control */ | ||
308 | #define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */ | 309 | #define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */ |
309 | #define E1000_SWSM 0x05B50 /* SW Semaphore */ | 310 | #define E1000_SWSM 0x05B50 /* SW Semaphore */ |
310 | #define E1000_FWSM 0x05B54 /* FW Semaphore */ | 311 | #define E1000_FWSM 0x05B54 /* FW Semaphore */ |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 39b3b6aa650b..2cb546078c52 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -5029,6 +5029,34 @@ static int igb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | |||
5029 | } | 5029 | } |
5030 | } | 5030 | } |
5031 | 5031 | ||
5032 | s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value) | ||
5033 | { | ||
5034 | struct igb_adapter *adapter = hw->back; | ||
5035 | u16 cap_offset; | ||
5036 | |||
5037 | cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP); | ||
5038 | if (!cap_offset) | ||
5039 | return -E1000_ERR_CONFIG; | ||
5040 | |||
5041 | pci_read_config_word(adapter->pdev, cap_offset + reg, value); | ||
5042 | |||
5043 | return 0; | ||
5044 | } | ||
5045 | |||
5046 | s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value) | ||
5047 | { | ||
5048 | struct igb_adapter *adapter = hw->back; | ||
5049 | u16 cap_offset; | ||
5050 | |||
5051 | cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP); | ||
5052 | if (!cap_offset) | ||
5053 | return -E1000_ERR_CONFIG; | ||
5054 | |||
5055 | pci_write_config_word(adapter->pdev, cap_offset + reg, *value); | ||
5056 | |||
5057 | return 0; | ||
5058 | } | ||
5059 | |||
5032 | static void igb_vlan_rx_register(struct net_device *netdev, | 5060 | static void igb_vlan_rx_register(struct net_device *netdev, |
5033 | struct vlan_group *grp) | 5061 | struct vlan_group *grp) |
5034 | { | 5062 | { |