Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.23-rc9 158 lines 4.9 kB view raw
1/* 2 * Copyright 2002-2005, Instant802 Networks, Inc. 3 * Copyright 2005-2006, Devicescape Software, Inc. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 */ 9 10/* 11 * This regulatory domain control implementation is known to be incomplete 12 * and confusing. mac80211 regulatory domain control will be significantly 13 * reworked in the not-too-distant future. 14 * 15 * For now, drivers wishing to control which channels are and aren't available 16 * are advised as follows: 17 * - set the IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED flag 18 * - continue to include *ALL* possible channels in the modes registered 19 * through ieee80211_register_hwmode() 20 * - for each allowable ieee80211_channel structure registered in the above 21 * call, set the flag member to some meaningful value such as 22 * IEEE80211_CHAN_W_SCAN | IEEE80211_CHAN_W_ACTIVE_SCAN | 23 * IEEE80211_CHAN_W_IBSS. 24 * - leave flag as 0 for non-allowable channels 25 * 26 * The usual implementation is for a driver to read a device EEPROM to 27 * determine which regulatory domain it should be operating under, then 28 * looking up the allowable channels in a driver-local table, then performing 29 * the above. 30 */ 31 32#include <linux/module.h> 33#include <linux/netdevice.h> 34#include <net/mac80211.h> 35#include "ieee80211_i.h" 36 37static int ieee80211_regdom = 0x10; /* FCC */ 38module_param(ieee80211_regdom, int, 0444); 39MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain; 64=MKK"); 40 41/* 42 * If firmware is upgraded by the vendor, additional channels can be used based 43 * on the new Japanese regulatory rules. This is indicated by setting 44 * ieee80211_japan_5ghz module parameter to one when loading the 80211 kernel 45 * module. 46 */ 47static int ieee80211_japan_5ghz /* = 0 */; 48module_param(ieee80211_japan_5ghz, int, 0444); 49MODULE_PARM_DESC(ieee80211_japan_5ghz, "Vendor-updated firmware for 5 GHz"); 50 51 52struct ieee80211_channel_range { 53 short start_freq; 54 short end_freq; 55 unsigned char power_level; 56 unsigned char antenna_max; 57}; 58 59static const struct ieee80211_channel_range ieee80211_fcc_channels[] = { 60 { 2412, 2462, 27, 6 } /* IEEE 802.11b/g, channels 1..11 */, 61 { 5180, 5240, 17, 6 } /* IEEE 802.11a, channels 36..48 */, 62 { 5260, 5320, 23, 6 } /* IEEE 802.11a, channels 52..64 */, 63 { 5745, 5825, 30, 6 } /* IEEE 802.11a, channels 149..165, outdoor */, 64 { 0 } 65}; 66 67static const struct ieee80211_channel_range ieee80211_mkk_channels[] = { 68 { 2412, 2472, 20, 6 } /* IEEE 802.11b/g, channels 1..13 */, 69 { 5170, 5240, 20, 6 } /* IEEE 802.11a, channels 34..48 */, 70 { 5260, 5320, 20, 6 } /* IEEE 802.11a, channels 52..64 */, 71 { 0 } 72}; 73 74 75static const struct ieee80211_channel_range *channel_range = 76 ieee80211_fcc_channels; 77 78 79static void ieee80211_unmask_channel(int mode, struct ieee80211_channel *chan) 80{ 81 int i; 82 83 chan->flag = 0; 84 85 if (ieee80211_regdom == 64 && 86 (mode == MODE_ATHEROS_TURBO || mode == MODE_ATHEROS_TURBOG)) { 87 /* Do not allow Turbo modes in Japan. */ 88 return; 89 } 90 91 for (i = 0; channel_range[i].start_freq; i++) { 92 const struct ieee80211_channel_range *r = &channel_range[i]; 93 if (r->start_freq <= chan->freq && r->end_freq >= chan->freq) { 94 if (ieee80211_regdom == 64 && !ieee80211_japan_5ghz && 95 chan->freq >= 5260 && chan->freq <= 5320) { 96 /* 97 * Skip new channels in Japan since the 98 * firmware was not marked having been upgraded 99 * by the vendor. 100 */ 101 continue; 102 } 103 104 if (ieee80211_regdom == 0x10 && 105 (chan->freq == 5190 || chan->freq == 5210 || 106 chan->freq == 5230)) { 107 /* Skip MKK channels when in FCC domain. */ 108 continue; 109 } 110 111 chan->flag |= IEEE80211_CHAN_W_SCAN | 112 IEEE80211_CHAN_W_ACTIVE_SCAN | 113 IEEE80211_CHAN_W_IBSS; 114 chan->power_level = r->power_level; 115 chan->antenna_max = r->antenna_max; 116 117 if (ieee80211_regdom == 64 && 118 (chan->freq == 5170 || chan->freq == 5190 || 119 chan->freq == 5210 || chan->freq == 5230)) { 120 /* 121 * New regulatory rules in Japan have backwards 122 * compatibility with old channels in 5.15-5.25 123 * GHz band, but the station is not allowed to 124 * use active scan on these old channels. 125 */ 126 chan->flag &= ~IEEE80211_CHAN_W_ACTIVE_SCAN; 127 } 128 129 if (ieee80211_regdom == 64 && 130 (chan->freq == 5260 || chan->freq == 5280 || 131 chan->freq == 5300 || chan->freq == 5320)) { 132 /* 133 * IBSS is not allowed on 5.25-5.35 GHz band 134 * due to radar detection requirements. 135 */ 136 chan->flag &= ~IEEE80211_CHAN_W_IBSS; 137 } 138 139 break; 140 } 141 } 142} 143 144 145void ieee80211_set_default_regdomain(struct ieee80211_hw_mode *mode) 146{ 147 int c; 148 for (c = 0; c < mode->num_channels; c++) 149 ieee80211_unmask_channel(mode->mode, &mode->channels[c]); 150} 151 152 153void ieee80211_regdomain_init(void) 154{ 155 if (ieee80211_regdom == 0x40) 156 channel_range = ieee80211_mkk_channels; 157} 158