iPXE
virtio-net.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2026 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stdint.h>
28#include <string.h>
29#include <unistd.h>
30#include <errno.h>
31#include <byteswap.h>
32#include <ipxe/netdevice.h>
33#include <ipxe/ethernet.h>
34#include <ipxe/if_ether.h>
35#include <ipxe/iobuf.h>
36#include <ipxe/malloc.h>
37#include <ipxe/pci.h>
38#include "virtio-net.h"
39
40/** @file
41 *
42 * Virtual I/O network device
43 *
44 */
45
46/** Supported features */
55
56/******************************************************************************
57 *
58 * Device-specific registers
59 *
60 ******************************************************************************
61 */
62
63/**
64 * Get MAC address
65 *
66 * @v netdev Network device
67 */
68static void virtio_net_mac ( struct net_device *netdev ) {
69 struct virtio_net *vnet = netdev->priv;
70 struct virtio_device *virtio = &vnet->virtio;
71 uint32_t has_mac;
72 unsigned int i;
73
74 /* Read MAC address from device registers */
75 for ( i = 0 ; i < ETH_ALEN ; i++ ) {
76 netdev->hw_addr[i] = ioread8 ( virtio->device +
77 VIRTIO_NET_MAC + i );
78 }
79
80 /* Use random MAC address if undefined or invalid */
81 has_mac = ( virtio->features.word[0] & VIRTIO_FEAT0_NET_MAC );
82 if ( ! ( has_mac && is_valid_ether_addr ( netdev->hw_addr ) ) ) {
83 DBGC ( vnet, "VNET %s has %s MAC address\n",
84 virtio->name, ( has_mac ? "invalid" : "no" ) );
85 eth_random_addr ( netdev->hw_addr );
86 }
87}
88
89/**
90 * Get MTU
91 *
92 * @v netdev Network device
93 */
94static void virtio_net_mtu ( struct net_device *netdev ) {
95 struct virtio_net *vnet = netdev->priv;
96 struct virtio_device *virtio = &vnet->virtio;
97 uint32_t has_mtu;
98
99 /* Read MTU from device registers, if available */
100 has_mtu = ( virtio->features.word[0] & VIRTIO_FEAT0_NET_MTU );
101 if ( has_mtu ) {
102 netdev->mtu = ioread16 ( virtio->device + VIRTIO_NET_MTU );
103 netdev->max_pkt_len = ( netdev->mtu + ETH_HLEN );
104 DBGC ( vnet, "VNET %s has MTU %zd\n",
105 virtio->name, netdev->mtu );
106 }
107}
108
109/******************************************************************************
110 *
111 * Queue management
112 *
113 ******************************************************************************
114 */
115
116/**
117 * Enable queue
118 *
119 * @v vnet Virtio network device
120 * @v queue Virtio network queue
121 * @ret rc Return status code
122 */
123static int virtio_net_enable ( struct virtio_net *vnet,
124 struct virtio_net_queue *queue ) {
125 struct virtio_device *virtio = &vnet->virtio;
126 struct virtio_desc *desc;
127 unsigned int count;
128 unsigned int max;
129 unsigned int fill;
130 unsigned int slot;
131 unsigned int index;
132 unsigned int write;
133 int rc;
134
135 /* Map packet header */
136 if ( ( rc = dma_map ( virtio->dma, &queue->map, &queue->hdr,
137 sizeof ( queue->hdr ), queue->dma ) ) != 0 ) {
138 DBGC ( vnet, "VNET %s Q%d could not map header: %s\n",
139 virtio->name, queue->queue.index, strerror ( rc ) );
140 goto err_map;
141 }
142
143 /* Enable queue */
144 count = ( queue->count * VIRTIO_NET_DESCS );
145 if ( ( rc = virtio_enable ( virtio, &queue->queue, count ) ) != 0 ) {
146 DBGC ( vnet, "VNET %s Q%d could not initialise: %s\n",
147 virtio->name, queue->queue.index, strerror ( rc ) );
148 goto err_enable;
149 }
150
151 /* Calculate mask */
152 max = ( queue->queue.count / VIRTIO_NET_DESCS );
153 fill = queue->max;
154 if ( fill > max )
155 fill = max;
156 queue->fill = fill;
157 queue->mask = ( fill - 1 );
158
159 /* Initialise descriptors and slot ring */
160 write = queue->write;
161 for ( slot = 0 ; slot < fill ; slot++ ) {
162 queue->slots[slot] = slot;
163 queue->iobufs[slot] = NULL;
165 desc = &queue->queue.desc[index];
166 desc[0].addr = cpu_to_le64 ( dma ( &queue->map, &queue->hdr ));
167 desc[0].len = cpu_to_le32 ( vnet->hlen );
168 desc[0].flags = cpu_to_le16 ( VIRTIO_DESC_FL_NEXT | write );
169 desc[0].next = cpu_to_le16 ( index + 1 );
170 desc[1].flags = cpu_to_le16 ( write );
171 }
172
173 DBGC ( vnet, "VNET %s Q%d using %d/%d descriptor pairs\n",
174 virtio->name, queue->queue.index, queue->fill, max );
175 return 0;
176
177 /* There may be no way to disable individual queues: the
178 * caller must reset the whole device to recover from a
179 * failure.
180 */
181 err_enable:
182 dma_unmap ( &queue->map, sizeof ( queue->hdr ) );
183 err_map:
184 return rc;
185}
186
187/**
188 * Submit I/O buffer to queue
189 *
190 * @v vnet Virtio network device
191 * @v queue Virtio network queue
192 * @v iobuf I/O buffer
193 * @v len Submitted length
194 */
195static void virtio_net_submit ( struct virtio_net *vnet,
196 struct virtio_net_queue *queue,
197 struct io_buffer *iobuf, size_t len ) {
198 struct virtio_device *virtio = &vnet->virtio;
199 struct virtio_desc *desc;
200 unsigned int prod;
201 unsigned int slot;
202 unsigned int index;
203
204 /* Get next descriptor pair and consume slot */
205 prod = queue->queue.prod;
206 slot = queue->slots[ prod & queue->mask ];
208 desc = &queue->queue.desc[index];
209
210 /* Populate descriptors */
211 desc[1].addr = cpu_to_le64 ( iob_dma ( iobuf ) );
212 desc[1].len = cpu_to_le32 ( len );
213 DBGC2 ( vnet, "VNET %s Q%d [%02x-%02x] is [%lx,%lx)\n",
214 virtio->name, queue->queue.index, index, ( index + 1 ),
215 virt_to_phys ( iobuf->data ),
216 ( virt_to_phys ( iobuf->data ) + len ) );
217
218 /* Record I/O buffer */
219 assert ( queue->iobufs[slot] == NULL );
220 queue->iobufs[slot] = iobuf;
221
222 /* Submit descriptors */
223 virtio_submit ( &queue->queue, index );
224}
225
226/**
227 * Complete I/O buffer
228 *
229 * @v vnet Virtio network device
230 * @v queue Virtio network queue
231 * @v len Length to fill in (or NULL to ignore)
232 * @ret iobuf I/O buffer
233 */
234static struct io_buffer * virtio_net_complete ( struct virtio_net *vnet,
235 struct virtio_net_queue *queue,
236 size_t *len ) {
237 struct virtio_device *virtio = &vnet->virtio;
238 struct io_buffer *iobuf;
239 unsigned int cons;
240 unsigned int slot;
241 unsigned int index;
242
243 /* Complete descriptor pair and recycle slot */
244 cons = queue->queue.cons;
245 index = virtio_complete ( &queue->queue, len );
247 queue->slots[ cons & queue->mask ] = slot;
248
249 /* Complete I/O buffer */
250 iobuf = queue->iobufs[slot];
251 assert ( iobuf != NULL );
252 queue->iobufs[slot] = NULL;
253 DBGC2 ( vnet, "VNET %s Q%d [%02x-%02x] complete",
254 virtio->name, queue->queue.index, index, ( index + 1 ) );
255 if ( len )
256 DBGC2 ( vnet, " len %#zx\n", *len );
257 DBGC2 ( vnet, "\n" );
258
259 return iobuf;
260}
261
262/******************************************************************************
263 *
264 * Network device interface
265 *
266 ******************************************************************************
267 */
268
269/**
270 * Refill receive queue
271 *
272 * @v vnet Virtio network device
273 */
274static void virtio_net_refill_rx ( struct virtio_net *vnet ) {
275 struct virtio_device *virtio = &vnet->virtio;
276 struct virtio_net_queue *queue = &vnet->rx;
277 struct io_buffer *iobuf;
278 size_t len = vnet->mfs;
279 unsigned int refilled = 0;
280
281 /* Refill queue */
282 while ( ( queue->queue.prod - queue->queue.cons ) < queue->fill ) {
283
284 /* Allocate I/O buffer */
285 iobuf = alloc_rx_iob ( len, virtio->dma );
286 if ( ! iobuf ) {
287 /* Wait for next refill */
288 break;
289 }
290
291 /* Submit I/O buffer */
292 virtio_net_submit ( vnet, queue, iobuf, len );
293 refilled++;
294 }
295
296 /* Notify queue, if applicable */
297 if ( refilled )
298 virtio_notify ( &queue->queue );
299}
300
301/**
302 * Open network device
303 *
304 * @v netdev Network device
305 * @ret rc Return status code
306 */
307static int virtio_net_open ( struct net_device *netdev ) {
308 struct virtio_net *vnet = netdev->priv;
309 struct virtio_device *virtio = &vnet->virtio;
311 int rc;
312
313 /* (Re)initialise device */
314 if ( ( rc = virtio_init ( virtio, &virtio_net_features ) ) != 0 ) {
315 DBGC ( vnet, "VNET %s could not initialise: %s\n",
316 virtio->name, strerror ( rc ) );
317 goto err_init;
318 }
319
320 /* Calculate header length */
321 vnet->hlen = ( virtio_is_legacy ( virtio ) ?
322 sizeof ( hdr.legacy ) : sizeof ( hdr.modern ) );
323
324 /* Calculate maximum frame size */
325 vnet->mfs = ( ETH_HLEN + 4 /* possible VLAN */ + netdev->mtu );
326
327 /* Enable receive queue */
328 if ( ( rc = virtio_net_enable ( vnet, &vnet->rx ) ) != 0 ) {
329 DBGC ( vnet, "VNET %s could not enable RX: %s\n",
330 virtio->name, strerror ( rc ) );
331 goto err_rx;
332 }
333
334 /* Enable transmit queue */
335 if ( ( rc = virtio_net_enable ( vnet, &vnet->tx ) ) != 0 ) {
336 DBGC ( vnet, "VNET %s could not enable TX: %s\n",
337 virtio->name, strerror ( rc ) );
338 goto err_tx;
339 }
340
341 /* Report driver readiness */
343
344 /* Refill receive queue */
345 virtio_net_refill_rx ( vnet );
346
347 return 0;
348
349 dma_unmap ( &vnet->tx.map, sizeof ( vnet->tx.hdr ) );
350 err_tx:
351 dma_unmap ( &vnet->rx.map, sizeof ( vnet->rx.hdr ) );
352 err_rx:
353 /* There may be no way to disable individual queues: we must
354 * reset the whole device instead and then free the queues.
355 */
356 virtio_reset ( virtio );
357 virtio_free ( virtio, &vnet->rx.queue );
358 virtio_free ( virtio, &vnet->tx.queue );
359 err_init:
360 return rc;
361}
362
363/**
364 * Close network device
365 *
366 * @v netdev Network device
367 */
368static void virtio_net_close ( struct net_device *netdev ) {
369 struct virtio_net *vnet = netdev->priv;
370 struct virtio_device *virtio = &vnet->virtio;
371 unsigned int i;
372
373 /* Reset device */
374 virtio_reset ( virtio );
375
376 /* Unmap headers (now that device is guaranteed idle) */
377 dma_unmap ( &vnet->rx.map, sizeof ( vnet->rx.hdr ) );
378 dma_unmap ( &vnet->tx.map, sizeof ( vnet->tx.hdr ) );
379
380 /* Free queues */
381 virtio_free ( virtio, &vnet->rx.queue );
382 virtio_free ( virtio, &vnet->tx.queue );
383
384 /* Discard any incomplete RX buffers */
385 for ( i = 0 ; i < VIRTIO_NET_RX_MAX ; i++ )
386 free_rx_iob ( vnet->rx_iobufs[i] );
387}
388
389/**
390 * Transmit packet
391 *
392 * @v netdev Network device
393 * @v iobuf I/O buffer
394 * @ret rc Return status code
395 */
397 struct io_buffer *iobuf ) {
398 struct virtio_net *vnet = netdev->priv;
399 struct virtio_net_queue *queue = &vnet->tx;
400
401 /* Defer packet if there are no available transmit descriptors */
402 if ( ( queue->queue.prod - queue->queue.cons ) >= queue->fill ) {
403 netdev_tx_defer ( netdev, iobuf );
404 return 0;
405 }
406
407 /* Submit I/O buffer */
408 virtio_net_submit ( vnet, queue, iobuf, iob_len ( iobuf ) );
409
410 /* Notify queue */
411 virtio_notify ( &queue->queue );
412
413 return 0;
414}
415
416/**
417 * Poll for completed packets
418 *
419 * @v netdev Network device
420 */
421static void virtio_net_poll_tx ( struct net_device *netdev ) {
422 struct virtio_net *vnet = netdev->priv;
423 struct virtio_net_queue *queue = &vnet->tx;
424 struct io_buffer *iobuf;
425
426 /* Poll for completed descriptors */
427 while ( virtio_completions ( &queue->queue ) ) {
428
429 /* Complete I/O buffer */
430 iobuf = virtio_net_complete ( vnet, queue, NULL );
431 netdev_tx_complete ( netdev, iobuf );
432 }
433}
434
435/**
436 * Poll for received packets
437 *
438 * @v netdev Network device
439 */
440static void virtio_net_poll_rx ( struct net_device *netdev ) {
441 struct virtio_net *vnet = netdev->priv;
442 struct virtio_net_queue *queue = &vnet->rx;
443 struct io_buffer *iobuf;
444 size_t len;
445
446 /* Poll for completed descriptors */
447 while ( virtio_completions ( &queue->queue ) > 0 ) {
448
449 /* Complete I/O buffer */
450 iobuf = virtio_net_complete ( vnet, queue, &len );
451 iob_put ( iobuf, ( len - vnet->hlen ) );
452 netdev_rx ( netdev, iobuf );
453 }
454}
455
456/**
457 * Poll for completed and received packets
458 *
459 * @v netdev Network device
460 */
461static void virtio_net_poll ( struct net_device *netdev ) {
462 struct virtio_net *vnet = netdev->priv;
463
464 /* Poll for completed packets */
466
467 /* Poll for received packets */
469
470 /* Refill receive queue */
471 virtio_net_refill_rx ( vnet );
472}
473
474/** Virtio network device operations */
476 .open = virtio_net_open,
477 .close = virtio_net_close,
478 .transmit = virtio_net_transmit,
479 .poll = virtio_net_poll,
480};
481
482/******************************************************************************
483 *
484 * PCI interface
485 *
486 ******************************************************************************
487 */
488
489/**
490 * Probe PCI device
491 *
492 * @v pci PCI device
493 * @ret rc Return status code
494 */
495static int virtio_net_probe ( struct pci_device *pci ) {
496 struct net_device *netdev;
497 struct virtio_net *vnet;
498 struct virtio_device *virtio;
499 int rc;
500
501 /* Allocate and initialise net device */
502 netdev = alloc_etherdev ( sizeof ( *vnet ) );
503 if ( ! netdev ) {
504 rc = -ENOMEM;
505 goto err_alloc;
506 }
508 vnet = netdev->priv;
509 pci_set_drvdata ( pci, netdev );
510 netdev->dev = &pci->dev;
511 netdev->dma = &pci->dma;
512 memset ( vnet, 0, sizeof ( *vnet ) );
513 virtio = &vnet->virtio;
514 virtio_net_queue_init ( &vnet->rx, vnet->rx_iobufs, vnet->rx_slots,
518 virtio_net_queue_init ( &vnet->tx, vnet->tx_iobufs, vnet->tx_slots,
521
522 /* Map PCI device */
523 if ( ( rc = virtio_pci_map ( virtio, pci ) ) != 0 ) {
524 DBGC ( vnet, "VNET %s could not map: %s\n",
525 virtio->name, strerror ( rc ) );
526 goto err_pci_map;
527 }
528
529 /* Initialise device */
530 if ( ( rc = virtio_init ( virtio, &virtio_net_features ) ) != 0 ) {
531 DBGC ( vnet, "VNET %s could not initialise: %s\n",
532 virtio->name, strerror ( rc ) );
533 goto err_init;
534 }
535
536 /* Get MAC address */
538
539 /* Set MTU */
541
542 /* Register network device */
543 if ( ( rc = register_netdev ( netdev ) ) != 0 )
544 goto err_register;
545
546 /* Mark as link up, since we have no way to test link state changes */
548
549 return 0;
550
552 err_register:
553 virtio_reset ( virtio );
554 err_init:
555 virtio_unmap ( virtio );
556 err_pci_map:
558 netdev_put ( netdev );
559 err_alloc:
560 return rc;
561}
562
563/**
564 * Remove PCI device
565 *
566 * @v pci PCI device
567 */
568static void virtio_net_remove ( struct pci_device *pci ) {
569 struct net_device *netdev = pci_get_drvdata ( pci );
570 struct virtio_net *vnet = netdev->priv;
571 struct virtio_device *virtio = &vnet->virtio;
572
573 /* Unregister network device */
575
576 /* Reset device */
577 virtio_reset ( virtio );
578
579 /* Free network device */
580 virtio_unmap ( virtio );
582 netdev_put ( netdev );
583}
584
585/** Virtio network PCI device IDs */
586static struct pci_device_id virtio_net_ids[] = {
587 PCI_ROM ( 0x1af4, 0x1000, "virtio-net", "Virtio (legacy)", 0 ),
588 PCI_ROM ( 0x1af4, 0x1041, "virtio-net", "Virtio (modern)", 0 ),
589};
590
591/** Virtio network PCI driver */
592struct pci_driver virtio_net_driver __pci_driver = {
593 .ids = virtio_net_ids,
594 .id_count = ( sizeof ( virtio_net_ids ) /
595 sizeof ( virtio_net_ids[0] ) ),
598};
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
struct golan_inbox_hdr hdr
Message header.
Definition CIB_PRM.h:0
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned int uint32_t
Definition stdint.h:12
long index
Definition bigint.h:30
static int fill
Definition string.h:209
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define max(x, y)
Definition ath.h:41
ring len
Length.
Definition dwmac.h:226
uint8_t slot
Slot.
Definition edd.h:3
uint16_t cons
Consumer index.
Definition ena.h:11
uint16_t queue
Queue ID.
Definition ena.h:11
struct ena_llq_option desc
Descriptor counts.
Definition ena.h:9
Error codes.
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition ethernet.c:265
void eth_random_addr(void *hw_addr)
Generate random Ethernet address.
Definition ethernet.c:160
Ethernet protocol.
static int is_valid_ether_addr(const void *addr)
Check if Ethernet address is valid.
Definition ethernet.h:78
static struct net_device * netdev
Definition gdbudp.c:53
#define DBGC2(...)
Definition compiler.h:547
#define DBGC(...)
Definition compiler.h:530
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:921
#define ENOMEM
Not enough space.
Definition errno.h:535
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:951
device nvs write
Definition threewire.h:62
#define VIRTIO_STAT_DRIVER_OK
Guest driver is ready.
Definition virtio.h:51
#define ETH_ALEN
Definition if_ether.h:9
#define ETH_HLEN
Definition if_ether.h:10
#define cpu_to_le64(value)
Definition byteswap.h:109
#define cpu_to_le32(value)
Definition byteswap.h:108
#define cpu_to_le16(value)
Definition byteswap.h:107
#define ioread16(io_addr)
Definition io.h:350
#define ioread8(io_addr)
Definition io.h:340
String functions.
void * memset(void *dest, int character, size_t len) __nonnull
struct io_buffer * alloc_rx_iob(size_t len, struct dma_device *dma)
Allocate and map I/O buffer for receive DMA.
Definition iobuf.c:188
void free_rx_iob(struct io_buffer *iobuf)
Unmap and free I/O buffer for receive DMA.
Definition iobuf.c:215
I/O buffers.
#define iob_put(iobuf, len)
Definition iobuf.h:125
static __always_inline physaddr_t iob_dma(struct io_buffer *iobuf)
Get I/O buffer DMA address.
Definition iobuf.h:268
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define DMA_TX
Device will read data from host memory.
Definition dma.h:135
#define DMA_RX
Device will write data to host memory.
Definition dma.h:138
void dma_unmap(struct dma_mapping *map, size_t len)
Unmap buffer.
physaddr_t dma(struct dma_mapping *map, void *addr)
Get DMA address from virtual address.
Dynamic memory allocation.
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition netdevice.c:549
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition netdevice.c:946
void netdev_tx_defer(struct net_device *netdev, struct io_buffer *iobuf)
Defer transmitted packet.
Definition netdevice.c:413
int register_netdev(struct net_device *netdev)
Register network device.
Definition netdevice.c:760
Network device management.
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition netdevice.h:792
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition netdevice.h:522
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition netdevice.h:535
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:579
static void netdev_tx_complete(struct net_device *netdev, struct io_buffer *iobuf)
Complete network transmission.
Definition netdevice.h:770
PCI bus.
#define __pci_driver
Declare a PCI driver.
Definition pci.h:281
static void pci_set_drvdata(struct pci_device *pci, void *priv)
Set PCI driver-private data.
Definition pci.h:370
#define PCI_ROM(_vendor, _device, _name, _description, _data)
Definition pci.h:311
static void * pci_get_drvdata(struct pci_device *pci)
Get PCI driver-private data.
Definition pci.h:380
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
Network device operations.
Definition netdevice.h:214
A network device.
Definition netdevice.h:353
A PCI device ID list entry.
Definition pci.h:178
A PCI device.
Definition pci.h:214
struct device dev
Generic device.
Definition pci.h:216
struct dma_device dma
DMA device.
Definition pci.h:218
A PCI driver.
Definition pci.h:255
int(* probe)(struct pci_device *pci)
Probe device.
Definition pci.h:268
A virtio buffer descriptor.
Definition virtio.h:152
A virtio device.
Definition virtio.h:311
struct virtio_features features
Negotiated features.
Definition virtio.h:329
const char * name
Device name.
Definition virtio.h:313
void * device
Device-specific registers.
Definition virtio.h:323
struct dma_device * dma
DMA device.
Definition virtio.h:317
A virtio feature set.
Definition virtio.h:299
uint32_t word[VIRTIO_FEATURE_WORDS]
Feature words.
Definition virtio.h:301
A virtio network queue.
Definition virtio-net.h:57
struct dma_mapping map
DMA mapping for packet header.
Definition virtio-net.h:72
struct virtio_queue queue
Underlying virtio queue.
Definition virtio-net.h:59
union virtio_net_header hdr
Shared packet header.
Definition virtio-net.h:70
A virtio network device.
Definition virtio-net.h:113
size_t hlen
Virtio network header length.
Definition virtio-net.h:122
size_t mfs
Maximum frame size.
Definition virtio-net.h:124
struct io_buffer * rx_iobufs[VIRTIO_NET_RX_MAX]
Receive I/O buffers.
Definition virtio-net.h:129
uint8_t rx_slots[VIRTIO_NET_RX_MAX]
Receive descriptor slot ring.
Definition virtio-net.h:127
struct virtio_device virtio
Underlying virtio device.
Definition virtio-net.h:115
struct virtio_net_queue tx
Transmit queue.
Definition virtio-net.h:119
struct virtio_net_queue rx
Receive queue.
Definition virtio-net.h:117
uint8_t tx_slots[VIRTIO_NET_TX_MAX]
Transmit descriptor slot ring.
Definition virtio-net.h:132
struct io_buffer * tx_iobufs[VIRTIO_NET_TX_MAX]
Transmit I/O buffers.
Definition virtio-net.h:134
A virtio network packet header.
Definition virtio-net.h:28
static void virtio_net_remove(struct pci_device *pci)
Remove PCI device.
Definition virtio-net.c:568
static void virtio_net_poll_rx(struct net_device *netdev)
Poll for received packets.
Definition virtio-net.c:440
static struct net_device_operations virtio_net_operations
Virtio network device operations.
Definition virtio-net.c:475
static int virtio_net_probe(struct pci_device *pci)
Probe PCI device.
Definition virtio-net.c:495
static void virtio_net_poll_tx(struct net_device *netdev)
Poll for completed packets.
Definition virtio-net.c:421
static void virtio_net_poll(struct net_device *netdev)
Poll for completed and received packets.
Definition virtio-net.c:461
static void virtio_net_close(struct net_device *netdev)
Close network device.
Definition virtio-net.c:368
static struct io_buffer * virtio_net_complete(struct virtio_net *vnet, struct virtio_net_queue *queue, size_t *len)
Complete I/O buffer.
Definition virtio-net.c:234
static int virtio_net_enable(struct virtio_net *vnet, struct virtio_net_queue *queue)
Enable queue.
Definition virtio-net.c:123
static void virtio_net_submit(struct virtio_net *vnet, struct virtio_net_queue *queue, struct io_buffer *iobuf, size_t len)
Submit I/O buffer to queue.
Definition virtio-net.c:195
static void virtio_net_mtu(struct net_device *netdev)
Get MTU.
Definition virtio-net.c:94
static void virtio_net_mac(struct net_device *netdev)
Get MAC address.
Definition virtio-net.c:68
static void virtio_net_refill_rx(struct virtio_net *vnet)
Refill receive queue.
Definition virtio-net.c:274
static struct pci_device_id virtio_net_ids[]
Virtio network PCI device IDs.
Definition virtio-net.c:586
static int virtio_net_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
Definition virtio-net.c:396
static int virtio_net_open(struct net_device *netdev)
Open network device.
Definition virtio-net.c:307
const struct virtio_features virtio_net_features
Supported features.
Definition virtio-net.c:47
Virtual I/O network device.
#define VIRTIO_NET_RX_COUNT
Receive queue requested queue size.
Definition virtio-net.h:39
#define VIRTIO_NET_RX_MAX
Receive queue maximum fill level.
Definition virtio-net.h:42
static void virtio_net_queue_init(struct virtio_net_queue *queue, struct io_buffer **iobufs, uint8_t *slots, unsigned int index, unsigned int count, unsigned int max, unsigned int dma, unsigned int write)
Initialise virtio network queue.
Definition virtio-net.h:97
#define VIRTIO_FEAT0_NET_MAC
Device has a MAC address.
Definition virtio-net.h:19
#define VIRTIO_FEAT0_NET_MTU
Device has a reported MTU.
Definition virtio-net.h:16
#define VIRTIO_NET_MTU
MTU register offset.
Definition virtio-net.h:25
#define VIRTIO_NET_DESCS
Number of descriptors per packet.
Definition virtio-net.h:54
#define VIRTIO_NET_TX_COUNT
Transmit queue requested queue size.
Definition virtio-net.h:48
#define VIRTIO_NET_MAC
MAC address register offset.
Definition virtio-net.h:22
#define VIRTIO_NET_TX_MAX
Transmit queue maximum fill level.
Definition virtio-net.h:51
#define VIRTIO_NET_RX_INDEX
Receive queue index.
Definition virtio-net.h:36
#define VIRTIO_NET_TX_INDEX
Transmit queue index.
Definition virtio-net.h:45
int virtio_init(struct virtio_device *virtio, const struct virtio_features *driver)
Initialise device.
Definition virtio.c:650
unsigned int virtio_status(struct virtio_device *virtio, unsigned int stat)
Report driver status.
Definition virtio.c:603
int virtio_enable(struct virtio_device *virtio, struct virtio_queue *queue, unsigned int count)
Enable queue.
Definition virtio.c:696
int virtio_reset(struct virtio_device *virtio)
Reset device.
Definition virtio.c:580
void virtio_free(struct virtio_device *virtio, struct virtio_queue *queue)
Free queue.
Definition virtio.c:764
void virtio_unmap(struct virtio_device *virtio)
Unmap device.
Definition virtio.c:780
int virtio_pci_map(struct virtio_device *virtio, struct pci_device *pci)
Map PCI device.
Definition virtio.c:479
#define VIRTIO_DESC_FL_WRITE
Buffer is write-only.
Definition virtio.h:167
static void virtio_notify(struct virtio_queue *queue)
Notify queue.
Definition virtio.h:404
#define VIRTIO_FEAT1_MODERN
Virtio version 1.0 or above.
Definition virtio.h:308
#define VIRTIO_FEAT0_ANY_LAYOUT
Arbitrary descriptor layouts may be used.
Definition virtio.h:305
static unsigned int virtio_completions(struct virtio_queue *queue)
Check for completed descriptors.
Definition virtio.h:422
static int virtio_is_legacy(struct virtio_device *virtio)
Check if device is using the legacy interface.
Definition virtio.h:457
static void virtio_submit(struct virtio_queue *queue, unsigned int index)
Submit descriptor(s) to queue.
Definition virtio.h:388
static unsigned int virtio_complete(struct virtio_queue *queue, size_t *len)
Complete descriptor(s).
Definition virtio.h:438
#define VIRTIO_DESC_FL_NEXT
Next descriptor index is valid.
Definition virtio.h:164
static struct xen_remove_from_physmap * remove
Definition xenmem.h:40