/**
  * i40e_tso - set up the tso context descriptor
- * @skb:      ptr to the skb we're sending
+ * @first:    pointer to first Tx buffer for xmit
  * @hdr_len:  ptr to the size of the packet header
  * @cd_type_cmd_tso_mss: Quad Word 1
  *
  * Returns 0 if no TSO can happen, 1 if tso is going, or error
  **/
-static int i40e_tso(struct sk_buff *skb, u8 *hdr_len, u64 *cd_type_cmd_tso_mss)
+static int i40e_tso(struct i40e_tx_buffer *first, u8 *hdr_len,
+                   u64 *cd_type_cmd_tso_mss)
 {
+       struct sk_buff *skb = first->skb;
        u64 cd_cmd, cd_tso_len, cd_mss;
        union {
                struct iphdr *v4;
                unsigned char *hdr;
        } l4;
        u32 paylen, l4_offset;
+       u16 gso_segs, gso_size;
        int err;
 
        if (skb->ip_summed != CHECKSUM_PARTIAL)
        /* compute length of segmentation header */
        *hdr_len = (l4.tcp->doff * 4) + l4_offset;
 
+       /* pull values out of skb_shinfo */
+       gso_size = skb_shinfo(skb)->gso_size;
+       gso_segs = skb_shinfo(skb)->gso_segs;
+
+       /* update GSO size and bytecount with header size */
+       first->gso_segs = gso_segs;
+       first->bytecount += (first->gso_segs - 1) * *hdr_len;
+
        /* find the field values */
        cd_cmd = I40E_TX_CTX_DESC_TSO;
        cd_tso_len = skb->len - *hdr_len;
-       cd_mss = skb_shinfo(skb)->gso_size;
+       cd_mss = gso_size;
        *cd_type_cmd_tso_mss |= (cd_cmd << I40E_TXD_CTX_QW1_CMD_SHIFT) |
                                (cd_tso_len << I40E_TXD_CTX_QW1_TSO_LEN_SHIFT) |
                                (cd_mss << I40E_TXD_CTX_QW1_MSS_SHIFT);
        u16 i = tx_ring->next_to_use;
        u32 td_tag = 0;
        dma_addr_t dma;
-       u16 gso_segs;
        u16 desc_count = 1;
 
        if (tx_flags & I40E_TX_FLAGS_HW_VLAN) {
                         I40E_TX_FLAGS_VLAN_SHIFT;
        }
 
-       if (tx_flags & (I40E_TX_FLAGS_TSO | I40E_TX_FLAGS_FSO))
-               gso_segs = skb_shinfo(skb)->gso_segs;
-       else
-               gso_segs = 1;
-
-       /* multiply data chunks by size of headers */
-       first->bytecount = skb->len - hdr_len + (gso_segs * hdr_len);
-       first->gso_segs = gso_segs;
-       first->skb = skb;
        first->tx_flags = tx_flags;
 
        dma = dma_map_single(tx_ring->dev, skb->data, size, DMA_TO_DEVICE);
 
        count = i40e_xmit_descriptor_count(skb);
        if (i40e_chk_linearize(skb, count)) {
-               if (__skb_linearize(skb))
-                       goto out_drop;
+               if (__skb_linearize(skb)) {
+                       dev_kfree_skb_any(skb);
+                       return NETDEV_TX_OK;
+               }
                count = i40e_txd_use_count(skb->len);
                tx_ring->tx_stats.tx_linearize++;
        }
                return NETDEV_TX_BUSY;
        }
 
+       /* record the location of the first descriptor for this packet */
+       first = &tx_ring->tx_bi[tx_ring->next_to_use];
+       first->skb = skb;
+       first->bytecount = skb->len;
+       first->gso_segs = 1;
+
        /* prepare the xmit flags */
        if (i40e_tx_prepare_vlan_flags(skb, tx_ring, &tx_flags))
                goto out_drop;
        /* obtain protocol of skb */
        protocol = vlan_get_protocol(skb);
 
-       /* record the location of the first descriptor for this packet */
-       first = &tx_ring->tx_bi[tx_ring->next_to_use];
-
        /* setup IPv4/IPv6 offloads */
        if (protocol == htons(ETH_P_IP))
                tx_flags |= I40E_TX_FLAGS_IPV4;
        else if (protocol == htons(ETH_P_IPV6))
                tx_flags |= I40E_TX_FLAGS_IPV6;
 
-       tso = i40e_tso(skb, &hdr_len, &cd_type_cmd_tso_mss);
+       tso = i40e_tso(first, &hdr_len, &cd_type_cmd_tso_mss);
 
        if (tso < 0)
                goto out_drop;
        return NETDEV_TX_OK;
 
 out_drop:
