diff options
author | Matthew Vick <matthew.vick@intel.com> | 2012-04-25 04:01:05 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2012-05-03 05:29:04 -0400 |
commit | f6bd5577a39aed21cefd698bc46f70cfeaa0923c (patch) | |
tree | aa5b9c51bf2d216e49e55e3f8b8b8a2557ff27c5 /drivers/net/ethernet/intel | |
parent | 885fe7be4b23d8b9e46cdd87148cefbec926868b (diff) |
e1000e: Driver workaround for IPv6 Header Extension Erratum.
Previously, IPv6 extension header parsing was disabled for all devices
supported by e1000e when using packet split mode. However, as per a
silicon errata, only certain devices need this restriction and will need
to disable IPv6 extension header parsing for all modes.
Signed-off-by: Matthew Vick <matthew.vick@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel')
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/80003es2lan.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/82571.c | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/ich8lan.c | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/netdev.c | 9 |
4 files changed, 26 insertions, 8 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/80003es2lan.c b/drivers/net/ethernet/intel/e1000e/80003es2lan.c index 66f9877bc4ec..4dd18a1f45d2 100644 --- a/drivers/net/ethernet/intel/e1000e/80003es2lan.c +++ b/drivers/net/ethernet/intel/e1000e/80003es2lan.c | |||
@@ -944,6 +944,14 @@ static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw) | |||
944 | else | 944 | else |
945 | reg |= (1 << 28); | 945 | reg |= (1 << 28); |
946 | ew32(TARC(1), reg); | 946 | ew32(TARC(1), reg); |
947 | |||
948 | /* | ||
949 | * Disable IPv6 extension header parsing because some malformed | ||
950 | * IPv6 headers can hang the Rx. | ||
951 | */ | ||
952 | reg = er32(RFCTL); | ||
953 | reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS); | ||
954 | ew32(RFCTL, reg); | ||
947 | } | 955 | } |
948 | 956 | ||
949 | /** | 957 | /** |
diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index 7b02e87b0b65..98632f4561b2 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c | |||
@@ -1279,6 +1279,16 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw) | |||
1279 | ew32(CTRL_EXT, reg); | 1279 | ew32(CTRL_EXT, reg); |
1280 | } | 1280 | } |
1281 | 1281 | ||
1282 | /* | ||
1283 | * Disable IPv6 extension header parsing because some malformed | ||
1284 | * IPv6 headers can hang the Rx. | ||
1285 | */ | ||
1286 | if (hw->mac.type <= e1000_82573) { | ||
1287 | reg = er32(RFCTL); | ||
1288 | reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS); | ||
1289 | ew32(RFCTL, reg); | ||
1290 | } | ||
1291 | |||
1282 | /* PCI-Ex Control Registers */ | 1292 | /* PCI-Ex Control Registers */ |
1283 | switch (hw->mac.type) { | 1293 | switch (hw->mac.type) { |
1284 | case e1000_82574: | 1294 | case e1000_82574: |
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index c58ed26d85af..dfff4416cf4b 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c | |||
@@ -3468,6 +3468,13 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw) | |||
3468 | */ | 3468 | */ |
3469 | reg = er32(RFCTL); | 3469 | reg = er32(RFCTL); |
3470 | reg |= (E1000_RFCTL_NFSW_DIS | E1000_RFCTL_NFSR_DIS); | 3470 | reg |= (E1000_RFCTL_NFSW_DIS | E1000_RFCTL_NFSR_DIS); |
3471 | |||
3472 | /* | ||
3473 | * Disable IPv6 extension header parsing because some malformed | ||
3474 | * IPv6 headers can hang the Rx. | ||
3475 | */ | ||
3476 | if (hw->mac.type == e1000_ich8lan) | ||
3477 | reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS); | ||
3471 | ew32(RFCTL, reg); | 3478 | ew32(RFCTL, reg); |
3472 | } | 3479 | } |
3473 | 3480 | ||
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index e86b524a5b15..ab4505c99e67 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
@@ -2939,6 +2939,7 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) | |||
2939 | /* Enable Extended Status in all Receive Descriptors */ | 2939 | /* Enable Extended Status in all Receive Descriptors */ |
2940 | rfctl = er32(RFCTL); | 2940 | rfctl = er32(RFCTL); |
2941 | rfctl |= E1000_RFCTL_EXTEN; | 2941 | rfctl |= E1000_RFCTL_EXTEN; |
2942 | ew32(RFCTL, rfctl); | ||
2942 | 2943 | ||
2943 | /* | 2944 | /* |
2944 | * 82571 and greater support packet-split where the protocol | 2945 | * 82571 and greater support packet-split where the protocol |
@@ -2964,13 +2965,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) | |||
2964 | if (adapter->rx_ps_pages) { | 2965 | if (adapter->rx_ps_pages) { |
2965 | u32 psrctl = 0; | 2966 | u32 psrctl = 0; |
2966 | 2967 | ||
2967 | /* | ||
2968 | * disable packet split support for IPv6 extension headers, | ||
2969 | * because some malformed IPv6 headers can hang the Rx | ||
2970 | */ | ||
2971 | rfctl |= (E1000_RFCTL_IPV6_EX_DIS | | ||
2972 | E1000_RFCTL_NEW_IPV6_EXT_DIS); | ||
2973 | |||
2974 | /* Enable Packet split descriptors */ | 2968 | /* Enable Packet split descriptors */ |
2975 | rctl |= E1000_RCTL_DTYP_PS; | 2969 | rctl |= E1000_RCTL_DTYP_PS; |
2976 | 2970 | ||
@@ -3009,7 +3003,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) | |||
3009 | */ | 3003 | */ |
3010 | } | 3004 | } |
3011 | 3005 | ||
3012 | ew32(RFCTL, rfctl); | ||
3013 | ew32(RCTL, rctl); | 3006 | ew32(RCTL, rctl); |
3014 | /* just started the receive unit, no need to restart */ | 3007 | /* just started the receive unit, no need to restart */ |
3015 | adapter->flags &= ~FLAG_RX_RESTART_NOW; | 3008 | adapter->flags &= ~FLAG_RX_RESTART_NOW; |