summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDon Skidmore <donald.c.skidmore@intel.com>2009-07-23 18:00:39 +0000
committerDavid S. Miller <davem@davemloft.net>2009-07-26 20:20:47 -0700
commit8bae1b2b13beb4cf4c0f119f97640503c2b74b0f (patch)
treef66e5ff4f682c7eb8fb46b90b3c6ba8aa2e3a143
parentca52efd5490f97f396d3c5863ba714624f272033 (diff)
ixgbe: fix for 82599 errata marking UDP checksum errors
There is an 82599 errata that UDP frames with a zero checksum are incorrectly marked as checksum invalid by the hardware. This was leading to misleading hw_csum_rx_error counts. This patch adds a test around this counter increase for this condition. Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 68877599f6db..200454f30f6a 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -511,8 +511,11 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
* @skb: skb currently being received and modified
**/
static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter,
- u32 status_err, struct sk_buff *skb)
+ union ixgbe_adv_rx_desc *rx_desc,
+ struct sk_buff *skb)
{
+ u32 status_err = le32_to_cpu(rx_desc->wb.upper.status_error);
+
skb->ip_summed = CHECKSUM_NONE;
/* Rx csum disabled */
@@ -530,6 +533,16 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter,
return;
if (status_err & IXGBE_RXDADV_ERR_TCPE) {
+ u16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
+
+ /*
+ * 82599 errata, UDP frames with a 0 checksum can be marked as
+ * checksum errors.
+ */
+ if ((pkt_info & IXGBE_RXDADV_PKTTYPE_UDP) &&
+ (adapter->hw.mac.type == ixgbe_mac_82599EB))
+ return;
+
adapter->hw_csum_rx_error++;
return;
}
@@ -803,7 +816,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
goto next_desc;
}
- ixgbe_rx_checksum(adapter, staterr, skb);
+ ixgbe_rx_checksum(adapter, rx_desc, skb);
/* probably a little skewed due to removing CRC */
total_rx_bytes += skb->len;