xref: /illumos-gate/usr/src/uts/common/sys/mac_impl.h (revision 10597944279b73141546abca67a8e947810e5bb2)
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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23  * Copyright 2019 Joyent, Inc.
24  * Copyright 2025 Oxide Computer Company
25  */
26 
27 #ifndef	_SYS_MAC_IMPL_H
28 #define	_SYS_MAC_IMPL_H
29 
30 #include <sys/cpupart.h>
31 #include <sys/modhash.h>
32 #include <sys/mac_client.h>
33 #include <sys/mac_provider.h>
34 #include <sys/note.h>
35 #include <sys/avl.h>
36 #include <net/if.h>
37 #include <sys/mac_flow_impl.h>
38 #include <netinet/ip6.h>
39 #include <sys/pattr.h>
40 
41 #ifdef	__cplusplus
42 extern "C" {
43 #endif
44 
45 /*
46  * This is the first minor number available for MAC provider private
47  * use.  This makes it possible to deliver a driver that is both a MAC
48  * provider and a regular character/block device.  See PSARC 2009/380
49  * for more detail about the construction of such devices.  The value
50  * chosen leaves half of the 32-bit minor numbers (which are really
51  * only 18 bits wide) available for driver private use.  Drivers can
52  * easily identify their private number by the presence of this value
53  * in the bits that make up the minor number, since its just the
54  * highest bit available for such minor numbers.
55  */
56 #define	MAC_PRIVATE_MINOR		((MAXMIN32 + 1) / 2)
57 
58 /*
59  * The maximum minor number that corresponds to a real instance.  This
60  * limits the number of physical ports that a mac provider can offer.
61  * Note that this macro must be synchronized with DLS_MAX_MINOR in
62  * <sys/dls.h>
63  */
64 #define	MAC_MAX_MINOR			1000
65 
66 typedef struct mac_margin_req_s	mac_margin_req_t;
67 
68 struct mac_margin_req_s {
69 	mac_margin_req_t	*mmr_nextp;
70 	uint_t			mmr_ref;
71 	uint32_t		mmr_margin;
72 };
73 
74 typedef struct mac_mtu_req_s mac_mtu_req_t;
75 struct mac_mtu_req_s {
76 	mac_mtu_req_t		*mtr_nextp;
77 	uint_t			mtr_ref;
78 	uint32_t		mtr_mtu;
79 };
80 
81 /* Generic linked chain type */
82 typedef	struct mac_chain_s {
83 	struct mac_chain_s	*next;
84 	void			*item;
85 } mac_chain_t;
86 
87 /*
88  * Generic mac callback list manipulation structures and macros. The mac_cb_t
89  * represents a general callback list element embedded in a particular
90  * data structure such as a mac_notify_cb_t or a mac_promisc_impl_t.
91  * The mac_cb_info_t represents general information about list walkers.
92  * Please see the comments above mac_callback_add for more information.
93  */
94 /* mcb_flags */
95 #define	MCB_CONDEMNED		0x1		/* Logically deleted */
96 #define	MCB_NOTIFY_CB_T		0x2
97 #define	MCB_TX_NOTIFY_CB_T	0x4
98 
99 extern boolean_t	mac_tx_serialize;
100 
101 typedef struct mac_cb_s {
102 	struct mac_cb_s		*mcb_nextp;	/* Linked list of callbacks */
103 	void			*mcb_objp;	/* Ptr to enclosing object  */
104 	size_t			mcb_objsize;	/* Sizeof the enclosing obj */
105 	uint_t			mcb_flags;
106 } mac_cb_t;
107 
108 typedef struct mac_cb_info_s {
109 	kmutex_t	*mcbi_lockp;
110 	kcondvar_t	mcbi_cv;
111 	uint_t		mcbi_del_cnt;		/* Deleted callback cnt */
112 	uint_t		mcbi_walker_cnt;	/* List walker count */
113 	uint_t		mcbi_barrier_cnt;	/* Barrier waiter count */
114 } mac_cb_info_t;
115 
116 typedef struct mac_notify_cb_s {
117 	mac_cb_t	mncb_link;		/* Linked list of callbacks */
118 	mac_notify_t	mncb_fn;		/* callback function */
119 	void		*mncb_arg;		/* callback argument */
120 	struct mac_impl_s *mncb_mip;
121 } mac_notify_cb_t;
122 
123 /*
124  * mac_callback_add(listinfo, listhead, listelement)
125  * mac_callback_remove(listinfo, listhead, listelement)
126  */
127 typedef boolean_t (*mcb_func_t)(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
128 
129 #define	MAC_CALLBACK_WALKER_INC(mcbi) \
130 	mac_callback_walker_enter(mcbi)
131 
132 #define	MAC_CALLBACK_WALKER_DCR(mcbi, headp) \
133 	mac_callback_walker_exit(mcbi, headp, B_FALSE)
134 
135 #define	MAC_PROMISC_WALKER_INC(mip) \
136 	mac_callback_walker_enter(&(mip)->mi_promisc_cb_info)
137 
138 #define	MAC_PROMISC_WALKER_DCR(mip) \
139 	mac_callback_walker_exit(&(mip)->mi_promisc_cb_info, \
140 	    &(mip)->mi_promisc_list, B_TRUE)
141 
142 typedef struct mactype_s {
143 	const char	*mt_ident;
144 	uint32_t	mt_ref;
145 	uint_t		mt_type;
146 	uint_t		mt_nativetype;
147 	size_t		mt_addr_length;
148 	uint8_t		*mt_brdcst_addr;
149 	mactype_ops_t	mt_ops;
150 	mac_stat_info_t	*mt_stats;	/* array of mac_stat_info_t elements */
151 	size_t		mt_statcount;	/* number of elements in mt_stats */
152 	mac_ndd_mapping_t *mt_mapping;
153 	size_t		mt_mappingcount;
154 } mactype_t;
155 
156 /*
157  * Multiple rings implementation.
158  */
159 typedef	enum {
160 	MAC_GROUP_STATE_UNINIT	= 0,	/* initial state of data structure */
161 	MAC_GROUP_STATE_REGISTERED,	/* hooked with h/w group */
162 	MAC_GROUP_STATE_RESERVED,	/* group is reserved and opened */
163 	MAC_GROUP_STATE_SHARED		/* default group shared among */
164 					/* multiple mac clients */
165 } mac_group_state_t;
166 
167 typedef	struct mac_ring_s mac_ring_t;
168 typedef	struct mac_group_s mac_group_t;
169 
170 /*
171  * Ring data structure for ring control and management.
172  */
173 typedef enum {
174 	MR_FREE,		/* Available for assignment to flows */
175 	MR_NEWLY_ADDED,		/* Just assigned to another group */
176 	MR_INUSE		/* Assigned to an SRS */
177 } mac_ring_state_t;
178 
179 /* mr_flag values */
180 #define	MR_INCIPIENT	0x1
181 #define	MR_CONDEMNED	0x2
182 #define	MR_QUIESCE	0x4
183 
184 typedef struct mac_impl_s mac_impl_t;
185 
186 struct mac_ring_s {
187 	int			mr_index;	/* index in the original list */
188 	mac_ring_type_t		mr_type;	/* ring type */
189 	mac_ring_t		*mr_next;	/* next ring in the chain */
190 	mac_group_handle_t	mr_gh;		/* reference to group */
191 
192 	mac_classify_type_t	mr_classify_type;
193 	struct mac_soft_ring_set_s *mr_srs;	/* associated SRS */
194 	mac_ring_handle_t	mr_prh;	/* associated pseudo ring hdl */
195 
196 	/*
197 	 * Ring passthru callback and arguments. See the
198 	 * MAC_PASSTHRU_CLASSIFIER comment in mac_provider.h.
199 	 */
200 	mac_rx_t		mr_pt_fn;
201 	void			*mr_pt_arg1;
202 	mac_resource_handle_t	mr_pt_arg2;
203 
204 	uint_t			mr_refcnt;	/* Ring references */
205 	/* ring generation no. to guard against drivers using stale rings */
206 	uint64_t		mr_gen_num;
207 
208 	kstat_t			*mr_ksp;	/* ring kstats */
209 	mac_impl_t		*mr_mip;	/* pointer to primary's mip */
210 
211 	kmutex_t		mr_lock;
212 	kcondvar_t		mr_cv;			/* mr_lock */
213 	mac_ring_state_t	mr_state;		/* mr_lock */
214 	uint_t			mr_flag;		/* mr_lock */
215 
216 	mac_ring_info_t		mr_info;	/* driver supplied info */
217 };
218 #define	mr_driver		mr_info.mri_driver
219 #define	mr_start		mr_info.mri_start
220 #define	mr_stop			mr_info.mri_stop
221 #define	mr_stat			mr_info.mri_stat
222 
223 #define	MAC_RING_MARK(mr, flag)		\
224 	(mr)->mr_flag |= flag;
225 
226 #define	MAC_RING_UNMARK(mr, flag)	\
227 	(mr)->mr_flag &= ~flag;
228 
229 /*
230  * Reference hold and release on mac_ring_t 'mr'
231  */
232 #define	MR_REFHOLD_LOCKED(mr)		{		\
233 	ASSERT(MUTEX_HELD(&mr->mr_lock));		\
234 	(mr)->mr_refcnt++;				\
235 }
236 
237 #define	MR_REFRELE(mr)		{			\
238 	mutex_enter(&(mr)->mr_lock);			\
239 	ASSERT((mr)->mr_refcnt != 0);			\
240 	(mr)->mr_refcnt--;				\
241 	if ((mr)->mr_refcnt == 0 &&			\
242 	    ((mr)->mr_flag & (MR_CONDEMNED | MR_QUIESCE))) \
243 		cv_signal(&(mr)->mr_cv);		\
244 	mutex_exit(&(mr)->mr_lock);			\
245 }
246 
247 /*
248  * Used to attach MAC clients to an Rx group. The members are SL
249  * protected.
250  */
251 typedef struct mac_grp_client {
252 	struct mac_grp_client		*mgc_next;
253 	struct mac_client_impl_s	*mgc_client;
254 } mac_grp_client_t;
255 
256 #define	MAC_GROUP_NO_CLIENT(g)	((g)->mrg_clients == NULL)
257 
258 #define	MAC_GROUP_ONLY_CLIENT(g)			\
259 	((((g)->mrg_clients != NULL) &&			\
260 	((g)->mrg_clients->mgc_next == NULL)) ?		\
261 	(g)->mrg_clients->mgc_client : NULL)
262 
263 #define	MAC_GROUP_HW_VLAN(g)				\
264 	(((g) != NULL) &&				\
265 	((g)->mrg_info.mgi_addvlan != NULL) &&		\
266 	((g)->mrg_info.mgi_remvlan != NULL))
267 
268 /*
269  * Common ring group data structure for ring control and management.
270  * The entire structure is SL protected.
271  */
272 struct mac_group_s {
273 	int			mrg_index;	/* index in the list */
274 	mac_ring_type_t		mrg_type;	/* ring type */
275 	mac_group_state_t	mrg_state;	/* state of the group */
276 	mac_group_t		*mrg_next;	/* next group in the chain */
277 	mac_handle_t		mrg_mh;		/* reference to MAC */
278 	mac_ring_t		*mrg_rings;	/* grouped rings */
279 	uint_t			mrg_cur_count;	/* actual size of group */
280 
281 	mac_grp_client_t	*mrg_clients;	/* clients list */
282 
283 	mac_group_info_t	mrg_info;	/* driver supplied info */
284 };
285 
286 #define	mrg_driver		mrg_info.mgi_driver
287 #define	mrg_start		mrg_info.mgi_start
288 #define	mrg_stop		mrg_info.mgi_stop
289 
290 #define	GROUP_INTR_HANDLE(g)		(g)->mrg_info.mgi_intr.mi_handle
291 #define	GROUP_INTR_ENABLE_FUNC(g)	(g)->mrg_info.mgi_intr.mi_enable
292 #define	GROUP_INTR_DISABLE_FUNC(g)	(g)->mrg_info.mgi_intr.mi_disable
293 
294 /* mci_tx_flag */
295 #define	MCI_TX_QUIESCE	0x1
296 
297 typedef struct mac_factory_addr_s {
298 	boolean_t		mfa_in_use;
299 	uint8_t			mfa_addr[MAXMACADDRLEN];
300 	struct mac_client_impl_s	*mfa_client;
301 } mac_factory_addr_t;
302 
303 typedef struct mac_mcast_addrs_s {
304 	struct mac_mcast_addrs_s	*mma_next;
305 	uint8_t				mma_addr[MAXMACADDRLEN];
306 	int				mma_ref;
307 } mac_mcast_addrs_t;
308 
309 typedef enum {
310 	MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED = 1,	/* HW classification */
311 	MAC_ADDRESS_TYPE_UNICAST_PROMISC		/* promiscuous mode */
312 } mac_address_type_t;
313 
314 typedef struct mac_vlan_s {
315 	struct mac_vlan_s	*mv_next;
316 	uint16_t		mv_vid;
317 } mac_vlan_t;
318 
319 typedef struct mac_address_s {
320 	mac_address_type_t	ma_type;		/* address type */
321 	int			ma_nusers;		/* num users of addr */
322 	struct mac_address_s	*ma_next;		/* next address */
323 	uint8_t			ma_addr[MAXMACADDRLEN];	/* address value */
324 	size_t			ma_len;			/* address length */
325 	mac_vlan_t		*ma_vlans;		/* VLANs on this addr */
326 	boolean_t		ma_untagged;		/* accept untagged? */
327 	mac_group_t		*ma_group;		/* asscociated group */
328 	mac_impl_t		*ma_mip;		/* MAC handle */
329 } mac_address_t;
330 
331 extern krwlock_t i_mac_impl_lock;
332 extern mod_hash_t *i_mac_impl_hash;
333 extern kmem_cache_t *i_mac_impl_cachep;
334 extern uint_t i_mac_impl_count;
335 
336 /*
337  * Each registered MAC is associated with a mac_impl_t structure. The
338  * structure represents the undelying hardware, in terms of definition,
339  * resources (transmit, receive rings etc.), callback functions etc. It
340  * also holds the table of MAC clients that are configured on the device.
341  * The table is used for classifying incoming packets in software.
342  *
343  * The protection scheme uses 2 elements, a coarse serialization mechanism
344  * called perimeter and a finer traditional lock based scheme. More details
345  * can be found in the big block comment in mac.c.
346  *
347  * The protection scheme for each member of the mac_impl_t is described below.
348  *
349  * Write Once Only (WO): Typically these don't change for the lifetime of the
350  * data structure. For example something in mac_impl_t that stays the same
351  * from mac_register to mac_unregister, or something in a mac_client_impl_t
352  * that stays the same from mac_client_open to mac_client_close.
353  *
354  * Serializer (SL): Protected by the Serializer. All SLOP operations on a
355  * mac endpoint go through the serializer. MTOPs don't care about reading
356  * these fields atomically.
357  *
358  * Lock: Traditional mutex/rw lock. Modify operations still go through the
359  * mac serializer, the lock helps synchronize readers with writers.
360  */
361 struct mac_impl_s {
362 	krwlock_t		mi_rw_lock;
363 	list_node_t		mi_node;
364 	char			mi_name[LIFNAMSIZ];	/* WO */
365 	uint32_t		mi_state_flags;
366 	void			*mi_driver;		/* Driver private, WO */
367 	mac_info_t		mi_info;		/* WO */
368 	mactype_t		*mi_type;		/* WO */
369 	void			*mi_pdata;		/* WO */
370 	size_t			mi_pdata_size;		/* WO */
371 	mac_callbacks_t		*mi_callbacks;		/* WO */
372 	dev_info_t		*mi_dip;		/* WO */
373 	uint32_t		mi_ref;			/* i_mac_impl_lock */
374 	uint_t			mi_active;		/* SL */
375 	link_state_t		mi_linkstate;		/* none */
376 	link_state_t		mi_lowlinkstate;	/* none */
377 	link_state_t		mi_lastlowlinkstate;	/* none */
378 	uint_t			mi_devpromisc;		/* SL */
379 	uint8_t			mi_addr[MAXMACADDRLEN];	/* mi_rw_lock */
380 	uint8_t			mi_dstaddr[MAXMACADDRLEN]; /* mi_rw_lock */
381 	boolean_t		mi_dstaddr_set;
382 
383 	/*
384 	 * The mac perimeter. All client initiated create/modify operations
385 	 * on a mac end point go through this.
386 	 */
387 	kmutex_t		mi_perim_lock;
388 	kthread_t		*mi_perim_owner;	/* mi_perim_lock */
389 	uint_t			mi_perim_ocnt;		/* mi_perim_lock */
390 	kcondvar_t		mi_perim_cv;		/* mi_perim_lock */
391 
392 	/* mac notification callbacks */
393 	kmutex_t		mi_notify_lock;
394 	mac_cb_info_t		mi_notify_cb_info;	/* mi_notify_lock */
395 	mac_cb_t		*mi_notify_cb_list;	/* mi_notify_lock */
396 	kthread_t		*mi_notify_thread;	/* mi_notify_lock */
397 	uint_t			mi_notify_bits;		/* mi_notify_lock */
398 
399 	uint32_t		mi_v12n_level;		/* Virt'ion readiness */
400 
401 	/*
402 	 * RX groups, ring capability
403 	 * Fields of this block are SL protected.
404 	 */
405 	mac_group_type_t	mi_rx_group_type;	/* grouping type */
406 	uint_t			mi_rx_group_count;
407 	mac_group_t		*mi_rx_groups;
408 	mac_group_t		*mi_rx_donor_grp;
409 	uint_t			mi_rxrings_rsvd;
410 	uint_t			mi_rxrings_avail;
411 	uint_t			mi_rxhwclnt_avail;
412 	uint_t			mi_rxhwclnt_used;
413 
414 	mac_capab_rings_t	mi_rx_rings_cap;
415 
416 	/*
417 	 * TX groups and ring capability, SL Protected.
418 	 */
419 	mac_group_type_t	mi_tx_group_type;	/* grouping type */
420 	uint_t			mi_tx_group_count;
421 	uint_t			mi_tx_group_free;
422 	mac_group_t		*mi_tx_groups;
423 	mac_capab_rings_t	mi_tx_rings_cap;
424 	uint_t			mi_txrings_rsvd;
425 	uint_t			mi_txrings_avail;
426 	uint_t			mi_txhwclnt_avail;
427 	uint_t			mi_txhwclnt_used;
428 
429 	mac_ring_handle_t	mi_default_tx_ring;
430 
431 	/*
432 	 * Transceiver capabilities. SL protected.
433 	 */
434 	mac_capab_transceiver_t	mi_transceiver;
435 
436 	/*
437 	 * LED Capability information. SL protected.
438 	 */
439 	mac_led_mode_t		mi_led_modes;
440 	mac_capab_led_t		mi_led;
441 
442 	/* Cache of the Tx DB_CKSUMFLAGS that this MAC supports. */
443 	uint16_t		mi_tx_cksum_flags; /* SL */
444 
445 	/*
446 	 * MAC address and VLAN lists. SL protected.
447 	 */
448 	mac_address_t		*mi_addresses;
449 
450 	/*
451 	 * This MAC's table of sub-flows
452 	 */
453 	flow_tab_t		*mi_flow_tab;		/* WO */
454 
455 	kstat_t			*mi_ksp;		/* WO */
456 	uint_t			mi_kstat_count;		/* WO */
457 	uint_t			mi_nactiveclients;	/* SL */
458 
459 	/* for broadcast and multicast support */
460 	struct mac_mcast_addrs_s *mi_mcast_addrs;	/* mi_rw_lock */
461 	struct mac_bcast_grp_s *mi_bcast_grp;		/* mi_rw_lock */
462 	uint_t			mi_bcast_ngrps;		/* mi_rw_lock */
463 
464 	/* list of MAC clients which opened this MAC */
465 	struct mac_client_impl_s *mi_clients_list;	/* mi_rw_lock */
466 	uint_t			mi_nclients;		/* mi_rw_lock */
467 	struct mac_client_impl_s *mi_single_active_client; /* mi_rw_lock */
468 
469 	uint32_t		mi_margin;		/* mi_rw_lock */
470 	uint_t			mi_sdu_min;		/* mi_rw_lock */
471 	uint_t			mi_sdu_max;		/* mi_rw_lock */
472 	uint_t			mi_sdu_multicast;	/* mi_rw_lock */
473 
474 	/*
475 	 * Cache of factory MAC addresses provided by the driver. If
476 	 * the driver doesn't provide multiple factory MAC addresses,
477 	 * the mi_factory_addr is set to NULL, and mi_factory_addr_num
478 	 * is set to zero.
479 	 */
480 	mac_factory_addr_t	*mi_factory_addr;	/* mi_rw_lock */
481 	uint_t			mi_factory_addr_num;	/* mi_rw_lock */
482 
483 	/* for promiscuous mode support */
484 	kmutex_t		mi_promisc_lock;
485 	mac_cb_t		*mi_promisc_list;	/* mi_promisc_lock */
486 	mac_cb_info_t		mi_promisc_cb_info;	/* mi_promisc_lock */
487 
488 	/* cache of rings over this mac_impl */
489 	kmutex_t		mi_ring_lock;
490 	mac_ring_t		*mi_ring_freelist;	/* mi_ring_lock */
491 
492 	/*
493 	 * These are used for caching the properties, if any, for the
494 	 * primary MAC client. If the MAC client is not yet in place
495 	 * when the properties are set then we cache them here to be
496 	 * applied to the MAC client when it is created.
497 	 */
498 	mac_resource_props_t	mi_resource_props;	/* SL */
499 	uint16_t		mi_pvid;		/* SL */
500 
501 	minor_t			mi_minor;		/* WO */
502 	uint32_t		mi_oref;		/* SL */
503 	mac_capab_legacy_t	mi_capab_legacy;	/* WO */
504 	dev_t			mi_phy_dev;		/* WO */
505 
506 	/*
507 	 * List of margin value requests added by mac clients. This list is
508 	 * sorted: the first one has the greatest value.
509 	 */
510 	mac_margin_req_t	*mi_mmrp;
511 	mac_mtu_req_t		*mi_mtrp;
512 	char			**mi_priv_prop;
513 	uint_t			mi_priv_prop_count;
514 
515 	/*
516 	 * Hybrid I/O related definitions.
517 	 */
518 	mac_capab_share_t	mi_share_capab;
519 
520 	/*
521 	 * Bridging hooks and limit values.  Uses mutex and reference counts
522 	 * (bridging only) for data path.  Limits need no synchronization.
523 	 */
524 	mac_handle_t		mi_bridge_link;
525 	kmutex_t		mi_bridge_lock;
526 	uint32_t		mi_llimit;
527 	uint32_t		mi_ldecay;
528 
529 /* This should be the last block in this structure */
530 #ifdef DEBUG
531 #define	MAC_PERIM_STACK_DEPTH	15
532 	int			mi_perim_stack_depth;
533 	pc_t			mi_perim_stack[MAC_PERIM_STACK_DEPTH];
534 #endif
535 };
536 
537 /*
538  * The default TX group is the last one in the list.
539  */
540 #define	MAC_DEFAULT_TX_GROUP(mip)	\
541 	(mip)->mi_tx_groups + (mip)->mi_tx_group_count
542 
543 /*
544  * The default RX group is the first one in the list
545  */
546 #define	MAC_DEFAULT_RX_GROUP(mip)	(mip)->mi_rx_groups
547 
548 /* Reserved RX rings */
549 #define	MAC_RX_RING_RESERVED(m, cnt)	{	\
550 	ASSERT((m)->mi_rxrings_avail >= (cnt));	\
551 	(m)->mi_rxrings_rsvd += (cnt);		\
552 	(m)->mi_rxrings_avail -= (cnt);		\
553 }
554 
555 /* Released RX rings */
556 #define	MAC_RX_RING_RELEASED(m, cnt)	{	\
557 	ASSERT((m)->mi_rxrings_rsvd >= (cnt));	\
558 	(m)->mi_rxrings_rsvd -= (cnt);		\
559 	(m)->mi_rxrings_avail += (cnt);		\
560 }
561 
562 /* Reserved a RX group */
563 #define	MAC_RX_GRP_RESERVED(m)	{		\
564 	ASSERT((m)->mi_rxhwclnt_avail > 0);	\
565 	(m)->mi_rxhwclnt_avail--;		\
566 	(m)->mi_rxhwclnt_used++;		\
567 }
568 
569 /* Released a RX group */
570 #define	MAC_RX_GRP_RELEASED(m)	{		\
571 	ASSERT((m)->mi_rxhwclnt_used > 0);	\
572 	(m)->mi_rxhwclnt_avail++;		\
573 	(m)->mi_rxhwclnt_used--;		\
574 }
575 
576 /* Reserved TX rings */
577 #define	MAC_TX_RING_RESERVED(m, cnt)	{	\
578 	ASSERT((m)->mi_txrings_avail >= (cnt));	\
579 	(m)->mi_txrings_rsvd += (cnt);		\
580 	(m)->mi_txrings_avail -= (cnt);		\
581 }
582 /* Released TX rings */
583 #define	MAC_TX_RING_RELEASED(m, cnt)	{	\
584 	ASSERT((m)->mi_txrings_rsvd >= (cnt));	\
585 	(m)->mi_txrings_rsvd -= (cnt);		\
586 	(m)->mi_txrings_avail += (cnt);		\
587 }
588 
589 /* Reserved a TX group */
590 #define	MAC_TX_GRP_RESERVED(m)	{		\
591 	ASSERT((m)->mi_txhwclnt_avail > 0);	\
592 	(m)->mi_txhwclnt_avail--;		\
593 	(m)->mi_txhwclnt_used++;		\
594 }
595 
596 /* Released a TX group */
597 #define	MAC_TX_GRP_RELEASED(m)	{		\
598 	ASSERT((m)->mi_txhwclnt_used > 0);	\
599 	(m)->mi_txhwclnt_avail++;		\
600 	(m)->mi_txhwclnt_used--;		\
601 }
602 
603 /* for mi_state_flags */
604 #define	MIS_DISABLED		0x0001
605 #define	MIS_IS_VNIC		0x0002
606 #define	MIS_IS_AGGR		0x0004
607 #define	MIS_NOTIFY_DONE		0x0008
608 #define	MIS_EXCLUSIVE		0x0010
609 #define	MIS_EXCLUSIVE_HELD	0x0020
610 #define	MIS_LEGACY		0x0040
611 #define	MIS_NO_ACTIVE		0x0080
612 #define	MIS_POLL_DISABLE	0x0100
613 #define	MIS_IS_OVERLAY		0x0200
614 
615 #define	mi_getstat	mi_callbacks->mc_getstat
616 #define	mi_start	mi_callbacks->mc_start
617 #define	mi_stop		mi_callbacks->mc_stop
618 #define	mi_open		mi_callbacks->mc_open
619 #define	mi_close	mi_callbacks->mc_close
620 #define	mi_setpromisc	mi_callbacks->mc_setpromisc
621 #define	mi_multicst	mi_callbacks->mc_multicst
622 #define	mi_unicst	mi_callbacks->mc_unicst
623 #define	mi_tx		mi_callbacks->mc_tx
624 #define	mi_ioctl	mi_callbacks->mc_ioctl
625 #define	mi_getcapab	mi_callbacks->mc_getcapab
626 
627 typedef struct mac_notify_task_arg {
628 	mac_impl_t		*mnt_mip;
629 	mac_notify_type_t	mnt_type;
630 	mac_ring_t		*mnt_ring;
631 } mac_notify_task_arg_t;
632 
633 /*
634  * The mac_perim_handle_t is an opaque type that encodes the 'mip' pointer
635  * and whether internally a mac_open was done when acquiring the perimeter.
636  */
637 #define	MAC_ENCODE_MPH(mph, mh, need_close)		\
638 	(mph) = (mac_perim_handle_t)((uintptr_t)(mh) | need_close)
639 
640 #define	MAC_DECODE_MPH(mph, mip, need_close) {		\
641 	mip = (mac_impl_t *)(((uintptr_t)mph) & ~0x1);	\
642 	(need_close) = ((uintptr_t)mph & 0x1);		\
643 }
644 
645 /*
646  * Type of property information that can be returned by a driver.
647  * Valid flags of the pr_flags of the mac_prop_info_t data structure.
648  */
649 #define	MAC_PROP_INFO_DEFAULT	0x0001
650 #define	MAC_PROP_INFO_RANGE	0x0002
651 #define	MAC_PROP_INFO_PERM	0x0004
652 
653 /*
654  * Property information. pr_flags is a combination of one of the
655  * MAC_PROP_INFO_* flags, it is reset by the framework before invoking
656  * the driver's prefix_propinfo() entry point.
657  *
658  * Drivers should use MAC_PROP_INFO_SET_*() macros to provide
659  * information about a property.
660  */
661 typedef struct mac_prop_info_state_s {
662 	uint8_t			pr_flags;
663 	uint8_t			pr_perm;
664 	uint8_t			pr_errno;
665 	void			*pr_default;
666 	size_t			pr_default_size;
667 	mac_propval_range_t	*pr_range;
668 	uint_t			pr_range_cur_count;
669 } mac_prop_info_state_t;
670 
671 #define	MAC_PROTECT_ENABLED(mcip, type) \
672 	(((mcip)->mci_flent-> \
673 	fe_resource_props.mrp_mask & MRP_PROTECT) != 0 && \
674 	((mcip)->mci_flent-> \
675 	fe_resource_props.mrp_protect.mp_types & (type)) != 0)
676 
677 typedef struct mac_client_impl_s mac_client_impl_t;
678 
679 extern void	mac_init(void);
680 extern int	mac_fini(void);
681 
682 /*
683  * MAC packet/chain drop functions to aggregate all dropped-packet
684  * debugging to a single surface.
685  */
686 /*PRINTFLIKE2*/
687 extern void	mac_drop_pkt(mblk_t *, const char *, ...)
688     __KPRINTFLIKE(2);
689 
690 /*PRINTFLIKE2*/
691 extern void	mac_drop_chain(mblk_t *, const char *, ...)
692     __KPRINTFLIKE(2);
693 
694 extern void	mac_ndd_ioctl(mac_impl_t *, queue_t *, mblk_t *);
695 extern boolean_t mac_ip_hdr_length_v6(ip6_t *, uint8_t *, uint16_t *,
696     uint8_t *, ip6_frag_t **);
697 
698 extern mblk_t *mac_copymsgchain_cksum(mblk_t *);
699 extern void mac_packet_print(mac_handle_t, mblk_t *);
700 extern void mac_rx_deliver(void *, mac_resource_handle_t, mblk_t *,
701     mac_header_info_t *);
702 extern void mac_tx_notify(mac_impl_t *);
703 extern mblk_t *mac_ring_tx(mac_handle_t, mac_ring_handle_t, mblk_t *);
704 extern mblk_t *mac_provider_tx(mac_impl_t *, mac_ring_handle_t, mblk_t *,
705     mac_client_impl_t *);
706 
707 extern void mac_callback_add(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
708 extern boolean_t mac_callback_remove(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
709 extern void mac_callback_remove_wait(mac_cb_info_t *);
710 extern void mac_callback_barrier(mac_cb_info_t *);
711 extern void mac_callback_free(mac_cb_t *);
712 extern void mac_callback_walker_enter(mac_cb_info_t *);
713 extern void mac_callback_walker_exit(mac_cb_info_t *, mac_cb_t **, boolean_t);
714 
715 /* in mac_bcast.c */
716 extern void mac_bcast_init(void);
717 extern void mac_bcast_fini(void);
718 extern mac_impl_t *mac_bcast_grp_mip(void *);
719 extern int mac_bcast_add(mac_client_impl_t *, const uint8_t *, uint16_t,
720     mac_addrtype_t);
721 extern void mac_bcast_delete(mac_client_impl_t *, const uint8_t *, uint16_t);
722 extern void mac_bcast_send(void *, void *, mblk_t *, boolean_t);
723 extern void mac_bcast_grp_free(void *);
724 extern void mac_bcast_refresh(mac_impl_t *, mac_multicst_t, void *,
725     boolean_t);
726 extern void mac_client_bcast_refresh(mac_client_impl_t *, mac_multicst_t,
727     void *, boolean_t);
728 
729 /*
730  * Grouping functions are used internally by MAC layer.
731  */
732 extern int mac_group_addmac(mac_group_t *, const uint8_t *);
733 extern int mac_group_remmac(mac_group_t *, const uint8_t *);
734 extern int mac_group_addvlan(mac_group_t *, uint16_t);
735 extern int mac_group_remvlan(mac_group_t *, uint16_t);
736 extern int mac_rx_group_add_flow(mac_client_impl_t *, flow_entry_t *,
737     mac_group_t *);
738 extern mblk_t *mac_hwring_tx(mac_ring_handle_t, mblk_t *);
739 extern mblk_t *mac_bridge_tx(mac_impl_t *, mac_ring_handle_t, mblk_t *);
740 extern mac_group_t *mac_reserve_rx_group(mac_client_impl_t *, uint8_t *,
741     boolean_t);
742 extern void mac_release_rx_group(mac_client_impl_t *, mac_group_t *);
743 extern int mac_rx_switch_group(mac_client_impl_t *, mac_group_t *,
744     mac_group_t *);
745 extern mac_ring_t *mac_reserve_tx_ring(mac_impl_t *, mac_ring_t *);
746 extern mac_group_t *mac_reserve_tx_group(mac_client_impl_t *, boolean_t);
747 extern void mac_release_tx_group(mac_client_impl_t *, mac_group_t *);
748 extern void mac_tx_switch_group(mac_client_impl_t *, mac_group_t *,
749     mac_group_t *);
750 extern void mac_rx_switch_grp_to_sw(mac_group_t *);
751 
752 /*
753  * MAC address functions are used internally by MAC layer.
754  */
755 extern mac_address_t *mac_find_macaddr(mac_impl_t *, uint8_t *);
756 extern mac_address_t *mac_find_macaddr_vlan(mac_impl_t *, uint8_t *, uint16_t);
757 extern boolean_t mac_check_macaddr_shared(mac_address_t *);
758 extern int mac_update_macaddr(mac_address_t *, uint8_t *);
759 extern void mac_freshen_macaddr(mac_address_t *, uint8_t *);
760 extern void mac_retrieve_macaddr(mac_address_t *, uint8_t *);
761 extern void mac_init_macaddr(mac_impl_t *);
762 extern void mac_fini_macaddr(mac_impl_t *);
763 
764 /*
765  * Flow construction/destruction routines.
766  * Not meant to be used by mac clients.
767  */
768 extern int mac_link_flow_init(mac_client_handle_t, flow_entry_t *);
769 extern void mac_link_flow_clean(mac_client_handle_t, flow_entry_t *);
770 
771 /*
772  * Fanout update routines called when the link speed of the NIC changes
773  * or when a MAC client's share is unbound.
774  */
775 extern void mac_fanout_recompute_client(mac_client_impl_t *, cpupart_t *);
776 extern void mac_fanout_recompute(mac_impl_t *);
777 
778 /*
779  * The following functions are used internally by the MAC layer to
780  * add/remove/update flows associated with a mac_impl_t. They should
781  * never be used directly by MAC clients.
782  */
783 extern int mac_datapath_setup(mac_client_impl_t *, flow_entry_t *, uint32_t);
784 extern void mac_datapath_teardown(mac_client_impl_t *, flow_entry_t *,
785     uint32_t);
786 extern void mac_rx_srs_group_setup(mac_client_impl_t *, flow_entry_t *,
787     uint32_t);
788 extern void mac_tx_srs_group_setup(mac_client_impl_t *, flow_entry_t *,
789     uint32_t);
790 extern void mac_rx_srs_group_teardown(flow_entry_t *, boolean_t);
791 extern void mac_tx_srs_group_teardown(mac_client_impl_t *, flow_entry_t *,
792 	    uint32_t);
793 extern int mac_rx_classify_flow_quiesce(flow_entry_t *, void *);
794 extern int mac_rx_classify_flow_restart(flow_entry_t *, void *);
795 extern void mac_client_quiesce(mac_client_impl_t *);
796 extern void mac_client_restart(mac_client_impl_t *);
797 
798 extern void mac_flow_update_priority(mac_client_impl_t *, flow_entry_t *);
799 
800 extern void mac_flow_rem_subflow(flow_entry_t *);
801 extern void mac_rename_flow(flow_entry_t *, const char *);
802 extern void mac_flow_set_name(flow_entry_t *, const char *);
803 
804 extern mblk_t *mac_add_vlan_tag(mblk_t *, uint_t, uint16_t);
805 extern mblk_t *mac_add_vlan_tag_chain(mblk_t *, uint_t, uint16_t);
806 extern mblk_t *mac_strip_vlan_tag_chain(mblk_t *);
807 extern void mac_rx_def(void *, mac_resource_handle_t, mblk_t *, boolean_t);
808 extern mblk_t *mac_rx_flow(mac_handle_t, mac_resource_handle_t, mblk_t *);
809 
810 extern void i_mac_share_alloc(mac_client_impl_t *);
811 extern void i_mac_share_free(mac_client_impl_t *);
812 extern void i_mac_perim_enter(mac_impl_t *);
813 extern void i_mac_perim_exit(mac_impl_t *);
814 extern int i_mac_perim_enter_nowait(mac_impl_t *);
815 extern void i_mac_tx_srs_notify(mac_impl_t *, mac_ring_handle_t);
816 extern int mac_hold(const char *, mac_impl_t **);
817 extern void mac_rele(mac_impl_t *);
818 extern int i_mac_disable(mac_impl_t *);
819 extern void i_mac_notify(mac_impl_t *, mac_notify_type_t);
820 extern void i_mac_notify_exit(mac_impl_t *);
821 extern void mac_rx_group_unmark(mac_group_t *, uint_t);
822 extern void mac_tx_client_flush(mac_client_impl_t *);
823 extern void mac_tx_client_block(mac_client_impl_t *);
824 extern void mac_tx_client_unblock(mac_client_impl_t *);
825 extern void mac_tx_invoke_callbacks(mac_client_impl_t *, mac_tx_cookie_t);
826 extern int i_mac_promisc_set(mac_impl_t *, boolean_t);
827 extern mactype_t *mactype_getplugin(const char *);
828 extern void mac_addr_factory_init(mac_impl_t *);
829 extern void mac_addr_factory_fini(mac_impl_t *);
830 extern void mac_register_priv_prop(mac_impl_t *, char **);
831 extern void mac_unregister_priv_prop(mac_impl_t *);
832 extern int mac_init_rings(mac_impl_t *, mac_ring_type_t);
833 extern void mac_free_rings(mac_impl_t *, mac_ring_type_t);
834 extern void mac_compare_ddi_handle(mac_group_t *, uint_t, mac_ring_t *);
835 
836 extern int mac_start_group(mac_group_t *);
837 extern void mac_stop_group(mac_group_t *);
838 extern int mac_start_ring(mac_ring_t *);
839 extern void mac_stop_ring(mac_ring_t *);
840 extern int mac_add_macaddr_vlan(mac_impl_t *, mac_group_t *, uint8_t *,
841     uint16_t, boolean_t);
842 extern int mac_remove_macaddr_vlan(mac_address_t *, uint16_t);
843 
844 extern void mac_set_group_state(mac_group_t *, mac_group_state_t);
845 extern void mac_group_add_client(mac_group_t *, mac_client_impl_t *);
846 extern void mac_group_remove_client(mac_group_t *, mac_client_impl_t *);
847 
848 extern int i_mac_group_add_ring(mac_group_t *, mac_ring_t *, int);
849 extern void i_mac_group_rem_ring(mac_group_t *, mac_ring_t *, boolean_t);
850 extern int mac_group_ring_modify(mac_client_impl_t *, mac_group_t *,
851     mac_group_t *);
852 extern void mac_poll_state_change(mac_handle_t, boolean_t);
853 
854 extern mac_group_state_t mac_group_next_state(mac_group_t *,
855     mac_client_impl_t **, mac_group_t *, boolean_t);
856 
857 extern mblk_t *mac_protect_check(mac_client_handle_t, mblk_t *);
858 extern int mac_protect_set(mac_client_handle_t, mac_resource_props_t *);
859 extern boolean_t mac_protect_enabled(mac_client_handle_t, uint32_t);
860 extern int mac_protect_validate(mac_resource_props_t *);
861 extern void mac_protect_update(mac_resource_props_t *, mac_resource_props_t *);
862 extern void mac_protect_update_mac_token(mac_client_impl_t *);
863 extern void mac_protect_intercept_dynamic(mac_client_impl_t *, mblk_t *);
864 extern void mac_protect_flush_dynamic(mac_client_impl_t *);
865 extern void mac_protect_cancel_timer(mac_client_impl_t *);
866 extern void mac_protect_init(mac_client_impl_t *);
867 extern void mac_protect_fini(mac_client_impl_t *);
868 
869 extern int mac_set_resources(mac_handle_t, mac_resource_props_t *);
870 extern void mac_get_resources(mac_handle_t, mac_resource_props_t *);
871 extern void mac_get_effective_resources(mac_handle_t, mac_resource_props_t *);
872 extern void mac_set_promisc_filtered(mac_client_handle_t, boolean_t);
873 extern boolean_t mac_get_promisc_filtered(mac_client_handle_t);
874 
875 extern cpupart_t *mac_pset_find(mac_resource_props_t *, boolean_t *);
876 extern void mac_set_pool_effective(boolean_t, cpupart_t *,
877     mac_resource_props_t *, mac_resource_props_t *);
878 extern void mac_set_rings_effective(mac_client_impl_t *);
879 extern mac_client_impl_t *mac_check_primary_relocation(mac_client_impl_t *,
880     boolean_t);
881 
882 /* Global callbacks into the bridging module (when loaded) */
883 extern mac_bridge_tx_t mac_bridge_tx_cb;
884 extern mac_bridge_rx_t mac_bridge_rx_cb;
885 extern mac_bridge_ref_t mac_bridge_ref_cb;
886 extern mac_bridge_ls_t mac_bridge_ls_cb;
887 
888 /*
889  * MAC Transceiver related functions
890  */
891 struct mac_transceiver_info {
892 	boolean_t		mti_present;
893 	boolean_t		mti_usable;
894 };
895 
896 extern void mac_transceiver_init(mac_impl_t *);
897 extern int mac_transceiver_count(mac_handle_t, uint_t *);
898 extern int mac_transceiver_info(mac_handle_t, uint_t, boolean_t *, boolean_t *);
899 extern int mac_transceiver_read(mac_handle_t, uint_t, uint_t, void *, size_t,
900     off_t, size_t *);
901 
902 /*
903  * MAC LED related functions
904  */
905 #define	MAC_LED_ALL	(MAC_LED_DEFAULT | MAC_LED_OFF | MAC_LED_IDENT | \
906 			    MAC_LED_ON)
907 extern void mac_led_init(mac_impl_t *);
908 extern int mac_led_get(mac_handle_t, mac_led_mode_t *, mac_led_mode_t *);
909 extern int mac_led_set(mac_handle_t, mac_led_mode_t);
910 
911 typedef struct mac_direct_rxs_s {
912 	mac_direct_rx_t	mdrx_v4;
913 	mac_direct_rx_t	mdrx_v6;
914 	void		*mdrx_arg_v4;
915 	void		*mdrx_arg_v6;
916 } mac_direct_rxs_t;
917 
918 #ifdef	__cplusplus
919 }
920 #endif
921 
922 #endif	/* _SYS_MAC_IMPL_H */
923