1
2
3
4
5
6#ifndef _VIRTIO_H_
7#define _VIRTIO_H_
8
9#include <rte_ether.h>
10
11
12#define VIRTIO_NET_F_CSUM 0
13#define VIRTIO_NET_F_GUEST_CSUM 1
14#define VIRTIO_NET_F_MTU 3
15#define VIRTIO_NET_F_MAC 5
16#define VIRTIO_NET_F_GUEST_TSO4 7
17#define VIRTIO_NET_F_GUEST_TSO6 8
18#define VIRTIO_NET_F_GUEST_ECN 9
19#define VIRTIO_NET_F_GUEST_UFO 10
20#define VIRTIO_NET_F_HOST_TSO4 11
21#define VIRTIO_NET_F_HOST_TSO6 12
22#define VIRTIO_NET_F_HOST_ECN 13
23#define VIRTIO_NET_F_HOST_UFO 14
24#define VIRTIO_NET_F_MRG_RXBUF 15
25#define VIRTIO_NET_F_STATUS 16
26#define VIRTIO_NET_F_CTRL_VQ 17
27#define VIRTIO_NET_F_CTRL_RX 18
28#define VIRTIO_NET_F_CTRL_VLAN 19
29#define VIRTIO_NET_F_CTRL_RX_EXTRA 20
30#define VIRTIO_NET_F_GUEST_ANNOUNCE 21
31#define VIRTIO_NET_F_MQ 22
32#define VIRTIO_NET_F_CTRL_MAC_ADDR 23
33
34
35
36
37
38#define VIRTIO_F_NOTIFY_ON_EMPTY 24
39
40
41#define VIRTIO_F_ANY_LAYOUT 27
42
43
44#define VIRTIO_RING_F_INDIRECT_DESC 28
45
46#define VIRTIO_F_VERSION_1 32
47#define VIRTIO_F_IOMMU_PLATFORM 33
48#define VIRTIO_F_RING_PACKED 34
49
50
51
52
53
54
55#define VIRTIO_TRANSPORT_F_START 28
56#define VIRTIO_TRANSPORT_F_END 34
57
58
59
60
61
62#define VIRTIO_F_IN_ORDER 35
63
64
65
66
67
68#define VIRTIO_F_ORDER_PLATFORM 36
69
70
71
72
73
74#define VIRTIO_F_NOTIFICATION_DATA 38
75
76
77#define VIRTIO_NET_F_SPEED_DUPLEX 63
78
79
80
81
82
83
84
85
86#define VIRTIO_RING_F_EVENT_IDX 29
87
88#define VIRTIO_NET_S_LINK_UP 1
89#define VIRTIO_NET_S_ANNOUNCE 2
90
91
92
93
94
95
96
97
98
99
100
101#define VIRTIO_MAX_INDIRECT ((int)(rte_mem_page_size() / 16))
102
103
104
105
106#define VIRTIO_MAX_VIRTQUEUE_PAIRS 8
107#define VIRTIO_MAX_VIRTQUEUES (VIRTIO_MAX_VIRTQUEUE_PAIRS * 2 + 1)
108
109
110#define VIRTIO_ID_NETWORK 0x01
111#define VIRTIO_ID_BLOCK 0x02
112#define VIRTIO_ID_CONSOLE 0x03
113#define VIRTIO_ID_ENTROPY 0x04
114#define VIRTIO_ID_BALLOON 0x05
115#define VIRTIO_ID_IOMEMORY 0x06
116#define VIRTIO_ID_9P 0x09
117
118
119#define VIRTIO_CONFIG_STATUS_RESET 0x00
120#define VIRTIO_CONFIG_STATUS_ACK 0x01
121#define VIRTIO_CONFIG_STATUS_DRIVER 0x02
122#define VIRTIO_CONFIG_STATUS_DRIVER_OK 0x04
123#define VIRTIO_CONFIG_STATUS_FEATURES_OK 0x08
124#define VIRTIO_CONFIG_STATUS_DEV_NEED_RESET 0x40
125#define VIRTIO_CONFIG_STATUS_FAILED 0x80
126
127
128#define VIRTIO_ISR_INTR 0x1
129
130#define VIRTIO_ISR_CONFIG 0x2
131
132#define VIRTIO_MSI_NO_VECTOR 0xFFFF
133
134
135#define VIRTIO_VRING_ALIGN 4096
136
137
138
139
140
141
142struct virtio_net_config {
143
144 uint8_t mac[RTE_ETHER_ADDR_LEN];
145
146 uint16_t status;
147 uint16_t max_virtqueue_pairs;
148 uint16_t mtu;
149
150
151
152
153 uint32_t speed;
154
155
156
157
158
159 uint8_t duplex;
160
161} __rte_packed;
162
163struct virtio_hw {
164 struct virtqueue **vqs;
165 uint64_t guest_features;
166 uint16_t vtnet_hdr_size;
167 uint8_t started;
168 uint8_t weak_barriers;
169 uint8_t vlan_strip;
170 uint8_t has_tx_offload;
171 uint8_t has_rx_offload;
172 uint8_t use_vec_rx;
173 uint8_t use_vec_tx;
174 uint8_t use_inorder_rx;
175 uint8_t use_inorder_tx;
176 uint8_t opened;
177 uint16_t port_id;
178 uint8_t mac_addr[RTE_ETHER_ADDR_LEN];
179 uint32_t speed;
180 uint8_t duplex;
181 uint8_t intr_lsc;
182 uint16_t max_mtu;
183
184
185
186
187
188 rte_spinlock_t state_lock;
189 struct rte_mbuf **inject_pkts;
190 uint16_t max_queue_pairs;
191 uint64_t req_guest_features;
192 struct virtnet_ctl *cvq;
193};
194
195struct virtio_ops {
196 void (*read_dev_cfg)(struct virtio_hw *hw, size_t offset, void *dst, int len);
197 void (*write_dev_cfg)(struct virtio_hw *hw, size_t offset, const void *src, int len);
198 uint8_t (*get_status)(struct virtio_hw *hw);
199 void (*set_status)(struct virtio_hw *hw, uint8_t status);
200 uint64_t (*get_features)(struct virtio_hw *hw);
201 void (*set_features)(struct virtio_hw *hw, uint64_t features);
202 int (*features_ok)(struct virtio_hw *hw);
203 uint8_t (*get_isr)(struct virtio_hw *hw);
204 uint16_t (*set_config_irq)(struct virtio_hw *hw, uint16_t vec);
205 uint16_t (*set_queue_irq)(struct virtio_hw *hw, struct virtqueue *vq, uint16_t vec);
206 uint16_t (*get_queue_num)(struct virtio_hw *hw, uint16_t queue_id);
207 int (*setup_queue)(struct virtio_hw *hw, struct virtqueue *vq);
208 void (*del_queue)(struct virtio_hw *hw, struct virtqueue *vq);
209 void (*notify_queue)(struct virtio_hw *hw, struct virtqueue *vq);
210 void (*intr_detect)(struct virtio_hw *hw);
211 int (*dev_close)(struct virtio_hw *hw);
212};
213
214
215
216
217struct virtio_hw_internal {
218 const struct virtio_ops *virtio_ops;
219};
220
221#define VIRTIO_OPS(hw) (virtio_hw_internal[(hw)->port_id].virtio_ops)
222
223extern struct virtio_hw_internal virtio_hw_internal[RTE_MAX_ETHPORTS];
224
225
226static inline int
227virtio_with_feature(struct virtio_hw *hw, uint64_t bit)
228{
229 return (hw->guest_features & (1ULL << bit)) != 0;
230}
231
232static inline int
233virtio_with_packed_queue(struct virtio_hw *hw)
234{
235 return virtio_with_feature(hw, VIRTIO_F_RING_PACKED);
236}
237
238uint64_t virtio_negotiate_features(struct virtio_hw *hw, uint64_t host_features);
239uint8_t virtio_get_status(struct virtio_hw *hw);
240void virtio_set_status(struct virtio_hw *hw, uint8_t status);
241void virtio_write_dev_config(struct virtio_hw *hw, size_t offset, const void *src, int length);
242void virtio_read_dev_config(struct virtio_hw *hw, size_t offset, void *dst, int length);
243void virtio_reset(struct virtio_hw *hw);
244void virtio_reinit_complete(struct virtio_hw *hw);
245uint8_t virtio_get_isr(struct virtio_hw *hw);
246#endif
247