docs/how-to-build.md: use proper markup for directory names
[unleashed/tickless.git] / include / sys / softmac_impl.h
blob00c37d34226108338052ed718372bdeaba50f70e
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #ifndef _SYS_SOFTMAC_IMPL_H
27 #define _SYS_SOFTMAC_IMPL_H
29 #include <sys/types.h>
30 #include <sys/ethernet.h>
31 #include <sys/taskq.h>
32 #include <sys/sunddi.h>
33 #include <sys/sunldi.h>
34 #include <sys/strsun.h>
35 #include <sys/stream.h>
36 #include <sys/dlpi.h>
37 #include <sys/mac.h>
38 #include <sys/mac_provider.h>
39 #include <sys/mac_client.h>
40 #include <sys/mac_client_priv.h>
41 #include <sys/mac_ether.h>
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
47 typedef void (*softmac_rx_t)(void *, mac_resource_handle_t, mblk_t *,
48 mac_header_info_t *);
50 typedef struct softmac_lower_rxinfo_s {
51 softmac_rx_t slr_rx;
52 void *slr_arg;
53 } softmac_lower_rxinfo_t;
55 typedef struct softmac_lower_s {
56 ldi_handle_t sl_lh;
57 struct softmac *sl_softmac;
58 queue_t *sl_wq;
59 struct softmac_upper_s *sl_sup;
60 softmac_lower_rxinfo_t *sl_rxinfo;
63 * When a control message is processed, either sl_pending_prim or
64 * sl_pending_ioctl will be set. They will be cleared when the
65 * acknowledgement of the specific control message is received
66 * from the underlying legacy driver.
68 kmutex_t sl_mutex;
69 kcondvar_t sl_cv;
70 t_uscalar_t sl_pending_prim;
71 boolean_t sl_pending_ioctl;
72 mblk_t *sl_ack_mp;
73 } softmac_lower_t;
75 typedef enum {
76 SOFTMAC_UNINIT,
77 SOFTMAC_ATTACH_INPROG,
78 SOFTMAC_ATTACH_DONE,
79 SOFTMAC_DETACH_INPROG,
80 } softmac_state_t;
82 typedef struct softmac_dev_s {
83 dev_t sd_dev;
84 } softmac_dev_t;
87 * smac_flag values.
89 #define SOFTMAC_GLDV3 0x01
90 #define SOFTMAC_NOSUPP 0x02
91 #define SOFTMAC_NEED_RECREATE 0x04
92 #define SOFTMAC_NOTIFY_QUIT 0x08
94 #define SMAC_NONZERO_NODECNT(softmac) \
95 ((softmac->smac_softmac[0] != NULL) + \
96 (softmac->smac_softmac[1] != NULL))
99 * The softmac structure allows all minor nodes (at most two, style-1 and
100 * style-2) for the same device to be processed. A softmac_dev_t will be
101 * created for each minor node.
103 * We try to "register" the mac after all the softmac_dev_t's are processed so
104 * that even if DLPI operations fail (because of driver bugs) for one minor
105 * node, the other minor node can still be used to register the mac.
106 * (Specifically, an incorrect xxx_getinfo() implementation will cause style-2
107 * minor node mac registration to fail.)
109 * Locking description:
110 * WO: write once, valid the life time.
112 typedef struct softmac {
113 char smac_devname[MAXNAMELEN]; /* WO */
114 major_t smac_umajor; /* WO */
115 int smac_uppa; /* WO */
116 uint32_t smac_cnt; /* WO, # of minor nodes */
118 kmutex_t smac_mutex;
119 kcondvar_t smac_cv;
120 softmac_state_t smac_state; /* smac_mutex */
122 * The smac_hold_cnt field increases when softmac_hold_device() is
123 * called to force the dls_vlan_t of the device to be created. The
124 * device pre-detach fails if this counter is not 0.
126 uint32_t smac_hold_cnt; /* smac_mutex */
127 uint32_t smac_flags; /* smac_mutex */
128 int smac_attacherr; /* smac_mutex */
129 mac_handle_t smac_mh;
130 softmac_dev_t *smac_softmac[2]; /* smac_mutex */
133 * Number of minor nodes whose post-attach routine has succeeded.
134 * This should be the same as the numbers of softmac_dev_t.
135 * Note that it does not imply SOFTMAC_ATTACH_DONE as the taskq might
136 * be still ongoing.
138 uint32_t smac_attachok_cnt; /* smac_mutex */
140 * Number of softmac_dev_t left when pre-detach fails. This is used
141 * to indicate whether postattach is called because of a failed
142 * pre-detach.
144 uint32_t smac_attached_left; /* smac_mutex */
147 * Thread handles the DL_NOTIFY_IND message from the lower stream.
149 kthread_t *smac_notify_thread; /* smac_mutex */
151 * Head and tail of the DL_NOTIFY_IND messsages.
153 mblk_t *smac_notify_head; /* smac_mutex */
154 mblk_t *smac_notify_tail; /* smac_mutex */
157 * The remaining fields are used to register the MAC for a legacy
158 * device. They are set in softmac_mac_register() and do not change.
159 * One can access them when mac_register() is done without locks.
163 * media type is needed for create <link name, linkid> mapping, so
164 * it is set for GLDv3 device as well
166 uint_t smac_media;
167 /* DLPI style of the underlying device */
168 int smac_style;
169 dev_t smac_dev;
170 size_t smac_saplen;
171 size_t smac_addrlen;
172 uchar_t smac_unicst_addr[MAXMACADDRLEN];
173 uint_t smac_min_sdu;
174 uint_t smac_max_sdu;
175 uint32_t smac_margin;
177 /* Notifications the underlying driver can support. */
178 uint32_t smac_notifications;
181 * Capabilities of the underlying driver.
183 uint32_t smac_capab_flags;
184 uint32_t smac_hcksum_txflags;
185 boolean_t smac_no_capability_req;
186 dl_capab_mdt_t smac_mdt_capab;
187 boolean_t smac_mdt;
190 * Lower stream structure, accessed by the MAC provider API. The GLDv3
191 * framework assures it's validity.
193 softmac_lower_t *smac_lower;
195 kmutex_t smac_active_mutex;
197 * Set by xxx_active_set() when aggregation is created.
199 boolean_t smac_active; /* smac_active_mutex */
201 * Numbers of the bounded streams in the fast-path mode.
203 uint32_t smac_nactive; /* smac_active_mutex */
205 kmutex_t smac_fp_mutex;
206 kcondvar_t smac_fp_cv;
208 * numbers of clients that request to disable fastpath.
210 uint32_t smac_fp_disable_clients; /* smac_fp_mutex */
211 boolean_t smac_fastpath_admin_disabled; /* smac_fp_mutex */
214 * stream list over this softmac.
216 list_t smac_sup_list; /* smac_fp_mutex */
217 } softmac_t;
219 typedef struct smac_ioc_start_s {
220 softmac_lower_t *si_slp;
221 } smac_ioc_start_t;
223 #define SMAC_IOC ('S' << 24 | 'M' << 16 | 'C' << 8)
224 #define SMAC_IOC_START (SMAC_IOC | 0x01)
227 * The su_mode of a non-IP/ARP stream is UNKNOWN, and the su_mode of an IP/ARP
228 * stream is either SLOWPATH or FASTPATH.
230 #define SOFTMAC_UNKNOWN 0x00
231 #define SOFTMAC_SLOWPATH 0x01
232 #define SOFTMAC_FASTPATH 0x02
234 typedef struct softmac_switch_req_s {
235 list_node_t ssq_req_list_node;
236 uint32_t ssq_expected_mode;
237 } softmac_switch_req_t;
239 #define DATAPATH_MODE(softmac) \
240 ((((softmac)->smac_fp_disable_clients != 0) || \
241 (softmac)->smac_fastpath_admin_disabled) ? SOFTMAC_SLOWPATH : \
242 SOFTMAC_FASTPATH)
246 * Locking description:
248 * WO: Set once and valid for life;
249 * SL: Serialized by the control path (softmac_wput_nondata_task())
251 typedef struct softmac_upper_s {
252 softmac_t *su_softmac; /* WO */
253 queue_t *su_rq; /* WO */
254 queue_t *su_wq; /* WO */
257 * List of upper streams that has pending DLPI messages to be processed.
259 list_node_t su_taskq_list_node; /* softmac_taskq_lock */
262 * non-NULL for IP/ARP streams in the fast-path mode
264 softmac_lower_t *su_slp; /* SL & su_mutex */
267 * List of all IP/ARP upperstreams on the same softmac (including
268 * the ones in both data-path modes).
270 list_node_t su_list_node; /* smac_fp_mutex */
273 * List of datapath switch requests.
275 list_t su_req_list; /* smac_fp_mutex */
278 * Place holder of RX callbacks used to handles data messages comes
279 * from the dedicated-lower-stream associated with the IP/ARP stream.
280 * Another RX callback is softmac_drop_rxinfo, which is a global
281 * variable.
283 softmac_lower_rxinfo_t su_rxinfo; /* WO */
284 softmac_lower_rxinfo_t su_direct_rxinfo; /* WO */
287 * Used to serialize the DLPI operation and fastpath<->slowpath
288 * switching over operation.
290 kmutex_t su_disp_mutex;
291 kcondvar_t su_disp_cv;
292 mblk_t *su_pending_head; /* su_disp_mutex */
293 mblk_t *su_pending_tail; /* su_disp_mutex */
294 boolean_t su_dlpi_pending; /* su_disp_mutex */
295 boolean_t su_closing; /* su_disp_mutex */
297 uint32_t su_bound : 1, /* SL */
298 su_active : 1, /* SL */
299 su_direct : 1, /* SL */
300 su_is_arp : 1,
301 su_pad_to_32:28;
304 * Used for fastpath data path.
306 kmutex_t su_mutex;
307 kcondvar_t su_cv;
308 mblk_t *su_tx_flow_mp; /* su_mutex */
309 boolean_t su_tx_busy; /* su_mutex */
311 * Number of softmac_srv() operation in fastpath processing.
313 uint32_t su_tx_inprocess; /* su_mutex */
315 * SOFTMAC_SLOWPATH or SOFTMAC_FASTPATH
317 uint32_t su_mode; /* SL & su_mutex */
320 * Whether this stream is already scheduled in softmac_taskq_list.
322 boolean_t su_taskq_scheduled; /* softmac_taskq_lock */
325 * The DLD_CAPAB_DIRECT related notify callback.
327 mac_tx_notify_t su_tx_notify_func; /* su_mutex */
328 void *su_tx_notify_arg; /* su_mutex */
329 } softmac_upper_t;
331 #define SOFTMAC_EQ_PENDING(sup, mp) { \
332 if ((sup)->su_pending_head == NULL) { \
333 (sup)->su_pending_head = (sup)->su_pending_tail = (mp); \
334 } else { \
335 (sup)->su_pending_tail->b_next = (mp); \
336 (sup)->su_pending_tail = (mp); \
340 #define SOFTMAC_DQ_PENDING(sup, mpp) { \
341 if ((sup)->su_pending_head == NULL) { \
342 *(mpp) = NULL; \
343 } else { \
344 *(mpp) = (sup)->su_pending_head; \
345 if (((sup)->su_pending_head = (*(mpp))->b_next) == NULL)\
346 (sup)->su_pending_tail = NULL; \
347 (*(mpp))->b_next = NULL; \
352 * A macro to check whether the write-queue of the lower stream is full
353 * and packets need to be enqueued.
355 * Because softmac is pushed right above the underlying device and
356 * _I_INSERT/_I_REMOVE is not processed in the lower stream, it is
357 * safe to directly access the q_next pointer.
359 #define SOFTMAC_CANPUTNEXT(q) \
360 (!((q)->q_next->q_nfsrv->q_flag & QFULL) || canput((q)->q_next))
363 extern dev_info_t *softmac_dip;
364 #define SOFTMAC_DEV_NAME "softmac"
366 extern int softmac_send_bind_req(softmac_lower_t *, uint_t);
367 extern int softmac_send_unbind_req(softmac_lower_t *);
368 extern int softmac_send_notify_req(softmac_lower_t *, uint32_t);
369 extern int softmac_send_promisc_req(softmac_lower_t *, t_uscalar_t,
370 boolean_t);
371 extern void softmac_init();
372 extern void softmac_fini();
373 extern void softmac_fp_init();
374 extern void softmac_fp_fini();
375 extern boolean_t softmac_busy();
376 extern int softmac_fill_capab(ldi_handle_t, softmac_t *);
377 extern int softmac_capab_enable(softmac_lower_t *);
378 extern void softmac_rput_process_notdata(queue_t *, softmac_upper_t *,
379 mblk_t *);
380 extern void softmac_rput_process_data(softmac_lower_t *, mblk_t *);
381 extern int softmac_output(softmac_lower_t *, mblk_t *, t_uscalar_t,
382 t_uscalar_t, mblk_t **);
383 extern int softmac_mexchange_error_ack(mblk_t **, t_uscalar_t,
384 t_uscalar_t, t_uscalar_t);
386 extern int softmac_m_promisc(void *, boolean_t);
387 extern int softmac_m_multicst(void *, boolean_t, const uint8_t *);
388 extern int softmac_m_unicst(void *, const uint8_t *);
389 extern void softmac_m_ioctl(void *, queue_t *, mblk_t *);
390 extern int softmac_m_stat(void *, uint_t, uint64_t *);
391 extern mblk_t *softmac_m_tx(void *, mblk_t *);
392 extern int softmac_proto_tx(softmac_lower_t *, mblk_t *, mblk_t **);
393 extern void softmac_ioctl_tx(softmac_lower_t *, mblk_t *, mblk_t **);
394 extern void softmac_notify_thread(void *);
396 extern int softmac_hold(dev_t, softmac_t **);
397 extern void softmac_rele(softmac_t *);
398 extern int softmac_lower_setup(softmac_t *, softmac_upper_t *,
399 softmac_lower_t **);
400 extern boolean_t softmac_active_set(void *);
401 extern void softmac_active_clear(void *);
402 extern int softmac_fastpath_disable(void *);
403 extern void softmac_fastpath_enable(void *);
404 extern int softmac_datapath_switch(softmac_t *, boolean_t, boolean_t);
406 extern void softmac_wput_data(softmac_upper_t *, mblk_t *);
407 extern void softmac_wput_nondata(softmac_upper_t *, mblk_t *);
408 extern void softmac_upperstream_close(softmac_upper_t *);
410 #ifdef __cplusplus
412 #endif
414 #endif /* _SYS_SOFTMAC_IMPL_H */