Deleted Added
sdiff udiff text old ( 165825 ) new ( 166012 )
full compact
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:

--- 17 unchanged lines hidden (view full) ---

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 166012 2007-01-15 01:12:28Z 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>

--- 219 unchanged lines hidden (view full) ---

262void
263ieee80211_ifdetach(struct ieee80211com *ic)
264{
265 struct ifnet *ifp = ic->ic_ifp;
266
267 ieee80211_remove_vap(ic);
268
269 ieee80211_sysctl_detach(ic);
270 /* NB: must be called before ieee80211_node_detach */
271 ieee80211_proto_detach(ic);
272 ieee80211_crypto_detach(ic);
273 ieee80211_node_detach(ic);
274 ifmedia_removeall(&ic->ic_media);
275
276 IEEE80211_BEACON_LOCK_DESTROY(ic);
277
278 bpfdetach(ifp);
279 ether_ifdetach(ifp);
280}
281
282static __inline int
283mapgsm(u_int freq, u_int flags)
284{
285 freq *= 10;
286 if (flags & IEEE80211_CHAN_QUARTER)
287 freq += 5;
288 else if (flags & IEEE80211_CHAN_HALF)
289 freq += 10;
290 else
291 freq += 20;
292 /* NB: there is no 907/20 wide but leave room */
293 return (freq - 906*10) / 5;
294}
295
296static __inline int
297mappsb(u_int freq, u_int flags)
298{
299 return 37 + ((freq * 10) + ((freq % 5) == 2 ? 5 : 0) - 49400) / 5;
300}
301
302/*
303 * Convert MHz frequency to IEEE channel number.
304 */
305int
306ieee80211_mhz2ieee(u_int freq, u_int flags)
307{
308 if (flags & IEEE80211_CHAN_GSM)
309 return mapgsm(freq, flags);
310 if (flags & IEEE80211_CHAN_2GHZ) { /* 2GHz band */
311 if (freq == 2484)
312 return 14;
313 if (freq < 2484)
314 return ((int) freq - 2407) / 5;
315 else
316 return 15 + ((freq - 2512) / 20);
317 } else if (flags & IEEE80211_CHAN_5GHZ) { /* 5Ghz band */
318 if (freq <= 5000) {
319 if (flags &(IEEE80211_CHAN_HALF|IEEE80211_CHAN_QUARTER))
320 return mappsb(freq, flags);
321 return (freq - 4000) / 5;
322 } else
323 return (freq - 5000) / 5;
324 } else { /* either, guess */
325 if (freq == 2484)
326 return 14;
327 if (freq < 2484) {
328 if (907 <= freq && freq <= 922)
329 return mapgsm(freq, flags);
330 return ((int) freq - 2407) / 5;
331 }
332 if (freq < 5000) {
333 if (flags &(IEEE80211_CHAN_HALF|IEEE80211_CHAN_QUARTER))
334 return mappsb(freq, flags);
335 else if (freq > 4900)
336 return (freq - 4000) / 5;
337 else
338 return 15 + ((freq - 2512) / 20);
339 }
340 return (freq - 5000) / 5;
341 }
342}

--- 19 unchanged lines hidden (view full) ---

