xref: /openbsd-src/sys/net80211/ieee80211.c (revision 4b70baf6e17fc8b27fc1f7fa7929335753fa94c3)
1 /*	$OpenBSD: ieee80211.c,v 1.72 2019/02/19 08:12:30 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 	};
848 	enum ieee80211_phymode mode;
849 	struct ieee80211_rateset *rs;
850 	int i, j;
851 
852 	for (mode = 0; mode < IEEE80211_MODE_MAX; mode++) {
853 		rs = &ic->ic_sup_rates[mode];
854 		for (i = 0; i < rs->rs_nrates; i++) {
855 			rs->rs_rates[i] &= IEEE80211_RATE_VAL;
856 			for (j = 0; j < basic[mode].rs_nrates; j++) {
857 				if (basic[mode].rs_rates[j] ==
858 				    rs->rs_rates[i]) {
859 					rs->rs_rates[i] |=
860 					    IEEE80211_RATE_BASIC;
861 					break;
862 				}
863 			}
864 		}
865 	}
866 }
867 
868 int
869 ieee80211_min_basic_rate(struct ieee80211com *ic)
870 {
871 	struct ieee80211_rateset *rs = &ic->ic_bss->ni_rates;
872 	int i, min, rval;
873 
874 	min = -1;
875 
876 	for (i = 0; i < rs->rs_nrates; i++) {
877 		if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) == 0)
878 			continue;
879 		rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL);
880 		if (min == -1)
881 			min = rval;
882 		else if (rval < min)
883 			min = rval;
884 	}
885 
886 	/* Default to 1 Mbit/s on 2GHz and 6 Mbit/s on 5GHz. */
887 	if (min == -1)
888 		min = IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan) ? 2 : 12;
889 
890 	return min;
891 }
892 
893 int
894 ieee80211_max_basic_rate(struct ieee80211com *ic)
895 {
896 	struct ieee80211_rateset *rs = &ic->ic_bss->ni_rates;
897 	int i, max, rval;
898 
899 	/* Default to 1 Mbit/s on 2GHz and 6 Mbit/s on 5GHz. */
900 	max = IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan) ? 2 : 12;
901 
902 	for (i = 0; i < rs->rs_nrates; i++) {
903 		if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) == 0)
904 			continue;
905 		rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL);
906 		if (rval > max)
907 			max = rval;
908 	}
909 
910 	return max;
911 }
912 
913 /*
914  * Set the current phy mode and recalculate the active channel
915  * set based on the available channels for this mode.  Also
916  * select a new default/current channel if the current one is
917  * inappropriate for this mode.
918  */
919 int
920 ieee80211_setmode(struct ieee80211com *ic, enum ieee80211_phymode mode)
921 {
922 	struct ifnet *ifp = &ic->ic_if;
923 	static const u_int chanflags[] = {
924 		0,			/* IEEE80211_MODE_AUTO */
925 		IEEE80211_CHAN_A,	/* IEEE80211_MODE_11A */
926 		IEEE80211_CHAN_B,	/* IEEE80211_MODE_11B */
927 		IEEE80211_CHAN_PUREG,	/* IEEE80211_MODE_11G */
928 		IEEE80211_CHAN_HT,	/* IEEE80211_MODE_11N */
929 		IEEE80211_CHAN_VHT,	/* IEEE80211_MODE_11AC */
930 	};
931 	const struct ieee80211_channel *c;
932 	u_int modeflags;
933 	int i;
934 
935 	/* validate new mode */
936 	if ((ic->ic_modecaps & (1<<mode)) == 0) {
937 		DPRINTF(("mode %u not supported (caps 0x%x)\n",
938 		    mode, ic->ic_modecaps));
939 		return EINVAL;
940 	}
941 
942 	/*
943 	 * Verify at least one channel is present in the available
944 	 * channel list before committing to the new mode.
945 	 */
946 	if (mode >= nitems(chanflags))
947 		panic("%s: unexpected mode %u", __func__, mode);
948 	modeflags = chanflags[mode];
949 	for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
950 		c = &ic->ic_channels[i];
951 		if (mode == IEEE80211_MODE_AUTO) {
952 			if (c->ic_flags != 0)
953 				break;
954 		} else if ((c->ic_flags & modeflags) == modeflags)
955 			break;
956 	}
957 	if (i > IEEE80211_CHAN_MAX) {
958 		DPRINTF(("no channels found for mode %u\n", mode));
959 		return EINVAL;
960 	}
961 
962 	/*
963 	 * Calculate the active channel set.
964 	 */
965 	memset(ic->ic_chan_active, 0, sizeof(ic->ic_chan_active));
966 	for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
967 		c = &ic->ic_channels[i];
968 		if (mode == IEEE80211_MODE_AUTO) {
969 			if (c->ic_flags != 0)
970 				setbit(ic->ic_chan_active, i);
971 		} else if ((c->ic_flags & modeflags) == modeflags)
972 			setbit(ic->ic_chan_active, i);
973 	}
974 	/*
975 	 * If no current/default channel is setup or the current
976 	 * channel is wrong for the mode then pick the first
977 	 * available channel from the active list.  This is likely
978 	 * not the right one.
979 	 */
980 	if (ic->ic_ibss_chan == NULL || isclr(ic->ic_chan_active,
981 	    ieee80211_chan2ieee(ic, ic->ic_ibss_chan))) {
982 		for (i = 0; i <= IEEE80211_CHAN_MAX; i++)
983 			if (isset(ic->ic_chan_active, i)) {
984 				ic->ic_ibss_chan = &ic->ic_channels[i];
985 				break;
986 			}
987 		if ((ic->ic_ibss_chan == NULL) || isclr(ic->ic_chan_active,
988 		    ieee80211_chan2ieee(ic, ic->ic_ibss_chan)))
989 			panic("Bad IBSS channel %u",
990 			    ieee80211_chan2ieee(ic, ic->ic_ibss_chan));
991 	}
992 
993 	/*
994 	 * Reset the scan state for the new mode. This avoids scanning
995 	 * of invalid channels, ie. 5GHz channels in 11b mode.
996 	 */
997 	ieee80211_reset_scan(ifp);
998 
999 	ic->ic_curmode = mode;
1000 	ieee80211_reset_erp(ic);	/* reset ERP state */
1001 
1002 	return 0;
1003 }
1004 
1005 enum ieee80211_phymode
1006 ieee80211_next_mode(struct ifnet *ifp)
1007 {
1008 	struct ieee80211com *ic = (void *)ifp;
1009 
1010 	if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) != IFM_AUTO) {
1011 		/*
1012 		 * Reset the scan state and indicate a wrap around
1013 		 * if we're running in a fixed, user-specified phy mode.
1014 		 */
1015 		ieee80211_reset_scan(ifp);
1016 		return (IEEE80211_MODE_AUTO);
1017 	}
1018 
1019 	/*
1020 	 * Get the next supported mode
1021 	 */
1022 	for (++ic->ic_curmode;
1023 	    ic->ic_curmode <= IEEE80211_MODE_MAX;
1024 	    ic->ic_curmode++) {
1025 		/*
1026 		 * Skip over 11n mode. Its set of channels is the superset
1027 		 * of all channels supported by the other modes.
1028 		 */
1029 		if (ic->ic_curmode == IEEE80211_MODE_11N)
1030 			continue;
1031 		/*
1032 		 * Skip over 11ac mode. Its set of channels is the set
1033 		 * of all channels supported by 11a.
1034 		 */
1035 		if (ic->ic_curmode == IEEE80211_MODE_11AC)
1036 			continue;
1037 
1038 		/* Always scan in AUTO mode if the driver scans all bands. */
1039 		if (ic->ic_curmode >= IEEE80211_MODE_MAX ||
1040 		    (ic->ic_caps & IEEE80211_C_SCANALLBAND)) {
1041 			ic->ic_curmode = IEEE80211_MODE_AUTO;
1042 			break;
1043 		}
1044 
1045 		if (ic->ic_modecaps & (1 << ic->ic_curmode))
1046 			break;
1047 	}
1048 
1049 	ieee80211_setmode(ic, ic->ic_curmode);
1050 
1051 	return (ic->ic_curmode);
1052 }
1053 
1054 /*
1055  * Return the phy mode for with the specified channel so the
1056  * caller can select a rate set.  This is problematic and the
1057  * work here assumes how things work elsewhere in this code.
1058  *
1059  * Because the result of this function is ultimately used to select a
1060  * rate from the rate set of the returned mode, it must not return
1061  * IEEE80211_MODE_11N, which uses MCS instead of rates for unicast frames.
1062  */
1063 enum ieee80211_phymode
1064 ieee80211_chan2mode(struct ieee80211com *ic,
1065     const struct ieee80211_channel *chan)
1066 {
1067 	/*
1068 	 * NB: this assumes the channel would not be supplied to us
1069 	 *     unless it was already compatible with the current mode.
1070 	 */
1071 	if (ic->ic_curmode != IEEE80211_MODE_11N &&
1072 	    ic->ic_curmode != IEEE80211_MODE_11AC &&
1073 	    (ic->ic_curmode != IEEE80211_MODE_AUTO ||
1074 	    chan == IEEE80211_CHAN_ANYC))
1075 		return ic->ic_curmode;
1076 	/*
1077 	 * In autoselect or 11n mode; deduce a mode based on the channel
1078 	 * characteristics.
1079 	 */
1080 	if (IEEE80211_IS_CHAN_5GHZ(chan))
1081 		return IEEE80211_MODE_11A;
1082 	else if (chan->ic_flags & (IEEE80211_CHAN_OFDM|IEEE80211_CHAN_DYN))
1083 		return IEEE80211_MODE_11G;
1084 	else
1085 		return IEEE80211_MODE_11B;
1086 }
1087 
1088 /*
1089  * Convert IEEE80211 MCS index to ifmedia subtype.
1090  */
1091 uint64_t
1092 ieee80211_mcs2media(struct ieee80211com *ic, int mcs,
1093     enum ieee80211_phymode mode)
1094 {
1095 	switch (mode) {
1096 	case IEEE80211_MODE_11A:
1097 	case IEEE80211_MODE_11B:
1098 	case IEEE80211_MODE_11G:
1099 		/* these modes use rates, not MCS */
1100 		panic("%s: unexpected mode %d", __func__, mode);
1101 		break;
1102 	case IEEE80211_MODE_11N:
1103 		if (mcs >= 0 && mcs < IEEE80211_HT_NUM_MCS)
1104 			return (IFM_IEEE80211_11N |
1105 			    (IFM_IEEE80211_HT_MCS0 + mcs));
1106 		break;
1107 	case IEEE80211_MODE_11AC:
1108 		if (mcs >= 0 && mcs < IEEE80211_VHT_NUM_MCS)
1109 			return (IFM_IEEE80211_11AC |
1110 			    (IFM_IEEE80211_VHT_MCS0 + mcs));
1111 		break;
1112 	case IEEE80211_MODE_AUTO:
1113 		break;
1114 	}
1115 
1116 	return IFM_AUTO;
1117 }
1118 
1119 /*
1120  * Convert ifmedia subtype to IEEE80211 MCS index.
1121  */
1122 int
1123 ieee80211_media2mcs(uint64_t mword)
1124 {
1125 	uint64_t subtype;
1126 
1127 	subtype = IFM_SUBTYPE(mword);
1128 
1129 	if (subtype == IFM_AUTO)
1130 		return -1;
1131 	else if (subtype == IFM_MANUAL || subtype == IFM_NONE)
1132 		return 0;
1133 
1134 	if (subtype >= IFM_IEEE80211_HT_MCS0 &&
1135 	    subtype <= IFM_IEEE80211_HT_MCS76)
1136 		return (int)(subtype - IFM_IEEE80211_HT_MCS0);
1137 
1138 	if (subtype >= IFM_IEEE80211_VHT_MCS0 &&
1139 	    subtype <= IFM_IEEE80211_VHT_MCS9)
1140 		return (int)(subtype - IFM_IEEE80211_VHT_MCS0);
1141 
1142 	return -1;
1143 }
1144 
1145 /*
1146  * convert IEEE80211 rate value to ifmedia subtype.
1147  * ieee80211 rate is in unit of 0.5Mbps.
1148  */
1149 uint64_t
1150 ieee80211_rate2media(struct ieee80211com *ic, int rate,
1151     enum ieee80211_phymode mode)
1152 {
1153 	static const struct {
1154 		uint64_t	m;	/* rate + mode */
1155 		uint64_t	r;	/* if_media rate */
1156 	} rates[] = {
1157 		{   2 | IFM_IEEE80211_11B, IFM_IEEE80211_DS1 },
1158 		{   4 | IFM_IEEE80211_11B, IFM_IEEE80211_DS2 },
1159 		{  11 | IFM_IEEE80211_11B, IFM_IEEE80211_DS5 },
1160 		{  22 | IFM_IEEE80211_11B, IFM_IEEE80211_DS11 },
1161 		{  44 | IFM_IEEE80211_11B, IFM_IEEE80211_DS22 },
1162 		{  12 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM6 },
1163 		{  18 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM9 },
1164 		{  24 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM12 },
1165 		{  36 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM18 },
1166 		{  48 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM24 },
1167 		{  72 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM36 },
1168 		{  96 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM48 },
1169 		{ 108 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM54 },
1170 		{   2 | IFM_IEEE80211_11G, IFM_IEEE80211_DS1 },
1171 		{   4 | IFM_IEEE80211_11G, IFM_IEEE80211_DS2 },
1172 		{  11 | IFM_IEEE80211_11G, IFM_IEEE80211_DS5 },
1173 		{  22 | IFM_IEEE80211_11G, IFM_IEEE80211_DS11 },
1174 		{  12 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM6 },
1175 		{  18 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM9 },
1176 		{  24 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM12 },
1177 		{  36 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM18 },
1178 		{  48 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM24 },
1179 		{  72 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM36 },
1180 		{  96 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM48 },
1181 		{ 108 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM54 },
1182 		/* NB: OFDM72 doesn't really exist so we don't handle it */
1183 	};
1184 	uint64_t mask;
1185 	int i;
1186 
1187 	mask = rate & IEEE80211_RATE_VAL;
1188 	switch (mode) {
1189 	case IEEE80211_MODE_11A:
1190 		mask |= IFM_IEEE80211_11A;
1191 		break;
1192 	case IEEE80211_MODE_11B:
1193 		mask |= IFM_IEEE80211_11B;
1194 		break;
1195 	case IEEE80211_MODE_AUTO:
1196 		/* NB: hack, 11g matches both 11b+11a rates */
1197 		/* FALLTHROUGH */
1198 	case IEEE80211_MODE_11G:
1199 		mask |= IFM_IEEE80211_11G;
1200 		break;
1201 	case IEEE80211_MODE_11N:
1202 	case IEEE80211_MODE_11AC:
1203 		/* 11n/11ac uses MCS, not rates. */
1204 		panic("%s: unexpected mode %d", __func__, mode);
1205 		break;
1206 	}
1207 	for (i = 0; i < nitems(rates); i++)
1208 		if (rates[i].m == mask)
1209 			return rates[i].r;
1210 	return IFM_AUTO;
1211 }
1212 
1213 int
1214 ieee80211_media2rate(uint64_t mword)
1215 {
1216 	int i;
1217 	static const struct {
1218 		uint64_t subtype;
1219 		int rate;
1220 	} ieeerates[] = {
1221 		{ IFM_AUTO,		-1	},
1222 		{ IFM_MANUAL,		0	},
1223 		{ IFM_NONE,		0	},
1224 		{ IFM_IEEE80211_DS1,	2	},
1225 		{ IFM_IEEE80211_DS2,	4	},
1226 		{ IFM_IEEE80211_DS5,	11	},
1227 		{ IFM_IEEE80211_DS11,	22	},
1228 		{ IFM_IEEE80211_DS22,	44	},
1229 		{ IFM_IEEE80211_OFDM6,	12	},
1230 		{ IFM_IEEE80211_OFDM9,	18	},
1231 		{ IFM_IEEE80211_OFDM12,	24	},
1232 		{ IFM_IEEE80211_OFDM18,	36	},
1233 		{ IFM_IEEE80211_OFDM24,	48	},
1234 		{ IFM_IEEE80211_OFDM36,	72	},
1235 		{ IFM_IEEE80211_OFDM48,	96	},
1236 		{ IFM_IEEE80211_OFDM54,	108	},
1237 		{ IFM_IEEE80211_OFDM72,	144	},
1238 	};
1239 	for (i = 0; i < nitems(ieeerates); i++) {
1240 		if (ieeerates[i].subtype == IFM_SUBTYPE(mword))
1241 			return ieeerates[i].rate;
1242 	}
1243 	return 0;
1244 }
1245 
1246 /*
1247  * Convert bit rate (in 0.5Mbps units) to PLCP signal (R4-R1) and vice versa.
1248  */
1249 u_int8_t
1250 ieee80211_rate2plcp(u_int8_t rate, enum ieee80211_phymode mode)
1251 {
1252 	rate &= IEEE80211_RATE_VAL;
1253 
1254 	if (mode == IEEE80211_MODE_11B) {
1255 		/* IEEE Std 802.11b-1999 page 15, subclause 18.2.3.3 */
1256 		switch (rate) {
1257 		case 2:		return 10;
1258 		case 4:		return 20;
1259 		case 11:	return 55;
1260 		case 22:	return 110;
1261 		/* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */
1262 		case 44:	return 220;
1263 		}
1264 	} else if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11A) {
1265 		/* IEEE Std 802.11a-1999 page 14, subclause 17.3.4.1 */
1266 		switch (rate) {
1267 		case 12:	return 0x0b;
1268 		case 18:	return 0x0f;
1269 		case 24:	return 0x0a;
1270 		case 36:	return 0x0e;
1271 		case 48:	return 0x09;
1272 		case 72:	return 0x0d;
1273 		case 96:	return 0x08;
1274 		case 108:	return 0x0c;
1275 		}
1276         } else
1277 		panic("%s: unexpected mode %u", __func__, mode);
1278 
1279 	DPRINTF(("unsupported rate %u\n", rate));
1280 
1281 	return 0;
1282 }
1283 
1284 u_int8_t
1285 ieee80211_plcp2rate(u_int8_t plcp, enum ieee80211_phymode mode)
1286 {
1287 	if (mode == IEEE80211_MODE_11B) {
1288 		/* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */
1289 		switch (plcp) {
1290 		case 10:	return 2;
1291 		case 20:	return 4;
1292 		case 55:	return 11;
1293 		case 110:	return 22;
1294 		/* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */
1295 		case 220:	return 44;
1296 		}
1297 	} else if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11A) {
1298 		/* IEEE Std 802.11a-1999 page 14, subclause 17.3.4.1 */
1299 		switch (plcp) {
1300 		case 0x0b:	return 12;
1301 		case 0x0f:	return 18;
1302 		case 0x0a:	return 24;
1303 		case 0x0e:	return 36;
1304 		case 0x09:	return 48;
1305 		case 0x0d:	return 72;
1306 		case 0x08:	return 96;
1307 		case 0x0c:	return 108;
1308 		}
1309 	} else
1310 		panic("%s: unexpected mode %u", __func__, mode);
1311 
1312 	DPRINTF(("unsupported plcp %u\n", plcp));
1313 
1314 	return 0;
1315 }
1316