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