-       dev_kfree_skb_any(skb);
+       dev_kfree_skb_any(first->skb);
+       first->skb = NULL;
        return NETDEV_TX_OK;
 }
 
 
 
 /**
  * i40e_tso - set up the tso context descriptor
- * @skb:      ptr to the skb we're sending
+ * @first:    pointer to first Tx buffer for xmit
  * @hdr_len:  ptr to the size of the packet header
  * @cd_type_cmd_tso_mss: Quad Word 1
  *
  * Returns 0 if no TSO can happen, 1 if tso is going, or error
  **/
-static int i40e_tso(struct sk_buff *skb, u8 *hdr_len, u64 *cd_type_cmd_tso_mss)
+static int i40e_tso(struct i40e_tx_buffer *first, u8 *hdr_len,
+                   u64 *cd_type_cmd_tso_mss)
 {
+       struct sk_buff *skb = first->skb;
        u64 cd_cmd, cd_tso_len, cd_mss;
        union {
                struct iphdr *v4;
                unsigned char *hdr;
        } l4;
        u32 paylen, l4_offset;
+       u16 gso_segs, gso_size;
        int err;
 
        if (skb->ip_summed != CHECKSUM_PARTIAL)
        /* compute length of segmentation header */
        *hdr_len = (l4.tcp->doff * 4) + l4_offset;
 
+       /* pull values out of skb_shinfo */
+       gso_size = skb_shinfo(skb)->gso_size;
+       gso_segs = skb_shinfo(skb)->gso_segs;
+
+       /* update GSO size and bytecount with header size */
+       first->gso_segs = gso_segs;
+       first->bytecount += (first->gso_segs - 1) * *hdr_len;
+
        /* find the field values */
        cd_cmd = I40E_TX_CTX_DESC_TSO;
        cd_tso_len = skb->len - *hdr_len;
-       cd_mss = skb_shinfo(skb)->gso_size;
+       cd_mss = gso_size;
        *cd_type_cmd_tso_mss |= (cd_cmd << I40E_TXD_CTX_QW1_CMD_SHIFT) |
                                (cd_tso_len << I40E_TXD_CTX_QW1_TSO_LEN_SHIFT) |
                                (cd_mss << I40E_TXD_CTX_QW1_MSS_SHIFT);
        u16 i = tx_ring->next_to_use;
        u32 td_tag = 0;
        dma_addr_t dma;
-       u16 gso_segs;
        u16 desc_count = 1;
 
        if (tx_flags & I40E_TX_FLAGS_HW_VLAN) {
                         I40E_TX_FLAGS_VLAN_SHIFT;
        }
 
-       if (tx_flags & (I40E_TX_FLAGS_TSO | I40E_TX_FLAGS_FSO))
-               gso_segs = skb_shinfo(skb)->gso_segs;
-       else
-               gso_segs = 1;
-
-       /* multiply data chunks by size of headers */
-       first->bytecount = skb->len - hdr_len + (gso_segs * hdr_len);
-       first->gso_segs = gso_segs;
-       first->skb = skb;
        first->tx_flags = tx_flags;
 
        dma = dma_map_single(tx_ring->dev, skb->data, size, DMA_TO_DEVICE);
 
        count = i40e_xmit_descriptor_count(skb);
        if (i40e_chk_linearize(skb, count)) {
-               if (__skb_linearize(skb))
-                       goto out_drop;
+               if (__skb_linearize(skb)) {
+                       dev_kfree_skb_any(skb);
+                       return NETDEV_TX_OK;
+               }
                count = i40e_txd_use_count(skb->len);
                tx_ring->tx_stats.tx_linearize++;
        }
                return NETDEV_TX_BUSY;
        }
 
+       /* record the location of the first descriptor for this packet */
+       first = &tx_ring->tx_bi[tx_ring->next_to_use];
+       first->skb = skb;
+       first->bytecount = skb->len;
+       first->gso_segs = 1;
+
        /* prepare the xmit flags */
        if (i40evf_tx_prepare_vlan_flags(skb, tx_ring, &tx_flags))
                goto out_drop;
        /* obtain protocol of skb */
        protocol = vlan_get_protocol(skb);
 
-       /* record the location of the first descriptor for this packet */
-       first = &tx_ring->tx_bi[tx_ring->next_to_use];
-
        /* setup IPv4/IPv6 offloads */
        if (protocol == htons(ETH_P_IP))
                tx_flags |= I40E_TX_FLAGS_IPV4;
        else if (protocol == htons(ETH_P_IPV6))
                tx_flags |= I40E_TX_FLAGS_IPV6;
 
-       tso = i40e_tso(skb, &hdr_len, &cd_type_cmd_tso_mss);
+       tso = i40e_tso(first, &hdr_len, &cd_type_cmd_tso_mss);
 
        if (tso < 0)
                goto out_drop;
        return NETDEV_TX_OK;
 
 out_drop:
-       dev_kfree_skb_any(skb);
+       dev_kfree_skb_any(first->skb);
+       first->skb = NULL;
        return NETDEV_TX_OK;
 }