aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-02-04 23:50:02 -0500
committerRusty Russell <rusty@rustcorp.com.au>2008-02-04 07:50:02 -0500
commit34a48579e4fb380604d06f0409db3851bd22d785 (patch)
tree0bf5091284b456719b527a288bc79111987fd0f2
parent50c8ea8080700014872f2bbd7466d31ce0476290 (diff)
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: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r--drivers/net/virtio_net.c32
-rw-r--r--include/linux/virtio_net.h12
2 files changed, 20 insertions, 24 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 3492ae0951de..73f01db59ab9 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -24,6 +24,10 @@
24#include <linux/virtio_net.h> 24#include <linux/virtio_net.h>
25#include <linux/scatterlist.h> 25#include <linux/scatterlist.h>
26 26
27static int csum = 1, gso = 1;
28module_param(csum, bool, 0444);
29module_param(gso, bool, 0444);
30
27/* FIXME: MTU in config. */ 31/* FIXME: MTU in config. */
28#define MAX_PACKET_LEN (ETH_HLEN+ETH_DATA_LEN) 32#define MAX_PACKET_LEN (ETH_HLEN+ETH_DATA_LEN)
29 33
@@ -88,13 +92,10 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb,
88 92
89 if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { 93 if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
90 pr_debug("GSO!\n"); 94 pr_debug("GSO!\n");
91 switch (hdr->gso_type) { 95 switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
92 case VIRTIO_NET_HDR_GSO_TCPV4: 96 case VIRTIO_NET_HDR_GSO_TCPV4:
93 skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; 97 skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
94 break; 98 break;
95 case VIRTIO_NET_HDR_GSO_TCPV4_ECN:
96 skb_shinfo(skb)->gso_type = SKB_GSO_TCP_ECN;
97 break;
98 case VIRTIO_NET_HDR_GSO_UDP: 99 case VIRTIO_NET_HDR_GSO_UDP:
99 skb_shinfo(skb)->gso_type = SKB_GSO_UDP; 100 skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
100 break; 101 break;
@@ -108,6 +109,9 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb,
108 goto frame_err; 109 goto frame_err;
109 } 110 }
110 111
112 if (hdr->gso_type & VIRTIO_NET_HDR_GSO_ECN)
113 skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN;
114
111 skb_shinfo(skb)->gso_size = hdr->gso_size; 115 skb_shinfo(skb)->gso_size = hdr->gso_size;
112 if (skb_shinfo(skb)->gso_size == 0) { 116 if (skb_shinfo(skb)->gso_size == 0) {
113 if (net_ratelimit()) 117 if (net_ratelimit())
@@ -244,9 +248,7 @@ static int start_xmit(struct sk_buff *skb, struct net_device *dev)
244 if (skb_is_gso(skb)) { 248 if (skb_is_gso(skb)) {
245 hdr->hdr_len = skb_transport_header(skb) - skb->data; 249 hdr->hdr_len = skb_transport_header(skb) - skb->data;
246 hdr->gso_size = skb_shinfo(skb)->gso_size; 250 hdr->gso_size = skb_shinfo(skb)->gso_size;
247 if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN) 251 if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
248 hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4_ECN;
249 else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
250 hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; 252 hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
251 else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) 253 else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
252 hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6; 254 hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
@@ -254,6 +256,8 @@ static int start_xmit(struct sk_buff *skb, struct net_device *dev)
254 hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP; 256 hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP;
255 else 257 else
256 BUG(); 258 BUG();
259 if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN)
260 hdr->gso_type |= VIRTIO_NET_HDR_GSO_ECN;
257 } else { 261 } else {
258 hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE; 262 hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
259 hdr->gso_size = hdr->hdr_len = 0; 263 hdr->gso_size = hdr->hdr_len = 0;
@@ -330,17 +334,13 @@ static int virtnet_probe(struct virtio_device *vdev)
330 SET_NETDEV_DEV(dev, &vdev->dev); 334 SET_NETDEV_DEV(dev, &vdev->dev);
331 335
332 /* Do we support "hardware" checksums? */ 336 /* Do we support "hardware" checksums? */
333 if (vdev->config->feature(vdev, VIRTIO_NET_F_NO_CSUM)) { 337 if (csum && vdev->config->feature(vdev, VIRTIO_NET_F_CSUM)) {
334 /* This opens up the world of extra features. */ 338 /* This opens up the world of extra features. */
335 dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; 339 dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
336 if (vdev->config->feature(vdev, VIRTIO_NET_F_TSO4)) 340 if (gso && vdev->config->feature(vdev, VIRTIO_NET_F_GSO)) {
337 dev->features |= NETIF_F_TSO; 341 dev->features |= NETIF_F_TSO | NETIF_F_UFO
338 if (vdev->config->feature(vdev, VIRTIO_NET_F_UFO)) 342 | NETIF_F_TSO_ECN | NETIF_F_TSO6;
339 dev->features |= NETIF_F_UFO; 343 }
340 if (vdev->config->feature(vdev, VIRTIO_NET_F_TSO4_ECN))
341 dev->features |= NETIF_F_TSO_ECN;
342 if (vdev->config->feature(vdev, VIRTIO_NET_F_TSO6))
343 dev->features |= NETIF_F_TSO6;
344 } 344 }
345 345
346 /* Configuration may specify what MAC to use. Otherwise random. */ 346 /* Configuration may specify what MAC to use. Otherwise random. */
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
index 1456f7b936d0..1ea3351df609 100644
--- a/include/linux/virtio_net.h
+++ b/include/linux/virtio_net.h
@@ -6,12 +6,9 @@
6#define VIRTIO_ID_NET 1 6#define VIRTIO_ID_NET 1
7 7
8/* The feature bitmap for virtio net */ 8/* The feature bitmap for virtio net */
9#define VIRTIO_NET_F_NO_CSUM 0 9#define VIRTIO_NET_F_CSUM 0 /* Can handle pkts w/ partial csum */
10#define VIRTIO_NET_F_TSO4 1 10#define VIRTIO_NET_F_MAC 5 /* Host has given MAC address. */
11#define VIRTIO_NET_F_UFO 2 11#define VIRTIO_NET_F_GSO 6 /* Can handle pkts w/ any GSO type */
12#define VIRTIO_NET_F_TSO4_ECN 3
13#define VIRTIO_NET_F_TSO6 4
14#define VIRTIO_NET_F_MAC 5
15 12
16struct virtio_net_config 13struct virtio_net_config
17{ 14{
@@ -27,10 +24,9 @@ struct virtio_net_hdr
27 __u8 flags; 24 __u8 flags;
28#define VIRTIO_NET_HDR_GSO_NONE 0 // Not a GSO frame 25#define VIRTIO_NET_HDR_GSO_NONE 0 // Not a GSO frame
29#define VIRTIO_NET_HDR_GSO_TCPV4 1 // GSO frame, IPv4 TCP (TSO) 26#define VIRTIO_NET_HDR_GSO_TCPV4 1 // GSO frame, IPv4 TCP (TSO)
30/* FIXME: Do we need this? If they said they can handle ECN, do they care? */
31#define VIRTIO_NET_HDR_GSO_TCPV4_ECN 2 // GSO frame, IPv4 TCP w/ ECN
32#define VIRTIO_NET_HDR_GSO_UDP 3 // GSO frame, IPv4 UDP (UFO) 27#define VIRTIO_NET_HDR_GSO_UDP 3 // GSO frame, IPv4 UDP (UFO)
33#define VIRTIO_NET_HDR_GSO_TCPV6 4 // GSO frame, IPv6 TCP 28#define VIRTIO_NET_HDR_GSO_TCPV6 4 // GSO frame, IPv6 TCP
29#define VIRTIO_NET_HDR_GSO_ECN 0x80 // TCP has ECN set
34 __u8 gso_type; 30 __u8 gso_type;
35 __u16 hdr_len; /* Ethernet + IP + tcp/udp hdrs */ 31 __u16 hdr_len; /* Ethernet + IP + tcp/udp hdrs */
36 __u16 gso_size; /* Bytes to append to gso_hdr_len per frame */ 32 __u16 gso_size; /* Bytes to append to gso_hdr_len per frame */