aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuval Mintz <Yuval.Mintz@qlogic.com>2015-12-18 03:42:12 -0500
committerDavid S. Miller <davem@davemloft.net>2015-12-18 16:34:32 -0500
commitea2465af3bbfa7994d134a401503966ee98710b6 (patch)
treeb1fafef828cc1bad1f283ad682d9921145f22d94
parent6d3c348a63685410b12bf961b97063efeef2f901 (diff)
bnx2x: Prevent FW assertion when using Vxlan
FW has a rare corner case in which a fragmented packet using lots of frags would not be linearized, causing the FW to assert while trying to transmit the packet. To prevent this, we need to make sure the window of fragements containing MSS worth of data contains 1 BD less than for regular packets due to the additional parsing BD. Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com> Signed-off-by: Ariel Elior <Ariel.Elior@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index f8d7a2f06950..c82ab87fcbe8 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -3430,25 +3430,29 @@ static u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
3430 return rc; 3430 return rc;
3431} 3431}
3432 3432
3433#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3) 3433/* VXLAN: 4 = 1 (for linear data BD) + 3 (2 for PBD and last BD) */
3434#define BNX2X_NUM_VXLAN_TSO_WIN_SUB_BDS 4
3435
3436/* Regular: 3 = 1 (for linear data BD) + 2 (for PBD and last BD) */
3437#define BNX2X_NUM_TSO_WIN_SUB_BDS 3
3438
3439#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - BDS_PER_TX_PKT)
3434/* check if packet requires linearization (packet is too fragmented) 3440/* check if packet requires linearization (packet is too fragmented)
3435 no need to check fragmentation if page size > 8K (there will be no 3441 no need to check fragmentation if page size > 8K (there will be no
3436 violation to FW restrictions) */ 3442 violation to FW restrictions) */
3437static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb, 3443static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
3438 u32 xmit_type) 3444 u32 xmit_type)
3439{ 3445{
3440 int to_copy = 0; 3446 int first_bd_sz = 0, num_tso_win_sub = BNX2X_NUM_TSO_WIN_SUB_BDS;
3441 int hlen = 0; 3447 int to_copy = 0, hlen = 0;
3442 int first_bd_sz = 0;
3443 3448
3444 /* 3 = 1 (for linear data BD) + 2 (for PBD and last BD) */ 3449 if (xmit_type & XMIT_GSO_ENC)
3445 if (skb_shinfo(skb)->nr_frags >= (MAX_FETCH_BD - 3)) { 3450 num_tso_win_sub = BNX2X_NUM_VXLAN_TSO_WIN_SUB_BDS;
3446 3451
3452 if (skb_shinfo(skb)->nr_frags >= (MAX_FETCH_BD - num_tso_win_sub)) {
3447 if (xmit_type & XMIT_GSO) { 3453 if (xmit_type & XMIT_GSO) {
3448 unsigned short lso_mss = skb_shinfo(skb)->gso_size; 3454 unsigned short lso_mss = skb_shinfo(skb)->gso_size;
3449 /* Check if LSO packet needs to be copied: 3455 int wnd_size = MAX_FETCH_BD - num_tso_win_sub;
3450 3 = 1 (for headers BD) + 2 (for PBD and last BD) */
3451 int wnd_size = MAX_FETCH_BD - 3;
3452 /* Number of windows to check */ 3456 /* Number of windows to check */
3453 int num_wnds = skb_shinfo(skb)->nr_frags - wnd_size; 3457 int num_wnds = skb_shinfo(skb)->nr_frags - wnd_size;
3454 int wnd_idx = 0; 3458 int wnd_idx = 0;