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