xref: /titanic_44/usr/src/uts/common/sys/mac_impl.h (revision 4d21059036851b1ba8fa33650d3167e890333d39)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5490ed22dSyz147064  * Common Development and Distribution License (the "License").
6490ed22dSyz147064  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
220591ddd0SPrakash Jalan  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
2348a4016cSRobert Mustacchi  * Copyright (c) 2017, Joyent, Inc.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #ifndef	_SYS_MAC_IMPL_H
277c478bd9Sstevel@tonic-gate #define	_SYS_MAC_IMPL_H
287c478bd9Sstevel@tonic-gate 
290dc2366fSVenugopal Iyer #include <sys/cpupart.h>
30da14cebeSEric Cheng #include <sys/modhash.h>
31da14cebeSEric Cheng #include <sys/mac_client.h>
32da14cebeSEric Cheng #include <sys/mac_provider.h>
334eaa4710SRishi Srivatsavai #include <sys/note.h>
340dc2366fSVenugopal Iyer #include <sys/avl.h>
35ba2e4443Sseb #include <net/if.h>
36da14cebeSEric Cheng #include <sys/mac_flow_impl.h>
37da14cebeSEric Cheng #include <netinet/ip6.h>
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
407c478bd9Sstevel@tonic-gate extern "C" {
417c478bd9Sstevel@tonic-gate #endif
427c478bd9Sstevel@tonic-gate 
4361af1958SGarrett D'Amore /*
4461af1958SGarrett D'Amore  * This is the first minor number available for MAC provider private
4561af1958SGarrett D'Amore  * use.  This makes it possible to deliver a driver that is both a MAC
4661af1958SGarrett D'Amore  * provider and a regular character/block device.  See PSARC 2009/380
4761af1958SGarrett D'Amore  * for more detail about the construction of such devices.  The value
4861af1958SGarrett D'Amore  * chosen leaves half of the 32-bit minor numbers (which are really
4961af1958SGarrett D'Amore  * only 18 bits wide) available for driver private use.  Drivers can
5061af1958SGarrett D'Amore  * easily identify their private number by the presence of this value
5161af1958SGarrett D'Amore  * in the bits that make up the minor number, since its just the
5261af1958SGarrett D'Amore  * highest bit available for such minor numbers.
5361af1958SGarrett D'Amore  */
5461af1958SGarrett D'Amore #define	MAC_PRIVATE_MINOR		((MAXMIN32 + 1) / 2)
5561af1958SGarrett D'Amore 
5661af1958SGarrett D'Amore /*
5761af1958SGarrett D'Amore  * The maximum minor number that corresponds to a real instance.  This
5861af1958SGarrett D'Amore  * limits the number of physical ports that a mac provider can offer.
5961af1958SGarrett D'Amore  * Note that this macro must be synchronized with DLS_MAX_MINOR in
6061af1958SGarrett D'Amore  * <sys/dls.h>
6161af1958SGarrett D'Amore  */
6261af1958SGarrett D'Amore #define	MAC_MAX_MINOR			1000
6361af1958SGarrett D'Amore 
64d62bc4baSyz147064 typedef struct mac_margin_req_s	mac_margin_req_t;
65d62bc4baSyz147064 
66d62bc4baSyz147064 struct mac_margin_req_s {
67d62bc4baSyz147064 	mac_margin_req_t	*mmr_nextp;
68d62bc4baSyz147064 	uint_t			mmr_ref;
69d62bc4baSyz147064 	uint32_t		mmr_margin;
70d62bc4baSyz147064 };
71d62bc4baSyz147064 
72a776d98eSRobert Mustacchi typedef struct mac_mtu_req_s mac_mtu_req_t;
73a776d98eSRobert Mustacchi struct mac_mtu_req_s {
74a776d98eSRobert Mustacchi 	mac_mtu_req_t		*mtr_nextp;
75a776d98eSRobert Mustacchi 	uint_t			mtr_ref;
76a776d98eSRobert Mustacchi 	uint32_t		mtr_mtu;
77a776d98eSRobert Mustacchi };
78a776d98eSRobert Mustacchi 
79da14cebeSEric Cheng /* Generic linked chain type */
80da14cebeSEric Cheng typedef	struct mac_chain_s {
81da14cebeSEric Cheng 	struct mac_chain_s	*next;
82da14cebeSEric Cheng 	void			*item;
83da14cebeSEric Cheng } mac_chain_t;
847c478bd9Sstevel@tonic-gate 
85da14cebeSEric Cheng /*
86da14cebeSEric Cheng  * Generic mac callback list manipulation structures and macros. The mac_cb_t
87da14cebeSEric Cheng  * represents a general callback list element embedded in a particular
88da14cebeSEric Cheng  * data structure such as a mac_notify_cb_t or a mac_promisc_impl_t.
89da14cebeSEric Cheng  * The mac_cb_info_t represents general information about list walkers.
90da14cebeSEric Cheng  * Please see the comments above mac_callback_add for more information.
91da14cebeSEric Cheng  */
92da14cebeSEric Cheng /* mcb_flags */
93da14cebeSEric Cheng #define	MCB_CONDEMNED		0x1		/* Logically deleted */
94da14cebeSEric Cheng #define	MCB_NOTIFY_CB_T		0x2
95da14cebeSEric Cheng #define	MCB_TX_NOTIFY_CB_T	0x4
967c478bd9Sstevel@tonic-gate 
970dc2366fSVenugopal Iyer extern boolean_t	mac_tx_serialize;
980dc2366fSVenugopal Iyer 
99da14cebeSEric Cheng typedef struct mac_cb_s {
100da14cebeSEric Cheng 	struct mac_cb_s		*mcb_nextp;	/* Linked list of callbacks */
101da14cebeSEric Cheng 	void			*mcb_objp;	/* Ptr to enclosing object  */
102da14cebeSEric Cheng 	size_t			mcb_objsize;	/* Sizeof the enclosing obj */
103da14cebeSEric Cheng 	uint_t			mcb_flags;
104da14cebeSEric Cheng } mac_cb_t;
1057c478bd9Sstevel@tonic-gate 
106da14cebeSEric Cheng typedef struct mac_cb_info_s {
107da14cebeSEric Cheng 	kmutex_t	*mcbi_lockp;
108da14cebeSEric Cheng 	kcondvar_t	mcbi_cv;
109da14cebeSEric Cheng 	uint_t		mcbi_del_cnt;		/* Deleted callback cnt */
110da14cebeSEric Cheng 	uint_t		mcbi_walker_cnt;	/* List walker count */
111da14cebeSEric Cheng } mac_cb_info_t;
1127c478bd9Sstevel@tonic-gate 
113da14cebeSEric Cheng typedef struct mac_notify_cb_s {
114da14cebeSEric Cheng 	mac_cb_t	mncb_link;		/* Linked list of callbacks */
115da14cebeSEric Cheng 	mac_notify_t	mncb_fn;		/* callback function */
116da14cebeSEric Cheng 	void		*mncb_arg;		/* callback argument */
117da14cebeSEric Cheng 	struct mac_impl_s *mncb_mip;
118da14cebeSEric Cheng } mac_notify_cb_t;
1197c478bd9Sstevel@tonic-gate 
120da14cebeSEric Cheng /*
121da14cebeSEric Cheng  * mac_callback_add(listinfo, listhead, listelement)
122da14cebeSEric Cheng  * mac_callback_remove(listinfo, listhead, listelement)
123da14cebeSEric Cheng  */
124da14cebeSEric Cheng typedef boolean_t (*mcb_func_t)(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
125da14cebeSEric Cheng 
126da14cebeSEric Cheng #define	MAC_CALLBACK_WALKER_INC(mcbi) {				\
127da14cebeSEric Cheng 	mutex_enter((mcbi)->mcbi_lockp);			\
128da14cebeSEric Cheng 	(mcbi)->mcbi_walker_cnt++;				\
129da14cebeSEric Cheng 	mutex_exit((mcbi)->mcbi_lockp);				\
130da14cebeSEric Cheng }
131da14cebeSEric Cheng 
132da14cebeSEric Cheng #define	MAC_CALLBACK_WALKER_INC_HELD(mcbi)	(mcbi)->mcbi_walker_cnt++;
133da14cebeSEric Cheng 
134da14cebeSEric Cheng #define	MAC_CALLBACK_WALKER_DCR(mcbi, headp) {			\
135da14cebeSEric Cheng 	mac_cb_t	*rmlist;				\
136da14cebeSEric Cheng 								\
137da14cebeSEric Cheng 	mutex_enter((mcbi)->mcbi_lockp);			\
138da14cebeSEric Cheng 	if (--(mcbi)->mcbi_walker_cnt == 0 && (mcbi)->mcbi_del_cnt != 0) { \
139da14cebeSEric Cheng 		rmlist = mac_callback_walker_cleanup((mcbi), headp);	\
140da14cebeSEric Cheng 		mac_callback_free(rmlist);			\
141da14cebeSEric Cheng 		cv_broadcast(&(mcbi)->mcbi_cv);			\
142da14cebeSEric Cheng 	}							\
143da14cebeSEric Cheng 	mutex_exit((mcbi)->mcbi_lockp);				\
144da14cebeSEric Cheng }
145da14cebeSEric Cheng 
146da14cebeSEric Cheng #define	MAC_PROMISC_WALKER_INC(mip)				\
147da14cebeSEric Cheng 	MAC_CALLBACK_WALKER_INC(&(mip)->mi_promisc_cb_info)
148da14cebeSEric Cheng 
149da14cebeSEric Cheng #define	MAC_PROMISC_WALKER_DCR(mip) {				\
150da14cebeSEric Cheng 	mac_cb_info_t	*mcbi;					\
151da14cebeSEric Cheng 								\
152da14cebeSEric Cheng 	mcbi = &(mip)->mi_promisc_cb_info;			\
153da14cebeSEric Cheng 	mutex_enter(mcbi->mcbi_lockp);				\
154da14cebeSEric Cheng 	if (--mcbi->mcbi_walker_cnt == 0 && mcbi->mcbi_del_cnt != 0) { \
155da14cebeSEric Cheng 		i_mac_promisc_walker_cleanup(mip);		\
156da14cebeSEric Cheng 		cv_broadcast(&mcbi->mcbi_cv);			\
157da14cebeSEric Cheng 	}							\
158da14cebeSEric Cheng 	mutex_exit(mcbi->mcbi_lockp);				\
159da14cebeSEric Cheng }
1607c478bd9Sstevel@tonic-gate 
161ba2e4443Sseb typedef struct mactype_s {
162ba2e4443Sseb 	const char	*mt_ident;
163ba2e4443Sseb 	uint32_t	mt_ref;
164ba2e4443Sseb 	uint_t		mt_type;
1650ba2cbe9Sxc151355 	uint_t		mt_nativetype;
166ba2e4443Sseb 	size_t		mt_addr_length;
167ba2e4443Sseb 	uint8_t		*mt_brdcst_addr;
168ba2e4443Sseb 	mactype_ops_t	mt_ops;
169ba2e4443Sseb 	mac_stat_info_t	*mt_stats;	/* array of mac_stat_info_t elements */
170ba2e4443Sseb 	size_t		mt_statcount;	/* number of elements in mt_stats */
1714045d941Ssowmini 	mac_ndd_mapping_t *mt_mapping;
1724045d941Ssowmini 	size_t		mt_mappingcount;
173ba2e4443Sseb } mactype_t;
1747c478bd9Sstevel@tonic-gate 
175da14cebeSEric Cheng /*
176da14cebeSEric Cheng  * Multiple rings implementation.
177da14cebeSEric Cheng  */
178da14cebeSEric Cheng typedef	enum {
179da14cebeSEric Cheng 	MAC_GROUP_STATE_UNINIT	= 0,	/* initial state of data structure */
180da14cebeSEric Cheng 	MAC_GROUP_STATE_REGISTERED,	/* hooked with h/w group */
181da14cebeSEric Cheng 	MAC_GROUP_STATE_RESERVED,	/* group is reserved and opened */
182da14cebeSEric Cheng 	MAC_GROUP_STATE_SHARED		/* default group shared among */
183da14cebeSEric Cheng 					/* multiple mac clients */
184da14cebeSEric Cheng } mac_group_state_t;
185843e1988Sjohnlev 
186da14cebeSEric Cheng typedef	struct mac_ring_s mac_ring_t;
187da14cebeSEric Cheng typedef	struct mac_group_s mac_group_t;
1884045d941Ssowmini 
189ba2e4443Sseb /*
190da14cebeSEric Cheng  * Ring data structure for ring control and management.
191ba2e4443Sseb  */
192da14cebeSEric Cheng typedef enum {
193da14cebeSEric Cheng 	MR_FREE,		/* Available for assignment to flows */
194da14cebeSEric Cheng 	MR_NEWLY_ADDED,		/* Just assigned to another group */
195da14cebeSEric Cheng 	MR_INUSE		/* Assigned to an SRS */
196da14cebeSEric Cheng } mac_ring_state_t;
197da14cebeSEric Cheng 
198da14cebeSEric Cheng /* mr_flag values */
199da14cebeSEric Cheng #define	MR_INCIPIENT	0x1
200da14cebeSEric Cheng #define	MR_CONDEMNED	0x2
201da14cebeSEric Cheng #define	MR_QUIESCE	0x4
202da14cebeSEric Cheng 
2030dc2366fSVenugopal Iyer typedef struct mac_impl_s mac_impl_t;
2040dc2366fSVenugopal Iyer 
205da14cebeSEric Cheng struct mac_ring_s {
206da14cebeSEric Cheng 	int			mr_index;	/* index in the original list */
207da14cebeSEric Cheng 	mac_ring_type_t		mr_type;	/* ring type */
208da14cebeSEric Cheng 	mac_ring_t		*mr_next;	/* next ring in the chain */
209da14cebeSEric Cheng 	mac_group_handle_t	mr_gh;		/* reference to group */
210da14cebeSEric Cheng 
211da14cebeSEric Cheng 	mac_classify_type_t	mr_classify_type;	/* HW vs SW */
212da14cebeSEric Cheng 	struct mac_soft_ring_set_s *mr_srs;	/* associated SRS */
2130dc2366fSVenugopal Iyer 	mac_ring_handle_t	mr_prh;		/* associated pseudo ring hdl */
214da14cebeSEric Cheng 	uint_t			mr_refcnt;	/* Ring references */
215da14cebeSEric Cheng 	/* ring generation no. to guard against drivers using stale rings */
216da14cebeSEric Cheng 	uint64_t		mr_gen_num;
217da14cebeSEric Cheng 
2180dc2366fSVenugopal Iyer 	kstat_t			*mr_ksp;	/* ring kstats */
2190dc2366fSVenugopal Iyer 	mac_impl_t		*mr_mip;	/* pointer to primary's mip */
2200dc2366fSVenugopal Iyer 
221da14cebeSEric Cheng 	kmutex_t		mr_lock;
222da14cebeSEric Cheng 	kcondvar_t		mr_cv;			/* mr_lock */
223da14cebeSEric Cheng 	mac_ring_state_t	mr_state;		/* mr_lock */
224da14cebeSEric Cheng 	uint_t			mr_flag;		/* mr_lock */
225da14cebeSEric Cheng 
226da14cebeSEric Cheng 	mac_ring_info_t		mr_info;	/* driver supplied info */
227da14cebeSEric Cheng };
228da14cebeSEric Cheng #define	mr_driver		mr_info.mri_driver
229da14cebeSEric Cheng #define	mr_start		mr_info.mri_start
230da14cebeSEric Cheng #define	mr_stop			mr_info.mri_stop
2310dc2366fSVenugopal Iyer #define	mr_stat			mr_info.mri_stat
232da14cebeSEric Cheng 
233da14cebeSEric Cheng #define	MAC_RING_MARK(mr, flag)		\
234da14cebeSEric Cheng 	(mr)->mr_flag |= flag;
235da14cebeSEric Cheng 
236da14cebeSEric Cheng #define	MAC_RING_UNMARK(mr, flag)	\
237da14cebeSEric Cheng 	(mr)->mr_flag &= ~flag;
238da14cebeSEric Cheng 
239d62bc4baSyz147064 /*
240da14cebeSEric Cheng  * Reference hold and release on mac_ring_t 'mr'
241d62bc4baSyz147064  */
242da14cebeSEric Cheng #define	MR_REFHOLD_LOCKED(mr)		{		\
243da14cebeSEric Cheng 	ASSERT(MUTEX_HELD(&mr->mr_lock));		\
244da14cebeSEric Cheng 	(mr)->mr_refcnt++;				\
245da14cebeSEric Cheng }
246d62bc4baSyz147064 
247da14cebeSEric Cheng #define	MR_REFRELE(mr)		{	 		\
248da14cebeSEric Cheng 	mutex_enter(&(mr)->mr_lock);			\
249da14cebeSEric Cheng 	ASSERT((mr)->mr_refcnt != 0);			\
250da14cebeSEric Cheng 	(mr)->mr_refcnt--;				\
251da14cebeSEric Cheng 	if ((mr)->mr_refcnt == 0 &&			\
252da14cebeSEric Cheng 	    ((mr)->mr_flag & (MR_CONDEMNED | MR_QUIESCE))) \
253da14cebeSEric Cheng 		cv_signal(&(mr)->mr_cv);		\
254da14cebeSEric Cheng 	mutex_exit(&(mr)->mr_lock);			\
255da14cebeSEric Cheng }
256d62bc4baSyz147064 
257da14cebeSEric Cheng /*
258da14cebeSEric Cheng  * Per mac client flow information associated with a RX group.
259da14cebeSEric Cheng  * The entire structure is SL protected.
260da14cebeSEric Cheng  */
261da14cebeSEric Cheng typedef struct mac_grp_client {
262da14cebeSEric Cheng 	struct mac_grp_client		*mgc_next;
263da14cebeSEric Cheng 	struct mac_client_impl_s	*mgc_client;
264da14cebeSEric Cheng } mac_grp_client_t;
265d62bc4baSyz147064 
2660dc2366fSVenugopal Iyer #define	MAC_GROUP_NO_CLIENT(g)	((g)->mrg_clients == NULL)
267d62bc4baSyz147064 
2680dc2366fSVenugopal Iyer #define	MAC_GROUP_ONLY_CLIENT(g)			\
269da14cebeSEric Cheng 	((((g)->mrg_clients != NULL) &&			\
270da14cebeSEric Cheng 	((g)->mrg_clients->mgc_next == NULL)) ?		\
271da14cebeSEric Cheng 	(g)->mrg_clients->mgc_client : NULL)
272d62bc4baSyz147064 
273da14cebeSEric Cheng /*
274da14cebeSEric Cheng  * Common ring group data structure for ring control and management.
275da14cebeSEric Cheng  * The entire structure is SL protected
276da14cebeSEric Cheng  */
277da14cebeSEric Cheng struct mac_group_s {
278da14cebeSEric Cheng 	int			mrg_index;	/* index in the list */
279da14cebeSEric Cheng 	mac_ring_type_t		mrg_type;	/* ring type */
280da14cebeSEric Cheng 	mac_group_state_t	mrg_state;	/* state of the group */
281da14cebeSEric Cheng 	mac_group_t		*mrg_next;	/* next ring in the chain */
282da14cebeSEric Cheng 	mac_handle_t		mrg_mh;		/* reference to MAC */
283da14cebeSEric Cheng 	mac_ring_t		*mrg_rings;	/* grouped rings */
284da14cebeSEric Cheng 	uint_t			mrg_cur_count;	/* actual size of group */
285d62bc4baSyz147064 
286da14cebeSEric Cheng 	mac_grp_client_t	*mrg_clients;	/* clients list */
287d62bc4baSyz147064 
288da14cebeSEric Cheng 	mac_group_info_t	mrg_info;	/* driver supplied info */
289da14cebeSEric Cheng };
290d62bc4baSyz147064 
291da14cebeSEric Cheng #define	mrg_driver		mrg_info.mgi_driver
292da14cebeSEric Cheng #define	mrg_start		mrg_info.mgi_start
293da14cebeSEric Cheng #define	mrg_stop		mrg_info.mgi_stop
294da14cebeSEric Cheng 
295da14cebeSEric Cheng #define	GROUP_INTR_HANDLE(g)		(g)->mrg_info.mgi_intr.mi_handle
296da14cebeSEric Cheng #define	GROUP_INTR_ENABLE_FUNC(g)	(g)->mrg_info.mgi_intr.mi_enable
297da14cebeSEric Cheng #define	GROUP_INTR_DISABLE_FUNC(g)	(g)->mrg_info.mgi_intr.mi_disable
298da14cebeSEric Cheng 
2994eaa4710SRishi Srivatsavai #define	MAC_RING_TX(mhp, rh, mp, rest) {				\
3004eaa4710SRishi Srivatsavai 	mac_ring_handle_t mrh = rh;					\
3014eaa4710SRishi Srivatsavai 	mac_impl_t *mimpl = (mac_impl_t *)mhp;				\
302da14cebeSEric Cheng 	/*								\
3034eaa4710SRishi Srivatsavai 	 * Send packets through a selected tx ring, or through the 	\
3044eaa4710SRishi Srivatsavai 	 * default handler if there is no selected ring.		\
305da14cebeSEric Cheng 	 */								\
3064eaa4710SRishi Srivatsavai 	if (mrh == NULL)						\
3074eaa4710SRishi Srivatsavai 		mrh = mimpl->mi_default_tx_ring;			\
3084eaa4710SRishi Srivatsavai 	if (mrh == NULL) {						\
3094eaa4710SRishi Srivatsavai 		rest = mimpl->mi_tx(mimpl->mi_driver, mp);		\
3104eaa4710SRishi Srivatsavai 	} else {							\
3114eaa4710SRishi Srivatsavai 		rest = mac_hwring_tx(mrh, mp);				\
3124eaa4710SRishi Srivatsavai 	}								\
3134eaa4710SRishi Srivatsavai }
3144eaa4710SRishi Srivatsavai 
3154eaa4710SRishi Srivatsavai /*
3164eaa4710SRishi Srivatsavai  * This is the final stop before reaching the underlying driver
3174eaa4710SRishi Srivatsavai  * or aggregation, so this is where the bridging hook is implemented.
3184eaa4710SRishi Srivatsavai  * Packets that are bridged will return through mac_bridge_tx(), with
3194eaa4710SRishi Srivatsavai  * rh nulled out if the bridge chooses to send output on a different
3204eaa4710SRishi Srivatsavai  * link due to forwarding.
3214eaa4710SRishi Srivatsavai  */
3220dc2366fSVenugopal Iyer #define	MAC_TX(mip, rh, mp, src_mcip) {					\
3230dc2366fSVenugopal Iyer 	mac_ring_handle_t	rhandle = (rh);				\
3244eaa4710SRishi Srivatsavai 	/*								\
3254eaa4710SRishi Srivatsavai 	 * If there is a bound Hybrid I/O share, send packets through 	\
3264eaa4710SRishi Srivatsavai 	 * the default tx ring. (When there's a bound Hybrid I/O share,	\
3274eaa4710SRishi Srivatsavai 	 * the tx rings of this client are mapped in the guest domain 	\
3284eaa4710SRishi Srivatsavai 	 * and not accessible from here.)				\
3294eaa4710SRishi Srivatsavai 	 */								\
3304eaa4710SRishi Srivatsavai 	_NOTE(CONSTANTCONDITION)					\
3310dc2366fSVenugopal Iyer 	if ((src_mcip)->mci_state_flags & MCIS_SHARE_BOUND)		\
3320dc2366fSVenugopal Iyer 		rhandle = (mip)->mi_default_tx_ring;			\
3330dc2366fSVenugopal Iyer 	if (mip->mi_promisc_list != NULL)				\
3340dc2366fSVenugopal Iyer 		mac_promisc_dispatch(mip, mp, src_mcip);		\
3354eaa4710SRishi Srivatsavai 	/*								\
3364eaa4710SRishi Srivatsavai 	 * Grab the proper transmit pointer and handle. Special 	\
3374eaa4710SRishi Srivatsavai 	 * optimization: we can test mi_bridge_link itself atomically,	\
3384eaa4710SRishi Srivatsavai 	 * and if that indicates no bridge send packets through tx ring.\
3394eaa4710SRishi Srivatsavai 	 */								\
3404eaa4710SRishi Srivatsavai 	if (mip->mi_bridge_link == NULL) {				\
3410dc2366fSVenugopal Iyer 		MAC_RING_TX(mip, rhandle, mp, mp);			\
3424eaa4710SRishi Srivatsavai 	} else {							\
3430dc2366fSVenugopal Iyer 		mp = mac_bridge_tx(mip, rhandle, mp);			\
3444eaa4710SRishi Srivatsavai 	}								\
345da14cebeSEric Cheng }
346da14cebeSEric Cheng 
347da14cebeSEric Cheng /* mci_tx_flag */
348da14cebeSEric Cheng #define	MCI_TX_QUIESCE	0x1
349da14cebeSEric Cheng 
350da14cebeSEric Cheng typedef struct mac_factory_addr_s {
351da14cebeSEric Cheng 	boolean_t		mfa_in_use;
352da14cebeSEric Cheng 	uint8_t			mfa_addr[MAXMACADDRLEN];
353da14cebeSEric Cheng 	struct mac_client_impl_s	*mfa_client;
354da14cebeSEric Cheng } mac_factory_addr_t;
355da14cebeSEric Cheng 
356da14cebeSEric Cheng typedef struct mac_mcast_addrs_s {
357da14cebeSEric Cheng 	struct mac_mcast_addrs_s	*mma_next;
358da14cebeSEric Cheng 	uint8_t				mma_addr[MAXMACADDRLEN];
359da14cebeSEric Cheng 	int				mma_ref;
360da14cebeSEric Cheng } mac_mcast_addrs_t;
361da14cebeSEric Cheng 
362da14cebeSEric Cheng typedef enum {
363da14cebeSEric Cheng 	MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED = 1,	/* hardware steering */
364da14cebeSEric Cheng 	MAC_ADDRESS_TYPE_UNICAST_PROMISC		/* promiscuous mode */
365da14cebeSEric Cheng } mac_address_type_t;
366da14cebeSEric Cheng 
367da14cebeSEric Cheng typedef struct mac_address_s {
368da14cebeSEric Cheng 	mac_address_type_t	ma_type;		/* address type */
369da14cebeSEric Cheng 	int			ma_nusers;		/* number of users */
370da14cebeSEric Cheng 							/* of that address */
371da14cebeSEric Cheng 	struct mac_address_s	*ma_next;		/* next address */
372da14cebeSEric Cheng 	uint8_t			ma_addr[MAXMACADDRLEN];	/* address value */
373da14cebeSEric Cheng 	size_t			ma_len;			/* address length */
374da14cebeSEric Cheng 	mac_group_t		*ma_group;		/* asscociated group */
375da14cebeSEric Cheng 	mac_impl_t		*ma_mip;		/* MAC handle */
376da14cebeSEric Cheng } mac_address_t;
377da14cebeSEric Cheng 
378da14cebeSEric Cheng extern krwlock_t i_mac_impl_lock;
379da14cebeSEric Cheng extern mod_hash_t *i_mac_impl_hash;
380da14cebeSEric Cheng extern kmem_cache_t *i_mac_impl_cachep;
381da14cebeSEric Cheng extern uint_t i_mac_impl_count;
382da14cebeSEric Cheng 
383da14cebeSEric Cheng /*
384da14cebeSEric Cheng  * Each registered MAC is associated with a mac_impl_t structure. The
385da14cebeSEric Cheng  * structure represents the undelying hardware, in terms of definition,
386da14cebeSEric Cheng  * resources (transmit, receive rings etc.), callback functions etc. It
387da14cebeSEric Cheng  * also holds the table of MAC clients that are configured on the device.
388da14cebeSEric Cheng  * The table is used for classifying incoming packets in software.
389da14cebeSEric Cheng  *
390da14cebeSEric Cheng  * The protection scheme uses 2 elements, a coarse serialization mechanism
391da14cebeSEric Cheng  * called perimeter and a finer traditional lock based scheme. More details
392da14cebeSEric Cheng  * can be found in the big block comment in mac.c.
393da14cebeSEric Cheng  *
394da14cebeSEric Cheng  * The protection scheme for each member of the mac_impl_t is described below.
395da14cebeSEric Cheng  *
396da14cebeSEric Cheng  * Write Once Only (WO): Typically these don't change for the lifetime of the
397da14cebeSEric Cheng  * data structure. For example something in mac_impl_t that stays the same
398da14cebeSEric Cheng  * from mac_register to mac_unregister, or something in a mac_client_impl_t
399da14cebeSEric Cheng  * that stays the same from mac_client_open to mac_client_close.
400da14cebeSEric Cheng  *
401da14cebeSEric Cheng  * Serializer (SL): Protected by the Serializer. All SLOP operations on a
402da14cebeSEric Cheng  * mac endpoint go through the serializer. MTOPs don't care about reading
403da14cebeSEric Cheng  * these fields atomically.
404da14cebeSEric Cheng  *
405da14cebeSEric Cheng  * Lock: Traditional mutex/rw lock. Modify operations still go through the
406da14cebeSEric Cheng  * mac serializer, the lock helps synchronize readers with writers.
407da14cebeSEric Cheng  */
408da14cebeSEric Cheng struct mac_impl_s {
409da14cebeSEric Cheng 	krwlock_t		mi_rw_lock;
410c228408bSMichael Lim 	list_node_t		mi_node;
411da14cebeSEric Cheng 	char			mi_name[LIFNAMSIZ];	/* WO */
412da14cebeSEric Cheng 	uint32_t		mi_state_flags;
413da14cebeSEric Cheng 	void			*mi_driver;		/* Driver private, WO */
414da14cebeSEric Cheng 	mac_info_t		mi_info;		/* WO */
415da14cebeSEric Cheng 	mactype_t		*mi_type;		/* WO */
416da14cebeSEric Cheng 	void			*mi_pdata;		/* WO */
417da14cebeSEric Cheng 	size_t			mi_pdata_size;		/* WO */
418da14cebeSEric Cheng 	mac_callbacks_t		*mi_callbacks;		/* WO */
419da14cebeSEric Cheng 	dev_info_t		*mi_dip;		/* WO */
420da14cebeSEric Cheng 	uint32_t		mi_ref;			/* i_mac_impl_lock */
421da14cebeSEric Cheng 	uint_t			mi_active;		/* SL */
422da14cebeSEric Cheng 	link_state_t		mi_linkstate;		/* none */
4234eaa4710SRishi Srivatsavai 	link_state_t		mi_lowlinkstate;	/* none */
4244eaa4710SRishi Srivatsavai 	link_state_t		mi_lastlowlinkstate;	/* none */
425da14cebeSEric Cheng 	uint_t			mi_devpromisc;		/* SL */
426da14cebeSEric Cheng 	uint8_t			mi_addr[MAXMACADDRLEN];	/* mi_rw_lock */
427da14cebeSEric Cheng 	uint8_t			mi_dstaddr[MAXMACADDRLEN]; /* mi_rw_lock */
4282b24ab6bSSebastien Roy 	boolean_t		mi_dstaddr_set;
429d62bc4baSyz147064 
430da14cebeSEric Cheng 	/*
431da14cebeSEric Cheng 	 * The mac perimeter. All client initiated create/modify operations
432da14cebeSEric Cheng 	 * on a mac end point go through this.
433da14cebeSEric Cheng 	 */
434da14cebeSEric Cheng 	kmutex_t		mi_perim_lock;
435da14cebeSEric Cheng 	kthread_t		*mi_perim_owner;	/* mi_perim_lock */
436da14cebeSEric Cheng 	uint_t			mi_perim_ocnt;		/* mi_perim_lock */
437da14cebeSEric Cheng 	kcondvar_t		mi_perim_cv;		/* mi_perim_lock */
438d62bc4baSyz147064 
439da14cebeSEric Cheng 	/* mac notification callbacks */
440da14cebeSEric Cheng 	kmutex_t		mi_notify_lock;
441da14cebeSEric Cheng 	mac_cb_info_t		mi_notify_cb_info;	/* mi_notify_lock */
442da14cebeSEric Cheng 	mac_cb_t		*mi_notify_cb_list;	/* mi_notify_lock */
443da14cebeSEric Cheng 	kthread_t		*mi_notify_thread;	/* mi_notify_lock */
444da14cebeSEric Cheng 	uint_t			mi_notify_bits;		/* mi_notify_lock */
445da14cebeSEric Cheng 
446da14cebeSEric Cheng 	uint32_t		mi_v12n_level;		/* Virt'ion readiness */
447da14cebeSEric Cheng 
448da14cebeSEric Cheng 	/*
449da14cebeSEric Cheng 	 * RX groups, ring capability
450da14cebeSEric Cheng 	 * Fields of this block are SL protected.
451da14cebeSEric Cheng 	 */
452da14cebeSEric Cheng 	mac_group_type_t	mi_rx_group_type;	/* grouping type */
453da14cebeSEric Cheng 	uint_t			mi_rx_group_count;
454da14cebeSEric Cheng 	mac_group_t		*mi_rx_groups;
4550dc2366fSVenugopal Iyer 	mac_group_t		*mi_rx_donor_grp;
4560dc2366fSVenugopal Iyer 	uint_t			mi_rxrings_rsvd;
4570dc2366fSVenugopal Iyer 	uint_t			mi_rxrings_avail;
4580dc2366fSVenugopal Iyer 	uint_t			mi_rxhwclnt_avail;
4590dc2366fSVenugopal Iyer 	uint_t			mi_rxhwclnt_used;
460da14cebeSEric Cheng 
461da14cebeSEric Cheng 	mac_capab_rings_t	mi_rx_rings_cap;
462da14cebeSEric Cheng 
463da14cebeSEric Cheng 	/*
464da14cebeSEric Cheng 	 * TX groups and ring capability, SL Protected.
465da14cebeSEric Cheng 	 */
466da14cebeSEric Cheng 	mac_group_type_t	mi_tx_group_type;	/* grouping type */
467da14cebeSEric Cheng 	uint_t			mi_tx_group_count;
468da14cebeSEric Cheng 	uint_t			mi_tx_group_free;
469da14cebeSEric Cheng 	mac_group_t		*mi_tx_groups;
470da14cebeSEric Cheng 	mac_capab_rings_t	mi_tx_rings_cap;
4710dc2366fSVenugopal Iyer 	uint_t			mi_txrings_rsvd;
4720dc2366fSVenugopal Iyer 	uint_t			mi_txrings_avail;
4730dc2366fSVenugopal Iyer 	uint_t			mi_txhwclnt_avail;
4740dc2366fSVenugopal Iyer 	uint_t			mi_txhwclnt_used;
475da14cebeSEric Cheng 
476da14cebeSEric Cheng 	mac_ring_handle_t	mi_default_tx_ring;
477da14cebeSEric Cheng 
478da14cebeSEric Cheng 	/*
47948a4016cSRobert Mustacchi 	 * Transceiver capabilities. SL protected.
48048a4016cSRobert Mustacchi 	 */
48148a4016cSRobert Mustacchi 	mac_capab_transceiver_t	mi_transceiver;
48248a4016cSRobert Mustacchi 
48348a4016cSRobert Mustacchi 	/*
484*4d210590SRobert Mustacchi 	 * LED Capability information. SL protected.
485*4d210590SRobert Mustacchi 	 */
486*4d210590SRobert Mustacchi 	mac_led_mode_t		mi_led_modes;
487*4d210590SRobert Mustacchi 	mac_capab_led_t		mi_led;
488*4d210590SRobert Mustacchi 
489*4d210590SRobert Mustacchi 	/*
490da14cebeSEric Cheng 	 * MAC address list. SL protected.
491da14cebeSEric Cheng 	 */
492da14cebeSEric Cheng 	mac_address_t		*mi_addresses;
493da14cebeSEric Cheng 
494da14cebeSEric Cheng 	/*
495da14cebeSEric Cheng 	 * This MAC's table of sub-flows
496da14cebeSEric Cheng 	 */
497da14cebeSEric Cheng 	flow_tab_t		*mi_flow_tab;		/* WO */
498da14cebeSEric Cheng 
499da14cebeSEric Cheng 	kstat_t			*mi_ksp;		/* WO */
500da14cebeSEric Cheng 	uint_t			mi_kstat_count;		/* WO */
501da14cebeSEric Cheng 	uint_t			mi_nactiveclients;	/* SL */
502da14cebeSEric Cheng 
503da14cebeSEric Cheng 	/* for broadcast and multicast support */
504da14cebeSEric Cheng 	struct mac_mcast_addrs_s *mi_mcast_addrs;	/* mi_rw_lock */
505da14cebeSEric Cheng 	struct mac_bcast_grp_s *mi_bcast_grp;		/* mi_rw_lock */
506da14cebeSEric Cheng 	uint_t			mi_bcast_ngrps;		/* mi_rw_lock */
507da14cebeSEric Cheng 
508da14cebeSEric Cheng 	/* list of MAC clients which opened this MAC */
509da14cebeSEric Cheng 	struct mac_client_impl_s *mi_clients_list;	/* mi_rw_lock */
510da14cebeSEric Cheng 	uint_t			mi_nclients;		/* mi_rw_lock */
511ae6aa22aSVenugopal Iyer 	struct mac_client_impl_s *mi_single_active_client; /* mi_rw_lock */
512da14cebeSEric Cheng 
513da14cebeSEric Cheng 	uint32_t		mi_margin;		/* mi_rw_lock */
514da14cebeSEric Cheng 	uint_t			mi_sdu_min;		/* mi_rw_lock */
515da14cebeSEric Cheng 	uint_t			mi_sdu_max;		/* mi_rw_lock */
5161eee170aSErik Nordmark 	uint_t			mi_sdu_multicast;	/* mi_rw_lock */
517da14cebeSEric Cheng 
518da14cebeSEric Cheng 	/*
519da14cebeSEric Cheng 	 * Cache of factory MAC addresses provided by the driver. If
520da14cebeSEric Cheng 	 * the driver doesn't provide multiple factory MAC addresses,
521da14cebeSEric Cheng 	 * the mi_factory_addr is set to NULL, and mi_factory_addr_num
522da14cebeSEric Cheng 	 * is set to zero.
523da14cebeSEric Cheng 	 */
524da14cebeSEric Cheng 	mac_factory_addr_t	*mi_factory_addr;	/* mi_rw_lock */
525da14cebeSEric Cheng 	uint_t			mi_factory_addr_num;	/* mi_rw_lock */
526da14cebeSEric Cheng 
527da14cebeSEric Cheng 	/* for promiscuous mode support */
528da14cebeSEric Cheng 	kmutex_t		mi_promisc_lock;
529da14cebeSEric Cheng 	mac_cb_t		*mi_promisc_list;	/* mi_promisc_lock */
530da14cebeSEric Cheng 	mac_cb_info_t		mi_promisc_cb_info;	/* mi_promisc_lock */
531da14cebeSEric Cheng 
532da14cebeSEric Cheng 	/* cache of rings over this mac_impl */
533da14cebeSEric Cheng 	kmutex_t		mi_ring_lock;
534da14cebeSEric Cheng 	mac_ring_t		*mi_ring_freelist;	/* mi_ring_lock */
535da14cebeSEric Cheng 
536da14cebeSEric Cheng 	/*
537da14cebeSEric Cheng 	 * These are used for caching the properties, if any, for the
538da14cebeSEric Cheng 	 * primary MAC client. If the MAC client is not yet in place
539da14cebeSEric Cheng 	 * when the properties are set then we cache them here to be
540da14cebeSEric Cheng 	 * applied to the MAC client when it is created.
541da14cebeSEric Cheng 	 */
542da14cebeSEric Cheng 	mac_resource_props_t	mi_resource_props;	/* SL */
5434eaa4710SRishi Srivatsavai 	uint16_t		mi_pvid;		/* SL */
544da14cebeSEric Cheng 
545da14cebeSEric Cheng 	minor_t			mi_minor;		/* WO */
546da14cebeSEric Cheng 	uint32_t		mi_oref;		/* SL */
5475d460eafSCathy Zhou 	mac_capab_legacy_t	mi_capab_legacy;	/* WO */
5485d460eafSCathy Zhou 	dev_t			mi_phy_dev;		/* WO */
5495d460eafSCathy Zhou 
550d62bc4baSyz147064 	/*
551d62bc4baSyz147064 	 * List of margin value requests added by mac clients. This list is
552d62bc4baSyz147064 	 * sorted: the first one has the greatest value.
553d62bc4baSyz147064 	 */
554d62bc4baSyz147064 	mac_margin_req_t	*mi_mmrp;
555a776d98eSRobert Mustacchi 	mac_mtu_req_t		*mi_mtrp;
5560dc2366fSVenugopal Iyer 	char			**mi_priv_prop;
5574045d941Ssowmini 	uint_t			mi_priv_prop_count;
558da14cebeSEric Cheng 
559da14cebeSEric Cheng 	/*
560da14cebeSEric Cheng 	 * Hybrid I/O related definitions.
561da14cebeSEric Cheng 	 */
562da14cebeSEric Cheng 	mac_capab_share_t	mi_share_capab;
563da14cebeSEric Cheng 
5644eaa4710SRishi Srivatsavai 	/*
5654eaa4710SRishi Srivatsavai 	 * Bridging hooks and limit values.  Uses mutex and reference counts
5664eaa4710SRishi Srivatsavai 	 * (bridging only) for data path.  Limits need no synchronization.
5674eaa4710SRishi Srivatsavai 	 */
5684eaa4710SRishi Srivatsavai 	mac_handle_t		mi_bridge_link;
5694eaa4710SRishi Srivatsavai 	kmutex_t		mi_bridge_lock;
5704eaa4710SRishi Srivatsavai 	uint32_t		mi_llimit;
5714eaa4710SRishi Srivatsavai 	uint32_t		mi_ldecay;
5724eaa4710SRishi Srivatsavai 
573da14cebeSEric Cheng /* This should be the last block in this structure */
574da14cebeSEric Cheng #ifdef DEBUG
575da14cebeSEric Cheng #define	MAC_PERIM_STACK_DEPTH	15
576da14cebeSEric Cheng 	int			mi_perim_stack_depth;
577da14cebeSEric Cheng 	pc_t			mi_perim_stack[MAC_PERIM_STACK_DEPTH];
578da14cebeSEric Cheng #endif
579da14cebeSEric Cheng };
580da14cebeSEric Cheng 
5810dc2366fSVenugopal Iyer /*
5820dc2366fSVenugopal Iyer  * The default TX group is the last one in the list.
5830dc2366fSVenugopal Iyer  */
5840dc2366fSVenugopal Iyer #define	MAC_DEFAULT_TX_GROUP(mip)	\
5850dc2366fSVenugopal Iyer 	(mip)->mi_tx_groups + (mip)->mi_tx_group_count
5860dc2366fSVenugopal Iyer 
5870dc2366fSVenugopal Iyer /*
5880dc2366fSVenugopal Iyer  * The default RX group is the first one in the list
5890dc2366fSVenugopal Iyer  */
5900dc2366fSVenugopal Iyer #define	MAC_DEFAULT_RX_GROUP(mip)	(mip)->mi_rx_groups
5910dc2366fSVenugopal Iyer 
5920dc2366fSVenugopal Iyer /* Reserved RX rings */
5930dc2366fSVenugopal Iyer #define	MAC_RX_RING_RESERVED(m, cnt)	{	\
5940dc2366fSVenugopal Iyer 	ASSERT((m)->mi_rxrings_avail >= (cnt));	\
5950dc2366fSVenugopal Iyer 	(m)->mi_rxrings_rsvd += (cnt);		\
5960dc2366fSVenugopal Iyer 	(m)->mi_rxrings_avail -= (cnt);		\
5970dc2366fSVenugopal Iyer }
5980dc2366fSVenugopal Iyer 
5990dc2366fSVenugopal Iyer /* Released RX rings */
6000dc2366fSVenugopal Iyer #define	MAC_RX_RING_RELEASED(m, cnt)	{	\
6010dc2366fSVenugopal Iyer 	ASSERT((m)->mi_rxrings_rsvd >= (cnt));	\
6020dc2366fSVenugopal Iyer 	(m)->mi_rxrings_rsvd -= (cnt);		\
6030dc2366fSVenugopal Iyer 	(m)->mi_rxrings_avail += (cnt);		\
6040dc2366fSVenugopal Iyer }
6050dc2366fSVenugopal Iyer 
6060dc2366fSVenugopal Iyer /* Reserved a RX group */
6070dc2366fSVenugopal Iyer #define	MAC_RX_GRP_RESERVED(m)	{		\
6080dc2366fSVenugopal Iyer 	ASSERT((m)->mi_rxhwclnt_avail > 0);	\
6090dc2366fSVenugopal Iyer 	(m)->mi_rxhwclnt_avail--;		\
6100dc2366fSVenugopal Iyer 	(m)->mi_rxhwclnt_used++;		\
6110dc2366fSVenugopal Iyer }
6120dc2366fSVenugopal Iyer 
6130dc2366fSVenugopal Iyer /* Released a RX group */
6140dc2366fSVenugopal Iyer #define	MAC_RX_GRP_RELEASED(m)	{		\
6150dc2366fSVenugopal Iyer 	ASSERT((m)->mi_rxhwclnt_used > 0);	\
6160dc2366fSVenugopal Iyer 	(m)->mi_rxhwclnt_avail++;		\
6170dc2366fSVenugopal Iyer 	(m)->mi_rxhwclnt_used--;		\
6180dc2366fSVenugopal Iyer }
6190dc2366fSVenugopal Iyer 
6200dc2366fSVenugopal Iyer /* Reserved TX rings */
6210dc2366fSVenugopal Iyer #define	MAC_TX_RING_RESERVED(m, cnt)	{	\
6220dc2366fSVenugopal Iyer 	ASSERT((m)->mi_txrings_avail >= (cnt));	\
6230dc2366fSVenugopal Iyer 	(m)->mi_txrings_rsvd += (cnt);		\
6240dc2366fSVenugopal Iyer 	(m)->mi_txrings_avail -= (cnt);		\
6250dc2366fSVenugopal Iyer }
6260dc2366fSVenugopal Iyer /* Released TX rings */
6270dc2366fSVenugopal Iyer #define	MAC_TX_RING_RELEASED(m, cnt)	{	\
6280dc2366fSVenugopal Iyer 	ASSERT((m)->mi_txrings_rsvd >= (cnt));	\
6290dc2366fSVenugopal Iyer 	(m)->mi_txrings_rsvd -= (cnt);		\
6300dc2366fSVenugopal Iyer 	(m)->mi_txrings_avail += (cnt);		\
6310dc2366fSVenugopal Iyer }
6320dc2366fSVenugopal Iyer 
6330dc2366fSVenugopal Iyer /* Reserved a TX group */
6340dc2366fSVenugopal Iyer #define	MAC_TX_GRP_RESERVED(m)	{		\
6350dc2366fSVenugopal Iyer 	ASSERT((m)->mi_txhwclnt_avail > 0);	\
6360dc2366fSVenugopal Iyer 	(m)->mi_txhwclnt_avail--;		\
6370dc2366fSVenugopal Iyer 	(m)->mi_txhwclnt_used++;		\
6380dc2366fSVenugopal Iyer }
6390dc2366fSVenugopal Iyer 
6400dc2366fSVenugopal Iyer /* Released a TX group */
6410dc2366fSVenugopal Iyer #define	MAC_TX_GRP_RELEASED(m)	{		\
6420dc2366fSVenugopal Iyer 	ASSERT((m)->mi_txhwclnt_used > 0);	\
6430dc2366fSVenugopal Iyer 	(m)->mi_txhwclnt_avail++;		\
6440dc2366fSVenugopal Iyer 	(m)->mi_txhwclnt_used--;		\
6450dc2366fSVenugopal Iyer }
6460dc2366fSVenugopal Iyer 
647da14cebeSEric Cheng /* for mi_state_flags */
648da14cebeSEric Cheng #define	MIS_DISABLED		0x0001
649da14cebeSEric Cheng #define	MIS_IS_VNIC		0x0002
650da14cebeSEric Cheng #define	MIS_IS_AGGR		0x0004
651da14cebeSEric Cheng #define	MIS_NOTIFY_DONE		0x0008
652da14cebeSEric Cheng #define	MIS_EXCLUSIVE		0x0010
653da14cebeSEric Cheng #define	MIS_EXCLUSIVE_HELD	0x0020
654da14cebeSEric Cheng #define	MIS_LEGACY		0x0040
6554eaa4710SRishi Srivatsavai #define	MIS_NO_ACTIVE		0x0080
6564eaa4710SRishi Srivatsavai #define	MIS_POLL_DISABLE	0x0100
657ba2e4443Sseb 
658ba2e4443Sseb #define	mi_getstat	mi_callbacks->mc_getstat
659ba2e4443Sseb #define	mi_start	mi_callbacks->mc_start
660ba2e4443Sseb #define	mi_stop		mi_callbacks->mc_stop
661d62bc4baSyz147064 #define	mi_open		mi_callbacks->mc_open
662d62bc4baSyz147064 #define	mi_close	mi_callbacks->mc_close
663ba2e4443Sseb #define	mi_setpromisc	mi_callbacks->mc_setpromisc
664ba2e4443Sseb #define	mi_multicst	mi_callbacks->mc_multicst
665ba2e4443Sseb #define	mi_unicst	mi_callbacks->mc_unicst
666ba2e4443Sseb #define	mi_tx		mi_callbacks->mc_tx
667ba2e4443Sseb #define	mi_ioctl	mi_callbacks->mc_ioctl
668ba2e4443Sseb #define	mi_getcapab	mi_callbacks->mc_getcapab
6697c478bd9Sstevel@tonic-gate 
670da14cebeSEric Cheng typedef struct mac_notify_task_arg {
671da14cebeSEric Cheng 	mac_impl_t		*mnt_mip;
672da14cebeSEric Cheng 	mac_notify_type_t	mnt_type;
673da14cebeSEric Cheng 	mac_ring_t		*mnt_ring;
674da14cebeSEric Cheng } mac_notify_task_arg_t;
675da14cebeSEric Cheng 
676da14cebeSEric Cheng /*
677da14cebeSEric Cheng  * The mac_perim_handle_t is an opaque type that encodes the 'mip' pointer
678da14cebeSEric Cheng  * and whether internally a mac_open was done when acquiring the perimeter.
679da14cebeSEric Cheng  */
680da14cebeSEric Cheng #define	MAC_ENCODE_MPH(mph, mh, need_close)		\
681da14cebeSEric Cheng 	(mph) = (mac_perim_handle_t)((uintptr_t)(mh) | need_close)
682da14cebeSEric Cheng 
683da14cebeSEric Cheng #define	MAC_DECODE_MPH(mph, mip, need_close) {		\
684da14cebeSEric Cheng 	mip = (mac_impl_t *)(((uintptr_t)mph) & ~0x1);	\
685da14cebeSEric Cheng 	(need_close) = ((uintptr_t)mph & 0x1);		\
686da14cebeSEric Cheng }
687da14cebeSEric Cheng 
6880dc2366fSVenugopal Iyer /*
6890dc2366fSVenugopal Iyer  * Type of property information that can be returned by a driver.
6900dc2366fSVenugopal Iyer  * Valid flags of the pr_flags of the mac_prop_info_t data structure.
6910dc2366fSVenugopal Iyer  */
6920dc2366fSVenugopal Iyer #define	MAC_PROP_INFO_DEFAULT	0x0001
6930dc2366fSVenugopal Iyer #define	MAC_PROP_INFO_RANGE	0x0002
6940dc2366fSVenugopal Iyer #define	MAC_PROP_INFO_PERM	0x0004
6950dc2366fSVenugopal Iyer 
6960dc2366fSVenugopal Iyer /*
6970dc2366fSVenugopal Iyer  * Property information. pr_flags is a combination of one of the
6980dc2366fSVenugopal Iyer  * MAC_PROP_INFO_* flags, it is reset by the framework before invoking
6990dc2366fSVenugopal Iyer  * the driver's prefix_propinfo() entry point.
7000dc2366fSVenugopal Iyer  *
7010dc2366fSVenugopal Iyer  * Drivers should use MAC_PROP_INFO_SET_*() macros to provide
7020dc2366fSVenugopal Iyer  * information about a property.
7030dc2366fSVenugopal Iyer  */
7040dc2366fSVenugopal Iyer typedef struct mac_prop_info_state_s {
7050dc2366fSVenugopal Iyer 	uint8_t			pr_flags;
7060dc2366fSVenugopal Iyer 	uint8_t			pr_perm;
7070591ddd0SPrakash Jalan 	uint8_t			pr_errno;
7080dc2366fSVenugopal Iyer 	void			*pr_default;
7090dc2366fSVenugopal Iyer 	size_t			pr_default_size;
7100dc2366fSVenugopal Iyer 	mac_propval_range_t	*pr_range;
7110591ddd0SPrakash Jalan 	uint_t			pr_range_cur_count;
7120dc2366fSVenugopal Iyer } mac_prop_info_state_t;
7130dc2366fSVenugopal Iyer 
7140dc2366fSVenugopal Iyer #define	MAC_PROTECT_ENABLED(mcip, type) \
7150dc2366fSVenugopal Iyer 	(((mcip)->mci_flent-> \
7160dc2366fSVenugopal Iyer 	fe_resource_props.mrp_mask & MRP_PROTECT) != 0 && \
7170dc2366fSVenugopal Iyer 	((mcip)->mci_flent-> \
7180dc2366fSVenugopal Iyer 	fe_resource_props.mrp_protect.mp_types & (type)) != 0)
7190dc2366fSVenugopal Iyer 
720da14cebeSEric Cheng typedef struct mac_client_impl_s mac_client_impl_t;
721da14cebeSEric Cheng 
7227c478bd9Sstevel@tonic-gate extern void	mac_init(void);
7237c478bd9Sstevel@tonic-gate extern int	mac_fini(void);
7247c478bd9Sstevel@tonic-gate 
7254045d941Ssowmini extern void	mac_ndd_ioctl(mac_impl_t *, queue_t *, mblk_t *);
7260dc2366fSVenugopal Iyer extern boolean_t mac_ip_hdr_length_v6(ip6_t *, uint8_t *, uint16_t *,
7270dc2366fSVenugopal Iyer     uint8_t *, ip6_frag_t **);
728da14cebeSEric Cheng 
729da14cebeSEric Cheng extern mblk_t *mac_copymsgchain_cksum(mblk_t *);
730da14cebeSEric Cheng extern mblk_t *mac_fix_cksum(mblk_t *);
731da14cebeSEric Cheng extern void mac_packet_print(mac_handle_t, mblk_t *);
732da14cebeSEric Cheng extern void mac_rx_deliver(void *, mac_resource_handle_t, mblk_t *,
733da14cebeSEric Cheng     mac_header_info_t *);
734da14cebeSEric Cheng extern void mac_tx_notify(mac_impl_t *);
735da14cebeSEric Cheng 
736da14cebeSEric Cheng extern	boolean_t mac_callback_find(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
737da14cebeSEric Cheng extern	void	mac_callback_add(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
738da14cebeSEric Cheng extern	boolean_t mac_callback_remove(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
739da14cebeSEric Cheng extern	void	mac_callback_remove_wait(mac_cb_info_t *);
740da14cebeSEric Cheng extern	void	mac_callback_free(mac_cb_t *);
741da14cebeSEric Cheng extern	mac_cb_t *mac_callback_walker_cleanup(mac_cb_info_t *, mac_cb_t **);
742da14cebeSEric Cheng 
743da14cebeSEric Cheng /* in mac_bcast.c */
744da14cebeSEric Cheng extern void mac_bcast_init(void);
745da14cebeSEric Cheng extern void mac_bcast_fini(void);
746da14cebeSEric Cheng extern mac_impl_t *mac_bcast_grp_mip(void *);
747da14cebeSEric Cheng extern int mac_bcast_add(mac_client_impl_t *, const uint8_t *, uint16_t,
748da14cebeSEric Cheng     mac_addrtype_t);
749da14cebeSEric Cheng extern void mac_bcast_delete(mac_client_impl_t *, const uint8_t *, uint16_t);
750da14cebeSEric Cheng extern void mac_bcast_send(void *, void *, mblk_t *, boolean_t);
751da14cebeSEric Cheng extern void mac_bcast_grp_free(void *);
752da14cebeSEric Cheng extern void mac_bcast_refresh(mac_impl_t *, mac_multicst_t, void *,
753da14cebeSEric Cheng     boolean_t);
754da14cebeSEric Cheng extern void mac_client_bcast_refresh(mac_client_impl_t *, mac_multicst_t,
755da14cebeSEric Cheng     void *, boolean_t);
756da14cebeSEric Cheng 
757da14cebeSEric Cheng /*
758da14cebeSEric Cheng  * Grouping functions are used internally by MAC layer.
759da14cebeSEric Cheng  */
760da14cebeSEric Cheng extern int mac_group_addmac(mac_group_t *, const uint8_t *);
761da14cebeSEric Cheng extern int mac_group_remmac(mac_group_t *, const uint8_t *);
762da14cebeSEric Cheng extern int mac_rx_group_add_flow(mac_client_impl_t *, flow_entry_t *,
763da14cebeSEric Cheng     mac_group_t *);
76463f531d1SSriharsha Basavapatna extern mblk_t *mac_hwring_tx(mac_ring_handle_t, mblk_t *);
7654eaa4710SRishi Srivatsavai extern mblk_t *mac_bridge_tx(mac_impl_t *, mac_ring_handle_t, mblk_t *);
7660dc2366fSVenugopal Iyer extern mac_group_t *mac_reserve_rx_group(mac_client_impl_t *, uint8_t *,
7670dc2366fSVenugopal Iyer     boolean_t);
7680dc2366fSVenugopal Iyer extern void mac_release_rx_group(mac_client_impl_t *, mac_group_t *);
7690dc2366fSVenugopal Iyer extern int mac_rx_switch_group(mac_client_impl_t *, mac_group_t *,
7700dc2366fSVenugopal Iyer     mac_group_t *);
771da14cebeSEric Cheng extern mac_ring_t *mac_reserve_tx_ring(mac_impl_t *, mac_ring_t *);
7720dc2366fSVenugopal Iyer extern mac_group_t *mac_reserve_tx_group(mac_client_impl_t *, boolean_t);
7730dc2366fSVenugopal Iyer extern void mac_release_tx_group(mac_client_impl_t *, mac_group_t *);
7740dc2366fSVenugopal Iyer extern void mac_tx_switch_group(mac_client_impl_t *, mac_group_t *,
7750dc2366fSVenugopal Iyer     mac_group_t *);
7760dc2366fSVenugopal Iyer extern void mac_rx_switch_grp_to_sw(mac_group_t *);
777da14cebeSEric Cheng 
778da14cebeSEric Cheng /*
779da14cebeSEric Cheng  * MAC address functions are used internally by MAC layer.
780da14cebeSEric Cheng  */
781da14cebeSEric Cheng extern mac_address_t *mac_find_macaddr(mac_impl_t *, uint8_t *);
782da14cebeSEric Cheng extern boolean_t mac_check_macaddr_shared(mac_address_t *);
783da14cebeSEric Cheng extern int mac_update_macaddr(mac_address_t *, uint8_t *);
784da14cebeSEric Cheng extern void mac_freshen_macaddr(mac_address_t *, uint8_t *);
785da14cebeSEric Cheng extern void mac_retrieve_macaddr(mac_address_t *, uint8_t *);
786da14cebeSEric Cheng extern void mac_init_macaddr(mac_impl_t *);
787da14cebeSEric Cheng extern void mac_fini_macaddr(mac_impl_t *);
788da14cebeSEric Cheng 
789da14cebeSEric Cheng /*
790da14cebeSEric Cheng  * Flow construction/destruction routines.
791da14cebeSEric Cheng  * Not meant to be used by mac clients.
792da14cebeSEric Cheng  */
793da14cebeSEric Cheng extern int mac_link_flow_init(mac_client_handle_t, flow_entry_t *);
794da14cebeSEric Cheng extern void mac_link_flow_clean(mac_client_handle_t, flow_entry_t *);
795da14cebeSEric Cheng 
796da14cebeSEric Cheng /*
79708ac1c49SNicolas Droux  * Fanout update routines called when the link speed of the NIC changes
79808ac1c49SNicolas Droux  * or when a MAC client's share is unbound.
799da14cebeSEric Cheng  */
8000dc2366fSVenugopal Iyer extern void mac_fanout_recompute_client(mac_client_impl_t *, cpupart_t *);
801da14cebeSEric Cheng extern void mac_fanout_recompute(mac_impl_t *);
802da14cebeSEric Cheng 
803da14cebeSEric Cheng /*
804da14cebeSEric Cheng  * The following functions are used internally by the MAC layer to
805da14cebeSEric Cheng  * add/remove/update flows associated with a mac_impl_t. They should
806da14cebeSEric Cheng  * never be used directly by MAC clients.
807da14cebeSEric Cheng  */
808da14cebeSEric Cheng extern int mac_datapath_setup(mac_client_impl_t *, flow_entry_t *, uint32_t);
809da14cebeSEric Cheng extern void mac_datapath_teardown(mac_client_impl_t *, flow_entry_t *,
810da14cebeSEric Cheng     uint32_t);
8110dc2366fSVenugopal Iyer extern void mac_rx_srs_group_setup(mac_client_impl_t *, flow_entry_t *,
8120dc2366fSVenugopal Iyer     uint32_t);
8130dc2366fSVenugopal Iyer extern void mac_tx_srs_group_setup(mac_client_impl_t *, flow_entry_t *,
8140dc2366fSVenugopal Iyer     uint32_t);
8150dc2366fSVenugopal Iyer extern void mac_rx_srs_group_teardown(flow_entry_t *, boolean_t);
8160dc2366fSVenugopal Iyer extern void mac_tx_srs_group_teardown(mac_client_impl_t *, flow_entry_t *,
817da14cebeSEric Cheng 	    uint32_t);
818da14cebeSEric Cheng extern int mac_rx_classify_flow_quiesce(flow_entry_t *, void *);
819da14cebeSEric Cheng extern int mac_rx_classify_flow_restart(flow_entry_t *, void *);
820da14cebeSEric Cheng extern void mac_client_quiesce(mac_client_impl_t *);
821da14cebeSEric Cheng extern void mac_client_restart(mac_client_impl_t *);
822da14cebeSEric Cheng 
823da14cebeSEric Cheng extern void mac_flow_update_priority(mac_client_impl_t *, flow_entry_t *);
824da14cebeSEric Cheng 
825da14cebeSEric Cheng extern void mac_flow_rem_subflow(flow_entry_t *);
826da14cebeSEric Cheng extern void mac_rename_flow(flow_entry_t *, const char *);
827da14cebeSEric Cheng extern void mac_flow_set_name(flow_entry_t *, const char *);
828da14cebeSEric Cheng 
829da14cebeSEric Cheng extern mblk_t *mac_add_vlan_tag(mblk_t *, uint_t, uint16_t);
830da14cebeSEric Cheng extern mblk_t *mac_add_vlan_tag_chain(mblk_t *, uint_t, uint16_t);
831da14cebeSEric Cheng extern mblk_t *mac_strip_vlan_tag_chain(mblk_t *);
832da14cebeSEric Cheng extern void mac_pkt_drop(void *, mac_resource_handle_t, mblk_t *, boolean_t);
833da14cebeSEric Cheng extern mblk_t *mac_rx_flow(mac_handle_t, mac_resource_handle_t, mblk_t *);
834da14cebeSEric Cheng 
835da14cebeSEric Cheng extern void i_mac_share_alloc(mac_client_impl_t *);
836da14cebeSEric Cheng extern void i_mac_share_free(mac_client_impl_t *);
837da14cebeSEric Cheng extern void i_mac_perim_enter(mac_impl_t *);
838da14cebeSEric Cheng extern void i_mac_perim_exit(mac_impl_t *);
839da14cebeSEric Cheng extern int i_mac_perim_enter_nowait(mac_impl_t *);
840da14cebeSEric Cheng extern void i_mac_tx_srs_notify(mac_impl_t *, mac_ring_handle_t);
841da14cebeSEric Cheng extern int mac_hold(const char *, mac_impl_t **);
842da14cebeSEric Cheng extern void mac_rele(mac_impl_t *);
843da14cebeSEric Cheng extern int i_mac_disable(mac_impl_t *);
844da14cebeSEric Cheng extern void i_mac_notify(mac_impl_t *, mac_notify_type_t);
845da14cebeSEric Cheng extern void i_mac_notify_exit(mac_impl_t *);
846da14cebeSEric Cheng extern void mac_rx_group_unmark(mac_group_t *, uint_t);
847da14cebeSEric Cheng extern void mac_tx_client_flush(mac_client_impl_t *);
848da14cebeSEric Cheng extern void mac_tx_client_block(mac_client_impl_t *);
849da14cebeSEric Cheng extern void mac_tx_client_unblock(mac_client_impl_t *);
8500dc2366fSVenugopal Iyer extern void mac_tx_invoke_callbacks(mac_client_impl_t *, mac_tx_cookie_t);
851d91a22bfSGirish Moodalbail extern int i_mac_promisc_set(mac_impl_t *, boolean_t);
852da14cebeSEric Cheng extern void i_mac_promisc_walker_cleanup(mac_impl_t *);
853da14cebeSEric Cheng extern mactype_t *mactype_getplugin(const char *);
854da14cebeSEric Cheng extern void mac_addr_factory_init(mac_impl_t *);
855da14cebeSEric Cheng extern void mac_addr_factory_fini(mac_impl_t *);
8560dc2366fSVenugopal Iyer extern void mac_register_priv_prop(mac_impl_t *, char **);
857da14cebeSEric Cheng extern void mac_unregister_priv_prop(mac_impl_t *);
858da14cebeSEric Cheng extern int mac_init_rings(mac_impl_t *, mac_ring_type_t);
859da14cebeSEric Cheng extern void mac_free_rings(mac_impl_t *, mac_ring_type_t);
8600dc2366fSVenugopal Iyer extern void mac_compare_ddi_handle(mac_group_t *, uint_t, mac_ring_t *);
861da14cebeSEric Cheng 
862da14cebeSEric Cheng extern int mac_start_group(mac_group_t *);
863da14cebeSEric Cheng extern void mac_stop_group(mac_group_t *);
864da14cebeSEric Cheng extern int mac_start_ring(mac_ring_t *);
865da14cebeSEric Cheng extern void mac_stop_ring(mac_ring_t *);
86608ac1c49SNicolas Droux extern int mac_add_macaddr(mac_impl_t *, mac_group_t *, uint8_t *, boolean_t);
867da14cebeSEric Cheng extern int mac_remove_macaddr(mac_address_t *);
868da14cebeSEric Cheng 
8690dc2366fSVenugopal Iyer extern void mac_set_group_state(mac_group_t *, mac_group_state_t);
8700dc2366fSVenugopal Iyer extern void mac_group_add_client(mac_group_t *, mac_client_impl_t *);
8710dc2366fSVenugopal Iyer extern void mac_group_remove_client(mac_group_t *, mac_client_impl_t *);
8720dc2366fSVenugopal Iyer 
873da14cebeSEric Cheng extern int i_mac_group_add_ring(mac_group_t *, mac_ring_t *, int);
874da14cebeSEric Cheng extern void i_mac_group_rem_ring(mac_group_t *, mac_ring_t *, boolean_t);
8750dc2366fSVenugopal Iyer extern int mac_group_ring_modify(mac_client_impl_t *, mac_group_t *,
8760dc2366fSVenugopal Iyer     mac_group_t *);
8774eaa4710SRishi Srivatsavai extern void mac_poll_state_change(mac_handle_t, boolean_t);
8784eaa4710SRishi Srivatsavai 
8790dc2366fSVenugopal Iyer extern mac_group_state_t mac_group_next_state(mac_group_t *,
8800dc2366fSVenugopal Iyer     mac_client_impl_t **, mac_group_t *, boolean_t);
8810dc2366fSVenugopal Iyer 
88225ec3e3dSEric Cheng extern mblk_t *mac_protect_check(mac_client_handle_t, mblk_t *);
88325ec3e3dSEric Cheng extern int mac_protect_set(mac_client_handle_t, mac_resource_props_t *);
88425ec3e3dSEric Cheng extern boolean_t mac_protect_enabled(mac_client_handle_t, uint32_t);
88525ec3e3dSEric Cheng extern int mac_protect_validate(mac_resource_props_t *);
88625ec3e3dSEric Cheng extern void mac_protect_update(mac_resource_props_t *, mac_resource_props_t *);
8871aec9edfSCody Peter Mello extern void mac_protect_update_mac_token(mac_client_impl_t *);
8881aec9edfSCody Peter Mello extern void mac_protect_intercept_dynamic(mac_client_impl_t *, mblk_t *);
8891aec9edfSCody Peter Mello extern void mac_protect_flush_dynamic(mac_client_impl_t *);
8900dc2366fSVenugopal Iyer extern void mac_protect_cancel_timer(mac_client_impl_t *);
8910dc2366fSVenugopal Iyer extern void mac_protect_init(mac_client_impl_t *);
8920dc2366fSVenugopal Iyer extern void mac_protect_fini(mac_client_impl_t *);
8930dc2366fSVenugopal Iyer 
8940dc2366fSVenugopal Iyer extern int mac_set_resources(mac_handle_t, mac_resource_props_t *);
8950dc2366fSVenugopal Iyer extern void mac_get_resources(mac_handle_t, mac_resource_props_t *);
8960dc2366fSVenugopal Iyer extern void mac_get_effective_resources(mac_handle_t, mac_resource_props_t *);
897a124e365SRobert Mustacchi extern void mac_set_promisc_filtered(mac_client_handle_t, boolean_t);
898a124e365SRobert Mustacchi extern boolean_t mac_get_promisc_filtered(mac_client_handle_t);
8990dc2366fSVenugopal Iyer 
9000dc2366fSVenugopal Iyer extern cpupart_t *mac_pset_find(mac_resource_props_t *, boolean_t *);
9010dc2366fSVenugopal Iyer extern void mac_set_pool_effective(boolean_t, cpupart_t *,
9020dc2366fSVenugopal Iyer     mac_resource_props_t *, mac_resource_props_t *);
9030dc2366fSVenugopal Iyer extern void mac_set_rings_effective(mac_client_impl_t *);
9040dc2366fSVenugopal Iyer extern mac_client_impl_t *mac_check_primary_relocation(mac_client_impl_t *,
9050dc2366fSVenugopal Iyer     boolean_t);
90625ec3e3dSEric Cheng 
9074eaa4710SRishi Srivatsavai /* Global callbacks into the bridging module (when loaded) */
9084eaa4710SRishi Srivatsavai extern mac_bridge_tx_t mac_bridge_tx_cb;
9094eaa4710SRishi Srivatsavai extern mac_bridge_rx_t mac_bridge_rx_cb;
9104eaa4710SRishi Srivatsavai extern mac_bridge_ref_t mac_bridge_ref_cb;
9114eaa4710SRishi Srivatsavai extern mac_bridge_ls_t mac_bridge_ls_cb;
9124eaa4710SRishi Srivatsavai 
91348a4016cSRobert Mustacchi /*
91448a4016cSRobert Mustacchi  * MAC Transceiver related functions
91548a4016cSRobert Mustacchi  */
91648a4016cSRobert Mustacchi struct mac_transceiver_info {
91748a4016cSRobert Mustacchi 	boolean_t		mti_present;
91848a4016cSRobert Mustacchi 	boolean_t		mti_usable;
91948a4016cSRobert Mustacchi };
92048a4016cSRobert Mustacchi 
92148a4016cSRobert Mustacchi extern void mac_transceiver_init(mac_impl_t *);
92248a4016cSRobert Mustacchi extern int mac_transceiver_count(mac_handle_t, uint_t *);
92348a4016cSRobert Mustacchi extern int mac_transceiver_info(mac_handle_t, uint_t, boolean_t *, boolean_t *);
92448a4016cSRobert Mustacchi extern int mac_transceiver_read(mac_handle_t, uint_t, uint_t, void *, size_t,
92548a4016cSRobert Mustacchi     off_t, size_t *);
9260dc2366fSVenugopal Iyer 
927*4d210590SRobert Mustacchi /*
928*4d210590SRobert Mustacchi  * MAC LED related functions
929*4d210590SRobert Mustacchi  */
930*4d210590SRobert Mustacchi #define	MAC_LED_ALL	(MAC_LED_DEFAULT | MAC_LED_OFF | MAC_LED_IDENT | \
931*4d210590SRobert Mustacchi 			    MAC_LED_ON)
932*4d210590SRobert Mustacchi extern void mac_led_init(mac_impl_t *);
933*4d210590SRobert Mustacchi extern int mac_led_get(mac_handle_t, mac_led_mode_t *, mac_led_mode_t *);
934*4d210590SRobert Mustacchi extern int mac_led_set(mac_handle_t, mac_led_mode_t);
935*4d210590SRobert Mustacchi 
9367c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
9377c478bd9Sstevel@tonic-gate }
9387c478bd9Sstevel@tonic-gate #endif
9397c478bd9Sstevel@tonic-gate 
9407c478bd9Sstevel@tonic-gate #endif	/* _SYS_MAC_IMPL_H */
941