diff options
Diffstat (limited to 'drivers/net/ethernet/intel/i40e/i40e_txrx.c')
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_txrx.c | 25 |
1 files changed, 10 insertions, 15 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 4bd3a80aba82..9d95042d5a0f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c | |||
@@ -2410,14 +2410,12 @@ static int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size) | |||
2410 | * i40e_chk_linearize - Check if there are more than 8 fragments per packet | 2410 | * i40e_chk_linearize - Check if there are more than 8 fragments per packet |
2411 | * @skb: send buffer | 2411 | * @skb: send buffer |
2412 | * @tx_flags: collected send information | 2412 | * @tx_flags: collected send information |
2413 | * @hdr_len: size of the packet header | ||
2414 | * | 2413 | * |
2415 | * Note: Our HW can't scatter-gather more than 8 fragments to build | 2414 | * Note: Our HW can't scatter-gather more than 8 fragments to build |
2416 | * a packet on the wire and so we need to figure out the cases where we | 2415 | * a packet on the wire and so we need to figure out the cases where we |
2417 | * need to linearize the skb. | 2416 | * need to linearize the skb. |
2418 | **/ | 2417 | **/ |
2419 | static bool i40e_chk_linearize(struct sk_buff *skb, u32 tx_flags, | 2418 | static bool i40e_chk_linearize(struct sk_buff *skb, u32 tx_flags) |
2420 | const u8 hdr_len) | ||
2421 | { | 2419 | { |
2422 | struct skb_frag_struct *frag; | 2420 | struct skb_frag_struct *frag; |
2423 | bool linearize = false; | 2421 | bool linearize = false; |
@@ -2429,7 +2427,7 @@ static bool i40e_chk_linearize(struct sk_buff *skb, u32 tx_flags, | |||
2429 | gso_segs = skb_shinfo(skb)->gso_segs; | 2427 | gso_segs = skb_shinfo(skb)->gso_segs; |
2430 | 2428 | ||
2431 | if (tx_flags & (I40E_TX_FLAGS_TSO | I40E_TX_FLAGS_FSO)) { | 2429 | if (tx_flags & (I40E_TX_FLAGS_TSO | I40E_TX_FLAGS_FSO)) { |
2432 | u16 j = 1; | 2430 | u16 j = 0; |
2433 | 2431 | ||
2434 | if (num_frags < (I40E_MAX_BUFFER_TXD)) | 2432 | if (num_frags < (I40E_MAX_BUFFER_TXD)) |
2435 | goto linearize_chk_done; | 2433 | goto linearize_chk_done; |
@@ -2440,21 +2438,18 @@ static bool i40e_chk_linearize(struct sk_buff *skb, u32 tx_flags, | |||
2440 | goto linearize_chk_done; | 2438 | goto linearize_chk_done; |
2441 | } | 2439 | } |
2442 | frag = &skb_shinfo(skb)->frags[0]; | 2440 | frag = &skb_shinfo(skb)->frags[0]; |
2443 | size = hdr_len; | ||
2444 | /* we might still have more fragments per segment */ | 2441 | /* we might still have more fragments per segment */ |
2445 | do { | 2442 | do { |
2446 | size += skb_frag_size(frag); | 2443 | size += skb_frag_size(frag); |
2447 | frag++; j++; | 2444 | frag++; j++; |
2445 | if ((size >= skb_shinfo(skb)->gso_size) && | ||
2446 | (j < I40E_MAX_BUFFER_TXD)) { | ||
2447 | size = (size % skb_shinfo(skb)->gso_size); | ||
2448 | j = (size) ? 1 : 0; | ||
2449 | } | ||
2448 | if (j == I40E_MAX_BUFFER_TXD) { | 2450 | if (j == I40E_MAX_BUFFER_TXD) { |
2449 | if (size < skb_shinfo(skb)->gso_size) { | 2451 | linearize = true; |
2450 | linearize = true; | 2452 | break; |
2451 | break; | ||
2452 | } | ||
2453 | j = 1; | ||
2454 | size -= skb_shinfo(skb)->gso_size; | ||
2455 | if (size) | ||
2456 | j++; | ||
2457 | size += hdr_len; | ||
2458 | } | 2453 | } |
2459 | num_frags--; | 2454 | num_frags--; |
2460 | } while (num_frags); | 2455 | } while (num_frags); |
@@ -2724,7 +2719,7 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb, | |||
2724 | if (tsyn) | 2719 | if (tsyn) |
2725 | tx_flags |= I40E_TX_FLAGS_TSYN; | 2720 | tx_flags |= I40E_TX_FLAGS_TSYN; |
2726 | 2721 | ||
2727 | if (i40e_chk_linearize(skb, tx_flags, hdr_len)) | 2722 | if (i40e_chk_linearize(skb, tx_flags)) |
2728 | if (skb_linearize(skb)) | 2723 | if (skb_linearize(skb)) |
2729 | goto out_drop; | 2724 | goto out_drop; |
2730 | 2725 | ||