iPXE
virtio-net.c File Reference

Virtual I/O network device. More...

#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/netdevice.h>
#include <ipxe/ethernet.h>
#include <ipxe/if_ether.h>
#include <ipxe/iobuf.h>
#include <ipxe/malloc.h>
#include <ipxe/pci.h>
#include "virtio-net.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static void virtio_net_mac (struct net_device *netdev)
 Get MAC address.
static void virtio_net_mtu (struct net_device *netdev)
 Get MTU.
static int virtio_net_enable (struct virtio_net *vnet, struct virtio_net_queue *queue)
 Enable queue.
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.
static struct io_buffervirtio_net_complete (struct virtio_net *vnet, struct virtio_net_queue *queue, size_t *len)
 Complete I/O buffer.
static void virtio_net_refill_rx (struct virtio_net *vnet)
 Refill receive queue.
static int virtio_net_open (struct net_device *netdev)
 Open network device.
static void virtio_net_close (struct net_device *netdev)
 Close network device.
static int virtio_net_transmit (struct net_device *netdev, struct io_buffer *iobuf)
 Transmit packet.
static void virtio_net_poll_tx (struct net_device *netdev)
 Poll for completed packets.
static void virtio_net_poll_rx (struct net_device *netdev)
 Poll for received packets.
static void virtio_net_poll (struct net_device *netdev)
 Poll for completed and received packets.
static int virtio_net_probe (struct pci_device *pci)
 Probe PCI device.
static void virtio_net_remove (struct pci_device *pci)
 Remove PCI device.

Variables

const struct virtio_features virtio_net_features
 Supported features.
static struct net_device_operations virtio_net_operations
 Virtio network device operations.
static struct pci_device_id virtio_net_ids []
 Virtio network PCI device IDs.
struct pci_driver virtio_net_driver __pci_driver
 Virtio network PCI driver.

Detailed Description

Virtual I/O network device.

Definition in file virtio-net.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ virtio_net_mac()

void virtio_net_mac ( struct net_device * netdev)
static

Get MAC address.

Parameters
netdevNetwork device

Definition at line 68 of file virtio-net.c.

68 {
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}
unsigned int uint32_t
Definition stdint.h:12
void eth_random_addr(void *hw_addr)
Generate random Ethernet address.
Definition ethernet.c:161
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 DBGC(...)
Definition compiler.h:530
#define ETH_ALEN
Definition if_ether.h:9
#define ioread8(io_addr)
Definition io.h:340
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
uint32_t word[VIRTIO_FEATURE_WORDS]
Feature words.
Definition virtio.h:301
A virtio network device.
Definition virtio-net.h:113
struct virtio_device virtio
Underlying virtio device.
Definition virtio-net.h:115
#define VIRTIO_FEAT0_NET_MAC
Device has a MAC address.
Definition virtio-net.h:19
#define VIRTIO_NET_MAC
MAC address register offset.
Definition virtio-net.h:22

References DBGC, virtio_device::device, ETH_ALEN, eth_random_addr(), virtio_device::features, ioread8, is_valid_ether_addr(), virtio_device::name, netdev, virtio_net::virtio, VIRTIO_FEAT0_NET_MAC, VIRTIO_NET_MAC, and virtio_features::word.

Referenced by virtio_net_probe().

◆ virtio_net_mtu()

void virtio_net_mtu ( struct net_device * netdev)
static

Get MTU.

Parameters
netdevNetwork device

Definition at line 94 of file virtio-net.c.

94 {
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}
#define ETH_HLEN
Definition if_ether.h:10
#define ioread16(io_addr)
Definition io.h:350
#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

References DBGC, virtio_device::device, ETH_HLEN, virtio_device::features, ioread16, virtio_device::name, netdev, virtio_net::virtio, VIRTIO_FEAT0_NET_MTU, VIRTIO_NET_MTU, and virtio_features::word.

Referenced by virtio_net_probe().

◆ virtio_net_enable()

int virtio_net_enable ( struct virtio_net * vnet,
struct virtio_net_queue * queue )
static

Enable queue.

Parameters
vnetVirtio network device
queueVirtio network queue
Return values
rcReturn status code

Definition at line 123 of file virtio-net.c.

124 {
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}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
long index
Definition bigint.h:30
static int fill
Definition string.h:209
#define max(x, y)
Definition ath.h:41
uint8_t slot
Slot.
Definition edd.h:3
uint16_t queue
Queue ID.
Definition ena.h:11
struct ena_llq_option desc
Descriptor counts.
Definition ena.h:9
static unsigned int count
Number of entries.
Definition dwmac.h:220
device nvs write
Definition threewire.h:62
#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
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.
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
A virtio buffer descriptor.
Definition virtio.h:152
struct dma_device * dma
DMA device.
Definition virtio.h:317
size_t hlen
Virtio network header length.
Definition virtio-net.h:122
#define VIRTIO_NET_DESCS
Number of descriptors per packet.
Definition virtio-net.h:54
int virtio_enable(struct virtio_device *virtio, struct virtio_queue *queue, unsigned int count)
Enable queue.
Definition virtio.c:696
#define VIRTIO_DESC_FL_NEXT
Next descriptor index is valid.
Definition virtio.h:164

