virtio-net.c File Reference

#include "etherboot.h"
#include "nic.h"
#include "gpxe/virtio-ring.h"
#include "gpxe/virtio-pci.h"
#include "virtio-net.h"

Go to the source code of this file.

Data Structures

struct  eth_hdr
struct  eth_frame

Defines

#define BUG()
#define BUG_ON(condition)   do { if (condition) BUG(); } while (0)
#define RX_BUF_NB   6

Enumerations

enum  { RX_INDEX = 0, TX_INDEX, QUEUE_NB }

Functions

static void virtnet_disable (struct nic *nic)
static int virtnet_poll (struct nic *nic, int retrieve)
static void virtnet_transmit (struct nic *nic, const char *destaddr, unsigned int type, unsigned int len, const char *data)
static void virtnet_irq (struct nic *nic __unused, irq_action_t action)
static void provide_buffers (struct nic *nic)
static int virtnet_probe (struct nic *nic, struct pci_device *pci)
 PCI_DRIVER (virtnet_driver, virtnet_nics, PCI_NO_CLASS)
 DRIVER ("VIRTIO-NET", nic_driver, pci_driver, virtnet_driver, virtnet_probe, virtnet_disable)

Variables

static struct virtio_net_hdr tx_virtio_hdr
static struct eth_frame tx_eth_frame
static struct virtio_net_hdr rx_hdr [RX_BUF_NB]
static unsigned char rx_buffer [RX_BUF_NB][ETH_FRAME_LEN]
static struct vring_virtqueue virtqueue [QUEUE_NB]
static struct nic_operations virtnet_operations
static struct pci_device_id virtnet_nics []


Define Documentation

 
#define BUG (  ) 

Value:

do { \
   printf("BUG: failure at %s:%d/%s()!\n", \
          __FILE__, __LINE__, __FUNCTION__); \
   while(1); \
} while (0)

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

#define BUG_ON ( condition   )     do { if (condition) BUG(); } while (0)

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

#define RX_BUF_NB   6

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

Referenced by provide_buffers().


Enumeration Type Documentation

anonymous enum

Enumerator:
RX_INDEX 
TX_INDEX 
QUEUE_NB 

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

00061      {
00062    RX_INDEX = 0,
00063    TX_INDEX,
00064    QUEUE_NB
00065 };


Function Documentation

static void virtnet_disable ( struct nic nic  )  [static]

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

References nic::ioaddr, QUEUE_NB, virtqueue, vp_del_vq(), vp_reset(), and vring_disable_cb().

00077 {
00078    int i;
00079 
00080    for (i = 0; i < QUEUE_NB; i++) {
00081            vring_disable_cb(&virtqueue[i]);
00082            vp_del_vq(nic->ioaddr, i);
00083    }
00084    vp_reset(nic->ioaddr);
00085 }

static int virtnet_poll ( struct nic nic,
int  retrieve 
) [static]

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

References vring_list::addr, BUG_ON, ETH_FRAME_LEN, nic::ioaddr, vring_list::length, memcpy, nic::packet, nic::packetlen, rx_buffer, rx_hdr, RX_INDEX, u16, virtqueue, vring_add_buf(), vring_get_buf(), vring_kick(), and vring_more_used().

00099 {
00100    unsigned int len;
00101    u16 token;
00102    struct virtio_net_hdr *hdr;
00103    struct vring_list list[2];
00104 
00105    if (!vring_more_used(&virtqueue[RX_INDEX]))
00106            return 0;
00107 
00108    if (!retrieve)
00109            return 1;
00110 
00111    token = vring_get_buf(&virtqueue[RX_INDEX], &len);
00112 
00113    BUG_ON(len > sizeof(struct virtio_net_hdr) + ETH_FRAME_LEN);
00114 
00115    hdr = &rx_hdr[token];   /* FIXME: check flags */
00116    len -= sizeof(struct virtio_net_hdr);
00117 
00118    nic->packetlen = len;
00119    memcpy(nic->packet, (char *)rx_buffer[token], nic->packetlen);
00120 
00121    /* add buffer to desc */
00122 
00123    list[0].addr = (char*)&rx_hdr[token];
00124    list[0].length = sizeof(struct virtio_net_hdr);
00125    list[1].addr = (char*)&rx_buffer[token];
00126    list[1].length = ETH_FRAME_LEN;
00127 
00128    vring_add_buf(&virtqueue[RX_INDEX], list, 0, 2, token, 0);
00129    vring_kick(nic->ioaddr, &virtqueue[RX_INDEX], 1);
00130 
00131    return 1;
00132 }

