xref: /illumos-gate/usr/src/uts/common/sys/dld.h (revision ac2250cb76bb32944fd2c8a3ba2cd3f79747748d)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  * Copyright (c) 2017, Joyent, Inc.
25  * Copyright 2026 Edgecast Cloud LLC.
26  */
27 
28 #ifndef	_SYS_DLD_H
29 #define	_SYS_DLD_H
30 
31 /*
32  * Data-Link Driver ioctl interfaces.
33  *
34  * Note that the data structures defined here define an ioctl interface
35  * that is shared betwen user and kernel space.  The dld driver thus
36  * assumes that the structures have identical layout and size when
37  * compiled in either IPL32 or LP64.
38  */
39 
40 #include <sys/types.h>
41 #include <sys/stream.h>
42 #include <sys/mac_flow.h>
43 #include <sys/conf.h>
44 #include <sys/sad.h>
45 #include <sys/mac.h>
46 
47 #ifdef	__cplusplus
48 extern "C" {
49 #endif
50 
51 /*
52  * Data-Link Driver Information (text emitted by modinfo(8))
53  */
54 #define	DLD_INFO	"Data-Link Driver"
55 
56 /*
57  * Options: To enable an option set the property name to a non-zero value
58  *	    in kernel/drv/dld.conf.
59  */
60 
61 /*
62  * Prevent use of the IP fast-path (direct M_DATA transmit).
63  */
64 #define	DLD_PROP_NO_FASTPATH	"no-fastpath"
65 
66 /*
67  * Prevent advertising of the DL_CAPAB_POLL capability.
68  */
69 #define	DLD_PROP_NO_POLL	"no-poll"
70 
71 /*
72  * Prevent advertising of the DL_CAPAB_ZEROCOPY capability.
73  */
74 #define	DLD_PROP_NO_ZEROCOPY	"no-zerocopy"
75 
76 /*
77  * Prevent advertising of the DL_CAPAB_SOFTRING capability.
78  */
79 #define	DLD_PROP_NO_SOFTRING	"no-softring"
80 
81 /*
82  * The name of the driver.
83  */
84 #define	DLD_DRIVER_NAME		"dld"
85 
86 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
87 #pragma pack(4)
88 #endif
89 
90 /*
91  * IOCTL codes and data structures.
92  */
93 #define	DLDIOC_ATTR	DLDIOC(0x03)
94 
95 typedef struct dld_ioc_attr {
96 	datalink_id_t		dia_linkid;
97 	uint_t			dia_max_sdu;
98 } dld_ioc_attr_t;
99 
100 #define	DLDIOC_VLAN_ATTR	DLDIOC(0x04)
101 typedef struct dld_ioc_vlan_attr {
102 	datalink_id_t	div_vlanid;
103 	uint16_t	div_vid;
104 	datalink_id_t	div_linkid;
105 	boolean_t	div_force;
106 } dld_ioc_vlan_attr_t;
107 
108 #define	DLDIOC_PHYS_ATTR	DLDIOC(0x05)
109 #define	DLPI_LINKNAME_MAX	32
110 
111 typedef struct dld_ioc_phys_attr {
112 	datalink_id_t	dip_linkid;
113 	/*
114 	 * Whether this physical link supports vanity naming. Note that
115 	 * physical links whose media type is not supported by GLDv3
116 	 * can not support vanity naming.
117 	 */
118 	boolean_t	dip_novanity;
119 	char		dip_dev[MAXLINKNAMELEN];
120 } dld_ioc_phys_attr_t;
121 
122 /*
123  * Secure objects ioctls
124  */
125 typedef enum {
126 	DLD_SECOBJ_CLASS_WEP = 1,
127 	DLD_SECOBJ_CLASS_WPA
128 } dld_secobj_class_t;
129 
130 #define	DLD_SECOBJ_OPT_CREATE	0x00000001
131 #define	DLD_SECOBJ_NAME_MAX	32
132 #define	DLD_SECOBJ_VAL_MAX	256
133 typedef struct dld_secobj {
134 	char			so_name[DLD_SECOBJ_NAME_MAX];
135 	dld_secobj_class_t	so_class;
136 	uint8_t			so_val[DLD_SECOBJ_VAL_MAX];
137 	uint_t			so_len;
138 } dld_secobj_t;
139 
140 #define	DLDIOC_SECOBJ_SET	DLDIOC(0x06)
141 typedef struct dld_ioc_secobj_set {
142 	dld_secobj_t		ss_obj;
143 	uint_t			ss_flags;
144 } dld_ioc_secobj_set_t;
145 
146 #define	DLDIOC_SECOBJ_GET	DLDIOC(0x07)
147 typedef struct dld_ioc_secobj_get {
148 	dld_secobj_t		sg_obj;
149 	uint_t			sg_count;
150 	uint_t			sg_size;
151 } dld_ioc_secobj_get_t;
152 
153 /*
154  * The following two slots were used outside of ON, so don't reuse them.
155  *
156  * #define DLDIOCHOLDVLAN DLDIOC(0x08)
157  * #define DLDIOCRELEVLAN DLDIOC(0x09)
158  */
159 
160 #define	DLDIOC_SECOBJ_UNSET	DLDIOC(0x0a)
161 typedef struct dld_ioc_secobj_unset {
162 	char			su_name[DLD_SECOBJ_NAME_MAX];
163 } dld_ioc_secobj_unset_t;
164 
165 #define	DLDIOC_CREATE_VLAN	DLDIOC(0x0b)
166 typedef struct dld_ioc_create_vlan {
167 	datalink_id_t	dic_vlanid;
168 	datalink_id_t	dic_linkid;
169 	uint16_t	dic_vid;
170 	boolean_t	dic_force;
171 } dld_ioc_create_vlan_t;
172 
173 #define	DLDIOC_DELETE_VLAN	DLDIOC(0x0c)
174 typedef struct dld_ioc_delete_vlan {
175 	datalink_id_t	did_linkid;
176 } dld_ioc_delete_vlan_t;
177 
178 /*
179  * The following constants have been removed, and the slots are open:
180  *
181  * #define DLDIOC_SETAUTOPUSH	DLDIOC(0x0d)
182  * #define DLDIOC_GETAUTOPUSH	DLDIOC(0x0e)
183  * #define DLDIOC_CLRAUTOPUSH	DLDIOC(0x0f)
184  */
185 
186 #define	DLDIOC_DOORSERVER	DLDIOC(0x10)
187 typedef struct dld_ioc_door {
188 	boolean_t	did_start_door;
189 } dld_ioc_door_t;
190 
191 #define	DLDIOC_RENAME		DLDIOC(0x11)
192 typedef struct dld_ioc_rename {
193 	datalink_id_t	dir_linkid1;
194 	datalink_id_t	dir_linkid2;
195 	char		dir_link[MAXLINKNAMELEN];
196 } dld_ioc_rename_t;
197 
198 /*
199  * The following constants have been removed, and the slots are open:
200  *
201  * #define DLDIOC_SETZID	DLDIOC(0x12)
202  * #define DLDIOC_GETZID	DLDIOC(0x13)
203  */
204 
205 typedef struct dld_ioc_zid {
206 	zoneid_t	diz_zid;
207 	datalink_id_t	diz_linkid;
208 } dld_ioc_zid_t;
209 
210 /*
211  * data-link autopush configuration.
212  */
213 struct dlautopush {
214 	uint_t	dap_anchor;
215 	uint_t	dap_npush;
216 	char	dap_aplist[MAXAPUSH][FMNAMESZ+1];
217 };
218 
219 #define	DLDIOC_MACADDRGET	DLDIOC(0x15)
220 typedef struct dld_ioc_macaddrget {
221 	datalink_id_t	dig_linkid;
222 	uint_t		dig_count;
223 	uint_t		dig_size;
224 } dld_ioc_macaddrget_t;
225 
226 /* possible flags for dmi_flags below */
227 #define	DLDIOCMACADDR_USED	0x1	/* address slot used */
228 
229 typedef struct dld_macaddrinfo {
230 	uint_t		dmi_slot;
231 	uint_t		dmi_flags;
232 	uint_t		dmi_addrlen;
233 	uchar_t		dmi_addr[MAXMACADDRLEN];
234 	char		dmi_client_name[MAXNAMELEN];
235 	datalink_id_t	dma_client_linkid;
236 } dld_macaddrinfo_t;
237 
238 /*
239  * IOCTL codes and data structures for flowadm.
240  */
241 #define	DLDIOC_ADDFLOW		DLDIOC(0x16)
242 typedef struct dld_ioc_addflow {
243 	datalink_id_t		af_linkid;
244 	flow_desc_t		af_flow_desc;
245 	mac_resource_props_t	af_resource_props;
246 	char			af_name[MAXFLOWNAMELEN];
247 } dld_ioc_addflow_t;
248 
249 #define	DLDIOC_REMOVEFLOW	DLDIOC(0x17)
250 typedef struct dld_ioc_removeflow {
251 	char			rf_name[MAXFLOWNAMELEN];
252 } dld_ioc_removeflow_t;
253 
254 #define	DLDIOC_MODIFYFLOW	DLDIOC(0x18)
255 typedef struct dld_ioc_modifyflow {
256 	char			mf_name[MAXFLOWNAMELEN];
257 	mac_resource_props_t	mf_resource_props;
258 } dld_ioc_modifyflow_t;
259 
260 #define	DLDIOC_WALKFLOW		DLDIOC(0x19)
261 typedef struct dld_ioc_walkflow {
262 	datalink_id_t		wf_linkid;
263 	char			wf_name[MAXFLOWNAMELEN];
264 	uint32_t		wf_nflows;
265 	uint_t			wf_len;
266 } dld_ioc_walkflow_t;
267 
268 typedef struct dld_flowinfo {
269 	datalink_id_t		fi_linkid;
270 	flow_desc_t		fi_flow_desc;
271 	mac_resource_props_t	fi_resource_props;
272 	char			fi_flowname[MAXFLOWNAMELEN];
273 	uint32_t		fi_pad;
274 } dld_flowinfo_t;
275 
276 #define	DLDIOC_USAGELOG		DLDIOC(0x1a)
277 typedef struct dld_ioc_usagelog {
278 	mac_logtype_t	ul_type;
279 	boolean_t	ul_onoff;
280 	uint_t		ul_interval;
281 } dld_ioc_usagelog_t;
282 
283 #define	DLDIOC_SETMACPROP	DLDIOC(0x1b)
284 #define	DLDIOC_GETMACPROP	DLDIOC(0x1c)
285 
286 /* pr_flags can be set to a combination of the following flags */
287 #define	DLD_PROP_DEFAULT	0x0001
288 #define	DLD_PROP_POSSIBLE	0x0002
289 
290 typedef struct dld_ioc_macprop_s {
291 	uint_t		pr_flags;
292 	datalink_id_t	pr_linkid;
293 	mac_prop_id_t	pr_num;
294 	uint_t		pr_perm_flags;
295 	char		pr_name[MAXLINKPROPNAME];
296 	uint_t		pr_valsize;	/* sizeof pr_val */
297 	char		pr_val[];	/* Might have padding, be cautious. */
298 } dld_ioc_macprop_t;
299 
300 #define	DLD_MACPROP_VALPAD \
301 	(sizeof (dld_ioc_macprop_t) - offsetof(dld_ioc_macprop_t, pr_val))
302 /* WARNING: We evaluate (v) twice! */
303 #define	DLD_MACPROP_BUFSIZE(v) \
304 	sizeof (dld_ioc_macprop_t) + (((v) <= DLD_MACPROP_VALPAD) ? 0 :	\
305 	    ((v) - DLD_MACPROP_VALPAD))
306 
307 
308 #define	DLDIOC_GETHWGRP		DLDIOC(0x1d)
309 
310 typedef struct dld_ioc_hwgrpget {
311 	datalink_id_t	dih_linkid;
312 	uint_t		dih_n_groups;	/* number of groups included in ioc */
313 	uint_t		dih_size;
314 } dld_ioc_hwgrpget_t;
315 
316 #define	MAXCLIENTNAMELEN	1024
317 typedef struct dld_hwgrpinfo {
318 	char	dhi_link_name[MAXLINKNAMELEN];
319 	uint_t	dhi_grp_num;
320 	uint_t	dhi_grp_type;
321 	uint_t	dhi_n_rings;
322 	uint_t	dhi_n_clnts;
323 	uint_t	dhi_rings[MAX_RINGS_PER_GROUP];
324 	char	dhi_clnts[MAXCLIENTNAMELEN];
325 } dld_hwgrpinfo_t;
326 
327 #define	DLDIOC_GETTRAN		DLDIOC(0x1e)
328 
329 #define	DLDIOC_GETTRAN_GETNTRAN	UINT32_MAX
330 
331 typedef struct dld_ioc_gettran {
332 	datalink_id_t		dgt_linkid;
333 	uint_t			dgt_tran_id;
334 	boolean_t		dgt_present;
335 	boolean_t		dgt_usable;
336 } dld_ioc_gettran_t;
337 
338 #define	DLDIOC_READTRAN		DLDIOC(0x1f)
339 typedef struct dld_ioc_tranio {
340 	datalink_id_t	dti_linkid;
341 	uint_t		dti_tran_id;
342 	uint_t		dti_page;
343 	uint_t		dti_nbytes;
344 	uint_t		dti_off;
345 	uint64_t	dti_buf;
346 } dld_ioc_tranio_t;
347 
348 #define	DLDIOC_GETLED		DLDIOC(0x20)
349 #define	DLDIOC_SETLED		DLDIOC(0x21)
350 
351 typedef struct dld_ioc_led {
352 	datalink_id_t	dil_linkid;
353 	mac_led_mode_t	dil_supported;
354 	mac_led_mode_t	dil_active;
355 	uint_t		dil_pad;
356 } dld_ioc_led_t;
357 
358 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
359 #pragma pack()
360 #endif
361 
362 #ifdef _KERNEL
363 
364 #define	DLD_CAPAB_DIRECT	0x00000001
365 #define	DLD_CAPAB_POLL		0x00000002
366 #define	DLD_CAPAB_PERIM		0x00000003
367 #define	DLD_CAPAB_LSO		0x00000004
368 
369 #define	DLD_ENABLE		0x00000001
370 #define	DLD_DISABLE		0x00000002
371 #define	DLD_QUERY		0x00000003
372 
373 /*
374  * GLDv3 entry point for negotiating capabilities.
375  * This is exposed to IP after negotiation of DL_CAPAB_DLD.
376  *
377  * This function takes the following arguments:
378  * handle: used for identifying the interface to operate on (provided by dld).
379  * type: capability type.
380  * arg: points to a capability-specific structure.
381  * flags: used for indicating whether to enable or disable a capability.
382  *
383  * With this function, capability negotiation is reduced from a multi-step
384  * process to just one single function call.
385  * e.g. the following code would pass 'x' from IP to dld and obtain
386  * arg.output_arg from dld:
387  *
388  * arg.input_arg = x;
389  * rc = (*dld_capab)(handle, DLD_CAPAB_XXX, &arg, DLD_ENABLE);
390  * ill->info1 = arg.output_arg;
391  */
392 typedef	int	(*dld_capab_func_t)(void *, uint_t, void *, uint_t);
393 
394 /*
395  * Direct Tx/Rx capability.
396  */
397 typedef struct dld_capab_direct_s {
398 	/*
399 	 * Rx entry point and handle, owned by IP.
400 	 */
401 	uintptr_t	di_rx_cf;
402 	void		*di_rx_ch;
403 
404 	/*
405 	 * Tx entry points and handle, owned by DLD.
406 	 */
407 	/* Entry point for transmitting packets */
408 	uintptr_t	di_tx_df;
409 	void		*di_tx_dh;
410 
411 	/* flow control notification callback */
412 	uintptr_t	di_tx_cb_df; /* callback registration/de-registration */
413 	void		*di_tx_cb_dh;
414 
415 	/* flow control "can I put on a ring" callback */
416 	uintptr_t	di_tx_fctl_df; /* canput-like callback */
417 	void		*di_tx_fctl_dh;
418 } dld_capab_direct_t;
419 
420 /*
421  * Polling/softring capability.
422  */
423 #define	POLL_SOFTRING		0x00000001
424 typedef struct dld_capab_poll_s {
425 	uintptr_t	poll_ring_add_cf;
426 	uintptr_t	poll_ring_remove_cf;
427 	uintptr_t	poll_ring_quiesce_cf;
428 	uintptr_t	poll_ring_restart_cf;
429 	uintptr_t	poll_ring_bind_cf;
430 	void		*poll_ring_ch;
431 	uintptr_t	poll_mac_accept_df;
432 	void		*poll_mac_dh;
433 } dld_capab_poll_t;
434 
435 /*
436  * LSO capability
437  */
438 /*
439  * Currently supported flags for LSO.
440  */
441 #define	DLD_LSO_BASIC_TCP_IPV4	0x01	/* TCP LSO over IPv4 capability */
442 #define	DLD_LSO_BASIC_TCP_IPV6	0x02	/* TCP LSO over IPv6 capability */
443 
444 typedef struct dld_capab_lso_s {
445 	uint_t  lso_flags;	/* capability flags */
446 	uint_t  lso_max_tcpv4;	/* maximum TCPv4 payload */
447 	uint_t  lso_max_tcpv6;	/* maximum TCPv6 payload */
448 } dld_capab_lso_t;
449 
450 int	dld_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
451 int	dld_devt_to_instance(dev_t);
452 int	dld_open(queue_t *, dev_t *, int, int, cred_t *);
453 int	dld_close(queue_t *, int, cred_t *);
454 int	dld_wput(queue_t *, mblk_t *);
455 int	dld_wsrv(queue_t *);
456 int	dld_str_open(queue_t *, dev_t *, void *);
457 int	dld_str_close(queue_t *);
458 void	*dld_str_private(queue_t *);
459 void	dld_init_ops(struct dev_ops *, const char *);
460 void	dld_fini_ops(struct dev_ops *);
461 int	dld_autopush(dev_t *, struct dlautopush *);
462 
463 int	dld_add_flow(datalink_id_t, char *, flow_desc_t *,
464     mac_resource_props_t *);
465 int	dld_remove_flow(char *);
466 int	dld_modify_flow(char *, mac_resource_props_t *);
467 int	dld_walk_flow(dld_ioc_walkflow_t *, intptr_t, cred_t *);
468 
469 #endif
470 
471 #ifdef	__cplusplus
472 }
473 #endif
474 
475 #endif	/* _SYS_DLD_H */
476