xref: /onnv-gate/usr/src/uts/common/sys/softmac_impl.h (revision 9073:a5a4bb23741e)
15895Syz147064 /*
25895Syz147064  * CDDL HEADER START
35895Syz147064  *
45895Syz147064  * The contents of this file are subject to the terms of the
55895Syz147064  * Common Development and Distribution License (the "License").
65895Syz147064  * You may not use this file except in compliance with the License.
75895Syz147064  *
85895Syz147064  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95895Syz147064  * or http://www.opensolaris.org/os/licensing.
105895Syz147064  * See the License for the specific language governing permissions
115895Syz147064  * and limitations under the License.
125895Syz147064  *
135895Syz147064  * When distributing Covered Code, include this CDDL HEADER in each
145895Syz147064  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155895Syz147064  * If applicable, add the following below this CDDL HEADER, with the
165895Syz147064  * fields enclosed by brackets "[]" replaced with your own identifying
175895Syz147064  * information: Portions Copyright [yyyy] [name of copyright owner]
185895Syz147064  *
195895Syz147064  * CDDL HEADER END
205895Syz147064  */
215895Syz147064 /*
228527SCathy.Zhou@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
235895Syz147064  * Use is subject to license terms.
245895Syz147064  */
255895Syz147064 
265895Syz147064 #ifndef	_SYS_SOFTMAC_IMPL_H
275895Syz147064 #define	_SYS_SOFTMAC_IMPL_H
285895Syz147064 
295895Syz147064 #include <sys/types.h>
305895Syz147064 #include <sys/ethernet.h>
315895Syz147064 #include <sys/taskq.h>
325895Syz147064 #include <sys/sunddi.h>
335895Syz147064 #include <sys/sunldi.h>
345895Syz147064 #include <sys/strsun.h>
355895Syz147064 #include <sys/stream.h>
365895Syz147064 #include <sys/dlpi.h>
375895Syz147064 #include <sys/mac.h>
388275SEric Cheng #include <sys/mac_provider.h>
398275SEric Cheng #include <sys/mac_client.h>
408275SEric Cheng #include <sys/mac_client_priv.h>
415895Syz147064 #include <sys/mac_ether.h>
425895Syz147064 
435895Syz147064 #ifdef	__cplusplus
445895Syz147064 extern "C" {
455895Syz147064 #endif
465895Syz147064 
47*9073SCathy.Zhou@Sun.COM typedef void	(*softmac_rx_t)(void *, mac_resource_handle_t, mblk_t *,
48*9073SCathy.Zhou@Sun.COM 		    mac_header_info_t *);
49*9073SCathy.Zhou@Sun.COM 
50*9073SCathy.Zhou@Sun.COM typedef struct softmac_lower_rxinfo_s {
51*9073SCathy.Zhou@Sun.COM 	softmac_rx_t	slr_rx;
52*9073SCathy.Zhou@Sun.COM 	void		*slr_arg;
53*9073SCathy.Zhou@Sun.COM } softmac_lower_rxinfo_t;
54*9073SCathy.Zhou@Sun.COM 
555895Syz147064 typedef struct softmac_lower_s {
56*9073SCathy.Zhou@Sun.COM 	ldi_handle_t		sl_lh;
575895Syz147064 	struct softmac		*sl_softmac;
585895Syz147064 	queue_t			*sl_wq;
59*9073SCathy.Zhou@Sun.COM 	struct softmac_upper_s	*sl_sup;
60*9073SCathy.Zhou@Sun.COM 	softmac_lower_rxinfo_t	*sl_rxinfo;
615895Syz147064 
625895Syz147064 	/*
635895Syz147064 	 * sl_ctl_inprogress is used to serialize the control path.  It will
645895Syz147064 	 * be set when either an ioctl or an M_{PC,}PROTO message is received
655895Syz147064 	 * from the upper layer, and will be cleared when processing done.
665895Syz147064 	 */
675895Syz147064 	kmutex_t		sl_ctl_mutex;
685895Syz147064 	kcondvar_t		sl_ctl_cv;
695895Syz147064 	boolean_t		sl_ctl_inprogress;
705895Syz147064 
715895Syz147064 	/*
725895Syz147064 	 * When a control message is processed, either sl_pending_prim or
735895Syz147064 	 * sl_pending_ioctl will be set.  They will be cleared when the
745895Syz147064 	 * acknowledgement of the specific control message is received
755895Syz147064 	 * from the underlying legacy driver.
765895Syz147064 	 */
775895Syz147064 	kmutex_t		sl_mutex;
785895Syz147064 	kcondvar_t		sl_cv;
795895Syz147064 	t_uscalar_t		sl_pending_prim;
805895Syz147064 	boolean_t		sl_pending_ioctl;
815895Syz147064 	mblk_t			*sl_ack_mp;
825895Syz147064 } softmac_lower_t;
835895Syz147064 
848275SEric Cheng typedef enum {
855895Syz147064 	SOFTMAC_INITIALIZED,
865895Syz147064 	SOFTMAC_READY
878275SEric Cheng } softmac_lower_state_t;
888275SEric Cheng 
898275SEric Cheng typedef enum {
908275SEric Cheng 	SOFTMAC_UNINIT,
918275SEric Cheng 	SOFTMAC_ATTACH_INPROG,
928275SEric Cheng 	SOFTMAC_ATTACH_DONE,
938275SEric Cheng 	SOFTMAC_DETACH_INPROG,
948275SEric Cheng } softmac_state_t;
955895Syz147064 
965895Syz147064 typedef struct softmac_dev_s {
975895Syz147064 	dev_t	sd_dev;
985895Syz147064 } softmac_dev_t;
995895Syz147064 
1005895Syz147064 /*
1015895Syz147064  * smac_flag values.
1025895Syz147064  */
1035895Syz147064 #define	SOFTMAC_GLDV3		0x01
1045895Syz147064 #define	SOFTMAC_NOSUPP		0x02
1058275SEric Cheng #define	SOFTMAC_NEED_RECREATE	0x04
1068275SEric Cheng #define	SOFTMAC_NOTIFY_QUIT	0x08
1078275SEric Cheng 
1088275SEric Cheng #define	SMAC_NONZERO_NODECNT(softmac)		\
1098275SEric Cheng 	((softmac->smac_softmac[0] != NULL) +	\
1108275SEric Cheng 	(softmac->smac_softmac[1] != NULL))
1115895Syz147064 
1125895Syz147064 /*
1135895Syz147064  * The softmac structure allows all minor nodes (at most two, style-1 and
1145895Syz147064  * style-2) for the same device to be processed.  A softmac_dev_t will be
1155895Syz147064  * created for each minor node.
1165895Syz147064  *
1175895Syz147064  * We try to "register" the mac after all the softmac_dev_t's are processed so
1185895Syz147064  * that even if DLPI operations fail (because of driver bugs) for one minor
1195895Syz147064  * node, the other minor node can still be used to register the mac.
1205895Syz147064  * (Specifically, an incorrect xxx_getinfo() implementation will cause style-2
1215895Syz147064  * minor node mac registration to fail.)
122*9073SCathy.Zhou@Sun.COM  *
123*9073SCathy.Zhou@Sun.COM  * Locking description:
124*9073SCathy.Zhou@Sun.COM  *	WO: write once, valid the life time.
1255895Syz147064  */
1265895Syz147064 typedef struct softmac {
127*9073SCathy.Zhou@Sun.COM 	char		smac_devname[MAXNAMELEN];	/* WO */
128*9073SCathy.Zhou@Sun.COM 	major_t		smac_umajor;			/* WO */
129*9073SCathy.Zhou@Sun.COM 	int		smac_uppa;			/* WO */
130*9073SCathy.Zhou@Sun.COM 	uint32_t	smac_cnt;	/* WO, # of minor nodes */
131*9073SCathy.Zhou@Sun.COM 
132*9073SCathy.Zhou@Sun.COM 	kmutex_t	smac_mutex;
133*9073SCathy.Zhou@Sun.COM 	kcondvar_t	smac_cv;
134*9073SCathy.Zhou@Sun.COM 	softmac_state_t	smac_state;		/* smac_mutex */
1355895Syz147064 	/*
1365895Syz147064 	 * The smac_hold_cnt field increases when softmac_hold_device() is
1375895Syz147064 	 * called to force the dls_vlan_t of the device to be created.  The
1385895Syz147064 	 * device pre-detach fails if this counter is not 0.
1395895Syz147064 	 */
140*9073SCathy.Zhou@Sun.COM 	uint32_t	smac_hold_cnt;		/* smac_mutex */
141*9073SCathy.Zhou@Sun.COM 	uint32_t	smac_flags;		/* smac_mutex */
142*9073SCathy.Zhou@Sun.COM 	int		smac_attacherr;		/* smac_mutex */
1435895Syz147064 	mac_handle_t	smac_mh;
144*9073SCathy.Zhou@Sun.COM 	softmac_dev_t	*smac_softmac[2];	/* smac_mutex */
145*9073SCathy.Zhou@Sun.COM 
1465895Syz147064 	/*
1475895Syz147064 	 * Number of minor nodes whose post-attach routine has succeeded.
1485895Syz147064 	 * This should be the same as the numbers of softmac_dev_t.
1495895Syz147064 	 * Note that it does not imply SOFTMAC_ATTACH_DONE as the taskq might
1505895Syz147064 	 * be still ongoing.
1515895Syz147064 	 */
152*9073SCathy.Zhou@Sun.COM 	uint32_t	smac_attachok_cnt;	/* smac_mutex */
1535895Syz147064 	/*
1545895Syz147064 	 * Number of softmac_dev_t left when pre-detach fails. This is used
1555895Syz147064 	 * to indicate whether postattach is called because of a failed
1565895Syz147064 	 * pre-detach.
1575895Syz147064 	 */
158*9073SCathy.Zhou@Sun.COM 	uint32_t	smac_attached_left;	/* smac_mutex */
1595895Syz147064 
1605895Syz147064 	/*
1618275SEric Cheng 	 * Thread handles the DL_NOTIFY_IND message from the lower stream.
1628275SEric Cheng 	 */
163*9073SCathy.Zhou@Sun.COM 	kthread_t	*smac_notify_thread;	/* smac_mutex */
1648275SEric Cheng 	/*
1658275SEric Cheng 	 * Head and tail of the DL_NOTIFY_IND messsages.
1668275SEric Cheng 	 */
167*9073SCathy.Zhou@Sun.COM 	mblk_t		*smac_notify_head;	/* smac_mutex */
168*9073SCathy.Zhou@Sun.COM 	mblk_t		*smac_notify_tail;	/* smac_mutex */
1698275SEric Cheng 
1708275SEric Cheng 	/*
1715895Syz147064 	 * The remaining fields are used to register the MAC for a legacy
1725895Syz147064 	 * device.  They are set in softmac_mac_register() and do not change.
1735895Syz147064 	 * One can access them when mac_register() is done without locks.
1745895Syz147064 	 */
1755895Syz147064 
1765895Syz147064 	/*
1775895Syz147064 	 * media type is needed for create <link name, linkid> mapping, so
1785895Syz147064 	 * it is set for GLDv3 device as well
1795895Syz147064 	 */
1805895Syz147064 	uint_t		smac_media;
1815895Syz147064 	/* DLPI style of the underlying device */
1825895Syz147064 	int		smac_style;
1835895Syz147064 	dev_t		smac_dev;
1845895Syz147064 	size_t		smac_saplen;
1855895Syz147064 	size_t		smac_addrlen;
1865895Syz147064 	uchar_t		smac_unicst_addr[MAXMACADDRLEN];
1875895Syz147064 	uint_t		smac_min_sdu;
1885895Syz147064 	uint_t		smac_max_sdu;
1895895Syz147064 	uint32_t	smac_margin;
1905895Syz147064 
1915895Syz147064 	/* Notifications the underlying driver can support. */
1925895Syz147064 	uint32_t	smac_notifications;
1935895Syz147064 
1945895Syz147064 	/*
1955895Syz147064 	 * Capabilities of the underlying driver.
1965895Syz147064 	 */
1975895Syz147064 	uint32_t	smac_capab_flags;
1985895Syz147064 	uint32_t	smac_hcksum_txflags;
1995895Syz147064 	boolean_t	smac_no_capability_req;
2005895Syz147064 	dl_capab_mdt_t	smac_mdt_capab;
2015895Syz147064 	boolean_t	smac_mdt;
2025895Syz147064 
203*9073SCathy.Zhou@Sun.COM 	/*
204*9073SCathy.Zhou@Sun.COM 	 * Lower stream structure, accessed by the MAC provider API. The GLDv3
205*9073SCathy.Zhou@Sun.COM 	 * framework assures it's validity.
206*9073SCathy.Zhou@Sun.COM 	 */
2075895Syz147064 	softmac_lower_t	*smac_lower;
208*9073SCathy.Zhou@Sun.COM 
209*9073SCathy.Zhou@Sun.COM 	kmutex_t	smac_active_mutex;
210*9073SCathy.Zhou@Sun.COM 	/*
211*9073SCathy.Zhou@Sun.COM 	 * Set by xxx_active_set() when aggregation is created.
212*9073SCathy.Zhou@Sun.COM 	 */
213*9073SCathy.Zhou@Sun.COM 	boolean_t	smac_active;	/* smac_active_mutex */
214*9073SCathy.Zhou@Sun.COM 	/*
215*9073SCathy.Zhou@Sun.COM 	 * Numbers of the bounded streams in the fast-path mode.
216*9073SCathy.Zhou@Sun.COM 	 */
217*9073SCathy.Zhou@Sun.COM 	uint32_t	smac_nactive;	/* smac_active_mutex */
218*9073SCathy.Zhou@Sun.COM 
219*9073SCathy.Zhou@Sun.COM 	kmutex_t	smac_fp_mutex;
220*9073SCathy.Zhou@Sun.COM 	kcondvar_t	smac_fp_cv;
221*9073SCathy.Zhou@Sun.COM 	/*
222*9073SCathy.Zhou@Sun.COM 	 * numbers of clients that request to disable fastpath.
223*9073SCathy.Zhou@Sun.COM 	 */
224*9073SCathy.Zhou@Sun.COM 	uint32_t	smac_fp_disable_clients;	/* smac_fp_mutex */
225*9073SCathy.Zhou@Sun.COM 	boolean_t	smac_fastpath_admin_disabled;	/* smac_fp_mutex */
226*9073SCathy.Zhou@Sun.COM 
227*9073SCathy.Zhou@Sun.COM 	/*
228*9073SCathy.Zhou@Sun.COM 	 * stream list over this softmac.
229*9073SCathy.Zhou@Sun.COM 	 */
230*9073SCathy.Zhou@Sun.COM 	list_t			smac_sup_list;		/* smac_fp_mutex */
2315895Syz147064 } softmac_t;
2325895Syz147064 
2335895Syz147064 typedef struct smac_ioc_start_s {
2345895Syz147064 	softmac_lower_t	*si_slp;
2355895Syz147064 } smac_ioc_start_t;
2365895Syz147064 
2375895Syz147064 #define	SMAC_IOC	('S' << 24 | 'M' << 16 | 'C' << 8)
2385895Syz147064 #define	SMAC_IOC_START	(SMAC_IOC | 0x01)
2395895Syz147064 
240*9073SCathy.Zhou@Sun.COM /*
241*9073SCathy.Zhou@Sun.COM  * The su_mode of a non-IP/ARP stream is UNKNOWN, and the su_mode of an IP/ARP
242*9073SCathy.Zhou@Sun.COM  * stream is either SLOWPATH or FASTPATH.
243*9073SCathy.Zhou@Sun.COM  */
244*9073SCathy.Zhou@Sun.COM #define	SOFTMAC_UNKNOWN		0x00
245*9073SCathy.Zhou@Sun.COM #define	SOFTMAC_SLOWPATH	0x01
246*9073SCathy.Zhou@Sun.COM #define	SOFTMAC_FASTPATH	0x02
247*9073SCathy.Zhou@Sun.COM 
248*9073SCathy.Zhou@Sun.COM typedef struct softmac_switch_req_s {
249*9073SCathy.Zhou@Sun.COM 	list_node_t	ssq_req_list_node;
250*9073SCathy.Zhou@Sun.COM 	uint32_t	ssq_expected_mode;
251*9073SCathy.Zhou@Sun.COM } softmac_switch_req_t;
252*9073SCathy.Zhou@Sun.COM 
253*9073SCathy.Zhou@Sun.COM #define	DATAPATH_MODE(softmac)						\
254*9073SCathy.Zhou@Sun.COM 	((((softmac)->smac_fp_disable_clients != 0) ||			\
255*9073SCathy.Zhou@Sun.COM 	(softmac)->smac_fastpath_admin_disabled) ? SOFTMAC_SLOWPATH :	\
256*9073SCathy.Zhou@Sun.COM 	SOFTMAC_FASTPATH)
257*9073SCathy.Zhou@Sun.COM 
258*9073SCathy.Zhou@Sun.COM 
259*9073SCathy.Zhou@Sun.COM /*
260*9073SCathy.Zhou@Sun.COM  * Locking description:
261*9073SCathy.Zhou@Sun.COM  *
262*9073SCathy.Zhou@Sun.COM  *	WO: Set once and valid for life;
263*9073SCathy.Zhou@Sun.COM  *	SL: Serialized by the control path (softmac_wput_nondata_task())
264*9073SCathy.Zhou@Sun.COM  */
265*9073SCathy.Zhou@Sun.COM typedef struct softmac_upper_s {
266*9073SCathy.Zhou@Sun.COM 	softmac_t		*su_softmac;	/* WO */
267*9073SCathy.Zhou@Sun.COM 	queue_t			*su_rq;		/* WO */
268*9073SCathy.Zhou@Sun.COM 	queue_t			*su_wq;		/* WO */
269*9073SCathy.Zhou@Sun.COM 
270*9073SCathy.Zhou@Sun.COM 	/*
271*9073SCathy.Zhou@Sun.COM 	 * List of upper streams that has pending DLPI messages to be processed.
272*9073SCathy.Zhou@Sun.COM 	 */
273*9073SCathy.Zhou@Sun.COM 	list_node_t		su_taskq_list_node; /* softmac_taskq_lock */
274*9073SCathy.Zhou@Sun.COM 
275*9073SCathy.Zhou@Sun.COM 	/*
276*9073SCathy.Zhou@Sun.COM 	 * non-NULL for IP/ARP streams in the fast-path mode
277*9073SCathy.Zhou@Sun.COM 	 */
278*9073SCathy.Zhou@Sun.COM 	softmac_lower_t		*su_slp;	/* SL & su_mutex */
279*9073SCathy.Zhou@Sun.COM 
280*9073SCathy.Zhou@Sun.COM 	/*
281*9073SCathy.Zhou@Sun.COM 	 * List of all IP/ARP upperstreams on the same softmac (including
282*9073SCathy.Zhou@Sun.COM 	 * the ones in both data-path modes).
283*9073SCathy.Zhou@Sun.COM 	 */
284*9073SCathy.Zhou@Sun.COM 	list_node_t		su_list_node;	/* smac_fp_mutex */
285*9073SCathy.Zhou@Sun.COM 
286*9073SCathy.Zhou@Sun.COM 	/*
287*9073SCathy.Zhou@Sun.COM 	 * List of datapath switch requests.
288*9073SCathy.Zhou@Sun.COM 	 */
289*9073SCathy.Zhou@Sun.COM 	list_t			su_req_list;	/* smac_fp_mutex */
290*9073SCathy.Zhou@Sun.COM 
291*9073SCathy.Zhou@Sun.COM 	/*
292*9073SCathy.Zhou@Sun.COM 	 * Place holder of RX callbacks used to handles data messages comes
293*9073SCathy.Zhou@Sun.COM 	 * from the dedicated-lower-stream associated with the IP/ARP stream.
294*9073SCathy.Zhou@Sun.COM 	 * Another RX callback is softmac_drop_rxinfo, which is a global
295*9073SCathy.Zhou@Sun.COM 	 * variable.
296*9073SCathy.Zhou@Sun.COM 	 */
297*9073SCathy.Zhou@Sun.COM 	softmac_lower_rxinfo_t	su_rxinfo;		/* WO */
298*9073SCathy.Zhou@Sun.COM 	softmac_lower_rxinfo_t	su_direct_rxinfo;	/* WO */
299*9073SCathy.Zhou@Sun.COM 
300*9073SCathy.Zhou@Sun.COM 	/*
301*9073SCathy.Zhou@Sun.COM 	 * Used to serialize the DLPI operation and fastpath<->slowpath
302*9073SCathy.Zhou@Sun.COM 	 * switching over operation.
303*9073SCathy.Zhou@Sun.COM 	 */
304*9073SCathy.Zhou@Sun.COM 	kmutex_t		su_disp_mutex;
305*9073SCathy.Zhou@Sun.COM 	kcondvar_t		su_disp_cv;
306*9073SCathy.Zhou@Sun.COM 	mblk_t			*su_pending_head;	/* su_disp_mutex */
307*9073SCathy.Zhou@Sun.COM 	mblk_t			*su_pending_tail;	/* su_disp_mutex */
308*9073SCathy.Zhou@Sun.COM 	boolean_t		su_dlpi_pending;	/* su_disp_mutex */
309*9073SCathy.Zhou@Sun.COM 	boolean_t		su_closing;		/* su_disp_mutex */
310*9073SCathy.Zhou@Sun.COM 
311*9073SCathy.Zhou@Sun.COM 	uint32_t		su_bound : 1,		/* SL */
312*9073SCathy.Zhou@Sun.COM 				su_active : 1,		/* SL */
313*9073SCathy.Zhou@Sun.COM 				su_direct : 1;		/* SL */
314*9073SCathy.Zhou@Sun.COM 
315*9073SCathy.Zhou@Sun.COM 	/*
316*9073SCathy.Zhou@Sun.COM 	 * Used for fastpath data path.
317*9073SCathy.Zhou@Sun.COM 	 */
318*9073SCathy.Zhou@Sun.COM 	kmutex_t		su_mutex;
319*9073SCathy.Zhou@Sun.COM 	kcondvar_t		su_cv;
320*9073SCathy.Zhou@Sun.COM 	mblk_t			*su_tx_flow_mp;		/* su_mutex */
321*9073SCathy.Zhou@Sun.COM 	boolean_t		su_tx_busy;		/* su_mutex */
322*9073SCathy.Zhou@Sun.COM 	/*
323*9073SCathy.Zhou@Sun.COM 	 * Number of softmac_srv() operation in fastpath processing.
324*9073SCathy.Zhou@Sun.COM 	 */
325*9073SCathy.Zhou@Sun.COM 	uint32_t		su_tx_inprocess;	/* su_mutex */
326*9073SCathy.Zhou@Sun.COM 	/*
327*9073SCathy.Zhou@Sun.COM 	 * SOFTMAC_SLOWPATH or SOFTMAC_FASTPATH
328*9073SCathy.Zhou@Sun.COM 	 */
329*9073SCathy.Zhou@Sun.COM 	uint32_t		su_mode;		/* SL & su_mutex */
330*9073SCathy.Zhou@Sun.COM 
331*9073SCathy.Zhou@Sun.COM 	/*
332*9073SCathy.Zhou@Sun.COM 	 * Whether this stream is already scheduled in softmac_taskq_list.
333*9073SCathy.Zhou@Sun.COM 	 */
334*9073SCathy.Zhou@Sun.COM 	boolean_t		su_taskq_scheduled;	/* softmac_taskq_lock */
335*9073SCathy.Zhou@Sun.COM } softmac_upper_t;
336*9073SCathy.Zhou@Sun.COM 
337*9073SCathy.Zhou@Sun.COM #define	SOFTMAC_EQ_PENDING(sup, mp) {					\
338*9073SCathy.Zhou@Sun.COM 	if ((sup)->su_pending_head == NULL) {				\
339*9073SCathy.Zhou@Sun.COM 		(sup)->su_pending_head = (sup)->su_pending_tail = (mp);	\
340*9073SCathy.Zhou@Sun.COM 	} else {							\
341*9073SCathy.Zhou@Sun.COM 		(sup)->su_pending_tail->b_next = (mp);			\
342*9073SCathy.Zhou@Sun.COM 		(sup)->su_pending_tail = (mp);				\
343*9073SCathy.Zhou@Sun.COM 	}								\
344*9073SCathy.Zhou@Sun.COM }
345*9073SCathy.Zhou@Sun.COM 
346*9073SCathy.Zhou@Sun.COM #define	SOFTMAC_DQ_PENDING(sup, mpp) {					\
347*9073SCathy.Zhou@Sun.COM 	if ((sup)->su_pending_head == NULL) {				\
348*9073SCathy.Zhou@Sun.COM 		*(mpp) = NULL;						\
349*9073SCathy.Zhou@Sun.COM 	} else {							\
350*9073SCathy.Zhou@Sun.COM 		*(mpp) = (sup)->su_pending_head;			\
351*9073SCathy.Zhou@Sun.COM 		if (((sup)->su_pending_head = (*(mpp))->b_next) == NULL)\
352*9073SCathy.Zhou@Sun.COM 			(sup)->su_pending_tail = NULL;			\
353*9073SCathy.Zhou@Sun.COM 		(*(mpp))->b_next = NULL;				\
354*9073SCathy.Zhou@Sun.COM 	}								\
355*9073SCathy.Zhou@Sun.COM }
356*9073SCathy.Zhou@Sun.COM 
357*9073SCathy.Zhou@Sun.COM /*
358*9073SCathy.Zhou@Sun.COM  * A macro to check whether the write-queue of the lower stream is full
359*9073SCathy.Zhou@Sun.COM  * and packets need to be enqueued.
360*9073SCathy.Zhou@Sun.COM  *
361*9073SCathy.Zhou@Sun.COM  * Because softmac is pushed right above the underlying device and
362*9073SCathy.Zhou@Sun.COM  * _I_INSERT/_I_REMOVE is not processed in the lower stream, it is
363*9073SCathy.Zhou@Sun.COM  * safe to directly access the q_next pointer.
364*9073SCathy.Zhou@Sun.COM  */
365*9073SCathy.Zhou@Sun.COM #define	SOFTMAC_CANPUTNEXT(q)	\
366*9073SCathy.Zhou@Sun.COM 	(!((q)->q_next->q_nfsrv->q_flag & QFULL) || canput((q)->q_next))
367*9073SCathy.Zhou@Sun.COM 
368*9073SCathy.Zhou@Sun.COM 
3695895Syz147064 extern dev_info_t		*softmac_dip;
3705895Syz147064 #define	SOFTMAC_DEV_NAME	"softmac"
3715895Syz147064 
3725895Syz147064 extern int	softmac_send_bind_req(softmac_lower_t *, uint_t);
373*9073SCathy.Zhou@Sun.COM extern int	softmac_send_unbind_req(softmac_lower_t *);
3745895Syz147064 extern int	softmac_send_notify_req(softmac_lower_t *, uint32_t);
3755895Syz147064 extern int	softmac_send_promisc_req(softmac_lower_t *, t_uscalar_t,
3765895Syz147064     boolean_t);
377*9073SCathy.Zhou@Sun.COM extern void	softmac_init();
378*9073SCathy.Zhou@Sun.COM extern void	softmac_fini();
379*9073SCathy.Zhou@Sun.COM extern void	softmac_fp_init();
380*9073SCathy.Zhou@Sun.COM extern void	softmac_fp_fini();
381*9073SCathy.Zhou@Sun.COM extern boolean_t softmac_busy();
3825895Syz147064 extern int	softmac_fill_capab(ldi_handle_t, softmac_t *);
3835895Syz147064 extern int	softmac_capab_enable(softmac_lower_t *);
384*9073SCathy.Zhou@Sun.COM extern void	softmac_rput_process_notdata(queue_t *, softmac_upper_t *,
385*9073SCathy.Zhou@Sun.COM     mblk_t *);
3865895Syz147064 extern void	softmac_rput_process_data(softmac_lower_t *, mblk_t *);
387*9073SCathy.Zhou@Sun.COM extern int	softmac_output(softmac_lower_t *, mblk_t *, t_uscalar_t,
388*9073SCathy.Zhou@Sun.COM     t_uscalar_t, mblk_t **);
389*9073SCathy.Zhou@Sun.COM extern int	softmac_mexchange_error_ack(mblk_t **, t_uscalar_t,
390*9073SCathy.Zhou@Sun.COM     t_uscalar_t, t_uscalar_t);
3915895Syz147064 
3925895Syz147064 extern int	softmac_m_promisc(void *, boolean_t);
3935895Syz147064 extern int	softmac_m_multicst(void *, boolean_t, const uint8_t *);
3945895Syz147064 extern int	softmac_m_unicst(void *, const uint8_t *);
3955895Syz147064 extern void	softmac_m_ioctl(void *, queue_t *, mblk_t *);
3965895Syz147064 extern int	softmac_m_stat(void *, uint_t, uint64_t *);
3975895Syz147064 extern mblk_t	*softmac_m_tx(void *, mblk_t *);
3985895Syz147064 extern int	softmac_proto_tx(softmac_lower_t *, mblk_t *, mblk_t **);
3995895Syz147064 extern void	softmac_ioctl_tx(softmac_lower_t *, mblk_t *, mblk_t **);
4008275SEric Cheng extern void	softmac_notify_thread(void *);
4015895Syz147064 
402*9073SCathy.Zhou@Sun.COM extern int	softmac_hold(dev_t, softmac_t **);
403*9073SCathy.Zhou@Sun.COM extern void	softmac_rele(softmac_t *);
404*9073SCathy.Zhou@Sun.COM extern int	softmac_lower_setup(softmac_t *, softmac_upper_t *,
405*9073SCathy.Zhou@Sun.COM     softmac_lower_t **);
406*9073SCathy.Zhou@Sun.COM extern boolean_t	softmac_active_set(void *);
407*9073SCathy.Zhou@Sun.COM extern void	softmac_active_clear(void *);
408*9073SCathy.Zhou@Sun.COM extern int	softmac_fastpath_disable(void *);
409*9073SCathy.Zhou@Sun.COM extern void	softmac_fastpath_enable(void *);
410*9073SCathy.Zhou@Sun.COM extern int	softmac_datapath_switch(softmac_t *, boolean_t, boolean_t);
411*9073SCathy.Zhou@Sun.COM 
412*9073SCathy.Zhou@Sun.COM extern void	softmac_wput_data(softmac_upper_t *, mblk_t *);
413*9073SCathy.Zhou@Sun.COM extern void	softmac_wput_nondata(softmac_upper_t *, mblk_t *);
414*9073SCathy.Zhou@Sun.COM extern void	softmac_upperstream_close(softmac_upper_t *);
415*9073SCathy.Zhou@Sun.COM 
4165895Syz147064 #ifdef	__cplusplus
4175895Syz147064 }
4185895Syz147064 #endif
4195895Syz147064 
4205895Syz147064 #endif	/* _SYS_SOFTMAC_IMPL_H */
421