1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*/
/*
* Copyright 2013 Pluribus Networks Inc.
* Copyright 2018 Joyent, Inc.
* Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
* Copyright 2025 Oxide Computer Company
*/
#ifndef _VIONA_IO_H_
#define _VIONA_IO_H_
#include <sys/sysmacros.h>
#define VNA_IOC (('V' << 16)|('C' << 8))
#define VNA_IOC_CREATE (VNA_IOC | 0x01)
#define VNA_IOC_DELETE (VNA_IOC | 0x02)
#define VNA_IOC_VERSION (VNA_IOC | 0x03)
#define VNA_IOC_DEFAULT_PARAMS (VNA_IOC | 0x04)
#define VNA_IOC_RING_INIT (VNA_IOC | 0x10)
#define VNA_IOC_RING_RESET (VNA_IOC | 0x11)
#define VNA_IOC_RING_KICK (VNA_IOC | 0x12)
#define VNA_IOC_RING_SET_MSI (VNA_IOC | 0x13)
#define VNA_IOC_RING_INTR_CLR (VNA_IOC | 0x14)
#define VNA_IOC_RING_SET_STATE (VNA_IOC | 0x15)
#define VNA_IOC_RING_GET_STATE (VNA_IOC | 0x16)
#define VNA_IOC_RING_PAUSE (VNA_IOC | 0x17)
#define VNA_IOC_RING_INIT_MODERN (VNA_IOC | 0x18)
#define VNA_IOC_INTR_POLL (VNA_IOC | 0x20)
#define VNA_IOC_SET_FEATURES (VNA_IOC | 0x21)
#define VNA_IOC_GET_FEATURES (VNA_IOC | 0x22)
#define VNA_IOC_SET_NOTIFY_IOP (VNA_IOC | 0x23)
#define VNA_IOC_SET_PROMISC (VNA_IOC | 0x24)
#define VNA_IOC_GET_PARAMS (VNA_IOC | 0x25)
#define VNA_IOC_SET_PARAMS (VNA_IOC | 0x26)
#define VNA_IOC_GET_MTU (VNA_IOC | 0x27)
#define VNA_IOC_SET_MTU (VNA_IOC | 0x28)
#define VNA_IOC_SET_NOTIFY_MMIO (VNA_IOC | 0x29)
#define VNA_IOC_INTR_POLL_MQ (VNA_IOC | 0x2a)
/*
* While the VirtIO specification allows for up to 0x8000 queue pairs, we
* impose a lower limit in Viona.
*/
#define VIONA_MIN_QPAIR 1
#define VIONA_MAX_QPAIR 0x100
#define VNA_IOC_GET_PAIRS (VNA_IOC | 0x30)
#define VNA_IOC_SET_PAIRS (VNA_IOC | 0x31)
#define VNA_IOC_GET_USEPAIRS (VNA_IOC | 0x32)
#define VNA_IOC_SET_USEPAIRS (VNA_IOC | 0x33)
/*
* Viona Interface Version
*
* Like bhyve, viona exposes Private interfaces which are nonetheless consumed
* by out-of-gate consumers. While those consumers assume all risk of breakage
* incurred by subsequent changes, it would be nice to equip them to potentially
* detect (and handle) those modifications.
*
* There are no established criteria for the magnitude of change which requires
* this version to be incremented, and maintenance of it is considered a
* best-effort activity. Nothing is to be inferred about the magnitude of a
* change when the version is modified. It follows no rules like semver.
*
*/
#define VIONA_CURRENT_INTERFACE_VERSION 6
typedef struct vioc_create {
datalink_id_t c_linkid;
int c_vmfd;
} vioc_create_t;
typedef struct vioc_ring_init {
uint16_t ri_index;
uint16_t ri_qsize;
uint64_t ri_qaddr;
} vioc_ring_init_t;
typedef struct vioc_ring_init_modern {
uint16_t rim_index;
uint16_t rim_qsize;
uint64_t rim_qaddr_desc;
uint64_t rim_qaddr_avail;
uint64_t rim_qaddr_used;
} vioc_ring_init_modern_t;
typedef struct vioc_ring_state {
uint16_t vrs_index;
uint16_t vrs_avail_idx;
uint16_t vrs_used_idx;
uint16_t vrs_qsize;
uint64_t vrs_qaddr_desc;
uint64_t vrs_qaddr_avail;
uint64_t vrs_qaddr_used;
} vioc_ring_state_t;
typedef struct vioc_ring_msi {
uint16_t rm_index;
uint64_t rm_addr;
uint64_t rm_msg;
} vioc_ring_msi_t;
typedef enum {
VIONA_PROMISC_NONE = 0,
VIONA_PROMISC_MULTI,
VIONA_PROMISC_ALL,
VIONA_PROMISC_MAX,
} viona_promisc_t;
/*
* The older VNA_IOC_INTR_POLL API, superseded by VNA_IOC_INTR_POLL_MQ, only
* polls interrupt status for the first queue pair (two rings).
*/
typedef struct vioc_intr_poll {
uint32_t vip_status[2];
} vioc_intr_poll_t;
#define VIONA_INTR_WORD_BITS 32
#define VIONA_INTR_WORDS \
howmany(VIONA_MAX_QPAIR * 2, VIONA_INTR_WORD_BITS)
#define VIONA_INTR_WORD(q) ((q) / VIONA_INTR_WORD_BITS)
#define VIONA_INTR_BIT(q) (1u << ((q) % VIONA_INTR_WORD_BITS))
#define VIONA_INTR_SET(vipm, q) \
(vipm)->vipm_status[VIONA_INTR_WORD(q)] |= VIONA_INTR_BIT(q)
#define VIONA_INTR_TEST(vipm, q) \
(((vipm)->vipm_status[VIONA_INTR_WORD(q)] & VIONA_INTR_BIT(q)) != 0)
typedef struct vioc_intr_poll_mq {
uint16_t vipm_nrings;
uint32_t vipm_status[VIONA_INTR_WORDS];
} vioc_intr_poll_mq_t;
typedef struct vioc_notify_mmio {
uint64_t vim_address;
uint32_t vim_size;
} vioc_notify_mmio_t;
/*
* Viona Parameter Interfaces
*
* A viona link can have various configuration parameters set upon it. This is
* done using packed nvlists in order to communicate those parameters to/from
* the device driver.
*
*
* Currently supported parameters are:
* - tx_copy_data (boolean): During packet transmission, should viona copy all
* of the packet data, rather than "loaning" those regions of guest memory
* (other than the packet headers) in the mblk.
* - tx_header_pad (uint16): How many bytes (if any) should be left as empty
* padding on transmitted packets? These could be used by subsequent
* encapsulation mechanisms in the network stack without the need to
* reallocate space for the then-longer header.
*
*/
/* Maximum size for parameter (or error) packed nvlist buffers */
#define VIONA_MAX_PARAM_NVLIST_SZ 4096
typedef struct vioc_get_params {
void *vgp_param;
size_t vgp_param_sz;
} vioc_get_params_t;
typedef struct vioc_set_params {
void *vsp_param;
size_t vsp_param_sz;
void *vsp_error;
size_t vsp_error_sz;
} vioc_set_params_t;
#endif /* _VIONA_IO_H_ */
|