aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2010-09-22 13:16:40 -0400
committerDavid S. Miller <davem@davemloft.net>2010-09-22 23:41:20 -0400
commita1ce647378c0262fe72757f989e961b2de6460a5 (patch)
treeafd3e62996a49b32509297ff0f38831e6336f1c7 /drivers
parent831bd2e6a6c09588fdde453ecb858f050ac1b942 (diff)
e1000e: 82579 jumbo frame workaround causing CRC errors
The subject workaround was causing CRC errors due to writing the wrong register with updates of the RCTL register. It was also found that the workaround function which modifies the RCTL register was being called in the middle of a read-modify-write operation of the RCTL register, so the function call has been moved appropriately. Lastly, jumbo frames must not be allowed when CRC stripping is disabled by a module parameter because the workaround requires the CRC be stripped. Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> Tested-by: Jeff Pieper <jeffrey.e.pieper@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')
-rw-r--r--drivers/net/e1000e/ich8lan.c12
-rw-r--r--drivers/net/e1000e/netdev.c29
2 files changed, 20 insertions, 21 deletions
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 89b1e1aea526..bb346ae3d9a0 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -1475,10 +1475,6 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
1475 goto out; 1475 goto out;
1476 1476
1477 /* Enable jumbo frame workaround in the PHY */ 1477 /* Enable jumbo frame workaround in the PHY */
1478 e1e_rphy(hw, PHY_REG(769, 20), &data);
1479 ret_val = e1e_wphy(hw, PHY_REG(769, 20), data & ~(1 << 14));
1480 if (ret_val)
1481 goto out;
1482 e1e_rphy(hw, PHY_REG(769, 23), &data); 1478 e1e_rphy(hw, PHY_REG(769, 23), &data);
1483 data &= ~(0x7F << 5); 1479 data &= ~(0x7F << 5);
1484 data |= (0x37 << 5); 1480 data |= (0x37 << 5);
@@ -1487,7 +1483,6 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
1487 goto out; 1483 goto out;
1488 e1e_rphy(hw, PHY_REG(769, 16), &data); 1484 e1e_rphy(hw, PHY_REG(769, 16), &data);
1489 data &= ~(1 << 13); 1485 data &= ~(1 << 13);
1490 data |= (1 << 12);
1491 ret_val = e1e_wphy(hw, PHY_REG(769, 16), data); 1486 ret_val = e1e_wphy(hw, PHY_REG(769, 16), data);
1492 if (ret_val) 1487 if (ret_val)
1493 goto out; 1488 goto out;
@@ -1512,7 +1507,7 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
1512 1507
1513 mac_reg = er32(RCTL); 1508 mac_reg = er32(RCTL);
1514 mac_reg &= ~E1000_RCTL_SECRC; 1509 mac_reg &= ~E1000_RCTL_SECRC;
1515 ew32(FFLT_DBG, mac_reg); 1510 ew32(RCTL, mac_reg);
1516 1511
1517 ret_val = e1000e_read_kmrn_reg(hw, 1512 ret_val = e1000e_read_kmrn_reg(hw,
1518 E1000_KMRNCTRLSTA_CTRL_OFFSET, 1513 E1000_KMRNCTRLSTA_CTRL_OFFSET,
@@ -1538,17 +1533,12 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
1538 goto out; 1533 goto out;
1539 1534
1540 /* Write PHY register values back to h/w defaults */ 1535 /* Write PHY register values back to h/w defaults */
1541 e1e_rphy(hw, PHY_REG(769, 20), &data);
1542 ret_val = e1e_wphy(hw, PHY_REG(769, 20), data & ~(1 << 14));
1543 if (ret_val)
1544 goto out;
1545 e1e_rphy(hw, PHY_REG(769, 23), &data); 1536 e1e_rphy(hw, PHY_REG(769, 23), &data);
1546 data &= ~(0x7F << 5); 1537 data &= ~(0x7F << 5);
1547 ret_val = e1e_wphy(hw, PHY_REG(769, 23), data); 1538 ret_val = e1e_wphy(hw, PHY_REG(769, 23), data);
1548 if (ret_val) 1539 if (ret_val)
1549 goto out; 1540 goto out;
1550 e1e_rphy(hw, PHY_REG(769, 16), &data); 1541 e1e_rphy(hw, PHY_REG(769, 16), &data);
1551 data &= ~(1 << 12);
1552 data |= (1 << 13); 1542 data |= (1 << 13);
1553 ret_val = e1e_wphy(hw, PHY_REG(769, 16), data); 1543 ret_val = e1e_wphy(hw, PHY_REG(769, 16), data);
1554 if (ret_val) 1544 if (ret_val)
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 2b8ef44bd2b1..e561d15c3eb1 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -2704,6 +2704,16 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
2704 u32 psrctl = 0; 2704 u32 psrctl = 0;
2705 u32 pages = 0; 2705 u32 pages = 0;
2706 2706
2707 /* Workaround Si errata on 82579 - configure jumbo frame flow */
2708 if (hw->mac.type == e1000_pch2lan) {
2709 s32 ret_val;
2710
2711 if (adapter->netdev->mtu > ETH_DATA_LEN)
2712 ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true);
2713 else
2714 ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false);
2715 }
2716
2707 /* Program MC offset vector base */ 2717 /* Program MC offset vector base */
2708 rctl = er32(RCTL); 2718 rctl = er32(RCTL);
2709 rctl &= ~(3 << E1000_RCTL_MO_SHIFT); 2719 rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
@@ -2744,16 +2754,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
2744 e1e_wphy(hw, 22, phy_data); 2754 e1e_wphy(hw, 22, phy_data);
2745 } 2755 }
2746 2756
2747 /* Workaround Si errata on 82579 - configure jumbo frame flow */
2748 if (hw->mac.type == e1000_pch2lan) {
2749 s32 ret_val;
2750
2751 if (rctl & E1000_RCTL_LPE)
2752 ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true);
2753 else
2754 ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false);
2755 }
2756
2757 /* Setup buffer sizes */ 2757 /* Setup buffer sizes */
2758 rctl &= ~E1000_RCTL_SZ_4096; 2758 rctl &= ~E1000_RCTL_SZ_4096;
2759 rctl |= E1000_RCTL_BSEX; 2759 rctl |= E1000_RCTL_BSEX;
@@ -4833,6 +4833,15 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
4833 return -EINVAL; 4833 return -EINVAL;
4834 } 4834 }
4835 4835
4836 /* Jumbo frame workaround on 82579 requires CRC be stripped */
4837 if ((adapter->hw.mac.type == e1000_pch2lan) &&
4838 !(adapter->flags2 & FLAG2_CRC_STRIPPING) &&
4839 (new_mtu > ETH_DATA_LEN)) {
4840 e_err("Jumbo Frames not supported on 82579 when CRC "
4841 "stripping is disabled.\n");
4842 return -EINVAL;
4843 }
4844
4836 /* 82573 Errata 17 */ 4845 /* 82573 Errata 17 */
4837 if (((adapter->hw.mac.type == e1000_82573) || 4846 if (((adapter->hw.mac.type == e1000_82573) ||
4838 (adapter->hw.mac.type == e1000_82574)) && 4847 (adapter->hw.mac.type == e1000_82574)) &&