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 2010 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
38extern "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
47typedef enum {
48	DLD_UNITDATA,
49	DLD_FASTPATH,
50	DLD_RAW
51} dld_str_mode_t;
52
53typedef 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
76struct 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	boolean_t		ds_nonip;		/* SL */
223};
224
225
226#define	DLD_DATATHR_INC(dsp)	{		\
227	ASSERT(MUTEX_HELD(&(dsp)->ds_lock));	\
228	dsp->ds_datathr_cnt++;			\
229}
230
231#define	DLD_DATATHR_DCR(dsp)	{		\
232	mutex_enter(&(dsp)->ds_lock);		\
233	(dsp)->ds_datathr_cnt--;		\
234	if ((dsp)->ds_datathr_cnt == 0)		\
235		cv_broadcast(&(dsp)->ds_datathr_cv);	\
236	mutex_exit(&(dsp)->ds_lock);		\
237}
238
239/*
240 * dld_str.c module.
241 */
242
243extern void		dld_str_init(void);
244extern int		dld_str_fini(void);
245extern dld_str_t	*dld_str_create(queue_t *, uint_t, major_t,
246    t_uscalar_t);
247extern void		dld_str_destroy(dld_str_t *);
248extern int		dld_str_attach(dld_str_t *, t_uscalar_t);
249extern void		dld_str_detach(dld_str_t *);
250extern void		dld_str_rx_raw(void *, mac_resource_handle_t,
251    mblk_t *, mac_header_info_t *);
252extern void		dld_str_rx_fastpath(void *, mac_resource_handle_t,
253    mblk_t *, mac_header_info_t *);
254extern void		dld_str_rx_unitdata(void *, mac_resource_handle_t,
255    mblk_t *, mac_header_info_t *);
256extern void		dld_str_notify_ind(dld_str_t *);
257extern mac_tx_cookie_t	str_mdata_fastpath_put(dld_str_t *, mblk_t *,
258    uintptr_t, uint16_t);
259extern int		dld_flow_ctl_callb(dld_str_t *, uint64_t,
260    int (*func)(), void *);
261
262/*
263 * dld_proto.c
264 */
265extern void		dld_proto(dld_str_t *, mblk_t *);
266extern void		dld_proto_unitdata_req(dld_str_t *, mblk_t *);
267extern void		dld_capabilities_disable(dld_str_t *);
268extern void		proto_unitdata_req(dld_str_t *, mblk_t *);
269
270/*
271 * dld_flow.c
272 */
273extern void		flow_rx_pkt_chain(void *, void *, mblk_t *);
274
275/*
276 * dld_drv.c
277 */
278extern mac_handle_t	dld_mac_open(char *dev_name, int *err);
279#define	dld_mac_close(mh) mac_close(mh)
280
281/*
282 * Options: there should be a separate bit defined here for each
283 *          DLD_PROP... defined in dld.h.
284 */
285#define	DLD_OPT_NO_FASTPATH	0x00000001
286#define	DLD_OPT_NO_POLL		0x00000002
287#define	DLD_OPT_NO_ZEROCOPY	0x00000004
288#define	DLD_OPT_NO_SOFTRING	0x00000008
289
290extern uint32_t		dld_opt;
291
292/*
293 * autopush information
294 */
295typedef struct dld_ap {
296	datalink_id_t		da_linkid;
297	struct dlautopush	da_ap;
298
299#define	da_anchor		da_ap.dap_anchor
300#define	da_npush		da_ap.dap_npush
301#define	da_aplist		da_ap.dap_aplist
302
303} dld_ap_t;
304
305/*
306 * Useful macros.
307 */
308
309#define	DLD_SETQFULL(dsp) {						\
310	queue_t *q = (dsp)->ds_wq;					\
311									\
312	mutex_enter(&(dsp)->ds_lock);					\
313	if ((dsp)->ds_tx_flow_mp != NULL) {				\
314		(void) putq(q, (dsp)->ds_tx_flow_mp);			\
315		(dsp)->ds_tx_flow_mp = NULL;				\
316		qenable((dsp)->ds_wq);					\
317	}								\
318	mutex_exit(&(dsp)->ds_lock);					\
319}
320
321/*
322 * This is called to check whether we can disable the flow control, and
323 * it is usually only needed in TX data-path when the dsp->ds_dlstate is
324 * DL_IDLE. Otherwise, it does not hurt to always disable the flow control.
325 */
326#define	DLD_CLRQFULL(dsp) {					\
327	queue_t *q = (dsp)->ds_wq;				\
328								\
329	mutex_enter(&(dsp)->ds_lock);				\
330	if ((dsp)->ds_dlstate != DL_IDLE ||			\
331	    !mac_tx_is_flow_blocked((dsp)->ds_mch, NULL)) {	\
332		if ((dsp)->ds_tx_flow_mp == NULL)		\
333			(dsp)->ds_tx_flow_mp = getq(q);		\
334		ASSERT((dsp)->ds_tx_flow_mp != NULL);		\
335	}							\
336	mutex_exit(&(dsp)->ds_lock);				\
337}
338
339#define	DLD_TX(dsp, mp, f_hint, flag)				\
340	mac_tx(dsp->ds_mch, mp, f_hint, flag, NULL)
341
342#ifdef DEBUG
343#define	DLD_DBG		cmn_err
344#else
345#define	DLD_DBG		if (0) cmn_err
346#endif
347
348#ifdef	__cplusplus
349}
350#endif
351
352#endif	/* _SYS_DLD_IMPL_H */
353