static void virtnet_transmit ( struct nic nic,
const char *  destaddr,
unsigned int  type,
unsigned int  len,
const char *  data 
) [static]

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

References vring_list::addr, BUG_ON, virtio_net_hdr::csum_offset, virtio_net_hdr::csum_start, eth_frame::data, eth_hdr::dst_addr, ETH_ALEN, ETH_FRAME_LEN, virtio_net_hdr::flags, virtio_net_hdr::gso_size, virtio_net_hdr::gso_type, eth_frame::hdr, virtio_net_hdr::hdr_len, htons, nic::ioaddr, vring_list::length, mb(), memcpy, nic::node_addr, NULL, eth_hdr::src_addr, tx_eth_frame, TX_INDEX, tx_virtio_hdr, eth_hdr::type, udelay(), VIRTIO_NET_HDR_GSO_NONE, virtqueue, vring_add_buf(), vring_get_buf(), vring_kick(), and vring_more_used().

00144 {
00145    struct vring_list list[2];
00146 
00147    /*
00148     * from http://www.etherboot.org/wiki/dev/devmanual :
00149     *     "You do not need more than one transmit buffer."
00150     */
00151 
00152    /* FIXME: initialize header according to vp_get_features() */
00153 
00154    tx_virtio_hdr.flags = 0;
00155    tx_virtio_hdr.csum_offset = 0;
00156    tx_virtio_hdr.csum_start = 0;
00157    tx_virtio_hdr.gso_type = VIRTIO_NET_HDR_GSO_NONE;
00158    tx_virtio_hdr.gso_size = 0;
00159    tx_virtio_hdr.hdr_len = 0;
00160 
00161    /* add ethernet frame into vring */
00162 
00163    BUG_ON(len > sizeof(tx_eth_frame.data));
00164 
00165    memcpy(tx_eth_frame.hdr.dst_addr, destaddr, ETH_ALEN);
00166    memcpy(tx_eth_frame.hdr.src_addr, nic->node_addr, ETH_ALEN);
00167    tx_eth_frame.hdr.type = htons(type);
00168    memcpy(tx_eth_frame.data, data, len);
00169 
00170    list[0].addr = (char*)&tx_virtio_hdr;
00171    list[0].length = sizeof(struct virtio_net_hdr);
00172    list[1].addr = (char*)&tx_eth_frame;
00173    list[1].length = ETH_FRAME_LEN;
00174 
00175    vring_add_buf(&virtqueue[TX_INDEX], list, 2, 0, 0, 0);
00176 
00177    vring_kick(nic->ioaddr, &virtqueue[TX_INDEX], 1);
00178 
00179    /*
00180     * http://www.etherboot.org/wiki/dev/devmanual
00181     *
00182     *   "You should ensure the packet is fully transmitted
00183     *    before returning from this routine"
00184     */
00185 
00186    while (!vring_more_used(&virtqueue[TX_INDEX])) {
00187            mb();
00188            udelay(10);
00189    }
00190 
00191    /* free desc */
00192 
00193    (void)vring_get_buf(&virtqueue[TX_INDEX], NULL);
00194 }

static void virtnet_irq ( struct nic *nic  __unused,
irq_action_t  action 
) [static]

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

References DISABLE, ENABLE, FORCE, RX_INDEX, TX_INDEX, virtqueue, vring_disable_cb(), and vring_enable_cb().

00197 {
00198    switch ( action ) {
00199    case DISABLE :
00200            vring_disable_cb(&virtqueue[RX_INDEX]);
00201            vring_disable_cb(&virtqueue[TX_INDEX]);
00202            break;
00203    case ENABLE :
00204            vring_enable_cb(&virtqueue[RX_INDEX]);
00205            vring_enable_cb(&virtqueue[TX_INDEX]);
00206            break;
00207    case FORCE :
00208            break;
00209    }
00210 }

static void provide_buffers ( struct nic nic  )  [static]

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

References vring_list::addr, ETH_FRAME_LEN, nic::ioaddr, vring_list::length, RX_BUF_NB, rx_buffer, rx_hdr, RX_INDEX, virtqueue, vring_add_buf(), and vring_kick().

Referenced by virtnet_probe().

