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