Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34a48579 authored by Rusty Russell's avatar Rusty Russell
Browse files

virtio: Tweak virtio_net defines



1) Turn GSO on virtio net into an all-or-nothing (keep checksumming
   separate).  Having multiple bits is a pain: if you can't support something
   you should handle it in software, which is still a performance win.

2) Make VIRTIO_NET_HDR_GSO_ECN a flag in the header, so it can apply to
   IPv6 or v4.

3) Rename VIRTIO_NET_F_NO_CSUM to VIRTIO_NET_F_CSUM (ie. means we do
   checksumming).

4) Add csum and gso params to virtio_net to allow more testing.

Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 50c8ea80
Loading
Loading
Loading
Loading
+16 −16
Original line number Diff line number Diff line
@@ -24,6 +24,10 @@
#include <linux/virtio_net.h>
#include <linux/scatterlist.h>

static int csum = 1, gso = 1;
module_param(csum, bool, 0444);
module_param(gso, bool, 0444);

/* FIXME: MTU in config. */
#define MAX_PACKET_LEN (ETH_HLEN+ETH_DATA_LEN)

@@ -88,13 +92,10 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb,

	if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
		pr_debug("GSO!\n");
		switch (hdr->gso_type) {
		switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
		case VIRTIO_NET_HDR_GSO_TCPV4:
			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
			break;
		case VIRTIO_NET_HDR_GSO_TCPV4_ECN:
			skb_shinfo(skb)->gso_type = SKB_GSO_TCP_ECN;
			break;
		case VIRTIO_NET_HDR_GSO_UDP:
			skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
			break;
@@ -108,6 +109,9 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb,
			goto frame_err;
		}

		if (hdr->gso_type & VIRTIO_NET_HDR_GSO_ECN)
			skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN;

		skb_shinfo(skb)->gso_size = hdr->gso_size;
		if (skb_shinfo(skb)->gso_size == 0) {
			if (net_ratelimit())
@@ -244,9 +248,7 @@ static int start_xmit(struct sk_buff *skb, struct net_device *dev)
	if (skb_is_gso(skb)) {
		hdr->hdr_len = skb_transport_header(skb) - skb->data;
		hdr->gso_size = skb_shinfo(skb)->gso_size;
		if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN)
			hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4_ECN;
		else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
		if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
			hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
		else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
			hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
@@ -254,6 +256,8 @@ static int start_xmit(struct sk_buff *skb, struct net_device *dev)
			hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP;
		else
			BUG();
		if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN)
			hdr->gso_type |= VIRTIO_NET_HDR_GSO_ECN;
	} else {
		hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
		hdr->gso_size = hdr->hdr_len = 0;
@@ -330,17 +334,13 @@ static int virtnet_probe(struct virtio_device *vdev)
	SET_NETDEV_DEV(dev, &vdev->dev);

	/* Do we support "hardware" checksums? */
	if (vdev->config->feature(vdev, VIRTIO_NET_F_NO_CSUM)) {
	if (csum && vdev->config->feature(vdev, VIRTIO_NET_F_CSUM)) {
		/* This opens up the world of extra features. */
		dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
		if (vdev->config->feature(vdev, VIRTIO_NET_F_TSO4))
			dev->features |= NETIF_F_TSO;
		if (vdev->config->feature(vdev, VIRTIO_NET_F_UFO))
			dev->features |= NETIF_F_UFO;
		if (vdev->config->feature(vdev, VIRTIO_NET_F_TSO4_ECN))
			dev->features |= NETIF_F_TSO_ECN;
		if (vdev->config->feature(vdev, VIRTIO_NET_F_TSO6))
			dev->features |= NETIF_F_TSO6;
		if (gso && vdev->config->feature(vdev, VIRTIO_NET_F_GSO)) {
			dev->features |= NETIF_F_TSO | NETIF_F_UFO
				| NETIF_F_TSO_ECN | NETIF_F_TSO6;
		}
	}

	/* Configuration may specify what MAC to use.  Otherwise random. */
+4 −8
Original line number Diff line number Diff line
@@ -6,12 +6,9 @@
#define VIRTIO_ID_NET	1

/* The feature bitmap for virtio net */
#define VIRTIO_NET_F_NO_CSUM	0
#define VIRTIO_NET_F_TSO4	1
#define VIRTIO_NET_F_UFO	2
#define VIRTIO_NET_F_TSO4_ECN	3
#define VIRTIO_NET_F_TSO6	4
#define VIRTIO_NET_F_MAC	5
#define VIRTIO_NET_F_CSUM	0	/* Can handle pkts w/ partial csum */
#define VIRTIO_NET_F_MAC	5	/* Host has given MAC address. */
#define VIRTIO_NET_F_GSO	6	/* Can handle pkts w/ any GSO type */

struct virtio_net_config
{
@@ -27,10 +24,9 @@ struct virtio_net_hdr
	__u8 flags;
#define VIRTIO_NET_HDR_GSO_NONE		0	// Not a GSO frame
#define VIRTIO_NET_HDR_GSO_TCPV4	1	// GSO frame, IPv4 TCP (TSO)
/* FIXME: Do we need this?  If they said they can handle ECN, do they care? */
#define VIRTIO_NET_HDR_GSO_TCPV4_ECN	2	// GSO frame, IPv4 TCP w/ ECN
#define VIRTIO_NET_HDR_GSO_UDP		3	// GSO frame, IPv4 UDP (UFO)
#define VIRTIO_NET_HDR_GSO_TCPV6	4	// GSO frame, IPv6 TCP
#define VIRTIO_NET_HDR_GSO_ECN		0x80	// TCP has ECN set
	__u8 gso_type;
	__u16 hdr_len;		/* Ethernet + IP + tcp/udp hdrs */
	__u16 gso_size;		/* Bytes to append to gso_hdr_len per frame */