[virtio] Add virtio-net driver
[etherboot.git] / src / drivers / net / virtio-pci.h
1 #ifndef _VIRTIO_PCI_H_
2 # define _VIRTIO_PCI_H_
3
4 #define offsetof(t,m) ((int )&(((t *)0)->m))
5
6 /* A 32-bit r/o bitmask of the features supported by the host */
7 #define VIRTIO_PCI_HOST_FEATURES        0
8
9 /* A 32-bit r/w bitmask of features activated by the guest */
10 #define VIRTIO_PCI_GUEST_FEATURES       4
11
12 /* A 32-bit r/w PFN for the currently selected queue */
13 #define VIRTIO_PCI_QUEUE_PFN            8
14
15 /* A 16-bit r/o queue size for the currently selected queue */
16 #define VIRTIO_PCI_QUEUE_NUM            12
17
18 /* A 16-bit r/w queue selector */
19 #define VIRTIO_PCI_QUEUE_SEL            14
20
21 /* A 16-bit r/w queue notifier */
22 #define VIRTIO_PCI_QUEUE_NOTIFY         16
23
24 /* An 8-bit device status register.  */
25 #define VIRTIO_PCI_STATUS               18
26
27 /* An 8-bit r/o interrupt status register.  Reading the value will return the
28  * current contents of the ISR and will also clear it.  This is effectively
29  * a read-and-acknowledge. */
30 #define VIRTIO_PCI_ISR                  19
31
32 /* The bit of the ISR which indicates a device configuration change. */
33 #define VIRTIO_PCI_ISR_CONFIG           0x2
34
35 /* The remaining space is defined by each driver as the per-driver
36  * configuration space */
37 #define VIRTIO_PCI_CONFIG               20
38
39 /* Virtio ABI version, this must match exactly */
40 #define VIRTIO_PCI_ABI_VERSION          0
41
42 static inline u32 vp_get_features(struct nic *nic)
43 {
44    return inl(nic->ioaddr + VIRTIO_PCI_HOST_FEATURES);
45 }
46
47 static inline void vp_set_features(struct nic *nic, u32 features)
48 {
49         outl(features, nic->ioaddr + VIRTIO_PCI_GUEST_FEATURES);
50 }
51
52 static inline void vp_get(struct nic *nic, unsigned offset,
53                      void *buf, unsigned len)
54 {
55    u8 *ptr = buf;
56    unsigned i;
57
58    for (i = 0; i < len; i++)
59            ptr[i] = inb(nic->ioaddr + VIRTIO_PCI_CONFIG + offset + i);
60 }
61
62 static inline u8 vp_get_status(struct nic *nic)
63 {
64    return inb(nic->ioaddr + VIRTIO_PCI_STATUS);
65 }
66
67 static inline void vp_set_status(struct nic *nic, u8 status)
68 {
69    if (status == 0)        /* reset */
70            return;
71         outb(status, nic->ioaddr + VIRTIO_PCI_STATUS);
72 }
73
74
75 static inline void vp_reset(struct nic *nic)
76 {
77    outb(0, nic->ioaddr + VIRTIO_PCI_STATUS);
78    (void)inb(nic->ioaddr + VIRTIO_PCI_ISR);
79 }
80
81 static inline void vp_notify(struct nic *nic, int queue_index)
82 {
83    outw(queue_index, nic->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY);
84 }
85
86 static inline void vp_del_vq(struct nic *nic, int queue_index)
87 {
88    /* select the queue */
89
90    outw(queue_index, nic->ioaddr + VIRTIO_PCI_QUEUE_SEL);
91
92    /* deactivate the queue */
93
94    outl(0, nic->ioaddr + VIRTIO_PCI_QUEUE_PFN);
95 }
96 #endif /* _VIRTIO_PCI_H_ */