From: Rusty Russell <rusty-8n+1lVoiYb80n/F98K4Iww@public.gmane.org>
To: kvm-devel
<kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>,
Xen Mailing List
<xen-devel-GuqFBffKawuULHF6PoxzQEEOCMrvLtNR@public.gmane.org>,
virtualization
<virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org>
Cc: Jimi Xenidis <jimix-aZOuKsOsJu3MbYB6QlFGEg@public.gmane.org>,
Stephen Rothwell <sfr-3FnU+UHB4dNDw9hX6IcOSA@public.gmane.org>,
"jmk-zzFmDc4TPjtKvsKVC3L/VUEOCMrvLtNR@public.gmane.org"
<jmk-zzFmDc4TPjtKvsKVC3L/VUEOCMrvLtNR@public.gmane.org>,
Herbert Xu
<herbert-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q@public.gmane.org>,
Christian Borntraeger
<cborntra-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org>,
Suzanne McIntosh
<skranjac-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>,
Martin Schwidefsky
<schwidefsky-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org>
Subject: [PATCH RFC 2/3] virtio infrastructure: example net driver
Date: Thu, 31 May 2007 22:20:44 +1000 [thread overview]
Message-ID: <1180614044.11133.61.camel@localhost.localdomain> (raw)
In-Reply-To: <1180613947.11133.58.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
Example net driver using virtio
TODO:
1) Locking (see #2).
2) NAPI.
3) GSO.
4) Checksum options.
Signed-off-by: Rusty Russell <rusty-8n+1lVoiYb80n/F98K4Iww@public.gmane.org>
---
drivers/net/Makefile | 2
drivers/net/virtio_net.c | 237 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/virtio_net.h | 13 ++
3 files changed, 251 insertions(+), 1 deletion(-)
diff -r 96df1769fce9 drivers/net/Makefile
--- a/drivers/net/Makefile Thu May 31 17:52:38 2007 +1000
+++ b/drivers/net/Makefile Thu May 31 17:52:40 2007 +1000
@@ -37,7 +37,7 @@ obj-$(CONFIG_CASSINI) += cassini.o
obj-$(CONFIG_MACE) += mace.o
obj-$(CONFIG_BMAC) += bmac.o
-
+obj-y += virtio_net.o
obj-$(CONFIG_DGRS) += dgrs.o
obj-$(CONFIG_VORTEX) += 3c59x.o
obj-$(CONFIG_TYPHOON) += typhoon.o
diff -r 96df1769fce9 drivers/net/virtio_net.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/net/virtio_net.c Thu May 31 17:53:54 2007 +1000
@@ -0,0 +1,236 @@
+/* A simple network driver using virtio.
+ *
+ * Copyright 2007 Rusty Russell <rusty-8n+1lVoiYb80n/F98K4Iww@public.gmane.org> IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+//#define DEBUG
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/module.h>
+#include <linux/virtio.h>
+#include <linux/scatterlist.h>
+
+#define NET_BUFS 128
+/* FIXME: Make dynamic */
+#define MAX_PACKET_LEN (ETH_HLEN+ETH_DATA_LEN)
+
+struct virtnet_info
+{
+ struct virtio_device *vdev;
+ struct net_device *ndev;
+
+ /* Receive queue. */
+ struct sk_buff *in[NET_BUFS];
+ /* Send queue. */
+ struct sk_buff *out[NET_BUFS];
+
+ /* Lengths for input buffers as they are used. */
+ unsigned long in_used[NET_BUFS];
+
+ /* Lengths for output buffers as they are used. */
+ unsigned long out_used[NET_BUFS];
+
+ /* IDs for buffers. */
+ long in_ids[NET_BUFS];
+ long out_ids[NET_BUFS];
+};
+
+static int start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct virtnet_info *vi = netdev_priv(dev);
+ unsigned int n, i;
+ /* FIXME: What *is* the max here? */
+ struct scatterlist sg[MAX_SKB_FRAGS + 2];
+ const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
+
+ pr_debug("%s: xmit %02x:%02x:%02x:%02x:%02x:%02x\n",
+ dev->name, dest[0],dest[1],dest[2],dest[3],dest[4],dest[5]);
+
+ /* Go through and find a new output slot, and free any on the way */
+ for (i = 0; i < NET_BUFS; i++) {
+ if (!vi->out[i])
+ break;
+
+ if (!vi->out_used[i])
+ continue;
+
+ vi->vdev->ops->detach_outbuf(vi->vdev, vi->out_ids[i]);
+ dev->stats.tx_bytes += vi->out_used[i];
+ dev->stats.tx_packets++;
+ dev_kfree_skb(vi->out[i]);
+ vi->out[i] = NULL;
+ break;
+ }
+ if (unlikely(i == NET_BUFS)) {
+ pr_debug("%s: ring full\n", dev->name);
+ goto stop;
+ }
+
+ n = skb_to_sgvec(skb, sg, 0, skb->len);
+ vi->out_used[i] = 0;
+ vi->out_ids[i] = vi->vdev->ops->add_outbuf(vi->vdev, sg, n,
+ &vi->out_used[i]);
+ if (IS_ERR_VALUE(vi->out_ids[i])) {
+ pr_debug("%s: virtio not prepared to send\n", dev->name);
+ goto stop;
+ }
+ vi->out[i] = skb;
+ virtio_sync(vi->vdev);
+ return 0;
+stop:
+ netif_stop_queue(dev);
+ return NETDEV_TX_BUSY;
+}
+
+static void receive_skb(struct net_device *dev, struct sk_buff *skb,
+ unsigned len)
+{
+ if (unlikely(len < ETH_HLEN)) {
+ pr_debug("%s: short packet %i\n", dev->name, len);
+ dev->stats.rx_length_errors++;
+ dev_kfree_skb(skb);
+ return;
+ }
+ BUG_ON(len > MAX_PACKET_LEN);
+
+ skb_trim(skb, len);
+ skb->protocol = eth_type_trans(skb, dev);
+ pr_debug("Receiving skb proto 0x%04x len %i type %i\n",
+ ntohs(skb->protocol), skb->len, skb->pkt_type);
+ dev->stats.rx_bytes += skb->len;
+ dev->stats.rx_packets++;
+ netif_rx(skb);
+}
+
+static void try_fill_recv(struct virtnet_info *vi, unsigned int i)
+{
+ /* FIXME: What *is* the max here? */
+ struct scatterlist sg[MAX_SKB_FRAGS + 1];
+ unsigned int n;
+
+ vi->in[i] = netdev_alloc_skb(vi->ndev, MAX_PACKET_LEN);
+ if (unlikely(!vi->in[i]))
+ return;
+
+ skb_put(vi->in[i], MAX_PACKET_LEN);
+ n = skb_to_sgvec(vi->in[i], sg, 0, vi->in[i]->len);
+ vi->in_used[i] = 0;
+ vi->in_ids[i] = vi->vdev->ops->add_inbuf(vi->vdev, sg, n,
+ &vi->in_used[i]);
+ if (IS_ERR_VALUE(vi->in_ids[i])) {
+ kfree_skb(vi->in[i]);
+ vi->in[i] = NULL;
+ }
+}
+
+static int virtnet_open(struct net_device *dev)
+{
+ struct virtnet_info *vi = netdev_priv(dev);
+ unsigned int i;
+
+ for (i = 0; i < NET_BUFS; i++)
+ try_fill_recv(vi, i);
+
+ virtio_sync(vi->vdev);
+ return 0;
+}
+
+static int virtnet_close(struct net_device *dev)
+{
+ struct virtnet_info *vi = netdev_priv(dev);
+ unsigned int i;
+
+ for (i = 0; i < NET_BUFS; i++) {
+ if (vi->in[i]) {
+ vi->vdev->ops->detach_inbuf(vi->vdev, vi->in_ids[i]);
+ kfree_skb(vi->in[i]);
+ vi->in[i] = NULL;
+ }
+ if (vi->out[i]) {
+ vi->vdev->ops->detach_outbuf(vi->vdev, vi->out_ids[i]);
+ kfree_skb(vi->out[i]);
+ vi->out[i] = NULL;
+ }
+ }
+ return 0;
+}
+
+struct net_device *virtnet_probe(struct virtio_device *vdev,
+ const u8 mac[ETH_ALEN])
+{
+ int err;
+ struct net_device *dev;
+ struct virtnet_info *vi;
+
+ dev = alloc_etherdev(sizeof(struct virtnet_info));
+ if (!dev)
+ return ERR_PTR(-ENOMEM);
+
+ SET_MODULE_OWNER(dev);
+
+ ether_setup(dev);
+ memcpy(dev->dev_addr, mac, ETH_ALEN);
+ dev->open = virtnet_open;
+ dev->stop = virtnet_close;
+ dev->hard_start_xmit = start_xmit;
+ SET_NETDEV_DEV(dev, vdev->dev);
+
+ vi = netdev_priv(dev);
+ vi->vdev = vdev;
+ vi->ndev = dev;
+
+ err = register_netdev(dev);
+ if (err) {
+ pr_debug("virtio_net: registering device failed\n");
+ goto free;
+ }
+ pr_debug("virtnet: registered device %s\n", dev->name);
+ return dev;
+
+free:
+ free_netdev(dev);
+ return ERR_PTR(err);
+}
+EXPORT_SYMBOL_GPL(virtnet_probe);
+
+/* We get this when the other side sends buffers, or consumes them. */
+int virtnet_interrupt(struct net_device *dev)
+{
+ struct virtnet_info *vi = netdev_priv(dev);
+ unsigned int i;
+
+ for (i = 0; i < NET_BUFS; i++) {
+ if (vi->in[i] && vi->in_used[i]) {
+ vi->vdev->ops->detach_inbuf(vi->vdev, vi->in_ids[i]);
+ receive_skb(dev, vi->in[i], vi->in_used[i]);
+ try_fill_recv(vi, i);
+ }
+ }
+
+ netif_wake_queue(dev);
+ return IRQ_HANDLED;
+}
+EXPORT_SYMBOL_GPL(virtnet_interrupt);
+
+void virtnet_remove(struct net_device *dev)
+{
+ unregister_netdev(dev);
+ free_netdev(dev);
+}
+EXPORT_SYMBOL_GPL(virtnet_remove);
+
+MODULE_DESCRIPTION("Virtio network driver");
+MODULE_LICENSE("GPL");
diff -r 96df1769fce9 include/linux/virtio_net.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/linux/virtio_net.h Thu May 31 17:52:40 2007 +1000
@@ -0,0 +1,13 @@
+#ifndef _LINUX_VIRTIO_NET_H
+#define _LINUX_VIRTIO_NET_H
+#include <linux/types.h>
+#include <linux/etherdevice.h>
+struct net_device;
+struct virtio_device;
+
+struct net_device *virtnet_probe(struct virtio_device *vdev,
+ const u8 mac[ETH_ALEN]);
+int virtnet_interrupt(struct net_device *dev);
+void virtnet_remove(struct net_device *dev);
+
+#endif /* _LINUX_VIRTIO_NET_H */
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
next prev parent reply other threads:[~2007-05-31 12:20 UTC|newest]
Thread overview: 81+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-05-31 12:19 [PATCH RFC 1/3] virtio infrastructure Rusty Russell
2007-05-31 12:20 ` [PATCH RFC 2/3] virtio infrastructure: example net driver Rusty Russell
[not found] ` <1180613947.11133.58.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-05-31 12:20 ` Rusty Russell [this message]
2007-05-31 12:21 ` [PATCH RFC 3/3] virtio infrastructure: example block driver Rusty Russell
[not found] ` <1180614044.11133.61.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-05-31 12:21 ` Rusty Russell
[not found] ` <1180614091.11133.63.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-05-31 12:57 ` Carsten Otte
2007-05-31 15:02 ` [kvm-devel] " Troy Benjegerdes
[not found] ` <465EC637.7020504-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org>
2007-05-31 15:02 ` Troy Benjegerdes
2007-05-31 17:01 ` [kvm-devel] " Carsten Otte
[not found] ` <20070531150206.GB6474-na1kE3HDu0idQnJuSAr7PQ@public.gmane.org>
2007-05-31 17:01 ` Carsten Otte
2007-05-31 17:36 ` [kvm-devel] " Avi Kivity
[not found] ` <465EFF72.5070100-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org>
2007-05-31 17:36 ` Avi Kivity
2007-05-31 23:39 ` Rusty Russell
[not found] ` <1180654765.10999.6.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-06-01 7:10 ` Carsten Otte
2007-06-01 13:13 ` [kvm-devel] " Jens Axboe
[not found] ` <465FC65C.6020905-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org>
2007-06-01 13:13 ` Jens Axboe
[not found] ` <20070601131315.GW32105-tSWWG44O7X1aa/9Udqfwiw@public.gmane.org>
2007-06-04 13:40 ` Carsten Otte
[not found] ` <4664164A.40604-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org>
2007-06-04 13:43 ` Jens Axboe
2007-06-04 13:52 ` [kvm-devel] " Rusty Russell
[not found] ` <20070604134322.GC32105-tSWWG44O7X1aa/9Udqfwiw@public.gmane.org>
2007-06-04 13:52 ` Rusty Russell
[not found] ` <1180965161.25878.47.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-06-04 13:54 ` Jens Axboe
[not found] ` <20070604135433.GG32105-tSWWG44O7X1aa/9Udqfwiw@public.gmane.org>
2007-06-04 14:12 ` Carsten Otte
2007-06-04 14:31 ` [kvm-devel] " Jens Axboe
[not found] ` <46641DC9.5050600-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org>
2007-06-04 14:31 ` Jens Axboe
2007-06-04 14:12 ` [kvm-devel] " Carsten Otte
2007-06-04 13:54 ` Jens Axboe
2007-06-04 13:43 ` Jens Axboe
2007-06-04 13:40 ` Carsten Otte
2007-06-02 9:28 ` Rusty Russell
2007-06-04 12:53 ` [kvm-devel] " Carsten Otte
[not found] ` <1180776482.9228.22.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-06-04 12:53 ` Carsten Otte
2007-06-02 9:28 ` [kvm-devel] " Rusty Russell
2007-06-01 7:10 ` Carsten Otte
2007-05-31 23:39 ` Rusty Russell
2007-05-31 12:57 ` Carsten Otte
2007-05-31 12:53 ` [PATCH RFC 1/3] virtio infrastructure Carsten Otte
2007-05-31 13:01 ` Dor Laor
2007-06-02 6:30 ` Avi Kivity
[not found] ` <46610E8D.10706-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-06-02 9:50 ` Rusty Russell
[not found] ` <1180777836.9228.44.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-06-03 5:28 ` Avi Kivity
2007-06-03 10:29 ` [kvm-devel] " Rusty Russell
[not found] ` <46625192.5020108-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-06-03 10:29 ` Rusty Russell
2007-06-03 11:39 ` [Xen-devel] Re: [kvm-devel] " Avi Kivity
[not found] ` <1180866540.17442.74.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-06-03 11:39 ` [Xen-devel] " Avi Kivity
2007-06-03 23:53 ` [Xen-devel] Re: [kvm-devel] " Rusty Russell
[not found] ` <4662A86A.7010706-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-06-03 23:53 ` [Xen-devel] " Rusty Russell
[not found] ` <1180914836.17442.104.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-06-04 9:55 ` Avi Kivity
[not found] ` <4663E18D.4030007-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-06-04 10:32 ` Herbert Xu
2007-06-04 11:19 ` Rusty Russell
[not found] ` <1180955964.25878.27.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-06-04 11:25 ` Avi Kivity
2007-06-04 11:40 ` [kvm-devel] " Rusty Russell
[not found] ` <4663F6AC.7070100-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-06-04 11:40 ` Rusty Russell
2007-06-04 12:17 ` Herbert Xu
2007-06-04 12:17 ` [kvm-devel] " Herbert Xu
2007-06-04 11:25 ` Avi Kivity
2007-06-04 10:32 ` [Xen-devel] " Herbert Xu
2007-06-04 11:19 ` Rusty Russell
2007-06-04 9:55 ` [Xen-devel] " Avi Kivity
2007-06-03 5:28 ` Avi Kivity
2007-06-02 9:50 ` Rusty Russell
2007-05-31 12:53 ` Carsten Otte
2007-05-31 13:01 ` Dor Laor
2007-06-01 23:35 ` Santos, Jose Renato G
2007-06-02 10:12 ` Rusty Russell
2007-06-04 21:14 ` [Xen-devel] " Santos, Jose Renato G
[not found] ` <1180779167.9228.66.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-06-04 21:14 ` Santos, Jose Renato G
[not found] ` <08CA2245AFCF444DB3AC415E47CC40AFBD2FD4-VylnnfFjWmASZAcGdq5asR6epYMZPwEe5NbjCUgZEJk@public.gmane.org>
2007-06-04 21:19 ` Jeremy Fitzhardinge
2007-06-05 2:05 ` Santos, Jose Renato G
[not found] ` <466481ED.8050209-TSDbQ3PG+2Y@public.gmane.org>
2007-06-05 2:05 ` Santos, Jose Renato G
2007-06-05 2:27 ` Rusty Russell
[not found] ` <08CA2245AFCF444DB3AC415E47CC40AFBD30B4-VylnnfFjWmASZAcGdq5asR6epYMZPwEe5NbjCUgZEJk@public.gmane.org>
2007-06-05 2:27 ` Rusty Russell
2007-06-05 2:49 ` Santos, Jose Renato G
2007-06-05 2:49 ` [Xen-devel] " Santos, Jose Renato G
2007-06-05 1:44 ` Rusty Russell
[not found] ` <1181007892.25878.112.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-06-05 2:39 ` Santos, Jose Renato G
2007-06-05 2:39 ` Santos, Jose Renato G
2007-06-04 21:19 ` Jeremy Fitzhardinge
2007-06-05 1:44 ` Rusty Russell
2007-06-02 10:12 ` Rusty Russell
2007-06-01 23:35 ` Santos, Jose Renato G
2007-06-02 6:30 ` [kvm-devel] " Avi Kivity
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1180614044.11133.61.camel@localhost.localdomain \
--to=rusty-8n+1lvoiyb80n/f98k4iww@public.gmane.org \
--cc=cborntra-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org \
--cc=herbert-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q@public.gmane.org \
--cc=jimix-aZOuKsOsJu3MbYB6QlFGEg@public.gmane.org \
--cc=jmk-zzFmDc4TPjtKvsKVC3L/VUEOCMrvLtNR@public.gmane.org \
--cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
--cc=schwidefsky-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org \
--cc=sfr-3FnU+UHB4dNDw9hX6IcOSA@public.gmane.org \
--cc=skranjac-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org \
--cc=virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \
--cc=xen-devel-GuqFBffKawuULHF6PoxzQEEOCMrvLtNR@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.