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