OSDN Git Service

iavf: add support for UDP Segmentation Offload
authorBrett Creeley <brett.creeley@intel.com>
Tue, 2 Mar 2021 18:12:13 +0000 (10:12 -0800)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Thu, 22 Apr 2021 16:26:22 +0000 (09:26 -0700)
Add code to support UDP segmentation offload (USO) for
hardware that supports it.

Suggested-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Brett Creeley <brett.creeley@intel.com>
Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/iavf/iavf_main.c
drivers/net/ethernet/intel/iavf/iavf_txrx.c
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c

index a3268c8..6cd6b9d 100644 (file)
@@ -3542,6 +3542,8 @@ int iavf_process_config(struct iavf_adapter *adapter)
        /* Enable cloud filter if ADQ is supported */
        if (vfres->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ)
                hw_features |= NETIF_F_HW_TC;
+       if (vfres->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_USO)
+               hw_features |= NETIF_F_GSO_UDP_L4;
 
        netdev->hw_features |= hw_features;
 
index d6cba53..3525eab 100644 (file)
@@ -1905,13 +1905,20 @@ static int iavf_tso(struct iavf_tx_buffer *first, u8 *hdr_len,
 
        /* determine offset of inner transport header */
        l4_offset = l4.hdr - skb->data;
-
        /* remove payload length from inner checksum */
        paylen = skb->len - l4_offset;
-       csum_replace_by_diff(&l4.tcp->check, (__force __wsum)htonl(paylen));
 
-       /* compute length of segmentation header */
-       *hdr_len = (l4.tcp->doff * 4) + l4_offset;
+       if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) {
+               csum_replace_by_diff(&l4.udp->check,
+                                    (__force __wsum)htonl(paylen));
+               /* compute length of UDP segmentation header */
+               *hdr_len = (u8)sizeof(l4.udp) + l4_offset;
+       } else {
+               csum_replace_by_diff(&l4.tcp->check,
+                                    (__force __wsum)htonl(paylen));
+               /* compute length of TCP segmentation header */
+               *hdr_len = (u8)((l4.tcp->doff * 4) + l4_offset);
+       }
 
        /* pull values out of skb_shinfo */
        gso_size = skb_shinfo(skb)->gso_size;
index 3069092..9aaade0 100644 (file)
@@ -140,6 +140,7 @@ int iavf_send_vf_config_msg(struct iavf_adapter *adapter)
               VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM |
               VIRTCHNL_VF_OFFLOAD_REQ_QUEUES |
               VIRTCHNL_VF_OFFLOAD_ADQ |
+              VIRTCHNL_VF_OFFLOAD_USO |
               VIRTCHNL_VF_OFFLOAD_FDIR_PF |
               VIRTCHNL_VF_CAP_ADV_LINK_SPEED;