xref: /openbsd-src/sys/net80211/ieee80211.c (revision 7350f337b9e3eb4461d99580e625c7ef148d107c)
1 /*	$OpenBSD: ieee80211.c,v 1.76 2019/06/10 16:33:02 stsp Exp $	*/
2 /*	$NetBSD: ieee80211.c,v 1.19 2004/06/06 05:45:29 dyoung Exp $	*/
3 
4 /*-
5  * Copyright (c) 2001 Atsushi Onoe
6  * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * IEEE 802.11 generic handler
34  */
35 
36 #include "bpfilter.h"
37 
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/mbuf.h>
41 #include <sys/kernel.h>
42 #include <sys/socket.h>
43 #include <sys/sockio.h>
44 #include <sys/endian.h>
45 #include <sys/errno.h>
46 #include <sys/sysctl.h>
47 
48 #include <net/if.h>
49 #include <net/if_dl.h>
50 #include <net/if_media.h>
51 
52 #if NBPFILTER > 0
53 #include <net/bpf.h>
54 #endif
55 
56 #include <netinet/in.h>
57 #include <netinet/if_ether.h>
58 
59 #include <net80211/ieee80211_var.h>
60 #include <net80211/ieee80211_priv.h>
61 
62 #ifdef IEEE80211_DEBUG
63 int	ieee80211_debug = 0;
64 #endif
65 
66 int ieee80211_cache_size = IEEE80211_CACHE_SIZE;
67 
68 void ieee80211_setbasicrates(struct ieee80211com *);
69 int ieee80211_findrate(struct ieee80211com *, enum ieee80211_phymode, int);
70 
71 void
72 ieee80211_begin_bgscan(struct ifnet *ifp)
73 {
74 	struct ieee80211com *ic = (void *)ifp;
75 
76 	if ((ic->ic_flags & IEEE80211_F_BGSCAN) ||
77 	    ic->ic_state != IEEE80211_S_RUN)
78 		return;
79 
80 	if (ic->ic_bgscan_start != NULL && ic->ic_bgscan_start(ic) == 0) {
81 		/*
82 		 * Free the nodes table to ensure we get an up-to-date view
83 		 * of APs around us. In particular, we need to kick out the
84 		 * AP we are associated to. Otherwise, our current AP might
85 		 * stay cached if it is turned off while we are scanning, and
86 		 * we could end up picking a now non-existent AP over and over.
87 		 */
88 		ieee80211_free_allnodes(ic, 0 /* keep ic->ic_bss */);
89 
90 		ic->ic_flags |= IEEE80211_F_BGSCAN;
91 		if (ifp->if_flags & IFF_DEBUG)
92 			printf("%s: begin background scan\n", ifp->if_xname);
93 
94 		/* Driver calls ieee80211_end_scan() when done. */
95 	}
96 }
97 
98 void
99 ieee80211_bgscan_timeout(void *arg)
100 {
101 	struct ifnet *ifp = arg;
102 
103 	ieee80211_begin_bgscan(ifp);
104 }
105 
106 void
107 ieee80211_channel_init(struct ifnet *ifp)
108 {
109 	struct ieee80211com *ic = (void *)ifp;
110 	struct ieee80211_channel *c;
111 	int i;
112 
113 	/*
114 	 * Fill in 802.11 available channel set, mark
115 	 * all available channels as active, and pick
116 	 * a default channel if not already specified.
117 	 */
118 	memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail));
119 	ic->ic_modecaps |= 1<<IEEE80211_MODE_AUTO;
120 	for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
121 		c = &ic->ic_channels[i];
122 		if (c->ic_flags) {
123 			/*
124 			 * Verify driver passed us valid data.
125 			 */
126 			if (i != ieee80211_chan2ieee(ic, c)) {
127 				printf("%s: bad channel ignored; "
128 					"freq %u flags %x number %u\n",
129 					ifp->if_xname, c->ic_freq, c->ic_flags,
130 					i);
131 				c->ic_flags = 0;	/* NB: remove */
132 				continue;
133 			}
134 			setbit(ic->ic_chan_avail, i);
135 			/*
136 			 * Identify mode capabilities.
137 			 */
138 			if (IEEE80211_IS_CHAN_A(c))
139 				ic->ic_modecaps |= 1<<IEEE80211_MODE_11A;
140 			if (IEEE80211_IS_CHAN_B(c))
141 				ic->ic_modecaps |= 1<<IEEE80211_MODE_11B;
142 			if (IEEE80211_IS_CHAN_PUREG(c))
143 				ic->ic_modecaps |= 1<<IEEE80211_MODE_11G;
144 			if (IEEE80211_IS_CHAN_N(c))
145 				ic->ic_modecaps |= 1<<IEEE80211_MODE_11N;
146 			if (IEEE80211_IS_CHAN_AC(c))
147 				ic->ic_modecaps |= 1<<IEEE80211_MODE_11AC;
148 		}
149 	}
150 	/* validate ic->ic_curmode */
151 	if ((ic->ic_modecaps & (1<<ic->ic_curmode)) == 0)
152 		ic->ic_curmode = IEEE80211_MODE_AUTO;
153 	ic->ic_des_chan = IEEE80211_CHAN_ANYC;	/* any channel is ok */
154 }
155 
156 void
157 ieee80211_ifattach(struct ifnet *ifp)
158 {
159 	struct ieee80211com *ic = (void *)ifp;
160 
161 	memcpy(((struct arpcom *)ifp)->ac_enaddr, ic->ic_myaddr,
162 		ETHER_ADDR_LEN);
163 	ether_ifattach(ifp);
164 
165 	ifp->if_output = ieee80211_output;
166 
167 #if NBPFILTER > 0
168 	bpfattach(&ic->ic_rawbpf, ifp, DLT_IEEE802_11,
169 	    sizeof(struct ieee80211_frame_addr4));
170 #endif
171 	ieee80211_crypto_attach(ifp);
172 
173 	ieee80211_channel_init(ifp);
174 
175 	/* IEEE 802.11 defines a MTU >= 2290 */
176 	ifp->if_capabilities |= IFCAP_VLAN_MTU;
177 
178 	ieee80211_setbasicrates(ic);
179 	(void)ieee80211_setmode(ic, ic->ic_curmode);
180 
181 	if (ic->ic_lintval == 0)
182 		ic->ic_lintval = 100;		/* default sleep */
183 	ic->ic_bmissthres = 7;	/* default 7 beacons */
184 	ic->ic_dtim_period = 1;	/* all TIMs are DTIMs */
185 
186 	ieee80211_node_attach(ifp);
187 	ieee80211_proto_attach(ifp);
188 
189 	if_addgroup(ifp, "wlan");
190 	ifp->if_priority = IF_WIRELESS_DEFAULT_PRIORITY;
191 
192 	ieee80211_set_link_state(ic, LINK_STATE_DOWN);
193 
194 	timeout_set(&ic->ic_bgscan_timeout, ieee80211_bgscan_timeout, ifp);
195 }
196 
197 void
198 ieee80211_ifdetach(struct ifnet *ifp)
199 {
200 	struct ieee80211com *ic = (void *)ifp;
201 
202 	timeout_del(&ic->ic_bgscan_timeout);
203 	ieee80211_proto_detach(ifp);
204 	ieee80211_crypto_detach(ifp);
205 	ieee80211_node_detach(ifp);
206 	ifmedia_delete_instance(&ic->ic_media, IFM_INST_ANY);
207 	ether_ifdetach(ifp);
208 }
209 
210 /*
211  * Convert MHz frequency to IEEE channel number.
212  */
213 u_int
214 ieee80211_mhz2ieee(u_int freq, u_int flags)
215 {
216 	if (flags & IEEE80211_CHAN_2GHZ) {	/* 2GHz band */
217 		if (freq == 2484)
218 			return 14;
219 		if (freq < 2484)
220 			return (freq - 2407) / 5;
221 		else
222 			return 15 + ((freq - 2512) / 20);
223 	} else if (flags & IEEE80211_CHAN_5GHZ) {	/* 5GHz band */
224 		return (freq - 5000) / 5;
225 	} else {				/* either, guess */
226 		if (freq == 2484)
227 			return 14;
228 		if (freq < 2484)
229 			return (freq - 2407) / 5;
230 		if (freq < 5000)
231 			return 15 + ((freq - 2512) / 20);
232 		return (freq - 5000) / 5;
233 	}
234 }
235 
236 /*
237  * Convert channel to IEEE channel number.
238  */
239 u_int
240 ieee80211_chan2ieee(struct ieee80211com *ic, const struct ieee80211_channel *c)
241 {
242 	struct ifnet *ifp = &ic->ic_if;
243 	if (ic->ic_channels <= c && c <= &ic->ic_channels[IEEE80211_CHAN_MAX])
244 		return c - ic->ic_channels;
245 	else if (c == IEEE80211_CHAN_ANYC)
246 		return IEEE80211_CHAN_ANY;
247 
248 	panic("%s: bogus channel pointer", ifp->if_xname);
249 }
250 
251 /*
252  * Convert IEEE channel number to MHz frequency.
253  */
254 u_int
255 ieee80211_ieee2mhz(u_int chan, u_int flags)
256 {
257 	if (flags & IEEE80211_CHAN_2GHZ) {	/* 2GHz band */
258 		if (chan == 14)
259 			return 2484;
260 		if (chan < 14)
261 			return 2407 + chan*5;
262 		else
263 			return 2512 + ((chan-15)*20);
264 	} else if (flags & IEEE80211_CHAN_5GHZ) {/* 5GHz band */
265 		return 5000 + (chan*5);
266 	} else {				/* either, guess */
267 		if (chan == 14)
268 			return 2484;
269 		if (chan < 14)			/* 0-13 */
270 			return 2407 + chan*5;
271 		if (chan < 27)			/* 15-26 */
272 			return 2512 + ((chan-15)*20);
273 		return 5000 + (chan*5);
274 	}
275 }
276 
277 /*
278  * Setup the media data structures according to the channel and
279  * rate tables.  This must be called by the driver after
280  * ieee80211_attach and before most anything else.
281  */
282 void
283 ieee80211_media_init(struct ifnet *ifp,
284 	ifm_change_cb_t media_change, ifm_stat_cb_t media_stat)
285 {
286 #define	ADD(_ic, _s, _o) \
287 	ifmedia_add(&(_ic)->ic_media, \
288 		IFM_MAKEWORD(IFM_IEEE80211, (_s), (_o), 0), 0, NULL)
289 	struct ieee80211com *ic = (void *)ifp;
290 	struct ifmediareq imr;
291 	int i, j, mode, rate, maxrate, r;
292 	uint64_t mword, mopt;
293 	const struct ieee80211_rateset *rs;
294 	struct ieee80211_rateset allrates;
295 
296 	/*
297 	 * Do late attach work that must wait for any subclass
298 	 * (i.e. driver) work such as overriding methods.
299 	 */
300 	ieee80211_node_lateattach(ifp);
301 
302 	/*
303 	 * Fill in media characteristics.
304 	 */
305 	ifmedia_init(&ic->ic_media, 0, media_change, media_stat);
306 	maxrate = 0;
307 	memset(&allrates, 0, sizeof(allrates));
308 	for (mode = IEEE80211_MODE_AUTO; mode <= IEEE80211_MODE_11G; mode++) {
309 		static const uint64_t mopts[] = {
310 			IFM_AUTO,
311 			IFM_IEEE80211_11A,
312 			IFM_IEEE80211_11B,
313 			IFM_IEEE80211_11G,
314 		};
315 		if ((ic->ic_modecaps & (1<<mode)) == 0)
316 			continue;
317 		mopt = mopts[mode];
318 		ADD(ic, IFM_AUTO, mopt);	/* e.g. 11a auto */
319 #ifndef IEEE80211_STA_ONLY
320 		if (ic->ic_caps & IEEE80211_C_IBSS)
321 			ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_IBSS);
322 		if (ic->ic_caps & IEEE80211_C_HOSTAP)
323 			ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_HOSTAP);
324 		if (ic->ic_caps & IEEE80211_C_AHDEMO)
325 			ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_ADHOC);
326 #endif
327 		if (ic->ic_caps & IEEE80211_C_MONITOR)
328 			ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_MONITOR);
329 		if (mode == IEEE80211_MODE_AUTO)
330 			continue;
331 		rs = &ic->ic_sup_rates[mode];
332 		for (i = 0; i < rs->rs_nrates; i++) {
333 			rate = rs->rs_rates[i];
334 			mword = ieee80211_rate2media(ic, rate, mode);
335 			if (mword == 0)
336 				continue;
337 			ADD(ic, mword, mopt);
338 #ifndef IEEE80211_STA_ONLY
339 			if (ic->ic_caps & IEEE80211_C_IBSS)
340 				ADD(ic, mword, mopt | IFM_IEEE80211_IBSS);
341 			if (ic->ic_caps & IEEE80211_C_HOSTAP)
342 				ADD(ic, mword, mopt | IFM_IEEE80211_HOSTAP);
343 			if (ic->ic_caps & IEEE80211_C_AHDEMO)
344 				ADD(ic, mword, mopt | IFM_IEEE80211_ADHOC);
345 #endif
346 			if (ic->ic_caps & IEEE80211_C_MONITOR)
347 				ADD(ic, mword, mopt | IFM_IEEE80211_MONITOR);
348 			/*
349 			 * Add rate to the collection of all rates.
350 			 */
351 			r = rate & IEEE80211_RATE_VAL;
352 			for (j = 0; j < allrates.rs_nrates; j++)
353 				if (allrates.rs_rates[j] == r)
354 					break;
355 			if (j == allrates.rs_nrates) {
356 				/* unique, add to the set */
357 				allrates.rs_rates[j] = r;
358 				allrates.rs_nrates++;
359 			}
360 			rate = (rate & IEEE80211_RATE_VAL) / 2;
361 			if (rate > maxrate)
362 				maxrate = rate;
363 		}
364 	}
365 	for (i = 0; i < allrates.rs_nrates; i++) {
366 		mword = ieee80211_rate2media(ic, allrates.rs_rates[i],
367 				IEEE80211_MODE_AUTO);
368 		if (mword == 0)
369 			continue;
370 		mword = IFM_SUBTYPE(mword);	/* remove media options */
371 		ADD(ic, mword, 0);
372 #ifndef IEEE80211_STA_ONLY
373 		if (ic->ic_caps & IEEE80211_C_IBSS)
374 			ADD(ic, mword, IFM_IEEE80211_IBSS);
375 		if (ic->ic_caps & IEEE80211_C_HOSTAP)
376 			ADD(ic, mword, IFM_IEEE80211_HOSTAP);
377 		if (ic->ic_caps & IEEE80211_C_AHDEMO)
378 			ADD(ic, mword, IFM_IEEE80211_ADHOC);
379 #endif
380 		if (ic->ic_caps & IEEE80211_C_MONITOR)
381 			ADD(ic, mword, IFM_IEEE80211_MONITOR);
382 	}
383 
384 	if (ic->ic_modecaps & (1 << IEEE80211_MODE_11N)) {
385 		mopt = IFM_IEEE80211_11N;
386 		ADD(ic, IFM_AUTO, mopt);
387 #ifndef IEEE80211_STA_ONLY
388 		if (ic->ic_caps & IEEE80211_C_IBSS)
389 			ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_IBSS);
390 		if (ic->ic_caps & IEEE80211_C_HOSTAP)
391 			ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_HOSTAP);
392 #endif
393 		if (ic->ic_caps & IEEE80211_C_MONITOR)
394 			ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_MONITOR);
395 		for (i = 0; i < IEEE80211_HT_NUM_MCS; i++) {
396 			if (!isset(ic->ic_sup_mcs, i))
397 				continue;
398 			ADD(ic, IFM_IEEE80211_HT_MCS0 + i, mopt);
399 #ifndef IEEE80211_STA_ONLY
400 			if (ic->ic_caps & IEEE80211_C_IBSS)
401 				ADD(ic, IFM_IEEE80211_HT_MCS0 + i,
402 				     mopt | IFM_IEEE80211_IBSS);
403 			if (ic->ic_caps & IEEE80211_C_HOSTAP)
404 				ADD(ic, IFM_IEEE80211_HT_MCS0 + i,
405 				    mopt | IFM_IEEE80211_HOSTAP);
406 #endif
407 			if (ic->ic_caps & IEEE80211_C_MONITOR)
408 				ADD(ic, IFM_IEEE80211_HT_MCS0 + i,
409 				    mopt | IFM_IEEE80211_MONITOR);
410 		}
411 		ic->ic_flags |= IEEE80211_F_HTON; /* enable 11n by default */
412 	}
413 
414 	if (ic->ic_modecaps & (1 << IEEE80211_MODE_11AC)) {
415 		mopt = IFM_IEEE80211_11AC;
416 		ADD(ic, IFM_AUTO, mopt);
417 #ifndef IEEE80211_STA_ONLY
418 		if (ic->ic_caps & IEEE80211_C_IBSS)
419 			ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_IBSS);
420 		if (ic->ic_caps & IEEE80211_C_HOSTAP)
421 			ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_HOSTAP);
422 #endif
423 		if (ic->ic_caps & IEEE80211_C_MONITOR)
424 			ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_MONITOR);
425 		for (i = 0; i < IEEE80211_VHT_NUM_MCS; i++) {
426 #if 0
427 			/* TODO: Obtain VHT MCS information from VHT CAP IE. */
428 			if (!vht_mcs_supported)
429 				continue;
430 #endif
431 			ADD(ic, IFM_IEEE80211_VHT_MCS0 + i, mopt);
432 #ifndef IEEE80211_STA_ONLY
433 			if (ic->ic_caps & IEEE80211_C_IBSS)
434 				ADD(ic, IFM_IEEE80211_VHT_MCS0 + i,
435 				     mopt | IFM_IEEE80211_IBSS);
436 			if (ic->ic_caps & IEEE80211_C_HOSTAP)
437 				ADD(ic, IFM_IEEE80211_VHT_MCS0 + i,
438 				    mopt | IFM_IEEE80211_HOSTAP);
439 #endif
440 			if (ic->ic_caps & IEEE80211_C_MONITOR)
441 				ADD(ic, IFM_IEEE80211_VHT_MCS0 + i,
442 				    mopt | IFM_IEEE80211_MONITOR);
443 		}
444 #if 0
445 		ic->ic_flags |= IEEE80211_F_VHTON; /* enable 11ac by default */
446 #endif
447 	}
448 
449 	ieee80211_media_status(ifp, &imr);
450 	ifmedia_set(&ic->ic_media, imr.ifm_active);
451 
452 	if (maxrate)
453 		ifp->if_baudrate = IF_Mbps(maxrate);
454 
455 #undef ADD
456 }
457 
458 int
459 ieee80211_findrate(struct ieee80211com *ic, enum ieee80211_phymode mode,
460     int rate)
461 {
462 #define	IEEERATE(_ic,_m,_i) \
463 	((_ic)->ic_sup_rates[_m].rs_rates[_i] & IEEE80211_RATE_VAL)
464 	int i, nrates = ic->ic_sup_rates[mode].rs_nrates;
465 	for (i = 0; i < nrates; i++)
466 		if (IEEERATE(ic, mode, i) == rate)
467 			return i;
468 	return -1;
469 #undef IEEERATE
470 }
471 
472 /*
473  * Handle a media change request.
474  */
475 int
476 ieee80211_media_change(struct ifnet *ifp)
477 {
478 	struct ieee80211com *ic = (void *)ifp;
479 	struct ifmedia_entry *ime;
480 	enum ieee80211_opmode newopmode;
481 	enum ieee80211_phymode newphymode;
482 	int i, j, newrate, error = 0;
483 
484 	ime = ic->ic_media.ifm_cur;
485 	/*
486 	 * First, identify the phy mode.
487 	 */
488 	switch (IFM_MODE(ime->ifm_media)) {
489 	case IFM_IEEE80211_11A:
490 		newphymode = IEEE80211_MODE_11A;
491 		break;
492 	case IFM_IEEE80211_11B:
493 		newphymode = IEEE80211_MODE_11B;
494 		break;
495 	case IFM_IEEE80211_11G:
496 		newphymode = IEEE80211_MODE_11G;
497 		break;
498 	case IFM_IEEE80211_11N:
499 		newphymode = IEEE80211_MODE_11N;
500 		break;
501 	case IFM_IEEE80211_11AC:
502 		newphymode = IEEE80211_MODE_11AC;
503 		break;
504 	case IFM_AUTO:
505 		newphymode = IEEE80211_MODE_AUTO;
506 		break;
507 	default:
508 		return EINVAL;
509 	}
510 
511 	/*
512 	 * Validate requested mode is available.
513 	 */
514 	if ((ic->ic_modecaps & (1<<newphymode)) == 0)
515 		return EINVAL;
516 
517 	/*
518 	 * Next, the fixed/variable rate.
519 	 */
520 	i = -1;
521 	if (IFM_SUBTYPE(ime->ifm_media) >= IFM_IEEE80211_VHT_MCS0 &&
522 	    IFM_SUBTYPE(ime->ifm_media) <= IFM_IEEE80211_VHT_MCS9) {
523 		if ((ic->ic_modecaps & (1 << IEEE80211_MODE_11AC)) == 0)
524 			return EINVAL;
525 		if (newphymode != IEEE80211_MODE_AUTO &&
526 		    newphymode != IEEE80211_MODE_11AC)
527 			return EINVAL;
528 		i = ieee80211_media2mcs(ime->ifm_media);
529 		/* TODO: Obtain VHT MCS information from VHT CAP IE. */
530 		if (i == -1 /* || !vht_mcs_supported */)
531 			return EINVAL;
532 	} else if (IFM_SUBTYPE(ime->ifm_media) >= IFM_IEEE80211_HT_MCS0 &&
533 	    IFM_SUBTYPE(ime->ifm_media) <= IFM_IEEE80211_HT_MCS76) {
534 		if ((ic->ic_modecaps & (1 << IEEE80211_MODE_11N)) == 0)
535 			return EINVAL;
536 		if (newphymode != IEEE80211_MODE_AUTO &&
537 		    newphymode != IEEE80211_MODE_11N)
538 			return EINVAL;
539 		i = ieee80211_media2mcs(ime->ifm_media);
540 		if (i == -1 || isclr(ic->ic_sup_mcs, i))
541 			return EINVAL;
542 	} else if (IFM_SUBTYPE(ime->ifm_media) != IFM_AUTO) {
543 		/*
544 		 * Convert media subtype to rate.
545 		 */
546 		newrate = ieee80211_media2rate(ime->ifm_media);
547 		if (newrate == 0)
548 			return EINVAL;
549 		/*
550 		 * Check the rate table for the specified/current phy.
551 		 */
552 		if (newphymode == IEEE80211_MODE_AUTO) {
553 			/*
554 			 * In autoselect mode search for the rate.
555 			 */
556 			for (j = IEEE80211_MODE_11A;
557 			     j < IEEE80211_MODE_MAX; j++) {
558 				if ((ic->ic_modecaps & (1<<j)) == 0)
559 					continue;
560 				i = ieee80211_findrate(ic, j, newrate);
561 				if (i != -1) {
562 					/* lock mode too */
563 					newphymode = j;
564 					break;
565 				}
566 			}
567 		} else {
568 			i = ieee80211_findrate(ic, newphymode, newrate);
569 		}
570 		if (i == -1)			/* mode/rate mismatch */
571 			return EINVAL;
572 	}
573 	/* NB: defer rate setting to later */
574 
575 	/*
576 	 * Deduce new operating mode but don't install it just yet.
577 	 */
578 #ifndef IEEE80211_STA_ONLY
579 	if (ime->ifm_media & IFM_IEEE80211_ADHOC)
580 		newopmode = IEEE80211_M_AHDEMO;
581 	else if (ime->ifm_media & IFM_IEEE80211_HOSTAP)
582 		newopmode = IEEE80211_M_HOSTAP;
583 	else if (ime->ifm_media & IFM_IEEE80211_IBSS)
584 		newopmode = IEEE80211_M_IBSS;
585 	else
586 #endif
587 	if (ime->ifm_media & IFM_IEEE80211_MONITOR)
588 		newopmode = IEEE80211_M_MONITOR;
589 	else
590 		newopmode = IEEE80211_M_STA;
591 
592 #ifndef IEEE80211_STA_ONLY
593 	/*
594 	 * Autoselect doesn't make sense when operating as an AP.
595 	 * If no phy mode has been selected, pick one and lock it
596 	 * down so rate tables can be used in forming beacon frames
597 	 * and the like.
598 	 */
599 	if (newopmode == IEEE80211_M_HOSTAP &&
600 	    newphymode == IEEE80211_MODE_AUTO) {
601 		if (ic->ic_modecaps & (1 << IEEE80211_MODE_11AC))
602 			newphymode = IEEE80211_MODE_11AC;
603 		else if (ic->ic_modecaps & (1 << IEEE80211_MODE_11N))
604 			newphymode = IEEE80211_MODE_11N;
605 		else if (ic->ic_modecaps & (1 << IEEE80211_MODE_11A))
606 			newphymode = IEEE80211_MODE_11A;
607 		else if (ic->ic_modecaps & (1 << IEEE80211_MODE_11G))
608 			newphymode = IEEE80211_MODE_11G;
609 		else
610 			newphymode = IEEE80211_MODE_11B;
611 	}
612 #endif
613 
614 	/*
615 	 * Handle phy mode change.
616 	 */
617 	if (ic->ic_curmode != newphymode) {		/* change phy mode */
618 		error = ieee80211_setmode(ic, newphymode);
619 		if (error != 0)
620 			return error;
621 		error = ENETRESET;
622 	}
623 
624 	/*
625 	 * Committed to changes, install the MCS/rate setting.
626 	 */
627 	ic->ic_flags &= ~(IEEE80211_F_HTON | IEEE80211_F_VHTON);
628 	if ((ic->ic_modecaps & (1 << IEEE80211_MODE_11AC)) &&
629 	    (newphymode == IEEE80211_MODE_AUTO ||
630 	    newphymode == IEEE80211_MODE_11AC))
631 		ic->ic_flags |= IEEE80211_F_VHTON;
632 	else if ((ic->ic_modecaps & (1 << IEEE80211_MODE_11N)) &&
633 	    (newphymode == IEEE80211_MODE_AUTO ||
634 	    newphymode == IEEE80211_MODE_11N))
635 		ic->ic_flags |= IEEE80211_F_HTON;
636 	if ((ic->ic_flags & (IEEE80211_F_HTON | IEEE80211_F_VHTON)) == 0) {
637 		ic->ic_fixed_mcs = -1;
638 	    	if (ic->ic_fixed_rate != i) {
639 			ic->ic_fixed_rate = i;		/* set fixed tx rate */
640 			error = ENETRESET;
641 		}
642 	} else {
643 		ic->ic_fixed_rate = -1;
644 		if (ic->ic_fixed_mcs != i) {
645 			ic->ic_fixed_mcs = i;		/* set fixed mcs */
646 			error = ENETRESET;
647 		}
648 	}
649 
650 	/*
651 	 * Handle operating mode change.
652 	 */
653 	if (ic->ic_opmode != newopmode) {
654 		ic->ic_opmode = newopmode;
655 #ifndef IEEE80211_STA_ONLY
656 		switch (newopmode) {
657 		case IEEE80211_M_AHDEMO:
658 		case IEEE80211_M_HOSTAP:
659 		case IEEE80211_M_STA:
660 		case IEEE80211_M_MONITOR:
661 			ic->ic_flags &= ~IEEE80211_F_IBSSON;
662 			break;
663 		case IEEE80211_M_IBSS:
664 			ic->ic_flags |= IEEE80211_F_IBSSON;
665 			break;
666 		}
667 #endif
668 		/*
669 		 * Yech, slot time may change depending on the
670 		 * operating mode so reset it to be sure everything
671 		 * is setup appropriately.
672 		 */
673 		ieee80211_reset_erp(ic);
674 		error = ENETRESET;
675 	}
676 #ifdef notdef
677 	if (error == 0)
678 		ifp->if_baudrate = ifmedia_baudrate(ime->ifm_media);
679 #endif
680 	return error;
681 }
682 
683 void
684 ieee80211_media_status(struct ifnet *ifp, struct ifmediareq *imr)
685 {
686 	struct ieee80211com *ic = (void *)ifp;
687 	const struct ieee80211_node *ni = NULL;
688 
689 	imr->ifm_status = IFM_AVALID;
690 	imr->ifm_active = IFM_IEEE80211;
691 	if (ic->ic_state == IEEE80211_S_RUN &&
692 	    (ic->ic_opmode != IEEE80211_M_STA ||
693 	     !(ic->ic_flags & IEEE80211_F_RSNON) ||
694 	     ic->ic_bss->ni_port_valid))
695 		imr->ifm_status |= IFM_ACTIVE;
696 	imr->ifm_active |= IFM_AUTO;
697 	switch (ic->ic_opmode) {
698 	case IEEE80211_M_STA:
699 		ni = ic->ic_bss;
700 		if (ic->ic_curmode == IEEE80211_MODE_11N ||
701 		    ic->ic_curmode == IEEE80211_MODE_11AC)
702 			imr->ifm_active |= ieee80211_mcs2media(ic,
703 				ni->ni_txmcs, ic->ic_curmode);
704 		else
705 			/* calculate rate subtype */
706 			imr->ifm_active |= ieee80211_rate2media(ic,
707 				ni->ni_rates.rs_rates[ni->ni_txrate],
708 				ic->ic_curmode);
709 		break;
710 #ifndef IEEE80211_STA_ONLY
711 	case IEEE80211_M_IBSS:
712 		imr->ifm_active |= IFM_IEEE80211_IBSS;
713 		break;
714 	case IEEE80211_M_AHDEMO:
715 		imr->ifm_active |= IFM_IEEE80211_ADHOC;
716 		break;
717 	case IEEE80211_M_HOSTAP:
718 		imr->ifm_active |= IFM_IEEE80211_HOSTAP;
719 		break;
720 #endif
721 	case IEEE80211_M_MONITOR:
722 		imr->ifm_active |= IFM_IEEE80211_MONITOR;
723 		break;
724 	default:
725 		break;
726 	}
727 	switch (ic->ic_curmode) {
728 	case IEEE80211_MODE_11A:
729 		imr->ifm_active |= IFM_IEEE80211_11A;
730 		break;
731 	case IEEE80211_MODE_11B:
732 		imr->ifm_active |= IFM_IEEE80211_11B;
733 		break;
734 	case IEEE80211_MODE_11G:
735 		imr->ifm_active |= IFM_IEEE80211_11G;
736 		break;
737 	case IEEE80211_MODE_11N:
738 		imr->ifm_active |= IFM_IEEE80211_11N;
739 		break;
740 	case IEEE80211_MODE_11AC:
741 		imr->ifm_active |= IFM_IEEE80211_11AC;
742 		break;
743 	}
744 }
745 
746 void
747 ieee80211_watchdog(struct ifnet *ifp)
748 {
749 	struct ieee80211com *ic = (void *)ifp;
750 
751 	if (ic->ic_mgt_timer && --ic->ic_mgt_timer == 0)
752 		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
753 
754 	if (ic->ic_mgt_timer != 0)
755 		ifp->if_timer = 1;
756 }
757 
758 const struct ieee80211_rateset ieee80211_std_rateset_11a =
759 	{ 8, { 12, 18, 24, 36, 48, 72, 96, 108 } };
760 
761 const struct ieee80211_rateset ieee80211_std_rateset_11b =
762 	{ 4, { 2, 4, 11, 22 } };
763 
764 const struct ieee80211_rateset ieee80211_std_rateset_11g =
765 	{ 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
766 
767 const struct ieee80211_ht_rateset ieee80211_std_ratesets_11n[] = {
768 	/* MCS 0-7, 20MHz channel, no SGI */
769 	{ 8, { 13, 26, 39, 52, 78, 104, 117, 130 }, 0x000000ff, 0, 7, 0},
770 
771 	/* MCS 0-7, 20MHz channel, SGI */
772 	{ 8, { 14, 29, 43, 58, 87, 116, 130, 144 }, 0x000000ff, 0, 7, 1 },
773 
774 	/* MCS 8-15, 20MHz channel, no SGI */
775 	{ 8, { 26, 52, 78, 104, 156, 208, 234, 260 }, 0x0000ff00, 8, 15, 0 },
776 
777 	/* MCS 8-15, 20MHz channel, SGI */
778 	{ 8, { 29, 58, 87, 116, 173, 231, 261, 289 }, 0x0000ff00, 8, 15, 1 },
779 
780 	/* MCS 16-23, 20MHz channel, no SGI */
781 	{ 8, { 39, 78, 117, 156, 234, 312, 351, 390 }, 0x00ff0000, 16, 23, 0 },
782 
783 	/* MCS 16-23, 20MHz channel, SGI */
784 	{ 8, { 43, 87, 130, 173, 260, 347, 390, 433 }, 0x00ff0000, 16, 23, 1 },
785 
786 	/* MCS 24-31, 20MHz channel, no SGI */
787 	{ 8, { 52, 104, 156, 208, 312, 416, 468, 520 }, 0xff000000, 24, 31, 0 },
788 
789 	/* MCS 24-31, 20MHz channel, SGI */
790 	{ 8, { 58, 116, 173, 231, 347, 462, 520, 578 }, 0xff000000, 24, 31, 1 },
791 };
792 
793 const struct ieee80211_vht_rateset ieee80211_std_ratesets_11ac[] = {
794 	/* MCS 0-8 (MCS 9 N/A), 1 SS, 20MHz channel, no SGI */
795 	{ 9, { 13, 26, 39, 52, 78, 104, 117, 130, 156 }, 1, 0 },
796 
797 	/* MCS 0-8 (MCS 9 N/A), 1 SS, 20MHz channel, SGI */
798 	{ 9, { 14, 29, 43, 58, 87, 116, 130, 144, 174 }, 1, 1 },
799 
800 	/* MCS 0-8 (MCS 9 N/A), 2 SS, 20MHz channel, no SGI */
801 	{ 9, { 26, 52, 78, 104, 156, 208, 234, 260, 312 }, 2, 0 },
802 
803 	/* MCS 0-8 (MCS 9 N/A), 2 SS, 20MHz channel, SGI */
804 	{ 9, { 29, 58, 87, 116, 173, 231, 261, 289, 347 }, 2, 1 },
805 
806 	/* MCS 0-9, 1 SS, 40MHz channel, no SGI */
807 	{ 10, { 27, 54, 81, 108, 162, 216, 243, 270, 324, 360 }, 1, 0 },
808 
809 	/* MCS 0-9, 1 SS, 40MHz channel, SGI */
810 	{ 10, { 30, 60, 90, 120, 180, 240, 270, 300, 360, 400 }, 1, 1 },
811 
812 	/* MCS 0-9, 2 SS, 40MHz channel, no SGI */
813 	{ 10, { 54, 108, 162, 216, 324, 432, 486, 540, 648, 720 }, 2, 0 },
814 
815 	/* MCS 0-9, 2 SS, 40MHz channel, SGI */
816 	{ 10, { 60, 120, 180, 240, 360, 480, 540, 600, 720, 800 }, 2, 1 },
817 
818 	/* MCS 0-9, 1 SS, 80MHz channel, no SGI */
819 	{ 10, { 59, 117, 176, 234, 351, 468, 527, 585, 702, 780 }, 1, 0 },
820 
821 	/* MCS 0-9, 1 SS, 80MHz channel, SGI */
822 	{ 10, { 65, 130, 195, 260, 390, 520, 585, 650, 780, 867 }, 1, 1 },
823 
824 	/* MCS 0-9, 2 SS, 80MHz channel, no SGI */
825 	{ 10, { 117, 234, 351, 468, 702, 936, 1053, 1404, 1560 }, 2, 0 },
826 
827 	/* MCS 0-9, 2 SS, 80MHz channel, SGI */
828 	{ 10, { 130, 260, 390, 520, 780, 1040, 1170, 1300, 1560, 1734 }, 2, 1 },
829 };
830 
831 /*
832  * Mark the basic rates for the 11g rate table based on the
833  * operating mode.  For real 11g we mark all the 11b rates
834  * and 6, 12, and 24 OFDM.  For 11b compatibility we mark only
835  * 11b rates.  There's also a pseudo 11a-mode used to mark only
836  * the basic OFDM rates.
837  */
838 void
839 ieee80211_setbasicrates(struct ieee80211com *ic)
840 {
841 	static const struct ieee80211_rateset basic[] = {
842 	    { 0 },				/* IEEE80211_MODE_AUTO */
843 	    { 3, { 12, 24, 48 } },		/* IEEE80211_MODE_11A */
844 	    { 2, { 2, 4 } },			/* IEEE80211_MODE_11B */
845 	    { 4, { 2, 4, 11, 22 } },		/* IEEE80211_MODE_11G */
846 	    { 0 },				/* IEEE80211_MODE_11N	*/
847 	    { 0 },				/* IEEE80211_MODE_11AC	*/
848 	};
849 	enum ieee80211_phymode mode;
850 	struct ieee80211_rateset *rs;
851 	int i, j;
852 
853 	for (mode = 0; mode < IEEE80211_MODE_MAX; mode++) {
854 		rs = &ic->ic_sup_rates[mode];
855 		for (i = 0; i < rs->rs_nrates; i++) {
856 			rs->rs_rates[i] &= IEEE80211_RATE_VAL;
857 			for (j = 0; j < basic[mode].rs_nrates; j++) {
858 				if (basic[mode].rs_rates[j] ==
859 				    rs->rs_rates[i]) {
860 					rs->rs_rates[i] |=
861 					    IEEE80211_RATE_BASIC;
862 					break;
863 				}
864 			}
865 		}
866 	}
867 }
868 
869 int
870 ieee80211_min_basic_rate(struct ieee80211com *ic)
871 {
872 	struct ieee80211_rateset *rs = &ic->ic_bss->ni_rates;
873 	int i, min, rval;
874 
875 	min = -1;
876 
877 	for (i = 0; i < rs->rs_nrates; i++) {
878 		if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) == 0)
879 			continue;
880 		rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL);
881 		if (min == -1)
882 			min = rval;
883 		else if (rval < min)
884 			min = rval;
885 	}
886 
887 	/* Default to 1 Mbit/s on 2GHz and 6 Mbit/s on 5GHz. */
888 	if (min == -1)
889 		min = IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan) ? 2 : 12;
890 
891 	return min;
892 }
893 
894 int
895 ieee80211_max_basic_rate(struct ieee80211com *ic)
896 {
897 	struct ieee80211_rateset *rs = &ic->ic_bss->ni_rates;
898 	int i, max, rval;
899 
900 	/* Default to 1 Mbit/s on 2GHz and 6 Mbit/s on 5GHz. */
901 	max = IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan) ? 2 : 12;
902 
903 	for (i = 0; i < rs->rs_nrates; i++) {
904 		if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) == 0)
905 			continue;
906 		rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL);
907 		if (rval > max)
908 			max = rval;
909 	}
910 
911 	return max;
912 }
913 
914 /*
915  * Set the current phy mode and recalculate the active channel
916  * set based on the available channels for this mode.  Also
917  * select a new default/current channel if the current one is
918  * inappropriate for this mode.
919  */
920 int
921 ieee80211_setmode(struct ieee80211com *ic, enum ieee80211_phymode mode)
922 {
923 	struct ifnet *ifp = &ic->ic_if;
924 	static const u_int chanflags[] = {
925 		0,			/* IEEE80211_MODE_AUTO */
926 		IEEE80211_CHAN_A,	/* IEEE80211_MODE_11A */
927 		IEEE80211_CHAN_B,	/* IEEE80211_MODE_11B */
928 		IEEE80211_CHAN_PUREG,	/* IEEE80211_MODE_11G */
929 		IEEE80211_CHAN_HT,	/* IEEE80211_MODE_11N */
930 		IEEE80211_CHAN_VHT,	/* IEEE80211_MODE_11AC */
931 	};
932 	const struct ieee80211_channel *c;
933 	u_int modeflags;
934 	int i;
935 
936 	/* validate new mode */
937 	if ((ic->ic_modecaps & (1<<mode)) == 0) {
938 		DPRINTF(("mode %u not supported (caps 0x%x)\n",
939 		    mode, ic->ic_modecaps));
940 		return EINVAL;
941 	}
942 
943 	/*
944 	 * Verify at least one channel is present in the available
945 	 * channel list before committing to the new mode.
946 	 */
947 	if (mode >= nitems(chanflags))
948 		panic("%s: unexpected mode %u", __func__, mode);
949 	modeflags = chanflags[mode];
950 	for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
951 		c = &ic->ic_channels[i];
952 		if (mode == IEEE80211_MODE_AUTO) {
953 			if (c->ic_flags != 0)
954 				break;
955 		} else if ((c->ic_flags & modeflags) == modeflags)
956 			break;
957 	}
958 	if (i > IEEE80211_CHAN_MAX) {
959 		DPRINTF(("no channels found for mode %u\n", mode));
960 		return EINVAL;
961 	}
962 
963 	/*
964 	 * Calculate the active channel set.
965 	 */
966 	memset(ic->ic_chan_active, 0, sizeof(ic->ic_chan_active));
967 	for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
968 		c = &ic->ic_channels[i];
969 		if (mode == IEEE80211_MODE_AUTO) {
970 			if (c->ic_flags != 0)
971 				setbit(ic->ic_chan_active, i);
972 		} else if ((c->ic_flags & modeflags) == modeflags)
973 			setbit(ic->ic_chan_active, i);
974 	}
975 	/*
976 	 * If no current/default channel is setup or the current
977 	 * channel is wrong for the mode then pick the first
978 	 * available channel from the active list.  This is likely
979 	 * not the right one.
980 	 */
981 	if (ic->ic_ibss_chan == NULL || isclr(ic->ic_chan_active,
982 	    ieee80211_chan2ieee(ic, ic->ic_ibss_chan))) {
983 		for (i = 0; i <= IEEE80211_CHAN_MAX; i++)
984 			if (isset(ic->ic_chan_active, i)) {
985 				ic->ic_ibss_chan = &ic->ic_channels[i];
986 				break;
987 			}
988 		if ((ic->ic_ibss_chan == NULL) || isclr(ic->ic_chan_active,
989 		    ieee80211_chan2ieee(ic, ic->ic_ibss_chan)))
990 			panic("Bad IBSS channel %u",
991 			    ieee80211_chan2ieee(ic, ic->ic_ibss_chan));
992 	}
993 
994 	/*
995 	 * Reset the scan state for the new mode. This avoids scanning
996 	 * of invalid channels, ie. 5GHz channels in 11b mode.
997 	 */
998 	ieee80211_reset_scan(ifp);
999 
1000 	ic->ic_curmode = mode;
1001 	ieee80211_reset_erp(ic);	/* reset ERP state */
1002 
1003 	return 0;
1004 }
1005 
1006 enum ieee80211_phymode
1007 ieee80211_next_mode(struct ifnet *ifp)
1008 {
1009 	struct ieee80211com *ic = (void *)ifp;
1010 	uint16_t mode;
1011 
1012 	/*
1013 	 * Indicate a wrap-around if we're running in a fixed, user-specified
1014 	 * phy mode or if the driver scans all bands in one scan iteration.
1015 	 */
1016 	if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) != IFM_AUTO ||
1017 	    (ic->ic_caps & IEEE80211_C_SCANALLBAND))
1018 		return (IEEE80211_MODE_AUTO);
1019 
1020 	/*
1021 	 * Get the next supported mode; effectively, this alternates between
1022 	 * the 11a (5GHz) and 11b/g (2GHz) modes. What matters is that each
1023 	 * supported channel gets scanned.
1024 	 */
1025 	for (mode = ic->ic_curmode + 1; mode <= IEEE80211_MODE_MAX; mode++) {
1026 		/*
1027 		 * Skip over 11n mode. Its set of channels is the superset
1028 		 * of all channels supported by the other modes.
1029 		 */
1030 		if (mode == IEEE80211_MODE_11N)
1031 			continue;
1032 		/*
1033 		 * Skip over 11ac mode. Its set of channels is the set
1034 		 * of all channels supported by 11a.
1035 		 */
1036 		if (mode == IEEE80211_MODE_11AC)
1037 			continue;
1038 
1039 		/* Start over if we have already tried all modes. */
1040 		if (mode == IEEE80211_MODE_MAX) {
1041 			mode = IEEE80211_MODE_AUTO;
1042 			break;
1043 		}
1044 
1045 		if (ic->ic_modecaps & (1 << mode))
1046 			break;
1047 	}
1048 
1049 	if (mode != ic->ic_curmode)
1050 		ieee80211_setmode(ic, mode);
1051 
1052 	return (ic->ic_curmode);
1053 }
1054 
1055 /*
1056  * Return the phy mode for with the specified channel so the
1057  * caller can select a rate set.  This is problematic and the
1058  * work here assumes how things work elsewhere in this code.
1059  *
1060  * Because the result of this function is ultimately used to select a
1061  * rate from the rate set of the returned mode, it must return one of the
1062  * legacy 11a/b/g modes; 11n and 11ac modes use MCS instead of rate sets.
1063  */
1064 enum ieee80211_phymode
1065 ieee80211_chan2mode(struct ieee80211com *ic,
1066     const struct ieee80211_channel *chan)
1067 {
1068 	/*
1069 	 * Are we fixed in 11a/b/g mode?
1070 	 * NB: this assumes the channel would not be supplied to us
1071 	 *     unless it was already compatible with the current mode.
1072 	 */
1073 	if (ic->ic_curmode == IEEE80211_MODE_11A ||
1074 	    ic->ic_curmode == IEEE80211_MODE_11B ||
1075 	    ic->ic_curmode == IEEE80211_MODE_11G)
1076 		return ic->ic_curmode;
1077 
1078 	/* If no channel was provided, return the most suitable legacy mode. */
1079 	if (chan == IEEE80211_CHAN_ANYC) {
1080 		switch (ic->ic_curmode) {
1081 		case IEEE80211_MODE_AUTO:
1082 		case IEEE80211_MODE_11N:
1083 			if (ic->ic_modecaps & (1 << IEEE80211_MODE_11A))
1084 				return IEEE80211_MODE_11A;
1085 			if (ic->ic_modecaps & (1 << IEEE80211_MODE_11G))
1086 				return IEEE80211_MODE_11G;
1087 			return IEEE80211_MODE_11B;
1088 		case IEEE80211_MODE_11AC:
1089 			return IEEE80211_MODE_11A;
1090 		default:
1091 			return ic->ic_curmode;
1092 		}
1093 	}
1094 
1095 	/* Deduce a legacy mode based on the channel characteristics. */
1096 	if (IEEE80211_IS_CHAN_5GHZ(chan))
1097 		return IEEE80211_MODE_11A;
1098 	else if (chan->ic_flags & (IEEE80211_CHAN_OFDM|IEEE80211_CHAN_DYN))
1099 		return IEEE80211_MODE_11G;
1100 	else
1101 		return IEEE80211_MODE_11B;
1102 }
1103 
1104 /*
1105  * Convert IEEE80211 MCS index to ifmedia subtype.
1106  */
1107 uint64_t
1108 ieee80211_mcs2media(struct ieee80211com *ic, int mcs,
1109     enum ieee80211_phymode mode)
1110 {
1111 	switch (mode) {
1112 	case IEEE80211_MODE_11A:
1113 	case IEEE80211_MODE_11B:
1114 	case IEEE80211_MODE_11G:
1115 		/* these modes use rates, not MCS */
1116 		panic("%s: unexpected mode %d", __func__, mode);
1117 		break;
1118 	case IEEE80211_MODE_11N:
1119 		if (mcs >= 0 && mcs < IEEE80211_HT_NUM_MCS)
1120 			return (IFM_IEEE80211_11N |
1121 			    (IFM_IEEE80211_HT_MCS0 + mcs));
1122 		break;
1123 	case IEEE80211_MODE_11AC:
1124 		if (mcs >= 0 && mcs < IEEE80211_VHT_NUM_MCS)
1125 			return (IFM_IEEE80211_11AC |
1126 			    (IFM_IEEE80211_VHT_MCS0 + mcs));
1127 		break;
1128 	case IEEE80211_MODE_AUTO:
1129 		break;
1130 	}
1131 
1132 	return IFM_AUTO;
1133 }
1134 
1135 /*
1136  * Convert ifmedia subtype to IEEE80211 MCS index.
1137  */
1138 int
1139 ieee80211_media2mcs(uint64_t mword)
1140 {
1141 	uint64_t subtype;
1142 
1143 	subtype = IFM_SUBTYPE(mword);
1144 
1145 	if (subtype == IFM_AUTO)
1146 		return -1;
1147 	else if (subtype == IFM_MANUAL || subtype == IFM_NONE)
1148 		return 0;
1149 
1150 	if (subtype >= IFM_IEEE80211_HT_MCS0 &&
1151 	    subtype <= IFM_IEEE80211_HT_MCS76)
1152 		return (int)(subtype - IFM_IEEE80211_HT_MCS0);
1153 
1154 	if (subtype >= IFM_IEEE80211_VHT_MCS0 &&
1155 	    subtype <= IFM_IEEE80211_VHT_MCS9)
1156 		return (int)(subtype - IFM_IEEE80211_VHT_MCS0);
1157 
1158 	return -1;
1159 }
1160 
1161 /*
1162  * convert IEEE80211 rate value to ifmedia subtype.
1163  * ieee80211 rate is in unit of 0.5Mbps.
1164  */
1165 uint64_t
1166 ieee80211_rate2media(struct ieee80211com *ic, int rate,
1167     enum ieee80211_phymode mode)
1168 {
1169 	static const struct {
1170 		uint64_t	m;	/* rate + mode */
1171 		uint64_t	r;	/* if_media rate */
1172 	} rates[] = {
1173 		{   2 | IFM_IEEE80211_11B, IFM_IEEE80211_DS1 },
1174 		{   4 | IFM_IEEE80211_11B, IFM_IEEE80211_DS2 },
1175 		{  11 | IFM_IEEE80211_11B, IFM_IEEE80211_DS5 },
1176 		{  22 | IFM_IEEE80211_11B, IFM_IEEE80211_DS11 },
1177 		{  44 | IFM_IEEE80211_11B, IFM_IEEE80211_DS22 },
1178 		{  12 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM6 },
1179 		{  18 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM9 },
1180 		{  24 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM12 },
1181 		{  36 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM18 },
1182 		{  48 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM24 },
1183 		{  72 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM36 },
1184 		{  96 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM48 },
1185 		{ 108 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM54 },
1186 		{   2 | IFM_IEEE80211_11G, IFM_IEEE80211_DS1 },
1187 		{   4 | IFM_IEEE80211_11G, IFM_IEEE80211_DS2 },
1188 		{  11 | IFM_IEEE80211_11G, IFM_IEEE80211_DS5 },
1189 		{  22 | IFM_IEEE80211_11G, IFM_IEEE80211_DS11 },
1190 		{  12 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM6 },
1191 		{  18 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM9 },
1192 		{  24 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM12 },
1193 		{  36 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM18 },
1194 		{  48 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM24 },
1195 		{  72 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM36 },
1196 		{  96 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM48 },
1197 		{ 108 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM54 },
1198 		/* NB: OFDM72 doesn't really exist so we don't handle it */
1199 	};
1200 	uint64_t mask;
1201 	int i;
1202 
1203 	mask = rate & IEEE80211_RATE_VAL;
1204 	switch (mode) {
1205 	case IEEE80211_MODE_11A:
1206 		mask |= IFM_IEEE80211_11A;
1207 		break;
1208 	case IEEE80211_MODE_11B:
1209 		mask |= IFM_IEEE80211_11B;
1210 		break;
1211 	case IEEE80211_MODE_AUTO:
1212 		/* NB: hack, 11g matches both 11b+11a rates */
1213 		/* FALLTHROUGH */
1214 	case IEEE80211_MODE_11G:
1215 		mask |= IFM_IEEE80211_11G;
1216 		break;
1217 	case IEEE80211_MODE_11N:
1218 	case IEEE80211_MODE_11AC:
1219 		/* 11n/11ac uses MCS, not rates. */
1220 		panic("%s: unexpected mode %d", __func__, mode);
1221 		break;
1222 	}
1223 	for (i = 0; i < nitems(rates); i++)
1224 		if (rates[i].m == mask)
1225 			return rates[i].r;
1226 	return IFM_AUTO;
1227 }
1228 
1229 int
1230 ieee80211_media2rate(uint64_t mword)
1231 {
1232 	int i;
1233 	static const struct {
1234 		uint64_t subtype;
1235 		int rate;
1236 	} ieeerates[] = {
1237 		{ IFM_AUTO,		-1	},
1238 		{ IFM_MANUAL,		0	},
1239 		{ IFM_NONE,		0	},
1240 		{ IFM_IEEE80211_DS1,	2	},
1241 		{ IFM_IEEE80211_DS2,	4	},
1242 		{ IFM_IEEE80211_DS5,	11	},
1243 		{ IFM_IEEE80211_DS11,	22	},
1244 		{ IFM_IEEE80211_DS22,	44	},
1245 		{ IFM_IEEE80211_OFDM6,	12	},
1246 		{ IFM_IEEE80211_OFDM9,	18	},
1247 		{ IFM_IEEE80211_OFDM12,	24	},
1248 		{ IFM_IEEE80211_OFDM18,	36	},
1249 		{ IFM_IEEE80211_OFDM24,	48	},
1250 		{ IFM_IEEE80211_OFDM36,	72	},
1251 		{ IFM_IEEE80211_OFDM48,	96	},
1252 		{ IFM_IEEE80211_OFDM54,	108	},
1253 		{ IFM_IEEE80211_OFDM72,	144	},
1254 	};
1255 	for (i = 0; i < nitems(ieeerates); i++) {
1256 		if (ieeerates[i].subtype == IFM_SUBTYPE(mword))
1257 			return ieeerates[i].rate;
1258 	}
1259 	return 0;
1260 }
1261 
1262 /*
1263  * Convert bit rate (in 0.5Mbps units) to PLCP signal (R4-R1) and vice versa.
1264  */
1265 u_int8_t
1266 ieee80211_rate2plcp(u_int8_t rate, enum ieee80211_phymode mode)
1267 {
1268 	rate &= IEEE80211_RATE_VAL;
1269 
1270 	if (mode == IEEE80211_MODE_11B) {
1271 		/* IEEE Std 802.11b-1999 page 15, subclause 18.2.3.3 */
1272 		switch (rate) {
1273 		case 2:		return 10;
1274 		case 4:		return 20;
1275 		case 11:	return 55;
1276 		case 22:	return 110;
1277 		/* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */
1278 		case 44:	return 220;
1279 		}
1280 	} else if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11A) {
1281 		/* IEEE Std 802.11a-1999 page 14, subclause 17.3.4.1 */
1282 		switch (rate) {
1283 		case 12:	return 0x0b;
1284 		case 18:	return 0x0f;
1285 		case 24:	return 0x0a;
1286 		case 36:	return 0x0e;
1287 		case 48:	return 0x09;
1288 		case 72:	return 0x0d;
1289 		case 96:	return 0x08;
1290 		case 108:	return 0x0c;
1291 		}
1292         } else
1293 		panic("%s: unexpected mode %u", __func__, mode);
1294 
1295 	DPRINTF(("unsupported rate %u\n", rate));
1296 
1297 	return 0;
1298 }
1299 
1300 u_int8_t
1301 ieee80211_plcp2rate(u_int8_t plcp, enum ieee80211_phymode mode)
1302 {
1303 	if (mode == IEEE80211_MODE_11B) {
1304 		/* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */
1305 		switch (plcp) {
1306 		case 10:	return 2;
1307 		case 20:	return 4;
1308 		case 55:	return 11;
1309 		case 110:	return 22;
1310 		/* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */
1311 		case 220:	return 44;
1312 		}
1313 	} else if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11A) {
1314 		/* IEEE Std 802.11a-1999 page 14, subclause 17.3.4.1 */
1315 		switch (plcp) {
1316 		case 0x0b:	return 12;
1317 		case 0x0f:	return 18;
1318 		case 0x0a:	return 24;
1319 		case 0x0e:	return 36;
1320 		case 0x09:	return 48;
1321 		case 0x0d:	return 72;
1322 		case 0x08:	return 96;
1323 		case 0x0c:	return 108;
1324 		}
1325 	} else
1326 		panic("%s: unexpected mode %u", __func__, mode);
1327 
1328 	DPRINTF(("unsupported plcp %u\n", plcp));
1329 
1330 	return 0;
1331 }
1332