drivers/net/virtio_net.c: Added USO support.
authorAndrew Melnychenko <andrew@daynix.com>
Wed, 7 Dec 2022 11:35:58 +0000 (13:35 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 12 Dec 2022 09:29:56 +0000 (09:29 +0000)
Now, it possible to enable GSO_UDP_L4("tx-udp-segmentation") for VirtioNet.

Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/virtio_net.c

index 19eee06..7723b2a 100644 (file)
@@ -60,13 +60,17 @@ static const unsigned long guest_offloads[] = {
        VIRTIO_NET_F_GUEST_TSO6,
        VIRTIO_NET_F_GUEST_ECN,
        VIRTIO_NET_F_GUEST_UFO,
-       VIRTIO_NET_F_GUEST_CSUM
+       VIRTIO_NET_F_GUEST_CSUM,
+       VIRTIO_NET_F_GUEST_USO4,
+       VIRTIO_NET_F_GUEST_USO6
 };
 
 #define GUEST_OFFLOAD_GRO_HW_MASK ((1ULL << VIRTIO_NET_F_GUEST_TSO4) | \
                                (1ULL << VIRTIO_NET_F_GUEST_TSO6) | \
                                (1ULL << VIRTIO_NET_F_GUEST_ECN)  | \
-                               (1ULL << VIRTIO_NET_F_GUEST_UFO))
+                               (1ULL << VIRTIO_NET_F_GUEST_UFO)  | \
+                               (1ULL << VIRTIO_NET_F_GUEST_USO4) | \
+                               (1ULL << VIRTIO_NET_F_GUEST_USO6))
 
 struct virtnet_stat_desc {
        char desc[ETH_GSTRING_LEN];
@@ -3085,7 +3089,9 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
                virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO6) ||
                virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) ||
                virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO) ||
-               virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM))) {
+               virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM) ||
+               virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO4) ||
+               virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO6))) {
                NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW/CSUM, disable GRO_HW/CSUM first");
                return -EOPNOTSUPP;
        }
@@ -3690,7 +3696,9 @@ static bool virtnet_check_guest_gso(const struct virtnet_info *vi)
        return virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO4) ||
                virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO6) ||
                virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) ||
-               virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO);
+               virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO) ||
+               (virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO4) &&
+               virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO6));
 }
 
 static void virtnet_set_big_packets(struct virtnet_info *vi, const int mtu)
@@ -3759,6 +3767,8 @@ static int virtnet_probe(struct virtio_device *vdev)
                        dev->hw_features |= NETIF_F_TSO6;
                if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN))
                        dev->hw_features |= NETIF_F_TSO_ECN;
+               if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_USO))
+                       dev->hw_features |= NETIF_F_GSO_UDP_L4;
 
                dev->features |= NETIF_F_GSO_ROBUST;
 
@@ -4036,6 +4046,7 @@ static struct virtio_device_id id_table[] = {
        VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, \
        VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, \
        VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO, \
+       VIRTIO_NET_F_HOST_USO, VIRTIO_NET_F_GUEST_USO4, VIRTIO_NET_F_GUEST_USO6, \
        VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ, \
        VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, \
        VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, \