1 /* virtio-net.c - etherboot driver for virtio network interface
3 * (c) Copyright 2008 Bull S.A.S.
5 * Author: Laurent Vivier <Laurent.Vivier@bull.net>
7 * some parts from Linux Virtio PCI driver
9 * Copyright IBM Corp. 2007
10 * Authors: Anthony Liguori <aliguori@us.ibm.com>
12 * some parts from Linux Virtio Ring
14 * Copyright Rusty Russell IBM Corporation 2007
16 * This work is licensed under the terms of the GNU GPL, version 2 or later.
17 * See the COPYING file in the top-level directory.
22 #include "etherboot.h"
24 #include "virtio-ring.h"
25 #include "virtio-pci.h"
26 #include "virtio-net.h"
29 printf("BUG: failure at %s:%d/%s()!\n", \
30 __FILE__, __LINE__, __FUNCTION__); \
33 #define BUG_ON(condition) do { if (condition) BUG(); } while (0)
38 unsigned char dst_addr[ETH_ALEN];
39 unsigned char src_addr[ETH_ALEN];
45 unsigned char data[ETH_FRAME_LEN];
48 typedef unsigned char virtio_queue_t[PAGE_MASK + vring_size(MAX_QUEUE_NUM)];
50 /* TX: virtio header and eth buffer */
52 static struct virtio_net_hdr tx_virtio_hdr;
53 static struct eth_frame tx_eth_frame;
55 /* RX: virtio headers and buffers */
58 static struct virtio_net_hdr rx_hdr[RX_BUF_NB];
59 static unsigned char rx_buffer[RX_BUF_NB][ETH_FRAME_LEN];
61 /* virtio queues and vrings */
69 static virtio_queue_t queue[QUEUE_NB];
70 static struct vring vring[QUEUE_NB];
71 static u16 free_head[QUEUE_NB];
72 static u16 last_used_idx[QUEUE_NB];
73 static u16 vdata[QUEUE_NB][MAX_QUEUE_NUM];
76 * Virtio PCI interface
80 static int vp_find_vq(struct nic *nic, int queue_index)
82 struct vring * vr = &vring[queue_index];
85 /* select the queue */
87 outw(queue_index, nic->ioaddr + VIRTIO_PCI_QUEUE_SEL);
89 /* check if the queue is available */
91 num = inw(nic->ioaddr + VIRTIO_PCI_QUEUE_NUM);
93 printf("ERROR: queue size is 0\n");
97 if (num > MAX_QUEUE_NUM) {
98 printf("ERROR: queue size %d > %d\n", num, MAX_QUEUE_NUM);
102 /* check if the queue is already active */
104 if (inl(nic->ioaddr + VIRTIO_PCI_QUEUE_PFN)) {
105 printf("ERROR: queue already active\n");
109 /* initialize the queue */
111 vring_init(vr, num, (unsigned char*)&queue[queue_index]);
113 /* activate the queue
115 * NOTE: vr->desc is initialized by vring_init()
118 outl((unsigned long)virt_to_phys(vr->desc) >> PAGE_SHIFT,
119 nic->ioaddr + VIRTIO_PCI_QUEUE_PFN);
125 * Virtual ring management
129 static void vring_enable_cb(int queue_index)
131 vring[queue_index].avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
134 static void vring_disable_cb(int queue_index)
136 vring[queue_index].avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
142 * put at the begin of the free list the current desc[head]
145 static void vring_detach(int queue_index, unsigned int head)
147 struct vring *vr = &vring[queue_index];
150 /* find end of given descriptor */
153 while (vr->desc[i].flags & VRING_DESC_F_NEXT)
154 i = vr->desc[i].next;
156 /* link it with free list and point to it */
158 vr->desc[i].next = free_head[queue_index];
160 free_head[queue_index] = head;
166 * is there some used buffers ?
170 static inline int vring_more_used(int queue_index)
173 return last_used_idx[queue_index] != vring[queue_index].used->idx;
179 * get a buffer from the used list
183 static int vring_get_buf(int queue_index, unsigned int *len)
185 struct vring *vr = &vring[queue_index];
186 struct vring_used_elem *elem;
190 elem = &vr->used->ring[last_used_idx[queue_index] % vr->num];
196 ret = vdata[queue_index][id];
198 vring_detach(queue_index, id);
200 last_used_idx[queue_index]++;
205 static void vring_add_buf(int queue_index, int index, int num_added)
207 struct vring *vr = &vring[queue_index];
210 BUG_ON(queue_index >= QUEUE_NB);
212 head = free_head[queue_index];
215 if (queue_index == TX_INDEX) {
219 /* add header into vring */
221 vr->desc[i].flags = VRING_DESC_F_NEXT;
222 vr->desc[i].addr = (u64)virt_to_phys(&tx_virtio_hdr);
223 vr->desc[i].len = sizeof(struct virtio_net_hdr);
224 i = vr->desc[i].next;
226 /* add frame buffer into vring */
228 vr->desc[i].flags = 0;
229 vr->desc[i].addr = (u64)virt_to_phys(&tx_eth_frame);
230 vr->desc[i].len = ETH_FRAME_LEN;
231 i = vr->desc[i].next;
233 } else if (queue_index == RX_INDEX) {
235 BUG_ON(index >= RX_BUF_NB);
237 /* add header into vring */
239 vr->desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE;
240 vr->desc[i].addr = (u64)virt_to_phys(&rx_hdr[index]);
241 vr->desc[i].len = sizeof(struct virtio_net_hdr);
242 i = vr->desc[i].next;
244 /* add frame buffer into vring */
246 vr->desc[i].flags = VRING_DESC_F_WRITE;
247 vr->desc[i].addr = (u64)virt_to_phys(&rx_buffer[index]);
248 vr->desc[i].len = ETH_FRAME_LEN;
249 i = vr->desc[i].next;
252 free_head[queue_index] = i;
254 vdata[queue_index][head] = index;
256 avail = (vr->avail->idx + num_added) % vr->num;
257 vr->avail->ring[avail] = head;
261 static void vring_kick(struct nic *nic, int queue_index, int num_added)
263 struct vring *vr = &vring[queue_index];
266 vr->avail->idx += num_added;
269 if (!(vr->used->flags & VRING_USED_F_NO_NOTIFY))
270 vp_notify(nic, queue_index);
276 * Turn off ethernet interface
280 static void virtnet_disable(struct nic *nic)
284 for (i = 0; i < QUEUE_NB; i++) {
296 * return true if there is a packet ready to read
298 * nic->packet should contain data on return
299 * nic->packetlen should contain length of data
302 static int virtnet_poll(struct nic *nic, int retrieve)
306 struct virtio_net_hdr *hdr;
308 if (!vring_more_used(RX_INDEX))
314 token = vring_get_buf(RX_INDEX, &len);
316 BUG_ON(len > sizeof(struct virtio_net_hdr) + ETH_FRAME_LEN);
318 hdr = &rx_hdr[token]; /* FIXME: check flags */
319 len -= sizeof(struct virtio_net_hdr);
321 nic->packetlen = len;
322 memcpy(nic->packet, (char *)rx_buffer[token], nic->packetlen);
324 /* add buffer to desc */
326 vring_add_buf(RX_INDEX, token, 0);
327 vring_kick(nic, RX_INDEX, 1);
340 static void virtnet_transmit(struct nic *nic, const char *destaddr,
341 unsigned int type, unsigned int len, const char *data)
344 * from http://www.etherboot.org/wiki/dev/devmanual :
345 * "You do not need more than one transmit buffer."
348 /* FIXME: initialize header according to vp_get_features() */
350 tx_virtio_hdr.flags = 0;
351 tx_virtio_hdr.csum_offset = 0;
352 tx_virtio_hdr.csum_start = 0;
353 tx_virtio_hdr.gso_type = VIRTIO_NET_HDR_GSO_NONE;
354 tx_virtio_hdr.gso_size = 0;
355 tx_virtio_hdr.hdr_len = 0;
357 /* add ethernet frame into vring */
359 BUG_ON(len > sizeof(tx_eth_frame.data));
361 memcpy(tx_eth_frame.hdr.dst_addr, destaddr, ETH_ALEN);
362 memcpy(tx_eth_frame.hdr.src_addr, nic->node_addr, ETH_ALEN);
363 tx_eth_frame.hdr.type = htons(type);
364 memcpy(tx_eth_frame.data, data, len);
366 vring_add_buf(TX_INDEX, 0, 0);
369 * http://www.etherboot.org/wiki/dev/devmanual
371 * "You should ensure the packet is fully transmitted
372 * before returning from this routine"
375 while (vring_more_used(TX_INDEX)) {
380 vring_kick(nic, TX_INDEX, 1);
384 (void)vring_get_buf(TX_INDEX, NULL);
387 static void virtnet_irq(struct nic *nic __unused, irq_action_t action)
391 vring_disable_cb(RX_INDEX);
392 vring_disable_cb(TX_INDEX);
395 vring_enable_cb(RX_INDEX);
396 vring_enable_cb(TX_INDEX);
403 static void provide_buffers(struct nic *nic)
407 for (i = 0; i < RX_BUF_NB; i++)
408 vring_add_buf(RX_INDEX, i, i);
412 vring_kick(nic, RX_INDEX, i);
415 static struct nic_operations virtnet_operations = {
416 .connect = dummy_connect,
417 .poll = virtnet_poll,
418 .transmit = virtnet_transmit,
425 * Look for a virtio network adapter
429 static int virtnet_probe(struct nic *nic, struct pci_device *pci)
434 /* Mask the bit that says "this is an io addr" */
436 nic->ioaddr = pci->ioaddr & ~3;
438 /* Copy IRQ from PCI information */
440 nic->irqno = pci->irq;
442 printf("I/O address 0x%08x, IRQ #%d\n", nic->ioaddr, nic->irqno);
444 adjust_pci_device(pci);
448 features = vp_get_features(nic);
449 if (features & (1 << VIRTIO_NET_F_MAC)) {
450 vp_get(nic, offsetof(struct virtio_net_config, mac),
451 nic->node_addr, ETH_ALEN);
452 printf("MAC address ");
453 for (i = 0; i < ETH_ALEN; i++) {
454 printf("%02x%c", nic->node_addr[i],
455 (i == ETH_ALEN - 1) ? '\n' : ':');
459 /* initialize emit/receive queue */
461 for (i = 0; i < QUEUE_NB; i++) {
463 last_used_idx[i] = 0;
464 memset((char*)&queue[i], 0, sizeof(queue[i]));
465 if (vp_find_vq(nic, i) == -1)
466 printf("Cannot register queue #%d\n", i);
469 /* provide some receive buffers */
471 provide_buffers(nic);
473 /* define NIC interface */
475 nic->nic_op = &virtnet_operations;
477 /* driver is ready */
479 vp_set_features(nic, features & (1 << VIRTIO_NET_F_MAC));
480 vp_set_status(nic, VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK);
485 static struct pci_device_id virtnet_nics[] = {
486 PCI_ROM(0x1af4, 0x1000, "virtio-net", "Virtio Network Interface"),
489 PCI_DRIVER ( virtnet_driver, virtnet_nics, PCI_NO_CLASS );
491 DRIVER ( "VIRTIO-NET", nic_driver, pci_driver, virtnet_driver,
492 virtnet_probe, virtnet_disable );