362}
363
364/*
365 * Convert IEEE channel number to MHz frequency.
366 */
367u_int
368ieee80211_ieee2mhz(u_int chan, u_int flags)
369{
370 if (flags & IEEE80211_CHAN_GSM)
371 return 907 + 5 * (chan / 10);
372 if (flags & IEEE80211_CHAN_2GHZ) { /* 2GHz band */
373 if (chan == 14)
374 return 2484;
375 if (chan < 14)
376 return 2407 + chan*5;
377 else
378 return 2512 + ((chan-15)*20);
379 } else if (flags & IEEE80211_CHAN_5GHZ) {/* 5Ghz band */
380 if (flags & (IEEE80211_CHAN_HALF|IEEE80211_CHAN_QUARTER)) {
381 chan -= 37;
382 return 4940 + chan*5 + (chan % 5 ? 2 : 0);
383 }
384 return 5000 + (chan*5);
385 } else { /* either, guess */
386 /* XXX can't distinguish PSB+GSM channels */
387 if (chan == 14)
388 return 2484;
389 if (chan < 14) /* 0-13 */
390 return 2407 + chan*5;
391 if (chan < 27) /* 15-26 */
392 return 2512 + ((chan-15)*20);
393 return 5000 + (chan*5);
394 }
395}
396
397/*
398 * Setup the media data structures according to the channel and
399 * rate tables. This must be called by the driver after
400 * ieee80211_attach and before most anything else.

--- 114 unchanged lines hidden (view full) ---

515#undef ADD
516}
517
518const struct ieee80211_rateset *
519ieee80211_get_suprates(struct ieee80211com *ic, const struct ieee80211_channel *c)
520{
521 enum ieee80211_phymode mode = ieee80211_chan2mode(ic, c);
522
523 if (IEEE80211_IS_CHAN_HALF(c))
524 return &ieee80211_rateset_half;
525 if (IEEE80211_IS_CHAN_QUARTER(c))
526 return &ieee80211_rateset_quarter;
527 return &ic->ic_sup_rates[mode];
528}
529
530void
531ieee80211_announce(struct ieee80211com *ic)
532{
533 struct ifnet *ifp = ic->ic_ifp;
534 int i, mode, rate, mword;

--- 250 unchanged lines hidden (view full) ---

785 imr->ifm_status |= IFM_ACTIVE;
786 /*
787 * Calculate a current rate if possible.
788 */
789 if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) {
790 /*
791 * A fixed rate is set, report that.
792 */
793 rs = ieee80211_get_suprates(ic, ic->ic_curchan);
794 imr->ifm_active |= ieee80211_rate2media(ic,
795 rs->rs_rates[ic->ic_fixed_rate], ic->ic_curmode);
796 } else if (ic->ic_opmode == IEEE80211_M_STA) {
797 /*
798 * In station mode report the current transmit rate.
799 */
800 rs = &ic->ic_bss->ni_rates;
801 imr->ifm_active |= ieee80211_rate2media(ic,

--- 140 unchanged lines hidden (view full) ---

942 }
943 }
944 /*
945 * If no current/default channel is setup or the current
946 * channel is wrong for the mode then pick the first
947 * available channel from the active list. This is likely
948 * not the right one.
949 */
950 if (isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, ic->ic_curchan))) {
951 ic->ic_curchan = NULL;
952 for (i = 0; i <= IEEE80211_CHAN_MAX; i++)
953 if (isset(ic->ic_chan_active, i)) {
954 ic->ic_curchan = &ic->ic_channels[i];
955 break;
956 }
957 KASSERT(ic->ic_curchan != NULL, ("no current channel"));
958 }
959 if (ic->ic_ibss_chan == NULL ||
960 isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, ic->ic_ibss_chan)))
961 ic->ic_ibss_chan = ic->ic_curchan;
962 /*
963 * If the desired channel is set but no longer valid then reset it.
964 */
965 if (ic->ic_des_chan != IEEE80211_CHAN_ANYC &&
966 isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, ic->ic_des_chan)))
967 ic->ic_des_chan = IEEE80211_CHAN_ANYC;
968
969 /*
970 * Adjust basic rates in 11b/11g supported rate set.
971 * Note that if operating on a hal/quarter rate channel
972 * this is a noop as those rates sets are different
973 * and used instead.
974 */
975 if (mode == IEEE80211_MODE_11G || mode == IEEE80211_MODE_11B)
976 ieee80211_set11gbasicrates(&ic->ic_sup_rates[mode], mode);
977
978 /*
979 * Setup an initial rate set according to the
980 * current/default channel selected above. This
981 * will be changed when scanning but must exist
982 * now so driver have a consistent state of ic_ibss_chan.
983 */
984 if (ic->ic_bss != NULL) /* NB: can be called before lateattach */
985 ic->ic_bss->ni_rates = ic->ic_sup_rates[mode];
986
987 ic->ic_curmode = mode;
988 ieee80211_reset_erp(ic); /* reset ERP state */
989 ieee80211_wme_initparams(ic); /* reset WME stat */
990
991 return 0;
992#undef N

--- 143 unchanged lines hidden ---