ieee80211.c revision 138568
1/*-
2 * Copyright (c) 2001 Atsushi Onoe
3 * Copyright (c) 2002-2004 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 * 3. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission.
16 *
17 * Alternatively, this software may be distributed under the terms of the
18 * GNU General Public License ("GPL") version 2 as published by the Free
19 * Software Foundation.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/net80211/ieee80211.c 138568 2004-12-08 17:26:47Z sam $");
35
36/*
37 * IEEE 802.11 generic handler
38 */
39
40#include <sys/param.h>
41#include <sys/systm.h>
42#include <sys/kernel.h>
43
44#include <sys/socket.h>
45
46#include <net/if.h>
47#include <net/if_media.h>
48#include <net/ethernet.h>
49
50#include <net80211/ieee80211_var.h>
51
52#include <net/bpf.h>
53
54static const char *ieee80211_phymode_name[] = {
55	"auto",		/* IEEE80211_MODE_AUTO */
56	"11a",		/* IEEE80211_MODE_11A */
57	"11b",		/* IEEE80211_MODE_11B */
58	"11g",		/* IEEE80211_MODE_11G */
59	"FH",		/* IEEE80211_MODE_FH */
60	"turboA",	/* IEEE80211_MODE_TURBO_A */
61	"turboG",	/* IEEE80211_MODE_TURBO_G */
62};
63
64/* list of all instances */
65SLIST_HEAD(ieee80211_list, ieee80211com);
66static struct ieee80211_list ieee80211_list =
67	SLIST_HEAD_INITIALIZER(ieee80211_list);
68static u_int8_t ieee80211_vapmap[32];		/* enough for 256 */
69static struct mtx ieee80211_vap_mtx;
70MTX_SYSINIT(ieee80211, &ieee80211_vap_mtx, "net80211 instances", MTX_DEF);
71
72static void
73ieee80211_add_vap(struct ieee80211com *ic)
74{
75#define	N(a)	(sizeof(a)/sizeof(a[0]))
76	int i;
77	u_int8_t b;
78
79	mtx_lock(&ieee80211_vap_mtx);
80	ic->ic_vap = 0;
81	for (i = 0; i < N(ieee80211_vapmap) && ieee80211_vapmap[i] == 0xff; i++)
82		ic->ic_vap += NBBY;
83	if (i == N(ieee80211_vapmap))
84		panic("vap table full");
85	for (b = ieee80211_vapmap[i]; b & 1; b >>= 1)
86		ic->ic_vap++;
87	setbit(ieee80211_vapmap, ic->ic_vap);
88	SLIST_INSERT_HEAD(&ieee80211_list, ic, ic_next);
89	mtx_unlock(&ieee80211_vap_mtx);
90#undef N
91}
92
93static void
94ieee80211_remove_vap(struct ieee80211com *ic)
95{
96	mtx_lock(&ieee80211_vap_mtx);
97	SLIST_REMOVE(&ieee80211_list, ic, ieee80211com, ic_next);
98	KASSERT(ic->ic_vap < sizeof(ieee80211_vapmap)*NBBY,
99		("invalid vap id %d", ic->ic_vap));
100	KASSERT(isset(ieee80211_vapmap, ic->ic_vap),
101		("vap id %d not allocated", ic->ic_vap));
102	clrbit(ieee80211_vapmap, ic->ic_vap);
103	mtx_unlock(&ieee80211_vap_mtx);
104}
105
106void
107ieee80211_ifattach(struct ieee80211com *ic)
108{
109	struct ifnet *ifp = ic->ic_ifp;
110	struct ieee80211_channel *c;
111	int i;
112
113	ether_ifattach(ifp, ic->ic_myaddr);
114	bpfattach2(ifp, DLT_IEEE802_11,
115	    sizeof(struct ieee80211_frame_addr4), &ic->ic_rawbpf);
116
117	ieee80211_crypto_attach(ic);
118
119	/*
120	 * Fill in 802.11 available channel set, mark
121	 * all available channels as active, and pick
122	 * a default channel if not already specified.
123	 */
124	memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail));
125	ic->ic_modecaps |= 1<<IEEE80211_MODE_AUTO;
126	for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
127		c = &ic->ic_channels[i];
128		if (c->ic_flags) {
129			/*
130			 * Verify driver passed us valid data.
131			 */
132			if (i != ieee80211_chan2ieee(ic, c)) {
133				if_printf(ifp, "bad channel ignored; "
134					"freq %u flags %x number %u\n",
135					c->ic_freq, c->ic_flags, i);
136				c->ic_flags = 0;	/* NB: remove */
137				continue;
138			}
139			setbit(ic->ic_chan_avail, i);
140			/*
141			 * Identify mode capabilities.
142			 */
143			if (IEEE80211_IS_CHAN_A(c))
144				ic->ic_modecaps |= 1<<IEEE80211_MODE_11A;
145			if (IEEE80211_IS_CHAN_B(c))
146				ic->ic_modecaps |= 1<<IEEE80211_MODE_11B;
147			if (IEEE80211_IS_CHAN_PUREG(c))
148				ic->ic_modecaps |= 1<<IEEE80211_MODE_11G;
149			if (IEEE80211_IS_CHAN_FHSS(c))
150				ic->ic_modecaps |= 1<<IEEE80211_MODE_FH;
151			if (IEEE80211_IS_CHAN_T(c))
152				ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO_A;
153			if (IEEE80211_IS_CHAN_108G(c))
154				ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO_G;
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	/*
163	 * Enable WME by default if we're capable.
164	 */
165	if (ic->ic_caps & IEEE80211_C_WME)
166		ic->ic_flags |= IEEE80211_F_WME;
167
168	(void) ieee80211_setmode(ic, ic->ic_curmode);
169
170	if (ic->ic_lintval == 0)
171		ic->ic_lintval = IEEE80211_BINTVAL_DEFAULT;
172	ic->ic_bmisstimeout = 7*ic->ic_lintval;	/* default 7 beacons */
173	ic->ic_dtim_period = IEEE80211_DTIM_DEFAULT;
174	IEEE80211_BEACON_LOCK_INIT(ic, "beacon");
175
176	ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX;
177
178	ieee80211_node_attach(ic);
179	ieee80211_proto_attach(ic);
180
181	ieee80211_add_vap(ic);
182
183	ieee80211_sysctl_attach(ic);		/* NB: requires ic_vap */
184}
185
186void
187ieee80211_ifdetach(struct ieee80211com *ic)
188{
189	struct ifnet *ifp = ic->ic_ifp;
190
191	ieee80211_remove_vap(ic);
192
193	ieee80211_sysctl_detach(ic);
194	ieee80211_proto_detach(ic);
195	ieee80211_crypto_detach(ic);
196	ieee80211_node_detach(ic);
197	ifmedia_removeall(&ic->ic_media);
198
199	IEEE80211_BEACON_LOCK_DESTROY(ic);
200
201	bpfdetach(ifp);
202	ether_ifdetach(ifp);
203}
204
205/*
206 * Convert MHz frequency to IEEE channel number.
207 */
208u_int
209ieee80211_mhz2ieee(u_int freq, u_int flags)
210{
211	if (flags & IEEE80211_CHAN_2GHZ) {	/* 2GHz band */
212		if (freq == 2484)
213			return 14;
214		if (freq < 2484)
215			return (freq - 2407) / 5;
216		else
217			return 15 + ((freq - 2512) / 20);
218	} else if (flags & IEEE80211_CHAN_5GHZ) {	/* 5Ghz band */
219		return (freq - 5000) / 5;
220	} else {				/* either, guess */
221		if (freq == 2484)
222			return 14;
223		if (freq < 2484)
224			return (freq - 2407) / 5;
225		if (freq < 5000)
226			return 15 + ((freq - 2512) / 20);
227		return (freq - 5000) / 5;
228	}
229}
230
231/*
232 * Convert channel to IEEE channel number.
233 */
234u_int
235ieee80211_chan2ieee(struct ieee80211com *ic, struct ieee80211_channel *c)
236{
237	if (ic->ic_channels <= c && c <= &ic->ic_channels[IEEE80211_CHAN_MAX])
238		return c - ic->ic_channels;
239	else if (c == IEEE80211_CHAN_ANYC)
240		return IEEE80211_CHAN_ANY;
241	else if (c != NULL) {
242		if_printf(ic->ic_ifp, "invalid channel freq %u flags %x\n",
243			c->ic_freq, c->ic_flags);
244		return 0;		/* XXX */
245	} else {
246		if_printf(ic->ic_ifp, "invalid channel (NULL)\n");
247		return 0;		/* XXX */
248	}
249}
250
251/*
252 * Convert IEEE channel number to MHz frequency.
253 */
254u_int
255ieee80211_ieee2mhz(u_int chan, u_int flags)
256{
257	if (flags & IEEE80211_CHAN_2GHZ) {	/* 2GHz band */
258		if (chan == 14)
259			return 2484;
260		if (chan < 14)
261			return 2407 + chan*5;
262		else
263			return 2512 + ((chan-15)*20);
264	} else if (flags & IEEE80211_CHAN_5GHZ) {/* 5Ghz band */
265		return 5000 + (chan*5);
266	} else {				/* either, guess */
267		if (chan == 14)
268			return 2484;
269		if (chan < 14)			/* 0-13 */
270			return 2407 + chan*5;
271		if (chan < 27)			/* 15-26 */
272			return 2512 + ((chan-15)*20);
273		return 5000 + (chan*5);
274	}
275}
276
277/*
278 * Setup the media data structures according to the channel and
279 * rate tables.  This must be called by the driver after
280 * ieee80211_attach and before most anything else.
281 */
282void
283ieee80211_media_init(struct ieee80211com *ic,
284	ifm_change_cb_t media_change, ifm_stat_cb_t media_stat)
285{
286#define	ADD(_ic, _s, _o) \
287	ifmedia_add(&(_ic)->ic_media, \
288		IFM_MAKEWORD(IFM_IEEE80211, (_s), (_o), 0), 0, NULL)
289	struct ifnet *ifp = ic->ic_ifp;
290	struct ifmediareq imr;
291	int i, j, mode, rate, maxrate, mword, mopt, r;
292	struct ieee80211_rateset *rs;
293	struct ieee80211_rateset allrates;
294
295	/*
296	 * Do late attach work that must wait for any subclass
297	 * (i.e. driver) work such as overriding methods.
298	 */
299	ieee80211_node_lateattach(ic);
300
301	/*
302	 * Fill in media characteristics.
303	 */
304	ifmedia_init(&ic->ic_media, 0, media_change, media_stat);
305	maxrate = 0;
306	memset(&allrates, 0, sizeof(allrates));
307	for (mode = IEEE80211_MODE_AUTO; mode < IEEE80211_MODE_MAX; mode++) {
308		static const u_int mopts[] = {
309			IFM_AUTO,
310			IFM_IEEE80211_11A,
311			IFM_IEEE80211_11B,
312			IFM_IEEE80211_11G,
313			IFM_IEEE80211_FH,
314			IFM_IEEE80211_11A | IFM_IEEE80211_TURBO,
315			IFM_IEEE80211_11G | IFM_IEEE80211_TURBO,
316		};
317		if ((ic->ic_modecaps & (1<<mode)) == 0)
318			continue;
319		mopt = mopts[mode];
320		ADD(ic, IFM_AUTO, mopt);	/* e.g. 11a auto */
321		if (ic->ic_caps & IEEE80211_C_IBSS)
322			ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_ADHOC);
323		if (ic->ic_caps & IEEE80211_C_HOSTAP)
324			ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_HOSTAP);
325		if (ic->ic_caps & IEEE80211_C_AHDEMO)
326			ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_ADHOC | IFM_FLAG0);
327		if (ic->ic_caps & IEEE80211_C_MONITOR)
328			ADD(ic, IFM_AUTO, mopt | IFM_IEEE80211_MONITOR);
329		if (mode == IEEE80211_MODE_AUTO)
330			continue;
331		rs = &ic->ic_sup_rates[mode];
332		for (i = 0; i < rs->rs_nrates; i++) {
333			rate = rs->rs_rates[i];
334			mword = ieee80211_rate2media(ic, rate, mode);
335			if (mword == 0)
336				continue;
337			ADD(ic, mword, mopt);
338			if (ic->ic_caps & IEEE80211_C_IBSS)
339				ADD(ic, mword, mopt | IFM_IEEE80211_ADHOC);
340			if (ic->ic_caps & IEEE80211_C_HOSTAP)
341				ADD(ic, mword, mopt | IFM_IEEE80211_HOSTAP);
342			if (ic->ic_caps & IEEE80211_C_AHDEMO)
343				ADD(ic, mword, mopt | IFM_IEEE80211_ADHOC | IFM_FLAG0);
344			if (ic->ic_caps & IEEE80211_C_MONITOR)
345				ADD(ic, mword, mopt | IFM_IEEE80211_MONITOR);
346			/*
347			 * Add rate to the collection of all rates.
348			 */
349			r = rate & IEEE80211_RATE_VAL;
350			for (j = 0; j < allrates.rs_nrates; j++)
351				if (allrates.rs_rates[j] == r)
352					break;
353			if (j == allrates.rs_nrates) {
354				/* unique, add to the set */
355				allrates.rs_rates[j] = r;
356				allrates.rs_nrates++;
357			}
358			rate = (rate & IEEE80211_RATE_VAL) / 2;
359			if (rate > maxrate)
360				maxrate = rate;
361		}
362	}
363	for (i = 0; i < allrates.rs_nrates; i++) {
364		mword = ieee80211_rate2media(ic, allrates.rs_rates[i],
365				IEEE80211_MODE_AUTO);
366		if (mword == 0)
367			continue;
368		mword = IFM_SUBTYPE(mword);	/* remove media options */
369		ADD(ic, mword, 0);
370		if (ic->ic_caps & IEEE80211_C_IBSS)
371			ADD(ic, mword, IFM_IEEE80211_ADHOC);
372		if (ic->ic_caps & IEEE80211_C_HOSTAP)
373			ADD(ic, mword, IFM_IEEE80211_HOSTAP);
374		if (ic->ic_caps & IEEE80211_C_AHDEMO)
375			ADD(ic, mword, IFM_IEEE80211_ADHOC | IFM_FLAG0);
376		if (ic->ic_caps & IEEE80211_C_MONITOR)
377			ADD(ic, mword, IFM_IEEE80211_MONITOR);
378	}
379	ieee80211_media_status(ifp, &imr);
380	ifmedia_set(&ic->ic_media, imr.ifm_active);
381
382	if (maxrate)
383		ifp->if_baudrate = IF_Mbps(maxrate);
384#undef ADD
385}
386
387void
388ieee80211_announce(struct ieee80211com *ic)
389{
390	struct ifnet *ifp = ic->ic_ifp;
391	int i, mode, rate, mword;
392	struct ieee80211_rateset *rs;
393
394	for (mode = IEEE80211_MODE_11A; mode < IEEE80211_MODE_MAX; mode++) {
395		if ((ic->ic_modecaps & (1<<mode)) == 0)
396			continue;
397		if_printf(ifp, "%s rates: ", ieee80211_phymode_name[mode]);
398		rs = &ic->ic_sup_rates[mode];
399		for (i = 0; i < rs->rs_nrates; i++) {
400			rate = rs->rs_rates[i];
401			mword = ieee80211_rate2media(ic, rate, mode);
402			if (mword == 0)
403				continue;
404			printf("%s%d%sMbps", (i != 0 ? " " : ""),
405			    (rate & IEEE80211_RATE_VAL) / 2,
406			    ((rate & 0x1) != 0 ? ".5" : ""));
407		}
408		printf("\n");
409	}
410}
411
412static int
413findrate(struct ieee80211com *ic, enum ieee80211_phymode mode, int rate)
414{
415#define	IEEERATE(_ic,_m,_i) \
416	((_ic)->ic_sup_rates[_m].rs_rates[_i] & IEEE80211_RATE_VAL)
417	int i, nrates = ic->ic_sup_rates[mode].rs_nrates;
418	for (i = 0; i < nrates; i++)
419		if (IEEERATE(ic, mode, i) == rate)
420			return i;
421	return -1;
422#undef IEEERATE
423}
424
425/*
426 * Find an instance by it's mac address.
427 */
428struct ieee80211com *
429ieee80211_find_vap(const u_int8_t mac[IEEE80211_ADDR_LEN])
430{
431	struct ieee80211com *ic;
432
433	/* XXX lock */
434	SLIST_FOREACH(ic, &ieee80211_list, ic_next)
435		if (IEEE80211_ADDR_EQ(mac, ic->ic_myaddr))
436			return ic;
437	return NULL;
438}
439
440static struct ieee80211com *
441ieee80211_find_instance(struct ifnet *ifp)
442{
443	struct ieee80211com *ic;
444
445	/* XXX lock */
446	/* XXX not right for multiple instances but works for now */
447	SLIST_FOREACH(ic, &ieee80211_list, ic_next)
448		if (ic->ic_ifp == ifp)
449			return ic;
450	return NULL;
451}
452
453/*
454 * Handle a media change request.
455 */
456int
457ieee80211_media_change(struct ifnet *ifp)
458{
459	struct ieee80211com *ic;
460	struct ifmedia_entry *ime;
461	enum ieee80211_opmode newopmode;
462	enum ieee80211_phymode newphymode;
463	int i, j, newrate, error = 0;
464
465	ic = ieee80211_find_instance(ifp);
466	if (!ic) {
467		if_printf(ifp, "%s: no 802.11 instance!\n", __func__);
468		return EINVAL;
469	}
470	ime = ic->ic_media.ifm_cur;
471	/*
472	 * First, identify the phy mode.
473	 */
474	switch (IFM_MODE(ime->ifm_media)) {
475	case IFM_IEEE80211_11A:
476		newphymode = IEEE80211_MODE_11A;
477		break;
478	case IFM_IEEE80211_11B:
479		newphymode = IEEE80211_MODE_11B;
480		break;
481	case IFM_IEEE80211_11G:
482		newphymode = IEEE80211_MODE_11G;
483		break;
484	case IFM_IEEE80211_FH:
485		newphymode = IEEE80211_MODE_FH;
486		break;
487	case IFM_AUTO:
488		newphymode = IEEE80211_MODE_AUTO;
489		break;
490	default:
491		return EINVAL;
492	}
493	/*
494	 * Turbo mode is an ``option''.
495	 * XXX does not apply to AUTO
496	 */
497	if (ime->ifm_media & IFM_IEEE80211_TURBO) {
498		if (newphymode == IEEE80211_MODE_11A)
499			newphymode = IEEE80211_MODE_TURBO_A;
500		else if (newphymode == IEEE80211_MODE_11G)
501			newphymode = IEEE80211_MODE_TURBO_G;
502		else
503			return EINVAL;
504	}
505	/*
506	 * Validate requested mode is available.
507	 */
508	if ((ic->ic_modecaps & (1<<newphymode)) == 0)
509		return EINVAL;
510
511	/*
512	 * Next, the fixed/variable rate.
513	 */
514	i = -1;
515	if (IFM_SUBTYPE(ime->ifm_media) != IFM_AUTO) {
516		/*
517		 * Convert media subtype to rate.
518		 */
519		newrate = ieee80211_media2rate(ime->ifm_media);
520		if (newrate == 0)
521			return EINVAL;
522		/*
523		 * Check the rate table for the specified/current phy.
524		 */
525		if (newphymode == IEEE80211_MODE_AUTO) {
526			/*
527			 * In autoselect mode search for the rate.
528			 */
529			for (j = IEEE80211_MODE_11A;
530			     j < IEEE80211_MODE_MAX; j++) {
531				if ((ic->ic_modecaps & (1<<j)) == 0)
532					continue;
533				i = findrate(ic, j, newrate);
534				if (i != -1) {
535					/* lock mode too */
536					newphymode = j;
537					break;
538				}
539			}
540		} else {
541			i = findrate(ic, newphymode, newrate);
542		}
543		if (i == -1)			/* mode/rate mismatch */
544			return EINVAL;
545	}
546	/* NB: defer rate setting to later */
547
548	/*
549	 * Deduce new operating mode but don't install it just yet.
550	 */
551	if ((ime->ifm_media & (IFM_IEEE80211_ADHOC|IFM_FLAG0)) ==
552	    (IFM_IEEE80211_ADHOC|IFM_FLAG0))
553		newopmode = IEEE80211_M_AHDEMO;
554	else if (ime->ifm_media & IFM_IEEE80211_HOSTAP)
555		newopmode = IEEE80211_M_HOSTAP;
556	else if (ime->ifm_media & IFM_IEEE80211_ADHOC)
557		newopmode = IEEE80211_M_IBSS;
558	else if (ime->ifm_media & IFM_IEEE80211_MONITOR)
559		newopmode = IEEE80211_M_MONITOR;
560	else
561		newopmode = IEEE80211_M_STA;
562
563	/*
564	 * Autoselect doesn't make sense when operating as an AP.
565	 * If no phy mode has been selected, pick one and lock it
566	 * down so rate tables can be used in forming beacon frames
567	 * and the like.
568	 */
569	if (newopmode == IEEE80211_M_HOSTAP &&
570	    newphymode == IEEE80211_MODE_AUTO) {
571		for (j = IEEE80211_MODE_11A; j < IEEE80211_MODE_MAX; j++)
572			if (ic->ic_modecaps & (1<<j)) {
573				newphymode = j;
574				break;
575			}
576	}
577
578	/*
579	 * Handle phy mode change.
580	 */
581	if (ic->ic_curmode != newphymode) {		/* change phy mode */
582		error = ieee80211_setmode(ic, newphymode);
583		if (error != 0)
584			return error;
585		error = ENETRESET;
586	}
587
588	/*
589	 * Committed to changes, install the rate setting.
590	 */
591	if (ic->ic_fixed_rate != i) {
592		ic->ic_fixed_rate = i;			/* set fixed tx rate */
593		error = ENETRESET;
594	}
595
596	/*
597	 * Handle operating mode change.
598	 */
599	if (ic->ic_opmode != newopmode) {
600		ic->ic_opmode = newopmode;
601		switch (newopmode) {
602		case IEEE80211_M_AHDEMO:
603		case IEEE80211_M_HOSTAP:
604		case IEEE80211_M_STA:
605		case IEEE80211_M_MONITOR:
606			ic->ic_flags &= ~IEEE80211_F_IBSSON;
607			break;
608		case IEEE80211_M_IBSS:
609			ic->ic_flags |= IEEE80211_F_IBSSON;
610			break;
611		}
612		/*
613		 * Yech, slot time may change depending on the
614		 * operating mode so reset it to be sure everything
615		 * is setup appropriately.
616		 */
617		ieee80211_reset_erp(ic);
618		ieee80211_wme_initparams(ic);	/* after opmode change */
619		error = ENETRESET;
620	}
621#ifdef notdef
622	if (error == 0)
623		ifp->if_baudrate = ifmedia_baudrate(ime->ifm_media);
624#endif
625	return error;
626}
627
628void
629ieee80211_media_status(struct ifnet *ifp, struct ifmediareq *imr)
630{
631	struct ieee80211com *ic;
632	struct ieee80211_rateset *rs;
633
634	ic = ieee80211_find_instance(ifp);
635	if (!ic) {
636		if_printf(ifp, "%s: no 802.11 instance!\n", __func__);
637		return;
638	}
639	imr->ifm_status = IFM_AVALID;
640	imr->ifm_active = IFM_IEEE80211;
641	if (ic->ic_state == IEEE80211_S_RUN)
642		imr->ifm_status |= IFM_ACTIVE;
643	/*
644	 * Calculate a current rate if possible.
645	 */
646	if (ic->ic_fixed_rate != -1) {
647		/*
648		 * A fixed rate is set, report that.
649		 */
650		rs = &ic->ic_sup_rates[ic->ic_curmode];
651		imr->ifm_active |= ieee80211_rate2media(ic,
652			rs->rs_rates[ic->ic_fixed_rate], ic->ic_curmode);
653	} else if (ic->ic_opmode == IEEE80211_M_STA) {
654		/*
655		 * In station mode report the current transmit rate.
656		 */
657		rs = &ic->ic_bss->ni_rates;
658		imr->ifm_active |= ieee80211_rate2media(ic,
659			rs->rs_rates[ic->ic_bss->ni_txrate], ic->ic_curmode);
660	} else
661		imr->ifm_active |= IFM_AUTO;
662	switch (ic->ic_opmode) {
663	case IEEE80211_M_STA:
664		break;
665	case IEEE80211_M_IBSS:
666		imr->ifm_active |= IFM_IEEE80211_ADHOC;
667		break;
668	case IEEE80211_M_AHDEMO:
669		/* should not come here */
670		break;
671	case IEEE80211_M_HOSTAP:
672		imr->ifm_active |= IFM_IEEE80211_HOSTAP;
673		break;
674	case IEEE80211_M_MONITOR:
675		imr->ifm_active |= IFM_IEEE80211_MONITOR;
676		break;
677	}
678	switch (ic->ic_curmode) {
679	case IEEE80211_MODE_11A:
680		imr->ifm_active |= IFM_IEEE80211_11A;
681		break;
682	case IEEE80211_MODE_11B:
683		imr->ifm_active |= IFM_IEEE80211_11B;
684		break;
685	case IEEE80211_MODE_11G:
686		imr->ifm_active |= IFM_IEEE80211_11G;
687		break;
688	case IEEE80211_MODE_FH:
689		imr->ifm_active |= IFM_IEEE80211_FH;
690		break;
691	case IEEE80211_MODE_TURBO_A:
692		imr->ifm_active |= IFM_IEEE80211_11A
693				|  IFM_IEEE80211_TURBO;
694		break;
695	case IEEE80211_MODE_TURBO_G:
696		imr->ifm_active |= IFM_IEEE80211_11G
697				|  IFM_IEEE80211_TURBO;
698		break;
699	}
700}
701
702void
703ieee80211_watchdog(struct ieee80211com *ic)
704{
705	struct ieee80211_node_table *nt;
706	int need_inact_timer = 0;
707
708	if (ic->ic_state != IEEE80211_S_INIT) {
709		if (ic->ic_mgt_timer && --ic->ic_mgt_timer == 0)
710			ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
711		nt = &ic->ic_scan;
712		if (nt->nt_inact_timer) {
713			if (--nt->nt_inact_timer == 0)
714				nt->nt_timeout(nt);
715			need_inact_timer += nt->nt_inact_timer;
716		}
717		nt = ic->ic_sta;
718		if (nt != NULL && nt->nt_inact_timer) {
719			if (--nt->nt_inact_timer == 0)
720				nt->nt_timeout(nt);
721			need_inact_timer += nt->nt_inact_timer;
722		}
723	}
724	if (ic->ic_mgt_timer != 0 || need_inact_timer)
725		ic->ic_ifp->if_timer = 1;
726}
727
728/*
729 * Set the current phy mode and recalculate the active channel
730 * set based on the available channels for this mode.  Also
731 * select a new default/current channel if the current one is
732 * inappropriate for this mode.
733 */
734int
735ieee80211_setmode(struct ieee80211com *ic, enum ieee80211_phymode mode)
736{
737#define	N(a)	(sizeof(a) / sizeof(a[0]))
738	static const u_int chanflags[] = {
739		0,			/* IEEE80211_MODE_AUTO */
740		IEEE80211_CHAN_A,	/* IEEE80211_MODE_11A */
741		IEEE80211_CHAN_B,	/* IEEE80211_MODE_11B */
742		IEEE80211_CHAN_PUREG,	/* IEEE80211_MODE_11G */
743		IEEE80211_CHAN_FHSS,	/* IEEE80211_MODE_FH */
744		IEEE80211_CHAN_T,	/* IEEE80211_MODE_TURBO_A */
745		IEEE80211_CHAN_108G,	/* IEEE80211_MODE_TURBO_G */
746	};
747	struct ieee80211_channel *c;
748	u_int modeflags;
749	int i;
750
751	/* validate new mode */
752	if ((ic->ic_modecaps & (1<<mode)) == 0) {
753		IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
754			"%s: mode %u not supported (caps 0x%x)\n",
755			__func__, mode, ic->ic_modecaps);
756		return EINVAL;
757	}
758
759	/*
760	 * Verify at least one channel is present in the available
761	 * channel list before committing to the new mode.
762	 */
763	KASSERT(mode < N(chanflags), ("Unexpected mode %u", mode));
764	modeflags = chanflags[mode];
765	for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
766		c = &ic->ic_channels[i];
767		if (mode == IEEE80211_MODE_AUTO) {
768			/* ignore turbo channels for autoselect */
769			if ((c->ic_flags &~ IEEE80211_CHAN_TURBO) != 0)
770				break;
771		} else {
772			if ((c->ic_flags & modeflags) == modeflags)
773				break;
774		}
775	}
776	if (i > IEEE80211_CHAN_MAX) {
777		IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
778			"%s: no channels found for mode %u\n", __func__, mode);
779		return EINVAL;
780	}
781
782	/*
783	 * Calculate the active channel set.
784	 */
785	memset(ic->ic_chan_active, 0, sizeof(ic->ic_chan_active));
786	for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
787		c = &ic->ic_channels[i];
788		if (mode == IEEE80211_MODE_AUTO) {
789			/* take anything but pure turbo channels */
790			if ((c->ic_flags &~ IEEE80211_CHAN_TURBO) != 0)
791				setbit(ic->ic_chan_active, i);
792		} else {
793			if ((c->ic_flags & modeflags) == modeflags)
794				setbit(ic->ic_chan_active, i);
795		}
796	}
797	/*
798	 * If no current/default channel is setup or the current
799	 * channel is wrong for the mode then pick the first
800	 * available channel from the active list.  This is likely
801	 * not the right one.
802	 */
803	if (ic->ic_ibss_chan == NULL ||
804	    isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, ic->ic_ibss_chan))) {
805		for (i = 0; i <= IEEE80211_CHAN_MAX; i++)
806			if (isset(ic->ic_chan_active, i)) {
807				ic->ic_ibss_chan = &ic->ic_channels[i];
808				break;
809			}
810		KASSERT(ic->ic_ibss_chan != NULL &&
811		    isset(ic->ic_chan_active,
812			ieee80211_chan2ieee(ic, ic->ic_ibss_chan)),
813		    ("Bad IBSS channel %u",
814		     ieee80211_chan2ieee(ic, ic->ic_ibss_chan)));
815	}
816	/*
817	 * If the desired channel is set but no longer valid then reset it.
818	 */
819	if (ic->ic_des_chan != IEEE80211_CHAN_ANYC &&
820	    isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, ic->ic_des_chan)))
821		ic->ic_des_chan = IEEE80211_CHAN_ANYC;
822
823	/*
824	 * Do mode-specific rate setup.
825	 */
826	if (mode == IEEE80211_MODE_11G) {
827		/*
828		 * Use a mixed 11b/11g rate set.
829		 */
830		ieee80211_set11gbasicrates(&ic->ic_sup_rates[mode],
831			IEEE80211_MODE_11G);
832	} else if (mode == IEEE80211_MODE_11B) {
833		/*
834		 * Force pure 11b rate set.
835		 */
836		ieee80211_set11gbasicrates(&ic->ic_sup_rates[mode],
837			IEEE80211_MODE_11B);
838	}
839	/*
840	 * Setup an initial rate set according to the
841	 * current/default channel selected above.  This
842	 * will be changed when scanning but must exist
843	 * now so driver have a consistent state of ic_ibss_chan.
844	 */
845	if (ic->ic_bss)		/* NB: can be called before lateattach */
846		ic->ic_bss->ni_rates = ic->ic_sup_rates[mode];
847
848	ic->ic_curmode = mode;
849	ieee80211_reset_erp(ic);	/* reset ERP state */
850	ieee80211_wme_initparams(ic);	/* reset WME stat */
851
852	return 0;
853#undef N
854}
855
856/*
857 * Return the phy mode for with the specified channel so the
858 * caller can select a rate set.  This is problematic for channels
859 * where multiple operating modes are possible (e.g. 11g+11b).
860 * In those cases we defer to the current operating mode when set.
861 */
862enum ieee80211_phymode
863ieee80211_chan2mode(struct ieee80211com *ic, struct ieee80211_channel *chan)
864{
865	if (IEEE80211_IS_CHAN_5GHZ(chan)) {
866		/*
867		 * This assumes all 11a turbo channels are also
868		 * usable withut turbo, which is currently true.
869		 */
870		if (ic->ic_curmode == IEEE80211_MODE_TURBO_A)
871			return IEEE80211_MODE_TURBO_A;
872		return IEEE80211_MODE_11A;
873	} else if (IEEE80211_IS_CHAN_FHSS(chan))
874		return IEEE80211_MODE_FH;
875	else if (chan->ic_flags & (IEEE80211_CHAN_OFDM|IEEE80211_CHAN_DYN)) {
876		/*
877		 * This assumes all 11g channels are also usable
878		 * for 11b, which is currently true.
879		 */
880		if (ic->ic_curmode == IEEE80211_MODE_TURBO_G)
881			return IEEE80211_MODE_TURBO_G;
882		if (ic->ic_curmode == IEEE80211_MODE_11B)
883			return IEEE80211_MODE_11B;
884		return IEEE80211_MODE_11G;
885	} else
886		return IEEE80211_MODE_11B;
887}
888
889/*
890 * convert IEEE80211 rate value to ifmedia subtype.
891 * ieee80211 rate is in unit of 0.5Mbps.
892 */
893int
894ieee80211_rate2media(struct ieee80211com *ic, int rate, enum ieee80211_phymode mode)
895{
896#define	N(a)	(sizeof(a) / sizeof(a[0]))
897	static const struct {
898		u_int	m;	/* rate + mode */
899		u_int	r;	/* if_media rate */
900	} rates[] = {
901		{   2 | IFM_IEEE80211_FH, IFM_IEEE80211_FH1 },
902		{   4 | IFM_IEEE80211_FH, IFM_IEEE80211_FH2 },
903		{   2 | IFM_IEEE80211_11B, IFM_IEEE80211_DS1 },
904		{   4 | IFM_IEEE80211_11B, IFM_IEEE80211_DS2 },
905		{  11 | IFM_IEEE80211_11B, IFM_IEEE80211_DS5 },
906		{  22 | IFM_IEEE80211_11B, IFM_IEEE80211_DS11 },
907		{  44 | IFM_IEEE80211_11B, IFM_IEEE80211_DS22 },
908		{  12 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM6 },
909		{  18 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM9 },
910		{  24 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM12 },
911		{  36 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM18 },
912		{  48 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM24 },
913		{  72 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM36 },
914		{  96 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM48 },
915		{ 108 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM54 },
916		{   2 | IFM_IEEE80211_11G, IFM_IEEE80211_DS1 },
917		{   4 | IFM_IEEE80211_11G, IFM_IEEE80211_DS2 },
918		{  11 | IFM_IEEE80211_11G, IFM_IEEE80211_DS5 },
919		{  22 | IFM_IEEE80211_11G, IFM_IEEE80211_DS11 },
920		{  12 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM6 },
921		{  18 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM9 },
922		{  24 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM12 },
923		{  36 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM18 },
924		{  48 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM24 },
925		{  72 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM36 },
926		{  96 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM48 },
927		{ 108 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM54 },
928		/* NB: OFDM72 doesn't realy exist so we don't handle it */
929	};
930	u_int mask, i;
931
932	mask = rate & IEEE80211_RATE_VAL;
933	switch (mode) {
934	case IEEE80211_MODE_11A:
935	case IEEE80211_MODE_TURBO_A:
936		mask |= IFM_IEEE80211_11A;
937		break;
938	case IEEE80211_MODE_11B:
939		mask |= IFM_IEEE80211_11B;
940		break;
941	case IEEE80211_MODE_FH:
942		mask |= IFM_IEEE80211_FH;
943		break;
944	case IEEE80211_MODE_AUTO:
945		/* NB: ic may be NULL for some drivers */
946		if (ic && ic->ic_phytype == IEEE80211_T_FH) {
947			mask |= IFM_IEEE80211_FH;
948			break;
949		}
950		/* NB: hack, 11g matches both 11b+11a rates */
951		/* fall thru... */
952	case IEEE80211_MODE_11G:
953	case IEEE80211_MODE_TURBO_G:
954		mask |= IFM_IEEE80211_11G;
955		break;
956	}
957	for (i = 0; i < N(rates); i++)
958		if (rates[i].m == mask)
959			return rates[i].r;
960	return IFM_AUTO;
961#undef N
962}
963
964int
965ieee80211_media2rate(int mword)
966{
967#define	N(a)	(sizeof(a) / sizeof(a[0]))
968	static const int ieeerates[] = {
969		-1,		/* IFM_AUTO */
970		0,		/* IFM_MANUAL */
971		0,		/* IFM_NONE */
972		2,		/* IFM_IEEE80211_FH1 */
973		4,		/* IFM_IEEE80211_FH2 */
974		2,		/* IFM_IEEE80211_DS1 */
975		4,		/* IFM_IEEE80211_DS2 */
976		11,		/* IFM_IEEE80211_DS5 */
977		22,		/* IFM_IEEE80211_DS11 */
978		44,		/* IFM_IEEE80211_DS22 */
979		12,		/* IFM_IEEE80211_OFDM6 */
980		18,		/* IFM_IEEE80211_OFDM9 */
981		24,		/* IFM_IEEE80211_OFDM12 */
982		36,		/* IFM_IEEE80211_OFDM18 */
983		48,		/* IFM_IEEE80211_OFDM24 */
984		72,		/* IFM_IEEE80211_OFDM36 */
985		96,		/* IFM_IEEE80211_OFDM48 */
986		108,		/* IFM_IEEE80211_OFDM54 */
987		144,		/* IFM_IEEE80211_OFDM72 */
988	};
989	return IFM_SUBTYPE(mword) < N(ieeerates) ?
990		ieeerates[IFM_SUBTYPE(mword)] : 0;
991#undef N
992}
993