References count, cpu_to_le16, cpu_to_le32, cpu_to_le64, DBGC, desc, dma(), virtio_device::dma, dma_unmap(), fill, virtio_net::hlen, index, max, virtio_device::name, NULL, queue, rc, slot, strerror(), virtio_net::virtio, VIRTIO_DESC_FL_NEXT, virtio_enable(), VIRTIO_NET_DESCS, and write.

Referenced by virtio_net_open().

◆ virtio_net_submit()

void virtio_net_submit ( struct virtio_net * vnet,
struct virtio_net_queue * queue,
struct io_buffer * iobuf,
size_t len )
static

Submit I/O buffer to queue.

Parameters
vnetVirtio network device
queueVirtio network queue
iobufI/O buffer
lenSubmitted length

Definition at line 195 of file virtio-net.c.

197 {
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}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
ring len
Length.
Definition dwmac.h:226
#define DBGC2(...)
Definition compiler.h:547
static __always_inline physaddr_t iob_dma(struct io_buffer *iobuf)
Get I/O buffer DMA address.
Definition iobuf.h:328
void * data
Start of data.
Definition iobuf.h:113
static void virtio_submit(struct virtio_queue *queue, unsigned int index)
Submit descriptor(s) to queue.
Definition virtio.h:388

References assert, cpu_to_le32, cpu_to_le64, io_buffer::data, DBGC2, desc, index, iob_dma(), len, virtio_device::name, NULL, queue, slot, virtio_net::virtio, VIRTIO_NET_DESCS, and virtio_submit().

Referenced by virtio_net_refill_rx(), and virtio_net_transmit().

◆ virtio_net_complete()

struct io_buffer * virtio_net_complete ( struct virtio_net * vnet,
struct virtio_net_queue * queue,
size_t * len )
static

Complete I/O buffer.

Parameters
vnetVirtio network device
queueVirtio network queue
lenLength to fill in (or NULL to ignore)
Return values
iobufI/O buffer

Definition at line 234 of file virtio-net.c.

236 {
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}
uint16_t cons
Consumer index.
Definition ena.h:11
A persistent I/O buffer.
Definition iobuf.h:98
static unsigned int virtio_complete(struct virtio_queue *queue, size_t *len)
Complete descriptor(s).
Definition virtio.h:438

References assert, cons, DBGC2, index, len, virtio_device::name, NULL, queue, slot, virtio_net::virtio, virtio_complete(), and VIRTIO_NET_DESCS.

Referenced by virtio_net_poll_rx(), and virtio_net_poll_tx().

◆ virtio_net_refill_rx()

void virtio_net_refill_rx ( struct virtio_net * vnet)
static

Refill receive queue.

Parameters
vnetVirtio network device

Definition at line 274 of file virtio-net.c.

274 {
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}
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
A virtio network queue.
Definition virtio-net.h:57
size_t mfs
Maximum frame size.
Definition virtio-net.h:124
struct virtio_net_queue rx
Receive queue.
Definition virtio-net.h:117
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_notify(struct virtio_queue *queue)
Notify queue.
Definition virtio.h:404

References alloc_rx_iob(), virtio_device::dma, len, virtio_net::mfs, queue, virtio_net::rx, virtio_net::virtio, virtio_net_submit(), and virtio_notify().

Referenced by virtio_net_open(), and virtio_net_poll().

◆ virtio_net_open()

int virtio_net_open ( struct net_device * netdev)
static

Open network device.

Parameters
netdevNetwork device
Return values
rcReturn status code

Definition at line 307 of file virtio-net.c.

307 {
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}
struct golan_inbox_hdr hdr
Message header.
Definition CIB_PRM.h:0
#define VIRTIO_STAT_DRIVER_OK
Guest driver is ready.
Definition virtio.h:51
if(natsemi->flags &NATSEMI_64BIT) return 1
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
struct virtio_net_queue tx
Transmit queue.
Definition virtio-net.h:119
A virtio network packet header.
Definition virtio-net.h:28
uint8_t modern[12]
Modern (version 1.0) interface.
Definition virtio-net.h:32
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_refill_rx(struct virtio_net *vnet)
Refill receive queue.
Definition virtio-net.c:274
const struct virtio_features virtio_net_features
Supported features.
Definition virtio-net.c:47
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_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
static int virtio_is_legacy(struct virtio_device *virtio)
Check if device is using the legacy interface.
Definition virtio.h:457

