xref: /onnv-gate/usr/src/uts/common/sys/dld_impl.h (revision 11474:857f9db4ef05)
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
51804Sericheng  * Common Development and Distribution License (the "License").
61804Sericheng  * 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 /*
22*11474SJonathan.Adams@Sun.COM  * Copyright 2010 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_DLD_IMPL_H
270Sstevel@tonic-gate #define	_SYS_DLD_IMPL_H
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <sys/types.h>
308275SEric Cheng #include <sys/list.h>
310Sstevel@tonic-gate #include <sys/ethernet.h>
320Sstevel@tonic-gate #include <sys/stream.h>
330Sstevel@tonic-gate #include <sys/dlpi.h>
340Sstevel@tonic-gate #include <sys/dld.h>
358275SEric Cheng #include <sys/dls_impl.h>
360Sstevel@tonic-gate 
370Sstevel@tonic-gate #ifdef	__cplusplus
380Sstevel@tonic-gate extern "C" {
390Sstevel@tonic-gate #endif
400Sstevel@tonic-gate 
417408SSebastien.Roy@Sun.COM #define	DLD_CONTROL_MINOR_NAME	"ctl"
427408SSebastien.Roy@Sun.COM #define	DLD_CONTROL_MINOR	0
437408SSebastien.Roy@Sun.COM 
440Sstevel@tonic-gate #define	DLD_CONTROL	0x00000001
450Sstevel@tonic-gate #define	DLD_DLPI	0x00000002
460Sstevel@tonic-gate 
470Sstevel@tonic-gate typedef enum {
480Sstevel@tonic-gate 	DLD_UNITDATA,
490Sstevel@tonic-gate 	DLD_FASTPATH,
500Sstevel@tonic-gate 	DLD_RAW
510Sstevel@tonic-gate } dld_str_mode_t;
520Sstevel@tonic-gate 
530Sstevel@tonic-gate typedef enum {
540Sstevel@tonic-gate 	DLD_UNINITIALIZED,
550Sstevel@tonic-gate 	DLD_PASSIVE,
560Sstevel@tonic-gate 	DLD_ACTIVE
570Sstevel@tonic-gate } dld_passivestate_t;
580Sstevel@tonic-gate 
598275SEric Cheng /*
608275SEric Cheng  * The dld_str_t object definition and protection scheme for each member
618275SEric Cheng  * is described below. The framework locking mechanism details are described in
628275SEric Cheng  * mac_impl.h and mac.c
638275SEric Cheng  *
648275SEric Cheng  * Write Once Only (WO): Typically these are initialized when the end point
658275SEric Cheng  * is created or initialized and don't change subsequently
668275SEric Cheng  *
678275SEric Cheng  * Serializer (SL): Protected by the Serializer. All modify operations on an
688275SEric Cheng  * end point go through the serializer. Readers don't care about reading
698275SEric Cheng  * these fields atomically, or readers also use the serializer to see the
708275SEric Cheng  * values atomically.
718275SEric Cheng  *
728275SEric Cheng  * Lock: kmutex_t or kwrlock_t lock. Modify operations still go through the
738275SEric Cheng  * serializer, the lock helps synchronize readers with writers.
748275SEric Cheng  */
750Sstevel@tonic-gate 
768275SEric Cheng struct dld_str_s {					/* Protected by */
770Sstevel@tonic-gate 	/*
78269Sericheng 	 * Major number of the device
79269Sericheng 	 */
808275SEric Cheng 	major_t			ds_major;		/* WO */
81269Sericheng 
82269Sericheng 	/*
830Sstevel@tonic-gate 	 * Ephemeral minor number for the object.
840Sstevel@tonic-gate 	 */
858275SEric Cheng 	minor_t			ds_minor;		/* WO */
868275SEric Cheng 
878275SEric Cheng 	/*
888275SEric Cheng 	 * PPA number this stream is attached to.
898275SEric Cheng 	 */
908275SEric Cheng 	t_uscalar_t		ds_ppa;			/* SL */
910Sstevel@tonic-gate 
920Sstevel@tonic-gate 	/*
930Sstevel@tonic-gate 	 * Read/write queues for the stream which the object represents.
940Sstevel@tonic-gate 	 */
958275SEric Cheng 	queue_t			*ds_rq;			/* WO */
968275SEric Cheng 	queue_t			*ds_wq;			/* WO */
97269Sericheng 
98269Sericheng 	/*
990Sstevel@tonic-gate 	 * Stream is open to DLD_CONTROL (control node) or
1000Sstevel@tonic-gate 	 * DLD_DLPI (DLS provider) node.
1010Sstevel@tonic-gate 	 */
1028275SEric Cheng 	uint_t			ds_type;		/* WO */
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate 	/*
1050Sstevel@tonic-gate 	 * The following fields are only used for DLD_DLPI type objects.
1060Sstevel@tonic-gate 	 */
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate 	/*
1090Sstevel@tonic-gate 	 * Current DLPI state.
1100Sstevel@tonic-gate 	 */
1119002SCathy.Zhou@Sun.COM 	t_uscalar_t		ds_dlstate;		/* SL */
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate 	/*
114269Sericheng 	 * DLPI style
115269Sericheng 	 */
1168275SEric Cheng 	t_uscalar_t		ds_style;		/* WO */
117269Sericheng 
118269Sericheng 	/*
1190Sstevel@tonic-gate 	 * Currently bound DLSAP.
1200Sstevel@tonic-gate 	 */
1218275SEric Cheng 	uint16_t		ds_sap;			/* SL */
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate 	/*
1240Sstevel@tonic-gate 	 * Handle of the MAC that is used by the data-link interface.
1250Sstevel@tonic-gate 	 */
1268275SEric Cheng 	mac_handle_t		ds_mh;			/* SL */
1278275SEric Cheng 	mac_client_handle_t	ds_mch;			/* SL */
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate 	/*
1300Sstevel@tonic-gate 	 * Promiscuity level information.
1310Sstevel@tonic-gate 	 */
1328275SEric Cheng 	uint32_t		ds_promisc;		/* SL */
1338275SEric Cheng 	mac_promisc_handle_t	ds_mph;
1348275SEric Cheng 	mac_promisc_handle_t	ds_vlan_mph;
1350Sstevel@tonic-gate 
1360Sstevel@tonic-gate 	/*
1370Sstevel@tonic-gate 	 * Immutable information of the MAC which the channel is using.
1380Sstevel@tonic-gate 	 */
1398275SEric Cheng 	const mac_info_t	*ds_mip;		/* SL */
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate 	/*
1420Sstevel@tonic-gate 	 * Current packet priority.
1430Sstevel@tonic-gate 	 */
1448275SEric Cheng 	uint_t			ds_pri;			/* SL */
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate 	/*
1470Sstevel@tonic-gate 	 * Handle of our MAC notification callback.
1480Sstevel@tonic-gate 	 */
1498275SEric Cheng 	mac_notify_handle_t	ds_mnh;			/* SL */
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate 	/*
1520Sstevel@tonic-gate 	 * Set of enabled DL_NOTE... notifications. (See dlpi.h).
1530Sstevel@tonic-gate 	 */
1548275SEric Cheng 	uint32_t		ds_notifications;	/* SL */
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate 	/*
1570Sstevel@tonic-gate 	 * Mode: unitdata, fast-path or raw.
1580Sstevel@tonic-gate 	 */
1598275SEric Cheng 	dld_str_mode_t		ds_mode;		/* SL */
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate 	/*
1623147Sxc151355 	 * Native mode state.
1633147Sxc151355 	 */
1648275SEric Cheng 	boolean_t		ds_native;		/* SL */
1653147Sxc151355 
1663147Sxc151355 	/*
1670Sstevel@tonic-gate 	 * IP polling is operational if this flag is set.
1680Sstevel@tonic-gate 	 */
1698275SEric Cheng 	boolean_t		ds_polling;		/* SL */
1708275SEric Cheng 	boolean_t		ds_direct;		/* SL */
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate 	/*
1733115Syl150051 	 * LSO is enabled if ds_lso is set.
1743115Syl150051 	 */
1758275SEric Cheng 	boolean_t		ds_lso;			/* SL */
1768275SEric Cheng 	uint64_t		ds_lso_max;		/* SL */
1773115Syl150051 
1783115Syl150051 	/*
1790Sstevel@tonic-gate 	 * State of DLPI user: may be active (regular network layer),
1800Sstevel@tonic-gate 	 * passive (snoop-like monitoring), or unknown (not yet
1810Sstevel@tonic-gate 	 * determined).
1820Sstevel@tonic-gate 	 */
1838275SEric Cheng 	dld_passivestate_t	ds_passivestate;	/* SL */
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate 	/*
186269Sericheng 	 * Dummy mblk used for flow-control.
187269Sericheng 	 */
1888275SEric Cheng 	mblk_t			*ds_tx_flow_mp;		/* ds_lock */
1895895Syz147064 
1905895Syz147064 	/*
1918275SEric Cheng 	 * List of queued DLPI requests. These will be processed
1928275SEric Cheng 	 * by a taskq thread. This block is protected by ds_lock
1935895Syz147064 	 */
1948275SEric Cheng 	kmutex_t		ds_lock;
1958275SEric Cheng 	krwlock_t		ds_rw_lock;
1968275SEric Cheng 	kcondvar_t		ds_datathr_cv;		/* ds_lock */
1978275SEric Cheng 	uint_t			ds_datathr_cnt;		/* ds_lock */
1988275SEric Cheng 	mblk_t			*ds_pending_head;	/* ds_lock */
1998275SEric Cheng 	mblk_t			*ds_pending_tail;	/* ds_lock */
2008275SEric Cheng 	kcondvar_t		ds_dlpi_pending_cv;	/* ds_lock */
2018275SEric Cheng 	uint32_t
2028275SEric Cheng 				ds_dlpi_pending : 1,	/* ds_lock */
2038275SEric Cheng 				ds_local	: 1,
2048275SEric Cheng 				ds_pad		: 30;	/* ds_lock */
2055895Syz147064 
2068275SEric Cheng 	dls_link_t		*ds_dlp;		/* SL */
2078275SEric Cheng 	dls_multicst_addr_t	*ds_dmap;		/* ds_rw_lock */
2088275SEric Cheng 	dls_rx_t		ds_rx;			/* ds_lock */
2098275SEric Cheng 	void			*ds_rx_arg;		/* ds_lock */
2109073SCathy.Zhou@Sun.COM 	uint_t			ds_nactive;		/* SL */
2118275SEric Cheng 	dld_str_t		*ds_next;		/* SL */
2128275SEric Cheng 	dls_head_t		*ds_head;
2138275SEric Cheng 	dls_dl_handle_t		ds_ddh;
2148275SEric Cheng 	list_node_t		ds_tqlist;
2159073SCathy.Zhou@Sun.COM 
2169073SCathy.Zhou@Sun.COM 	/*
2179073SCathy.Zhou@Sun.COM 	 * driver private data set by the driver when calling dld_str_open().
2189073SCathy.Zhou@Sun.COM 	 */
2199073SCathy.Zhou@Sun.COM 	void			*ds_private;
22010491SRishi.Srivatsavai@Sun.COM 
22110491SRishi.Srivatsavai@Sun.COM 	boolean_t		ds_lowlink;		/* SL */
22211021SEric.Cheng@Sun.COM 	boolean_t		ds_nonip;		/* SL */
2237378SShuguo.Yang@Sun.COM };
2240Sstevel@tonic-gate 
2259073SCathy.Zhou@Sun.COM 
2268275SEric Cheng #define	DLD_DATATHR_INC(dsp)	{		\
2278275SEric Cheng 	ASSERT(MUTEX_HELD(&(dsp)->ds_lock));	\
2288275SEric Cheng 	dsp->ds_datathr_cnt++;			\
2295895Syz147064 }
2305895Syz147064 
2318275SEric Cheng #define	DLD_DATATHR_DCR(dsp)	{		\
2328275SEric Cheng 	mutex_enter(&(dsp)->ds_lock);		\
2338275SEric Cheng 	(dsp)->ds_datathr_cnt--;		\
2348275SEric Cheng 	if ((dsp)->ds_datathr_cnt == 0)		\
2358275SEric Cheng 		cv_broadcast(&(dsp)->ds_datathr_cv);	\
2368275SEric Cheng 	mutex_exit(&(dsp)->ds_lock);		\
2375895Syz147064 }
2385895Syz147064 
2390Sstevel@tonic-gate /*
2400Sstevel@tonic-gate  * dld_str.c module.
2410Sstevel@tonic-gate  */
2420Sstevel@tonic-gate 
2430Sstevel@tonic-gate extern void		dld_str_init(void);
2440Sstevel@tonic-gate extern int		dld_str_fini(void);
245269Sericheng extern dld_str_t	*dld_str_create(queue_t *, uint_t, major_t,
246269Sericheng     t_uscalar_t);
2470Sstevel@tonic-gate extern void		dld_str_destroy(dld_str_t *);
248269Sericheng extern int		dld_str_attach(dld_str_t *, t_uscalar_t);
2490Sstevel@tonic-gate extern void		dld_str_detach(dld_str_t *);
2500Sstevel@tonic-gate extern void		dld_str_rx_raw(void *, mac_resource_handle_t,
2512760Sdg199075     mblk_t *, mac_header_info_t *);
2520Sstevel@tonic-gate extern void		dld_str_rx_fastpath(void *, mac_resource_handle_t,
2532760Sdg199075     mblk_t *, mac_header_info_t *);
2540Sstevel@tonic-gate extern void		dld_str_rx_unitdata(void *, mac_resource_handle_t,
2552760Sdg199075     mblk_t *, mac_header_info_t *);
2560Sstevel@tonic-gate extern void		dld_str_notify_ind(dld_str_t *);
2578275SEric Cheng extern mac_tx_cookie_t	str_mdata_fastpath_put(dld_str_t *, mblk_t *,
2588275SEric Cheng     uintptr_t, uint16_t);
2598275SEric Cheng extern int		dld_flow_ctl_callb(dld_str_t *, uint64_t,
2608275SEric Cheng     int (*func)(), void *);
261269Sericheng 
2620Sstevel@tonic-gate /*
2630Sstevel@tonic-gate  * dld_proto.c
2640Sstevel@tonic-gate  */
2658275SEric Cheng extern void		dld_proto(dld_str_t *, mblk_t *);
2668275SEric Cheng extern void		dld_proto_unitdata_req(dld_str_t *, mblk_t *);
2675113Syz147064 extern void		dld_capabilities_disable(dld_str_t *);
2688275SEric Cheng extern void		proto_unitdata_req(dld_str_t *, mblk_t *);
2698275SEric Cheng 
2708275SEric Cheng /*
2718275SEric Cheng  * dld_flow.c
2728275SEric Cheng  */
2738275SEric Cheng extern void		flow_rx_pkt_chain(void *, void *, mblk_t *);
2748275SEric Cheng 
2758275SEric Cheng /*
2768275SEric Cheng  * dld_drv.c
2778275SEric Cheng  */
2788275SEric Cheng extern mac_handle_t	dld_mac_open(char *dev_name, int *err);
2798275SEric Cheng #define	dld_mac_close(mh) mac_close(mh)
2800Sstevel@tonic-gate 
2810Sstevel@tonic-gate /*
2820Sstevel@tonic-gate  * Options: there should be a separate bit defined here for each
2838275SEric Cheng  *          DLD_PROP... defined in dld.h.
2840Sstevel@tonic-gate  */
285269Sericheng #define	DLD_OPT_NO_FASTPATH	0x00000001
286269Sericheng #define	DLD_OPT_NO_POLL		0x00000002
287269Sericheng #define	DLD_OPT_NO_ZEROCOPY	0x00000004
2884114Sja97890 #define	DLD_OPT_NO_SOFTRING	0x00000008
2890Sstevel@tonic-gate 
2900Sstevel@tonic-gate extern uint32_t		dld_opt;
2910Sstevel@tonic-gate 
2920Sstevel@tonic-gate /*
2935895Syz147064  * autopush information
2945895Syz147064  */
2955895Syz147064 typedef struct dld_ap {
2965895Syz147064 	datalink_id_t		da_linkid;
2975895Syz147064 	struct dlautopush	da_ap;
2985895Syz147064 
2995895Syz147064 #define	da_anchor		da_ap.dap_anchor
3005895Syz147064 #define	da_npush		da_ap.dap_npush
3015895Syz147064 #define	da_aplist		da_ap.dap_aplist
3025895Syz147064 
3035895Syz147064 } dld_ap_t;
3045895Syz147064 
3055895Syz147064 /*
3060Sstevel@tonic-gate  * Useful macros.
3070Sstevel@tonic-gate  */
3080Sstevel@tonic-gate 
3098275SEric Cheng #define	DLD_SETQFULL(dsp) {						\
3108275SEric Cheng 	queue_t *q = (dsp)->ds_wq;					\
3118275SEric Cheng 									\
3128275SEric Cheng 	mutex_enter(&(dsp)->ds_lock);					\
3138275SEric Cheng 	if ((dsp)->ds_tx_flow_mp != NULL) {				\
3148275SEric Cheng 		(void) putq(q, (dsp)->ds_tx_flow_mp);			\
3158275SEric Cheng 		(dsp)->ds_tx_flow_mp = NULL;				\
3168275SEric Cheng 		qenable((dsp)->ds_wq);					\
3178275SEric Cheng 	}								\
3188275SEric Cheng 	mutex_exit(&(dsp)->ds_lock);					\
3198275SEric Cheng }
3208275SEric Cheng 
3219002SCathy.Zhou@Sun.COM /*
3229002SCathy.Zhou@Sun.COM  * This is called to check whether we can disable the flow control, and
3239002SCathy.Zhou@Sun.COM  * it is usually only needed in TX data-path when the dsp->ds_dlstate is
3249002SCathy.Zhou@Sun.COM  * DL_IDLE. Otherwise, it does not hurt to always disable the flow control.
3259002SCathy.Zhou@Sun.COM  */
3269002SCathy.Zhou@Sun.COM #define	DLD_CLRQFULL(dsp) {					\
3279002SCathy.Zhou@Sun.COM 	queue_t *q = (dsp)->ds_wq;				\
3289002SCathy.Zhou@Sun.COM 								\
3299002SCathy.Zhou@Sun.COM 	mutex_enter(&(dsp)->ds_lock);				\
3309002SCathy.Zhou@Sun.COM 	if ((dsp)->ds_dlstate != DL_IDLE ||			\
3319002SCathy.Zhou@Sun.COM 	    !mac_tx_is_flow_blocked((dsp)->ds_mch, NULL)) {	\
3329002SCathy.Zhou@Sun.COM 		if ((dsp)->ds_tx_flow_mp == NULL)		\
3339002SCathy.Zhou@Sun.COM 			(dsp)->ds_tx_flow_mp = getq(q);		\
3349002SCathy.Zhou@Sun.COM 		ASSERT((dsp)->ds_tx_flow_mp != NULL);		\
3359002SCathy.Zhou@Sun.COM 	}							\
3369002SCathy.Zhou@Sun.COM 	mutex_exit(&(dsp)->ds_lock);				\
3378275SEric Cheng }
3388275SEric Cheng 
3398833SVenu.Iyer@Sun.COM #define	DLD_TX(dsp, mp, f_hint, flag)				\
3408275SEric Cheng 	mac_tx(dsp->ds_mch, mp, f_hint, flag, NULL)
3418275SEric Cheng 
342269Sericheng #ifdef DEBUG
343269Sericheng #define	DLD_DBG		cmn_err
344269Sericheng #else
345269Sericheng #define	DLD_DBG		if (0) cmn_err
346269Sericheng #endif
347269Sericheng 
3480Sstevel@tonic-gate #ifdef	__cplusplus
3490Sstevel@tonic-gate }
3500Sstevel@tonic-gate #endif
3510Sstevel@tonic-gate 
3520Sstevel@tonic-gate #endif	/* _SYS_DLD_IMPL_H */
353