aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Kravkov <dmitry@broadcom.com>2012-02-20 04:59:11 -0500
committerDavid S. Miller <davem@davemloft.net>2012-02-20 19:34:08 -0500
commitfe603b4d680a2bba9d8c6d4267450fcf295f30d1 (patch)
tree9a95941a880b25f703eac83f444f2f92ea0a9cd0
parente65de0716f4fb72b09fb37f603b71f4eabe18322 (diff)
bnx2x: add gro_check
The patch provides workaround for BUG in FW 7.2.16, which in GRO mode may miscalculate buffer and place on SGE one frag less than it could. It may happen only for some MTUs, we mark these MTUs with gro_check flag during device initialization or MTU change. Next FW should include fix for the issue and the patch could be reverted. Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x.h4
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c12
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h7
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c2
4 files changed, 25 insertions, 0 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 3cf9df833cb4..6ebb55d6a98f 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -341,6 +341,7 @@ union db_prod {
341#define SGE_PAGE_SIZE PAGE_SIZE 341#define SGE_PAGE_SIZE PAGE_SIZE
342#define SGE_PAGE_SHIFT PAGE_SHIFT 342#define SGE_PAGE_SHIFT PAGE_SHIFT
343#define SGE_PAGE_ALIGN(addr) PAGE_ALIGN((typeof(PAGE_SIZE))(addr)) 343#define SGE_PAGE_ALIGN(addr) PAGE_ALIGN((typeof(PAGE_SIZE))(addr))
344#define SGE_PAGES (SGE_PAGE_SIZE * PAGES_PER_SGE)
344 345
345/* SGE ring related macros */ 346/* SGE ring related macros */
346#define NUM_RX_SGE_PAGES 2 347#define NUM_RX_SGE_PAGES 2
@@ -1210,6 +1211,7 @@ struct bnx2x {
1210#define ETH_MAX_JUMBO_PACKET_SIZE 9600 1211#define ETH_MAX_JUMBO_PACKET_SIZE 9600
1211/* TCP with Timestamp Option (32) + IPv6 (40) */ 1212/* TCP with Timestamp Option (32) + IPv6 (40) */
1212#define ETH_MAX_TPA_HEADER_SIZE 72 1213#define ETH_MAX_TPA_HEADER_SIZE 72
1214#define ETH_MIN_TPA_HEADER_SIZE 40
1213 1215
1214 /* Max supported alignment is 256 (8 shift) */ 1216 /* Max supported alignment is 256 (8 shift) */
1215#define BNX2X_RX_ALIGN_SHIFT min(8, L1_CACHE_SHIFT) 1217#define BNX2X_RX_ALIGN_SHIFT min(8, L1_CACHE_SHIFT)
@@ -1329,6 +1331,8 @@ struct bnx2x {
1329 1331
1330 u8 wol; 1332 u8 wol;
1331 1333
1334 bool gro_check;
1335
1332 int rx_ring_size; 1336 int rx_ring_size;
1333 1337
1334 u16 tx_quick_cons_trip_int; 1338 u16 tx_quick_cons_trip_int;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 0a45251edb8f..f82dfff58243 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -330,6 +330,16 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue,
330 u16 gro_size = le16_to_cpu(cqe->pkt_len_or_gro_seg_len); 330 u16 gro_size = le16_to_cpu(cqe->pkt_len_or_gro_seg_len);
331 tpa_info->full_page = 331 tpa_info->full_page =
332 SGE_PAGE_SIZE * PAGES_PER_SGE / gro_size * gro_size; 332 SGE_PAGE_SIZE * PAGES_PER_SGE / gro_size * gro_size;
333 /*
334 * FW 7.2.16 BUG workaround:
335 * if SGE size is (exactly) multiple gro_size
336 * fw will place one less frag on SGE.
337 * the calculation is done only for potentially
338 * dangerous MTUs.
339 */
340 if (unlikely(bp->gro_check))
341 if (!(SGE_PAGE_SIZE * PAGES_PER_SGE % gro_size))
342 tpa_info->full_page -= gro_size;
333 tpa_info->gro_size = gro_size; 343 tpa_info->gro_size = gro_size;
334 } 344 }
335 345
@@ -3486,6 +3496,8 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
3486 */ 3496 */
3487 dev->mtu = new_mtu; 3497 dev->mtu = new_mtu;
3488 3498
3499 bp->gro_check = bnx2x_need_gro_check(new_mtu);
3500
3489 return bnx2x_reload_if_running(dev); 3501 return bnx2x_reload_if_running(dev);
3490} 3502}
3491 3503
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index d2093ee9b85e..33aa7de24016 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -1504,6 +1504,13 @@ static inline bool bnx2x_mtu_allows_gro(int mtu)
1504 */ 1504 */
1505 return mtu <= SGE_PAGE_SIZE && (U_ETH_SGL_SIZE * fpp) <= MAX_SKB_FRAGS; 1505 return mtu <= SGE_PAGE_SIZE && (U_ETH_SGL_SIZE * fpp) <= MAX_SKB_FRAGS;
1506} 1506}
1507
1508static inline bool bnx2x_need_gro_check(int mtu)
1509{
1510 return (SGE_PAGES / (mtu - ETH_MAX_TPA_HEADER_SIZE - 1)) !=
1511 (SGE_PAGES / (mtu - ETH_MIN_TPA_HEADER_SIZE + 1));
1512}
1513
1507/** 1514/**
1508 * bnx2x_bz_fp - zero content of the fastpath structure. 1515 * bnx2x_bz_fp - zero content of the fastpath structure.
1509 * 1516 *
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 816e7d42f61c..b4afef60a25b 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -10214,6 +10214,8 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
10214 if (CHIP_IS_E3B0(bp)) 10214 if (CHIP_IS_E3B0(bp))
10215 bp->max_cos = BNX2X_MULTI_TX_COS_E3B0; 10215 bp->max_cos = BNX2X_MULTI_TX_COS_E3B0;
10216 10216
10217 bp->gro_check = bnx2x_need_gro_check(bp->dev->mtu);
10218
10217 return rc; 10219 return rc;
10218} 10220}
10219 10221