References DBGC, dma_unmap(), ETH_HLEN, hdr, virtio_net_queue::hdr, virtio_net::hlen, virtio_net_queue::map, virtio_net::mfs, virtio_device::name, netdev, virtio_net_queue::queue, rc, virtio_net::rx, strerror(), virtio_net::tx, virtio_net::virtio, virtio_free(), virtio_init(), virtio_is_legacy(), virtio_net_enable(), virtio_net_features, virtio_net_refill_rx(), virtio_reset(), VIRTIO_STAT_DRIVER_OK, and virtio_status().

◆ virtio_net_close()

void virtio_net_close ( struct net_device * netdev)
static

Close network device.

Parameters
netdevNetwork device

Definition at line 368 of file virtio-net.c.

368 {
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}
void free_rx_iob(struct io_buffer *iobuf)
Unmap and free I/O buffer for receive DMA.
Definition iobuf.c:215
struct io_buffer * rx_iobufs[VIRTIO_NET_RX_MAX]
Receive I/O buffers.
Definition virtio-net.h:129
#define VIRTIO_NET_RX_MAX
Receive queue maximum fill level.
Definition virtio-net.h:42

References dma_unmap(), free_rx_iob(), virtio_net_queue::hdr, virtio_net_queue::map, netdev, virtio_net_queue::queue, virtio_net::rx, virtio_net::rx_iobufs, virtio_net::tx, virtio_net::virtio, virtio_free(), VIRTIO_NET_RX_MAX, and virtio_reset().

◆ virtio_net_transmit()

int virtio_net_transmit ( struct net_device * netdev,
struct io_buffer * iobuf )
static

Transmit packet.

Parameters
netdevNetwork device
iobufI/O buffer
Return values
rcReturn status code

Definition at line 396 of file virtio-net.c.

397 {
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}
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:220
void netdev_tx_defer(struct net_device *netdev, struct io_buffer *iobuf)
Defer transmitted packet.
Definition netdevice.c:413

References iob_len(), netdev, netdev_tx_defer(), queue, virtio_net::tx, virtio_net_submit(), and virtio_notify().

◆ virtio_net_poll_tx()

void virtio_net_poll_tx ( struct net_device * netdev)
static

Poll for completed packets.

Parameters
netdevNetwork device

Definition at line 421 of file virtio-net.c.

421 {
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}
static void netdev_tx_complete(struct net_device *netdev, struct io_buffer *iobuf)
Complete network transmission.
Definition netdevice.h:770
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 unsigned int virtio_completions(struct virtio_queue *queue)
Check for completed descriptors.
Definition virtio.h:422

References netdev, netdev_tx_complete(), NULL, queue, virtio_net::tx, virtio_completions(), and virtio_net_complete().

Referenced by virtio_net_poll().

◆ virtio_net_poll_rx()

void virtio_net_poll_rx ( struct net_device * netdev)
static

Poll for received packets.

Parameters
netdevNetwork device

Definition at line 440 of file virtio-net.c.

440 {
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}
#define iob_put(iobuf, len)
Definition iobuf.h:185
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition netdevice.c:549

References virtio_net::hlen, iob_put, len, netdev, netdev_rx(), queue, virtio_net::rx, virtio_completions(), and virtio_net_complete().

Referenced by virtio_net_poll().

◆ virtio_net_poll()

void virtio_net_poll ( struct net_device * netdev)
static

Poll for completed and received packets.

Parameters
netdevNetwork device

Definition at line 461 of file virtio-net.c.

461 {
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}
static void virtio_net_poll_rx(struct net_device *netdev)
Poll for received packets.
Definition virtio-net.c:440
static void virtio_net_poll_tx(struct net_device *netdev)
Poll for completed packets.
Definition virtio-net.c:421

References netdev, virtio_net_poll_rx(), virtio_net_poll_tx(), and virtio_net_refill_rx().

◆ virtio_net_probe()

int virtio_net_probe ( struct pci_device * pci)
static

Probe PCI device.

Parameters
pciPCI device
Return values
rcReturn status code

Definition at line 495 of file virtio-net.c.

