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