ieee80211.c revision 184278
1/*-
2 * Copyright (c) 2001 Atsushi Onoe
3 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/net80211/ieee80211.c 184278 2008-10-25 23:43:08Z sam $");
29
30/*
31 * IEEE 802.11 generic handler
32 */
33#include "opt_wlan.h"
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/kernel.h>
38
39#include <sys/socket.h>
40
41#include <net/if.h>
42#include <net/if_dl.h>
43#include <net/if_media.h>
44#include <net/if_types.h>
45#include <net/ethernet.h>
46
47#include <net80211/ieee80211_var.h>
48#include <net80211/ieee80211_regdomain.h>
49
50#include <net/bpf.h>
51
52const char *ieee80211_phymode_name[IEEE80211_MODE_MAX] = {
53	[IEEE80211_MODE_AUTO]	  = "auto",
54	[IEEE80211_MODE_11A]	  = "11a",
55	[IEEE80211_MODE_11B]	  = "11b",
56	[IEEE80211_MODE_11G]	  = "11g",
57	[IEEE80211_MODE_FH]	  = "FH",
58	[IEEE80211_MODE_TURBO_A]  = "turboA",
59	[IEEE80211_MODE_TURBO_G]  = "turboG",
60	[IEEE80211_MODE_STURBO_A] = "sturboA",
61	[IEEE80211_MODE_11NA]	  = "11na",
62	[IEEE80211_MODE_11NG]	  = "11ng",
63};
64/* map ieee80211_opmode to the corresponding capability bit */
65const int ieee80211_opcap[IEEE80211_OPMODE_MAX] = {
66	[IEEE80211_M_IBSS]	= IEEE80211_C_IBSS,
67	[IEEE80211_M_WDS]	= IEEE80211_C_WDS,
68	[IEEE80211_M_STA]	= IEEE80211_C_STA,
69	[IEEE80211_M_AHDEMO]	= IEEE80211_C_AHDEMO,
70	[IEEE80211_M_HOSTAP]	= IEEE80211_C_HOSTAP,
71	[IEEE80211_M_MONITOR]	= IEEE80211_C_MONITOR,
72};
73
74static const uint8_t ieee80211broadcastaddr[IEEE80211_ADDR_LEN] =
75	{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
76
77static	void ieee80211_syncflag_locked(struct ieee80211com *ic, int flag);
78static	void ieee80211_syncflag_ext_locked(struct ieee80211com *ic, int flag);
79static	int ieee80211_media_setup(struct ieee80211com *ic,
80		struct ifmedia *media, int caps, int addsta,
81		ifm_change_cb_t media_change, ifm_stat_cb_t media_stat);
82static	void ieee80211com_media_status(struct ifnet *, struct ifmediareq *);
83static	int ieee80211com_media_change(struct ifnet *);
84static	int media_status(enum ieee80211_opmode,
85		const struct ieee80211_channel *);
86
87MALLOC_DEFINE(M_80211_VAP, "80211vap", "802.11 vap state");
88
89/*
90 * Default supported rates for 802.11 operation (in IEEE .5Mb units).
91 */
92#define	B(r)	((r) | IEEE80211_RATE_BASIC)
93static const struct ieee80211_rateset ieee80211_rateset_11a =
94	{ 8, { B(12), 18, B(24), 36, B(48), 72, 96, 108 } };
95static const struct ieee80211_rateset ieee80211_rateset_half =
96	{ 8, { B(6), 9, B(12), 18, B(24), 36, 48, 54 } };
97static const struct ieee80211_rateset ieee80211_rateset_quarter =
98	{ 8, { B(3), 4, B(6), 9, B(12), 18, 24, 27 } };
99static const struct ieee80211_rateset ieee80211_rateset_11b =
100	{ 4, { B(2), B(4), B(11), B(22) } };
101/* NB: OFDM rates are handled specially based on mode */
102static const struct ieee80211_rateset ieee80211_rateset_11g =
103	{ 12, { B(2), B(4), B(11), B(22), 12, 18, 24, 36, 48, 72, 96, 108 } };
104#undef B
105
106/*
107 * Fill in 802.11 available channel set, mark
108 * all available channels as active, and pick
109 * a default channel if not already specified.
110 */
111static void
112ieee80211_chan_init(struct ieee80211com *ic)
113{
114#define	DEFAULTRATES(m, def) do { \
115	if (isset(ic->ic_modecaps, m) && ic->ic_sup_rates[m].rs_nrates == 0) \
116		ic->ic_sup_rates[m] = def; \
117} while (0)
118	struct ieee80211_channel *c;
119	int i;
120
121	KASSERT(0 < ic->ic_nchans && ic->ic_nchans < IEEE80211_CHAN_MAX,
122		("invalid number of channels specified: %u", ic->ic_nchans));
123	memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail));
124	memset(ic->ic_modecaps, 0, sizeof(ic->ic_modecaps));
125	setbit(ic->ic_modecaps, IEEE80211_MODE_AUTO);
126	for (i = 0; i < ic->ic_nchans; i++) {
127		c = &ic->ic_channels[i];
128		KASSERT(c->ic_flags != 0, ("channel with no flags"));
129		KASSERT(c->ic_ieee < IEEE80211_CHAN_MAX,
130			("channel with bogus ieee number %u", c->ic_ieee));
131		setbit(ic->ic_chan_avail, c->ic_ieee);
132		/*
133		 * Identify mode capabilities.
134		 */
135		if (IEEE80211_IS_CHAN_A(c))
136			setbit(ic->ic_modecaps, IEEE80211_MODE_11A);
137		if (IEEE80211_IS_CHAN_B(c))
138			setbit(ic->ic_modecaps, IEEE80211_MODE_11B);
139		if (IEEE80211_IS_CHAN_ANYG(c))
140			setbit(ic->ic_modecaps, IEEE80211_MODE_11G);
141		if (IEEE80211_IS_CHAN_FHSS(c))
142			setbit(ic->ic_modecaps, IEEE80211_MODE_FH);
143		if (IEEE80211_IS_CHAN_108A(c))
144			setbit(ic->ic_modecaps, IEEE80211_MODE_TURBO_A);
145		if (IEEE80211_IS_CHAN_108G(c))
146			setbit(ic->ic_modecaps, IEEE80211_MODE_TURBO_G);
147		if (IEEE80211_IS_CHAN_ST(c))
148			setbit(ic->ic_modecaps, IEEE80211_MODE_STURBO_A);
149		if (IEEE80211_IS_CHAN_HTA(c))
150			setbit(ic->ic_modecaps, IEEE80211_MODE_11NA);
151		if (IEEE80211_IS_CHAN_HTG(c))
152			setbit(ic->ic_modecaps, IEEE80211_MODE_11NG);
153	}
154	/* initialize candidate channels to all available */
155	memcpy(ic->ic_chan_active, ic->ic_chan_avail,
156		sizeof(ic->ic_chan_avail));
157
158	/* sort channel table to allow lookup optimizations */
159	ieee80211_sort_channels(ic->ic_channels, ic->ic_nchans);
160
161	/* invalidate any previous state */
162	ic->ic_bsschan = IEEE80211_CHAN_ANYC;
163	ic->ic_prevchan = NULL;
164	ic->ic_csa_newchan = NULL;
165	/* arbitrarily pick the first channel */
166	ic->ic_curchan = &ic->ic_channels[0];
167
168	/* fillin well-known rate sets if driver has not specified */
169	DEFAULTRATES(IEEE80211_MODE_11B,	 ieee80211_rateset_11b);
170	DEFAULTRATES(IEEE80211_MODE_11G,	 ieee80211_rateset_11g);
171	DEFAULTRATES(IEEE80211_MODE_11A,	 ieee80211_rateset_11a);
172	DEFAULTRATES(IEEE80211_MODE_TURBO_A,	 ieee80211_rateset_11a);
173	DEFAULTRATES(IEEE80211_MODE_TURBO_G,	 ieee80211_rateset_11g);
174
175	/*
176	 * Set auto mode to reset active channel state and any desired channel.
177	 */
178	(void) ieee80211_setmode(ic, IEEE80211_MODE_AUTO);
179#undef DEFAULTRATES
180}
181
182static void
183null_update_mcast(struct ifnet *ifp)
184{
185	if_printf(ifp, "need multicast update callback\n");
186}
187
188static void
189null_update_promisc(struct ifnet *ifp)
190{
191	if_printf(ifp, "need promiscuous mode update callback\n");
192}
193
194static int
195null_output(struct ifnet *ifp, struct mbuf *m,
196	struct sockaddr *dst, struct rtentry *rt0)
197{
198	if_printf(ifp, "discard raw packet\n");
199	m_freem(m);
200	return EIO;
201}
202
203static void
204null_input(struct ifnet *ifp, struct mbuf *m)
205{
206	if_printf(ifp, "if_input should not be called\n");
207	m_freem(m);
208}
209
210/*
211 * Attach/setup the common net80211 state.  Called by
212 * the driver on attach to prior to creating any vap's.
213 */
214void
215ieee80211_ifattach(struct ieee80211com *ic)
216{
217	struct ifnet *ifp = ic->ic_ifp;
218	struct sockaddr_dl *sdl;
219	struct ifaddr *ifa;
220
221	KASSERT(ifp->if_type == IFT_IEEE80211, ("if_type %d", ifp->if_type));
222
223	IEEE80211_LOCK_INIT(ic, ifp->if_xname);
224	TAILQ_INIT(&ic->ic_vaps);
225	/*
226	 * Fill in 802.11 available channel set, mark all
227	 * available channels as active, and pick a default
228	 * channel if not already specified.
229	 */
230	ieee80211_media_init(ic);
231
232	ic->ic_update_mcast = null_update_mcast;
233	ic->ic_update_promisc = null_update_promisc;
234
235	ic->ic_bintval = IEEE80211_BINTVAL_DEFAULT;
236	ic->ic_lintval = ic->ic_bintval;
237	ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX;
238
239	ieee80211_crypto_attach(ic);
240	ieee80211_node_attach(ic);
241	ieee80211_power_attach(ic);
242	ieee80211_proto_attach(ic);
243	ieee80211_ht_attach(ic);
244	ieee80211_scan_attach(ic);
245	ieee80211_regdomain_attach(ic);
246
247	ieee80211_sysctl_attach(ic);
248
249	ifp->if_addrlen = IEEE80211_ADDR_LEN;
250	ifp->if_hdrlen = 0;
251	if_attach(ifp);
252	ifp->if_mtu = IEEE80211_MTU_MAX;
253	ifp->if_broadcastaddr = ieee80211broadcastaddr;
254	ifp->if_output = null_output;
255	ifp->if_input = null_input;	/* just in case */
256	ifp->if_resolvemulti = NULL;	/* NB: callers check */
257
258	ifa = ifaddr_byindex(ifp->if_index);
259	KASSERT(ifa != NULL, ("%s: no lladdr!\n", __func__));
260	sdl = (struct sockaddr_dl *)ifa->ifa_addr;
261	sdl->sdl_type = IFT_ETHER;		/* XXX IFT_IEEE80211? */
262	sdl->sdl_alen = IEEE80211_ADDR_LEN;
263	IEEE80211_ADDR_COPY(LLADDR(sdl), ic->ic_myaddr);
264}
265
266/*
267 * Detach net80211 state on device detach.  Tear down
268 * all vap's and reclaim all common state prior to the
269 * device state going away.  Note we may call back into
270 * driver; it must be prepared for this.
271 */
272void
273ieee80211_ifdetach(struct ieee80211com *ic)
274{
275	struct ifnet *ifp = ic->ic_ifp;
276	struct ieee80211vap *vap;
277
278	/* XXX ieee80211_stop_all? */
279	while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL)
280		ieee80211_vap_destroy(vap);
281
282	ieee80211_sysctl_detach(ic);
283	ieee80211_regdomain_detach(ic);
284	ieee80211_scan_detach(ic);
285	ieee80211_ht_detach(ic);
286	/* NB: must be called before ieee80211_node_detach */
287	ieee80211_proto_detach(ic);
288	ieee80211_crypto_detach(ic);
289	ieee80211_power_detach(ic);
290	ieee80211_node_detach(ic);
291	ifmedia_removeall(&ic->ic_media);
292
293	IEEE80211_LOCK_DESTROY(ic);
294	if_detach(ifp);
295}
296
297/*
298 * Default reset method for use with the ioctl support.  This
299 * method is invoked after any state change in the 802.11
300 * layer that should be propagated to the hardware but not
301 * require re-initialization of the 802.11 state machine (e.g
302 * rescanning for an ap).  We always return ENETRESET which
303 * should cause the driver to re-initialize the device. Drivers
304 * can override this method to implement more optimized support.
305 */
306static int
307default_reset(struct ieee80211vap *vap, u_long cmd)
308{
309	return ENETRESET;
310}
311
312/*
313 * Prepare a vap for use.  Drivers use this call to
314 * setup net80211 state in new vap's prior attaching
315 * them with ieee80211_vap_attach (below).
316 */
317int
318ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
319	const char name[IFNAMSIZ], int unit, int opmode, int flags,
320	const uint8_t bssid[IEEE80211_ADDR_LEN],
321	const uint8_t macaddr[IEEE80211_ADDR_LEN])
322{
323	struct ifnet *ifp;
324
325	ifp = if_alloc(IFT_ETHER);
326	if (ifp == NULL) {
327		if_printf(ic->ic_ifp, "%s: unable to allocate ifnet\n",
328		    __func__);
329		return ENOMEM;
330	}
331	if_initname(ifp, name, unit);
332	ifp->if_softc = vap;			/* back pointer */
333	ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
334	ifp->if_start = ieee80211_start;
335	ifp->if_ioctl = ieee80211_ioctl;
336	ifp->if_watchdog = NULL;		/* NB: no watchdog routine */
337	ifp->if_init = ieee80211_init;
338	/* NB: input+output filled in by ether_ifattach */
339	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
340	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
341	IFQ_SET_READY(&ifp->if_snd);
342
343	vap->iv_ifp = ifp;
344	vap->iv_ic = ic;
345	vap->iv_flags = ic->ic_flags;		/* propagate common flags */
346	vap->iv_flags_ext = ic->ic_flags_ext;
347	vap->iv_flags_ven = ic->ic_flags_ven;
348	vap->iv_caps = ic->ic_caps &~ IEEE80211_C_OPMODE;
349	vap->iv_htcaps = ic->ic_htcaps;
350	vap->iv_opmode = opmode;
351	vap->iv_caps |= ieee80211_opcap[opmode];
352	switch (opmode) {
353	case IEEE80211_M_WDS:
354		/*
355		 * WDS links must specify the bssid of the far end.
356		 * For legacy operation this is a static relationship.
357		 * For non-legacy operation the station must associate
358		 * and be authorized to pass traffic.  Plumbing the
359		 * vap to the proper node happens when the vap
360		 * transitions to RUN state.
361		 */
362		IEEE80211_ADDR_COPY(vap->iv_des_bssid, bssid);
363		vap->iv_flags |= IEEE80211_F_DESBSSID;
364		if (flags & IEEE80211_CLONE_WDSLEGACY)
365			vap->iv_flags_ext |= IEEE80211_FEXT_WDSLEGACY;
366		break;
367	}
368	/* auto-enable s/w beacon miss support */
369	if (flags & IEEE80211_CLONE_NOBEACONS)
370		vap->iv_flags_ext |= IEEE80211_FEXT_SWBMISS;
371	/*
372	 * Enable various functionality by default if we're
373	 * capable; the driver can override us if it knows better.
374	 */
375	if (vap->iv_caps & IEEE80211_C_WME)
376		vap->iv_flags |= IEEE80211_F_WME;
377	if (vap->iv_caps & IEEE80211_C_BURST)
378		vap->iv_flags |= IEEE80211_F_BURST;
379	if (vap->iv_caps & IEEE80211_C_FF)
380		vap->iv_flags |= IEEE80211_F_FF;
381	if (vap->iv_caps & IEEE80211_C_TURBOP)
382		vap->iv_flags |= IEEE80211_F_TURBOP;
383	/* NB: bg scanning only makes sense for station mode right now */
384	if (vap->iv_opmode == IEEE80211_M_STA &&
385	    (vap->iv_caps & IEEE80211_C_BGSCAN))
386		vap->iv_flags |= IEEE80211_F_BGSCAN;
387	vap->iv_flags |= IEEE80211_F_DOTH;	/* XXX no cap, just ena */
388	/* NB: DFS support only makes sense for ap mode right now */
389	if (vap->iv_opmode == IEEE80211_M_HOSTAP &&
390	    (vap->iv_caps & IEEE80211_C_DFS))
391		vap->iv_flags_ext |= IEEE80211_FEXT_DFS;
392
393	vap->iv_des_chan = IEEE80211_CHAN_ANYC;		/* any channel is ok */
394	vap->iv_bmissthreshold = IEEE80211_HWBMISS_DEFAULT;
395	vap->iv_dtim_period = IEEE80211_DTIM_DEFAULT;
396	/*
397	 * Install a default reset method for the ioctl support;
398	 * the driver can override this.
399	 */
400	vap->iv_reset = default_reset;
401
402	IEEE80211_ADDR_COPY(vap->iv_myaddr, macaddr);
403
404	ieee80211_sysctl_vattach(vap);
405	ieee80211_crypto_vattach(vap);
406	ieee80211_node_vattach(vap);
407	ieee80211_power_vattach(vap);
408	ieee80211_proto_vattach(vap);
409	ieee80211_ht_vattach(vap);
410	ieee80211_scan_vattach(vap);
411	ieee80211_regdomain_vattach(vap);
412
413	return 0;
414}
415
416/*
417 * Activate a vap.  State should have been prepared with a
418 * call to ieee80211_vap_setup and by the driver.  On return
419 * from this call the vap is ready for use.
420 */
421int
422ieee80211_vap_attach(struct ieee80211vap *vap,
423	ifm_change_cb_t media_change, ifm_stat_cb_t media_stat)
424{
425	struct ifnet *ifp = vap->iv_ifp;
426	struct ieee80211com *ic = vap->iv_ic;
427	struct ifmediareq imr;
428	int maxrate;
429
430	IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,
431	    "%s: %s parent %s flags 0x%x flags_ext 0x%x\n",
432	    __func__, ieee80211_opmode_name[vap->iv_opmode],
433	    ic->ic_ifp->if_xname, vap->iv_flags, vap->iv_flags_ext);
434
435	/*
436	 * Do late attach work that cannot happen until after
437	 * the driver has had a chance to override defaults.
438	 */
439	ieee80211_node_latevattach(vap);
440	ieee80211_power_latevattach(vap);
441
442	maxrate = ieee80211_media_setup(ic, &vap->iv_media, vap->iv_caps,
443	    vap->iv_opmode == IEEE80211_M_STA, media_change, media_stat);
444	ieee80211_media_status(ifp, &imr);
445	/* NB: strip explicit mode; we're actually in autoselect */
446	ifmedia_set(&vap->iv_media, imr.ifm_active &~ IFM_MMASK);
447	if (maxrate)
448		ifp->if_baudrate = IF_Mbps(maxrate);
449
450	ether_ifattach(ifp, vap->iv_myaddr);
451	/* hook output method setup by ether_ifattach */
452	vap->iv_output = ifp->if_output;
453	ifp->if_output = ieee80211_output;
454	/* NB: if_mtu set by ether_ifattach to ETHERMTU */
455	bpfattach2(ifp, DLT_IEEE802_11, ifp->if_hdrlen, &vap->iv_rawbpf);
456
457	IEEE80211_LOCK(ic);
458	TAILQ_INSERT_TAIL(&ic->ic_vaps, vap, iv_next);
459	ieee80211_syncflag_locked(ic, IEEE80211_F_WME);
460	ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP);
461	ieee80211_syncflag_locked(ic, IEEE80211_F_PCF);
462	ieee80211_syncflag_locked(ic, IEEE80211_F_BURST);
463	ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_HT);
464	ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_USEHT40);
465	ieee80211_syncifflag_locked(ic, IFF_PROMISC);
466	ieee80211_syncifflag_locked(ic, IFF_ALLMULTI);
467	IEEE80211_UNLOCK(ic);
468
469	return 1;
470}
471
472/*
473 * Tear down vap state and reclaim the ifnet.
474 * The driver is assumed to have prepared for
475 * this; e.g. by turning off interrupts for the
476 * underlying device.
477 */
478void
479ieee80211_vap_detach(struct ieee80211vap *vap)
480{
481	struct ieee80211com *ic = vap->iv_ic;
482	struct ifnet *ifp = vap->iv_ifp;
483
484	IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s parent %s\n",
485	    __func__, ieee80211_opmode_name[vap->iv_opmode],
486	    ic->ic_ifp->if_xname);
487
488	IEEE80211_LOCK(ic);
489	/* block traffic from above */
490	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
491	/*
492	 * Evil hack.  Clear the backpointer from the ifnet to the
493	 * vap so any requests from above will return an error or
494	 * be ignored.  In particular this short-circuits requests
495	 * by the bridge to turn off promiscuous mode as a result
496	 * of calling ether_ifdetach.
497	 */
498	ifp->if_softc = NULL;
499	/*
500	 * Stop the vap before detaching the ifnet.  Ideally we'd
501	 * do this in the other order so the ifnet is inaccessible
502	 * while we cleanup internal state but that is hard.
503	 */
504	ieee80211_stop_locked(vap);
505
506	/* XXX accumulate iv_stats in ic_stats? */
507	TAILQ_REMOVE(&ic->ic_vaps, vap, iv_next);
508	ieee80211_syncflag_locked(ic, IEEE80211_F_WME);
509	ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP);
510	ieee80211_syncflag_locked(ic, IEEE80211_F_PCF);
511	ieee80211_syncflag_locked(ic, IEEE80211_F_BURST);
512	ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_HT);
513	ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_USEHT40);
514	ieee80211_syncifflag_locked(ic, IFF_PROMISC);
515	ieee80211_syncifflag_locked(ic, IFF_ALLMULTI);
516	IEEE80211_UNLOCK(ic);
517
518	/* XXX can't hold com lock */
519	/* NB: bpfattach is called by ether_ifdetach and claims all taps */
520	ether_ifdetach(ifp);
521
522	ifmedia_removeall(&vap->iv_media);
523
524	ieee80211_regdomain_vdetach(vap);
525	ieee80211_scan_vdetach(vap);
526	ieee80211_ht_vdetach(vap);
527	/* NB: must be before ieee80211_node_vdetach */
528	ieee80211_proto_vdetach(vap);
529	ieee80211_crypto_vdetach(vap);
530	ieee80211_power_vdetach(vap);
531	ieee80211_node_vdetach(vap);
532	ieee80211_sysctl_vdetach(vap);
533
534	if_free(ifp);
535}
536
537/*
538 * Synchronize flag bit state in the parent ifnet structure
539 * according to the state of all vap ifnet's.  This is used,
540 * for example, to handle IFF_PROMISC and IFF_ALLMULTI.
541 */
542void
543ieee80211_syncifflag_locked(struct ieee80211com *ic, int flag)
544{
545	struct ifnet *ifp = ic->ic_ifp;
546	struct ieee80211vap *vap;
547	int bit, oflags;
548
549	IEEE80211_LOCK_ASSERT(ic);
550
551	bit = 0;
552	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
553		if (vap->iv_ifp->if_flags & flag) {
554			/*
555			 * XXX the bridge sets PROMISC but we don't want to
556			 * enable it on the device, discard here so all the
557			 * drivers don't need to special-case it
558			 */
559			if (flag == IFF_PROMISC &&
560			    vap->iv_opmode == IEEE80211_M_HOSTAP)
561				continue;
562			bit = 1;
563			break;
564		}
565	oflags = ifp->if_flags;
566	if (bit)
567		ifp->if_flags |= flag;
568	else
569		ifp->if_flags &= ~flag;
570	if ((ifp->if_flags ^ oflags) & flag) {
571		/* XXX should we return 1/0 and let caller do this? */
572		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
573			if (flag == IFF_PROMISC)
574				ic->ic_update_promisc(ifp);
575			else if (flag == IFF_ALLMULTI)
576				ic->ic_update_mcast(ifp);
577		}
578	}
579}
580
581/*
582 * Synchronize flag bit state in the com structure
583 * according to the state of all vap's.  This is used,
584 * for example, to handle state changes via ioctls.
585 */
586static void
587ieee80211_syncflag_locked(struct ieee80211com *ic, int flag)
588{
589	struct ieee80211vap *vap;
590	int bit;
591
592	IEEE80211_LOCK_ASSERT(ic);
593
594	bit = 0;
595	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
596		if (vap->iv_flags & flag) {
597			bit = 1;
598			break;
599		}
600	if (bit)
601		ic->ic_flags |= flag;
602	else
603		ic->ic_flags &= ~flag;
604}
605
606void
607ieee80211_syncflag(struct ieee80211vap *vap, int flag)
608{
609	struct ieee80211com *ic = vap->iv_ic;
610
611	IEEE80211_LOCK(ic);
612	if (flag < 0) {
613		flag = -flag;
614		vap->iv_flags &= ~flag;
615	} else
616		vap->iv_flags |= flag;
617	ieee80211_syncflag_locked(ic, flag);
618	IEEE80211_UNLOCK(ic);
619}
620
621/*
622 * Synchronize flag bit state in the com structure
623 * according to the state of all vap's.  This is used,
624 * for example, to handle state changes via ioctls.
625 */
626static void
627ieee80211_syncflag_ext_locked(struct ieee80211com *ic, int flag)
628{
629	struct ieee80211vap *vap;
630	int bit;
631
632	IEEE80211_LOCK_ASSERT(ic);
633
634	bit = 0;
635	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
636		if (vap->iv_flags_ext & flag) {
637			bit = 1;
638			break;
639		}
640	if (bit)
641		ic->ic_flags_ext |= flag;
642	else
643		ic->ic_flags_ext &= ~flag;
644}
645
646void
647ieee80211_syncflag_ext(struct ieee80211vap *vap, int flag)
648{
649	struct ieee80211com *ic = vap->iv_ic;
650
651	IEEE80211_LOCK(ic);
652	if (flag < 0) {
653		flag = -flag;
654		vap->iv_flags_ext &= ~flag;
655	} else
656		vap->iv_flags_ext |= flag;
657	ieee80211_syncflag_ext_locked(ic, flag);
658	IEEE80211_UNLOCK(ic);
659}
660
661static __inline int
662mapgsm(u_int freq, u_int flags)
663{
664	freq *= 10;
665	if (flags & IEEE80211_CHAN_QUARTER)
666		freq += 5;
667	else if (flags & IEEE80211_CHAN_HALF)
668		freq += 10;
669	else
670		freq += 20;
671	/* NB: there is no 907/20 wide but leave room */
672	return (freq - 906*10) / 5;
673}
674
675static __inline int
676mappsb(u_int freq, u_int flags)
677{
678	return 37 + ((freq * 10) + ((freq % 5) == 2 ? 5 : 0) - 49400) / 5;
679}
680
681/*
682 * Convert MHz frequency to IEEE channel number.
683 */
684int
685ieee80211_mhz2ieee(u_int freq, u_int flags)
686{
687#define	IS_FREQ_IN_PSB(_freq) ((_freq) > 4940 && (_freq) < 4990)
688	if (flags & IEEE80211_CHAN_GSM)
689		return mapgsm(freq, flags);
690	if (flags & IEEE80211_CHAN_2GHZ) {	/* 2GHz band */
691		if (freq == 2484)
692			return 14;
693		if (freq < 2484)
694			return ((int) freq - 2407) / 5;
695		else
696			return 15 + ((freq - 2512) / 20);
697	} else if (flags & IEEE80211_CHAN_5GHZ) {	/* 5Ghz band */
698		if (freq <= 5000) {
699			/* XXX check regdomain? */
700			if (IS_FREQ_IN_PSB(freq))
701				return mappsb(freq, flags);
702			return (freq - 4000) / 5;
703		} else
704			return (freq - 5000) / 5;
705	} else {				/* either, guess */
706		if (freq == 2484)
707			return 14;
708		if (freq < 2484) {
709			if (907 <= freq && freq <= 922)
710				return mapgsm(freq, flags);
711			return ((int) freq - 2407) / 5;
712		}
713		if (freq < 5000) {
714			if (IS_FREQ_IN_PSB(freq))
715				return mappsb(freq, flags);
716			else if (freq > 4900)
717				return (freq - 4000) / 5;
718			else
719				return 15 + ((freq - 2512) / 20);
720		}
721		return (freq - 5000) / 5;
722	}
723#undef IS_FREQ_IN_PSB
724}
725
726/*
727 * Convert channel to IEEE channel number.
728 */
729int
730ieee80211_chan2ieee(struct ieee80211com *ic, const struct ieee80211_channel *c)
731{
732	if (c == NULL) {
733		if_printf(ic->ic_ifp, "invalid channel (NULL)\n");
734		return 0;		/* XXX */
735	}
736	return (c == IEEE80211_CHAN_ANYC ?  IEEE80211_CHAN_ANY : c->ic_ieee);
737}
738
739/*
740 * Convert IEEE channel number to MHz frequency.
741 */
742u_int
743ieee80211_ieee2mhz(u_int chan, u_int flags)
744{
745	if (flags & IEEE80211_CHAN_GSM)
746		return 907 + 5 * (chan / 10);
747	if (flags & IEEE80211_CHAN_2GHZ) {	/* 2GHz band */
748		if (chan == 14)
749			return 2484;
750		if (chan < 14)
751			return 2407 + chan*5;
752		else
753			return 2512 + ((chan-15)*20);
754	} else if (flags & IEEE80211_CHAN_5GHZ) {/* 5Ghz band */
755		if (flags & (IEEE80211_CHAN_HALF|IEEE80211_CHAN_QUARTER)) {
756			chan -= 37;
757			return 4940 + chan*5 + (chan % 5 ? 2 : 0);
758		}
759		return 5000 + (chan*5);
760	} else {				/* either, guess */
761		/* XXX can't distinguish PSB+GSM channels */
762		if (chan == 14)
763			return 2484;
764		if (chan < 14)			/* 0-13 */
765			return 2407 + chan*5;
766		if (chan < 27)			/* 15-26 */
767			return 2512 + ((chan-15)*20);
768		return 5000 + (chan*5);
769	}
770}
771
772/*
773 * Locate a channel given a frequency+flags.  We cache
774 * the previous lookup to optimize switching between two
775 * channels--as happens with dynamic turbo.
776 */
777struct ieee80211_channel *
778ieee80211_find_channel(struct ieee80211com *ic, int freq, int flags)
779{
780	struct ieee80211_channel *c;
781	int i;
782
783	flags &= IEEE80211_CHAN_ALLTURBO;
784	c = ic->ic_prevchan;
785	if (c != NULL && c->ic_freq == freq &&
786	    (c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags)
787		return c;
788	/* brute force search */
789	for (i = 0; i < ic->ic_nchans; i++) {
790		c = &ic->ic_channels[i];
791		if (c->ic_freq == freq &&
792		    (c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags)
793			return c;
794	}
795	return NULL;
796}
797
798/*
799 * Locate a channel given a channel number+flags.  We cache
800 * the previous lookup to optimize switching between two
801 * channels--as happens with dynamic turbo.
802 */
803struct ieee80211_channel *
804ieee80211_find_channel_byieee(struct ieee80211com *ic, int ieee, int flags)
805{
806	struct ieee80211_channel *c;
807	int i;
808
809	flags &= IEEE80211_CHAN_ALLTURBO;
810	c = ic->ic_prevchan;
811	if (c != NULL && c->ic_ieee == ieee &&
812	    (c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags)
813		return c;
814	/* brute force search */
815	for (i = 0; i < ic->ic_nchans; i++) {
816		c = &ic->ic_channels[i];
817		if (c->ic_ieee == ieee &&
818		    (c->ic_flags & IEEE80211_CHAN_ALLTURBO) == flags)
819			return c;
820	}
821	return NULL;
822}
823
824static void
825addmedia(struct ifmedia *media, int caps, int addsta, int mode, int mword)
826{
827#define	ADD(_ic, _s, _o) \
828	ifmedia_add(media, \
829		IFM_MAKEWORD(IFM_IEEE80211, (_s), (_o), 0), 0, NULL)
830	static const u_int mopts[IEEE80211_MODE_MAX] = {
831		IFM_AUTO,
832		IFM_IEEE80211_11A,
833		IFM_IEEE80211_11B,
834		IFM_IEEE80211_11G,
835		IFM_IEEE80211_FH,
836		IFM_IEEE80211_11A | IFM_IEEE80211_TURBO,
837		IFM_IEEE80211_11G | IFM_IEEE80211_TURBO,
838		IFM_IEEE80211_11A | IFM_IEEE80211_TURBO,
839		IFM_IEEE80211_11NA,
840		IFM_IEEE80211_11NG,
841	};
842	u_int mopt;
843
844	mopt = mopts[mode];
845	if (addsta)
846		ADD(ic, mword, mopt);	/* STA mode has no cap */
847	if (caps & IEEE80211_C_IBSS)
848		ADD(media, mword, mopt | IFM_IEEE80211_ADHOC);
849	if (caps & IEEE80211_C_HOSTAP)
850		ADD(media, mword, mopt | IFM_IEEE80211_HOSTAP);
851	if (caps & IEEE80211_C_AHDEMO)
852		ADD(media, mword, mopt | IFM_IEEE80211_ADHOC | IFM_FLAG0);
853	if (caps & IEEE80211_C_MONITOR)
854		ADD(media, mword, mopt | IFM_IEEE80211_MONITOR);
855	if (caps & IEEE80211_C_WDS)
856		ADD(media, mword, mopt | IFM_IEEE80211_WDS);
857#undef ADD
858}
859
860/*
861 * Setup the media data structures according to the channel and
862 * rate tables.
863 */
864static int
865ieee80211_media_setup(struct ieee80211com *ic,
866	struct ifmedia *media, int caps, int addsta,
867	ifm_change_cb_t media_change, ifm_stat_cb_t media_stat)
868{
869	int i, j, mode, rate, maxrate, mword, r;
870	const struct ieee80211_rateset *rs;
871	struct ieee80211_rateset allrates;
872
873	/*
874	 * Fill in media characteristics.
875	 */
876	ifmedia_init(media, 0, media_change, media_stat);
877	maxrate = 0;
878	/*
879	 * Add media for legacy operating modes.
880	 */
881	memset(&allrates, 0, sizeof(allrates));
882	for (mode = IEEE80211_MODE_AUTO; mode < IEEE80211_MODE_11NA; mode++) {
883		if (isclr(ic->ic_modecaps, mode))
884			continue;
885		addmedia(media, caps, addsta, mode, IFM_AUTO);
886		if (mode == IEEE80211_MODE_AUTO)
887			continue;
888		rs = &ic->ic_sup_rates[mode];
889		for (i = 0; i < rs->rs_nrates; i++) {
890			rate = rs->rs_rates[i];
891			mword = ieee80211_rate2media(ic, rate, mode);
892			if (mword == 0)
893				continue;
894			addmedia(media, caps, addsta, mode, mword);
895			/*
896			 * Add legacy rate to the collection of all rates.
897			 */
898			r = rate & IEEE80211_RATE_VAL;
899			for (j = 0; j < allrates.rs_nrates; j++)
900				if (allrates.rs_rates[j] == r)
901					break;
902			if (j == allrates.rs_nrates) {
903				/* unique, add to the set */
904				allrates.rs_rates[j] = r;
905				allrates.rs_nrates++;
906			}
907			rate = (rate & IEEE80211_RATE_VAL) / 2;
908			if (rate > maxrate)
909				maxrate = rate;
910		}
911	}
912	for (i = 0; i < allrates.rs_nrates; i++) {
913		mword = ieee80211_rate2media(ic, allrates.rs_rates[i],
914				IEEE80211_MODE_AUTO);
915		if (mword == 0)
916			continue;
917		/* NB: remove media options from mword */
918		addmedia(media, caps, addsta,
919		    IEEE80211_MODE_AUTO, IFM_SUBTYPE(mword));
920	}
921	/*
922	 * Add HT/11n media.  Note that we do not have enough
923	 * bits in the media subtype to express the MCS so we
924	 * use a "placeholder" media subtype and any fixed MCS
925	 * must be specified with a different mechanism.
926	 */
927	for (; mode < IEEE80211_MODE_MAX; mode++) {
928		if (isclr(ic->ic_modecaps, mode))
929			continue;
930		addmedia(media, caps, addsta, mode, IFM_AUTO);
931		addmedia(media, caps, addsta, mode, IFM_IEEE80211_MCS);
932	}
933	if (isset(ic->ic_modecaps, IEEE80211_MODE_11NA) ||
934	    isset(ic->ic_modecaps, IEEE80211_MODE_11NG)) {
935		addmedia(media, caps, addsta,
936		    IEEE80211_MODE_AUTO, IFM_IEEE80211_MCS);
937		/* XXX could walk htrates */
938		/* XXX known array size */
939		if (ieee80211_htrates[15].ht40_rate_400ns > maxrate)
940			maxrate = ieee80211_htrates[15].ht40_rate_400ns;
941	}
942	return maxrate;
943}
944
945void
946ieee80211_media_init(struct ieee80211com *ic)
947{
948	struct ifnet *ifp = ic->ic_ifp;
949	int maxrate;
950
951	/* NB: this works because the structure is initialized to zero */
952	if (!LIST_EMPTY(&ic->ic_media.ifm_list)) {
953		/*
954		 * We are re-initializing the channel list; clear
955		 * the existing media state as the media routines
956		 * don't suppress duplicates.
957		 */
958		ifmedia_removeall(&ic->ic_media);
959	}
960	ieee80211_chan_init(ic);
961
962	/*
963	 * Recalculate media settings in case new channel list changes
964	 * the set of available modes.
965	 */
966	maxrate = ieee80211_media_setup(ic, &ic->ic_media, ic->ic_caps, 1,
967		ieee80211com_media_change, ieee80211com_media_status);
968	/* NB: strip explicit mode; we're actually in autoselect */
969	ifmedia_set(&ic->ic_media,
970		media_status(ic->ic_opmode, ic->ic_curchan) &~ IFM_MMASK);
971	if (maxrate)
972		ifp->if_baudrate = IF_Mbps(maxrate);
973
974	/* XXX need to propagate new media settings to vap's */
975}
976
977const struct ieee80211_rateset *
978ieee80211_get_suprates(struct ieee80211com *ic, const struct ieee80211_channel *c)
979{
980	if (IEEE80211_IS_CHAN_HALF(c))
981		return &ieee80211_rateset_half;
982	if (IEEE80211_IS_CHAN_QUARTER(c))
983		return &ieee80211_rateset_quarter;
984	if (IEEE80211_IS_CHAN_HTA(c))
985		return &ic->ic_sup_rates[IEEE80211_MODE_11A];
986	if (IEEE80211_IS_CHAN_HTG(c)) {
987		/* XXX does this work for basic rates? */
988		return &ic->ic_sup_rates[IEEE80211_MODE_11G];
989	}
990	return &ic->ic_sup_rates[ieee80211_chan2mode(c)];
991}
992
993void
994ieee80211_announce(struct ieee80211com *ic)
995{
996	struct ifnet *ifp = ic->ic_ifp;
997	int i, mode, rate, mword;
998	const struct ieee80211_rateset *rs;
999
1000	/* NB: skip AUTO since it has no rates */
1001	for (mode = IEEE80211_MODE_AUTO+1; mode < IEEE80211_MODE_11NA; mode++) {
1002		if (isclr(ic->ic_modecaps, mode))
1003			continue;
1004		if_printf(ifp, "%s rates: ", ieee80211_phymode_name[mode]);
1005		rs = &ic->ic_sup_rates[mode];
1006		for (i = 0; i < rs->rs_nrates; i++) {
1007			mword = ieee80211_rate2media(ic, rs->rs_rates[i], mode);
1008			if (mword == 0)
1009				continue;
1010			rate = ieee80211_media2rate(mword);
1011			printf("%s%d%sMbps", (i != 0 ? " " : ""),
1012			    rate / 2, ((rate & 0x1) != 0 ? ".5" : ""));
1013		}
1014		printf("\n");
1015	}
1016	ieee80211_ht_announce(ic);
1017}
1018
1019void
1020ieee80211_announce_channels(struct ieee80211com *ic)
1021{
1022	const struct ieee80211_channel *c;
1023	char type;
1024	int i, cw;
1025
1026	printf("Chan  Freq  CW  RegPwr  MinPwr  MaxPwr\n");
1027	for (i = 0; i < ic->ic_nchans; i++) {
1028		c = &ic->ic_channels[i];
1029		if (IEEE80211_IS_CHAN_ST(c))
1030			type = 'S';
1031		else if (IEEE80211_IS_CHAN_108A(c))
1032			type = 'T';
1033		else if (IEEE80211_IS_CHAN_108G(c))
1034			type = 'G';
1035		else if (IEEE80211_IS_CHAN_HT(c))
1036			type = 'n';
1037		else if (IEEE80211_IS_CHAN_A(c))
1038			type = 'a';
1039		else if (IEEE80211_IS_CHAN_ANYG(c))
1040			type = 'g';
1041		else if (IEEE80211_IS_CHAN_B(c))
1042			type = 'b';
1043		else
1044			type = 'f';
1045		if (IEEE80211_IS_CHAN_HT40(c) || IEEE80211_IS_CHAN_TURBO(c))
1046			cw = 40;
1047		else if (IEEE80211_IS_CHAN_HALF(c))
1048			cw = 10;
1049		else if (IEEE80211_IS_CHAN_QUARTER(c))
1050			cw = 5;
1051		else
1052			cw = 20;
1053		printf("%4d  %4d%c %2d%c %6d  %4d.%d  %4d.%d\n"
1054			, c->ic_ieee, c->ic_freq, type
1055			, cw
1056			, IEEE80211_IS_CHAN_HT40U(c) ? '+' :
1057			  IEEE80211_IS_CHAN_HT40D(c) ? '-' : ' '
1058			, c->ic_maxregpower
1059			, c->ic_minpower / 2, c->ic_minpower & 1 ? 5 : 0
1060			, c->ic_maxpower / 2, c->ic_maxpower & 1 ? 5 : 0
1061		);
1062	}
1063}
1064
1065static int
1066media2mode(const struct ifmedia_entry *ime, uint32_t flags, uint16_t *mode)
1067{
1068	switch (IFM_MODE(ime->ifm_media)) {
1069	case IFM_IEEE80211_11A:
1070		*mode = IEEE80211_MODE_11A;
1071		break;
1072	case IFM_IEEE80211_11B:
1073		*mode = IEEE80211_MODE_11B;
1074		break;
1075	case IFM_IEEE80211_11G:
1076		*mode = IEEE80211_MODE_11G;
1077		break;
1078	case IFM_IEEE80211_FH:
1079		*mode = IEEE80211_MODE_FH;
1080		break;
1081	case IFM_IEEE80211_11NA:
1082		*mode = IEEE80211_MODE_11NA;
1083		break;
1084	case IFM_IEEE80211_11NG:
1085		*mode = IEEE80211_MODE_11NG;
1086		break;
1087	case IFM_AUTO:
1088		*mode = IEEE80211_MODE_AUTO;
1089		break;
1090	default:
1091		return 0;
1092	}
1093	/*
1094	 * Turbo mode is an ``option''.
1095	 * XXX does not apply to AUTO
1096	 */
1097	if (ime->ifm_media & IFM_IEEE80211_TURBO) {
1098		if (*mode == IEEE80211_MODE_11A) {
1099			if (flags & IEEE80211_F_TURBOP)
1100				*mode = IEEE80211_MODE_TURBO_A;
1101			else
1102				*mode = IEEE80211_MODE_STURBO_A;
1103		} else if (*mode == IEEE80211_MODE_11G)
1104			*mode = IEEE80211_MODE_TURBO_G;
1105		else
1106			return 0;
1107	}
1108	/* XXX HT40 +/- */
1109	return 1;
1110}
1111
1112/*
1113 * Handle a media change request on the underlying interface.
1114 */
1115int
1116ieee80211com_media_change(struct ifnet *ifp)
1117{
1118	return EINVAL;
1119}
1120
1121/*
1122 * Handle a media change request on the vap interface.
1123 */
1124int
1125ieee80211_media_change(struct ifnet *ifp)
1126{
1127	struct ieee80211vap *vap = ifp->if_softc;
1128	struct ifmedia_entry *ime = vap->iv_media.ifm_cur;
1129	uint16_t newmode;
1130
1131	if (!media2mode(ime, vap->iv_flags, &newmode))
1132		return EINVAL;
1133	if (vap->iv_des_mode != newmode) {
1134		vap->iv_des_mode = newmode;
1135		return ENETRESET;
1136	}
1137	return 0;
1138}
1139
1140/*
1141 * Common code to calculate the media status word
1142 * from the operating mode and channel state.
1143 */
1144static int
1145media_status(enum ieee80211_opmode opmode, const struct ieee80211_channel *chan)
1146{
1147	int status;
1148
1149	status = IFM_IEEE80211;
1150	switch (opmode) {
1151	case IEEE80211_M_STA:
1152		break;
1153	case IEEE80211_M_IBSS:
1154		status |= IFM_IEEE80211_ADHOC;
1155		break;
1156	case IEEE80211_M_HOSTAP:
1157		status |= IFM_IEEE80211_HOSTAP;
1158		break;
1159	case IEEE80211_M_MONITOR:
1160		status |= IFM_IEEE80211_MONITOR;
1161		break;
1162	case IEEE80211_M_AHDEMO:
1163		status |= IFM_IEEE80211_ADHOC | IFM_FLAG0;
1164		break;
1165	case IEEE80211_M_WDS:
1166		status |= IFM_IEEE80211_WDS;
1167		break;
1168	}
1169	if (IEEE80211_IS_CHAN_HTA(chan)) {
1170		status |= IFM_IEEE80211_11NA;
1171	} else if (IEEE80211_IS_CHAN_HTG(chan)) {
1172		status |= IFM_IEEE80211_11NG;
1173	} else if (IEEE80211_IS_CHAN_A(chan)) {
1174		status |= IFM_IEEE80211_11A;
1175	} else if (IEEE80211_IS_CHAN_B(chan)) {
1176		status |= IFM_IEEE80211_11B;
1177	} else if (IEEE80211_IS_CHAN_ANYG(chan)) {
1178		status |= IFM_IEEE80211_11G;
1179	} else if (IEEE80211_IS_CHAN_FHSS(chan)) {
1180		status |= IFM_IEEE80211_FH;
1181	}
1182	/* XXX else complain? */
1183
1184	if (IEEE80211_IS_CHAN_TURBO(chan))
1185		status |= IFM_IEEE80211_TURBO;
1186#if 0
1187	if (IEEE80211_IS_CHAN_HT20(chan))
1188		status |= IFM_IEEE80211_HT20;
1189	if (IEEE80211_IS_CHAN_HT40(chan))
1190		status |= IFM_IEEE80211_HT40;
1191#endif
1192	return status;
1193}
1194
1195static void
1196ieee80211com_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1197{
1198	struct ieee80211com *ic = ifp->if_l2com;
1199	struct ieee80211vap *vap;
1200
1201	imr->ifm_status = IFM_AVALID;
1202	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
1203		if (vap->iv_ifp->if_flags & IFF_UP) {
1204			imr->ifm_status |= IFM_ACTIVE;
1205			break;
1206		}
1207	imr->ifm_active = media_status(ic->ic_opmode, ic->ic_curchan);
1208	if (imr->ifm_status & IFM_ACTIVE)
1209		imr->ifm_current = imr->ifm_active;
1210}
1211
1212void
1213ieee80211_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1214{
1215	struct ieee80211vap *vap = ifp->if_softc;
1216	struct ieee80211com *ic = vap->iv_ic;
1217	enum ieee80211_phymode mode;
1218
1219	imr->ifm_status = IFM_AVALID;
1220	/*
1221	 * NB: use the current channel's mode to lock down a xmit
1222	 * rate only when running; otherwise we may have a mismatch
1223	 * in which case the rate will not be convertible.
1224	 */
1225	if (vap->iv_state == IEEE80211_S_RUN) {
1226		imr->ifm_status |= IFM_ACTIVE;
1227		mode = ieee80211_chan2mode(ic->ic_curchan);
1228	} else
1229		mode = IEEE80211_MODE_AUTO;
1230	imr->ifm_active = media_status(vap->iv_opmode, ic->ic_curchan);
1231	/*
1232	 * Calculate a current rate if possible.
1233	 */
1234	if (vap->iv_txparms[mode].ucastrate != IEEE80211_FIXED_RATE_NONE) {
1235		/*
1236		 * A fixed rate is set, report that.
1237		 */
1238		imr->ifm_active |= ieee80211_rate2media(ic,
1239			vap->iv_txparms[mode].ucastrate, mode);
1240	} else if (vap->iv_opmode == IEEE80211_M_STA) {
1241		/*
1242		 * In station mode report the current transmit rate.
1243		 */
1244		imr->ifm_active |= ieee80211_rate2media(ic,
1245			vap->iv_bss->ni_txrate, mode);
1246	} else
1247		imr->ifm_active |= IFM_AUTO;
1248	if (imr->ifm_status & IFM_ACTIVE)
1249		imr->ifm_current = imr->ifm_active;
1250}
1251
1252/*
1253 * Set the current phy mode and recalculate the active channel
1254 * set based on the available channels for this mode.  Also
1255 * select a new default/current channel if the current one is
1256 * inappropriate for this mode.
1257 */
1258int
1259ieee80211_setmode(struct ieee80211com *ic, enum ieee80211_phymode mode)
1260{
1261	/*
1262	 * Adjust basic rates in 11b/11g supported rate set.
1263	 * Note that if operating on a hal/quarter rate channel
1264	 * this is a noop as those rates sets are different
1265	 * and used instead.
1266	 */
1267	if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11B)
1268		ieee80211_setbasicrates(&ic->ic_sup_rates[mode], mode);
1269
1270	ic->ic_curmode = mode;
1271	ieee80211_reset_erp(ic);	/* reset ERP state */
1272
1273	return 0;
1274}
1275
1276/*
1277 * Return the phy mode for with the specified channel.
1278 */
1279enum ieee80211_phymode
1280ieee80211_chan2mode(const struct ieee80211_channel *chan)
1281{
1282
1283	if (IEEE80211_IS_CHAN_HTA(chan))
1284		return IEEE80211_MODE_11NA;
1285	else if (IEEE80211_IS_CHAN_HTG(chan))
1286		return IEEE80211_MODE_11NG;
1287	else if (IEEE80211_IS_CHAN_108G(chan))
1288		return IEEE80211_MODE_TURBO_G;
1289	else if (IEEE80211_IS_CHAN_ST(chan))
1290		return IEEE80211_MODE_STURBO_A;
1291	else if (IEEE80211_IS_CHAN_TURBO(chan))
1292		return IEEE80211_MODE_TURBO_A;
1293	else if (IEEE80211_IS_CHAN_A(chan))
1294		return IEEE80211_MODE_11A;
1295	else if (IEEE80211_IS_CHAN_ANYG(chan))
1296		return IEEE80211_MODE_11G;
1297	else if (IEEE80211_IS_CHAN_B(chan))
1298		return IEEE80211_MODE_11B;
1299	else if (IEEE80211_IS_CHAN_FHSS(chan))
1300		return IEEE80211_MODE_FH;
1301
1302	/* NB: should not get here */
1303	printf("%s: cannot map channel to mode; freq %u flags 0x%x\n",
1304		__func__, chan->ic_freq, chan->ic_flags);
1305	return IEEE80211_MODE_11B;
1306}
1307
1308struct ratemedia {
1309	u_int	match;	/* rate + mode */
1310	u_int	media;	/* if_media rate */
1311};
1312
1313static int
1314findmedia(const struct ratemedia rates[], int n, u_int match)
1315{
1316	int i;
1317
1318	for (i = 0; i < n; i++)
1319		if (rates[i].match == match)
1320			return rates[i].media;
1321	return IFM_AUTO;
1322}
1323
1324/*
1325 * Convert IEEE80211 rate value to ifmedia subtype.
1326 * Rate is either a legacy rate in units of 0.5Mbps
1327 * or an MCS index.
1328 */
1329int
1330ieee80211_rate2media(struct ieee80211com *ic, int rate, enum ieee80211_phymode mode)
1331{
1332#define	N(a)	(sizeof(a) / sizeof(a[0]))
1333	static const struct ratemedia rates[] = {
1334		{   2 | IFM_IEEE80211_FH, IFM_IEEE80211_FH1 },
1335		{   4 | IFM_IEEE80211_FH, IFM_IEEE80211_FH2 },
1336		{   2 | IFM_IEEE80211_11B, IFM_IEEE80211_DS1 },
1337		{   4 | IFM_IEEE80211_11B, IFM_IEEE80211_DS2 },
1338		{  11 | IFM_IEEE80211_11B, IFM_IEEE80211_DS5 },
1339		{  22 | IFM_IEEE80211_11B, IFM_IEEE80211_DS11 },
1340		{  44 | IFM_IEEE80211_11B, IFM_IEEE80211_DS22 },
1341		{  12 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM6 },
1342		{  18 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM9 },
1343		{  24 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM12 },
1344		{  36 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM18 },
1345		{  48 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM24 },
1346		{  72 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM36 },
1347		{  96 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM48 },
1348		{ 108 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM54 },
1349		{   2 | IFM_IEEE80211_11G, IFM_IEEE80211_DS1 },
1350		{   4 | IFM_IEEE80211_11G, IFM_IEEE80211_DS2 },
1351		{  11 | IFM_IEEE80211_11G, IFM_IEEE80211_DS5 },
1352		{  22 | IFM_IEEE80211_11G, IFM_IEEE80211_DS11 },
1353		{  12 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM6 },
1354		{  18 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM9 },
1355		{  24 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM12 },
1356		{  36 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM18 },
1357		{  48 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM24 },
1358		{  72 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM36 },
1359		{  96 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM48 },
1360		{ 108 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM54 },
1361		{   6 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM3 },
1362		{   9 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM4 },
1363		{  54 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM27 },
1364		/* NB: OFDM72 doesn't realy exist so we don't handle it */
1365	};
1366	static const struct ratemedia htrates[] = {
1367		{   0, IFM_IEEE80211_MCS },
1368		{   1, IFM_IEEE80211_MCS },
1369		{   2, IFM_IEEE80211_MCS },
1370		{   3, IFM_IEEE80211_MCS },
1371		{   4, IFM_IEEE80211_MCS },
1372		{   5, IFM_IEEE80211_MCS },
1373		{   6, IFM_IEEE80211_MCS },
1374		{   7, IFM_IEEE80211_MCS },
1375		{   8, IFM_IEEE80211_MCS },
1376		{   9, IFM_IEEE80211_MCS },
1377		{  10, IFM_IEEE80211_MCS },
1378		{  11, IFM_IEEE80211_MCS },
1379		{  12, IFM_IEEE80211_MCS },
1380		{  13, IFM_IEEE80211_MCS },
1381		{  14, IFM_IEEE80211_MCS },
1382		{  15, IFM_IEEE80211_MCS },
1383	};
1384	int m;
1385
1386	/*
1387	 * Check 11n rates first for match as an MCS.
1388	 */
1389	if (mode == IEEE80211_MODE_11NA) {
1390		if (rate & IEEE80211_RATE_MCS) {
1391			rate &= ~IEEE80211_RATE_MCS;
1392			m = findmedia(htrates, N(htrates), rate);
1393			if (m != IFM_AUTO)
1394				return m | IFM_IEEE80211_11NA;
1395		}
1396	} else if (mode == IEEE80211_MODE_11NG) {
1397		/* NB: 12 is ambiguous, it will be treated as an MCS */
1398		if (rate & IEEE80211_RATE_MCS) {
1399			rate &= ~IEEE80211_RATE_MCS;
1400			m = findmedia(htrates, N(htrates), rate);
1401			if (m != IFM_AUTO)
1402				return m | IFM_IEEE80211_11NG;
1403		}
1404	}
1405	rate &= IEEE80211_RATE_VAL;
1406	switch (mode) {
1407	case IEEE80211_MODE_11A:
1408	case IEEE80211_MODE_11NA:
1409	case IEEE80211_MODE_TURBO_A:
1410	case IEEE80211_MODE_STURBO_A:
1411		return findmedia(rates, N(rates), rate | IFM_IEEE80211_11A);
1412	case IEEE80211_MODE_11B:
1413		return findmedia(rates, N(rates), rate | IFM_IEEE80211_11B);
1414	case IEEE80211_MODE_FH:
1415		return findmedia(rates, N(rates), rate | IFM_IEEE80211_FH);
1416	case IEEE80211_MODE_AUTO:
1417		/* NB: ic may be NULL for some drivers */
1418		if (ic && ic->ic_phytype == IEEE80211_T_FH)
1419			return findmedia(rates, N(rates),
1420			    rate | IFM_IEEE80211_FH);
1421		/* NB: hack, 11g matches both 11b+11a rates */
1422		/* fall thru... */
1423	case IEEE80211_MODE_11G:
1424	case IEEE80211_MODE_11NG:
1425	case IEEE80211_MODE_TURBO_G:
1426		return findmedia(rates, N(rates), rate | IFM_IEEE80211_11G);
1427	}
1428	return IFM_AUTO;
1429#undef N
1430}
1431
1432int
1433ieee80211_media2rate(int mword)
1434{
1435#define	N(a)	(sizeof(a) / sizeof(a[0]))
1436	static const int ieeerates[] = {
1437		-1,		/* IFM_AUTO */
1438		0,		/* IFM_MANUAL */
1439		0,		/* IFM_NONE */
1440		2,		/* IFM_IEEE80211_FH1 */
1441		4,		/* IFM_IEEE80211_FH2 */
1442		2,		/* IFM_IEEE80211_DS1 */
1443		4,		/* IFM_IEEE80211_DS2 */
1444		11,		/* IFM_IEEE80211_DS5 */
1445		22,		/* IFM_IEEE80211_DS11 */
1446		44,		/* IFM_IEEE80211_DS22 */
1447		12,		/* IFM_IEEE80211_OFDM6 */
1448		18,		/* IFM_IEEE80211_OFDM9 */
1449		24,		/* IFM_IEEE80211_OFDM12 */
1450		36,		/* IFM_IEEE80211_OFDM18 */
1451		48,		/* IFM_IEEE80211_OFDM24 */
1452		72,		/* IFM_IEEE80211_OFDM36 */
1453		96,		/* IFM_IEEE80211_OFDM48 */
1454		108,		/* IFM_IEEE80211_OFDM54 */
1455		144,		/* IFM_IEEE80211_OFDM72 */
1456		0,		/* IFM_IEEE80211_DS354k */
1457		0,		/* IFM_IEEE80211_DS512k */
1458		6,		/* IFM_IEEE80211_OFDM3 */
1459		9,		/* IFM_IEEE80211_OFDM4 */
1460		54,		/* IFM_IEEE80211_OFDM27 */
1461		-1,		/* IFM_IEEE80211_MCS */
1462	};
1463	return IFM_SUBTYPE(mword) < N(ieeerates) ?
1464		ieeerates[IFM_SUBTYPE(mword)] : 0;
1465#undef N
1466}
1467