public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
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/

  parent reply	other threads:[~2007-05-31 12:20 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-31 12:19 [PATCH RFC 1/3] virtio infrastructure Rusty Russell
     [not found] ` <1180613947.11133.58.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-05-31 12:20   ` Rusty Russell [this message]
     [not found]     ` <1180614044.11133.61.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-05-31 12:21       ` [PATCH RFC 3/3] virtio infrastructure: example block driver Rusty Russell
     [not found]         ` <1180614091.11133.63.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-05-31 12:57           ` Carsten Otte
     [not found]             ` <465EC637.7020504-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org>
2007-05-31 15:02               ` Troy Benjegerdes
     [not found]                 ` <20070531150206.GB6474-na1kE3HDu0idQnJuSAr7PQ@public.gmane.org>
2007-05-31 17:01                   ` Carsten Otte
     [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
     [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
     [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
     [not found]                                             ` <46641DC9.5050600-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org>
2007-06-04 14:31                                               ` Jens Axboe
2007-06-02  9:28                       ` Rusty Russell
     [not found]                         ` <1180776482.9228.22.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-06-04 12:53                           ` 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
     [not found]             ` <46625192.5020108-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-06-03 10:29               ` Rusty Russell
     [not found]                 ` <1180866540.17442.74.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-06-03 11:39                   ` [Xen-devel] " Avi Kivity
     [not found]                     ` <4662A86A.7010706-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-06-03 23:53                       ` 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
     [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-01 23:35 ` Santos, Jose Renato G
2007-06-02 10:12   ` Rusty Russell
     [not found]     ` <1180779167.9228.66.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-06-04 21:14       ` [Xen-devel] " Santos, Jose Renato G
     [not found]         ` <08CA2245AFCF444DB3AC415E47CC40AFBD2FD4-VylnnfFjWmASZAcGdq5asR6epYMZPwEe5NbjCUgZEJk@public.gmane.org>
2007-06-04 21:19           ` Jeremy Fitzhardinge
     [not found]             ` <466481ED.8050209-TSDbQ3PG+2Y@public.gmane.org>
2007-06-05  2:05               ` Santos, Jose Renato G
     [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  1:44           ` [Xen-devel] " Rusty Russell
     [not found]             ` <1181007892.25878.112.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-06-05  2:39               ` Santos, Jose Renato G

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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox