blob: a61c176607f4585b53a7514c90b89a9de0ce30ef [file] [log] [blame]
Rusty Russell296f96f2007-10-22 11:03:37 +10001/* A simple network driver using virtio.
2 *
3 * Copyright 2007 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19//#define DEBUG
20#include <linux/netdevice.h>
21#include <linux/etherdevice.h>
22#include <linux/module.h>
23#include <linux/virtio.h>
24#include <linux/virtio_net.h>
25#include <linux/scatterlist.h>
26
Rusty Russell34a48572008-02-04 23:50:02 -050027static int csum = 1, gso = 1;
28module_param(csum, bool, 0444);
29module_param(gso, bool, 0444);
30
Rusty Russell296f96f2007-10-22 11:03:37 +100031/* FIXME: MTU in config. */
32#define MAX_PACKET_LEN (ETH_HLEN+ETH_DATA_LEN)
33
34struct virtnet_info
35{
36 struct virtio_device *vdev;
37 struct virtqueue *rvq, *svq;
38 struct net_device *dev;
39 struct napi_struct napi;
40
41 /* Number of input buffers, and max we've ever had. */
42 unsigned int num, max;
43
44 /* Receive & send queues. */
45 struct sk_buff_head recv;
46 struct sk_buff_head send;
47};
48
49static inline struct virtio_net_hdr *skb_vnet_hdr(struct sk_buff *skb)
50{
51 return (struct virtio_net_hdr *)skb->cb;
52}
53
54static inline void vnet_hdr_to_sg(struct scatterlist *sg, struct sk_buff *skb)
55{
56 sg_init_one(sg, skb_vnet_hdr(skb), sizeof(struct virtio_net_hdr));
57}
58
Rusty Russell2cb9c6b2008-02-04 23:50:07 -050059static void skb_xmit_done(struct virtqueue *svq)
Rusty Russell296f96f2007-10-22 11:03:37 +100060{
Rusty Russell2cb9c6b2008-02-04 23:50:07 -050061 struct virtnet_info *vi = svq->vdev->priv;
Rusty Russell296f96f2007-10-22 11:03:37 +100062
Rusty Russell2cb9c6b2008-02-04 23:50:07 -050063 /* Suppress further interrupts. */
64 svq->vq_ops->disable_cb(svq);
65 /* We were waiting for more output buffers. */
Rusty Russell296f96f2007-10-22 11:03:37 +100066 netif_wake_queue(vi->dev);
Rusty Russell296f96f2007-10-22 11:03:37 +100067}
68
69static void receive_skb(struct net_device *dev, struct sk_buff *skb,
70 unsigned len)
71{
72 struct virtio_net_hdr *hdr = skb_vnet_hdr(skb);
73
74 if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) {
75 pr_debug("%s: short packet %i\n", dev->name, len);
76 dev->stats.rx_length_errors++;
77 goto drop;
78 }
79 len -= sizeof(struct virtio_net_hdr);
80 BUG_ON(len > MAX_PACKET_LEN);
81
82 skb_trim(skb, len);
83 skb->protocol = eth_type_trans(skb, dev);
84 pr_debug("Receiving skb proto 0x%04x len %i type %i\n",
85 ntohs(skb->protocol), skb->len, skb->pkt_type);
86 dev->stats.rx_bytes += skb->len;
87 dev->stats.rx_packets++;
88
89 if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
90 pr_debug("Needs csum!\n");
Rusty Russellf35d9d82008-02-04 23:49:54 -050091 if (!skb_partial_csum_set(skb,hdr->csum_start,hdr->csum_offset))
Rusty Russell296f96f2007-10-22 11:03:37 +100092 goto frame_err;
Rusty Russell296f96f2007-10-22 11:03:37 +100093 }
94
95 if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
96 pr_debug("GSO!\n");
Rusty Russell34a48572008-02-04 23:50:02 -050097 switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
Rusty Russell296f96f2007-10-22 11:03:37 +100098 case VIRTIO_NET_HDR_GSO_TCPV4:
99 skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
100 break;
Rusty Russell296f96f2007-10-22 11:03:37 +1000101 case VIRTIO_NET_HDR_GSO_UDP:
102 skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
103 break;
104 case VIRTIO_NET_HDR_GSO_TCPV6:
105 skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
106 break;
107 default:
108 if (net_ratelimit())
109 printk(KERN_WARNING "%s: bad gso type %u.\n",
110 dev->name, hdr->gso_type);
111 goto frame_err;
112 }
113
Rusty Russell34a48572008-02-04 23:50:02 -0500114 if (hdr->gso_type & VIRTIO_NET_HDR_GSO_ECN)
115 skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN;
116
Rusty Russell296f96f2007-10-22 11:03:37 +1000117 skb_shinfo(skb)->gso_size = hdr->gso_size;
118 if (skb_shinfo(skb)->gso_size == 0) {
119 if (net_ratelimit())
120 printk(KERN_WARNING "%s: zero gso size.\n",
121 dev->name);
122 goto frame_err;
123 }
124
125 /* Header must be checked, and gso_segs computed. */
126 skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
127 skb_shinfo(skb)->gso_segs = 0;
128 }
129
130 netif_receive_skb(skb);
131 return;
132
133frame_err:
134 dev->stats.rx_frame_errors++;
135drop:
136 dev_kfree_skb(skb);
137}
138
139static void try_fill_recv(struct virtnet_info *vi)
140{
141 struct sk_buff *skb;
142 struct scatterlist sg[1+MAX_SKB_FRAGS];
143 int num, err;
144
Rusty Russell4d125de2007-11-07 16:34:49 +1100145 sg_init_table(sg, 1+MAX_SKB_FRAGS);
Rusty Russell296f96f2007-10-22 11:03:37 +1000146 for (;;) {
147 skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN);
148 if (unlikely(!skb))
149 break;
150
151 skb_put(skb, MAX_PACKET_LEN);
152 vnet_hdr_to_sg(sg, skb);
153 num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
154 skb_queue_head(&vi->recv, skb);
155
156 err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, num, skb);
157 if (err) {
158 skb_unlink(skb, &vi->recv);
159 kfree_skb(skb);
160 break;
161 }
162 vi->num++;
163 }
164 if (unlikely(vi->num > vi->max))
165 vi->max = vi->num;
166 vi->rvq->vq_ops->kick(vi->rvq);
167}
168
Rusty Russell18445c42008-02-04 23:49:57 -0500169static void skb_recv_done(struct virtqueue *rvq)
Rusty Russell296f96f2007-10-22 11:03:37 +1000170{
171 struct virtnet_info *vi = rvq->vdev->priv;
Rusty Russell18445c42008-02-04 23:49:57 -0500172 /* Schedule NAPI, Suppress further interrupts if successful. */
173 if (netif_rx_schedule_prep(vi->dev, &vi->napi)) {
174 rvq->vq_ops->disable_cb(rvq);
175 __netif_rx_schedule(vi->dev, &vi->napi);
176 }
Rusty Russell296f96f2007-10-22 11:03:37 +1000177}
178
179static int virtnet_poll(struct napi_struct *napi, int budget)
180{
181 struct virtnet_info *vi = container_of(napi, struct virtnet_info, napi);
182 struct sk_buff *skb = NULL;
183 unsigned int len, received = 0;
184
185again:
186 while (received < budget &&
187 (skb = vi->rvq->vq_ops->get_buf(vi->rvq, &len)) != NULL) {
188 __skb_unlink(skb, &vi->recv);
189 receive_skb(vi->dev, skb, len);
190 vi->num--;
191 received++;
192 }
193
194 /* FIXME: If we oom and completely run out of inbufs, we need
195 * to start a timer trying to fill more. */
196 if (vi->num < vi->max / 2)
197 try_fill_recv(vi);
198
Rusty Russell8329d982007-11-19 11:20:43 -0500199 /* Out of packets? */
200 if (received < budget) {
Rusty Russell296f96f2007-10-22 11:03:37 +1000201 netif_rx_complete(vi->dev, napi);
Rusty Russell18445c42008-02-04 23:49:57 -0500202 if (unlikely(!vi->rvq->vq_ops->enable_cb(vi->rvq))
Rusty Russell296f96f2007-10-22 11:03:37 +1000203 && netif_rx_reschedule(vi->dev, napi))
204 goto again;
205 }
206
207 return received;
208}
209
210static void free_old_xmit_skbs(struct virtnet_info *vi)
211{
212 struct sk_buff *skb;
213 unsigned int len;
214
215 while ((skb = vi->svq->vq_ops->get_buf(vi->svq, &len)) != NULL) {
216 pr_debug("Sent skb %p\n", skb);
217 __skb_unlink(skb, &vi->send);
218 vi->dev->stats.tx_bytes += len;
219 vi->dev->stats.tx_packets++;
220 kfree_skb(skb);
221 }
222}
223
224static int start_xmit(struct sk_buff *skb, struct net_device *dev)
225{
226 struct virtnet_info *vi = netdev_priv(dev);
227 int num, err;
228 struct scatterlist sg[1+MAX_SKB_FRAGS];
229 struct virtio_net_hdr *hdr;
230 const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
231 DECLARE_MAC_BUF(mac);
232
Rusty Russell4d125de2007-11-07 16:34:49 +1100233 sg_init_table(sg, 1+MAX_SKB_FRAGS);
234
Rusty Russell296f96f2007-10-22 11:03:37 +1000235 pr_debug("%s: xmit %p %s\n", dev->name, skb, print_mac(mac, dest));
236
Rusty Russell296f96f2007-10-22 11:03:37 +1000237 /* Encode metadata header at front. */
238 hdr = skb_vnet_hdr(skb);
239 if (skb->ip_summed == CHECKSUM_PARTIAL) {
240 hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
241 hdr->csum_start = skb->csum_start - skb_headroom(skb);
242 hdr->csum_offset = skb->csum_offset;
243 } else {
244 hdr->flags = 0;
245 hdr->csum_offset = hdr->csum_start = 0;
246 }
247
248 if (skb_is_gso(skb)) {
Rusty Russell50c8ea82008-02-04 23:50:01 -0500249 hdr->hdr_len = skb_transport_header(skb) - skb->data;
Rusty Russell296f96f2007-10-22 11:03:37 +1000250 hdr->gso_size = skb_shinfo(skb)->gso_size;
Rusty Russell34a48572008-02-04 23:50:02 -0500251 if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
Rusty Russell296f96f2007-10-22 11:03:37 +1000252 hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
253 else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
254 hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
255 else if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP)
256 hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP;
257 else
258 BUG();
Rusty Russell34a48572008-02-04 23:50:02 -0500259 if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN)
260 hdr->gso_type |= VIRTIO_NET_HDR_GSO_ECN;
Rusty Russell296f96f2007-10-22 11:03:37 +1000261 } else {
262 hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
Rusty Russell50c8ea82008-02-04 23:50:01 -0500263 hdr->gso_size = hdr->hdr_len = 0;
Rusty Russell296f96f2007-10-22 11:03:37 +1000264 }
265
266 vnet_hdr_to_sg(sg, skb);
267 num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
268 __skb_queue_head(&vi->send, skb);
Rusty Russell2cb9c6b2008-02-04 23:50:07 -0500269
270again:
271 /* Free up any pending old buffers before queueing new ones. */
272 free_old_xmit_skbs(vi);
Rusty Russell296f96f2007-10-22 11:03:37 +1000273 err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb);
274 if (err) {
275 pr_debug("%s: virtio not prepared to send\n", dev->name);
Rusty Russell296f96f2007-10-22 11:03:37 +1000276 netif_stop_queue(dev);
Rusty Russell2cb9c6b2008-02-04 23:50:07 -0500277
278 /* Activate callback for using skbs: if this fails it
279 * means some were used in the meantime. */
280 if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) {
281 printk("Unlikely: restart svq failed\n");
282 netif_start_queue(dev);
283 goto again;
284 }
285 __skb_unlink(skb, &vi->send);
286
Rusty Russell296f96f2007-10-22 11:03:37 +1000287 return NETDEV_TX_BUSY;
288 }
289 vi->svq->vq_ops->kick(vi->svq);
290
291 return 0;
292}
293
294static int virtnet_open(struct net_device *dev)
295{
296 struct virtnet_info *vi = netdev_priv(dev);
297
Rusty Russell296f96f2007-10-22 11:03:37 +1000298 napi_enable(&vi->napi);
Rusty Russella48bd8f2008-02-04 23:50:07 -0500299
300 /* If all buffers were filled by other side before we napi_enabled, we
301 * won't get another interrupt, so process any outstanding packets
302 * now. virtnet_poll wants re-enable the queue, so we disable here. */
303 vi->rvq->vq_ops->disable_cb(vi->rvq);
304 netif_rx_schedule(vi->dev, &vi->napi);
305
Rusty Russell296f96f2007-10-22 11:03:37 +1000306 return 0;
307}
308
309static int virtnet_close(struct net_device *dev)
310{
311 struct virtnet_info *vi = netdev_priv(dev);
Rusty Russell296f96f2007-10-22 11:03:37 +1000312
313 napi_disable(&vi->napi);
314
Rusty Russell296f96f2007-10-22 11:03:37 +1000315 return 0;
316}
317
318static int virtnet_probe(struct virtio_device *vdev)
319{
320 int err;
Rusty Russell296f96f2007-10-22 11:03:37 +1000321 struct net_device *dev;
322 struct virtnet_info *vi;
Rusty Russell296f96f2007-10-22 11:03:37 +1000323
324 /* Allocate ourselves a network device with room for our info */
325 dev = alloc_etherdev(sizeof(struct virtnet_info));
326 if (!dev)
327 return -ENOMEM;
328
329 /* Set up network device as normal. */
Rusty Russell296f96f2007-10-22 11:03:37 +1000330 dev->open = virtnet_open;
331 dev->stop = virtnet_close;
332 dev->hard_start_xmit = start_xmit;
333 dev->features = NETIF_F_HIGHDMA;
334 SET_NETDEV_DEV(dev, &vdev->dev);
335
336 /* Do we support "hardware" checksums? */
Rusty Russell34a48572008-02-04 23:50:02 -0500337 if (csum && vdev->config->feature(vdev, VIRTIO_NET_F_CSUM)) {
Rusty Russell296f96f2007-10-22 11:03:37 +1000338 /* This opens up the world of extra features. */
339 dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
Rusty Russell34a48572008-02-04 23:50:02 -0500340 if (gso && vdev->config->feature(vdev, VIRTIO_NET_F_GSO)) {
341 dev->features |= NETIF_F_TSO | NETIF_F_UFO
342 | NETIF_F_TSO_ECN | NETIF_F_TSO6;
343 }
Rusty Russell296f96f2007-10-22 11:03:37 +1000344 }
345
346 /* Configuration may specify what MAC to use. Otherwise random. */
Rusty Russella586d4f2008-02-04 23:49:56 -0500347 if (vdev->config->feature(vdev, VIRTIO_NET_F_MAC)) {
348 vdev->config->get(vdev,
349 offsetof(struct virtio_net_config, mac),
350 dev->dev_addr, dev->addr_len);
Rusty Russell296f96f2007-10-22 11:03:37 +1000351 } else
352 random_ether_addr(dev->dev_addr);
353
354 /* Set up our device-specific information */
355 vi = netdev_priv(dev);
356 netif_napi_add(dev, &vi->napi, virtnet_poll, 16);
357 vi->dev = dev;
358 vi->vdev = vdev;
359
360 /* We expect two virtqueues, receive then send. */
Rusty Russella586d4f2008-02-04 23:49:56 -0500361 vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done);
Rusty Russell296f96f2007-10-22 11:03:37 +1000362 if (IS_ERR(vi->rvq)) {
363 err = PTR_ERR(vi->rvq);
364 goto free;
365 }
366
Rusty Russella586d4f2008-02-04 23:49:56 -0500367 vi->svq = vdev->config->find_vq(vdev, 1, skb_xmit_done);
Rusty Russell296f96f2007-10-22 11:03:37 +1000368 if (IS_ERR(vi->svq)) {
369 err = PTR_ERR(vi->svq);
370 goto free_recv;
371 }
372
373 /* Initialize our empty receive and send queues. */
374 skb_queue_head_init(&vi->recv);
375 skb_queue_head_init(&vi->send);
376
377 err = register_netdev(dev);
378 if (err) {
379 pr_debug("virtio_net: registering device failed\n");
380 goto free_send;
381 }
Rusty Russellb3369c12008-02-04 23:50:02 -0500382
383 /* Last of all, set up some receive buffers. */
384 try_fill_recv(vi);
385
386 /* If we didn't even get one input buffer, we're useless. */
387 if (vi->num == 0) {
388 err = -ENOMEM;
389 goto unregister;
390 }
391
Rusty Russell296f96f2007-10-22 11:03:37 +1000392 pr_debug("virtnet: registered device %s\n", dev->name);
393 vdev->priv = vi;
394 return 0;
395
Rusty Russellb3369c12008-02-04 23:50:02 -0500396unregister:
397 unregister_netdev(dev);
Rusty Russell296f96f2007-10-22 11:03:37 +1000398free_send:
399 vdev->config->del_vq(vi->svq);
400free_recv:
401 vdev->config->del_vq(vi->rvq);
402free:
403 free_netdev(dev);
404 return err;
405}
406
407static void virtnet_remove(struct virtio_device *vdev)
408{
Rusty Russell74b25532007-11-19 11:20:42 -0500409 struct virtnet_info *vi = vdev->priv;
Rusty Russellb3369c12008-02-04 23:50:02 -0500410 struct sk_buff *skb;
411
Rusty Russell6e5aa7e2008-02-04 23:50:03 -0500412 /* Stop all the virtqueues. */
413 vdev->config->reset(vdev);
414
Rusty Russellb3369c12008-02-04 23:50:02 -0500415 /* Free our skbs in send and recv queues, if any. */
Rusty Russellb3369c12008-02-04 23:50:02 -0500416 while ((skb = __skb_dequeue(&vi->recv)) != NULL) {
417 kfree_skb(skb);
418 vi->num--;
419 }
Rusty Russellb3369c12008-02-04 23:50:02 -0500420 while ((skb = __skb_dequeue(&vi->send)) != NULL)
421 kfree_skb(skb);
422
423 BUG_ON(vi->num != 0);
Rusty Russell74b25532007-11-19 11:20:42 -0500424
425 vdev->config->del_vq(vi->svq);
426 vdev->config->del_vq(vi->rvq);
427 unregister_netdev(vi->dev);
428 free_netdev(vi->dev);
Rusty Russell296f96f2007-10-22 11:03:37 +1000429}
430
431static struct virtio_device_id id_table[] = {
432 { VIRTIO_ID_NET, VIRTIO_DEV_ANY_ID },
433 { 0 },
434};
435
436static struct virtio_driver virtio_net = {
437 .driver.name = KBUILD_MODNAME,
438 .driver.owner = THIS_MODULE,
439 .id_table = id_table,
440 .probe = virtnet_probe,
441 .remove = __devexit_p(virtnet_remove),
442};
443
444static int __init init(void)
445{
446 return register_virtio_driver(&virtio_net);
447}
448
449static void __exit fini(void)
450{
451 unregister_virtio_driver(&virtio_net);
452}
453module_init(init);
454module_exit(fini);
455
456MODULE_DEVICE_TABLE(virtio, id_table);
457MODULE_DESCRIPTION("Virtio network driver");
458MODULE_LICENSE("GPL");