diff options
author | Michael Chan <mchan@broadcom.com> | 2013-05-13 07:04:16 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-05-14 14:32:04 -0400 |
commit | 0f0d15100a8ac875bdd408324c473e16d73d3557 (patch) | |
tree | febfe0543aa31aa965ec5358a6e71f6672d25380 /drivers/net/ethernet/broadcom/tg3.c | |
parent | 44f3b503c16425c8e9db4bbaa2fc9cd0c9d0ba91 (diff) |
tg3: Fix data corruption on 5725 with TSO
The 5725 family of devices (asic rev 5762), corrupts TSO packets where
the buffer is within MSS bytes of a 4G boundary (4G, 8G etc.). Detect
this condition and trigger the workaround path.
Cc: <stable@vger.kernel.org>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: Nithin Nayak Sujir <nsujir@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/tg3.c')
-rw-r--r-- | drivers/net/ethernet/broadcom/tg3.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 781be7660125..e285d7645651 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -7448,6 +7448,20 @@ static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len) | |||
7448 | return (base > 0xffffdcc0) && (base + len + 8 < base); | 7448 | return (base > 0xffffdcc0) && (base + len + 8 < base); |
7449 | } | 7449 | } |
7450 | 7450 | ||
7451 | /* Test for TSO DMA buffers that cross into regions which are within MSS bytes | ||
7452 | * of any 4GB boundaries: 4G, 8G, etc | ||
7453 | */ | ||
7454 | static inline int tg3_4g_tso_overflow_test(struct tg3 *tp, dma_addr_t mapping, | ||
7455 | u32 len, u32 mss) | ||
7456 | { | ||
7457 | if (tg3_asic_rev(tp) == ASIC_REV_5762 && mss) { | ||
7458 | u32 base = (u32) mapping & 0xffffffff; | ||
7459 | |||
7460 | return ((base + len + (mss & 0x3fff)) < base); | ||
7461 | } | ||
7462 | return 0; | ||
7463 | } | ||
7464 | |||
7451 | /* Test for DMA addresses > 40-bit */ | 7465 | /* Test for DMA addresses > 40-bit */ |
7452 | static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping, | 7466 | static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping, |
7453 | int len) | 7467 | int len) |
@@ -7484,6 +7498,9 @@ static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget, | |||
7484 | if (tg3_4g_overflow_test(map, len)) | 7498 | if (tg3_4g_overflow_test(map, len)) |
7485 | hwbug = true; | 7499 | hwbug = true; |
7486 | 7500 | ||
7501 | if (tg3_4g_tso_overflow_test(tp, map, len, mss)) | ||
7502 | hwbug = true; | ||
7503 | |||
7487 | if (tg3_40bit_overflow_test(tp, map, len)) | 7504 | if (tg3_40bit_overflow_test(tp, map, len)) |
7488 | hwbug = true; | 7505 | hwbug = true; |
7489 | 7506 | ||