zd_ieee80211.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /* ZD1211 USB-WLAN driver for Linux
  2. *
  3. * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
  4. * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. /*
  21. * In the long term, we'll probably find a better way of handling regulatory
  22. * requirements outside of the driver.
  23. */
  24. #include <linux/kernel.h>
  25. #include <net/mac80211.h>
  26. #include "zd_ieee80211.h"
  27. #include "zd_mac.h"
  28. struct channel_range {
  29. u8 regdomain;
  30. u8 start;
  31. u8 end; /* exclusive (channel must be less than end) */
  32. };
  33. static const struct channel_range channel_ranges[] = {
  34. { ZD_REGDOMAIN_FCC, 1, 12 },
  35. { ZD_REGDOMAIN_IC, 1, 12 },
  36. { ZD_REGDOMAIN_ETSI, 1, 14 },
  37. { ZD_REGDOMAIN_JAPAN, 1, 14 },
  38. { ZD_REGDOMAIN_SPAIN, 1, 14 },
  39. { ZD_REGDOMAIN_FRANCE, 1, 14 },
  40. /* Japan originally only had channel 14 available (see CHNL_ID 0x40 in
  41. * 802.11). However, in 2001 the range was extended to include channels
  42. * 1-13. The ZyDAS devices still use the old region code but are
  43. * designed to allow the extra channel access in Japan. */
  44. { ZD_REGDOMAIN_JAPAN_ADD, 1, 15 },
  45. };
  46. static const struct channel_range *zd_channel_range(u8 regdomain)
  47. {
  48. int i;
  49. for (i = 0; i < ARRAY_SIZE(channel_ranges); i++) {
  50. const struct channel_range *range = &channel_ranges[i];
  51. if (range->regdomain == regdomain)
  52. return range;
  53. }
  54. return NULL;
  55. }
  56. #define CHAN_TO_IDX(chan) ((chan) - 1)
  57. static void unmask_bg_channels(struct ieee80211_hw *hw,
  58. const struct channel_range *range,
  59. struct ieee80211_supported_band *sband)
  60. {
  61. u8 channel;
  62. for (channel = range->start; channel < range->end; channel++) {
  63. struct ieee80211_channel *chan =
  64. &sband->channels[CHAN_TO_IDX(channel)];
  65. chan->flags = 0;
  66. }
  67. }
  68. void zd_geo_init(struct ieee80211_hw *hw, u8 regdomain)
  69. {
  70. struct zd_mac *mac = zd_hw_mac(hw);
  71. const struct channel_range *range;
  72. dev_dbg(zd_mac_dev(mac), "regdomain %#02x\n", regdomain);
  73. range = zd_channel_range(regdomain);
  74. if (!range) {
  75. /* The vendor driver overrides the regulatory domain and
  76. * allowed channel registers and unconditionally restricts
  77. * available channels to 1-11 everywhere. Match their
  78. * questionable behaviour only for regdomains which we don't
  79. * recognise. */
  80. dev_warn(zd_mac_dev(mac), "Unrecognised regulatory domain: "
  81. "%#02x. Defaulting to FCC.\n", regdomain);
  82. range = zd_channel_range(ZD_REGDOMAIN_FCC);
  83. }
  84. unmask_bg_channels(hw, range, &mac->band);
  85. }