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