[tcp] Merge boolean flags into a single "flags" field
[gpxe.git] / src / drivers / net / virtio-net.c
blob20e4175ebdd1090112664246b0ca96a22ec97c54
1 /*
2 * (c) Copyright 2010 Stefan Hajnoczi <stefanha@gmail.com>
4 * based on the Etherboot virtio-net driver
6 * (c) Copyright 2008 Bull S.A.S.
8 * Author: Laurent Vivier <Laurent.Vivier@bull.net>
10 * some parts from Linux Virtio PCI driver
12 * Copyright IBM Corp. 2007
13 * Authors: Anthony Liguori <aliguori@us.ibm.com>
15 * some parts from Linux Virtio Ring
17 * Copyright Rusty Russell IBM Corporation 2007
19 * This work is licensed under the terms of the GNU GPL, version 2 or later.
20 * See the COPYING file in the top-level directory.
23 FILE_LICENCE ( GPL2_OR_LATER );
25 #include <errno.h>
26 #include <stdlib.h>
27 #include <gpxe/list.h>
28 #include <gpxe/iobuf.h>
29 #include <gpxe/netdevice.h>
30 #include <gpxe/pci.h>
31 #include <gpxe/if_ether.h>
32 #include <gpxe/ethernet.h>
33 #include <gpxe/virtio-ring.h>
34 #include <gpxe/virtio-pci.h>
35 #include "virtio-net.h"
38 * Virtio network device driver
40 * Specification:
41 * http://ozlabs.org/~rusty/virtio-spec/
43 * The virtio network device is supported by Linux virtualization software
44 * including QEMU/KVM and lguest. This driver supports the virtio over PCI
45 * transport; virtual machines have one virtio-net PCI adapter per NIC.
47 * Virtio-net is different from hardware NICs because virtio devices
48 * communicate with the hypervisor via virtqueues, not traditional descriptor
49 * rings. Virtqueues are unordered queues, they support add_buf() and
50 * get_buf() operations. To transmit a packet, the driver has to add the
51 * packet buffer onto the virtqueue. To receive a packet, the driver must
52 * first add an empty buffer to the virtqueue and then get the filled packet
53 * buffer on completion.
55 * Virtqueues are an abstraction that is commonly implemented using the vring
56 * descriptor ring layout. The vring is the actual shared memory structure
57 * that allows the virtual machine to communicate buffers with the hypervisor.
58 * Because the vring layout is optimized for flexibility and performance rather
59 * than space, it is heavy-weight and allocated like traditional descriptor
60 * rings in the open() function of the driver and not in probe().
62 * There is no true interrupt enable/disable. Virtqueues have callback
63 * enable/disable flags but these are only hints. The hypervisor may still
64 * raise an interrupt. Nevertheless, this driver disables callbacks in the
65 * hopes of avoiding interrupts.
68 /* Driver types are declared here so virtio-net.h can be easily synced with its
69 * Linux source.
72 /* Virtqueue indicies */
73 enum {
74 RX_INDEX = 0,
75 TX_INDEX,
76 QUEUE_NB
79 enum {
80 /** Max number of pending rx packets */
81 NUM_RX_BUF = 8,
83 /** Max Ethernet frame length, including FCS and VLAN tag */
84 RX_BUF_SIZE = 1522,
87 struct virtnet_nic {
88 /** Base pio register address */
89 unsigned long ioaddr;
91 /** RX/TX virtqueues */
92 struct vring_virtqueue *virtqueue;
94 /** RX packets handed to the NIC waiting to be filled in */
95 struct list_head rx_iobufs;
97 /** Pending rx packet count */
98 unsigned int rx_num_iobufs;
100 /** Virtio net packet header, we only need one */
101 struct virtio_net_hdr empty_header;
104 /** Add an iobuf to a virtqueue
106 * @v netdev Network device
107 * @v vq_idx Virtqueue index (RX_INDEX or TX_INDEX)
108 * @v iobuf I/O buffer
110 * The virtqueue is kicked after the iobuf has been added.
112 static void virtnet_enqueue_iob ( struct net_device *netdev,
113 int vq_idx, struct io_buffer *iobuf ) {
114 struct virtnet_nic *virtnet = netdev->priv;
115 struct vring_virtqueue *vq = &virtnet->virtqueue[vq_idx];
116 unsigned int out = ( vq_idx == TX_INDEX ) ? 2 : 0;
117 unsigned int in = ( vq_idx == TX_INDEX ) ? 0 : 2;
118 struct vring_list list[] = {
120 /* Share a single zeroed virtio net header between all
121 * rx and tx packets. This works because this driver
122 * does not use any advanced features so none of the
123 * header fields get used.
125 .addr = ( char* ) &virtnet->empty_header,
126 .length = sizeof ( virtnet->empty_header ),
129 .addr = ( char* ) iobuf->data,
130 .length = iob_len ( iobuf ),
134 DBGC ( virtnet, "VIRTIO-NET %p enqueuing iobuf %p on vq %d\n",
135 virtnet, iobuf, vq_idx );
137 vring_add_buf ( vq, list, out, in, iobuf, 0 );
138 vring_kick ( virtnet->ioaddr, vq, 1 );
141 /** Try to keep rx virtqueue filled with iobufs
143 * @v netdev Network device
145 static void virtnet_refill_rx_virtqueue ( struct net_device *netdev ) {
146 struct virtnet_nic *virtnet = netdev->priv;
148 while ( virtnet->rx_num_iobufs < NUM_RX_BUF ) {
149 struct io_buffer *iobuf;
151 /* Try to allocate a buffer, stop for now if out of memory */
152 iobuf = alloc_iob ( RX_BUF_SIZE );
153 if ( ! iobuf )
154 break;
156 /* Keep track of iobuf so close() can free it */
157 list_add ( &iobuf->list, &virtnet->rx_iobufs );
159 /* Mark packet length until we know the actual size */
160 iob_put ( iobuf, RX_BUF_SIZE );
162 virtnet_enqueue_iob ( netdev, RX_INDEX, iobuf );
163 virtnet->rx_num_iobufs++;
167 /** Open network device
169 * @v netdev Network device
170 * @ret rc Return status code
172 static int virtnet_open ( struct net_device *netdev ) {
173 struct virtnet_nic *virtnet = netdev->priv;
174 unsigned long ioaddr = virtnet->ioaddr;
175 u32 features;
176 int i;
178 /* Reset for sanity */
179 vp_reset ( ioaddr );
181 /* Allocate virtqueues */
182 virtnet->virtqueue = zalloc ( QUEUE_NB *
183 sizeof ( *virtnet->virtqueue ) );
184 if ( ! virtnet->virtqueue )
185 return -ENOMEM;
187 /* Initialize rx/tx virtqueues */
188 for ( i = 0; i < QUEUE_NB; i++ ) {
189 if ( vp_find_vq ( ioaddr, i, &virtnet->virtqueue[i] ) == -1 ) {
190 DBGC ( virtnet, "VIRTIO-NET %p cannot register queue %d\n",
191 virtnet, i );
192 free ( virtnet->virtqueue );
193 virtnet->virtqueue = NULL;
194 return -ENOENT;
198 /* Initialize rx packets */
199 INIT_LIST_HEAD ( &virtnet->rx_iobufs );
200 virtnet->rx_num_iobufs = 0;
201 virtnet_refill_rx_virtqueue ( netdev );
203 /* Disable interrupts before starting */
204 netdev_irq ( netdev, 0 );
206 /* Driver is ready */
207 features = vp_get_features ( ioaddr );
208 vp_set_features ( ioaddr, features & ( 1 << VIRTIO_NET_F_MAC ) );
209 vp_set_status ( ioaddr, VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK );
210 return 0;
213 /** Close network device
215 * @v netdev Network device
217 static void virtnet_close ( struct net_device *netdev ) {
218 struct virtnet_nic *virtnet = netdev->priv;
219 struct io_buffer *iobuf;
220 struct io_buffer *next_iobuf;
222 vp_reset ( virtnet->ioaddr );
224 /* Virtqueues can be freed now that NIC is reset */
225 free ( virtnet->virtqueue );
226 virtnet->virtqueue = NULL;
228 /* Free rx iobufs */
229 list_for_each_entry_safe ( iobuf, next_iobuf, &virtnet->rx_iobufs, list ) {
230 free_iob ( iobuf );
232 INIT_LIST_HEAD ( &virtnet->rx_iobufs );
233 virtnet->rx_num_iobufs = 0;
236 /** Transmit packet
238 * @v netdev Network device
239 * @v iobuf I/O buffer
240 * @ret rc Return status code
242 static int virtnet_transmit ( struct net_device *netdev,
243 struct io_buffer *iobuf ) {
244 virtnet_enqueue_iob ( netdev, TX_INDEX, iobuf );
245 return 0;
248 /** Complete packet transmission
250 * @v netdev Network device
252 static void virtnet_process_tx_packets ( struct net_device *netdev ) {
253 struct virtnet_nic *virtnet = netdev->priv;
254 struct vring_virtqueue *tx_vq = &virtnet->virtqueue[TX_INDEX];
256 while ( vring_more_used ( tx_vq ) ) {
257 struct io_buffer *iobuf = vring_get_buf ( tx_vq, NULL );
259 DBGC ( virtnet, "VIRTIO-NET %p tx complete iobuf %p\n",
260 virtnet, iobuf );
262 netdev_tx_complete ( netdev, iobuf );
266 /** Complete packet reception
268 * @v netdev Network device
270 static void virtnet_process_rx_packets ( struct net_device *netdev ) {
271 struct virtnet_nic *virtnet = netdev->priv;
272 struct vring_virtqueue *rx_vq = &virtnet->virtqueue[RX_INDEX];
274 while ( vring_more_used ( rx_vq ) ) {
275 unsigned int len;
276 struct io_buffer *iobuf = vring_get_buf ( rx_vq, &len );
278 /* Release ownership of iobuf */
279 list_del ( &iobuf->list );
280 virtnet->rx_num_iobufs--;
282 /* Update iobuf length */
283 iob_unput ( iobuf, RX_BUF_SIZE );
284 iob_put ( iobuf, len - sizeof ( struct virtio_net_hdr ) );
286 DBGC ( virtnet, "VIRTIO-NET %p rx complete iobuf %p len %zd\n",
287 virtnet, iobuf, iob_len ( iobuf ) );
289 /* Pass completed packet to the network stack */
290 netdev_rx ( netdev, iobuf );
293 virtnet_refill_rx_virtqueue ( netdev );
296 /** Poll for completed and received packets
298 * @v netdev Network device
300 static void virtnet_poll ( struct net_device *netdev ) {
301 struct virtnet_nic *virtnet = netdev->priv;
303 /* Acknowledge interrupt. This is necessary for UNDI operation and
304 * interrupts that are raised despite VRING_AVAIL_F_NO_INTERRUPT being
305 * set (that flag is just a hint and the hypervisor not not have to
306 * honor it).
308 vp_get_isr ( virtnet->ioaddr );
310 virtnet_process_tx_packets ( netdev );
311 virtnet_process_rx_packets ( netdev );
314 /** Enable or disable interrupts
316 * @v netdev Network device
317 * @v enable Interrupts should be enabled
319 static void virtnet_irq ( struct net_device *netdev, int enable ) {
320 struct virtnet_nic *virtnet = netdev->priv;
321 int i;
323 for ( i = 0; i < QUEUE_NB; i++ ) {
324 if ( enable )
325 vring_enable_cb ( &virtnet->virtqueue[i] );
326 else
327 vring_disable_cb ( &virtnet->virtqueue[i] );
331 /** virtio-net device operations */
332 static struct net_device_operations virtnet_operations = {
333 .open = virtnet_open,
334 .close = virtnet_close,
335 .transmit = virtnet_transmit,
336 .poll = virtnet_poll,
337 .irq = virtnet_irq,
341 * Probe PCI device
343 * @v pci PCI device
344 * @v id PCI ID
345 * @ret rc Return status code
347 static int virtnet_probe ( struct pci_device *pci,
348 const struct pci_device_id *id __unused ) {
349 unsigned long ioaddr = pci->ioaddr;
350 struct net_device *netdev;
351 struct virtnet_nic *virtnet;
352 u32 features;
353 int rc;
355 /* Allocate and hook up net device */
356 netdev = alloc_etherdev ( sizeof ( *virtnet ) );
357 if ( ! netdev )
358 return -ENOMEM;
359 netdev_init ( netdev, &virtnet_operations );
360 virtnet = netdev->priv;
361 virtnet->ioaddr = ioaddr;
362 pci_set_drvdata ( pci, netdev );
363 netdev->dev = &pci->dev;
365 DBGC ( virtnet, "VIRTIO-NET %p busaddr=%s ioaddr=%#lx irq=%d\n",
366 virtnet, pci->dev.name, ioaddr, pci->irq );
368 /* Enable PCI bus master and reset NIC */
369 adjust_pci_device ( pci );
370 vp_reset ( ioaddr );
372 /* Load MAC address */
373 features = vp_get_features ( ioaddr );
374 if ( features & ( 1 << VIRTIO_NET_F_MAC ) ) {
375 vp_get ( ioaddr, offsetof ( struct virtio_net_config, mac ),
376 netdev->hw_addr, ETH_ALEN );
377 DBGC ( virtnet, "VIRTIO-NET %p mac=%s\n", virtnet,
378 eth_ntoa ( netdev->hw_addr ) );
381 /* Mark link as up, control virtqueue is not used */
382 netdev_link_up ( netdev );
384 if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
385 vp_reset ( ioaddr );
386 netdev_nullify ( netdev );
387 netdev_put ( netdev );
389 return rc;
393 * Remove device
395 * @v pci PCI device
397 static void virtnet_remove ( struct pci_device *pci ) {
398 struct net_device *netdev = pci_get_drvdata ( pci );
400 unregister_netdev ( netdev );
401 netdev_nullify ( netdev );
402 netdev_put ( netdev );
405 static struct pci_device_id virtnet_nics[] = {
406 PCI_ROM(0x1af4, 0x1000, "virtio-net", "Virtio Network Interface", 0),
409 struct pci_driver virtnet_driver __pci_driver = {
410 .ids = virtnet_nics,
411 .id_count = ( sizeof ( virtnet_nics ) / sizeof ( virtnet_nics[0] ) ),
412 .probe = virtnet_probe,
413 .remove = virtnet_remove,