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/e1000_82575.c | |
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/e1000_82575.c')
-rw-r--r-- | drivers/net/igb/e1000_82575.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 606c25c56a0..c4506bf1fca 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 |