xref: /onnv-gate/usr/src/uts/common/sys/mac_impl.h (revision 10654)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51852Syz147064  * Common Development and Distribution License (the "License").
61852Syz147064  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
228833SVenu.Iyer@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #ifndef	_SYS_MAC_IMPL_H
270Sstevel@tonic-gate #define	_SYS_MAC_IMPL_H
280Sstevel@tonic-gate 
298275SEric Cheng #include <sys/modhash.h>
308275SEric Cheng #include <sys/mac_client.h>
318275SEric Cheng #include <sys/mac_provider.h>
3210491SRishi.Srivatsavai@Sun.COM #include <sys/note.h>
332311Sseb #include <net/if.h>
348275SEric Cheng #include <sys/mac_flow_impl.h>
358275SEric Cheng #include <netinet/ip6.h>
360Sstevel@tonic-gate 
370Sstevel@tonic-gate #ifdef	__cplusplus
380Sstevel@tonic-gate extern "C" {
390Sstevel@tonic-gate #endif
400Sstevel@tonic-gate 
41*10654SGarrett.Damore@Sun.COM /*
42*10654SGarrett.Damore@Sun.COM  * This is the first minor number available for MAC provider private
43*10654SGarrett.Damore@Sun.COM  * use.  This makes it possible to deliver a driver that is both a MAC
44*10654SGarrett.Damore@Sun.COM  * provider and a regular character/block device.  See PSARC 2009/380
45*10654SGarrett.Damore@Sun.COM  * for more detail about the construction of such devices.  The value
46*10654SGarrett.Damore@Sun.COM  * chosen leaves half of the 32-bit minor numbers (which are really
47*10654SGarrett.Damore@Sun.COM  * only 18 bits wide) available for driver private use.  Drivers can
48*10654SGarrett.Damore@Sun.COM  * easily identify their private number by the presence of this value
49*10654SGarrett.Damore@Sun.COM  * in the bits that make up the minor number, since its just the
50*10654SGarrett.Damore@Sun.COM  * highest bit available for such minor numbers.
51*10654SGarrett.Damore@Sun.COM  */
52*10654SGarrett.Damore@Sun.COM #define	MAC_PRIVATE_MINOR		((MAXMIN32 + 1) / 2)
53*10654SGarrett.Damore@Sun.COM 
54*10654SGarrett.Damore@Sun.COM /*
55*10654SGarrett.Damore@Sun.COM  * The maximum minor number that corresponds to a real instance.  This
56*10654SGarrett.Damore@Sun.COM  * limits the number of physical ports that a mac provider can offer.
57*10654SGarrett.Damore@Sun.COM  * Note that this macro must be synchronized with DLS_MAX_MINOR in
58*10654SGarrett.Damore@Sun.COM  * <sys/dls.h>
59*10654SGarrett.Damore@Sun.COM  */
60*10654SGarrett.Damore@Sun.COM #define	MAC_MAX_MINOR			1000
61*10654SGarrett.Damore@Sun.COM 
625895Syz147064 typedef struct mac_margin_req_s	mac_margin_req_t;
635895Syz147064 
645895Syz147064 struct mac_margin_req_s {
655895Syz147064 	mac_margin_req_t	*mmr_nextp;
665895Syz147064 	uint_t			mmr_ref;
675895Syz147064 	uint32_t		mmr_margin;
685895Syz147064 };
695895Syz147064 
708275SEric Cheng /* Generic linked chain type */
718275SEric Cheng typedef	struct mac_chain_s {
728275SEric Cheng 	struct mac_chain_s	*next;
738275SEric Cheng 	void			*item;
748275SEric Cheng } mac_chain_t;
758275SEric Cheng 
768275SEric Cheng /*
778275SEric Cheng  * Generic mac callback list manipulation structures and macros. The mac_cb_t
788275SEric Cheng  * represents a general callback list element embedded in a particular
798275SEric Cheng  * data structure such as a mac_notify_cb_t or a mac_promisc_impl_t.
808275SEric Cheng  * The mac_cb_info_t represents general information about list walkers.
818275SEric Cheng  * Please see the comments above mac_callback_add for more information.
828275SEric Cheng  */
838275SEric Cheng /* mcb_flags */
848275SEric Cheng #define	MCB_CONDEMNED		0x1		/* Logically deleted */
858275SEric Cheng #define	MCB_NOTIFY_CB_T		0x2
868275SEric Cheng #define	MCB_TX_NOTIFY_CB_T	0x4
870Sstevel@tonic-gate 
888275SEric Cheng typedef struct mac_cb_s {
898275SEric Cheng 	struct mac_cb_s		*mcb_nextp;	/* Linked list of callbacks */
908275SEric Cheng 	void			*mcb_objp;	/* Ptr to enclosing object  */
918275SEric Cheng 	size_t			mcb_objsize;	/* Sizeof the enclosing obj */
928275SEric Cheng 	uint_t			mcb_flags;
938275SEric Cheng } mac_cb_t;
940Sstevel@tonic-gate 
958275SEric Cheng typedef struct mac_cb_info_s {
968275SEric Cheng 	kmutex_t	*mcbi_lockp;
978275SEric Cheng 	kcondvar_t	mcbi_cv;
988275SEric Cheng 	uint_t		mcbi_del_cnt;		/* Deleted callback cnt */
998275SEric Cheng 	uint_t		mcbi_walker_cnt;	/* List walker count */
1008275SEric Cheng } mac_cb_info_t;
1018275SEric Cheng 
1028275SEric Cheng typedef struct mac_notify_cb_s {
1038275SEric Cheng 	mac_cb_t	mncb_link;		/* Linked list of callbacks */
1048275SEric Cheng 	mac_notify_t	mncb_fn;		/* callback function */
1058275SEric Cheng 	void		*mncb_arg;		/* callback argument */
1068275SEric Cheng 	struct mac_impl_s *mncb_mip;
1078275SEric Cheng } mac_notify_cb_t;
1080Sstevel@tonic-gate 
1098275SEric Cheng /*
1108275SEric Cheng  * mac_callback_add(listinfo, listhead, listelement)
1118275SEric Cheng  * mac_callback_remove(listinfo, listhead, listelement)
1128275SEric Cheng  */
1138275SEric Cheng typedef boolean_t (*mcb_func_t)(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
1148275SEric Cheng 
1158275SEric Cheng #define	MAC_CALLBACK_WALKER_INC(mcbi) {				\
1168275SEric Cheng 	mutex_enter((mcbi)->mcbi_lockp);			\
1178275SEric Cheng 	(mcbi)->mcbi_walker_cnt++;				\
1188275SEric Cheng 	mutex_exit((mcbi)->mcbi_lockp);				\
1198275SEric Cheng }
1208275SEric Cheng 
1218275SEric Cheng #define	MAC_CALLBACK_WALKER_INC_HELD(mcbi)	(mcbi)->mcbi_walker_cnt++;
1220Sstevel@tonic-gate 
1238275SEric Cheng #define	MAC_CALLBACK_WALKER_DCR(mcbi, headp) {			\
1248275SEric Cheng 	mac_cb_t	*rmlist;				\
1258275SEric Cheng 								\
1268275SEric Cheng 	mutex_enter((mcbi)->mcbi_lockp);			\
1278275SEric Cheng 	if (--(mcbi)->mcbi_walker_cnt == 0 && (mcbi)->mcbi_del_cnt != 0) { \
1288275SEric Cheng 		rmlist = mac_callback_walker_cleanup((mcbi), headp);	\
1298275SEric Cheng 		mac_callback_free(rmlist);			\
1308275SEric Cheng 		cv_broadcast(&(mcbi)->mcbi_cv);			\
1318275SEric Cheng 	}							\
1328275SEric Cheng 	mutex_exit((mcbi)->mcbi_lockp);				\
1338275SEric Cheng }
1340Sstevel@tonic-gate 
1358275SEric Cheng #define	MAC_PROMISC_WALKER_INC(mip)				\
1368275SEric Cheng 	MAC_CALLBACK_WALKER_INC(&(mip)->mi_promisc_cb_info)
1378275SEric Cheng 
1388275SEric Cheng #define	MAC_PROMISC_WALKER_DCR(mip) {				\
1398275SEric Cheng 	mac_cb_info_t	*mcbi;					\
1408275SEric Cheng 								\
1418275SEric Cheng 	mcbi = &(mip)->mi_promisc_cb_info;			\
1428275SEric Cheng 	mutex_enter(mcbi->mcbi_lockp);				\
1438275SEric Cheng 	if (--mcbi->mcbi_walker_cnt == 0 && mcbi->mcbi_del_cnt != 0) { \
1448275SEric Cheng 		i_mac_promisc_walker_cleanup(mip);		\
1458275SEric Cheng 		cv_broadcast(&mcbi->mcbi_cv);			\
1468275SEric Cheng 	}							\
1478275SEric Cheng 	mutex_exit(mcbi->mcbi_lockp);				\
1488275SEric Cheng }
1490Sstevel@tonic-gate 
1502311Sseb typedef struct mactype_s {
1512311Sseb 	const char	*mt_ident;
1522311Sseb 	uint32_t	mt_ref;
1532311Sseb 	uint_t		mt_type;
1543147Sxc151355 	uint_t		mt_nativetype;
1552311Sseb 	size_t		mt_addr_length;
1562311Sseb 	uint8_t		*mt_brdcst_addr;
1572311Sseb 	mactype_ops_t	mt_ops;
1582311Sseb 	mac_stat_info_t	*mt_stats;	/* array of mac_stat_info_t elements */
1592311Sseb 	size_t		mt_statcount;	/* number of elements in mt_stats */
1606512Ssowmini 	mac_ndd_mapping_t *mt_mapping;
1616512Ssowmini 	size_t		mt_mappingcount;
1622311Sseb } mactype_t;
1630Sstevel@tonic-gate 
1648275SEric Cheng /*
1658275SEric Cheng  * Multiple rings implementation.
1668275SEric Cheng  */
1678275SEric Cheng typedef	enum {
1688275SEric Cheng 	MAC_GROUP_STATE_UNINIT	= 0,	/* initial state of data structure */
1698275SEric Cheng 	MAC_GROUP_STATE_REGISTERED,	/* hooked with h/w group */
1708275SEric Cheng 	MAC_GROUP_STATE_RESERVED,	/* group is reserved and opened */
1718275SEric Cheng 	MAC_GROUP_STATE_SHARED		/* default group shared among */
1728275SEric Cheng 					/* multiple mac clients */
1738275SEric Cheng } mac_group_state_t;
1745084Sjohnlev 
1758275SEric Cheng typedef	struct mac_ring_s mac_ring_t;
1768275SEric Cheng typedef	struct mac_group_s mac_group_t;
1778275SEric Cheng 
1788275SEric Cheng /*
1798275SEric Cheng  * Ring data structure for ring control and management.
1808275SEric Cheng  */
1818275SEric Cheng typedef enum {
1828275SEric Cheng 	MR_FREE,		/* Available for assignment to flows */
1838275SEric Cheng 	MR_NEWLY_ADDED,		/* Just assigned to another group */
1848275SEric Cheng 	MR_INUSE		/* Assigned to an SRS */
1858275SEric Cheng } mac_ring_state_t;
1868275SEric Cheng 
1878275SEric Cheng /* mr_flag values */
1888275SEric Cheng #define	MR_INCIPIENT	0x1
1898275SEric Cheng #define	MR_CONDEMNED	0x2
1908275SEric Cheng #define	MR_QUIESCE	0x4
1918275SEric Cheng 
1928275SEric Cheng struct mac_ring_s {
1938275SEric Cheng 	int			mr_index;	/* index in the original list */
1948275SEric Cheng 	mac_ring_type_t		mr_type;	/* ring type */
1958275SEric Cheng 	mac_ring_t		*mr_next;	/* next ring in the chain */
1968275SEric Cheng 	mac_group_handle_t	mr_gh;		/* reference to group */
1978275SEric Cheng 
1988275SEric Cheng 	mac_classify_type_t	mr_classify_type;	/* HW vs SW */
1998275SEric Cheng 	struct mac_soft_ring_set_s *mr_srs;		/* associated SRS */
2008275SEric Cheng 	uint_t			mr_refcnt;		/* Ring references */
2018275SEric Cheng 	/* ring generation no. to guard against drivers using stale rings */
2028275SEric Cheng 	uint64_t		mr_gen_num;
2038275SEric Cheng 
2048275SEric Cheng 	kmutex_t		mr_lock;
2058275SEric Cheng 	kcondvar_t		mr_cv;			/* mr_lock */
2068275SEric Cheng 	mac_ring_state_t	mr_state;		/* mr_lock */
2078275SEric Cheng 	uint_t			mr_flag;		/* mr_lock */
2088275SEric Cheng 
2098275SEric Cheng 	mac_ring_info_t		mr_info;	/* driver supplied info */
2108275SEric Cheng };
2118275SEric Cheng #define	mr_driver		mr_info.mri_driver
2128275SEric Cheng #define	mr_start		mr_info.mri_start
2138275SEric Cheng #define	mr_stop			mr_info.mri_stop
2148275SEric Cheng 
2158275SEric Cheng #define	MAC_RING_MARK(mr, flag)		\
2168275SEric Cheng 	(mr)->mr_flag |= flag;
2178275SEric Cheng 
2188275SEric Cheng #define	MAC_RING_UNMARK(mr, flag)	\
2198275SEric Cheng 	(mr)->mr_flag &= ~flag;
2208275SEric Cheng 
2218275SEric Cheng /*
2228275SEric Cheng  * Reference hold and release on mac_ring_t 'mr'
2238275SEric Cheng  */
2248275SEric Cheng #define	MR_REFHOLD_LOCKED(mr)		{		\
2258275SEric Cheng 	ASSERT(MUTEX_HELD(&mr->mr_lock));		\
2268275SEric Cheng 	(mr)->mr_refcnt++;				\
2275084Sjohnlev }
2285084Sjohnlev 
2298275SEric Cheng #define	MR_REFRELE(mr)		{	 		\
2308275SEric Cheng 	mutex_enter(&(mr)->mr_lock);			\
2318275SEric Cheng 	ASSERT((mr)->mr_refcnt != 0);			\
2328275SEric Cheng 	(mr)->mr_refcnt--;				\
2338275SEric Cheng 	if ((mr)->mr_refcnt == 0 &&			\
2348275SEric Cheng 	    ((mr)->mr_flag & (MR_CONDEMNED | MR_QUIESCE))) \
2358275SEric Cheng 		cv_signal(&(mr)->mr_cv);		\
2368275SEric Cheng 	mutex_exit(&(mr)->mr_lock);			\
2375084Sjohnlev }
2385084Sjohnlev 
2398275SEric Cheng /*
2408275SEric Cheng  * Per mac client flow information associated with a RX group.
2418275SEric Cheng  * The entire structure is SL protected.
2428275SEric Cheng  */
2438275SEric Cheng typedef struct mac_grp_client {
2448275SEric Cheng 	struct mac_grp_client		*mgc_next;
2458275SEric Cheng 	struct mac_client_impl_s	*mgc_client;
2468275SEric Cheng } mac_grp_client_t;
2475084Sjohnlev 
2488275SEric Cheng #define	MAC_RX_GROUP_NO_CLIENT(g)	((g)->mrg_clients == NULL)
2498275SEric Cheng 
2508275SEric Cheng #define	MAC_RX_GROUP_ONLY_CLIENT(g)			\
2518275SEric Cheng 	((((g)->mrg_clients != NULL) &&			\
2528275SEric Cheng 	((g)->mrg_clients->mgc_next == NULL)) ?		\
2538275SEric Cheng 	(g)->mrg_clients->mgc_client : NULL)
2546512Ssowmini 
2552311Sseb /*
2568275SEric Cheng  * Common ring group data structure for ring control and management.
2578275SEric Cheng  * The entire structure is SL protected
2582311Sseb  */
2598275SEric Cheng struct mac_group_s {
2608275SEric Cheng 	int			mrg_index;	/* index in the list */
2618275SEric Cheng 	mac_ring_type_t		mrg_type;	/* ring type */
2628275SEric Cheng 	mac_group_state_t	mrg_state;	/* state of the group */
2638275SEric Cheng 	mac_group_t		*mrg_next;	/* next ring in the chain */
2648275SEric Cheng 	mac_handle_t		mrg_mh;		/* reference to MAC */
2658275SEric Cheng 	mac_ring_t		*mrg_rings;	/* grouped rings */
2668275SEric Cheng 	uint_t			mrg_cur_count;	/* actual size of group */
2678275SEric Cheng 
2688275SEric Cheng 	mac_grp_client_t	*mrg_clients;	/* clients list */
2698275SEric Cheng 
2708275SEric Cheng 	struct mac_client_impl_s *mrg_tx_client; /* TX client pointer */
2718275SEric Cheng 	mac_group_info_t	mrg_info;	/* driver supplied info */
2728275SEric Cheng };
2738275SEric Cheng 
2748275SEric Cheng #define	mrg_driver		mrg_info.mgi_driver
2758275SEric Cheng #define	mrg_start		mrg_info.mgi_start
2768275SEric Cheng #define	mrg_stop		mrg_info.mgi_stop
2778275SEric Cheng 
2788275SEric Cheng #define	GROUP_INTR_HANDLE(g)		(g)->mrg_info.mgi_intr.mi_handle
2798275SEric Cheng #define	GROUP_INTR_ENABLE_FUNC(g)	(g)->mrg_info.mgi_intr.mi_enable
2808275SEric Cheng #define	GROUP_INTR_DISABLE_FUNC(g)	(g)->mrg_info.mgi_intr.mi_disable
2818275SEric Cheng 
2828275SEric Cheng #define	MAC_DEFAULT_GROUP(mh)		(((mac_impl_t *)mh)->mi_rx_groups)
2838275SEric Cheng 
28410491SRishi.Srivatsavai@Sun.COM #define	MAC_RING_TX(mhp, rh, mp, rest) {				\
28510491SRishi.Srivatsavai@Sun.COM 	mac_ring_handle_t mrh = rh;					\
28610491SRishi.Srivatsavai@Sun.COM 	mac_impl_t *mimpl = (mac_impl_t *)mhp;				\
2878275SEric Cheng 	/*								\
28810491SRishi.Srivatsavai@Sun.COM 	 * Send packets through a selected tx ring, or through the 	\
28910491SRishi.Srivatsavai@Sun.COM 	 * default handler if there is no selected ring.		\
2908275SEric Cheng 	 */								\
29110491SRishi.Srivatsavai@Sun.COM 	if (mrh == NULL)						\
29210491SRishi.Srivatsavai@Sun.COM 		mrh = mimpl->mi_default_tx_ring;			\
29310491SRishi.Srivatsavai@Sun.COM 	if (mrh == NULL) {						\
29410491SRishi.Srivatsavai@Sun.COM 		rest = mimpl->mi_tx(mimpl->mi_driver, mp);		\
29510491SRishi.Srivatsavai@Sun.COM 	} else {							\
29610491SRishi.Srivatsavai@Sun.COM 		rest = mac_hwring_tx(mrh, mp);				\
29710491SRishi.Srivatsavai@Sun.COM 	}								\
29810491SRishi.Srivatsavai@Sun.COM }
29910491SRishi.Srivatsavai@Sun.COM 
30010491SRishi.Srivatsavai@Sun.COM /*
30110491SRishi.Srivatsavai@Sun.COM  * This is the final stop before reaching the underlying driver
30210491SRishi.Srivatsavai@Sun.COM  * or aggregation, so this is where the bridging hook is implemented.
30310491SRishi.Srivatsavai@Sun.COM  * Packets that are bridged will return through mac_bridge_tx(), with
30410491SRishi.Srivatsavai@Sun.COM  * rh nulled out if the bridge chooses to send output on a different
30510491SRishi.Srivatsavai@Sun.COM  * link due to forwarding.
30610491SRishi.Srivatsavai@Sun.COM  */
30710491SRishi.Srivatsavai@Sun.COM #define	MAC_TX(mip, rh, mp, share_bound) {				\
30810491SRishi.Srivatsavai@Sun.COM 	/*								\
30910491SRishi.Srivatsavai@Sun.COM 	 * If there is a bound Hybrid I/O share, send packets through 	\
31010491SRishi.Srivatsavai@Sun.COM 	 * the default tx ring. (When there's a bound Hybrid I/O share,	\
31110491SRishi.Srivatsavai@Sun.COM 	 * the tx rings of this client are mapped in the guest domain 	\
31210491SRishi.Srivatsavai@Sun.COM 	 * and not accessible from here.)				\
31310491SRishi.Srivatsavai@Sun.COM 	 */								\
31410491SRishi.Srivatsavai@Sun.COM 	_NOTE(CONSTANTCONDITION)					\
31510491SRishi.Srivatsavai@Sun.COM 	if (share_bound)						\
31610491SRishi.Srivatsavai@Sun.COM 		rh = NULL;						\
31710491SRishi.Srivatsavai@Sun.COM 	/*								\
31810491SRishi.Srivatsavai@Sun.COM 	 * Grab the proper transmit pointer and handle. Special 	\
31910491SRishi.Srivatsavai@Sun.COM 	 * optimization: we can test mi_bridge_link itself atomically,	\
32010491SRishi.Srivatsavai@Sun.COM 	 * and if that indicates no bridge send packets through tx ring.\
32110491SRishi.Srivatsavai@Sun.COM 	 */								\
32210491SRishi.Srivatsavai@Sun.COM 	if (mip->mi_bridge_link == NULL) {				\
32310491SRishi.Srivatsavai@Sun.COM 		MAC_RING_TX(mip, rh, mp, mp);				\
32410491SRishi.Srivatsavai@Sun.COM 	} else {							\
32510491SRishi.Srivatsavai@Sun.COM 		mp = mac_bridge_tx(mip, rh, mp);			\
32610491SRishi.Srivatsavai@Sun.COM 	}								\
3278275SEric Cheng }
3288275SEric Cheng 
3298275SEric Cheng /* mci_tx_flag */
3308275SEric Cheng #define	MCI_TX_QUIESCE	0x1
3318275SEric Cheng 
3328275SEric Cheng typedef struct mac_factory_addr_s {
3338275SEric Cheng 	boolean_t		mfa_in_use;
3348275SEric Cheng 	uint8_t			mfa_addr[MAXMACADDRLEN];
3358275SEric Cheng 	struct mac_client_impl_s	*mfa_client;
3368275SEric Cheng } mac_factory_addr_t;
3375895Syz147064 
3388275SEric Cheng typedef struct mac_mcast_addrs_s {
3398275SEric Cheng 	struct mac_mcast_addrs_s	*mma_next;
3408275SEric Cheng 	uint8_t				mma_addr[MAXMACADDRLEN];
3418275SEric Cheng 	int				mma_ref;
3428275SEric Cheng } mac_mcast_addrs_t;
3438275SEric Cheng 
3448275SEric Cheng typedef enum {
3458275SEric Cheng 	MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED = 1,	/* hardware steering */
3468275SEric Cheng 	MAC_ADDRESS_TYPE_UNICAST_PROMISC		/* promiscuous mode */
3478275SEric Cheng } mac_address_type_t;
3488275SEric Cheng 
3498275SEric Cheng typedef struct mac_impl_s mac_impl_t;
3508275SEric Cheng 
3518275SEric Cheng typedef struct mac_address_s {
3528275SEric Cheng 	mac_address_type_t	ma_type;		/* address type */
3538275SEric Cheng 	int			ma_nusers;		/* number of users */
3548275SEric Cheng 							/* of that address */
3558275SEric Cheng 	struct mac_address_s	*ma_next;		/* next address */
3568275SEric Cheng 	uint8_t			ma_addr[MAXMACADDRLEN];	/* address value */
3578275SEric Cheng 	size_t			ma_len;			/* address length */
3588275SEric Cheng 	mac_group_t		*ma_group;		/* asscociated group */
3598275SEric Cheng 	mac_impl_t		*ma_mip;		/* MAC handle */
3608275SEric Cheng } mac_address_t;
3618275SEric Cheng 
3628275SEric Cheng extern krwlock_t i_mac_impl_lock;
3638275SEric Cheng extern mod_hash_t *i_mac_impl_hash;
3648275SEric Cheng extern kmem_cache_t *i_mac_impl_cachep;
3658275SEric Cheng extern uint_t i_mac_impl_count;
3665895Syz147064 
3678275SEric Cheng /*
3688275SEric Cheng  * Each registered MAC is associated with a mac_impl_t structure. The
3698275SEric Cheng  * structure represents the undelying hardware, in terms of definition,
3708275SEric Cheng  * resources (transmit, receive rings etc.), callback functions etc. It
3718275SEric Cheng  * also holds the table of MAC clients that are configured on the device.
3728275SEric Cheng  * The table is used for classifying incoming packets in software.
3738275SEric Cheng  *
3748275SEric Cheng  * The protection scheme uses 2 elements, a coarse serialization mechanism
3758275SEric Cheng  * called perimeter and a finer traditional lock based scheme. More details
3768275SEric Cheng  * can be found in the big block comment in mac.c.
3778275SEric Cheng  *
3788275SEric Cheng  * The protection scheme for each member of the mac_impl_t is described below.
3798275SEric Cheng  *
3808275SEric Cheng  * Write Once Only (WO): Typically these don't change for the lifetime of the
3818275SEric Cheng  * data structure. For example something in mac_impl_t that stays the same
3828275SEric Cheng  * from mac_register to mac_unregister, or something in a mac_client_impl_t
3838275SEric Cheng  * that stays the same from mac_client_open to mac_client_close.
3848275SEric Cheng  *
3858275SEric Cheng  * Serializer (SL): Protected by the Serializer. All SLOP operations on a
3868275SEric Cheng  * mac endpoint go through the serializer. MTOPs don't care about reading
3878275SEric Cheng  * these fields atomically.
3888275SEric Cheng  *
3898275SEric Cheng  * Lock: Traditional mutex/rw lock. Modify operations still go through the
3908275SEric Cheng  * mac serializer, the lock helps synchronize readers with writers.
3918275SEric Cheng  */
3928275SEric Cheng struct mac_impl_s {
3938275SEric Cheng 	krwlock_t		mi_rw_lock;
3948275SEric Cheng 	char			mi_name[LIFNAMSIZ];	/* WO */
3958275SEric Cheng 	uint32_t		mi_state_flags;
3968275SEric Cheng 	void			*mi_driver;		/* Driver private, WO */
3978275SEric Cheng 	mac_info_t		mi_info;		/* WO */
3988275SEric Cheng 	mactype_t		*mi_type;		/* WO */
3998275SEric Cheng 	void			*mi_pdata;		/* WO */
4008275SEric Cheng 	size_t			mi_pdata_size;		/* WO */
4018275SEric Cheng 	mac_callbacks_t		*mi_callbacks;		/* WO */
4028275SEric Cheng 	dev_info_t		*mi_dip;		/* WO */
4038275SEric Cheng 	uint32_t		mi_ref;			/* i_mac_impl_lock */
4048275SEric Cheng 	uint_t			mi_active;		/* SL */
4058275SEric Cheng 	link_state_t		mi_linkstate;		/* none */
40610491SRishi.Srivatsavai@Sun.COM 	link_state_t		mi_lowlinkstate;	/* none */
40710491SRishi.Srivatsavai@Sun.COM 	link_state_t		mi_lastlowlinkstate;	/* none */
4088275SEric Cheng 	uint_t			mi_devpromisc;		/* SL */
4098275SEric Cheng 	kmutex_t		mi_lock;
4108275SEric Cheng 	uint8_t			mi_addr[MAXMACADDRLEN];	/* mi_rw_lock */
4118275SEric Cheng 	uint8_t			mi_dstaddr[MAXMACADDRLEN]; /* mi_rw_lock */
41210616SSebastien.Roy@Sun.COM 	boolean_t		mi_dstaddr_set;
4135895Syz147064 
4148275SEric Cheng 	/*
4158275SEric Cheng 	 * The mac perimeter. All client initiated create/modify operations
4168275SEric Cheng 	 * on a mac end point go through this.
4178275SEric Cheng 	 */
4188275SEric Cheng 	kmutex_t		mi_perim_lock;
4198275SEric Cheng 	kthread_t		*mi_perim_owner;	/* mi_perim_lock */
4208275SEric Cheng 	uint_t			mi_perim_ocnt;		/* mi_perim_lock */
4218275SEric Cheng 	kcondvar_t		mi_perim_cv;		/* mi_perim_lock */
4225895Syz147064 
4238275SEric Cheng 	/* mac notification callbacks */
4248275SEric Cheng 	kmutex_t		mi_notify_lock;
4258275SEric Cheng 	mac_cb_info_t		mi_notify_cb_info;	/* mi_notify_lock */
4268275SEric Cheng 	mac_cb_t		*mi_notify_cb_list;	/* mi_notify_lock */
4278275SEric Cheng 	kthread_t		*mi_notify_thread;	/* mi_notify_lock */
4288275SEric Cheng 	uint_t			mi_notify_bits;		/* mi_notify_lock */
4298275SEric Cheng 
4308275SEric Cheng 	uint32_t		mi_v12n_level;		/* Virt'ion readiness */
4318275SEric Cheng 
4328275SEric Cheng 	/*
4338275SEric Cheng 	 * RX groups, ring capability
4348275SEric Cheng 	 * Fields of this block are SL protected.
4358275SEric Cheng 	 */
4368275SEric Cheng 	mac_group_type_t	mi_rx_group_type;	/* grouping type */
4378275SEric Cheng 	uint_t			mi_rx_group_count;
4388275SEric Cheng 	mac_group_t		*mi_rx_groups;
4395895Syz147064 
4408275SEric Cheng 	mac_capab_rings_t	mi_rx_rings_cap;
4418275SEric Cheng 
4428275SEric Cheng 	/*
4438275SEric Cheng 	 * TX groups and ring capability, SL Protected.
4448275SEric Cheng 	 */
4458275SEric Cheng 	mac_group_type_t	mi_tx_group_type;	/* grouping type */
4468275SEric Cheng 	uint_t			mi_tx_group_count;
4478275SEric Cheng 	uint_t			mi_tx_group_free;
4488275SEric Cheng 	mac_group_t		*mi_tx_groups;
4498275SEric Cheng 
4508275SEric Cheng 	mac_capab_rings_t	mi_tx_rings_cap;
4518275SEric Cheng 
4528275SEric Cheng 	mac_ring_handle_t	mi_default_tx_ring;
4535895Syz147064 
4548275SEric Cheng 	/*
4558275SEric Cheng 	 * MAC address list. SL protected.
4568275SEric Cheng 	 */
4578275SEric Cheng 	mac_address_t		*mi_addresses;
4588275SEric Cheng 
4598275SEric Cheng 	/*
4608275SEric Cheng 	 * This MAC's table of sub-flows
4618275SEric Cheng 	 */
4628275SEric Cheng 	flow_tab_t		*mi_flow_tab;		/* WO */
4638275SEric Cheng 
4648275SEric Cheng 	kstat_t			*mi_ksp;		/* WO */
4658275SEric Cheng 	uint_t			mi_kstat_count;		/* WO */
4668275SEric Cheng 	uint_t			mi_nactiveclients;	/* SL */
4678275SEric Cheng 
4688275SEric Cheng 	/* for broadcast and multicast support */
4698275SEric Cheng 	struct mac_mcast_addrs_s *mi_mcast_addrs;	/* mi_rw_lock */
4708275SEric Cheng 	struct mac_bcast_grp_s *mi_bcast_grp;		/* mi_rw_lock */
4718275SEric Cheng 	uint_t			mi_bcast_ngrps;		/* mi_rw_lock */
4725895Syz147064 
4738275SEric Cheng 	/* list of MAC clients which opened this MAC */
4748275SEric Cheng 	struct mac_client_impl_s *mi_clients_list;	/* mi_rw_lock */
4758275SEric Cheng 	uint_t			mi_nclients;		/* mi_rw_lock */
4768833SVenu.Iyer@Sun.COM 	struct mac_client_impl_s *mi_single_active_client; /* mi_rw_lock */
4778275SEric Cheng 
4788275SEric Cheng 	uint32_t		mi_margin;		/* mi_rw_lock */
4798275SEric Cheng 	uint_t			mi_sdu_min;		/* mi_rw_lock */
4808275SEric Cheng 	uint_t			mi_sdu_max;		/* mi_rw_lock */
4818275SEric Cheng 
4828275SEric Cheng 	/*
4838275SEric Cheng 	 * Cache of factory MAC addresses provided by the driver. If
4848275SEric Cheng 	 * the driver doesn't provide multiple factory MAC addresses,
4858275SEric Cheng 	 * the mi_factory_addr is set to NULL, and mi_factory_addr_num
4868275SEric Cheng 	 * is set to zero.
4878275SEric Cheng 	 */
4888275SEric Cheng 	mac_factory_addr_t	*mi_factory_addr;	/* mi_rw_lock */
4898275SEric Cheng 	uint_t			mi_factory_addr_num;	/* mi_rw_lock */
4905895Syz147064 
4918275SEric Cheng 	/* for promiscuous mode support */
4928275SEric Cheng 	kmutex_t		mi_promisc_lock;
4938275SEric Cheng 	mac_cb_t		*mi_promisc_list;	/* mi_promisc_lock */
4948275SEric Cheng 	mac_cb_info_t		mi_promisc_cb_info;	/* mi_promisc_lock */
4958275SEric Cheng 
4968275SEric Cheng 	/* cache of rings over this mac_impl */
4978275SEric Cheng 	kmutex_t		mi_ring_lock;
4988275SEric Cheng 	mac_ring_t		*mi_ring_freelist;	/* mi_ring_lock */
4995895Syz147064 
5005895Syz147064 	/*
5018275SEric Cheng 	 * These are used for caching the properties, if any, for the
5028275SEric Cheng 	 * primary MAC client. If the MAC client is not yet in place
5038275SEric Cheng 	 * when the properties are set then we cache them here to be
5048275SEric Cheng 	 * applied to the MAC client when it is created.
5058275SEric Cheng 	 */
5068275SEric Cheng 	mac_resource_props_t	mi_resource_props;	/* SL */
50710491SRishi.Srivatsavai@Sun.COM 	uint16_t		mi_pvid;		/* SL */
5088275SEric Cheng 
5098275SEric Cheng 	minor_t			mi_minor;		/* WO */
5109073SCathy.Zhou@Sun.COM 	uint32_t		mi_oref;		/* SL */
5119073SCathy.Zhou@Sun.COM 	mac_capab_legacy_t	mi_capab_legacy;	/* WO */
5128275SEric Cheng 	dev_t			mi_phy_dev;		/* WO */
5139073SCathy.Zhou@Sun.COM 
5148275SEric Cheng 	/*
5155895Syz147064 	 * List of margin value requests added by mac clients. This list is
5165895Syz147064 	 * sorted: the first one has the greatest value.
5175895Syz147064 	 */
5185895Syz147064 	mac_margin_req_t	*mi_mmrp;
5196512Ssowmini 	mac_priv_prop_t		*mi_priv_prop;
5206512Ssowmini 	uint_t			mi_priv_prop_count;
5218275SEric Cheng 
5228275SEric Cheng 	/*
5238275SEric Cheng 	 * Hybrid I/O related definitions.
5248275SEric Cheng 	 */
5258275SEric Cheng 	mac_capab_share_t	mi_share_capab;
5268275SEric Cheng 
52710491SRishi.Srivatsavai@Sun.COM 	/*
52810491SRishi.Srivatsavai@Sun.COM 	 * Bridging hooks and limit values.  Uses mutex and reference counts
52910491SRishi.Srivatsavai@Sun.COM 	 * (bridging only) for data path.  Limits need no synchronization.
53010491SRishi.Srivatsavai@Sun.COM 	 */
53110491SRishi.Srivatsavai@Sun.COM 	mac_handle_t		mi_bridge_link;
53210491SRishi.Srivatsavai@Sun.COM 	kmutex_t		mi_bridge_lock;
53310491SRishi.Srivatsavai@Sun.COM 	uint32_t		mi_llimit;
53410491SRishi.Srivatsavai@Sun.COM 	uint32_t		mi_ldecay;
53510491SRishi.Srivatsavai@Sun.COM 
5368275SEric Cheng /* This should be the last block in this structure */
5378275SEric Cheng #ifdef DEBUG
5388275SEric Cheng #define	MAC_PERIM_STACK_DEPTH	15
5398275SEric Cheng 	int			mi_perim_stack_depth;
5408275SEric Cheng 	pc_t			mi_perim_stack[MAC_PERIM_STACK_DEPTH];
5418275SEric Cheng #endif
5428275SEric Cheng };
5438275SEric Cheng 
5448275SEric Cheng /* for mi_state_flags */
5458275SEric Cheng #define	MIS_DISABLED		0x0001
5468275SEric Cheng #define	MIS_IS_VNIC		0x0002
5478275SEric Cheng #define	MIS_IS_AGGR		0x0004
5488275SEric Cheng #define	MIS_NOTIFY_DONE		0x0008
5498275SEric Cheng #define	MIS_EXCLUSIVE		0x0010
5508275SEric Cheng #define	MIS_EXCLUSIVE_HELD	0x0020
5518275SEric Cheng #define	MIS_LEGACY		0x0040
55210491SRishi.Srivatsavai@Sun.COM #define	MIS_NO_ACTIVE		0x0080
55310491SRishi.Srivatsavai@Sun.COM #define	MIS_POLL_DISABLE	0x0100
5542311Sseb 
5552311Sseb #define	mi_getstat	mi_callbacks->mc_getstat
5562311Sseb #define	mi_start	mi_callbacks->mc_start
5572311Sseb #define	mi_stop		mi_callbacks->mc_stop
5585895Syz147064 #define	mi_open		mi_callbacks->mc_open
5595895Syz147064 #define	mi_close	mi_callbacks->mc_close
5602311Sseb #define	mi_setpromisc	mi_callbacks->mc_setpromisc
5612311Sseb #define	mi_multicst	mi_callbacks->mc_multicst
5622311Sseb #define	mi_unicst	mi_callbacks->mc_unicst
5632311Sseb #define	mi_tx		mi_callbacks->mc_tx
5642311Sseb #define	mi_ioctl	mi_callbacks->mc_ioctl
5652311Sseb #define	mi_getcapab	mi_callbacks->mc_getcapab
5660Sstevel@tonic-gate 
5678275SEric Cheng typedef struct mac_notify_task_arg {
5688275SEric Cheng 	mac_impl_t		*mnt_mip;
5698275SEric Cheng 	mac_notify_type_t	mnt_type;
5708275SEric Cheng 	mac_ring_t		*mnt_ring;
5718275SEric Cheng } mac_notify_task_arg_t;
5728275SEric Cheng 
5738275SEric Cheng typedef enum {
5748275SEric Cheng 	MAC_RX_NO_RESERVE,
5758275SEric Cheng 	MAC_RX_RESERVE_DEFAULT,
5768275SEric Cheng 	MAC_RX_RESERVE_NONDEFAULT
5778275SEric Cheng } mac_rx_group_reserve_type_t;
5788275SEric Cheng 
5798275SEric Cheng /*
5808275SEric Cheng  * XXX All MAC_DBG_PRTs must be replaced with call to dtrace probes. For now
5818275SEric Cheng  * it may be easier to have these printfs for easier debugging
5828275SEric Cheng  */
5838275SEric Cheng #ifdef DEBUG
5848275SEric Cheng extern int mac_dbg;
5858275SEric Cheng #define	MAC_DBG_PRT(a)	if (mac_dbg > 0) {(void) printf a; }
5868275SEric Cheng #else
5878275SEric Cheng #define	MAC_DBG_PRT(a)
5888275SEric Cheng #endif
5898275SEric Cheng 
5908275SEric Cheng /*
5918275SEric Cheng  * The mac_perim_handle_t is an opaque type that encodes the 'mip' pointer
5928275SEric Cheng  * and whether internally a mac_open was done when acquiring the perimeter.
5938275SEric Cheng  */
5948275SEric Cheng #define	MAC_ENCODE_MPH(mph, mh, need_close)		\
5958275SEric Cheng 	(mph) = (mac_perim_handle_t)((uintptr_t)(mh) | need_close)
5968275SEric Cheng 
5978275SEric Cheng #define	MAC_DECODE_MPH(mph, mip, need_close) {		\
5988275SEric Cheng 	mip = (mac_impl_t *)(((uintptr_t)mph) & ~0x1);	\
5998275SEric Cheng 	(need_close) = ((uintptr_t)mph & 0x1);		\
6008275SEric Cheng }
6018275SEric Cheng 
6028275SEric Cheng typedef struct mac_client_impl_s mac_client_impl_t;
6038275SEric Cheng 
6040Sstevel@tonic-gate extern void	mac_init(void);
6050Sstevel@tonic-gate extern int	mac_fini(void);
6060Sstevel@tonic-gate 
6070Sstevel@tonic-gate extern void	mac_stat_create(mac_impl_t *);
6080Sstevel@tonic-gate extern void	mac_stat_destroy(mac_impl_t *);
6092311Sseb extern uint64_t	mac_stat_default(mac_impl_t *, uint_t);
6108275SEric Cheng extern void	mac_ndd_ioctl(mac_impl_t *, queue_t *, mblk_t *);
6118275SEric Cheng extern void	mac_create_soft_ring_kstats(mac_impl_t *, int32_t);
6128275SEric Cheng extern boolean_t mac_ip_hdr_length_v6(mblk_t *, ip6_t *, uint16_t *,
6138275SEric Cheng     uint8_t *);
6140Sstevel@tonic-gate 
6158275SEric Cheng extern mblk_t *mac_copymsgchain_cksum(mblk_t *);
6168275SEric Cheng extern mblk_t *mac_fix_cksum(mblk_t *);
6178275SEric Cheng extern void mac_packet_print(mac_handle_t, mblk_t *);
6188275SEric Cheng extern void mac_rx_deliver(void *, mac_resource_handle_t, mblk_t *,
6198275SEric Cheng     mac_header_info_t *);
6208275SEric Cheng extern void mac_tx_notify(mac_impl_t *);
6218275SEric Cheng 
6228275SEric Cheng extern	boolean_t mac_callback_find(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
6238275SEric Cheng extern	void	mac_callback_add(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
6248275SEric Cheng extern	boolean_t mac_callback_remove(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
6258275SEric Cheng extern	void	mac_callback_remove_wait(mac_cb_info_t *);
6268275SEric Cheng extern	void	mac_callback_free(mac_cb_t *);
6278275SEric Cheng extern	mac_cb_t *mac_callback_walker_cleanup(mac_cb_info_t *, mac_cb_t **);
6288275SEric Cheng 
6298275SEric Cheng /* in mac_bcast.c */
6308275SEric Cheng extern void mac_bcast_init(void);
6318275SEric Cheng extern void mac_bcast_fini(void);
6328275SEric Cheng extern mac_impl_t *mac_bcast_grp_mip(void *);
6338275SEric Cheng extern int mac_bcast_add(mac_client_impl_t *, const uint8_t *, uint16_t,
6348275SEric Cheng     mac_addrtype_t);
6358275SEric Cheng extern void mac_bcast_delete(mac_client_impl_t *, const uint8_t *, uint16_t);
6368275SEric Cheng extern void mac_bcast_send(void *, void *, mblk_t *, boolean_t);
6378275SEric Cheng extern void mac_bcast_grp_free(void *);
6388275SEric Cheng extern void mac_bcast_refresh(mac_impl_t *, mac_multicst_t, void *,
6398275SEric Cheng     boolean_t);
6408275SEric Cheng extern void mac_client_bcast_refresh(mac_client_impl_t *, mac_multicst_t,
6418275SEric Cheng     void *, boolean_t);
6428275SEric Cheng 
6438275SEric Cheng /*
6448275SEric Cheng  * Grouping functions are used internally by MAC layer.
6458275SEric Cheng  */
6468275SEric Cheng extern int mac_group_addmac(mac_group_t *, const uint8_t *);
6478275SEric Cheng extern int mac_group_remmac(mac_group_t *, const uint8_t *);
6488275SEric Cheng extern int mac_rx_group_add_flow(mac_client_impl_t *, flow_entry_t *,
6498275SEric Cheng     mac_group_t *);
65010309SSriharsha.Basavapatna@Sun.COM extern mblk_t *mac_hwring_tx(mac_ring_handle_t, mblk_t *);
65110491SRishi.Srivatsavai@Sun.COM extern mblk_t *mac_bridge_tx(mac_impl_t *, mac_ring_handle_t, mblk_t *);
6528275SEric Cheng extern mac_ring_t *mac_reserve_tx_ring(mac_impl_t *, mac_ring_t *);
6538275SEric Cheng extern void mac_release_tx_ring(mac_ring_handle_t);
6548275SEric Cheng extern mac_group_t *mac_reserve_tx_group(mac_impl_t *, mac_share_handle_t);
6558275SEric Cheng extern void mac_release_tx_group(mac_impl_t *, mac_group_t *);
6568275SEric Cheng 
6578275SEric Cheng /*
6588275SEric Cheng  * MAC address functions are used internally by MAC layer.
6598275SEric Cheng  */
6608275SEric Cheng extern mac_address_t *mac_find_macaddr(mac_impl_t *, uint8_t *);
6618275SEric Cheng extern boolean_t mac_check_macaddr_shared(mac_address_t *);
6628275SEric Cheng extern int mac_update_macaddr(mac_address_t *, uint8_t *);
6638275SEric Cheng extern void mac_freshen_macaddr(mac_address_t *, uint8_t *);
6648275SEric Cheng extern void mac_retrieve_macaddr(mac_address_t *, uint8_t *);
6658275SEric Cheng extern void mac_init_macaddr(mac_impl_t *);
6668275SEric Cheng extern void mac_fini_macaddr(mac_impl_t *);
6678275SEric Cheng 
6688275SEric Cheng /*
6698275SEric Cheng  * Flow construction/destruction routines.
6708275SEric Cheng  * Not meant to be used by mac clients.
6718275SEric Cheng  */
6728275SEric Cheng extern int mac_link_flow_init(mac_client_handle_t, flow_entry_t *);
6738275SEric Cheng extern void mac_link_flow_clean(mac_client_handle_t, flow_entry_t *);
6748275SEric Cheng 
6758275SEric Cheng /*
6768400SNicolas.Droux@Sun.COM  * Fanout update routines called when the link speed of the NIC changes
6778400SNicolas.Droux@Sun.COM  * or when a MAC client's share is unbound.
6788275SEric Cheng  */
6798400SNicolas.Droux@Sun.COM extern void mac_fanout_recompute_client(mac_client_impl_t *);
6808275SEric Cheng extern void mac_fanout_recompute(mac_impl_t *);
6818275SEric Cheng 
6828275SEric Cheng /*
6838275SEric Cheng  * The following functions are used internally by the MAC layer to
6848275SEric Cheng  * add/remove/update flows associated with a mac_impl_t. They should
6858275SEric Cheng  * never be used directly by MAC clients.
6868275SEric Cheng  */
6878275SEric Cheng extern int mac_datapath_setup(mac_client_impl_t *, flow_entry_t *, uint32_t);
6888275SEric Cheng extern void mac_datapath_teardown(mac_client_impl_t *, flow_entry_t *,
6898275SEric Cheng     uint32_t);
6908275SEric Cheng extern void mac_srs_group_setup(mac_client_impl_t *, flow_entry_t *,
6918275SEric Cheng     mac_group_t *, uint32_t);
6928275SEric Cheng extern void mac_srs_group_teardown(mac_client_impl_t *, flow_entry_t *,
6938275SEric Cheng 	    uint32_t);
6948275SEric Cheng extern int mac_rx_classify_flow_quiesce(flow_entry_t *, void *);
6958275SEric Cheng extern int mac_rx_classify_flow_restart(flow_entry_t *, void *);
6968275SEric Cheng extern void mac_tx_client_quiesce(mac_client_impl_t *, uint_t);
6978275SEric Cheng extern void mac_tx_client_restart(mac_client_impl_t *);
6988275SEric Cheng extern void mac_client_quiesce(mac_client_impl_t *);
6998275SEric Cheng extern void mac_client_restart(mac_client_impl_t *);
7008275SEric Cheng 
7018275SEric Cheng extern void mac_flow_update_priority(mac_client_impl_t *, flow_entry_t *);
7028275SEric Cheng 
7038275SEric Cheng extern void mac_flow_rem_subflow(flow_entry_t *);
7048275SEric Cheng extern void mac_rename_flow(flow_entry_t *, const char *);
7058275SEric Cheng extern void mac_flow_set_name(flow_entry_t *, const char *);
7068275SEric Cheng 
7078275SEric Cheng extern mblk_t *mac_add_vlan_tag(mblk_t *, uint_t, uint16_t);
7088275SEric Cheng extern mblk_t *mac_add_vlan_tag_chain(mblk_t *, uint_t, uint16_t);
7098275SEric Cheng extern mblk_t *mac_strip_vlan_tag_chain(mblk_t *);
7108275SEric Cheng extern void mac_pkt_drop(void *, mac_resource_handle_t, mblk_t *, boolean_t);
7118275SEric Cheng extern mblk_t *mac_rx_flow(mac_handle_t, mac_resource_handle_t, mblk_t *);
7128275SEric Cheng 
7138275SEric Cheng extern void i_mac_share_alloc(mac_client_impl_t *);
7148275SEric Cheng extern void i_mac_share_free(mac_client_impl_t *);
7158275SEric Cheng extern void i_mac_perim_enter(mac_impl_t *);
7168275SEric Cheng extern void i_mac_perim_exit(mac_impl_t *);
7178275SEric Cheng extern int i_mac_perim_enter_nowait(mac_impl_t *);
7188275SEric Cheng extern void i_mac_tx_srs_notify(mac_impl_t *, mac_ring_handle_t);
7198275SEric Cheng extern int mac_hold(const char *, mac_impl_t **);
7208275SEric Cheng extern void mac_rele(mac_impl_t *);
7218275SEric Cheng extern int i_mac_disable(mac_impl_t *);
7228275SEric Cheng extern void i_mac_notify(mac_impl_t *, mac_notify_type_t);
7238275SEric Cheng extern void i_mac_notify_exit(mac_impl_t *);
7248275SEric Cheng extern void mac_rx_group_unmark(mac_group_t *, uint_t);
7258275SEric Cheng extern void mac_tx_client_flush(mac_client_impl_t *);
7268275SEric Cheng extern void mac_tx_client_block(mac_client_impl_t *);
7278275SEric Cheng extern void mac_tx_client_unblock(mac_client_impl_t *);
7289641SGirish.Moodalbail@Sun.COM extern int i_mac_promisc_set(mac_impl_t *, boolean_t);
7298275SEric Cheng extern void i_mac_promisc_walker_cleanup(mac_impl_t *);
7308275SEric Cheng extern mactype_t *mactype_getplugin(const char *);
7318275SEric Cheng extern void mac_addr_factory_init(mac_impl_t *);
7328275SEric Cheng extern void mac_addr_factory_fini(mac_impl_t *);
7338275SEric Cheng extern void mac_register_priv_prop(mac_impl_t *, mac_priv_prop_t *, uint_t);
7348275SEric Cheng extern void mac_unregister_priv_prop(mac_impl_t *);
7358275SEric Cheng extern int mac_init_rings(mac_impl_t *, mac_ring_type_t);
7368275SEric Cheng extern void mac_free_rings(mac_impl_t *, mac_ring_type_t);
7378275SEric Cheng 
7388275SEric Cheng extern int mac_start_group(mac_group_t *);
7398275SEric Cheng extern void mac_stop_group(mac_group_t *);
7408275SEric Cheng extern int mac_start_ring(mac_ring_t *);
7418275SEric Cheng extern void mac_stop_ring(mac_ring_t *);
7428400SNicolas.Droux@Sun.COM extern int mac_add_macaddr(mac_impl_t *, mac_group_t *, uint8_t *, boolean_t);
7438275SEric Cheng extern int mac_remove_macaddr(mac_address_t *);
7448275SEric Cheng 
7458275SEric Cheng extern void mac_set_rx_group_state(mac_group_t *, mac_group_state_t);
7468275SEric Cheng extern void mac_rx_group_add_client(mac_group_t *, mac_client_impl_t *);
7478275SEric Cheng extern void mac_rx_group_remove_client(mac_group_t *, mac_client_impl_t *)
7488275SEric Cheng ;
7498275SEric Cheng extern int i_mac_group_add_ring(mac_group_t *, mac_ring_t *, int);
7508275SEric Cheng extern void i_mac_group_rem_ring(mac_group_t *, mac_ring_t *, boolean_t);
7516512Ssowmini 
75210491SRishi.Srivatsavai@Sun.COM extern void mac_poll_state_change(mac_handle_t, boolean_t);
75310491SRishi.Srivatsavai@Sun.COM 
75410491SRishi.Srivatsavai@Sun.COM /* Global callbacks into the bridging module (when loaded) */
75510491SRishi.Srivatsavai@Sun.COM extern mac_bridge_tx_t mac_bridge_tx_cb;
75610491SRishi.Srivatsavai@Sun.COM extern mac_bridge_rx_t mac_bridge_rx_cb;
75710491SRishi.Srivatsavai@Sun.COM extern mac_bridge_ref_t mac_bridge_ref_cb;
75810491SRishi.Srivatsavai@Sun.COM extern mac_bridge_ls_t mac_bridge_ls_cb;
75910491SRishi.Srivatsavai@Sun.COM 
7600Sstevel@tonic-gate #ifdef	__cplusplus
7610Sstevel@tonic-gate }
7620Sstevel@tonic-gate #endif
7630Sstevel@tonic-gate 
7640Sstevel@tonic-gate #endif	/* _SYS_MAC_IMPL_H */
765