Commit a54e3b8c authored by Brett Creeley's avatar Brett Creeley Committed by Jeff Kirsher

ice: Support UDP segmentation offload

Based on the work done by Alex Duyck on other Intel drivers, add code to
support UDP segmentation offload (USO) for the ice driver.
Signed-off-by: default avatarBrett Creeley <brett.creeley@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 3c85efb8
...@@ -2330,7 +2330,8 @@ static void ice_set_netdev_features(struct net_device *netdev) ...@@ -2330,7 +2330,8 @@ static void ice_set_netdev_features(struct net_device *netdev)
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX; NETIF_F_HW_VLAN_CTAG_RX;
tso_features = NETIF_F_TSO; tso_features = NETIF_F_TSO |
NETIF_F_GSO_UDP_L4;
/* set features that user can change */ /* set features that user can change */
netdev->hw_features = dflt_features | csumo_features | netdev->hw_features = dflt_features | csumo_features |
......
...@@ -1925,6 +1925,7 @@ int ice_tso(struct ice_tx_buf *first, struct ice_tx_offload_params *off) ...@@ -1925,6 +1925,7 @@ int ice_tso(struct ice_tx_buf *first, struct ice_tx_offload_params *off)
} ip; } ip;
union { union {
struct tcphdr *tcp; struct tcphdr *tcp;
struct udphdr *udp;
unsigned char *hdr; unsigned char *hdr;
} l4; } l4;
u64 cd_mss, cd_tso_len; u64 cd_mss, cd_tso_len;
...@@ -1958,10 +1959,18 @@ int ice_tso(struct ice_tx_buf *first, struct ice_tx_offload_params *off) ...@@ -1958,10 +1959,18 @@ int ice_tso(struct ice_tx_buf *first, struct ice_tx_offload_params *off)
/* remove payload length from checksum */ /* remove payload length from checksum */
paylen = skb->len - l4_start; paylen = skb->len - l4_start;
csum_replace_by_diff(&l4.tcp->check, (__force __wsum)htonl(paylen));
/* compute length of segmentation header */ 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 */
off->header_len = sizeof(l4.udp) + l4_start;
} else {
csum_replace_by_diff(&l4.tcp->check,
(__force __wsum)htonl(paylen));
/* compute length of TCP segmentation header */
off->header_len = (l4.tcp->doff * 4) + l4_start; off->header_len = (l4.tcp->doff * 4) + l4_start;
}
/* update gso_segs and bytecount */ /* update gso_segs and bytecount */
first->gso_segs = skb_shinfo(skb)->gso_segs; first->gso_segs = skb_shinfo(skb)->gso_segs;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment