1 /*
2  * Copyright (c) 2001 Atsushi Onoe
3  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * Alternatively, this software may be distributed under the terms of the
18  * GNU General Public License ("GPL") version 2 as published by the Free
19  * Software Foundation.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * $FreeBSD: src/sys/net80211/ieee80211_proto.c,v 1.17.2.9 2006/03/13 03:10:31 sam Exp $
33  * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_proto.c,v 1.12 2007/04/26 12:59:14 sephe Exp $
34  */
35 
36 /*
37  * IEEE 802.11 protocol support.
38  */
39 
40 #include "opt_inet.h"
41 
42 #include <sys/param.h>
43 #include <sys/kernel.h>
44 #include <sys/systm.h>
45 #include <sys/serialize.h>
46 
47 #include <sys/socket.h>
48 
49 #include <net/if.h>
50 #include <net/if_arp.h>
51 #include <net/if_media.h>
52 #include <net/ethernet.h>		/* XXX for ether_sprintf */
53 
54 #include <netproto/802_11/ieee80211_var.h>
55 
56 /* XXX tunables */
57 #define	AGGRESSIVE_MODE_SWITCH_HYSTERESIS	3	/* pkts / 100ms */
58 #define	HIGH_PRI_SWITCH_THRESH			10	/* pkts / 100ms */
59 
60 #define	IEEE80211_RATE2MBS(r)	(((r) & IEEE80211_RATE_VAL) / 2)
61 
62 const char *ieee80211_mgt_subtype_name[] = IEEE80211_MGT_SUBTYPE_NAMES;
63 const char *ieee80211_ctl_subtype_name[] = IEEE80211_CTL_SUBTYPE_NAMES;
64 const char *ieee80211_state_name[IEEE80211_S_MAX] = {
65 	"INIT",		/* IEEE80211_S_INIT */
66 	"SCAN",		/* IEEE80211_S_SCAN */
67 	"AUTH",		/* IEEE80211_S_AUTH */
68 	"ASSOC",	/* IEEE80211_S_ASSOC */
69 	"RUN"		/* IEEE80211_S_RUN */
70 };
71 const char *ieee80211_wme_acnames[] = {
72 	"WME_AC_BE",
73 	"WME_AC_BK",
74 	"WME_AC_VI",
75 	"WME_AC_VO",
76 	"WME_UPSD",
77 };
78 
79 static int ieee80211_newstate(struct ieee80211com *, enum ieee80211_state, int);
80 
81 void
82 ieee80211_proto_attach(struct ieee80211com *ic)
83 {
84 	struct ifnet *ifp = ic->ic_ifp;
85 
86 	/* XXX room for crypto  */
87 	ifp->if_hdrlen = sizeof(struct ieee80211_qosframe_addr4);
88 
89 	ic->ic_rtsthreshold = IEEE80211_RTS_DEFAULT;
90 	ic->ic_fragthreshold = IEEE80211_FRAG_DEFAULT;
91 	ic->ic_fixed_rate = IEEE80211_FIXED_RATE_NONE;
92 	ic->ic_bmiss_max = IEEE80211_BMISS_MAX;
93 	callout_init(&ic->ic_swbmiss);
94 	ic->ic_mcast_rate = IEEE80211_MCAST_RATE_DEFAULT;
95 	ic->ic_protmode = IEEE80211_PROT_CTSONLY;
96 	ic->ic_roaming = IEEE80211_ROAMING_AUTO;
97 
98 	ic->ic_wme.wme_hipri_switch_hysteresis =
99 		AGGRESSIVE_MODE_SWITCH_HYSTERESIS;
100 
101 	/* protocol state change handler */
102 	ic->ic_newstate = ieee80211_newstate;
103 
104 	/* initialize management frame handlers */
105 	ic->ic_recv_mgmt = ieee80211_recv_mgmt;
106 	ic->ic_send_mgmt = ieee80211_send_mgmt;
107 }
108 
109 void
110 ieee80211_proto_detach(struct ieee80211com *ic)
111 {
112 
113 	/*
114 	 * This should not be needed as we detach when reseting
115 	 * the state but be conservative here since the
116 	 * authenticator may do things like spawn kernel threads.
117 	 */
118 	if (ic->ic_auth->ia_detach)
119 		ic->ic_auth->ia_detach(ic);
120 
121 	ieee80211_drain_mgtq(&ic->ic_mgtq);
122 
123 	/*
124 	 * Detach any ACL'ator.
125 	 */
126 	if (ic->ic_acl != NULL)
127 		ic->ic_acl->iac_detach(ic);
128 }
129 
130 /*
131  * Simple-minded authenticator module support.
132  */
133 
134 #define	IEEE80211_AUTH_MAX	(IEEE80211_AUTH_WPA+1)
135 /* XXX well-known names */
136 static const char *auth_modnames[IEEE80211_AUTH_MAX] = {
137 	"wlan_internal",	/* IEEE80211_AUTH_NONE */
138 	"wlan_internal",	/* IEEE80211_AUTH_OPEN */
139 	"wlan_internal",	/* IEEE80211_AUTH_SHARED */
140 	"wlan_xauth",		/* IEEE80211_AUTH_8021X	 */
141 	"wlan_internal",	/* IEEE80211_AUTH_AUTO */
142 	"wlan_xauth",		/* IEEE80211_AUTH_WPA */
143 };
144 static const struct ieee80211_authenticator *authenticators[IEEE80211_AUTH_MAX];
145 
146 static const struct ieee80211_authenticator auth_internal = {
147 	.ia_name		= "wlan_internal",
148 	.ia_attach		= NULL,
149 	.ia_detach		= NULL,
150 	.ia_node_join		= NULL,
151 	.ia_node_leave		= NULL,
152 };
153 
154 /*
155  * Setup internal authenticators once; they are never unregistered.
156  */
157 static void
158 ieee80211_auth_setup(void)
159 {
160 	ieee80211_authenticator_register(IEEE80211_AUTH_OPEN, &auth_internal);
161 	ieee80211_authenticator_register(IEEE80211_AUTH_SHARED, &auth_internal);
162 	ieee80211_authenticator_register(IEEE80211_AUTH_AUTO, &auth_internal);
163 }
164 SYSINIT(wlan_auth, SI_SUB_DRIVERS, SI_ORDER_FIRST, ieee80211_auth_setup, NULL);
165 
166 const struct ieee80211_authenticator *
167 ieee80211_authenticator_get(int auth)
168 {
169 	if (auth >= IEEE80211_AUTH_MAX)
170 		return NULL;
171 	if (authenticators[auth] == NULL)
172 		ieee80211_load_module(auth_modnames[auth]);
173 	return authenticators[auth];
174 }
175 
176 void
177 ieee80211_authenticator_register(int type,
178 	const struct ieee80211_authenticator *auth)
179 {
180 	if (type >= IEEE80211_AUTH_MAX)
181 		return;
182 	authenticators[type] = auth;
183 }
184 
185 void
186 ieee80211_authenticator_unregister(int type)
187 {
188 
189 	if (type >= IEEE80211_AUTH_MAX)
190 		return;
191 	authenticators[type] = NULL;
192 }
193 
194 /*
195  * Very simple-minded ACL module support.
196  */
197 /* XXX just one for now */
198 static	const struct ieee80211_aclator *acl = NULL;
199 
200 void
201 ieee80211_aclator_register(const struct ieee80211_aclator *iac)
202 {
203 	kprintf("wlan: %s acl policy registered\n", iac->iac_name);
204 	acl = iac;
205 }
206 
207 void
208 ieee80211_aclator_unregister(const struct ieee80211_aclator *iac)
209 {
210 	if (acl == iac)
211 		acl = NULL;
212 	kprintf("wlan: %s acl policy unregistered\n", iac->iac_name);
213 }
214 
215 const struct ieee80211_aclator *
216 ieee80211_aclator_get(const char *name)
217 {
218 	if (acl == NULL)
219 		ieee80211_load_module("wlan_acl");
220 	return acl != NULL && strcmp(acl->iac_name, name) == 0 ? acl : NULL;
221 }
222 
223 void
224 ieee80211_print_essid(const uint8_t *essid, int len)
225 {
226 	const uint8_t *p;
227 	int i;
228 
229 	if (len > IEEE80211_NWID_LEN)
230 		len = IEEE80211_NWID_LEN;
231 	/* determine printable or not */
232 	for (i = 0, p = essid; i < len; i++, p++) {
233 		if (*p < ' ' || *p > 0x7e)
234 			break;
235 	}
236 	if (i == len) {
237 		kprintf("\"");
238 		for (i = 0, p = essid; i < len; i++, p++)
239 			kprintf("%c", *p);
240 		kprintf("\"");
241 	} else {
242 		kprintf("0x");
243 		for (i = 0, p = essid; i < len; i++, p++)
244 			kprintf("%02x", *p);
245 	}
246 }
247 
248 void
249 ieee80211_print_rateset(const struct ieee80211_rateset *rs)
250 {
251 	int i;
252 
253 	for (i = 0; i < rs->rs_nrates; ++i) {
254 		kprintf("%d%s ", IEEE80211_RS_RATE(rs, i),
255 		       (rs->rs_rates[i] & IEEE80211_RATE_BASIC) ?  "*" : "");
256 	}
257 }
258 
259 void
260 ieee80211_dump_pkt(const uint8_t *buf, int len, int rate, int rssi)
261 {
262 	const struct ieee80211_frame *wh;
263 	int i;
264 
265 	wh = (const struct ieee80211_frame *)buf;
266 	switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
267 	case IEEE80211_FC1_DIR_NODS:
268 		kprintf("NODS %6D", wh->i_addr2, ":");
269 		kprintf("->%6D", wh->i_addr1, ":");
270 		kprintf("(%6D)", wh->i_addr3, ":");
271 		break;
272 	case IEEE80211_FC1_DIR_TODS:
273 		kprintf("TODS %6D", wh->i_addr2, ":");
274 		kprintf("->%6D", wh->i_addr3, ":");
275 		kprintf("(%6D)", wh->i_addr1, ":");
276 		break;
277 	case IEEE80211_FC1_DIR_FROMDS:
278 		kprintf("FRDS %6D", wh->i_addr3, ":");
279 		kprintf("->%6D", wh->i_addr1, ":");
280 		kprintf("(%6D)", wh->i_addr2, ":");
281 		break;
282 	case IEEE80211_FC1_DIR_DSTODS:
283 		kprintf("DSDS %6D", (const uint8_t *)&wh[1], ":");
284 		kprintf("->%6D", wh->i_addr3, ":");
285 		kprintf("(%6D", wh->i_addr2, ":");
286 		kprintf("->%6D)", wh->i_addr1, ":");
287 		break;
288 	}
289 	switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
290 	case IEEE80211_FC0_TYPE_DATA:
291 		kprintf(" data");
292 		break;
293 	case IEEE80211_FC0_TYPE_MGT:
294 		kprintf(" %s", ieee80211_mgt_subtype_name[
295 		    (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK)
296 		    >> IEEE80211_FC0_SUBTYPE_SHIFT]);
297 		break;
298 	default:
299 		kprintf(" type#%d", wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK);
300 		break;
301 	}
302 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
303 		int i;
304 		kprintf(" WEP [IV");
305 		for (i = 0; i < IEEE80211_WEP_IVLEN; i++)
306 			kprintf(" %.02x", buf[sizeof(*wh)+i]);
307 		kprintf(" KID %u]", buf[sizeof(*wh)+i] >> 6);
308 	}
309 	if (rate >= 0)
310 		kprintf(" %dM", rate / 2);
311 	if (rssi >= 0)
312 		kprintf(" +%d", rssi);
313 	kprintf("\n");
314 	if (len > 0) {
315 		for (i = 0; i < len; i++) {
316 			if ((i & 1) == 0)
317 				kprintf(" ");
318 			kprintf("%02x", buf[i]);
319 		}
320 		kprintf("\n");
321 	}
322 }
323 
324 int
325 ieee80211_fix_rate(struct ieee80211_node *ni, int flags, int join)
326 {
327 #define	RV(v)	((v) & IEEE80211_RATE_VAL)
328 	struct ieee80211com *ic = ni->ni_ic;
329 	int i, j, ignore, error, nbasicrates;
330 	int okrate, badrate, fixedrate;
331 	const struct ieee80211_rateset *srs;
332 	struct ieee80211_rateset *nrs;
333 	uint8_t r;
334 
335 	/*
336 	 * If the fixed rate check was requested but no
337 	 * fixed has been defined then just remove it.
338 	 */
339 	if ((flags & IEEE80211_F_DOFRATE) &&
340 	    ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE)
341 		flags &= ~IEEE80211_F_DOFRATE;
342 	error = 0;
343 	okrate = badrate = fixedrate = 0;
344 	nbasicrates = 0;
345 	srs = &ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)];
346 	nrs = &ni->ni_rates;
347 	for (i = 0; i < nrs->rs_nrates; ) {
348 		ignore = 0;
349 		if (flags & IEEE80211_F_DOSORT) {
350 			/*
351 			 * Sort rates.
352 			 */
353 			for (j = i + 1; j < nrs->rs_nrates; j++) {
354 				if (RV(nrs->rs_rates[i]) > RV(nrs->rs_rates[j])) {
355 					r = nrs->rs_rates[i];
356 					nrs->rs_rates[i] = nrs->rs_rates[j];
357 					nrs->rs_rates[j] = r;
358 				}
359 			}
360 
361 			/*
362 			 * Remove duplicated rate
363 			 */
364 			if (i > 0 &&
365 			    IEEE80211_RS_RATE(nrs, i) ==
366 			    IEEE80211_RS_RATE(nrs, i - 1)) {
367 				ignore = 1;
368 				goto delit;
369 			}
370 		}
371 		r = nrs->rs_rates[i] & IEEE80211_RATE_VAL;
372 		badrate = r;
373 		if (flags & IEEE80211_F_DOFRATE) {
374 			/*
375 			 * Check any fixed rate is included.
376 			 */
377 			if (r == RV(srs->rs_rates[ic->ic_fixed_rate]))
378 				fixedrate = r;
379 		}
380 		if (flags & (IEEE80211_F_DONEGO | IEEE80211_F_DODEL)) {
381 			/*
382 			 * Check against supported rates.
383 			 */
384 			for (j = 0; j < srs->rs_nrates; j++) {
385 				if (r == RV(srs->rs_rates[j])) {
386 					/*
387 					 * Overwrite with the supported rate
388 					 * value so any basic rate bit is set.
389 					 */
390 					if ((flags & IEEE80211_F_DONEGO) &&
391 					    !join) {
392 						nrs->rs_rates[i] =
393 						    srs->rs_rates[j];
394 
395 						if (nrs->rs_rates[i] &
396 						    IEEE80211_RATE_BASIC)
397 							nbasicrates++;
398 					}
399 					break;
400 				}
401 			}
402 			if (j == srs->rs_nrates) {
403 				/*
404 				 * A rate in the node's rate set is not
405 				 * supported.  If this is a basic rate and
406 				 * we are operating as an STA then this is
407 				 * an error.
408 				 */
409 				if ((flags & IEEE80211_F_DONEGO) && join &&
410 				    (nrs->rs_rates[i] & IEEE80211_RATE_BASIC))
411 					error++;
412 				ignore++;
413 			}
414 		}
415 		if (flags & IEEE80211_F_DODEL) {
416 delit:
417 			/*
418 			 * Delete unacceptable rates.
419 			 */
420 			if (ignore) {
421 				nrs->rs_nrates--;
422 				for (j = i; j < nrs->rs_nrates; j++)
423 					nrs->rs_rates[j] = nrs->rs_rates[j + 1];
424 				nrs->rs_rates[j] = 0;
425 				continue;
426 			}
427 		}
428 		if (!ignore)
429 			okrate = nrs->rs_rates[i];
430 		i++;
431 	}
432 
433 	/*
434 	 * Prevent STA from associating, if it does not support
435 	 * all of the rates in the basic rate set.
436 	 */
437 	if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
438 	    (flags & IEEE80211_F_DONEGO) && !join &&
439 	    ic->ic_nbasicrates > nbasicrates)
440 		error++;
441 
442 	if (okrate == 0 || error != 0 ||
443 	    ((flags & IEEE80211_F_DOFRATE) && fixedrate == 0))
444 		return badrate | IEEE80211_RATE_BASIC;
445 	else
446 		return RV(okrate);
447 #undef RV
448 }
449 
450 /*
451  * Reset 11g-related state.
452  */
453 void
454 ieee80211_reset_erp(struct ieee80211com *ic)
455 {
456 	ic->ic_flags &= ~IEEE80211_F_USEPROT;
457 	ic->ic_nonerpsta = 0;
458 	ic->ic_longslotsta = 0;
459 	/*
460 	 * Short slot time is enabled only when operating in 11g
461 	 * and not in an IBSS.  We must also honor whether or not
462 	 * the driver is capable of doing it.
463 	 */
464 	ieee80211_set_shortslottime(ic,
465 		ic->ic_curmode == IEEE80211_MODE_11A ||
466 		(ic->ic_curmode == IEEE80211_MODE_11G &&
467 		ic->ic_opmode == IEEE80211_M_HOSTAP &&
468 		(ic->ic_caps & IEEE80211_C_SHSLOT)));
469 	/*
470 	 * Set short preamble and ERP barker-preamble flags.
471 	 */
472 	ieee80211_set_shortpreamble(ic,
473 		ic->ic_curmode == IEEE80211_MODE_11A ||
474 		(ic->ic_caps & IEEE80211_C_SHPREAMBLE));
475 }
476 
477 /*
478  * Set the short slot time state and notify the driver.
479  */
480 void
481 ieee80211_set_shortslottime(struct ieee80211com *ic, int onoff)
482 {
483 	if (onoff)
484 		ic->ic_flags |= IEEE80211_F_SHSLOT;
485 	else
486 		ic->ic_flags &= ~IEEE80211_F_SHSLOT;
487 
488 	/* Notify driver */
489 	if (ic->ic_updateslot != NULL)
490 		ic->ic_updateslot(ic->ic_ifp);
491 }
492 
493 /*
494  * Set the short preamble state and notify driver.
495  */
496 void
497 ieee80211_set_shortpreamble(struct ieee80211com *ic, int onoff)
498 {
499 	if (onoff) {
500 		ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
501 		ic->ic_flags &= ~IEEE80211_F_USEBARKER;
502 	} else {
503 		ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
504 		ic->ic_flags |= IEEE80211_F_USEBARKER;
505 	}
506 
507 	/* Notify driver */
508 	if (ic->ic_update_preamble != NULL)
509 		ic->ic_update_preamble(ic->ic_ifp);
510 }
511 
512 /*
513  * Check if the specified rate set supports ERP.
514  * NB: the rate set is assumed to be sorted.
515  */
516 int
517 ieee80211_iserp_rateset(struct ieee80211com *ic,
518 			const struct ieee80211_rateset *rs)
519 {
520 #define N(a)	(sizeof(a) / sizeof(a[0]))
521 	static const int rates[] = { 2, 4, 11, 22, 12, 24, 48 };
522 	int i, j;
523 
524 	if (rs->rs_nrates < N(rates))
525 		return 0;
526 	for (i = 0; i < N(rates); i++) {
527 		for (j = 0; j < rs->rs_nrates; j++) {
528 			int r = rs->rs_rates[j] & IEEE80211_RATE_VAL;
529 			if (rates[i] == r)
530 				goto next;
531 			if (r > rates[i])
532 				return 0;
533 		}
534 		return 0;
535 	next:
536 		;
537 	}
538 	return 1;
539 #undef N
540 }
541 
542 /*
543  * Mark the basic rates for the 11g rate table based on the
544  * operating mode.  For real 11g we mark all the 11b rates
545  * and 6, 12, and 24 OFDM.  For 11b compatibility we mark only
546  * 11b rates.  There's also a pseudo 11a-mode used to mark only
547  * the basic OFDM rates.
548  */
549 void
550 ieee80211_set_basicrates(struct ieee80211_rateset *rs,
551 			 enum ieee80211_phymode mode, int pureg)
552 {
553 	static const struct ieee80211_rateset basic[] = {
554 	    [IEEE80211_MODE_AUTO]	= { 0 },
555 	    [IEEE80211_MODE_11A]	= { 3, { 12, 24, 48 } },
556 	    [IEEE80211_MODE_11B]	= { 2, { 2, 4 } },
557 	    [IEEE80211_MODE_11G]	= { 4, { 2, 4, 11, 22 } },
558 	    [IEEE80211_MODE_FH]		= { 0 },
559 	    [IEEE80211_MODE_TURBO_A]	= { 3, { 12, 24, 48 } },
560 	    [IEEE80211_MODE_TURBO_G]	= { 4, { 2, 4, 11, 22 } }
561 	};
562 	static const struct ieee80211_rateset basic_pureg =
563 	    { 7, { 2, 4, 11, 22, 12, 24, 48 } };
564 	const struct ieee80211_rateset *basic_rs;
565 	int i, j;
566 
567 	KASSERT(mode < IEEE80211_MODE_MAX, ("invalid phymode %u\n", mode));
568 
569 	if ((mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_TURBO_G) &&
570 	    pureg)
571 		basic_rs = &basic_pureg;
572 	else
573 		basic_rs = &basic[mode];
574 
575 	for (i = 0; i < rs->rs_nrates; i++) {
576 		rs->rs_rates[i] &= IEEE80211_RATE_VAL;
577 		for (j = 0; j < basic_rs->rs_nrates; j++) {
578 			if (basic_rs->rs_rates[j] == rs->rs_rates[i]) {
579 				rs->rs_rates[i] |= IEEE80211_RATE_BASIC;
580 				break;
581 			}
582 		}
583 	}
584 }
585 
586 int
587 ieee80211_copy_basicrates(struct ieee80211_rateset *to,
588 			  const struct ieee80211_rateset *from)
589 {
590 	int i, nbasicrates = 0;
591 
592 	for (i = 0; i < to->rs_nrates; ++i) {
593 		int j;
594 
595 		to->rs_rates[i] &= IEEE80211_RATE_VAL;
596 		for (j = 0; j < from->rs_nrates; ++j) {
597 			if ((from->rs_rates[j] & IEEE80211_RATE_BASIC) &&
598 			    IEEE80211_RS_RATE(from, j) == to->rs_rates[i]) {
599 				to->rs_rates[i] |= IEEE80211_RATE_BASIC;
600 				++nbasicrates;
601 				break;
602 			}
603 		}
604 	}
605 	return nbasicrates;
606 }
607 
608 /*
609  * WME protocol support.  The following parameters come from the spec.
610  */
611 typedef struct phyParamType {
612 	uint8_t aifsn;
613 	uint8_t logcwmin;
614 	uint8_t logcwmax;
615 	uint16_t txopLimit;
616 	uint8_t acm;
617 } paramType;
618 
619 static const struct phyParamType phyParamForAC_BE[IEEE80211_MODE_MAX] = {
620 	{ 3, 4, 6 },		/* IEEE80211_MODE_AUTO */
621 	{ 3, 4, 6 },		/* IEEE80211_MODE_11A */
622 	{ 3, 5, 7 },		/* IEEE80211_MODE_11B */
623 	{ 3, 4, 6 },		/* IEEE80211_MODE_11G */
624 	{ 3, 5, 7 },		/* IEEE80211_MODE_FH */
625 	{ 2, 3, 5 },		/* IEEE80211_MODE_TURBO_A */
626 	{ 2, 3, 5 },		/* IEEE80211_MODE_TURBO_G */
627 };
628 static const struct phyParamType phyParamForAC_BK[IEEE80211_MODE_MAX] = {
629 	{ 7, 4, 10 },		/* IEEE80211_MODE_AUTO */
630 	{ 7, 4, 10 },		/* IEEE80211_MODE_11A */
631 	{ 7, 5, 10 },		/* IEEE80211_MODE_11B */
632 	{ 7, 4, 10 },		/* IEEE80211_MODE_11G */
633 	{ 7, 5, 10 },		/* IEEE80211_MODE_FH */
634 	{ 7, 3, 10 },		/* IEEE80211_MODE_TURBO_A */
635 	{ 7, 3, 10 },		/* IEEE80211_MODE_TURBO_G */
636 };
637 static const struct phyParamType phyParamForAC_VI[IEEE80211_MODE_MAX] = {
638 	{ 1, 3, 4,  94 },	/* IEEE80211_MODE_AUTO */
639 	{ 1, 3, 4,  94 },	/* IEEE80211_MODE_11A */
640 	{ 1, 4, 5, 188 },	/* IEEE80211_MODE_11B */
641 	{ 1, 3, 4,  94 },	/* IEEE80211_MODE_11G */
642 	{ 1, 4, 5, 188 },	/* IEEE80211_MODE_FH */
643 	{ 1, 2, 3,  94 },	/* IEEE80211_MODE_TURBO_A */
644 	{ 1, 2, 3,  94 },	/* IEEE80211_MODE_TURBO_G */
645 };
646 static const struct phyParamType phyParamForAC_VO[IEEE80211_MODE_MAX] = {
647 	{ 1, 2, 3,  47 },	/* IEEE80211_MODE_AUTO */
648 	{ 1, 2, 3,  47 },	/* IEEE80211_MODE_11A */
649 	{ 1, 3, 4, 102 },	/* IEEE80211_MODE_11B */
650 	{ 1, 2, 3,  47 },	/* IEEE80211_MODE_11G */
651 	{ 1, 3, 4, 102 },	/* IEEE80211_MODE_FH */
652 	{ 1, 2, 2,  47 },	/* IEEE80211_MODE_TURBO_A */
653 	{ 1, 2, 2,  47 },	/* IEEE80211_MODE_TURBO_G */
654 };
655 
656 static const struct phyParamType bssPhyParamForAC_BE[IEEE80211_MODE_MAX] = {
657 	{ 3, 4, 10 },		/* IEEE80211_MODE_AUTO */
658 	{ 3, 4, 10 },		/* IEEE80211_MODE_11A */
659 	{ 3, 5, 10 },		/* IEEE80211_MODE_11B */
660 	{ 3, 4, 10 },		/* IEEE80211_MODE_11G */
661 	{ 3, 5, 10 },		/* IEEE80211_MODE_FH */
662 	{ 2, 3, 10 },		/* IEEE80211_MODE_TURBO_A */
663 	{ 2, 3, 10 },		/* IEEE80211_MODE_TURBO_G */
664 };
665 static const struct phyParamType bssPhyParamForAC_VI[IEEE80211_MODE_MAX] = {
666 	{ 2, 3, 4,  94 },	/* IEEE80211_MODE_AUTO */
667 	{ 2, 3, 4,  94 },	/* IEEE80211_MODE_11A */
668 	{ 2, 4, 5, 188 },	/* IEEE80211_MODE_11B */
669 	{ 2, 3, 4,  94 },	/* IEEE80211_MODE_11G */
670 	{ 2, 4, 5, 188 },	/* IEEE80211_MODE_FH */
671 	{ 2, 2, 3,  94 },	/* IEEE80211_MODE_TURBO_A */
672 	{ 2, 2, 3,  94 },	/* IEEE80211_MODE_TURBO_G */
673 };
674 static const struct phyParamType bssPhyParamForAC_VO[IEEE80211_MODE_MAX] = {
675 	{ 2, 2, 3,  47 },	/* IEEE80211_MODE_AUTO */
676 	{ 2, 2, 3,  47 },	/* IEEE80211_MODE_11A */
677 	{ 2, 3, 4, 102 },	/* IEEE80211_MODE_11B */
678 	{ 2, 2, 3,  47 },	/* IEEE80211_MODE_11G */
679 	{ 2, 3, 4, 102 },	/* IEEE80211_MODE_FH */
680 	{ 1, 2, 2,  47 },	/* IEEE80211_MODE_TURBO_A */
681 	{ 1, 2, 2,  47 },	/* IEEE80211_MODE_TURBO_G */
682 };
683 
684 void
685 ieee80211_wme_initparams(struct ieee80211com *ic)
686 {
687 	struct ieee80211_wme_state *wme = &ic->ic_wme;
688 	const paramType *pPhyParam, *pBssPhyParam;
689 	struct wmeParams *wmep;
690 	int i;
691 
692 	if ((ic->ic_caps & IEEE80211_C_WME) == 0)
693 		return;
694 
695 	for (i = 0; i < WME_NUM_AC; i++) {
696 		switch (i) {
697 		case WME_AC_BK:
698 			pPhyParam = &phyParamForAC_BK[ic->ic_curmode];
699 			pBssPhyParam = &phyParamForAC_BK[ic->ic_curmode];
700 			break;
701 		case WME_AC_VI:
702 			pPhyParam = &phyParamForAC_VI[ic->ic_curmode];
703 			pBssPhyParam = &bssPhyParamForAC_VI[ic->ic_curmode];
704 			break;
705 		case WME_AC_VO:
706 			pPhyParam = &phyParamForAC_VO[ic->ic_curmode];
707 			pBssPhyParam = &bssPhyParamForAC_VO[ic->ic_curmode];
708 			break;
709 		case WME_AC_BE:
710 		default:
711 			pPhyParam = &phyParamForAC_BE[ic->ic_curmode];
712 			pBssPhyParam = &bssPhyParamForAC_BE[ic->ic_curmode];
713 			break;
714 		}
715 
716 		wmep = &wme->wme_wmeChanParams.cap_wmeParams[i];
717 		if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
718 			wmep->wmep_acm = pPhyParam->acm;
719 			wmep->wmep_aifsn = pPhyParam->aifsn;
720 			wmep->wmep_logcwmin = pPhyParam->logcwmin;
721 			wmep->wmep_logcwmax = pPhyParam->logcwmax;
722 			wmep->wmep_txopLimit = pPhyParam->txopLimit;
723 		} else {
724 			wmep->wmep_acm = pBssPhyParam->acm;
725 			wmep->wmep_aifsn = pBssPhyParam->aifsn;
726 			wmep->wmep_logcwmin = pBssPhyParam->logcwmin;
727 			wmep->wmep_logcwmax = pBssPhyParam->logcwmax;
728 			wmep->wmep_txopLimit = pBssPhyParam->txopLimit;
729 
730 		}
731 		IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME,
732 			"%s: %s chan [acm %u aifsn %u log2(cwmin) %u "
733 			"log2(cwmax) %u txpoLimit %u]\n", __func__
734 			, ieee80211_wme_acnames[i]
735 			, wmep->wmep_acm
736 			, wmep->wmep_aifsn
737 			, wmep->wmep_logcwmin
738 			, wmep->wmep_logcwmax
739 			, wmep->wmep_txopLimit
740 		);
741 
742 		wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[i];
743 		wmep->wmep_acm = pBssPhyParam->acm;
744 		wmep->wmep_aifsn = pBssPhyParam->aifsn;
745 		wmep->wmep_logcwmin = pBssPhyParam->logcwmin;
746 		wmep->wmep_logcwmax = pBssPhyParam->logcwmax;
747 		wmep->wmep_txopLimit = pBssPhyParam->txopLimit;
748 		IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME,
749 			"%s: %s  bss [acm %u aifsn %u log2(cwmin) %u "
750 			"log2(cwmax) %u txpoLimit %u]\n", __func__
751 			, ieee80211_wme_acnames[i]
752 			, wmep->wmep_acm
753 			, wmep->wmep_aifsn
754 			, wmep->wmep_logcwmin
755 			, wmep->wmep_logcwmax
756 			, wmep->wmep_txopLimit
757 		);
758 	}
759 	/* NB: check ic_bss to avoid NULL deref on initial attach */
760 	if (ic->ic_bss != NULL) {
761 		/*
762 		 * Calculate agressive mode switching threshold based
763 		 * on beacon interval.  This doesn't need locking since
764 		 * we're only called before entering the RUN state at
765 		 * which point we start sending beacon frames.
766 		 */
767 		wme->wme_hipri_switch_thresh =
768 			(HIGH_PRI_SWITCH_THRESH * ic->ic_bss->ni_intval) / 100;
769 		ieee80211_wme_updateparams(ic);
770 	}
771 }
772 
773 /*
774  * Update WME parameters for ourself and the BSS.
775  */
776 void
777 ieee80211_wme_updateparams(struct ieee80211com *ic)
778 {
779 	static const paramType phyParam[IEEE80211_MODE_MAX] = {
780 		{ 2, 4, 10, 64 },	/* IEEE80211_MODE_AUTO */
781 		{ 2, 4, 10, 64 },	/* IEEE80211_MODE_11A */
782 		{ 2, 5, 10, 64 },	/* IEEE80211_MODE_11B */
783 		{ 2, 4, 10, 64 },	/* IEEE80211_MODE_11G */
784 		{ 2, 5, 10, 64 },	/* IEEE80211_MODE_FH */
785 		{ 1, 3, 10, 64 },	/* IEEE80211_MODE_TURBO_A */
786 		{ 1, 3, 10, 64 },	/* IEEE80211_MODE_TURBO_G */
787 	};
788 	struct ieee80211_wme_state *wme = &ic->ic_wme;
789 	const struct wmeParams *wmep;
790 	struct wmeParams *chanp, *bssp;
791 	int i;
792 
793 	ASSERT_SERIALIZED(ic->ic_ifp->if_serializer);
794 
795 	if ((ic->ic_caps & IEEE80211_C_WME) == 0)
796 		return;
797 
798        	/* set up the channel access parameters for the physical device */
799 	for (i = 0; i < WME_NUM_AC; i++) {
800 		chanp = &wme->wme_chanParams.cap_wmeParams[i];
801 		wmep = &wme->wme_wmeChanParams.cap_wmeParams[i];
802 		chanp->wmep_aifsn = wmep->wmep_aifsn;
803 		chanp->wmep_logcwmin = wmep->wmep_logcwmin;
804 		chanp->wmep_logcwmax = wmep->wmep_logcwmax;
805 		chanp->wmep_txopLimit = wmep->wmep_txopLimit;
806 
807 		chanp = &wme->wme_bssChanParams.cap_wmeParams[i];
808 		wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[i];
809 		chanp->wmep_aifsn = wmep->wmep_aifsn;
810 		chanp->wmep_logcwmin = wmep->wmep_logcwmin;
811 		chanp->wmep_logcwmax = wmep->wmep_logcwmax;
812 		chanp->wmep_txopLimit = wmep->wmep_txopLimit;
813 	}
814 
815 	/*
816 	 * This implements agressive mode as found in certain
817 	 * vendors' AP's.  When there is significant high
818 	 * priority (VI/VO) traffic in the BSS throttle back BE
819 	 * traffic by using conservative parameters.  Otherwise
820 	 * BE uses agressive params to optimize performance of
821 	 * legacy/non-QoS traffic.
822 	 */
823         if ((ic->ic_opmode == IEEE80211_M_HOSTAP &&
824 	     (wme->wme_flags & WME_F_AGGRMODE) != 0) ||
825 	    (ic->ic_opmode == IEEE80211_M_STA &&
826 	     (ic->ic_bss->ni_flags & IEEE80211_NODE_QOS) == 0) ||
827 	    (ic->ic_flags & IEEE80211_F_WME) == 0) {
828 		chanp = &wme->wme_chanParams.cap_wmeParams[WME_AC_BE];
829 		bssp = &wme->wme_bssChanParams.cap_wmeParams[WME_AC_BE];
830 
831 		chanp->wmep_aifsn = bssp->wmep_aifsn =
832 			phyParam[ic->ic_curmode].aifsn;
833 		chanp->wmep_logcwmin = bssp->wmep_logcwmin =
834 			phyParam[ic->ic_curmode].logcwmin;
835 		chanp->wmep_logcwmax = bssp->wmep_logcwmax =
836 			phyParam[ic->ic_curmode].logcwmax;
837 		chanp->wmep_txopLimit = bssp->wmep_txopLimit =
838 			(ic->ic_flags & IEEE80211_F_BURST) ?
839 				phyParam[ic->ic_curmode].txopLimit : 0;
840 		IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME,
841 			"%s: %s [acm %u aifsn %u log2(cwmin) %u "
842 			"log2(cwmax) %u txpoLimit %u]\n", __func__
843 			, ieee80211_wme_acnames[WME_AC_BE]
844 			, chanp->wmep_acm
845 			, chanp->wmep_aifsn
846 			, chanp->wmep_logcwmin
847 			, chanp->wmep_logcwmax
848 			, chanp->wmep_txopLimit
849 		);
850 	}
851 
852 	if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
853 	    ic->ic_sta_assoc < 2 && (wme->wme_flags & WME_F_AGGRMODE) != 0) {
854         	static const uint8_t logCwMin[IEEE80211_MODE_MAX] = {
855               		3,	/* IEEE80211_MODE_AUTO */
856               		3,	/* IEEE80211_MODE_11A */
857               		4,	/* IEEE80211_MODE_11B */
858               		3,	/* IEEE80211_MODE_11G */
859               		4,	/* IEEE80211_MODE_FH */
860               		3,	/* IEEE80211_MODE_TURBO_A */
861               		3,	/* IEEE80211_MODE_TURBO_G */
862 		};
863 		chanp = &wme->wme_chanParams.cap_wmeParams[WME_AC_BE];
864 		bssp = &wme->wme_bssChanParams.cap_wmeParams[WME_AC_BE];
865 
866 		chanp->wmep_logcwmin = bssp->wmep_logcwmin =
867 			logCwMin[ic->ic_curmode];
868 		IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME,
869 			"%s: %s log2(cwmin) %u\n", __func__
870 			, ieee80211_wme_acnames[WME_AC_BE]
871 			, chanp->wmep_logcwmin
872 		);
873     	}
874 	if (ic->ic_opmode == IEEE80211_M_HOSTAP) {	/* XXX ibss? */
875 		/*
876 		 * Arrange for a beacon update and bump the parameter
877 		 * set number so associated stations load the new values.
878 		 */
879 		wme->wme_bssChanParams.cap_info =
880 			(wme->wme_bssChanParams.cap_info+1) & WME_QOSINFO_COUNT;
881 		ic->ic_flags |= IEEE80211_F_WMEUPDATE;
882 	}
883 
884 	wme->wme_update(ic);
885 
886 	IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME,
887 		"%s: WME params updated, cap_info 0x%x\n", __func__,
888 		ic->ic_opmode == IEEE80211_M_STA ?
889 			wme->wme_wmeChanParams.cap_info :
890 			wme->wme_bssChanParams.cap_info);
891 }
892 
893 void
894 ieee80211_beacon_miss(struct ieee80211com *ic)
895 {
896 
897 	if (ic->ic_flags & IEEE80211_F_SCAN) {
898 		/* XXX check ic_curchan != ic_bsschan? */
899 		return;
900 	}
901 	IEEE80211_DPRINTF(ic,
902 		IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
903 		"%s\n", "beacon miss");
904 
905 	/*
906 	 * Our handling is only meaningful for stations that are
907 	 * associated; any other conditions else will be handled
908 	 * through different means (e.g. the tx timeout on mgt frames).
909 	 */
910 	if (ic->ic_opmode != IEEE80211_M_STA || ic->ic_state != IEEE80211_S_RUN)
911 		return;
912 
913 	if (++ic->ic_bmiss_count < ic->ic_bmiss_max) {
914 		/*
915 		 * Send a directed probe req before falling back to a scan;
916 		 * if we receive a response ic_bmiss_count will be reset.
917 		 * Some cards mistakenly report beacon miss so this avoids
918 		 * the expensive scan if the ap is still there.
919 		 */
920 		ieee80211_send_probereq(ic->ic_bss, ic->ic_myaddr,
921 			ic->ic_bss->ni_bssid, ic->ic_bss->ni_bssid,
922 			ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen,
923 			ic->ic_opt_ie, ic->ic_opt_ie_len);
924 		return;
925 	}
926 	ic->ic_bmiss_count = 0;
927 	ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
928 }
929 
930 /*
931  * Software beacon miss handling.  Check if any beacons
932  * were received in the last period.  If not post a
933  * beacon miss; otherwise reset the counter.
934  */
935 static void
936 ieee80211_swbmiss(void *arg)
937 {
938 	struct ieee80211com *ic = arg;
939 	struct ifnet *ifp = ic->ic_ifp;
940 
941 	lwkt_serialize_enter(ifp->if_serializer);
942 
943 	if (ic->ic_swbmiss_count == 0) {
944 		ieee80211_beacon_miss(ic);
945 		if (ic->ic_bmiss_count == 0)	/* don't re-arm timer */
946 			goto back;
947 	} else
948 		ic->ic_swbmiss_count = 0;
949 	callout_reset(&ic->ic_swbmiss, ic->ic_swbmiss_period,
950 		ieee80211_swbmiss, ic);
951 
952 back:
953 	lwkt_serialize_exit(ifp->if_serializer);
954 }
955 
956 static void
957 sta_disconnect(void *arg, struct ieee80211_node *ni)
958 {
959 	struct ieee80211com *ic = arg;
960 
961 	if (ni->ni_associd != 0) {
962 		IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DISASSOC,
963 			IEEE80211_REASON_ASSOC_LEAVE);
964 		ieee80211_node_leave(ic, ni);
965 	} else if (ni->ni_flags & IEEE80211_NODE_AREF) {
966 		IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
967 			IEEE80211_REASON_ASSOC_LEAVE);
968 		ieee80211_node_leave(ic, ni);
969 	}
970 }
971 
972 void
973 ieee80211_reset_state(struct ieee80211com *ic,
974 		      enum ieee80211_state cur_state)
975 {
976 	struct ieee80211_node *ni;
977 
978 	IEEE80211_DPRINTF(ic, IEEE80211_MSG_STATE,
979 			  "%s reset internal state machine (%s)\n",
980 			  __func__, ieee80211_state_name[cur_state]);
981 
982 	ni = ic->ic_bss;
983 	KASSERT(ni != NULL, ("empty ic_bss\n"));
984 
985 	switch (cur_state) {
986 	case IEEE80211_S_INIT:
987 		break;
988 	case IEEE80211_S_RUN:
989 		switch (ic->ic_opmode) {
990 		case IEEE80211_M_STA:
991 			/*
992 			 * Avoid sending disassoc to self.  This could happen
993 			 * when operational mode is switched directly from
994 			 * HOSTAP/IBSS to STA.
995 			 */
996 			if (!IEEE80211_ADDR_EQ(ic->ic_myaddr, ni->ni_macaddr)) {
997 				IEEE80211_SEND_MGMT(ic, ni,
998 				    IEEE80211_FC0_SUBTYPE_DISASSOC,
999 				    IEEE80211_REASON_ASSOC_LEAVE);
1000 				ieee80211_sta_leave(ic, ni);
1001 			}
1002 			break;
1003 		case IEEE80211_M_HOSTAP:
1004 			ieee80211_iterate_nodes(&ic->ic_sta,
1005 				sta_disconnect, ic);
1006 			break;
1007 		default:
1008 			break;
1009 		}
1010 		break;
1011 	case IEEE80211_S_ASSOC:
1012 		switch (ic->ic_opmode) {
1013 		case IEEE80211_M_STA:
1014 			/*
1015 			 * Avoid sending deauth to self.
1016 			 */
1017 			if (!IEEE80211_ADDR_EQ(ic->ic_myaddr, ni->ni_macaddr)) {
1018 				IEEE80211_SEND_MGMT(ic, ni,
1019 				    IEEE80211_FC0_SUBTYPE_DEAUTH,
1020 				    IEEE80211_REASON_AUTH_LEAVE);
1021 			}
1022 			break;
1023 		default:
1024 			break;
1025 		}
1026 		break;
1027 	case IEEE80211_S_SCAN:
1028 		ieee80211_cancel_scan(ic);
1029 		/* FALL THROUGH */
1030 	case IEEE80211_S_AUTH:
1031 		break;
1032 	}
1033 
1034 	ieee80211_drain_mgtq(&ic->ic_mgtq);
1035 	ieee80211_reset_bss(ic);
1036 }
1037 
1038 static int
1039 ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1040 {
1041 	struct ifnet *ifp = ic->ic_ifp;
1042 	struct ieee80211_node *ni;
1043 	enum ieee80211_state ostate;
1044 
1045 	ostate = ic->ic_state;
1046 	IEEE80211_DPRINTF(ic, IEEE80211_MSG_STATE, "%s: %s -> %s\n", __func__,
1047 		ieee80211_state_name[ostate], ieee80211_state_name[nstate]);
1048 	ic->ic_state = nstate;			/* state transition */
1049 	ni = ic->ic_bss;			/* NB: no reference held */
1050 	if (ic->ic_flags_ext & IEEE80211_FEXT_SWBMISS)
1051 		callout_stop(&ic->ic_swbmiss);
1052 	switch (nstate) {
1053 	case IEEE80211_S_INIT:
1054 		ieee80211_reset_state(ic, ostate);
1055 		ic->ic_mgt_timer = 0;
1056 
1057 		if (ic->ic_auth->ia_detach != NULL)
1058 			ic->ic_auth->ia_detach(ic);
1059 		break;
1060 
1061 	case IEEE80211_S_SCAN:
1062 		switch (ostate) {
1063 		case IEEE80211_S_INIT:
1064 			if ((ic->ic_opmode == IEEE80211_M_HOSTAP ||
1065 			     ic->ic_opmode == IEEE80211_M_IBSS ||
1066 			     ic->ic_opmode == IEEE80211_M_AHDEMO) &&
1067 			    ic->ic_des_chan != IEEE80211_CHAN_ANYC) {
1068 				/*
1069 				 * AP operation and we already have a channel;
1070 				 * bypass the scan and startup immediately.
1071 				 */
1072 				ieee80211_create_ibss(ic, ic->ic_des_chan);
1073 			} else {
1074 				ieee80211_begin_scan(ic, arg);
1075 			}
1076 			break;
1077 		case IEEE80211_S_SCAN:
1078 			/*
1079 			 * Scan next. If doing an active scan probe
1080 			 * for the requested ap (if any).
1081 			 */
1082 			if (ic->ic_flags & IEEE80211_F_ASCAN)
1083 				ieee80211_probe_curchan(ic, 0);
1084 			break;
1085 		case IEEE80211_S_RUN:
1086 			/* beacon miss */
1087 			IEEE80211_DPRINTF(ic, IEEE80211_MSG_STATE,
1088 				"no recent beacons from %6D; rescanning\n",
1089 				ic->ic_bss->ni_bssid, ":");
1090 			ieee80211_sta_leave(ic, ni);
1091 			ic->ic_flags &= ~IEEE80211_F_SIBSS;	/* XXX */
1092 			/* FALLTHRU */
1093 		case IEEE80211_S_AUTH:
1094 		case IEEE80211_S_ASSOC:
1095 			/* timeout restart scan */
1096 			ni = ieee80211_find_node(&ic->ic_scan,
1097 				ic->ic_bss->ni_macaddr);
1098 			if (ni != NULL) {
1099 				ni->ni_fails++;
1100 				ieee80211_unref_node(&ni);
1101 			}
1102 			if (ic->ic_roaming == IEEE80211_ROAMING_AUTO)
1103 				ieee80211_begin_scan(ic, arg);
1104 			break;
1105 		}
1106 		break;
1107 	case IEEE80211_S_AUTH:
1108 		switch (ostate) {
1109 		case IEEE80211_S_INIT:
1110 		case IEEE80211_S_SCAN:
1111 			IEEE80211_SEND_MGMT(ic, ni,
1112 			    IEEE80211_FC0_SUBTYPE_AUTH, 1);
1113 			break;
1114 		case IEEE80211_S_AUTH:
1115 		case IEEE80211_S_ASSOC:
1116 			switch (arg) {
1117 			case IEEE80211_FC0_SUBTYPE_AUTH:
1118 				/* ??? */
1119 				IEEE80211_SEND_MGMT(ic, ni,
1120 				    IEEE80211_FC0_SUBTYPE_AUTH, 2);
1121 				break;
1122 			case IEEE80211_FC0_SUBTYPE_DEAUTH:
1123 				/* ignore and retry scan on timeout */
1124 				break;
1125 			}
1126 			break;
1127 		case IEEE80211_S_RUN:
1128 			switch (arg) {
1129 			case IEEE80211_FC0_SUBTYPE_AUTH:
1130 				IEEE80211_SEND_MGMT(ic, ni,
1131 				    IEEE80211_FC0_SUBTYPE_AUTH, 2);
1132 				ic->ic_state = ostate;	/* stay RUN */
1133 				break;
1134 			case IEEE80211_FC0_SUBTYPE_DEAUTH:
1135 				ieee80211_sta_leave(ic, ni);
1136 				if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {
1137 					/* try to reauth */
1138 					IEEE80211_SEND_MGMT(ic, ni,
1139 					    IEEE80211_FC0_SUBTYPE_AUTH, 1);
1140 				}
1141 				break;
1142 			}
1143 			break;
1144 		}
1145 		break;
1146 	case IEEE80211_S_ASSOC:
1147 		switch (ostate) {
1148 		case IEEE80211_S_INIT:
1149 		case IEEE80211_S_SCAN:
1150 		case IEEE80211_S_ASSOC:
1151 			IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
1152 				"%s: invalid transition\n", __func__);
1153 			break;
1154 		case IEEE80211_S_AUTH:
1155 			IEEE80211_SEND_MGMT(ic, ni,
1156 			    IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0);
1157 			break;
1158 		case IEEE80211_S_RUN:
1159 			ieee80211_sta_leave(ic, ni);
1160 			if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {
1161 				IEEE80211_SEND_MGMT(ic, ni,
1162 				    IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 1);
1163 			}
1164 			break;
1165 		}
1166 		break;
1167 	case IEEE80211_S_RUN:
1168 		if (ic->ic_flags & IEEE80211_F_WPA) {
1169 			/* XXX validate prerequisites */
1170 		}
1171 		switch (ostate) {
1172 		case IEEE80211_S_INIT:
1173 			if (ic->ic_opmode == IEEE80211_M_MONITOR)
1174 				break;
1175 			/* fall thru... */
1176 		case IEEE80211_S_AUTH:
1177 			IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
1178 				"%s: invalid transition\n", __func__);
1179 			/* fall thru... */
1180 		case IEEE80211_S_RUN:
1181 			break;
1182 		case IEEE80211_S_SCAN:		/* adhoc/hostap mode */
1183 		case IEEE80211_S_ASSOC:		/* infra mode */
1184 			KASSERT(ni->ni_txrate < ni->ni_rates.rs_nrates,
1185 				("%s: bogus xmit rate %u setup\n", __func__,
1186 					ni->ni_txrate));
1187 #ifdef IEEE80211_DEBUG
1188 			if (ieee80211_msg_debug(ic)) {
1189 				if (ic->ic_opmode == IEEE80211_M_STA)
1190 					if_printf(ifp, "associated ");
1191 				else
1192 					if_printf(ifp, "synchronized ");
1193 				kprintf("with %6D ssid ", ni->ni_bssid, ":");
1194 				ieee80211_print_essid(ic->ic_bss->ni_essid,
1195 				    ni->ni_esslen);
1196 				kprintf(" channel %d start %uMb\n",
1197 					ieee80211_chan2ieee(ic, ic->ic_curchan),
1198 					IEEE80211_RATE2MBS(ni->ni_rates.rs_rates[ni->ni_txrate]));
1199 			}
1200 #endif
1201 			ic->ic_mgt_timer = 0;
1202 			if (ic->ic_opmode == IEEE80211_M_STA)
1203 				ieee80211_notify_node_join(ic, ni,
1204 					arg == IEEE80211_FC0_SUBTYPE_ASSOC_RESP);
1205 			ifp->if_start(ifp);	/* XXX not authorized yet */
1206 			break;
1207 		}
1208 		if (ostate != IEEE80211_S_RUN &&
1209 		    ic->ic_opmode == IEEE80211_M_STA &&
1210 		    (ic->ic_flags_ext & IEEE80211_FEXT_SWBMISS)) {
1211 			/*
1212 			 * Start s/w beacon miss timer for devices w/o
1213 			 * hardware support.  We fudge a bit here since
1214 			 * we're doing this in software.
1215 			 */
1216 			ic->ic_swbmiss_period = IEEE80211_TU_TO_TICKS(
1217 				2 * ic->ic_bmissthreshold * ni->ni_intval);
1218 			ic->ic_swbmiss_count = 0;
1219 			callout_reset(&ic->ic_swbmiss, ic->ic_swbmiss_period,
1220 				ieee80211_swbmiss, ic);
1221 		}
1222 		/*
1223 		 * Start/stop the authenticator when operating as an
1224 		 * AP.  We delay until here to allow configuration to
1225 		 * happen out of order.
1226 		 */
1227 		if (ic->ic_opmode == IEEE80211_M_HOSTAP && /* XXX IBSS/AHDEMO */
1228 		    ic->ic_auth->ia_attach != NULL) {
1229 			/* XXX check failure */
1230 			ic->ic_auth->ia_attach(ic);
1231 		} else if (ic->ic_auth->ia_detach != NULL) {
1232 			ic->ic_auth->ia_detach(ic);
1233 		}
1234 		/*
1235 		 * When 802.1x is not in use mark the port authorized
1236 		 * at this point so traffic can flow.
1237 		 */
1238 		if (ni->ni_authmode != IEEE80211_AUTH_8021X)
1239 			ieee80211_node_authorize(ni);
1240 		/*
1241 		 * Enable inactivity processing.
1242 		 * XXX
1243 		 */
1244 		ic->ic_scan.nt_inact_timer = IEEE80211_INACT_WAIT;
1245 		ic->ic_sta.nt_inact_timer = IEEE80211_INACT_WAIT;
1246 		break;
1247 	}
1248 	return 0;
1249 }
1250