00213 {
00214    int i;
00215    struct vring_list list[2];
00216 
00217    for (i = 0; i < RX_BUF_NB; i++) {
00218            list[0].addr = (char*)&rx_hdr[i];
00219            list[0].length = sizeof(struct virtio_net_hdr);
00220            list[1].addr = (char*)&rx_buffer[i];
00221            list[1].length = ETH_FRAME_LEN;
00222            vring_add_buf(&virtqueue[RX_INDEX], list, 0, 2, i, i);
00223    }
00224 
00225    /* nofify */
00226 
00227    vring_kick(nic->ioaddr, &virtqueue[RX_INDEX], i);
00228 }

static int virtnet_probe ( struct nic nic,
struct pci_device pci 
) [static]

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

References adjust_pci_device(), ETH_ALEN, vring_virtqueue::free_head, pci_device::ioaddr, nic::ioaddr, pci_device::irq, nic::irqno, vring_virtqueue::last_used_idx, memset(), nic::nic_op, nic::node_addr, offsetof, printf(), provide_buffers(), QUEUE_NB, u32, VIRTIO_CONFIG_S_DRIVER, VIRTIO_CONFIG_S_DRIVER_OK, VIRTIO_NET_F_MAC, virtqueue, vp_find_vq(), vp_get(), vp_get_features(), vp_reset(), vp_set_features(), and vp_set_status().

00245 {
00246    u32 features;
00247    int i;
00248 
00249    /* Mask the bit that says "this is an io addr" */
00250 
00251    nic->ioaddr = pci->ioaddr & ~3;
00252 
00253    /* Copy IRQ from PCI information */
00254 
00255    nic->irqno = pci->irq;
00256 
00257    printf("I/O address 0x%08x, IRQ #%d\n", nic->ioaddr, nic->irqno);
00258 
00259    adjust_pci_device(pci);
00260 
00261    vp_reset(nic->ioaddr);
00262 
00263    features = vp_get_features(nic->ioaddr);
00264    if (features & (1 << VIRTIO_NET_F_MAC)) {
00265            vp_get(nic->ioaddr, offsetof(struct virtio_net_config, mac),
00266                   nic->node_addr, ETH_ALEN);
00267            printf("MAC address ");
00268            for (i = 0; i < ETH_ALEN; i++) {
00269                    printf("%02x%c", nic->node_addr[i],
00270                           (i == ETH_ALEN - 1) ? '\n' : ':');
00271            }
00272    }
00273 
00274    /* initialize emit/receive queue */
00275 
00276    for (i = 0; i < QUEUE_NB; i++) {
00277            virtqueue[i].free_head = 0;
00278            virtqueue[i].last_used_idx = 0;
00279            memset((char*)&virtqueue[i].queue, 0, sizeof(virtqueue[i].queue));
00280            if (vp_find_vq(nic->ioaddr, i, &virtqueue[i]) == -1)
00281                    printf("Cannot register queue #%d\n", i);
00282    }
00283 
00284    /* provide some receive buffers */
00285 
00286     provide_buffers(nic);
00287 
00288    /* define NIC interface */
00289 
00290     nic->nic_op = &virtnet_operations;
00291 
00292    /* driver is ready */
00293 
00294    vp_set_features(nic->ioaddr, features & (1 << VIRTIO_NET_F_MAC));
00295    vp_set_status(nic->ioaddr, VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK);
00296 
00297    return 1;
00298 }

PCI_DRIVER ( virtnet_driver  ,
virtnet_nics  ,
PCI_NO_CLASS   
)

DRIVER ( "VIRTIO-NET"  ,
nic_driver  ,
pci_driver  ,
virtnet_driver  ,
virtnet_probe  ,
virtnet_disable   
)


Variable Documentation

struct virtio_net_hdr tx_virtio_hdr [static]

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

Referenced by virtnet_transmit().

struct eth_frame tx_eth_frame [static]

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

Referenced by virtnet_transmit().

struct virtio_net_hdr rx_hdr[RX_BUF_NB] [static]

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

Referenced by bnx2_poll(), provide_buffers(), and virtnet_poll().

unsigned char rx_buffer[RX_BUF_NB][ETH_FRAME_LEN] [static]

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

Referenced by provide_buffers(), and virtnet_poll().

struct vring_virtqueue virtqueue[QUEUE_NB] [static]

Initial value:

 {
        .connect = dummy_connect,
        .poll = virtnet_poll,
        .transmit = virtnet_transmit,
        .irq = virtnet_irq,
}

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

struct pci_device_id virtnet_nics[] [static]

Initial value:

 {
PCI_ROM(0x1af4, 0x1000, "virtio-net",              "Virtio Network Interface", 0),
}

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


Generated on Tue Apr 6 20:01:44 2010 for gPXE by  doxygen 1.5.7.1