aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/virtio_net.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r--drivers/net/virtio_net.c114
1 files changed, 100 insertions, 14 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index c28d7cb2035b..0196a0df9021 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -19,6 +19,7 @@
19//#define DEBUG 19//#define DEBUG
20#include <linux/netdevice.h> 20#include <linux/netdevice.h>
21#include <linux/etherdevice.h> 21#include <linux/etherdevice.h>
22#include <linux/ethtool.h>
22#include <linux/module.h> 23#include <linux/module.h>
23#include <linux/virtio.h> 24#include <linux/virtio.h>
24#include <linux/virtio_net.h> 25#include <linux/virtio_net.h>
@@ -54,9 +55,15 @@ struct virtnet_info
54 struct tasklet_struct tasklet; 55 struct tasklet_struct tasklet;
55 bool free_in_tasklet; 56 bool free_in_tasklet;
56 57
58 /* I like... big packets and I cannot lie! */
59 bool big_packets;
60
57 /* Receive & send queues. */ 61 /* Receive & send queues. */
58 struct sk_buff_head recv; 62 struct sk_buff_head recv;
59 struct sk_buff_head send; 63 struct sk_buff_head send;
64
65 /* Chain pages by the private ptr. */
66 struct page *pages;
60}; 67};
61 68
62static inline struct virtio_net_hdr *skb_vnet_hdr(struct sk_buff *skb) 69static inline struct virtio_net_hdr *skb_vnet_hdr(struct sk_buff *skb)
@@ -69,6 +76,23 @@ static inline void vnet_hdr_to_sg(struct scatterlist *sg, struct sk_buff *skb)
69 sg_init_one(sg, skb_vnet_hdr(skb), sizeof(struct virtio_net_hdr)); 76 sg_init_one(sg, skb_vnet_hdr(skb), sizeof(struct virtio_net_hdr));
70} 77}
71 78
79static void give_a_page(struct virtnet_info *vi, struct page *page)
80{
81 page->private = (unsigned long)vi->pages;
82 vi->pages = page;
83}
84
85static struct page *get_a_page(struct virtnet_info *vi, gfp_t gfp_mask)
86{
87 struct page *p = vi->pages;
88
89 if (p)
90 vi->pages = (struct page *)p->private;
91 else
92 p = alloc_page(gfp_mask);
93 return p;
94}
95
72static void skb_xmit_done(struct virtqueue *svq) 96static void skb_xmit_done(struct virtqueue *svq)
73{ 97{
74 struct virtnet_info *vi = svq->vdev->priv; 98 struct virtnet_info *vi = svq->vdev->priv;
@@ -88,6 +112,7 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb,
88 unsigned len) 112 unsigned len)
89{ 113{
90 struct virtio_net_hdr *hdr = skb_vnet_hdr(skb); 114 struct virtio_net_hdr *hdr = skb_vnet_hdr(skb);
115 int err;
91 116
92 if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) { 117 if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) {
93 pr_debug("%s: short packet %i\n", dev->name, len); 118 pr_debug("%s: short packet %i\n", dev->name, len);
@@ -95,10 +120,23 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb,
95 goto drop; 120 goto drop;
96 } 121 }
97 len -= sizeof(struct virtio_net_hdr); 122 len -= sizeof(struct virtio_net_hdr);
98 BUG_ON(len > MAX_PACKET_LEN);
99 123
100 skb_trim(skb, len); 124 if (len <= MAX_PACKET_LEN) {
125 unsigned int i;
101 126
127 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
128 give_a_page(dev->priv, skb_shinfo(skb)->frags[i].page);
129 skb->data_len = 0;
130 skb_shinfo(skb)->nr_frags = 0;
131 }
132
133 err = pskb_trim(skb, len);
134 if (err) {
135 pr_debug("%s: pskb_trim failed %i %d\n", dev->name, len, err);
136 dev->stats.rx_dropped++;
137 goto drop;
138 }
139 skb->truesize += skb->data_len;
102 dev->stats.rx_bytes += skb->len; 140 dev->stats.rx_bytes += skb->len;
103 dev->stats.rx_packets++; 141 dev->stats.rx_packets++;
104 142
@@ -160,7 +198,7 @@ static void try_fill_recv(struct virtnet_info *vi)
160{ 198{
161 struct sk_buff *skb; 199 struct sk_buff *skb;
162 struct scatterlist sg[2+MAX_SKB_FRAGS]; 200 struct scatterlist sg[2+MAX_SKB_FRAGS];
163 int num, err; 201 int num, err, i;
164 202
165 sg_init_table(sg, 2+MAX_SKB_FRAGS); 203 sg_init_table(sg, 2+MAX_SKB_FRAGS);
166 for (;;) { 204 for (;;) {
@@ -170,6 +208,24 @@ static void try_fill_recv(struct virtnet_info *vi)
170 208
171 skb_put(skb, MAX_PACKET_LEN); 209 skb_put(skb, MAX_PACKET_LEN);
172 vnet_hdr_to_sg(sg, skb); 210 vnet_hdr_to_sg(sg, skb);
211
212 if (vi->big_packets) {
213 for (i = 0; i < MAX_SKB_FRAGS; i++) {
214 skb_frag_t *f = &skb_shinfo(skb)->frags[i];
215 f->page = get_a_page(vi, GFP_ATOMIC);
216 if (!f->page)
217 break;
218
219 f->page_offset = 0;
220 f->size = PAGE_SIZE;
221
222 skb->data_len += PAGE_SIZE;
223 skb->len += PAGE_SIZE;
224
225 skb_shinfo(skb)->nr_frags++;
226 }
227 }
228
173 num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; 229 num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
174 skb_queue_head(&vi->recv, skb); 230 skb_queue_head(&vi->recv, skb);
175 231
@@ -335,16 +391,11 @@ again:
335 free_old_xmit_skbs(vi); 391 free_old_xmit_skbs(vi);
336 392
337 /* If we has a buffer left over from last time, send it now. */ 393 /* If we has a buffer left over from last time, send it now. */
338 if (unlikely(vi->last_xmit_skb)) { 394 if (unlikely(vi->last_xmit_skb) &&
339 if (xmit_skb(vi, vi->last_xmit_skb) != 0) { 395 xmit_skb(vi, vi->last_xmit_skb) != 0)
340 /* Drop this skb: we only queue one. */ 396 goto stop_queue;
341 vi->dev->stats.tx_dropped++; 397
342 kfree_skb(skb); 398 vi->last_xmit_skb = NULL;
343 skb = NULL;
344 goto stop_queue;
345 }
346 vi->last_xmit_skb = NULL;
347 }
348 399
349 /* Put new one in send queue and do transmit */ 400 /* Put new one in send queue and do transmit */
350 if (likely(skb)) { 401 if (likely(skb)) {
@@ -370,6 +421,11 @@ stop_queue:
370 netif_start_queue(dev); 421 netif_start_queue(dev);
371 goto again; 422 goto again;
372 } 423 }
424 if (skb) {
425 /* Drop this skb: we only queue one. */
426 vi->dev->stats.tx_dropped++;
427 kfree_skb(skb);
428 }
373 goto done; 429 goto done;
374} 430}
375 431
@@ -408,6 +464,22 @@ static int virtnet_close(struct net_device *dev)
408 return 0; 464 return 0;
409} 465}
410 466
467static int virtnet_set_tx_csum(struct net_device *dev, u32 data)
468{
469 struct virtnet_info *vi = netdev_priv(dev);
470 struct virtio_device *vdev = vi->vdev;
471
472 if (data && !virtio_has_feature(vdev, VIRTIO_NET_F_CSUM))
473 return -ENOSYS;
474
475 return ethtool_op_set_tx_hw_csum(dev, data);
476}
477
478static struct ethtool_ops virtnet_ethtool_ops = {
479 .set_tx_csum = virtnet_set_tx_csum,
480 .set_sg = ethtool_op_set_sg,
481};
482
411static int virtnet_probe(struct virtio_device *vdev) 483static int virtnet_probe(struct virtio_device *vdev)
412{ 484{
413 int err; 485 int err;
@@ -427,6 +499,7 @@ static int virtnet_probe(struct virtio_device *vdev)
427#ifdef CONFIG_NET_POLL_CONTROLLER 499#ifdef CONFIG_NET_POLL_CONTROLLER
428 dev->poll_controller = virtnet_netpoll; 500 dev->poll_controller = virtnet_netpoll;
429#endif 501#endif
502 SET_ETHTOOL_OPS(dev, &virtnet_ethtool_ops);
430 SET_NETDEV_DEV(dev, &vdev->dev); 503 SET_NETDEV_DEV(dev, &vdev->dev);
431 504
432 /* Do we support "hardware" checksums? */ 505 /* Do we support "hardware" checksums? */
@@ -462,11 +535,18 @@ static int virtnet_probe(struct virtio_device *vdev)
462 vi->dev = dev; 535 vi->dev = dev;
463 vi->vdev = vdev; 536 vi->vdev = vdev;
464 vdev->priv = vi; 537 vdev->priv = vi;
538 vi->pages = NULL;
465 539
466 /* If they give us a callback when all buffers are done, we don't need 540 /* If they give us a callback when all buffers are done, we don't need
467 * the timer. */ 541 * the timer. */
468 vi->free_in_tasklet = virtio_has_feature(vdev,VIRTIO_F_NOTIFY_ON_EMPTY); 542 vi->free_in_tasklet = virtio_has_feature(vdev,VIRTIO_F_NOTIFY_ON_EMPTY);
469 543
544 /* If we can receive ANY GSO packets, we must allocate large ones. */
545 if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4)
546 || virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6)
547 || virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN))
548 vi->big_packets = true;
549
470 /* We expect two virtqueues, receive then send. */ 550 /* We expect two virtqueues, receive then send. */
471 vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done); 551 vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done);
472 if (IS_ERR(vi->rvq)) { 552 if (IS_ERR(vi->rvq)) {
@@ -541,6 +621,10 @@ static void virtnet_remove(struct virtio_device *vdev)
541 vdev->config->del_vq(vi->svq); 621 vdev->config->del_vq(vi->svq);
542 vdev->config->del_vq(vi->rvq); 622 vdev->config->del_vq(vi->rvq);
543 unregister_netdev(vi->dev); 623 unregister_netdev(vi->dev);
624
625 while (vi->pages)
626 __free_pages(get_a_page(vi, GFP_KERNEL), 0);
627
544 free_netdev(vi->dev); 628 free_netdev(vi->dev);
545} 629}
546 630
@@ -553,7 +637,9 @@ static unsigned int features[] = {
553 VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM, 637 VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM,
554 VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, 638 VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
555 VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, 639 VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
556 VIRTIO_NET_F_HOST_ECN, VIRTIO_F_NOTIFY_ON_EMPTY, 640 VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
641 VIRTIO_NET_F_GUEST_ECN, /* We don't yet handle UFO input. */
642 VIRTIO_F_NOTIFY_ON_EMPTY,
557}; 643};
558 644
559static struct virtio_driver virtio_net = { 645static struct virtio_driver virtio_net = {