495 {
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}
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition ethernet.c:266
#define ENOMEM
Not enough space.
Definition errno.h:578
void * memset(void *dest, int character, size_t len) __nonnull
#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 unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition netdevice.c:946
int register_netdev(struct net_device *netdev)
Register network device.
Definition netdevice.c:760
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 pci_set_drvdata(struct pci_device *pci, void *priv)
Set PCI driver-private data.
Definition pci.h:370
A network device.
Definition netdevice.h:353
struct device dev
Generic device.
Definition pci.h:216
struct dma_device dma
DMA device.
Definition pci.h:218
uint8_t rx_slots[VIRTIO_NET_RX_MAX]
Receive descriptor slot ring.
Definition virtio-net.h:127
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
static struct net_device_operations virtio_net_operations
Virtio network device operations.
Definition virtio-net.c:475
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
#define VIRTIO_NET_RX_COUNT
Receive queue requested queue size.
Definition virtio-net.h:39
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_NET_TX_COUNT
Transmit queue requested queue size.
Definition virtio-net.h:48
#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
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

References alloc_etherdev(), DBGC, pci_device::dev, pci_device::dma, DMA_RX, DMA_TX, ENOMEM, memset(), virtio_device::name, netdev, netdev_init(), netdev_link_up(), netdev_nullify(), netdev_put(), pci_set_drvdata(), rc, register_netdev(), virtio_net::rx, virtio_net::rx_iobufs, virtio_net::rx_slots, strerror(), virtio_net::tx, virtio_net::tx_iobufs, virtio_net::tx_slots, unregister_netdev(), virtio_net::virtio, VIRTIO_DESC_FL_WRITE, virtio_init(), virtio_net_features, virtio_net_mac(), virtio_net_mtu(), virtio_net_operations, virtio_net_queue_init(), VIRTIO_NET_RX_COUNT, VIRTIO_NET_RX_INDEX, VIRTIO_NET_RX_MAX, VIRTIO_NET_TX_COUNT, VIRTIO_NET_TX_INDEX, VIRTIO_NET_TX_MAX, virtio_pci_map(), virtio_reset(), and virtio_unmap().

◆ virtio_net_remove()

void virtio_net_remove ( struct pci_device * pci)
static

Remove PCI device.

Parameters
pciPCI device

Definition at line 568 of file virtio-net.c.

568 {
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}
static void * pci_get_drvdata(struct pci_device *pci)
Get PCI driver-private data.
Definition pci.h:380

References netdev, netdev_nullify(), netdev_put(), pci_get_drvdata(), unregister_netdev(), virtio_net::virtio, virtio_reset(), and virtio_unmap().

Variable Documentation

◆ virtio_net_features

const struct virtio_features virtio_net_features
Initial value:
= {
.word = {
},
}
#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

Supported features.

Definition at line 47 of file virtio-net.c.

47 {
48 .word = {
53 },
54};

Referenced by virtio_net_open(), and virtio_net_probe().

◆ virtio_net_operations

struct net_device_operations virtio_net_operations
static
Initial value:
= {
.open = virtio_net_open,
.close = virtio_net_close,
.transmit = virtio_net_transmit,
.poll = virtio_net_poll,
}
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 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

Virtio network device operations.

Definition at line 475 of file virtio-net.c.

475 {
476 .open = virtio_net_open,
477 .close = virtio_net_close,
478 .transmit = virtio_net_transmit,
479 .poll = virtio_net_poll,
480};

Referenced by virtio_net_probe().

◆ virtio_net_ids

struct pci_device_id virtio_net_ids[]
static
Initial value:
= {
PCI_ROM ( 0x1af4, 0x1000, "virtio-net", "Virtio (legacy)", 0 ),
PCI_ROM ( 0x1af4, 0x1041, "virtio-net", "Virtio (modern)", 0 ),
}
#define PCI_ROM(_vendor, _device, _name, _description, _data)
Definition pci.h:311

Virtio network PCI device IDs.

Definition at line 586 of file virtio-net.c.

586 {
587 PCI_ROM ( 0x1af4, 0x1000, "virtio-net", "Virtio (legacy)", 0 ),
588 PCI_ROM ( 0x1af4, 0x1041, "virtio-net", "Virtio (modern)", 0 ),
589};

◆ __pci_driver

struct pci_driver virtio_net_driver __pci_driver
Initial value:
= {
.id_count = ( sizeof ( virtio_net_ids ) /
sizeof ( virtio_net_ids[0] ) ),
.probe = virtio_net_probe,
}
static void virtio_net_remove(struct pci_device *pci)
Remove PCI device.
Definition virtio-net.c:568
static int virtio_net_probe(struct pci_device *pci)
Probe PCI device.
Definition virtio-net.c:495
static struct pci_device_id virtio_net_ids[]
Virtio network PCI device IDs.
Definition virtio-net.c:586
static struct xen_remove_from_physmap * remove
Definition xenmem.h:40

Virtio network PCI driver.

Definition at line 592 of file virtio-net.c.

592 {
593 .ids = virtio_net_ids,
594 .id_count = ( sizeof ( virtio_net_ids ) /
595 sizeof ( virtio_net_ids[0] ) ),
596 .probe = virtio_net_probe,
598};