xref: /illumos-gate/usr/src/uts/common/sys/dld_impl.h (revision abdf5d9abf528d6c318fd8533e09bc3cac1f228b)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef	_SYS_DLD_IMPL_H
27 #define	_SYS_DLD_IMPL_H
28 
29 #include <sys/types.h>
30 #include <sys/list.h>
31 #include <sys/ethernet.h>
32 #include <sys/stream.h>
33 #include <sys/dlpi.h>
34 #include <sys/dld.h>
35 #include <sys/dls_impl.h>
36 
37 #ifdef	__cplusplus
38 extern "C" {
39 #endif
40 
41 #define	DLD_CONTROL_MINOR_NAME	"ctl"
42 #define	DLD_CONTROL_MINOR	0
43 
44 #define	DLD_CONTROL	0x00000001
45 #define	DLD_DLPI	0x00000002
46 
47 typedef enum {
48 	DLD_UNITDATA,
49 	DLD_FASTPATH,
50 	DLD_RAW
51 } dld_str_mode_t;
52 
53 typedef enum {
54 	DLD_UNINITIALIZED,
55 	DLD_PASSIVE,
56 	DLD_ACTIVE
57 } dld_passivestate_t;
58 
59 /*
60  * The dld_str_t object definition and protection scheme for each member
61  * is described below. The framework locking mechanism details are described in
62  * mac_impl.h and mac.c
63  *
64  * Write Once Only (WO): Typically these are initialized when the end point
65  * is created or initialized and don't change subsequently
66  *
67  * Serializer (SL): Protected by the Serializer. All modify operations on an
68  * end point go through the serializer. Readers don't care about reading
69  * these fields atomically, or readers also use the serializer to see the
70  * values atomically.
71  *
72  * Lock: kmutex_t or kwrlock_t lock. Modify operations still go through the
73  * serializer, the lock helps synchronize readers with writers.
74  */
75 
76 struct dld_str_s {					/* Protected by */
77 	/*
78 	 * Major number of the device
79 	 */
80 	major_t			ds_major;		/* WO */
81 
82 	/*
83 	 * Ephemeral minor number for the object.
84 	 */
85 	minor_t			ds_minor;		/* WO */
86 
87 	/*
88 	 * PPA number this stream is attached to.
89 	 */
90 	t_uscalar_t		ds_ppa;			/* SL */
91 
92 	/*
93 	 * Read/write queues for the stream which the object represents.
94 	 */
95 	queue_t			*ds_rq;			/* WO */
96 	queue_t			*ds_wq;			/* WO */
97 
98 	/*
99 	 * Stream is open to DLD_CONTROL (control node) or
100 	 * DLD_DLPI (DLS provider) node.
101 	 */
102 	uint_t			ds_type;		/* WO */
103 
104 	/*
105 	 * The following fields are only used for DLD_DLPI type objects.
106 	 */
107 
108 	/*
109 	 * Current DLPI state.
110 	 */
111 	t_uscalar_t		ds_dlstate;		/* SL */
112 
113 	/*
114 	 * DLPI style
115 	 */
116 	t_uscalar_t		ds_style;		/* WO */
117 
118 	/*
119 	 * Currently bound DLSAP.
120 	 */
121 	uint16_t		ds_sap;			/* SL */
122 
123 	/*
124 	 * Handle of the MAC that is used by the data-link interface.
125 	 */
126 	mac_handle_t		ds_mh;			/* SL */
127 	mac_client_handle_t	ds_mch;			/* SL */
128 
129 	/*
130 	 * Promiscuity level information.
131 	 */
132 	uint32_t		ds_promisc;		/* SL */
133 	mac_promisc_handle_t	ds_mph;
134 	mac_promisc_handle_t	ds_vlan_mph;
135 
136 	/*
137 	 * Immutable information of the MAC which the channel is using.
138 	 */
139 	const mac_info_t	*ds_mip;		/* SL */
140 
141 	/*
142 	 * Current packet priority.
143 	 */
144 	uint_t			ds_pri;			/* SL */
145 
146 	/*
147 	 * Handle of our MAC notification callback.
148 	 */
149 	mac_notify_handle_t	ds_mnh;			/* SL */
150 
151 	/*
152 	 * Set of enabled DL_NOTE... notifications. (See dlpi.h).
153 	 */
154 	uint32_t		ds_notifications;	/* SL */
155 
156 	/*
157 	 * Mode: unitdata, fast-path or raw.
158 	 */
159 	dld_str_mode_t		ds_mode;		/* SL */
160 
161 	/*
162 	 * Native mode state.
163 	 */
164 	boolean_t		ds_native;		/* SL */
165 
166 	/*
167 	 * IP polling is operational if this flag is set.
168 	 */
169 	boolean_t		ds_polling;		/* SL */
170 	boolean_t		ds_direct;		/* SL */
171 
172 	/*
173 	 * LSO is enabled if ds_lso is set.
174 	 */
175 	boolean_t		ds_lso;			/* SL */
176 	uint64_t		ds_lso_max;		/* SL */
177 
178 	/*
179 	 * State of DLPI user: may be active (regular network layer),
180 	 * passive (snoop-like monitoring), or unknown (not yet
181 	 * determined).
182 	 */
183 	dld_passivestate_t	ds_passivestate;	/* SL */
184 
185 	/*
186 	 * Dummy mblk used for flow-control.
187 	 */
188 	mblk_t			*ds_tx_flow_mp;		/* ds_lock */
189 
190 	/*
191 	 * List of queued DLPI requests. These will be processed
192 	 * by a taskq thread. This block is protected by ds_lock
193 	 */
194 	kmutex_t		ds_lock;
195 	krwlock_t		ds_rw_lock;
196 	kcondvar_t		ds_datathr_cv;		/* ds_lock */
197 	uint_t			ds_datathr_cnt;		/* ds_lock */
198 	mblk_t			*ds_pending_head;	/* ds_lock */
199 	mblk_t			*ds_pending_tail;	/* ds_lock */
200 	kcondvar_t		ds_dlpi_pending_cv;	/* ds_lock */
201 	uint32_t
202 				ds_dlpi_pending : 1,	/* ds_lock */
203 				ds_local	: 1,
204 				ds_pad		: 30;	/* ds_lock */
205 
206 	dls_link_t		*ds_dlp;		/* SL */
207 	dls_multicst_addr_t	*ds_dmap;		/* ds_rw_lock */
208 	dls_rx_t		ds_rx;			/* ds_lock */
209 	void			*ds_rx_arg;		/* ds_lock */
210 	uint_t			ds_nactive;		/* SL */
211 	dld_str_t		*ds_next;		/* SL */
212 	dls_head_t		*ds_head;
213 	dls_dl_handle_t		ds_ddh;
214 	list_node_t		ds_tqlist;
215 
216 	/*
217 	 * driver private data set by the driver when calling dld_str_open().
218 	 */
219 	void			*ds_private;
220 
221 	boolean_t		ds_lowlink;		/* SL */
222 };
223 
224 
225 #define	DLD_DATATHR_INC(dsp)	{		\
226 	ASSERT(MUTEX_HELD(&(dsp)->ds_lock));	\
227 	dsp->ds_datathr_cnt++;			\
228 }
229 
230 #define	DLD_DATATHR_DCR(dsp)	{		\
231 	mutex_enter(&(dsp)->ds_lock);		\
232 	(dsp)->ds_datathr_cnt--;		\
233 	if ((dsp)->ds_datathr_cnt == 0)		\
234 		cv_broadcast(&(dsp)->ds_datathr_cv);	\
235 	mutex_exit(&(dsp)->ds_lock);		\
236 }
237 
238 /*
239  * dld_str.c module.
240  */
241 
242 extern void		dld_str_init(void);
243 extern int		dld_str_fini(void);
244 extern dld_str_t	*dld_str_create(queue_t *, uint_t, major_t,
245     t_uscalar_t);
246 extern void		dld_str_destroy(dld_str_t *);
247 extern int		dld_str_attach(dld_str_t *, t_uscalar_t);
248 extern void		dld_str_detach(dld_str_t *);
249 extern void		dld_str_rx_raw(void *, mac_resource_handle_t,
250     mblk_t *, mac_header_info_t *);
251 extern void		dld_str_rx_fastpath(void *, mac_resource_handle_t,
252     mblk_t *, mac_header_info_t *);
253 extern void		dld_str_rx_unitdata(void *, mac_resource_handle_t,
254     mblk_t *, mac_header_info_t *);
255 extern void		dld_str_notify_ind(dld_str_t *);
256 extern mac_tx_cookie_t	str_mdata_fastpath_put(dld_str_t *, mblk_t *,
257     uintptr_t, uint16_t);
258 extern int		dld_flow_ctl_callb(dld_str_t *, uint64_t,
259     int (*func)(), void *);
260 
261 /*
262  * dld_proto.c
263  */
264 extern void		dld_proto(dld_str_t *, mblk_t *);
265 extern void		dld_proto_unitdata_req(dld_str_t *, mblk_t *);
266 extern void		dld_capabilities_disable(dld_str_t *);
267 extern void		proto_unitdata_req(dld_str_t *, mblk_t *);
268 
269 /*
270  * dld_flow.c
271  */
272 extern void		flow_rx_pkt_chain(void *, void *, mblk_t *);
273 
274 /*
275  * dld_drv.c
276  */
277 extern mac_handle_t	dld_mac_open(char *dev_name, int *err);
278 #define	dld_mac_close(mh) mac_close(mh)
279 
280 /*
281  * Options: there should be a separate bit defined here for each
282  *          DLD_PROP... defined in dld.h.
283  */
284 #define	DLD_OPT_NO_FASTPATH	0x00000001
285 #define	DLD_OPT_NO_POLL		0x00000002
286 #define	DLD_OPT_NO_ZEROCOPY	0x00000004
287 #define	DLD_OPT_NO_SOFTRING	0x00000008
288 
289 extern uint32_t		dld_opt;
290 
291 /*
292  * autopush information
293  */
294 typedef struct dld_ap {
295 	datalink_id_t		da_linkid;
296 	struct dlautopush	da_ap;
297 
298 #define	da_anchor		da_ap.dap_anchor
299 #define	da_npush		da_ap.dap_npush
300 #define	da_aplist		da_ap.dap_aplist
301 
302 } dld_ap_t;
303 
304 /*
305  * Useful macros.
306  */
307 
308 #define	IMPLY(p, c)	(!(p) || (c))
309 
310 #define	DLD_SETQFULL(dsp) {						\
311 	queue_t *q = (dsp)->ds_wq;					\
312 									\
313 	mutex_enter(&(dsp)->ds_lock);					\
314 	if ((dsp)->ds_tx_flow_mp != NULL) {				\
315 		(void) putq(q, (dsp)->ds_tx_flow_mp);			\
316 		(dsp)->ds_tx_flow_mp = NULL;				\
317 		qenable((dsp)->ds_wq);					\
318 	}								\
319 	mutex_exit(&(dsp)->ds_lock);					\
320 }
321 
322 /*
323  * This is called to check whether we can disable the flow control, and
324  * it is usually only needed in TX data-path when the dsp->ds_dlstate is
325  * DL_IDLE. Otherwise, it does not hurt to always disable the flow control.
326  */
327 #define	DLD_CLRQFULL(dsp) {					\
328 	queue_t *q = (dsp)->ds_wq;				\
329 								\
330 	mutex_enter(&(dsp)->ds_lock);				\
331 	if ((dsp)->ds_dlstate != DL_IDLE ||			\
332 	    !mac_tx_is_flow_blocked((dsp)->ds_mch, NULL)) {	\
333 		if ((dsp)->ds_tx_flow_mp == NULL)		\
334 			(dsp)->ds_tx_flow_mp = getq(q);		\
335 		ASSERT((dsp)->ds_tx_flow_mp != NULL);		\
336 	}							\
337 	mutex_exit(&(dsp)->ds_lock);				\
338 }
339 
340 #define	DLD_TX(dsp, mp, f_hint, flag)				\
341 	mac_tx(dsp->ds_mch, mp, f_hint, flag, NULL)
342 
343 #ifdef DEBUG
344 #define	DLD_DBG		cmn_err
345 #else
346 #define	DLD_DBG		if (0) cmn_err
347 #endif
348 
349 #ifdef	__cplusplus
350 }
351 #endif
352 
353 #endif	/* _SYS_DLD_IMPL_H */
354