1*3147Sxc151355 /*
2*3147Sxc151355  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
3*3147Sxc151355  * Use is subject to license terms.
4*3147Sxc151355  */
5*3147Sxc151355 
6*3147Sxc151355 /*
7*3147Sxc151355  * Copyright (c) 2001 Atsushi Onoe
8*3147Sxc151355  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
9*3147Sxc151355  * All rights reserved.
10*3147Sxc151355  *
11*3147Sxc151355  * Redistribution and use in source and binary forms, with or without
12*3147Sxc151355  * modification, are permitted provided that the following conditions
13*3147Sxc151355  * are met:
14*3147Sxc151355  * 1. Redistributions of source code must retain the above copyright
15*3147Sxc151355  *    notice, this list of conditions and the following disclaimer.
16*3147Sxc151355  * 2. Redistributions in binary form must reproduce the above copyright
17*3147Sxc151355  *    notice, this list of conditions and the following disclaimer in the
18*3147Sxc151355  *    documentation and/or other materials provided with the distribution.
19*3147Sxc151355  * 3. The name of the author may not be used to endorse or promote products
20*3147Sxc151355  *    derived from this software without specific prior written permission.
21*3147Sxc151355  *
22*3147Sxc151355  * Alternatively, this software may be distributed under the terms of the
23*3147Sxc151355  * GNU General Public License ("GPL") version 2 as published by the Free
24*3147Sxc151355  * Software Foundation.
25*3147Sxc151355  *
26*3147Sxc151355  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27*3147Sxc151355  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28*3147Sxc151355  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29*3147Sxc151355  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30*3147Sxc151355  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31*3147Sxc151355  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32*3147Sxc151355  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33*3147Sxc151355  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34*3147Sxc151355  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35*3147Sxc151355  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36*3147Sxc151355  */
37*3147Sxc151355 
38*3147Sxc151355 #pragma ident	"%Z%%M%	%I%	%E% SMI"
39*3147Sxc151355 
40*3147Sxc151355 #ifndef _SYS_NET80211_IMPL_H
41*3147Sxc151355 #define	_SYS_NET80211_IMPL_H
42*3147Sxc151355 
43*3147Sxc151355 #include <sys/sysmacros.h>
44*3147Sxc151355 #include <sys/list.h>
45*3147Sxc151355 #include <sys/note.h>
46*3147Sxc151355 #include <sys/net80211_proto.h>
47*3147Sxc151355 #include <sys/net80211.h>
48*3147Sxc151355 #include <sys/mac_wifi.h>
49*3147Sxc151355 
50*3147Sxc151355 /*
51*3147Sxc151355  * IEEE802.11 kernel support module
52*3147Sxc151355  */
53*3147Sxc151355 
54*3147Sxc151355 #ifdef	__cplusplus
55*3147Sxc151355 extern "C" {
56*3147Sxc151355 #endif
57*3147Sxc151355 
58*3147Sxc151355 #define	IEEE80211_TXPOWER_MAX	100	/* .5 dbM */
59*3147Sxc151355 #define	IEEE80211_TXPOWER_MIN	0	/* kill radio */
60*3147Sxc151355 
61*3147Sxc151355 #define	IEEE80211_DTIM_MAX	15	/* max DTIM period */
62*3147Sxc151355 #define	IEEE80211_DTIM_MIN	1	/* min DTIM period */
63*3147Sxc151355 #define	IEEE80211_DTIM_DEFAULT	1	/* default DTIM period */
64*3147Sxc151355 
65*3147Sxc151355 /* NB: min+max come from WiFi requirements */
66*3147Sxc151355 #define	IEEE80211_BINTVAL_MAX	1000	/* max beacon interval (TU's) */
67*3147Sxc151355 #define	IEEE80211_BINTVAL_MIN	25	/* min beacon interval (TU's) */
68*3147Sxc151355 #define	IEEE80211_BINTVAL_DEFAULT 100	/* default beacon interval (TU's) */
69*3147Sxc151355 
70*3147Sxc151355 #define	IEEE80211_BMISS_MAX	2	/* maximum consecutive bmiss allowed */
71*3147Sxc151355 #define	IEEE80211_SWBMISS_THRESHOLD 50	/* s/w bmiss threshold (TU's) */
72*3147Sxc151355 #define	IEEE80211_HWBMISS_DEFAULT 7	/* h/w bmiss threshold (beacons) */
73*3147Sxc151355 
74*3147Sxc151355 #define	IEEE80211_PS_SLEEP	0x1	/* STA is in power saving mode */
75*3147Sxc151355 #define	IEEE80211_PS_MAX_QUEUE	50	/* maximum saved packets */
76*3147Sxc151355 
77*3147Sxc151355 #define	IEEE80211_RTS_DEFAULT	IEEE80211_RTS_MAX
78*3147Sxc151355 #define	IEEE80211_FRAG_DEFAULT	IEEE80211_FRAG_MAX
79*3147Sxc151355 
80*3147Sxc151355 /*
81*3147Sxc151355  * The RSSI values of two node are taken as almost the same when
82*3147Sxc151355  * the difference between these two node's RSSI values is within
83*3147Sxc151355  * IEEE80211_RSSI_CMP_THRESHOLD
84*3147Sxc151355  */
85*3147Sxc151355 #define	IEEE80211_RSSI_CMP_THRESHOLD	5
86*3147Sxc151355 
87*3147Sxc151355 /*
88*3147Sxc151355  * Each ieee80211com instance has a single timer that fires once a
89*3147Sxc151355  * second.  This is used to initiate various work depending on the
90*3147Sxc151355  * state of the instance: scanning (passive or active), ``transition''
91*3147Sxc151355  * (waiting for a response to a management frame when operating
92*3147Sxc151355  * as a station), and node inactivity processing (when operating
93*3147Sxc151355  * as an AP).  For inactivity processing each node has a timeout
94*3147Sxc151355  * set in it's in_inact field that is decremented on each timeout
95*3147Sxc151355  * and the node is reclaimed when the counter goes to zero.  We
96*3147Sxc151355  * use different inactivity timeout values depending on whether
97*3147Sxc151355  * the node is associated and authorized (either by 802.1x or
98*3147Sxc151355  * open/shared key authentication) or associated but yet to be
99*3147Sxc151355  * authorized.  The latter timeout is shorter to more aggressively
100*3147Sxc151355  * reclaim nodes that leave part way through the 802.1x exchange.
101*3147Sxc151355  *
102*3147Sxc151355  * IEEE80211_INACT_WAIT defines node table's inactivity interval in
103*3147Sxc151355  * seconds. On timeout, node table's registered nt_timeout callback
104*3147Sxc151355  * function is executed. Each node in the node table has a timeout
105*3147Sxc151355  * set in its in_inact field with IEEE80211_INACT_<state>. In
106*3147Sxc151355  * nt_timeout function, node table is iterated and each node's
107*3147Sxc151355  * in_inact is decremented. So IEEE80211_INACT_<state> is defined in
108*3147Sxc151355  * the form [inact_sec]/IEEE80211_INACT_WAIT.
109*3147Sxc151355  *
110*3147Sxc151355  */
111*3147Sxc151355 #define	IEEE80211_INACT_WAIT	15	/* inactivity interval (secs) */
112*3147Sxc151355 #define	IEEE80211_INACT_INIT	(30/IEEE80211_INACT_WAIT)	/* initial */
113*3147Sxc151355 #define	IEEE80211_INACT_ASSOC	(180/IEEE80211_INACT_WAIT)
114*3147Sxc151355 					/* associated but not authorized */
115*3147Sxc151355 #define	IEEE80211_INACT_RUN	(300/IEEE80211_INACT_WAIT)	/* authorized */
116*3147Sxc151355 #define	IEEE80211_INACT_PROBE	(30/IEEE80211_INACT_WAIT)	/* probe */
117*3147Sxc151355 #define	IEEE80211_INACT_SCAN	(300/IEEE80211_INACT_WAIT)	/* scanned */
118*3147Sxc151355 
119*3147Sxc151355 #define	IEEE80211_TRANS_WAIT 	5	/* mgt frame tx timer (secs) */
120*3147Sxc151355 
121*3147Sxc151355 /*
122*3147Sxc151355  * Useful combinations of channel characteristics.
123*3147Sxc151355  */
124*3147Sxc151355 #define	IEEE80211_CHAN_FHSS	\
125*3147Sxc151355 	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
126*3147Sxc151355 #define	IEEE80211_CHAN_A	\
127*3147Sxc151355 	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
128*3147Sxc151355 #define	IEEE80211_CHAN_B	\
129*3147Sxc151355 	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
130*3147Sxc151355 #define	IEEE80211_CHAN_PUREG	\
131*3147Sxc151355 	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
132*3147Sxc151355 #define	IEEE80211_CHAN_G	\
133*3147Sxc151355 	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
134*3147Sxc151355 #define	IEEE80211_CHAN_T	\
135*3147Sxc151355 	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
136*3147Sxc151355 #define	IEEE80211_CHAN_108G	\
137*3147Sxc151355 	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
138*3147Sxc151355 
139*3147Sxc151355 #define	IEEE80211_CHAN_ALL	\
140*3147Sxc151355 	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_GFSK | \
141*3147Sxc151355 	IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_DYN)
142*3147Sxc151355 #define	IEEE80211_CHAN_ALLTURBO	\
143*3147Sxc151355 	(IEEE80211_CHAN_ALL | IEEE80211_CHAN_TURBO)
144*3147Sxc151355 
145*3147Sxc151355 #define	IEEE80211_IS_CHAN_FHSS(_c)	\
146*3147Sxc151355 	(((_c)->ich_flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
147*3147Sxc151355 #define	IEEE80211_IS_CHAN_A(_c)		\
148*3147Sxc151355 	(((_c)->ich_flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
149*3147Sxc151355 #define	IEEE80211_IS_CHAN_B(_c)		\
150*3147Sxc151355 	(((_c)->ich_flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
151*3147Sxc151355 #define	IEEE80211_IS_CHAN_PUREG(_c)	\
152*3147Sxc151355 	(((_c)->ich_flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
153*3147Sxc151355 #define	IEEE80211_IS_CHAN_G(_c)		\
154*3147Sxc151355 	(((_c)->ich_flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
155*3147Sxc151355 #define	IEEE80211_IS_CHAN_ANYG(_c)	\
156*3147Sxc151355 	(IEEE80211_IS_CHAN_PUREG(_c) || IEEE80211_IS_CHAN_G(_c))
157*3147Sxc151355 #define	IEEE80211_IS_CHAN_T(_c)		\
158*3147Sxc151355 	(((_c)->ich_flags & IEEE80211_CHAN_T) == IEEE80211_CHAN_T)
159*3147Sxc151355 #define	IEEE80211_IS_CHAN_108G(_c)	\
160*3147Sxc151355 	(((_c)->ich_flags & IEEE80211_CHAN_108G) == IEEE80211_CHAN_108G)
161*3147Sxc151355 
162*3147Sxc151355 #define	IEEE80211_IS_CHAN_OFDM(_c)	\
163*3147Sxc151355 	((_c)->ich_flags & IEEE80211_CHAN_OFDM)
164*3147Sxc151355 #define	IEEE80211_IS_CHAN_CCK(_c)	\
165*3147Sxc151355 	((_c)->ich_flags & IEEE80211_CHAN_CCK)
166*3147Sxc151355 #define	IEEE80211_IS_CHAN_GFSK(_c)	\
167*3147Sxc151355 	((_c)->ich_flags & IEEE80211_CHAN_GFSK)
168*3147Sxc151355 #define	IEEE80211_IS_CHAN_PASSIVE(_c)	\
169*3147Sxc151355 	((_c)->ich_flags & IEEE80211_CHAN_PASSIVE)
170*3147Sxc151355 
171*3147Sxc151355 /* ni_chan encoding for FH phy */
172*3147Sxc151355 #define	IEEE80211_FH_CHANMOD	80
173*3147Sxc151355 #define	IEEE80211_FH_CHAN(set, pat)	\
174*3147Sxc151355 	(((set) - 1) * IEEE80211_FH_CHANMOD + (pat))
175*3147Sxc151355 #define	IEEE80211_FH_CHANSET(chan)	\
176*3147Sxc151355 	((chan) / IEEE80211_FH_CHANMOD + 1)
177*3147Sxc151355 #define	IEEE80211_FH_CHANPAT(chan)	\
178*3147Sxc151355 	((chan) % IEEE80211_FH_CHANMOD)
179*3147Sxc151355 
180*3147Sxc151355 #define	IEEE80211_NODE_AUTH	0x0001		/* authorized for data */
181*3147Sxc151355 #define	IEEE80211_NODE_QOS	0x0002		/* QoS enabled */
182*3147Sxc151355 #define	IEEE80211_NODE_ERP	0x0004		/* ERP enabled */
183*3147Sxc151355 #define	IEEE80211_NODE_PWR_MGT	0x0010		/* power save mode enabled */
184*3147Sxc151355 #define	IEEE80211_NODE_AREF	0x0020		/* authentication ref held */
185*3147Sxc151355 
186*3147Sxc151355 #define	IEEE80211_MAXRSSI	127
187*3147Sxc151355 
188*3147Sxc151355 /* Debug Flags */
189*3147Sxc151355 #define	IEEE80211_MSG_DEBUG	0x40000000	/* IFF_DEBUG equivalent */
190*3147Sxc151355 #define	IEEE80211_MSG_DUMPPKTS	0x20000000	/* IFF_LINK2 equivalant */
191*3147Sxc151355 #define	IEEE80211_MSG_CRYPTO	0x10000000	/* crypto work */
192*3147Sxc151355 #define	IEEE80211_MSG_INPUT	0x08000000	/* input handling */
193*3147Sxc151355 #define	IEEE80211_MSG_XRATE	0x04000000	/* rate set handling */
194*3147Sxc151355 #define	IEEE80211_MSG_ELEMID	0x02000000	/* element id parsing */
195*3147Sxc151355 #define	IEEE80211_MSG_NODE	0x01000000	/* node handling */
196*3147Sxc151355 #define	IEEE80211_MSG_ASSOC	0x00800000	/* association handling */
197*3147Sxc151355 #define	IEEE80211_MSG_AUTH	0x00400000	/* authentication handling */
198*3147Sxc151355 #define	IEEE80211_MSG_SCAN	0x00200000	/* scanning */
199*3147Sxc151355 #define	IEEE80211_MSG_OUTPUT	0x00100000	/* output handling */
200*3147Sxc151355 #define	IEEE80211_MSG_STATE	0x00080000	/* state machine */
201*3147Sxc151355 #define	IEEE80211_MSG_POWER	0x00040000	/* power save handling */
202*3147Sxc151355 #define	IEEE80211_MSG_DOT1X	0x00020000	/* 802.1x authenticator */
203*3147Sxc151355 #define	IEEE80211_MSG_DOT1XSM	0x00010000	/* 802.1x state machine */
204*3147Sxc151355 #define	IEEE80211_MSG_RADIUS	0x00008000	/* 802.1x radius client */
205*3147Sxc151355 #define	IEEE80211_MSG_RADDUMP	0x00004000	/* dump 802.1x radius packets */
206*3147Sxc151355 #define	IEEE80211_MSG_RADKEYS	0x00002000	/* dump 802.1x keys */
207*3147Sxc151355 #define	IEEE80211_MSG_WPA	0x00001000	/* WPA/RSN protocol */
208*3147Sxc151355 #define	IEEE80211_MSG_ACL	0x00000800	/* ACL handling */
209*3147Sxc151355 #define	IEEE80211_MSG_WME	0x00000400	/* WME protocol */
210*3147Sxc151355 #define	IEEE80211_MSG_SUPERG	0x00000200	/* Atheros SuperG protocol */
211*3147Sxc151355 #define	IEEE80211_MSG_DOTH	0x00000100	/* 802.11h support */
212*3147Sxc151355 #define	IEEE80211_MSG_INACT	0x00000080	/* inactivity handling */
213*3147Sxc151355 #define	IEEE80211_MSG_ROAM	0x00000040	/* sta-mode roaming */
214*3147Sxc151355 #define	IEEE80211_MSG_CONFIG	0x00000020	/* wificonfig/dladm */
215*3147Sxc151355 #define	IEEE80211_MSG_ANY	0xffffffff	/* anything */
216*3147Sxc151355 
217*3147Sxc151355 /* Error flags returned by ieee80211_match_bss */
218*3147Sxc151355 #define	IEEE80211_BADCHAN	0x01
219*3147Sxc151355 #define	IEEE80211_BADOPMODE	0x02
220*3147Sxc151355 #define	IEEE80211_BADPRIVACY	0x04
221*3147Sxc151355 #define	IEEE80211_BADRATE	0x08
222*3147Sxc151355 #define	IEEE80211_BADESSID	0x10
223*3147Sxc151355 #define	IEEE80211_BADBSSID	0x20
224*3147Sxc151355 #define	IEEE80211_NODEFAIL	0x40
225*3147Sxc151355 
226*3147Sxc151355 typedef struct ieee80211_impl {
227*3147Sxc151355 	struct ieee80211com	*ic;
228*3147Sxc151355 	uint8_t			im_chan_avail[IEEE80211_CHAN_BYTES];
229*3147Sxc151355 	uint8_t			im_chan_scan[IEEE80211_CHAN_BYTES];
230*3147Sxc151355 
231*3147Sxc151355 	uint8_t			im_bmiss_count;	/* current beacon miss count */
232*3147Sxc151355 	int32_t			im_bmiss_max;	/* max bmiss before scan */
233*3147Sxc151355 	timeout_id_t		im_swbmiss;
234*3147Sxc151355 	uint16_t		im_swbmiss_count; /* beacons in last period */
235*3147Sxc151355 	uint16_t		im_swbmiss_period;	/* s/w bmiss period */
236*3147Sxc151355 
237*3147Sxc151355 	int32_t			im_mgt_timer;	/* mgmt timeout, secs */
238*3147Sxc151355 	int32_t			im_inact_timer;	/* inactivity timer wait, sec */
239*3147Sxc151355 	int32_t			im_inact_init;	/* initial setting */
240*3147Sxc151355 	int32_t			im_inact_assoc;	/* assoc but not authorized */
241*3147Sxc151355 	int32_t			im_inact_run;	/* authorized setting */
242*3147Sxc151355 	int32_t			im_inact_probe;	/* inactive probe time */
243*3147Sxc151355 
244*3147Sxc151355 	kcondvar_t		im_scan_cv;	/* wait scan complete */
245*3147Sxc151355 } ieee80211_impl_t;
246*3147Sxc151355 
247*3147Sxc151355 /*
248*3147Sxc151355  * Parameters supplied when adding/updating an entry in a
249*3147Sxc151355  * scan cache.  Pointer variables should be set to NULL
250*3147Sxc151355  * if no data is available.  Pointer references can be to
251*3147Sxc151355  * local data; any information that is saved will be copied.
252*3147Sxc151355  * All multi-byte values must be in host byte order.
253*3147Sxc151355  */
254*3147Sxc151355 struct ieee80211_scanparams {
255*3147Sxc151355 	uint16_t		capinfo;	/* 802.11 capabilities */
256*3147Sxc151355 	enum ieee80211_phytype	phytype;
257*3147Sxc151355 	uint16_t		fhdwell;	/* FHSS dwell interval */
258*3147Sxc151355 	uint8_t			chan;
259*3147Sxc151355 	uint8_t			bchan;
260*3147Sxc151355 	uint8_t			fhindex;
261*3147Sxc151355 	uint8_t			erp;
262*3147Sxc151355 	uint16_t		bintval;
263*3147Sxc151355 	uint8_t			timoff;
264*3147Sxc151355 	uint8_t			*tim;
265*3147Sxc151355 	uint8_t			*tstamp;
266*3147Sxc151355 	uint8_t			*country;
267*3147Sxc151355 	uint8_t			*ssid;
268*3147Sxc151355 	uint8_t			*rates;
269*3147Sxc151355 	uint8_t			*xrates;
270*3147Sxc151355 	uint8_t			*wpa;
271*3147Sxc151355 	uint8_t			*wme;
272*3147Sxc151355 };
273*3147Sxc151355 
274*3147Sxc151355 #define	IEEE80211_SEND_MGMT(_ic, _in, _type, _arg)			\
275*3147Sxc151355 	((*(_ic)->ic_send_mgmt)((_ic), (_in), (_type), (_arg)))
276*3147Sxc151355 
277*3147Sxc151355 /* Verify the existence and length of __elem or get out. */
278*3147Sxc151355 #define	IEEE80211_VERIFY_ELEMENT(__elem, __maxlen, __func) do {		\
279*3147Sxc151355 	_NOTE(CONSTCOND)						\
280*3147Sxc151355 	if ((__elem) == NULL) {						\
281*3147Sxc151355 		ieee80211_err("ieee80211: no #__elem \n");		\
282*3147Sxc151355 		__func;							\
283*3147Sxc151355 	}								\
284*3147Sxc151355 	if ((__elem)[1] > (__maxlen)) {					\
285*3147Sxc151355 		ieee80211_err("ieee80211: bad "#__elem " len %d\n",	\
286*3147Sxc151355 		    (__elem)[1]);					\
287*3147Sxc151355 		__func;							\
288*3147Sxc151355 	}								\
289*3147Sxc151355 	_NOTE(CONSTCOND)						\
290*3147Sxc151355 } while (0)
291*3147Sxc151355 
292*3147Sxc151355 #define	IEEE80211_VERIFY_LENGTH(_len, _minlen, _func) do {		\
293*3147Sxc151355 	_NOTE(CONSTCOND)						\
294*3147Sxc151355 	if ((_len) < (_minlen)) {					\
295*3147Sxc151355 		ieee80211_dbg(IEEE80211_MSG_ELEMID,			\
296*3147Sxc151355 		    "ie of type %s too short",				\
297*3147Sxc151355 		    ieee80211_mgt_subtype_name[subtype >>		\
298*3147Sxc151355 			IEEE80211_FC0_SUBTYPE_SHIFT]);			\
299*3147Sxc151355 		_func;							\
300*3147Sxc151355 	}								\
301*3147Sxc151355 	_NOTE(CONSTCOND)						\
302*3147Sxc151355 } while (0)
303*3147Sxc151355 
304*3147Sxc151355 #define	IEEE80211_VERIFY_SSID(_in, _ssid, _func) do {			\
305*3147Sxc151355 	_NOTE(CONSTCOND)						\
306*3147Sxc151355 	ASSERT((_in) != NULL);						\
307*3147Sxc151355 	if ((_ssid)[1] != 0 &&						\
308*3147Sxc151355 	    ((_ssid)[1] != (_in)->in_esslen ||				\
309*3147Sxc151355 	    bcmp((_ssid) + 2, (_in)->in_essid, (_ssid)[1]) != 0)) {	\
310*3147Sxc151355 		_func;							\
311*3147Sxc151355 	}								\
312*3147Sxc151355 	_NOTE(CONSTCOND)						\
313*3147Sxc151355 } while (0)
314*3147Sxc151355 
315*3147Sxc151355 #define	ieee80211_setbit(a, i)	((a)[(i)/NBBY] |= (1 << ((i)%NBBY)))
316*3147Sxc151355 #define	ieee80211_clrbit(a, i)	((a)[(i)/NBBY] &= ~(1 << ((i)%NBBY)))
317*3147Sxc151355 #define	ieee80211_isset(a, i)	((a)[(i)/NBBY] & (1 << ((i)%NBBY)))
318*3147Sxc151355 #define	ieee80211_isclr(a, i)	(!((a)[(i)/NBBY] & (1 << ((i)%NBBY))))
319*3147Sxc151355 
320*3147Sxc151355 #define	IEEE80211_N(a)		(sizeof (a) / sizeof (a[0]))
321*3147Sxc151355 
322*3147Sxc151355 #define	IEEE80211_LOCK(_ic)		\
323*3147Sxc151355 	mutex_enter(&(_ic)->ic_genlock)
324*3147Sxc151355 #define	IEEE80211_UNLOCK(_ic)		\
325*3147Sxc151355 	mutex_exit(&(_ic)->ic_genlock)
326*3147Sxc151355 #define	IEEE80211_IS_LOCKED(_ic)	\
327*3147Sxc151355 	mutex_owned(&(_ic)->ic_genlock)
328*3147Sxc151355 #define	IEEE80211_LOCK_ASSERT(_ic)	\
329*3147Sxc151355 	ASSERT(mutex_owned(&(_ic)->ic_genlock))
330*3147Sxc151355 
331*3147Sxc151355 #define	IEEE80211_NODE_LOCK(_nt)		\
332*3147Sxc151355 	mutex_enter(&(_nt)->nt_nodelock)
333*3147Sxc151355 #define	IEEE80211_NODE_UNLOCK(_nt)		\
334*3147Sxc151355 	mutex_exit(&(_nt)->nt_nodelock)
335*3147Sxc151355 #define	IEEE80211_NODE_IS_LOCKED(_nt)		\
336*3147Sxc151355 	mutex_owned(&(_nt)->nt_nodelock)
337*3147Sxc151355 #define	IEEE80211_NODE_LOCK_ASSERT(_nt)		\
338*3147Sxc151355 	ASSERT(mutex_owned(&(_nt)->nt_nodelock))
339*3147Sxc151355 #define	ieee80211_node_hash(addr)		\
340*3147Sxc151355 	(((uint8_t *)(addr))[IEEE80211_ADDR_LEN - 1] % IEEE80211_NODE_HASHSIZE)
341*3147Sxc151355 
342*3147Sxc151355 #define	IEEE80211_SCAN_LOCK(_nt)	mutex_enter(&(_nt)->nt_scanlock)
343*3147Sxc151355 #define	IEEE80211_SCAN_UNLOCK(_nt)	mutex_exit(&(_nt)->nt_scanlock)
344*3147Sxc151355 
345*3147Sxc151355 #define	IEEE80211_RV(v)			((v) & IEEE80211_RATE_VAL)
346*3147Sxc151355 
347*3147Sxc151355 #define	IEEE80211_SUBTYPE_NAME(subtype)		\
348*3147Sxc151355 	ieee80211_mgt_subtype_name[(subtype) >> IEEE80211_FC0_SUBTYPE_SHIFT]
349*3147Sxc151355 
350*3147Sxc151355 extern const char *ieee80211_mgt_subtype_name[];
351*3147Sxc151355 extern const char *ieee80211_phymode_name[];
352*3147Sxc151355 
353*3147Sxc151355 void ieee80211_err(const int8_t *, ...);
354*3147Sxc151355 void ieee80211_dbg(uint32_t, const int8_t *, ...);
355*3147Sxc151355 int ieee80211_hdrspace(const void *);
356*3147Sxc151355 
357*3147Sxc151355 /* node */
358*3147Sxc151355 void ieee80211_node_attach(ieee80211com_t *);
359*3147Sxc151355 void ieee80211_node_lateattach(ieee80211com_t *);
360*3147Sxc151355 void ieee80211_node_detach(ieee80211com_t *);
361*3147Sxc151355 void ieee80211_reset_bss(ieee80211com_t *);
362*3147Sxc151355 void ieee80211_cancel_scan(ieee80211com_t *);
363*3147Sxc151355 void ieee80211_add_scan(ieee80211com_t *, const struct ieee80211_scanparams *,
364*3147Sxc151355     const struct ieee80211_frame *, int, int, int);
365*3147Sxc151355 void ieee80211_init_neighbor(ieee80211_node_t *, const struct ieee80211_frame *,
366*3147Sxc151355     const struct ieee80211_scanparams *);
367*3147Sxc151355 ieee80211_node_t *ieee80211_add_neighbor(ieee80211com_t *,
368*3147Sxc151355     const struct ieee80211_frame *, const struct ieee80211_scanparams *);
369*3147Sxc151355 void ieee80211_create_ibss(ieee80211com_t *, struct ieee80211_channel *);
370*3147Sxc151355 ieee80211_node_t *ieee80211_fakeup_adhoc_node(ieee80211_node_table_t *,
371*3147Sxc151355     const uint8_t *);
372*3147Sxc151355 ieee80211_node_t *ieee80211_tmp_node(ieee80211com_t *, const uint8_t *);
373*3147Sxc151355 
374*3147Sxc151355 /* proto */
375*3147Sxc151355 void ieee80211_proto_attach(ieee80211com_t *);
376*3147Sxc151355 int ieee80211_fix_rate(ieee80211_node_t *, int);
377*3147Sxc151355 void ieee80211_setbasicrates(struct ieee80211_rateset *,
378*3147Sxc151355     enum ieee80211_phymode);
379*3147Sxc151355 void ieee80211_reset_erp(ieee80211com_t *);
380*3147Sxc151355 void ieee80211_set_shortslottime(ieee80211com_t *, boolean_t);
381*3147Sxc151355 
382*3147Sxc151355 /* input */
383*3147Sxc151355 int ieee80211_setup_rates(ieee80211_node_t *, const uint8_t *,
384*3147Sxc151355     const uint8_t *, int);
385*3147Sxc151355 void ieee80211_recv_mgmt(ieee80211com_t *, mblk_t *, ieee80211_node_t *,
386*3147Sxc151355     int, int, uint32_t);
387*3147Sxc151355 
388*3147Sxc151355 /* output */
389*3147Sxc151355 int ieee80211_send_probereq(ieee80211_node_t *, const uint8_t *,
390*3147Sxc151355     const uint8_t *, const uint8_t *, const uint8_t *, size_t, const void *,
391*3147Sxc151355     size_t);
392*3147Sxc151355 int ieee80211_send_mgmt(ieee80211com_t *, ieee80211_node_t *, int, int);
393*3147Sxc151355 int ieee80211_send_nulldata(ieee80211_node_t *);
394*3147Sxc151355 
395*3147Sxc151355 /* crypto */
396*3147Sxc151355 struct ieee80211_key *ieee80211_crypto_getkey(ieee80211com_t *);
397*3147Sxc151355 uint8_t ieee80211_crypto_getciphertype(ieee80211com_t *);
398*3147Sxc151355 
399*3147Sxc151355 /* generic */
400*3147Sxc151355 mblk_t *ieee80211_getmgtframe(uint8_t **, int);
401*3147Sxc151355 void ieee80211_notify_node_join(ieee80211com_t *, ieee80211_node_t *);
402*3147Sxc151355 void ieee80211_notify_node_leave(ieee80211com_t *, ieee80211_node_t *);
403*3147Sxc151355 
404*3147Sxc151355 #ifdef	__cplusplus
405*3147Sxc151355 }
406*3147Sxc151355 #endif
407*3147Sxc151355 
408*3147Sxc151355 #endif	/* _SYS_NET80211_IMPL_H */
409