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