xref: /illumos-gate/usr/src/uts/common/sys/softmac_impl.h (revision bfed486ad8de8b8ebc6345a8e10accae08bf2f45)
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_SOFTMAC_IMPL_H
27 #define	_SYS_SOFTMAC_IMPL_H
28 
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>
42 
43 #ifdef	__cplusplus
44 extern "C" {
45 #endif
46 
47 typedef struct softmac_lower_s {
48 	struct softmac		*sl_softmac;
49 	queue_t			*sl_wq;
50 
51 	/*
52 	 * sl_ctl_inprogress is used to serialize the control path.  It will
53 	 * be set when either an ioctl or an M_{PC,}PROTO message is received
54 	 * from the upper layer, and will be cleared when processing done.
55 	 */
56 	kmutex_t		sl_ctl_mutex;
57 	kcondvar_t		sl_ctl_cv;
58 	boolean_t		sl_ctl_inprogress;
59 
60 	/*
61 	 * When a control message is processed, either sl_pending_prim or
62 	 * sl_pending_ioctl will be set.  They will be cleared when the
63 	 * acknowledgement of the specific control message is received
64 	 * from the underlying legacy driver.
65 	 */
66 	kmutex_t		sl_mutex;
67 	kcondvar_t		sl_cv;
68 	t_uscalar_t		sl_pending_prim;
69 	boolean_t		sl_pending_ioctl;
70 	mblk_t			*sl_ack_mp;
71 
72 	ldi_handle_t		sl_lh;
73 } softmac_lower_t;
74 
75 typedef enum {
76 	SOFTMAC_INITIALIZED,
77 	SOFTMAC_READY
78 } softmac_lower_state_t;
79 
80 typedef enum {
81 	SOFTMAC_UNINIT,
82 	SOFTMAC_ATTACH_INPROG,
83 	SOFTMAC_ATTACH_DONE,
84 	SOFTMAC_DETACH_INPROG,
85 } softmac_state_t;
86 
87 typedef struct softmac_dev_s {
88 	dev_t	sd_dev;
89 } softmac_dev_t;
90 
91 /*
92  * smac_flag values.
93  */
94 #define	SOFTMAC_GLDV3		0x01
95 #define	SOFTMAC_NOSUPP		0x02
96 #define	SOFTMAC_NEED_RECREATE	0x04
97 #define	SOFTMAC_NOTIFY_QUIT	0x08
98 
99 #define	SMAC_NONZERO_NODECNT(softmac)		\
100 	((softmac->smac_softmac[0] != NULL) +	\
101 	(softmac->smac_softmac[1] != NULL))
102 
103 /*
104  * The softmac structure allows all minor nodes (at most two, style-1 and
105  * style-2) for the same device to be processed.  A softmac_dev_t will be
106  * created for each minor node.
107  *
108  * We try to "register" the mac after all the softmac_dev_t's are processed so
109  * that even if DLPI operations fail (because of driver bugs) for one minor
110  * node, the other minor node can still be used to register the mac.
111  * (Specifically, an incorrect xxx_getinfo() implementation will cause style-2
112  * minor node mac registration to fail.)
113  */
114 typedef struct softmac {
115 	/*
116 	 * The following fields will be set when the softmac is created and
117 	 * will not change.  No lock is required.
118 	 */
119 	char		smac_devname[MAXNAMELEN];
120 	major_t		smac_umajor;
121 	int		smac_uppa;
122 	uint32_t	smac_cnt;	/* # of minor nodes for this device */
123 
124 	/*
125 	 * The following fields are protected by smac_mutex.
126 	 *
127 	 * The smac_hold_cnt field increases when softmac_hold_device() is
128 	 * called to force the dls_vlan_t of the device to be created.  The
129 	 * device pre-detach fails if this counter is not 0.
130 	 */
131 	softmac_state_t	smac_state;
132 	uint32_t	smac_hold_cnt;
133 	kmutex_t	smac_mutex;
134 	kcondvar_t	smac_cv;
135 	uint32_t	smac_flags;
136 	int		smac_attacherr;
137 	mac_handle_t	smac_mh;
138 	softmac_dev_t	*smac_softmac[2];
139 	/*
140 	 * Number of minor nodes whose post-attach routine has succeeded.
141 	 * This should be the same as the numbers of softmac_dev_t.
142 	 * Note that it does not imply SOFTMAC_ATTACH_DONE as the taskq might
143 	 * be still ongoing.
144 	 */
145 	uint32_t	smac_attachok_cnt;
146 	/*
147 	 * Number of softmac_dev_t left when pre-detach fails. This is used
148 	 * to indicate whether postattach is called because of a failed
149 	 * pre-detach.
150 	 */
151 	uint32_t	smac_attached_left;
152 
153 	/*
154 	 * Thread handles the DL_NOTIFY_IND message from the lower stream.
155 	 */
156 	kthread_t	*smac_notify_thread;
157 	/*
158 	 * Head and tail of the DL_NOTIFY_IND messsages.
159 	 */
160 	mblk_t		*smac_notify_head;
161 	mblk_t		*smac_notify_tail;
162 
163 	/*
164 	 * The remaining fields are used to register the MAC for a legacy
165 	 * device.  They are set in softmac_mac_register() and do not change.
166 	 * One can access them when mac_register() is done without locks.
167 	 */
168 
169 	/*
170 	 * media type is needed for create <link name, linkid> mapping, so
171 	 * it is set for GLDv3 device as well
172 	 */
173 	uint_t		smac_media;
174 	/* DLPI style of the underlying device */
175 	int		smac_style;
176 	dev_t		smac_dev;
177 	size_t		smac_saplen;
178 	size_t		smac_addrlen;
179 	uchar_t		smac_unicst_addr[MAXMACADDRLEN];
180 	uint_t		smac_min_sdu;
181 	uint_t		smac_max_sdu;
182 	uint32_t	smac_margin;
183 
184 	/* Notifications the underlying driver can support. */
185 	uint32_t	smac_notifications;
186 
187 	/*
188 	 * Capabilities of the underlying driver.
189 	 */
190 	uint32_t	smac_capab_flags;
191 	uint32_t	smac_hcksum_txflags;
192 	boolean_t	smac_no_capability_req;
193 	dl_capab_mdt_t	smac_mdt_capab;
194 	boolean_t	smac_mdt;
195 
196 	/* Following fields protected by the mac perimeter */
197 	softmac_lower_state_t	smac_lower_state;
198 	/* Lower stream structure */
199 	softmac_lower_t	*smac_lower;
200 } softmac_t;
201 
202 typedef struct smac_ioc_start_s {
203 	softmac_lower_t	*si_slp;
204 } smac_ioc_start_t;
205 
206 #define	SMAC_IOC	('S' << 24 | 'M' << 16 | 'C' << 8)
207 #define	SMAC_IOC_START	(SMAC_IOC | 0x01)
208 
209 extern dev_info_t		*softmac_dip;
210 #define	SOFTMAC_DEV_NAME	"softmac"
211 
212 extern int	softmac_send_bind_req(softmac_lower_t *, uint_t);
213 extern int	softmac_send_notify_req(softmac_lower_t *, uint32_t);
214 extern int	softmac_send_promisc_req(softmac_lower_t *, t_uscalar_t,
215     boolean_t);
216 extern void	softmac_init(void);
217 extern void	softmac_fini(void);
218 extern boolean_t softmac_busy(void);
219 extern int	softmac_fill_capab(ldi_handle_t, softmac_t *);
220 extern int	softmac_capab_enable(softmac_lower_t *);
221 extern void	softmac_rput_process_notdata(queue_t *, mblk_t *);
222 extern void	softmac_rput_process_data(softmac_lower_t *, mblk_t *);
223 
224 extern int	softmac_m_promisc(void *, boolean_t);
225 extern int	softmac_m_multicst(void *, boolean_t, const uint8_t *);
226 extern int	softmac_m_unicst(void *, const uint8_t *);
227 extern void	softmac_m_ioctl(void *, queue_t *, mblk_t *);
228 extern int	softmac_m_stat(void *, uint_t, uint64_t *);
229 extern mblk_t	*softmac_m_tx(void *, mblk_t *);
230 extern int	softmac_proto_tx(softmac_lower_t *, mblk_t *, mblk_t **);
231 extern void	softmac_ioctl_tx(softmac_lower_t *, mblk_t *, mblk_t **);
232 extern void	softmac_notify_thread(void *);
233 
234 #ifdef	__cplusplus
235 }
236 #endif
237 
238 #endif	/* _SYS_SOFTMAC_IMPL_H */
239