ah_regdomain.c revision 185377
1/* 2 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting 3 * Copyright (c) 2005-2006 Atheros Communications, Inc. 4 * All rights reserved. 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 * $Id: ah_regdomain.c,v 1.17 2008/11/10 04:08:00 sam Exp $ 19 */ 20#include "opt_ah.h" 21 22#include "ah.h" 23#include "ah_internal.h" 24#include "ah_eeprom.h" 25#include "ah_devid.h" 26 27/* 28 * XXX this code needs a audit+review 29 */ 30 31/* used throughout this file... */ 32#define N(a) (sizeof (a) / sizeof (a[0])) 33 34#define HAL_MODE_11A_TURBO HAL_MODE_108A 35#define HAL_MODE_11G_TURBO HAL_MODE_108G 36 37/* 10MHz is half the 11A bandwidth used to determine upper edge freq 38 of the outdoor channel */ 39#define HALF_MAXCHANBW 10 40 41/* 42 * Used to set the RegDomain bitmask which chooses which frequency 43 * band specs are used. 44 */ 45 46#define BMLEN 2 /* Use 2 64 bit uint for channel bitmask 47 NB: Must agree with macro below (BM) */ 48#define BMZERO {(uint64_t) 0, (uint64_t) 0} /* BMLEN zeros */ 49 50#define BM(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh, _fi, _fj, _fk, _fl) \ 51 {((((_fa >= 0) && (_fa < 64)) ? (((uint64_t) 1) << _fa) : (uint64_t) 0) | \ 52 (((_fb >= 0) && (_fb < 64)) ? (((uint64_t) 1) << _fb) : (uint64_t) 0) | \ 53 (((_fc >= 0) && (_fc < 64)) ? (((uint64_t) 1) << _fc) : (uint64_t) 0) | \ 54 (((_fd >= 0) && (_fd < 64)) ? (((uint64_t) 1) << _fd) : (uint64_t) 0) | \ 55 (((_fe >= 0) && (_fe < 64)) ? (((uint64_t) 1) << _fe) : (uint64_t) 0) | \ 56 (((_ff >= 0) && (_ff < 64)) ? (((uint64_t) 1) << _ff) : (uint64_t) 0) | \ 57 (((_fg >= 0) && (_fg < 64)) ? (((uint64_t) 1) << _fg) : (uint64_t) 0) | \ 58 (((_fh >= 0) && (_fh < 64)) ? (((uint64_t) 1) << _fh) : (uint64_t) 0) | \ 59 (((_fi >= 0) && (_fi < 64)) ? (((uint64_t) 1) << _fi) : (uint64_t) 0) | \ 60 (((_fj >= 0) && (_fj < 64)) ? (((uint64_t) 1) << _fj) : (uint64_t) 0) | \ 61 (((_fk >= 0) && (_fk < 64)) ? (((uint64_t) 1) << _fk) : (uint64_t) 0) | \ 62 (((_fl >= 0) && (_fl < 64)) ? (((uint64_t) 1) << _fl) : (uint64_t) 0) | \ 63 ((((_fa > 63) && (_fa < 128)) ? (((uint64_t) 1) << (_fa - 64)) : (uint64_t) 0) | \ 64 (((_fb > 63) && (_fb < 128)) ? (((uint64_t) 1) << (_fb - 64)) : (uint64_t) 0) | \ 65 (((_fc > 63) && (_fc < 128)) ? (((uint64_t) 1) << (_fc - 64)) : (uint64_t) 0) | \ 66 (((_fd > 63) && (_fd < 128)) ? (((uint64_t) 1) << (_fd - 64)) : (uint64_t) 0) | \ 67 (((_fe > 63) && (_fe < 128)) ? (((uint64_t) 1) << (_fe - 64)) : (uint64_t) 0) | \ 68 (((_ff > 63) && (_ff < 128)) ? (((uint64_t) 1) << (_ff - 64)) : (uint64_t) 0) | \ 69 (((_fg > 63) && (_fg < 128)) ? (((uint64_t) 1) << (_fg - 64)) : (uint64_t) 0) | \ 70 (((_fh > 63) && (_fh < 128)) ? (((uint64_t) 1) << (_fh - 64)) : (uint64_t) 0) | \ 71 (((_fi > 63) && (_fi < 128)) ? (((uint64_t) 1) << (_fi - 64)) : (uint64_t) 0) | \ 72 (((_fj > 63) && (_fj < 128)) ? (((uint64_t) 1) << (_fj - 64)) : (uint64_t) 0) | \ 73 (((_fk > 63) && (_fk < 128)) ? (((uint64_t) 1) << (_fk - 64)) : (uint64_t) 0) | \ 74 (((_fl > 63) && (_fl < 128)) ? (((uint64_t) 1) << (_fl - 64)) : (uint64_t) 0)))} 75 76/* 77 * Country/Region Codes 78 * Numbering from ISO 3166 79 */ 80enum CountryCode { 81 CTRY_ALBANIA = 8, /* Albania */ 82 CTRY_ALGERIA = 12, /* Algeria */ 83 CTRY_ARGENTINA = 32, /* Argentina */ 84 CTRY_ARMENIA = 51, /* Armenia */ 85 CTRY_AUSTRALIA = 36, /* Australia */ 86 CTRY_AUSTRIA = 40, /* Austria */ 87 CTRY_AZERBAIJAN = 31, /* Azerbaijan */ 88 CTRY_BAHRAIN = 48, /* Bahrain */ 89 CTRY_BELARUS = 112, /* Belarus */ 90 CTRY_BELGIUM = 56, /* Belgium */ 91 CTRY_BELIZE = 84, /* Belize */ 92 CTRY_BOLIVIA = 68, /* Bolivia */ 93 CTRY_BRAZIL = 76, /* Brazil */ 94 CTRY_BRUNEI_DARUSSALAM = 96, /* Brunei Darussalam */ 95 CTRY_BULGARIA = 100, /* Bulgaria */ 96 CTRY_CANADA = 124, /* Canada */ 97 CTRY_CHILE = 152, /* Chile */ 98 CTRY_CHINA = 156, /* People's Republic of China */ 99 CTRY_COLOMBIA = 170, /* Colombia */ 100 CTRY_COSTA_RICA = 188, /* Costa Rica */ 101 CTRY_CROATIA = 191, /* Croatia */ 102 CTRY_CYPRUS = 196, 103 CTRY_CZECH = 203, /* Czech Republic */ 104 CTRY_DENMARK = 208, /* Denmark */ 105 CTRY_DOMINICAN_REPUBLIC = 214, /* Dominican Republic */ 106 CTRY_ECUADOR = 218, /* Ecuador */ 107 CTRY_EGYPT = 818, /* Egypt */ 108 CTRY_EL_SALVADOR = 222, /* El Salvador */ 109 CTRY_ESTONIA = 233, /* Estonia */ 110 CTRY_FAEROE_ISLANDS = 234, /* Faeroe Islands */ 111 CTRY_FINLAND = 246, /* Finland */ 112 CTRY_FRANCE = 250, /* France */ 113 CTRY_FRANCE2 = 255, /* France2 */ 114 CTRY_GEORGIA = 268, /* Georgia */ 115 CTRY_GERMANY = 276, /* Germany */ 116 CTRY_GREECE = 300, /* Greece */ 117 CTRY_GUATEMALA = 320, /* Guatemala */ 118 CTRY_HONDURAS = 340, /* Honduras */ 119 CTRY_HONG_KONG = 344, /* Hong Kong S.A.R., P.R.C. */ 120 CTRY_HUNGARY = 348, /* Hungary */ 121 CTRY_ICELAND = 352, /* Iceland */ 122 CTRY_INDIA = 356, /* India */ 123 CTRY_INDONESIA = 360, /* Indonesia */ 124 CTRY_IRAN = 364, /* Iran */ 125 CTRY_IRAQ = 368, /* Iraq */ 126 CTRY_IRELAND = 372, /* Ireland */ 127 CTRY_ISRAEL = 376, /* Israel */ 128 CTRY_ITALY = 380, /* Italy */ 129 CTRY_JAMAICA = 388, /* Jamaica */ 130 CTRY_JAPAN = 392, /* Japan */ 131 CTRY_JAPAN1 = 393, /* Japan (JP1) */ 132 CTRY_JAPAN2 = 394, /* Japan (JP0) */ 133 CTRY_JAPAN3 = 395, /* Japan (JP1-1) */ 134 CTRY_JAPAN4 = 396, /* Japan (JE1) */ 135 CTRY_JAPAN5 = 397, /* Japan (JE2) */ 136 CTRY_JAPAN6 = 399, /* Japan (JP6) */ 137 138 CTRY_JAPAN7 = 4007, /* Japan (J7) */ 139 CTRY_JAPAN8 = 4008, /* Japan (J8) */ 140 CTRY_JAPAN9 = 4009, /* Japan (J9) */ 141 142 CTRY_JAPAN10 = 4010, /* Japan (J10) */ 143 CTRY_JAPAN11 = 4011, /* Japan (J11) */ 144 CTRY_JAPAN12 = 4012, /* Japan (J12) */ 145 146 CTRY_JAPAN13 = 4013, /* Japan (J13) */ 147 CTRY_JAPAN14 = 4014, /* Japan (J14) */ 148 CTRY_JAPAN15 = 4015, /* Japan (J15) */ 149 150 CTRY_JAPAN16 = 4016, /* Japan (J16) */ 151 CTRY_JAPAN17 = 4017, /* Japan (J17) */ 152 CTRY_JAPAN18 = 4018, /* Japan (J18) */ 153 154 CTRY_JAPAN19 = 4019, /* Japan (J19) */ 155 CTRY_JAPAN20 = 4020, /* Japan (J20) */ 156 CTRY_JAPAN21 = 4021, /* Japan (J21) */ 157 158 CTRY_JAPAN22 = 4022, /* Japan (J22) */ 159 CTRY_JAPAN23 = 4023, /* Japan (J23) */ 160 CTRY_JAPAN24 = 4024, /* Japan (J24) */ 161 162 CTRY_JORDAN = 400, /* Jordan */ 163 CTRY_KAZAKHSTAN = 398, /* Kazakhstan */ 164 CTRY_KENYA = 404, /* Kenya */ 165 CTRY_KOREA_NORTH = 408, /* North Korea */ 166 CTRY_KOREA_ROC = 410, /* South Korea */ 167 CTRY_KOREA_ROC2 = 411, /* South Korea */ 168 CTRY_KOREA_ROC3 = 412, /* South Korea */ 169 CTRY_KUWAIT = 414, /* Kuwait */ 170 CTRY_LATVIA = 428, /* Latvia */ 171 CTRY_LEBANON = 422, /* Lebanon */ 172 CTRY_LIBYA = 434, /* Libya */ 173 CTRY_LIECHTENSTEIN = 438, /* Liechtenstein */ 174 CTRY_LITHUANIA = 440, /* Lithuania */ 175 CTRY_LUXEMBOURG = 442, /* Luxembourg */ 176 CTRY_MACAU = 446, /* Macau */ 177 CTRY_MACEDONIA = 807, /* the Former Yugoslav Republic of Macedonia */ 178 CTRY_MALAYSIA = 458, /* Malaysia */ 179 CTRY_MALTA = 470, /* Malta */ 180 CTRY_MEXICO = 484, /* Mexico */ 181 CTRY_MONACO = 492, /* Principality of Monaco */ 182 CTRY_MOROCCO = 504, /* Morocco */ 183 CTRY_NETHERLANDS = 528, /* Netherlands */ 184 CTRY_NEW_ZEALAND = 554, /* New Zealand */ 185 CTRY_NICARAGUA = 558, /* Nicaragua */ 186 CTRY_NORWAY = 578, /* Norway */ 187 CTRY_OMAN = 512, /* Oman */ 188 CTRY_PAKISTAN = 586, /* Islamic Republic of Pakistan */ 189 CTRY_PANAMA = 591, /* Panama */ 190 CTRY_PARAGUAY = 600, /* Paraguay */ 191 CTRY_PERU = 604, /* Peru */ 192 CTRY_PHILIPPINES = 608, /* Republic of the Philippines */ 193 CTRY_POLAND = 616, /* Poland */ 194 CTRY_PORTUGAL = 620, /* Portugal */ 195 CTRY_PUERTO_RICO = 630, /* Puerto Rico */ 196 CTRY_QATAR = 634, /* Qatar */ 197 CTRY_ROMANIA = 642, /* Romania */ 198 CTRY_RUSSIA = 643, /* Russia */ 199 CTRY_SAUDI_ARABIA = 682, /* Saudi Arabia */ 200 CTRY_SINGAPORE = 702, /* Singapore */ 201 CTRY_SLOVAKIA = 703, /* Slovak Republic */ 202 CTRY_SLOVENIA = 705, /* Slovenia */ 203 CTRY_SOUTH_AFRICA = 710, /* South Africa */ 204 CTRY_SPAIN = 724, /* Spain */ 205 CTRY_SWEDEN = 752, /* Sweden */ 206 CTRY_SWITZERLAND = 756, /* Switzerland */ 207 CTRY_SYRIA = 760, /* Syria */ 208 CTRY_TAIWAN = 158, /* Taiwan */ 209 CTRY_THAILAND = 764, /* Thailand */ 210 CTRY_TRINIDAD_Y_TOBAGO = 780, /* Trinidad y Tobago */ 211 CTRY_TUNISIA = 788, /* Tunisia */ 212 CTRY_TURKEY = 792, /* Turkey */ 213 CTRY_UAE = 784, /* U.A.E. */ 214 CTRY_UKRAINE = 804, /* Ukraine */ 215 CTRY_UNITED_KINGDOM = 826, /* United Kingdom */ 216 CTRY_UNITED_STATES = 840, /* United States */ 217 CTRY_UNITED_STATES_FCC49 = 842, /* United States (Public Safety)*/ 218 CTRY_URUGUAY = 858, /* Uruguay */ 219 CTRY_UZBEKISTAN = 860, /* Uzbekistan */ 220 CTRY_VENEZUELA = 862, /* Venezuela */ 221 CTRY_VIET_NAM = 704, /* Viet Nam */ 222 CTRY_YEMEN = 887, /* Yemen */ 223 CTRY_ZIMBABWE = 716 /* Zimbabwe */ 224}; 225 226 227/* Mask to check whether a domain is a multidomain or a single 228 domain */ 229 230#define MULTI_DOMAIN_MASK 0xFF00 231 232/* Enumerated Regulatory Domain Information 8 bit values indicate that 233 * the regdomain is really a pair of unitary regdomains. 12 bit values 234 * are the real unitary regdomains and are the only ones which have the 235 * frequency bitmasks and flags set. 236 */ 237 238enum EnumRd { 239 /* 240 * The following regulatory domain definitions are 241 * found in the EEPROM. Each regulatory domain 242 * can operate in either a 5GHz or 2.4GHz wireless mode or 243 * both 5GHz and 2.4GHz wireless modes. 244 * In general, the value holds no special 245 * meaning and is used to decode into either specific 246 * 2.4GHz or 5GHz wireless mode for that particular 247 * regulatory domain. 248 */ 249 NO_ENUMRD = 0x00, 250 NULL1_WORLD = 0x03, /* For 11b-only countries (no 11a allowed) */ 251 NULL1_ETSIB = 0x07, /* Israel */ 252 NULL1_ETSIC = 0x08, 253 FCC1_FCCA = 0x10, /* USA */ 254 FCC1_WORLD = 0x11, /* Hong Kong */ 255 FCC4_FCCA = 0x12, /* USA - Public Safety */ 256 257 FCC2_FCCA = 0x20, /* Canada */ 258 FCC2_WORLD = 0x21, /* Australia & HK */ 259 FCC2_ETSIC = 0x22, 260 FRANCE_RES = 0x31, /* Legacy France for OEM */ 261 FCC3_FCCA = 0x3A, /* USA & Canada w/5470 band, 11h, DFS enabled */ 262 FCC3_WORLD = 0x3B, /* USA & Canada w/5470 band, 11h, DFS enabled */ 263 264 ETSI1_WORLD = 0x37, 265 ETSI3_ETSIA = 0x32, /* France (optional) */ 266 ETSI2_WORLD = 0x35, /* Hungary & others */ 267 ETSI3_WORLD = 0x36, /* France & others */ 268 ETSI4_WORLD = 0x30, 269 ETSI4_ETSIC = 0x38, 270 ETSI5_WORLD = 0x39, 271 ETSI6_WORLD = 0x34, /* Bulgaria */ 272 ETSI_RESERVED = 0x33, /* Reserved (Do not used) */ 273 274 MKK1_MKKA = 0x40, /* Japan (JP1) */ 275 MKK1_MKKB = 0x41, /* Japan (JP0) */ 276 APL4_WORLD = 0x42, /* Singapore */ 277 MKK2_MKKA = 0x43, /* Japan with 4.9G channels */ 278 APL_RESERVED = 0x44, /* Reserved (Do not used) */ 279 APL2_WORLD = 0x45, /* Korea */ 280 APL2_APLC = 0x46, 281 APL3_WORLD = 0x47, 282 MKK1_FCCA = 0x48, /* Japan (JP1-1) */ 283 APL2_APLD = 0x49, /* Korea with 2.3G channels */ 284 MKK1_MKKA1 = 0x4A, /* Japan (JE1) */ 285 MKK1_MKKA2 = 0x4B, /* Japan (JE2) */ 286 MKK1_MKKC = 0x4C, /* Japan (MKK1_MKKA,except Ch14) */ 287 288 APL3_FCCA = 0x50, 289 APL1_WORLD = 0x52, /* Latin America */ 290 APL1_FCCA = 0x53, 291 APL1_APLA = 0x54, 292 APL1_ETSIC = 0x55, 293 APL2_ETSIC = 0x56, /* Venezuela */ 294 APL5_WORLD = 0x58, /* Chile */ 295 APL6_WORLD = 0x5B, /* Singapore */ 296 APL7_FCCA = 0x5C, /* Taiwan 5.47 Band */ 297 APL8_WORLD = 0x5D, /* Malaysia 5GHz */ 298 APL9_WORLD = 0x5E, /* Korea 5GHz */ 299 300 /* 301 * World mode SKUs 302 */ 303 WOR0_WORLD = 0x60, /* World0 (WO0 SKU) */ 304 WOR1_WORLD = 0x61, /* World1 (WO1 SKU) */ 305 WOR2_WORLD = 0x62, /* World2 (WO2 SKU) */ 306 WOR3_WORLD = 0x63, /* World3 (WO3 SKU) */ 307 WOR4_WORLD = 0x64, /* World4 (WO4 SKU) */ 308 WOR5_ETSIC = 0x65, /* World5 (WO5 SKU) */ 309 310 WOR01_WORLD = 0x66, /* World0-1 (WW0-1 SKU) */ 311 WOR02_WORLD = 0x67, /* World0-2 (WW0-2 SKU) */ 312 EU1_WORLD = 0x68, /* Same as World0-2 (WW0-2 SKU), except active scan ch1-13. No ch14 */ 313 314 WOR9_WORLD = 0x69, /* World9 (WO9 SKU) */ 315 WORA_WORLD = 0x6A, /* WorldA (WOA SKU) */ 316 317 MKK3_MKKB = 0x80, /* Japan UNI-1 even + MKKB */ 318 MKK3_MKKA2 = 0x81, /* Japan UNI-1 even + MKKA2 */ 319 MKK3_MKKC = 0x82, /* Japan UNI-1 even + MKKC */ 320 321 MKK4_MKKB = 0x83, /* Japan UNI-1 even + UNI-2 + MKKB */ 322 MKK4_MKKA2 = 0x84, /* Japan UNI-1 even + UNI-2 + MKKA2 */ 323 MKK4_MKKC = 0x85, /* Japan UNI-1 even + UNI-2 + MKKC */ 324 325 MKK5_MKKB = 0x86, /* Japan UNI-1 even + UNI-2 + mid-band + MKKB */ 326 MKK5_MKKA2 = 0x87, /* Japan UNI-1 even + UNI-2 + mid-band + MKKA2 */ 327 MKK5_MKKC = 0x88, /* Japan UNI-1 even + UNI-2 + mid-band + MKKC */ 328 329 MKK6_MKKB = 0x89, /* Japan UNI-1 even + UNI-1 odd MKKB */ 330 MKK6_MKKA2 = 0x8A, /* Japan UNI-1 even + UNI-1 odd + MKKA2 */ 331 MKK6_MKKC = 0x8B, /* Japan UNI-1 even + UNI-1 odd + MKKC */ 332 333 MKK7_MKKB = 0x8C, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKB */ 334 MKK7_MKKA2 = 0x8D, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA2 */ 335 MKK7_MKKC = 0x8E, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKC */ 336 337 MKK8_MKKB = 0x8F, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKB */ 338 MKK8_MKKA2 = 0x90, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKA2 */ 339 MKK8_MKKC = 0x91, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKC */ 340 341 /* Following definitions are used only by s/w to map old 342 * Japan SKUs. 343 */ 344 MKK3_MKKA = 0xF0, /* Japan UNI-1 even + MKKA */ 345 MKK3_MKKA1 = 0xF1, /* Japan UNI-1 even + MKKA1 */ 346 MKK3_FCCA = 0xF2, /* Japan UNI-1 even + FCCA */ 347 MKK4_MKKA = 0xF3, /* Japan UNI-1 even + UNI-2 + MKKA */ 348 MKK4_MKKA1 = 0xF4, /* Japan UNI-1 even + UNI-2 + MKKA1 */ 349 MKK4_FCCA = 0xF5, /* Japan UNI-1 even + UNI-2 + FCCA */ 350 MKK9_MKKA = 0xF6, /* Japan UNI-1 even + 4.9GHz */ 351 MKK10_MKKA = 0xF7, /* Japan UNI-1 even + UNI-2 + 4.9GHz */ 352 353 /* 354 * Regulator domains ending in a number (e.g. APL1, 355 * MK1, ETSI4, etc) apply to 5GHz channel and power 356 * information. Regulator domains ending in a letter 357 * (e.g. APLA, FCCA, etc) apply to 2.4GHz channel and 358 * power information. 359 */ 360 APL1 = 0x0150, /* LAT & Asia */ 361 APL2 = 0x0250, /* LAT & Asia */ 362 APL3 = 0x0350, /* Taiwan */ 363 APL4 = 0x0450, /* Jordan */ 364 APL5 = 0x0550, /* Chile */ 365 APL6 = 0x0650, /* Singapore */ 366 APL8 = 0x0850, /* Malaysia */ 367 APL9 = 0x0950, /* Korea (South) ROC 3 */ 368 369 ETSI1 = 0x0130, /* Europe & others */ 370 ETSI2 = 0x0230, /* Europe & others */ 371 ETSI3 = 0x0330, /* Europe & others */ 372 ETSI4 = 0x0430, /* Europe & others */ 373 ETSI5 = 0x0530, /* Europe & others */ 374 ETSI6 = 0x0630, /* Europe & others */ 375 ETSIA = 0x0A30, /* France */ 376 ETSIB = 0x0B30, /* Israel */ 377 ETSIC = 0x0C30, /* Latin America */ 378 379 FCC1 = 0x0110, /* US & others */ 380 FCC2 = 0x0120, /* Canada, Australia & New Zealand */ 381 FCC3 = 0x0160, /* US w/new middle band & DFS */ 382 FCC4 = 0x0165, /* US Public Safety */ 383 FCCA = 0x0A10, 384 385 APLD = 0x0D50, /* South Korea */ 386 387 MKK1 = 0x0140, /* Japan (UNI-1 odd)*/ 388 MKK2 = 0x0240, /* Japan (4.9 GHz + UNI-1 odd) */ 389 MKK3 = 0x0340, /* Japan (UNI-1 even) */ 390 MKK4 = 0x0440, /* Japan (UNI-1 even + UNI-2) */ 391 MKK5 = 0x0540, /* Japan (UNI-1 even + UNI-2 + mid-band) */ 392 MKK6 = 0x0640, /* Japan (UNI-1 odd + UNI-1 even) */ 393 MKK7 = 0x0740, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 */ 394 MKK8 = 0x0840, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 + mid-band) */ 395 MKK9 = 0x0940, /* Japan (UNI-1 even + 4.9 GHZ) */ 396 MKK10 = 0x0B40, /* Japan (UNI-1 even + UNI-2 + 4.9 GHZ) */ 397 MKKA = 0x0A40, /* Japan */ 398 MKKC = 0x0A50, 399 400 NULL1 = 0x0198, 401 WORLD = 0x0199, 402 DEBUG_REG_DMN = 0x01ff, 403}; 404 405#define WORLD_SKU_MASK 0x00F0 406#define WORLD_SKU_PREFIX 0x0060 407 408enum { /* conformance test limits */ 409 FCC = 0x10, 410 MKK = 0x40, 411 ETSI = 0x30, 412}; 413 414/* 415 * The following are flags for different requirements per reg domain. 416 * These requirements are either inhereted from the reg domain pair or 417 * from the unitary reg domain if the reg domain pair flags value is 418 * 0 419 */ 420 421enum { 422 NO_REQ = 0x00000000, 423 DISALLOW_ADHOC_11A = 0x00000001, 424 DISALLOW_ADHOC_11A_TURB = 0x00000002, 425 NEED_NFC = 0x00000004, 426 427 ADHOC_PER_11D = 0x00000008, /* Start Ad-Hoc mode */ 428 ADHOC_NO_11A = 0x00000010, 429 430 PUBLIC_SAFETY_DOMAIN = 0x00000020, /* public safety domain */ 431 LIMIT_FRAME_4MS = 0x00000040, /* 4msec limit on the frame length */ 432 433 NO_HOSTAP = 0x00000080, /* No HOSTAP mode opereation */ 434}; 435 436/* 437 * The following describe the bit masks for different passive scan 438 * capability/requirements per regdomain. 439 */ 440#define NO_PSCAN 0x0ULL 441#define PSCAN_FCC 0x0000000000000001ULL 442#define PSCAN_FCC_T 0x0000000000000002ULL 443#define PSCAN_ETSI 0x0000000000000004ULL 444#define PSCAN_MKK1 0x0000000000000008ULL 445#define PSCAN_MKK2 0x0000000000000010ULL 446#define PSCAN_MKKA 0x0000000000000020ULL 447#define PSCAN_MKKA_G 0x0000000000000040ULL 448#define PSCAN_ETSIA 0x0000000000000080ULL 449#define PSCAN_ETSIB 0x0000000000000100ULL 450#define PSCAN_ETSIC 0x0000000000000200ULL 451#define PSCAN_WWR 0x0000000000000400ULL 452#define PSCAN_MKKA1 0x0000000000000800ULL 453#define PSCAN_MKKA1_G 0x0000000000001000ULL 454#define PSCAN_MKKA2 0x0000000000002000ULL 455#define PSCAN_MKKA2_G 0x0000000000004000ULL 456#define PSCAN_MKK3 0x0000000000008000ULL 457#define PSCAN_DEFER 0x7FFFFFFFFFFFFFFFULL 458#define IS_ECM_CHAN 0x8000000000000000ULL 459 460/* 461 * THE following table is the mapping of regdomain pairs specified by 462 * an 8 bit regdomain value to the individual unitary reg domains 463 */ 464 465typedef struct reg_dmn_pair_mapping { 466 HAL_REG_DOMAIN regDmnEnum; /* 16 bit reg domain pair */ 467 HAL_REG_DOMAIN regDmn5GHz; /* 5GHz reg domain */ 468 HAL_REG_DOMAIN regDmn2GHz; /* 2GHz reg domain */ 469 uint32_t flags5GHz; /* Requirements flags (AdHoc 470 disallow, noise floor cal needed, 471 etc) */ 472 uint32_t flags2GHz; /* Requirements flags (AdHoc 473 disallow, noise floor cal needed, 474 etc) */ 475 uint64_t pscanMask; /* Passive Scan flags which 476 can override unitary domain 477 passive scan flags. This 478 value is used as a mask on 479 the unitary flags*/ 480 uint16_t singleCC; /* Country code of single country if 481 a one-on-one mapping exists */ 482} REG_DMN_PAIR_MAPPING; 483 484static REG_DMN_PAIR_MAPPING regDomainPairs[] = { 485 {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 486 {NULL1_WORLD, NULL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 487 {NULL1_ETSIB, NULL1, ETSIB, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 488 {NULL1_ETSIC, NULL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 489 490 {FCC2_FCCA, FCC2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 491 {FCC2_WORLD, FCC2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 492 {FCC2_ETSIC, FCC2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 493 {FCC3_FCCA, FCC3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 494 {FCC3_WORLD, FCC3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 495 {FCC4_FCCA, FCC4, FCCA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, 496 497 {ETSI1_WORLD, ETSI1, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, 498 {ETSI2_WORLD, ETSI2, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, 499 {ETSI3_WORLD, ETSI3, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, 500 {ETSI4_WORLD, ETSI4, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, 501 {ETSI5_WORLD, ETSI5, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, 502 {ETSI6_WORLD, ETSI6, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, 503 504 {ETSI3_ETSIA, ETSI3, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, 505 {FRANCE_RES, ETSI3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 506 507 {FCC1_WORLD, FCC1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 508 {FCC1_FCCA, FCC1, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 509 {APL1_WORLD, APL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 510 {APL2_WORLD, APL2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 511 {APL3_WORLD, APL3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 512 {APL4_WORLD, APL4, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 513 {APL5_WORLD, APL5, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 514 {APL6_WORLD, APL6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 515 {APL8_WORLD, APL8, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 516 {APL9_WORLD, APL9, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 517 518 {APL3_FCCA, APL3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 519 {APL1_ETSIC, APL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 520 {APL2_ETSIC, APL2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 521 {APL2_APLD, APL2, APLD, NO_REQ, NO_REQ, PSCAN_DEFER, }, 522 523 {MKK1_MKKA, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA, CTRY_JAPAN }, 524 {MKK1_MKKB, MKK1, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN1 }, 525 {MKK1_FCCA, MKK1, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN2 }, 526 {MKK1_MKKA1, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN4 }, 527 {MKK1_MKKA2, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN5 }, 528 {MKK1_MKKC, MKK1, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN6 }, 529 530 /* MKK2 */ 531 {MKK2_MKKA, MKK2, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN3 }, 532 533 /* MKK3 */ 534 {MKK3_MKKA, MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC , PSCAN_MKKA, 0 }, 535 {MKK3_MKKB, MKK3, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN7 }, 536 {MKK3_MKKA1, MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA1 | PSCAN_MKKA1_G, 0 }, 537 {MKK3_MKKA2,MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN8 }, 538 {MKK3_MKKC, MKK3, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, CTRY_JAPAN9 }, 539 {MKK3_FCCA, MKK3, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, 0 }, 540 541 /* MKK4 */ 542 {MKK4_MKKB, MKK4, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN10 }, 543 {MKK4_MKKA1, MKK4, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, 0 }, 544 {MKK4_MKKA2, MKK4, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 |PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11 }, 545 {MKK4_MKKC, MKK4, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN12 }, 546 {MKK4_FCCA, MKK4, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, 0 }, 547 548 /* MKK5 */ 549 {MKK5_MKKB, MKK5, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN13 }, 550 {MKK5_MKKA2,MKK5, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN14 }, 551 {MKK5_MKKC, MKK5, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN15 }, 552 553 /* MKK6 */ 554 {MKK6_MKKB, MKK6, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN16 }, 555 {MKK6_MKKA2, MKK6, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN17 }, 556 {MKK6_MKKC, MKK6, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN18 }, 557 558 /* MKK7 */ 559 {MKK7_MKKB, MKK7, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN19 }, 560 {MKK7_MKKA2, MKK7, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN20 }, 561 {MKK7_MKKC, MKK7, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN21 }, 562 563 /* MKK8 */ 564 {MKK8_MKKB, MKK8, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN22 }, 565 {MKK8_MKKA2,MKK8, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN23 }, 566 {MKK8_MKKC, MKK8, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 , CTRY_JAPAN24 }, 567 568 {MKK9_MKKA, MKK9, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, 0 }, 569 {MKK10_MKKA, MKK10, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, 0 }, 570 571 /* These are super domains */ 572 {WOR0_WORLD, WOR0_WORLD, WOR0_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 573 {WOR1_WORLD, WOR1_WORLD, WOR1_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, 574 {WOR2_WORLD, WOR2_WORLD, WOR2_WORLD, DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, 575 {WOR3_WORLD, WOR3_WORLD, WOR3_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 576 {WOR4_WORLD, WOR4_WORLD, WOR4_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, 577 {WOR5_ETSIC, WOR5_ETSIC, WOR5_ETSIC, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, 578 {WOR01_WORLD, WOR01_WORLD, WOR01_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 579 {WOR02_WORLD, WOR02_WORLD, WOR02_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 580 {EU1_WORLD, EU1_WORLD, EU1_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, 581 {WOR9_WORLD, WOR9_WORLD, WOR9_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, 582 {WORA_WORLD, WORA_WORLD, WORA_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, 583}; 584 585/* 586 * The following table of vendor specific regdomain pairs and 587 * additional flags used to modify the flags5GHz and flags2GHz 588 * of the original regdomain 589 */ 590 591#define NO_INTERSECT_REQ 0xFFFFFFFF 592#define NO_UNION_REQ 0 593#define MAX_MAPS 2 594 595struct ccmap { 596 char isoName[3]; 597 HAL_CTRY_CODE countryCode; 598}; 599 600 601/* 602 * The following table is the master list for all different freqeuncy 603 * bands with the complete matrix of all possible flags and settings 604 * for each band if it is used in ANY reg domain. 605 */ 606 607#define DEF_REGDMN FCC1_FCCA 608#define DEF_DMN_5 FCC1 609#define DEF_DMN_2 FCCA 610#define COUNTRY_ERD_FLAG 0x8000 611#define WORLDWIDE_ROAMING_FLAG 0x4000 612#define SUPER_DOMAIN_MASK 0x0fff 613#define COUNTRY_CODE_MASK 0x3fff 614 615#define YES AH_TRUE 616#define NO AH_FALSE 617 618typedef struct { 619 HAL_CTRY_CODE countryCode; 620 HAL_REG_DOMAIN regDmnEnum; 621 HAL_BOOL allow11g; 622 HAL_BOOL allow11aTurbo; 623 HAL_BOOL allow11gTurbo; 624 HAL_BOOL allow11ng20; 625 HAL_BOOL allow11ng40; 626 HAL_BOOL allow11na20; 627 HAL_BOOL allow11na40; 628 uint16_t outdoorChanStart; 629} COUNTRY_CODE_TO_ENUM_RD; 630 631static COUNTRY_CODE_TO_ENUM_RD allCountries[] = { 632 {CTRY_DEBUG, NO_ENUMRD, YES, YES, YES, YES,YES, YES,YES, 7000 }, 633 {CTRY_DEFAULT, DEF_REGDMN, YES, YES, YES, YES,YES, YES,YES, 7000 }, 634 {CTRY_ALBANIA, NULL1_WORLD, YES, NO, YES, YES, NO, NO, NO, 7000 }, 635 {CTRY_ALGERIA, NULL1_WORLD, YES, NO, YES, YES, NO, NO, NO, 7000 }, 636 {CTRY_ARGENTINA, APL3_WORLD, NO, NO, NO, NO, NO, NO, NO, 7000 }, 637 {CTRY_ARMENIA, ETSI4_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 }, 638 {CTRY_AUSTRALIA, FCC2_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 }, 639 {CTRY_AUSTRIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 640 {CTRY_AZERBAIJAN, ETSI4_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 }, 641 {CTRY_BAHRAIN, APL6_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 642 {CTRY_BELARUS, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 643 {CTRY_BELGIUM, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 644 {CTRY_BELIZE, APL1_ETSIC, YES, YES, YES, YES,YES, YES,YES, 7000 }, 645 {CTRY_BOLIVIA, APL1_ETSIC, YES, YES, YES, YES,YES, YES,YES, 7000 }, 646 {CTRY_BRAZIL, FCC3_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 }, 647 {CTRY_BRUNEI_DARUSSALAM,APL1_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 }, 648 {CTRY_BULGARIA, ETSI6_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 649 {CTRY_CANADA, FCC2_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 }, 650 {CTRY_CHILE, APL6_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 }, 651 {CTRY_CHINA, APL1_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 }, 652 {CTRY_COLOMBIA, FCC1_FCCA, YES, NO, YES, YES,YES, YES, NO, 7000 }, 653 {CTRY_COSTA_RICA, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 654 {CTRY_CROATIA, ETSI3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 655 {CTRY_CYPRUS, ETSI1_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 }, 656 {CTRY_CZECH, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 657 {CTRY_DENMARK, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 658 {CTRY_DOMINICAN_REPUBLIC,FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 }, 659 {CTRY_ECUADOR, NULL1_WORLD, NO, NO, NO, NO, NO, NO, NO, 7000 }, 660 {CTRY_EGYPT, ETSI3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 661 {CTRY_EL_SALVADOR, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 }, 662 {CTRY_ESTONIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 663 {CTRY_FINLAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 664 {CTRY_FRANCE, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 665 {CTRY_FRANCE2, ETSI3_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 666 {CTRY_GEORGIA, ETSI4_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 }, 667 {CTRY_GERMANY, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 668 {CTRY_GREECE, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 669 {CTRY_GUATEMALA, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 }, 670 {CTRY_HONDURAS, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 671 {CTRY_HONG_KONG, FCC2_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 }, 672 {CTRY_HUNGARY, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 673 {CTRY_ICELAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 674 {CTRY_INDIA, APL6_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 675 {CTRY_INDONESIA, APL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 676 {CTRY_IRAN, APL1_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 }, 677 {CTRY_IRELAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 678 {CTRY_ISRAEL, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 679 {CTRY_ITALY, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 680 {CTRY_JAPAN, MKK1_MKKA, YES, NO, NO, YES, NO, YES, NO, 7000 }, 681 {CTRY_JAPAN1, MKK1_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 }, 682 {CTRY_JAPAN2, MKK1_FCCA, YES, NO, NO, NO, NO, NO, NO, 7000 }, 683 {CTRY_JAPAN3, MKK2_MKKA, YES, NO, NO, NO, NO, NO, NO, 7000 }, 684 {CTRY_JAPAN4, MKK1_MKKA1, YES, NO, NO, NO, NO, NO, NO, 7000 }, 685 {CTRY_JAPAN5, MKK1_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 }, 686 {CTRY_JAPAN6, MKK1_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 }, 687 688 {CTRY_JAPAN7, MKK3_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 }, 689 {CTRY_JAPAN8, MKK3_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 }, 690 {CTRY_JAPAN9, MKK3_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 }, 691 692 {CTRY_JAPAN10, MKK4_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 }, 693 {CTRY_JAPAN11, MKK4_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 }, 694 {CTRY_JAPAN12, MKK4_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 }, 695 696 {CTRY_JAPAN13, MKK5_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 }, 697 {CTRY_JAPAN14, MKK5_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 }, 698 {CTRY_JAPAN15, MKK5_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 }, 699 700 {CTRY_JAPAN16, MKK6_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 }, 701 {CTRY_JAPAN17, MKK6_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 }, 702 {CTRY_JAPAN18, MKK6_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 }, 703 704 {CTRY_JAPAN19, MKK7_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 }, 705 {CTRY_JAPAN20, MKK7_MKKA2, YES, NO, NO, YES, NO, YES, NO, 7000 }, 706 {CTRY_JAPAN21, MKK7_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 }, 707 708 {CTRY_JAPAN22, MKK8_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 }, 709 {CTRY_JAPAN23, MKK8_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 }, 710 {CTRY_JAPAN24, MKK8_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 }, 711 712 {CTRY_JORDAN, APL4_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 713 {CTRY_KAZAKHSTAN, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 }, 714 {CTRY_KOREA_NORTH, APL2_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 }, 715 {CTRY_KOREA_ROC, APL2_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 }, 716 {CTRY_KOREA_ROC2, APL2_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 }, 717 {CTRY_KOREA_ROC3, APL9_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 }, 718 {CTRY_KUWAIT, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 719 {CTRY_LATVIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 720 {CTRY_LEBANON, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 721 {CTRY_LIECHTENSTEIN,ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 722 {CTRY_LITHUANIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 723 {CTRY_LUXEMBOURG, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 724 {CTRY_MACAU, FCC2_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 }, 725 {CTRY_MACEDONIA, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 }, 726 {CTRY_MALAYSIA, APL8_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 }, 727 {CTRY_MALTA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 728 {CTRY_MEXICO, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 }, 729 {CTRY_MONACO, ETSI4_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 }, 730 {CTRY_MOROCCO, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 }, 731 {CTRY_NETHERLANDS, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 732 {CTRY_NEW_ZEALAND, FCC2_ETSIC, YES, NO, YES, YES,YES, YES,YES, 7000 }, 733 {CTRY_NORWAY, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 734 {CTRY_OMAN, APL6_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 735 {CTRY_PAKISTAN, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 }, 736 {CTRY_PANAMA, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 }, 737 {CTRY_PERU, APL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 738 {CTRY_PHILIPPINES, FCC3_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 }, 739 {CTRY_POLAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 740 {CTRY_PORTUGAL, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 741 {CTRY_PUERTO_RICO, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 }, 742 {CTRY_QATAR, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 }, 743 {CTRY_ROMANIA, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 }, 744 {CTRY_RUSSIA, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 }, 745 {CTRY_SAUDI_ARABIA,FCC2_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 746 {CTRY_SINGAPORE, APL6_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 }, 747 {CTRY_SLOVAKIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 748 {CTRY_SLOVENIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 749 {CTRY_SOUTH_AFRICA,FCC3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 750 {CTRY_SPAIN, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 751 {CTRY_SWEDEN, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 752 {CTRY_SWITZERLAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 }, 753 {CTRY_SYRIA, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 754 {CTRY_TAIWAN, APL3_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 }, 755 {CTRY_THAILAND, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 }, 756 {CTRY_TRINIDAD_Y_TOBAGO,ETSI4_WORLD,YES, NO, YES, YES,YES, YES, NO, 7000 }, 757 {CTRY_TUNISIA, ETSI3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 758 {CTRY_TURKEY, ETSI3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 759 {CTRY_UKRAINE, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 }, 760 {CTRY_UAE, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 }, 761 {CTRY_UNITED_KINGDOM, ETSI1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 762 {CTRY_UNITED_STATES, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 5825 }, 763 {CTRY_UNITED_STATES_FCC49,FCC4_FCCA,YES, YES, YES, YES,YES, YES,YES, 7000 }, 764 {CTRY_URUGUAY, FCC1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 }, 765 {CTRY_UZBEKISTAN, FCC3_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 }, 766 {CTRY_VENEZUELA, APL2_ETSIC, YES, NO, YES, YES,YES, YES, NO, 7000 }, 767 {CTRY_VIET_NAM, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 }, 768 {CTRY_YEMEN, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 }, 769 {CTRY_ZIMBABWE, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 } 770}; 771 772typedef struct RegDmnFreqBand { 773 uint16_t lowChannel; /* Low channel center in MHz */ 774 uint16_t highChannel; /* High Channel center in MHz */ 775 uint8_t powerDfs; /* Max power (dBm) for channel 776 range when using DFS */ 777 uint8_t antennaMax; /* Max allowed antenna gain */ 778 uint8_t channelBW; /* Bandwidth of the channel */ 779 uint8_t channelSep; /* Channel separation within 780 the band */ 781 uint64_t useDfs; /* Use DFS in the RegDomain 782 if corresponding bit is set */ 783 uint64_t usePassScan; /* Use Passive Scan in the RegDomain 784 if corresponding bit is set */ 785 uint8_t regClassId; /* Regulatory class id */ 786} REG_DMN_FREQ_BAND; 787 788/* Bit masks for DFS per regdomain */ 789 790enum { 791 NO_DFS = 0x0000000000000000ULL, 792 DFS_FCC3 = 0x0000000000000001ULL, 793 DFS_ETSI = 0x0000000000000002ULL, 794 DFS_MKK4 = 0x0000000000000004ULL, 795}; 796 797/* The table of frequency bands is indexed by a bitmask. The ordering 798 * must be consistent with the enum below. When adding a new 799 * frequency band, be sure to match the location in the enum with the 800 * comments 801 */ 802 803/* 804 * 5GHz 11A channel tags 805 */ 806 807enum { 808 F1_4915_4925, 809 F1_4935_4945, 810 F1_4920_4980, 811 F1_4942_4987, 812 F1_4945_4985, 813 F1_4950_4980, 814 F1_5035_5040, 815 F1_5040_5080, 816 F1_5055_5055, 817 818 F1_5120_5240, 819 820 F1_5170_5230, 821 F2_5170_5230, 822 823 F1_5180_5240, 824 F2_5180_5240, 825 F3_5180_5240, 826 F4_5180_5240, 827 F5_5180_5240, 828 F6_5180_5240, 829 830 F1_5180_5320, 831 832 F1_5240_5280, 833 834 F1_5260_5280, 835 836 F1_5260_5320, 837 F2_5260_5320, 838 F3_5260_5320, 839 F4_5260_5320, 840 F5_5260_5320, 841 F6_5260_5320, 842 843 F1_5260_5700, 844 845 F1_5280_5320, 846 847 F1_5500_5620, 848 849 F1_5500_5700, 850 F2_5500_5700, 851 F3_5500_5700, 852 F4_5500_5700, 853 854 F1_5745_5805, 855 F2_5745_5805, 856 F3_5745_5805, 857 858 F1_5745_5825, 859 F2_5745_5825, 860 F3_5745_5825, 861 F4_5745_5825, 862 F5_5745_5825, 863 F6_5745_5825, 864 865 W1_4920_4980, 866 W1_5040_5080, 867 W1_5170_5230, 868 W1_5180_5240, 869 W1_5260_5320, 870 W1_5745_5825, 871 W1_5500_5700, 872 W2_5260_5320, 873 W2_5180_5240, 874 W2_5825_5825, 875}; 876 877static REG_DMN_FREQ_BAND regDmn5GhzFreq[] = { 878 { 4915, 4925, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16 }, /* F1_4915_4925 */ 879 { 4935, 4945, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16 }, /* F1_4935_4945 */ 880 { 4920, 4980, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 7 }, /* F1_4920_4980 */ 881 { 4942, 4987, 27, 6, 5, 5, NO_DFS, PSCAN_FCC, 0 }, /* F1_4942_4987 */ 882 { 4945, 4985, 30, 6, 10, 5, NO_DFS, PSCAN_FCC, 0 }, /* F1_4945_4985 */ 883 { 4950, 4980, 33, 6, 20, 5, NO_DFS, PSCAN_FCC, 0 }, /* F1_4950_4980 */ 884 { 5035, 5040, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12 }, /* F1_5035_5040 */ 885 { 5040, 5080, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 2 }, /* F1_5040_5080 */ 886 { 5055, 5055, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12 }, /* F1_5055_5055 */ 887 888 { 5120, 5240, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F1_5120_5240 */ 889 890 { 5170, 5230, 23, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1 }, /* F1_5170_5230 */ 891 { 5170, 5230, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1 }, /* F2_5170_5230 */ 892 893 { 5180, 5240, 15, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F1_5180_5240 */ 894 { 5180, 5240, 17, 6, 20, 20, NO_DFS, PSCAN_FCC, 1 }, /* F2_5180_5240 */ 895 { 5180, 5240, 18, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F3_5180_5240 */ 896 { 5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F4_5180_5240 */ 897 { 5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F5_5180_5240 */ 898 { 5180, 5240, 23, 6, 20, 20, NO_DFS, PSCAN_FCC, 0 }, /* F6_5180_5240 */ 899 900 { 5180, 5320, 20, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0 }, /* F1_5180_5320 */ 901 902 { 5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F1_5240_5280 */ 903 904 { 5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F1_5260_5280 */ 905 906 { 5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F1_5260_5320 */ 907 908 { 5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3 , 0 }, 909 /* F2_5260_5320 */ 910 911 { 5260, 5320, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 }, /* F3_5260_5320 */ 912 { 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 }, /* F4_5260_5320 */ 913 { 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0 }, /* F5_5260_5320 */ 914 { 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F6_5260_5320 */ 915 916 { 5260, 5700, 5, 6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0 }, /* F1_5260_5700 */ 917 918 { 5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0 }, /* F1_5280_5320 */ 919 920 { 5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0 }, /* F1_5500_5620 */ 921 922 { 5500, 5700, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 4 }, /* F1_5500_5700 */ 923 { 5500, 5700, 27, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F2_5500_5700 */ 924 { 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F3_5500_5700 */ 925 { 5500, 5700, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_MKK3 | PSCAN_FCC, 0 }, 926 /* F4_5500_5700 */ 927 928 { 5745, 5805, 23, 0, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F1_5745_5805 */ 929 { 5745, 5805, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F2_5745_5805 */ 930 { 5745, 5805, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0 }, /* F3_5745_5805 */ 931 { 5745, 5825, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F1_5745_5825 */ 932 { 5745, 5825, 17, 0, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F2_5745_5825 */ 933 { 5745, 5825, 20, 0, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F3_5745_5825 */ 934 { 5745, 5825, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F4_5745_5825 */ 935 { 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 3 }, /* F5_5745_5825 */ 936 { 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F6_5745_5825 */ 937 938 /* 939 * Below are the world roaming channels 940 * All WWR domains have no power limit, instead use the card's CTL 941 * or max power settings. 942 */ 943 { 4920, 4980, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 }, /* W1_4920_4980 */ 944 { 5040, 5080, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 }, /* W1_5040_5080 */ 945 { 5170, 5230, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 }, /* W1_5170_5230 */ 946 { 5180, 5240, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 }, /* W1_5180_5240 */ 947 { 5260, 5320, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 }, /* W1_5260_5320 */ 948 { 5745, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 }, /* W1_5745_5825 */ 949 { 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 }, /* W1_5500_5700 */ 950 { 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* W2_5260_5320 */ 951 { 5180, 5240, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* W2_5180_5240 */ 952 { 5825, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 }, /* W2_5825_5825 */ 953}; 954 955/* 956 * 5GHz Turbo (dynamic & static) tags 957 */ 958 959enum { 960 T1_5130_5210, 961 T1_5250_5330, 962 T1_5370_5490, 963 T1_5530_5650, 964 965 T1_5150_5190, 966 T1_5230_5310, 967 T1_5350_5470, 968 T1_5510_5670, 969 970 T1_5200_5240, 971 T2_5200_5240, 972 T1_5210_5210, 973 T2_5210_5210, 974 975 T1_5280_5280, 976 T2_5280_5280, 977 T1_5250_5250, 978 T1_5290_5290, 979 T1_5250_5290, 980 T2_5250_5290, 981 982 T1_5540_5660, 983 T1_5760_5800, 984 T2_5760_5800, 985 986 T1_5765_5805, 987 988 WT1_5210_5250, 989 WT1_5290_5290, 990 WT1_5540_5660, 991 WT1_5760_5800, 992}; 993 994static REG_DMN_FREQ_BAND regDmn5GhzTurboFreq[] = { 995 { 5130, 5210, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_5130_5210 */ 996 { 5250, 5330, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0}, /* T1_5250_5330 */ 997 { 5370, 5490, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_5370_5490 */ 998 { 5530, 5650, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0}, /* T1_5530_5650 */ 999 1000 { 5150, 5190, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_5150_5190 */ 1001 { 5230, 5310, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0}, /* T1_5230_5310 */ 1002 { 5350, 5470, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_5350_5470 */ 1003 { 5510, 5670, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0}, /* T1_5510_5670 */ 1004 1005 { 5200, 5240, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_5200_5240 */ 1006 { 5200, 5240, 23, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T2_5200_5240 */ 1007 { 5210, 5210, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_5210_5210 */ 1008 { 5210, 5210, 23, 0, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T2_5210_5210 */ 1009 1010 { 5280, 5280, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0}, /* T1_5280_5280 */ 1011 { 5280, 5280, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0}, /* T2_5280_5280 */ 1012 { 5250, 5250, 17, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0}, /* T1_5250_5250 */ 1013 { 5290, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0}, /* T1_5290_5290 */ 1014 { 5250, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0}, /* T1_5250_5290 */ 1015 { 5250, 5290, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0}, /* T2_5250_5290 */ 1016 1017 { 5540, 5660, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0}, /* T1_5540_5660 */ 1018 { 5760, 5800, 20, 0, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_5760_5800 */ 1019 { 5760, 5800, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T2_5760_5800 */ 1020 1021 { 5765, 5805, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_5765_5805 */ 1022 1023 /* 1024 * Below are the WWR frequencies 1025 */ 1026 1027 { 5210, 5250, 15, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0}, /* WT1_5210_5250 */ 1028 { 5290, 5290, 18, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0}, /* WT1_5290_5290 */ 1029 { 5540, 5660, 20, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0}, /* WT1_5540_5660 */ 1030 { 5760, 5800, 20, 0, 40, 40, NO_DFS, PSCAN_WWR, 0}, /* WT1_5760_5800 */ 1031}; 1032 1033/* 1034 * 2GHz 11b channel tags 1035 */ 1036enum { 1037 F1_2312_2372, 1038 F2_2312_2372, 1039 1040 F1_2412_2472, 1041 F2_2412_2472, 1042 F3_2412_2472, 1043 1044 F1_2412_2462, 1045 F2_2412_2462, 1046 1047 F1_2432_2442, 1048 1049 F1_2457_2472, 1050 1051 F1_2467_2472, 1052 1053 F1_2484_2484, 1054 F2_2484_2484, 1055 1056 F1_2512_2732, 1057 1058 W1_2312_2372, 1059 W1_2412_2412, 1060 W1_2417_2432, 1061 W1_2437_2442, 1062 W1_2447_2457, 1063 W1_2462_2462, 1064 W1_2467_2467, 1065 W2_2467_2467, 1066 W1_2472_2472, 1067 W2_2472_2472, 1068 W1_2484_2484, 1069 W2_2484_2484, 1070}; 1071 1072static REG_DMN_FREQ_BAND regDmn2GhzFreq[] = { 1073 { 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2312_2372 */ 1074 { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F2_2312_2372 */ 1075 1076 { 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2412_2472 */ 1077 { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0}, /* F2_2412_2472 */ 1078 { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F3_2412_2472 */ 1079 1080 { 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2412_2462 */ 1081 { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0}, /* F2_2412_2462 */ 1082 1083 { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2432_2442 */ 1084 1085 { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2457_2472 */ 1086 1087 { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0}, /* F1_2467_2472 */ 1088 1089 { 2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2484_2484 */ 1090 { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 0}, /* F2_2484_2484 */ 1091 1092 { 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2512_2732 */ 1093 1094 /* 1095 * WWR have powers opened up to 20dBm. Limits should often come from CTL/Max powers 1096 */ 1097 1098 { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* W1_2312_2372 */ 1099 { 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* W1_2412_2412 */ 1100 { 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* W1_2417_2432 */ 1101 { 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* W1_2437_2442 */ 1102 { 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* W1_2447_2457 */ 1103 { 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* W1_2462_2462 */ 1104 { 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0}, /* W1_2467_2467 */ 1105 { 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0}, /* W2_2467_2467 */ 1106 { 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0}, /* W1_2472_2472 */ 1107 { 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0}, /* W2_2472_2472 */ 1108 { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0}, /* W1_2484_2484 */ 1109 { 2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0}, /* W2_2484_2484 */ 1110}; 1111 1112/* 1113 * 2GHz 11g channel tags 1114 */ 1115 1116enum { 1117 G1_2312_2372, 1118 G2_2312_2372, 1119 1120 G1_2412_2472, 1121 G2_2412_2472, 1122 G3_2412_2472, 1123 1124 G1_2412_2462, 1125 G2_2412_2462, 1126 1127 G1_2432_2442, 1128 1129 G1_2457_2472, 1130 1131 G1_2512_2732, 1132 1133 G1_2467_2472 , 1134 1135 WG1_2312_2372, 1136 WG1_2412_2412, 1137 WG1_2417_2432, 1138 WG1_2437_2442, 1139 WG1_2447_2457, 1140 WG1_2462_2462, 1141 WG1_2467_2467, 1142 WG2_2467_2467, 1143 WG1_2472_2472, 1144 WG2_2472_2472, 1145 1146 S1_907_922_5, 1147 S1_907_922_10, 1148 S1_912_917, 1149 1150 S2_907_922_5, 1151 S2_907_922_10, 1152 S2_912_917, 1153}; 1154 1155static REG_DMN_FREQ_BAND regDmn2Ghz11gFreq[] = { 1156 { 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G1_2312_2372 */ 1157 { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G2_2312_2372 */ 1158 1159 { 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G1_2412_2472 */ 1160 { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0}, /* G2_2412_2472 */ 1161 { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G3_2412_2472 */ 1162 1163 { 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G1_2412_2462 */ 1164 { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0}, /* G2_2412_2462 */ 1165 1166 { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G1_2432_2442 */ 1167 1168 { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G1_2457_2472 */ 1169 1170 { 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G1_2512_2732 */ 1171 1172 { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0 }, /* G1_2467_2472 */ 1173 1174 /* 1175 * WWR open up the power to 20dBm 1176 */ 1177 1178 { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* WG1_2312_2372 */ 1179 { 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* WG1_2412_2412 */ 1180 { 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* WG1_2417_2432 */ 1181 { 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* WG1_2437_2442 */ 1182 { 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* WG1_2447_2457 */ 1183 { 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* WG1_2462_2462 */ 1184 { 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0}, /* WG1_2467_2467 */ 1185 { 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0}, /* WG2_2467_2467 */ 1186 { 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0}, /* WG1_2472_2472 */ 1187 { 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0}, /* WG2_2472_2472 */ 1188}; 1189 1190/* 1191 * 2GHz Dynamic turbo tags 1192 */ 1193 1194enum { 1195 T1_2312_2372, 1196 T1_2437_2437, 1197 T2_2437_2437, 1198 T3_2437_2437, 1199 T1_2512_2732 1200}; 1201 1202static REG_DMN_FREQ_BAND regDmn2Ghz11gTurboFreq[] = { 1203 { 2312, 2372, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_2312_2372 */ 1204 { 2437, 2437, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_2437_2437 */ 1205 { 2437, 2437, 20, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T2_2437_2437 */ 1206 { 2437, 2437, 18, 6, 40, 40, NO_DFS, PSCAN_WWR, 0}, /* T3_2437_2437 */ 1207 { 2512, 2732, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_2512_2732 */ 1208}; 1209 1210typedef struct regDomain { 1211 uint16_t regDmnEnum; /* value from EnumRd table */ 1212 uint8_t conformanceTestLimit; 1213 uint64_t dfsMask; /* DFS bitmask for 5Ghz tables */ 1214 uint64_t pscan; /* Bitmask for passive scan */ 1215 uint32_t flags; /* Requirement flags (AdHoc disallow, noise 1216 floor cal needed, etc) */ 1217 uint64_t chan11a[BMLEN];/* 128 bit bitmask for channel/band 1218 selection */ 1219 uint64_t chan11a_turbo[BMLEN];/* 128 bit bitmask for channel/band 1220 selection */ 1221 uint64_t chan11a_dyn_turbo[BMLEN]; /* 128 bit bitmask for channel/band 1222 selection */ 1223 uint64_t chan11b[BMLEN];/* 128 bit bitmask for channel/band 1224 selection */ 1225 uint64_t chan11g[BMLEN];/* 128 bit bitmask for channel/band 1226 selection */ 1227 uint64_t chan11g_turbo[BMLEN];/* 128 bit bitmask for channel/band 1228 selection */ 1229} REG_DOMAIN; 1230 1231static REG_DOMAIN regDomains[] = { 1232 1233 {DEBUG_REG_DMN, FCC, DFS_FCC3, NO_PSCAN, NO_REQ, 1234 BM(F1_5120_5240, F1_5260_5700, F1_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1235 BM(T1_5130_5210, T1_5250_5330, T1_5370_5490, T1_5530_5650, T1_5150_5190, T1_5230_5310, T1_5350_5470, T1_5510_5670, -1, -1, -1, -1), 1236 BM(T1_5200_5240, T1_5280_5280, T1_5540_5660, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1), 1237 BM(F1_2312_2372, F1_2412_2472, F1_2484_2484, F1_2512_2732, -1, -1, -1, -1, -1, -1, -1, -1), 1238 BM(G1_2312_2372, G1_2412_2472, G1_2512_2732, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1239 BM(T1_2312_2372, T1_2437_2437, T1_2512_2732, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1240 1241 {APL1, FCC, NO_DFS, NO_PSCAN, NO_REQ, 1242 BM(F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1243 BMZERO, 1244 BMZERO, 1245 BMZERO, 1246 BMZERO, 1247 BMZERO}, 1248 1249 {APL2, FCC, NO_DFS, NO_PSCAN, NO_REQ, 1250 BM(F1_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1251 BMZERO, 1252 BMZERO, 1253 BMZERO, 1254 BMZERO, 1255 BMZERO}, 1256 1257 {APL3, FCC, NO_DFS, NO_PSCAN, NO_REQ, 1258 BM(F1_5280_5320, F2_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1259 BMZERO, 1260 BMZERO, 1261 BMZERO, 1262 BMZERO, 1263 BMZERO}, 1264 1265 {APL4, FCC, NO_DFS, NO_PSCAN, NO_REQ, 1266 BM(F4_5180_5240, F3_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1267 BMZERO, 1268 BMZERO, 1269 BMZERO, 1270 BMZERO, 1271 BMZERO}, 1272 1273 {APL5, FCC, NO_DFS, NO_PSCAN, NO_REQ, 1274 BM(F2_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1275 BMZERO, 1276 BMZERO, 1277 BMZERO, 1278 BMZERO, 1279 BMZERO}, 1280 1281 {APL6, ETSI, DFS_ETSI, PSCAN_FCC_T | PSCAN_FCC , NO_REQ, 1282 BM(F4_5180_5240, F2_5260_5320, F3_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1283 BM(T2_5210_5210, T1_5250_5290, T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1284 BMZERO, 1285 BMZERO, 1286 BMZERO, 1287 BMZERO}, 1288 1289 {APL8, ETSI, NO_DFS, NO_PSCAN, DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB, 1290 BM(F6_5260_5320, F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1291 BMZERO, 1292 BMZERO, 1293 BMZERO, 1294 BMZERO, 1295 BMZERO}, 1296 1297 {APL9, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB, 1298 BM(F1_5180_5320, F1_5500_5620, F3_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1299 BMZERO, 1300 BMZERO, 1301 BMZERO, 1302 BMZERO, 1303 BMZERO}, 1304 1305 {ETSI1, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, 1306 BM(W2_5180_5240, F2_5260_5320, F2_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1307 BMZERO, 1308 BMZERO, 1309 BMZERO, 1310 BMZERO, 1311 BMZERO}, 1312 1313 {ETSI2, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, 1314 BM(F3_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1315 BMZERO, 1316 BMZERO, 1317 BMZERO, 1318 BMZERO, 1319 BMZERO}, 1320 1321 {ETSI3, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, 1322 BM(W2_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1323 BMZERO, 1324 BMZERO, 1325 BMZERO, 1326 BMZERO, 1327 BMZERO}, 1328 1329 {ETSI4, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, 1330 BM(F3_5180_5240, F1_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1331 BMZERO, 1332 BMZERO, 1333 BMZERO, 1334 BMZERO, 1335 BMZERO}, 1336 1337 {ETSI5, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, 1338 BM(F1_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1339 BMZERO, 1340 BMZERO, 1341 BMZERO, 1342 BMZERO, 1343 BMZERO}, 1344 1345 {ETSI6, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, 1346 BM(F5_5180_5240, F1_5260_5280, F3_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1347 BMZERO, 1348 BMZERO, 1349 BMZERO, 1350 BMZERO, 1351 BMZERO}, 1352 1353 {FCC1, FCC, NO_DFS, NO_PSCAN, NO_REQ, 1354 BM(F2_5180_5240, F4_5260_5320, F5_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1355 BM(T1_5210_5210, T2_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1356 BM(T1_5200_5240, T1_5280_5280, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1357 BMZERO, 1358 BMZERO, 1359 BMZERO}, 1360 1361 {FCC2, FCC, NO_DFS, NO_PSCAN, NO_REQ, 1362 BM(F6_5180_5240, F5_5260_5320, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1363 BM(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1364 BM(T2_5200_5240, T1_5280_5280, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1365 BMZERO, 1366 BMZERO, 1367 BMZERO}, 1368 1369 {FCC3, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ, 1370 BM(F2_5180_5240, F3_5260_5320, F1_5500_5700, F5_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1), 1371 BM(T1_5210_5210, T1_5250_5250, T1_5290_5290, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1), 1372 BM(T1_5200_5240, T2_5280_5280, T1_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1373 BMZERO, 1374 BMZERO, 1375 BMZERO}, 1376 1377 {FCC4, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ, 1378 BM(F1_4942_4987, F1_4945_4985, F1_4950_4980, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1379 BMZERO, 1380 BMZERO, 1381 BMZERO, 1382 BMZERO, 1383 BMZERO}, 1384 1385 {MKK1, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB, 1386 BM(F1_5170_5230, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1387 BMZERO, 1388 BMZERO, 1389 BMZERO, 1390 BMZERO, 1391 BMZERO}, 1392 1393 {MKK2, MKK, NO_DFS, PSCAN_MKK2, DISALLOW_ADHOC_11A_TURB, 1394 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040, F1_5055_5055, F1_5040_5080, F1_5170_5230, -1, -1, -1, -1, -1), 1395 BMZERO, 1396 BMZERO, 1397 BMZERO, 1398 BMZERO, 1399 BMZERO}, 1400 1401 /* UNI-1 even */ 1402 {MKK3, MKK, NO_DFS, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, 1403 BM(F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1404 BMZERO, 1405 BMZERO, 1406 BMZERO, 1407 BMZERO, 1408 BMZERO}, 1409 1410 /* UNI-1 even + UNI-2 */ 1411 {MKK4, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, 1412 BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1413 BMZERO, 1414 BMZERO, 1415 BMZERO, 1416 BMZERO, 1417 BMZERO}, 1418 1419 /* UNI-1 even + UNI-2 + mid-band */ 1420 {MKK5, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, 1421 BM(F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1422 BMZERO, 1423 BMZERO, 1424 BMZERO, 1425 BMZERO, 1426 BMZERO}, 1427 1428 /* UNI-1 odd + even */ 1429 {MKK6, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB, 1430 BM(F2_5170_5230, F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1431 BMZERO, 1432 BMZERO, 1433 BMZERO, 1434 BMZERO, 1435 BMZERO}, 1436 1437 /* UNI-1 odd + UNI-1 even + UNI-2 */ 1438 {MKK7, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3 , DISALLOW_ADHOC_11A_TURB, 1439 BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1440 BMZERO, 1441 BMZERO, 1442 BMZERO, 1443 BMZERO, 1444 BMZERO}, 1445 1446 /* UNI-1 odd + UNI-1 even + UNI-2 + mid-band */ 1447 {MKK8, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3 , DISALLOW_ADHOC_11A_TURB, 1448 BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1), 1449 BMZERO, 1450 BMZERO, 1451 BMZERO, 1452 BMZERO, 1453 BMZERO}, 1454 1455 /* UNI-1 even + 4.9 GHZ */ 1456 {MKK9, MKK, NO_DFS, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, 1457 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040, F1_5055_5055, F1_5040_5080, F4_5180_5240, -1, -1, -1, -1, -1), 1458 BMZERO, 1459 BMZERO, 1460 BMZERO, 1461 BMZERO, 1462 BMZERO}, 1463 1464 /* UNI-1 even + UNI-2 + 4.9 GHZ */ 1465 {MKK10, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, 1466 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040, F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320, -1, -1, -1, -1), 1467 BMZERO, 1468 BMZERO, 1469 BMZERO, 1470 BMZERO, 1471 BMZERO}, 1472 1473 /* Defined here to use when 2G channels are authorised for country K2 */ 1474 {APLD, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ, 1475 BMZERO, 1476 BMZERO, 1477 BMZERO, 1478 BM(F2_2312_2372,F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1479 BM(G2_2312_2372,G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1480 BMZERO}, 1481 1482 {ETSIA, NO_CTL, NO_DFS, PSCAN_ETSIA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, 1483 BMZERO, 1484 BMZERO, 1485 BMZERO, 1486 BM(F1_2457_2472,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1487 BM(G1_2457_2472,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1488 BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1489 1490 {ETSIB, ETSI, NO_DFS, PSCAN_ETSIB, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, 1491 BMZERO, 1492 BMZERO, 1493 BMZERO, 1494 BM(F1_2432_2442,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), 1495 BM(G1_2432_2442,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), 1496 BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1497 1498 {ETSIC, ETSI, NO_DFS, PSCAN_ETSIC, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, 1499 BMZERO, 1500 BMZERO, 1501 BMZERO, 1502 BM(F3_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), 1503 BM(G3_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), 1504 BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1505 1506 {FCCA, FCC, NO_DFS, NO_PSCAN, NO_REQ, 1507 BMZERO, 1508 BMZERO, 1509 BMZERO, 1510 BM(F1_2412_2462,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), 1511 BM(G1_2412_2462,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), 1512 BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1513 1514 {MKKA, MKK, NO_DFS, PSCAN_MKKA | PSCAN_MKKA_G | PSCAN_MKKA1 | PSCAN_MKKA1_G | PSCAN_MKKA2 | PSCAN_MKKA2_G, DISALLOW_ADHOC_11A_TURB, 1515 BMZERO, 1516 BMZERO, 1517 BMZERO, 1518 BM(F2_2412_2462, F1_2467_2472, F2_2484_2484, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1519 BM(G2_2412_2462, G1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1520 BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1521 1522 {MKKC, MKK, NO_DFS, NO_PSCAN, NO_REQ, 1523 BMZERO, 1524 BMZERO, 1525 BMZERO, 1526 BM(F2_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), 1527 BM(G2_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), 1528 BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1529 1530 {WORLD, ETSI, NO_DFS, NO_PSCAN, NO_REQ, 1531 BMZERO, 1532 BMZERO, 1533 BMZERO, 1534 BM(F2_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), 1535 BM(G2_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), 1536 BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1537 1538 {WOR0_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, 1539 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), 1540 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1541 BMZERO, 1542 BM(W1_2412_2412,W1_2437_2442,W1_2462_2462,W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, -1, -1), 1543 BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462,WG1_2472_2472,WG1_2417_2432,WG1_2447_2457,WG1_2467_2467, -1, -1, -1, -1, -1), 1544 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1545 1546 {WOR01_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, 1547 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), 1548 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1549 BMZERO, 1550 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432, W1_2447_2457, -1, -1, -1, -1, -1, -1, -1), 1551 BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG1_2417_2432, WG1_2447_2457, -1, -1, -1, -1, -1, -1, -1), 1552 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1553 1554 {WOR02_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, 1555 BM(W1_5260_5320, W1_5180_5240,W1_5170_5230,W1_5745_5825,W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), 1556 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1557 BMZERO, 1558 BM(W1_2412_2412,W1_2437_2442,W1_2462_2462, W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), 1559 BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462, WG1_2472_2472,WG1_2417_2432, WG1_2447_2457, WG1_2467_2467, -1, -1, -1, -1, -1), 1560 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1561 1562 {EU1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, 1563 BM(W1_5260_5320, W1_5180_5240,W1_5170_5230,W1_5745_5825,W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), 1564 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1565 BMZERO, 1566 BM(W1_2412_2412,W1_2437_2442,W1_2462_2462, W2_2472_2472,W1_2417_2432, W1_2447_2457, W2_2467_2467, -1, -1, -1, -1, -1), 1567 BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462, WG2_2472_2472,WG1_2417_2432, WG1_2447_2457, WG2_2467_2467, -1, -1, -1, -1, -1), 1568 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1569 1570 {WOR1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, 1571 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), 1572 BMZERO, 1573 BMZERO, 1574 BM(W1_2412_2412,W1_2437_2442,W1_2462_2462,W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, -1, -1), 1575 BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462,WG1_2472_2472,WG1_2417_2432,WG1_2447_2457,WG1_2467_2467, -1, -1, -1, -1, -1), 1576 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1577 1578 {WOR2_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, 1579 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), 1580 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1581 BMZERO, 1582 BM(W1_2412_2412,W1_2437_2442,W1_2462_2462,W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, -1, -1), 1583 BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462,WG1_2472_2472,WG1_2417_2432,WG1_2447_2457,WG1_2467_2467, -1, -1, -1, -1, -1), 1584 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1585 1586 {WOR3_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, 1587 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1), 1588 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1589 BMZERO, 1590 BM(W1_2412_2412,W1_2437_2442,W1_2462_2462,W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), 1591 BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462,WG1_2472_2472,WG1_2417_2432,WG1_2447_2457,WG1_2467_2467,-1, -1, -1, -1, -1), 1592 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1593 1594 {WOR4_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, 1595 BM(W2_5260_5320, W2_5180_5240, F2_5745_5805, W2_5825_5825, -1, -1, -1, -1, -1, -1, -1, -1), 1596 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1597 BMZERO, 1598 BM(W1_2412_2412,W1_2437_2442,W1_2462_2462, W1_2417_2432,W1_2447_2457,-1, -1, -1, -1, -1, -1, -1), 1599 BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462, WG1_2417_2432,WG1_2447_2457,-1, -1, -1, -1, -1, -1, -1), 1600 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1601 1602 {WOR5_ETSIC, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, 1603 BM(W1_5260_5320, W2_5180_5240, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1604 BMZERO, 1605 BMZERO, 1606 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W2_2472_2472, W1_2417_2432, W1_2447_2457, W2_2467_2467, -1, -1, -1, -1, -1), 1607 BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG2_2472_2472, WG1_2417_2432, WG1_2447_2457, WG2_2467_2467, -1, -1, -1, -1, -1), 1608 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1609 1610 {WOR9_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, 1611 BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1), 1612 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), 1613 BMZERO, 1614 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432, W1_2447_2457, -1, -1, -1, -1, -1, -1, -1), 1615 BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG1_2417_2432, WG1_2447_2457, -1, -1, -1, -1, -1, -1, -1), 1616 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1617 1618 {WORA_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, 1619 BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1), 1620 BMZERO, 1621 BMZERO, 1622 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), 1623 BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG1_2472_2472, WG1_2417_2432, WG1_2447_2457, WG1_2467_2467, -1, -1, -1, -1, -1), 1624 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, 1625 1626 {NULL1, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ, 1627 BMZERO, 1628 BMZERO, 1629 BMZERO, 1630 BMZERO, 1631 BMZERO, 1632 BMZERO} 1633}; 1634 1635struct cmode { 1636 u_int mode; 1637 u_int flags; 1638}; 1639 1640static const struct cmode modes[] = { 1641 { HAL_MODE_TURBO, CHANNEL_ST}, /* TURBO means 11a Static Turbo */ 1642 { HAL_MODE_11A, CHANNEL_A}, 1643 { HAL_MODE_11B, CHANNEL_B}, 1644 { HAL_MODE_11G, CHANNEL_G}, 1645 { HAL_MODE_11G_TURBO, CHANNEL_108G}, 1646 { HAL_MODE_11A_TURBO, CHANNEL_108A}, 1647 { HAL_MODE_11NG_HT20, CHANNEL_G_HT20}, 1648 { HAL_MODE_11NG_HT40PLUS, CHANNEL_G_HT40PLUS}, 1649 { HAL_MODE_11NG_HT40MINUS, CHANNEL_G_HT40MINUS}, 1650 { HAL_MODE_11NA_HT20, CHANNEL_A_HT20}, 1651 { HAL_MODE_11NA_HT40PLUS, CHANNEL_A_HT40PLUS}, 1652 { HAL_MODE_11NA_HT40MINUS, CHANNEL_A_HT40MINUS}, 1653}; 1654 1655static int 1656chansort(const void *a, const void *b) 1657{ 1658#define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) 1659 const HAL_CHANNEL_INTERNAL *ca = a; 1660 const HAL_CHANNEL_INTERNAL *cb = b; 1661 1662 return (ca->channel == cb->channel) ? 1663 (ca->channelFlags & CHAN_FLAGS) - 1664 (cb->channelFlags & CHAN_FLAGS) : 1665 ca->channel - cb->channel; 1666#undef CHAN_FLAGS 1667} 1668typedef int ath_hal_cmp_t(const void *, const void *); 1669static void ath_hal_sort(void *a, size_t n, size_t es, ath_hal_cmp_t *cmp); 1670static COUNTRY_CODE_TO_ENUM_RD* findCountry(HAL_CTRY_CODE countryCode); 1671static HAL_BOOL getWmRD(struct ath_hal *ah, COUNTRY_CODE_TO_ENUM_RD *country, uint16_t channelFlag, REG_DOMAIN *rd); 1672 1673 1674static uint16_t 1675getEepromRD(struct ath_hal *ah) 1676{ 1677 return AH_PRIVATE(ah)->ah_currentRD &~ WORLDWIDE_ROAMING_FLAG; 1678} 1679 1680/* 1681 * Test to see if the bitmask array is all zeros 1682 */ 1683static HAL_BOOL 1684isChanBitMaskZero(uint64_t *bitmask) 1685{ 1686#if BMLEN > 2 1687#error "add more cases" 1688#endif 1689#if BMLEN > 1 1690 if (bitmask[1] != 0) 1691 return AH_FALSE; 1692#endif 1693 return (bitmask[0] == 0); 1694} 1695 1696/* 1697 * Return whether or not the regulatory domain/country in EEPROM 1698 * is acceptable. 1699 */ 1700static HAL_BOOL 1701isEepromValid(struct ath_hal *ah) 1702{ 1703 uint16_t rd = getEepromRD(ah); 1704 int i; 1705 1706 if (rd & COUNTRY_ERD_FLAG) { 1707 uint16_t cc = rd &~ COUNTRY_ERD_FLAG; 1708 for (i = 0; i < N(allCountries); i++) 1709 if (allCountries[i].countryCode == cc) 1710 return AH_TRUE; 1711 } else { 1712 for (i = 0; i < N(regDomainPairs); i++) 1713 if (regDomainPairs[i].regDmnEnum == rd) 1714 return AH_TRUE; 1715 } 1716 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 1717 "%s: invalid regulatory domain/country code 0x%x\n", __func__, rd); 1718 return AH_FALSE; 1719} 1720 1721/* 1722 * Returns whether or not the specified country code 1723 * is allowed by the EEPROM setting 1724 */ 1725static HAL_BOOL 1726isCountryCodeValid(struct ath_hal *ah, HAL_CTRY_CODE cc) 1727{ 1728 uint16_t rd; 1729 1730 /* Default setting requires no checks */ 1731 if (cc == CTRY_DEFAULT) 1732 return AH_TRUE; 1733#ifdef AH_DEBUG_COUNTRY 1734 if (cc == CTRY_DEBUG) 1735 return AH_TRUE; 1736#endif 1737 rd = getEepromRD(ah); 1738 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: EEPROM regdomain 0x%x\n", 1739 __func__, rd); 1740 1741 if (rd & COUNTRY_ERD_FLAG) { 1742 /* EEP setting is a country - config shall match */ 1743 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 1744 "%s: EEPROM setting is country code %u\n", __func__, 1745 rd &~ COUNTRY_ERD_FLAG); 1746 return (cc == (rd & ~COUNTRY_ERD_FLAG)); 1747 } else if (rd == DEBUG_REG_DMN || rd == NO_ENUMRD) { 1748 /* Set to Debug or AllowAnyCountry mode - allow any setting */ 1749 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: rd %d allowed\n", 1750 __func__, rd); 1751 return AH_TRUE; 1752#ifdef AH_SUPPORT_11D 1753 } else if ((rd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) { 1754 int i; 1755 for (i=0; i < N(allCountries); i++) { 1756 if (cc == allCountries[i].countryCode) 1757 return AH_TRUE; 1758 } 1759#endif 1760 } else { 1761 int i; 1762 for (i = 0; i < N(allCountries); i++) { 1763 if (cc == allCountries[i].countryCode && 1764 allCountries[i].regDmnEnum == rd) 1765 return AH_TRUE; 1766 } 1767 } 1768 return AH_FALSE; 1769} 1770 1771/* 1772 * Return the mask of available modes based on the hardware 1773 * capabilities and the specified country code and reg domain. 1774 */ 1775static u_int 1776ath_hal_getwmodesnreg(struct ath_hal *ah, COUNTRY_CODE_TO_ENUM_RD *country, 1777 REG_DOMAIN *rd5GHz) 1778{ 1779 u_int modesAvail; 1780 1781 /* Get modes that HW is capable of */ 1782 modesAvail = ath_hal_getWirelessModes(ah); 1783 1784 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 1785 "%s: wireless modes 0x%x cc %u rd %u\n", 1786 __func__, modesAvail, country->countryCode, country->regDmnEnum); 1787 1788 /* Check country regulations for allowed modes */ 1789 if ((modesAvail & (HAL_MODE_11A_TURBO|HAL_MODE_TURBO)) && 1790 !country->allow11aTurbo) { 1791 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 1792 "%s: disallow 11aTurbo\n", __func__); 1793 modesAvail &= ~(HAL_MODE_11A_TURBO | HAL_MODE_TURBO); 1794 } 1795 if ((modesAvail & HAL_MODE_11G_TURBO) && !country->allow11gTurbo) { 1796 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 1797 "%s: disallow 11gTurbo\n", __func__); 1798 modesAvail &= ~HAL_MODE_11G_TURBO; 1799 } 1800 if ((modesAvail & HAL_MODE_11G) && !country->allow11g) { 1801 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 1802 "%s: disallow 11g\n", __func__); 1803 modesAvail &= ~HAL_MODE_11G; 1804 } 1805 if ((modesAvail & HAL_MODE_11A) && isChanBitMaskZero(rd5GHz->chan11a)) { 1806 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 1807 "%s: disallow 11a\n", __func__); 1808 modesAvail &= ~HAL_MODE_11A; 1809 } 1810 1811 if ((modesAvail & HAL_MODE_11NG_HT20) && !country->allow11ng20) { 1812 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 1813 "%s: disallow 11g HT20\n", __func__); 1814 modesAvail &= ~HAL_MODE_11NG_HT20; 1815 } 1816 if ((modesAvail & HAL_MODE_11NA_HT20) && !country->allow11na20) { 1817 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 1818 "%s: disallow 11a HT20\n", __func__); 1819 modesAvail &= ~HAL_MODE_11NA_HT20; 1820 } 1821 if ((modesAvail & HAL_MODE_11NG_HT40PLUS) && !country->allow11ng40) { 1822 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 1823 "%s: disallow 11g HT40+\n", __func__); 1824 modesAvail &= ~HAL_MODE_11NG_HT40PLUS; 1825 } 1826 if ((modesAvail & HAL_MODE_11NG_HT40MINUS) && !country->allow11ng40) { 1827 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 1828 "%s: disallow 11g HT40-\n", __func__); 1829 modesAvail &= ~HAL_MODE_11NG_HT40MINUS; 1830 } 1831 if ((modesAvail & HAL_MODE_11NA_HT40PLUS) && !country->allow11na40) { 1832 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 1833 "%s: disallow 11a HT40+\n", __func__); 1834 modesAvail &= ~HAL_MODE_11NA_HT40PLUS; 1835 } 1836 if ((modesAvail & HAL_MODE_11NA_HT40MINUS) && !country->allow11na40) { 1837 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 1838 "%s: disallow 11a HT40-\n", __func__); 1839 modesAvail &= ~HAL_MODE_11NA_HT40MINUS; 1840 } 1841 1842 return modesAvail; 1843} 1844 1845/* 1846 * Return the mask of available modes based on the hardware 1847 * capabilities and the specified country code. 1848 */ 1849 1850u_int 1851ath_hal_getwirelessmodes(struct ath_hal *ah, HAL_CTRY_CODE cc) 1852{ 1853 COUNTRY_CODE_TO_ENUM_RD *country = AH_NULL; 1854 u_int mode = 0; 1855 REG_DOMAIN rd; 1856 1857 country = findCountry(cc); 1858 if (country != AH_NULL) { 1859 if (getWmRD(ah, country, ~CHANNEL_2GHZ, &rd)) 1860 mode = ath_hal_getwmodesnreg(ah, country, &rd); 1861 } 1862 return mode; 1863} 1864 1865/* 1866 * Return if device is public safety. 1867 */ 1868HAL_BOOL 1869ath_hal_ispublicsafetysku(struct ath_hal *ah) 1870{ 1871 uint16_t rd = getEepromRD(ah); 1872 1873 switch (rd) { 1874 case FCC4_FCCA: 1875 case CTRY_UNITED_STATES_FCC49 | COUNTRY_ERD_FLAG: 1876 return AH_TRUE; 1877 case DEBUG_REG_DMN: 1878 case NO_ENUMRD: 1879 if (AH_PRIVATE(ah)->ah_countryCode == CTRY_UNITED_STATES_FCC49) 1880 return AH_TRUE; 1881 break; 1882 } 1883 return AH_FALSE; 1884} 1885 1886/* 1887 * Find the pointer to the country element in the country table 1888 * corresponding to the country code 1889 */ 1890static COUNTRY_CODE_TO_ENUM_RD* 1891findCountry(HAL_CTRY_CODE countryCode) 1892{ 1893 int i; 1894 1895 for (i = 0; i < N(allCountries); i++) { 1896 if (allCountries[i].countryCode == countryCode) 1897 return &allCountries[i]; 1898 } 1899 return AH_NULL; /* Not found */ 1900} 1901 1902/* 1903 * Calculate a default country based on the EEPROM setting. 1904 */ 1905static HAL_CTRY_CODE 1906getDefaultCountry(struct ath_hal *ah) 1907{ 1908 uint16_t rd; 1909 int i; 1910 1911 rd = getEepromRD(ah); 1912 if (rd & COUNTRY_ERD_FLAG) { 1913 COUNTRY_CODE_TO_ENUM_RD *country = AH_NULL; 1914 uint16_t cc = rd & ~COUNTRY_ERD_FLAG; 1915 1916 country = findCountry(cc); 1917 if (country != AH_NULL) 1918 return cc; 1919 } 1920 /* 1921 * Check reg domains that have only one country 1922 */ 1923 for (i = 0; i < N(regDomainPairs); i++) 1924 if (regDomainPairs[i].regDmnEnum == rd) { 1925 if (regDomainPairs[i].singleCC != 0) 1926 return regDomainPairs[i].singleCC; 1927 else 1928 i = N(regDomainPairs); 1929 } 1930 return CTRY_DEFAULT; 1931} 1932 1933static HAL_BOOL 1934isValidRegDmn(int regDmn, REG_DOMAIN *rd) 1935{ 1936 int i; 1937 1938 for (i = 0; i < N(regDomains); i++) { 1939 if (regDomains[i].regDmnEnum == regDmn) { 1940 if (rd != AH_NULL) { 1941 OS_MEMCPY(rd, ®Domains[i], 1942 sizeof(REG_DOMAIN)); 1943 } 1944 return AH_TRUE; 1945 } 1946 } 1947 return AH_FALSE; 1948} 1949 1950static HAL_BOOL 1951isValidRegDmnPair(int regDmnPair) 1952{ 1953 int i; 1954 1955 if (regDmnPair == NO_ENUMRD) 1956 return AH_FALSE; 1957 for (i = 0; i < N(regDomainPairs); i++) { 1958 if (regDomainPairs[i].regDmnEnum == regDmnPair) 1959 return AH_TRUE; 1960 } 1961 return AH_FALSE; 1962} 1963 1964/* 1965 * Return the Wireless Mode Regulatory Domain based 1966 * on the country code and the wireless mode. 1967 */ 1968static HAL_BOOL 1969getWmRD(struct ath_hal *ah, COUNTRY_CODE_TO_ENUM_RD *country, 1970 uint16_t channelFlag, REG_DOMAIN *rd) 1971{ 1972 int regDmn; 1973 REG_DMN_PAIR_MAPPING *regPair; 1974 uint64_t flags; 1975 1976 if (country->countryCode == CTRY_DEFAULT) { 1977 uint16_t rdnum = getEepromRD(ah); 1978 1979 if ((rdnum & COUNTRY_ERD_FLAG) == 0) { 1980 if (isValidRegDmn(rdnum, AH_NULL) || 1981 isValidRegDmnPair(rdnum)) 1982 regDmn = rdnum; 1983 else 1984 regDmn = country->regDmnEnum; 1985 } else 1986 regDmn = country->regDmnEnum; 1987 } else 1988 regDmn = country->regDmnEnum; 1989 regPair = AH_NULL; 1990 flags = NO_REQ; 1991 if ((regDmn & MULTI_DOMAIN_MASK) == 0) { 1992 int i; 1993 1994 for (i = 0; i < N(regDomainPairs); i++) { 1995 if (regDomainPairs[i].regDmnEnum == regDmn) { 1996 regPair = ®DomainPairs[i]; 1997 break; 1998 } 1999 } 2000 if (regPair == AH_NULL) { 2001 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2002 "%s: Failed to find reg domain pair %u\n", 2003 __func__, regDmn); 2004 return AH_FALSE; 2005 } 2006 if (channelFlag & CHANNEL_2GHZ) { 2007 regDmn = regPair->regDmn2GHz; 2008 flags = regPair->flags2GHz; 2009 } else { 2010 regDmn = regPair->regDmn5GHz; 2011 flags = regPair->flags5GHz; 2012 } 2013 } 2014 2015 /* 2016 * We either started with a unitary reg domain or we've found the 2017 * unitary reg domain of the pair 2018 */ 2019 if (isValidRegDmn(regDmn, rd)) { 2020 if (regPair != AH_NULL) 2021 rd->pscan &= regPair->pscanMask; 2022 if ((country->regDmnEnum & MULTI_DOMAIN_MASK) == 0 && 2023 flags != NO_REQ) 2024 rd->flags = flags; 2025 return AH_TRUE; 2026 } else { 2027 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2028 "%s: Failed to find unitary reg domain %u\n", __func__, 2029 country->regDmnEnum); 2030 return AH_FALSE; 2031 } 2032} 2033 2034static HAL_BOOL 2035IS_BIT_SET(int bit, const uint64_t bitmask[]) 2036{ 2037 int byteOffset, bitnum; 2038 uint64_t val; 2039 2040 byteOffset = bit/64; 2041 bitnum = bit - byteOffset*64; 2042 val = ((uint64_t) 1) << bitnum; 2043 return (bitmask[byteOffset] & val) != 0; 2044} 2045 2046/* Add given regclassid into regclassids array upto max of maxregids */ 2047static void 2048ath_add_regclassid(uint8_t *regclassids, u_int maxregids, 2049 u_int *nregids, uint8_t regclassid) 2050{ 2051 int i; 2052 2053 /* Is regclassid valid? */ 2054 if (regclassid == 0) 2055 return; 2056 2057 for (i = 0; i < maxregids; i++) { 2058 if (regclassids[i] == regclassid) /* already present */ 2059 return; 2060 if (regclassids[i] == 0) { /* free slot */ 2061 regclassids[i] = regclassid; 2062 (*nregids)++; 2063 return; 2064 } 2065 } 2066} 2067 2068/* 2069 * Setup the channel list based on the information in the EEPROM and 2070 * any supplied country code. Note that we also do a bunch of EEPROM 2071 * verification here and setup certain regulatory-related access 2072 * control data used later on. 2073 */ 2074 2075HAL_BOOL 2076ath_hal_init_channels(struct ath_hal *ah, 2077 HAL_CHANNEL *chans, u_int maxchans, u_int *nchans, 2078 uint8_t *regclassids, u_int maxregids, u_int *nregids, 2079 HAL_CTRY_CODE cc, u_int modeSelect, 2080 HAL_BOOL enableOutdoor, HAL_BOOL enableExtendedChannels) 2081{ 2082#define CHANNEL_HALF_BW 10 2083#define CHANNEL_QUARTER_BW 5 2084 u_int modesAvail; 2085 uint16_t maxChan; 2086 COUNTRY_CODE_TO_ENUM_RD *country = AH_NULL; 2087 REG_DOMAIN rd5GHz, rd2GHz; 2088 const struct cmode *cm; 2089 HAL_CHANNEL_INTERNAL *ichans = &AH_PRIVATE(ah)->ah_channels[0]; 2090 int next, b; 2091 uint8_t ctl; 2092 int is_quarterchan_cap, is_halfchan_cap; 2093 2094 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: cc %u mode 0x%x%s%s\n", 2095 __func__, cc, modeSelect, enableOutdoor? " Enable outdoor" : " ", 2096 enableExtendedChannels ? " Enable ecm" : ""); 2097 2098 /* 2099 * Validate the EEPROM setting and setup defaults 2100 */ 2101 if (!isEepromValid(ah)) { 2102 /* 2103 * Don't return any channels if the EEPROM has an 2104 * invalid regulatory domain/country code setting. 2105 */ 2106 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2107 "%s: invalid EEPROM contents\n",__func__); 2108 return AH_FALSE; 2109 } 2110 2111 AH_PRIVATE(ah)->ah_countryCode = getDefaultCountry(ah); 2112 2113#ifndef AH_SUPPORT_11D 2114 if (AH_PRIVATE(ah)->ah_countryCode == CTRY_DEFAULT) { 2115#endif 2116 /* 2117 * We now have enough state to validate any country code 2118 * passed in by the caller. 2119 */ 2120 if (!isCountryCodeValid(ah, cc)) { 2121 /* NB: Atheros silently ignores invalid country codes */ 2122 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2123 "%s: invalid country code %d\n", __func__, cc); 2124 return AH_FALSE; 2125 } 2126 AH_PRIVATE(ah)->ah_countryCode = cc & COUNTRY_CODE_MASK; 2127#ifndef AH_SUPPORT_11D 2128 } 2129#endif 2130 2131 /* Get pointers to the country element and the reg domain elements */ 2132 country = findCountry(AH_PRIVATE(ah)->ah_countryCode); 2133 2134 if (country == AH_NULL) { 2135 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "NULL Country!, cc= %d\n", 2136 AH_PRIVATE(ah)->ah_countryCode); 2137 return AH_FALSE; 2138 } 2139 2140 if (!getWmRD(ah, country, ~CHANNEL_2GHZ, &rd5GHz)) { 2141 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2142 "%s: no unitary 5GHz regdomain for country %u\n", 2143 __func__, AH_PRIVATE(ah)->ah_countryCode); 2144 return AH_FALSE; 2145 } 2146 if (!getWmRD(ah, country, CHANNEL_2GHZ, &rd2GHz)) { 2147 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2148 "%s: no unitary 2GHz regdomain for country %u\n", 2149 __func__, AH_PRIVATE(ah)->ah_countryCode); 2150 return AH_FALSE; 2151 } 2152 2153 modesAvail = ath_hal_getwmodesnreg(ah, country, &rd5GHz); 2154 maxChan = !enableOutdoor ? country->outdoorChanStart : 7000; 2155 is_halfchan_cap = AH_PRIVATE(ah)->ah_caps.halChanHalfRate; 2156 is_quarterchan_cap = AH_PRIVATE(ah)->ah_caps.halChanQuarterRate; 2157 2158 if (maxchans > N(AH_PRIVATE(ah)->ah_channels)) 2159 maxchans = N(AH_PRIVATE(ah)->ah_channels); 2160 next = 0; 2161 for (cm = modes; cm < &modes[N(modes)]; cm++) { 2162 uint16_t c, c_hi, c_lo; 2163 uint64_t *channelBM = AH_NULL; 2164 REG_DOMAIN *rd = AH_NULL; 2165 REG_DMN_FREQ_BAND *fband = AH_NULL,*freqs; 2166 int low_adj, hi_adj, channelSep, lastc; 2167 2168 if ((cm->mode & modeSelect) == 0) { 2169 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2170 "%s: skip mode 0x%x flags 0x%x\n", 2171 __func__, cm->mode, cm->flags); 2172 continue; 2173 } 2174 if ((cm->mode & modesAvail) == 0) { 2175 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2176 "%s: !avail mode 0x%x (0x%x) flags 0x%x\n", 2177 __func__, modesAvail, cm->mode, cm->flags); 2178 continue; 2179 } 2180 if (!ath_hal_getChannelEdges(ah, cm->flags, &c_lo, &c_hi)) { 2181 /* channel not supported by hardware, skip it */ 2182 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2183 "%s: channels 0x%x not supported by hardware\n", 2184 __func__,cm->flags); 2185 continue; 2186 } 2187 switch (cm->mode) { 2188 case HAL_MODE_TURBO: 2189 rd = &rd5GHz; 2190 channelBM = rd->chan11a_turbo; 2191 freqs = ®Dmn5GhzTurboFreq[0]; 2192 ctl = rd->conformanceTestLimit | CTL_TURBO; 2193 break; 2194 case HAL_MODE_11A: 2195 case HAL_MODE_11NA_HT20: 2196 case HAL_MODE_11NA_HT40PLUS: 2197 case HAL_MODE_11NA_HT40MINUS: 2198 rd = &rd5GHz; 2199 channelBM = rd->chan11a; 2200 freqs = ®Dmn5GhzFreq[0]; 2201 ctl = rd->conformanceTestLimit; 2202 break; 2203 case HAL_MODE_11B: 2204 rd = &rd2GHz; 2205 channelBM = rd->chan11b; 2206 freqs = ®Dmn2GhzFreq[0]; 2207 ctl = rd->conformanceTestLimit | CTL_11B; 2208 break; 2209 case HAL_MODE_11G: 2210 case HAL_MODE_11NG_HT20: 2211 case HAL_MODE_11NG_HT40PLUS: 2212 case HAL_MODE_11NG_HT40MINUS: 2213 rd = &rd2GHz; 2214 channelBM = rd->chan11g; 2215 freqs = ®Dmn2Ghz11gFreq[0]; 2216 ctl = rd->conformanceTestLimit | CTL_11G; 2217 break; 2218 case HAL_MODE_11G_TURBO: 2219 rd = &rd2GHz; 2220 channelBM = rd->chan11g_turbo; 2221 freqs = ®Dmn2Ghz11gTurboFreq[0]; 2222 ctl = rd->conformanceTestLimit | CTL_108G; 2223 break; 2224 case HAL_MODE_11A_TURBO: 2225 rd = &rd5GHz; 2226 channelBM = rd->chan11a_dyn_turbo; 2227 freqs = ®Dmn5GhzTurboFreq[0]; 2228 ctl = rd->conformanceTestLimit | CTL_108G; 2229 break; 2230 default: 2231 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2232 "%s: Unkonwn HAL mode 0x%x\n", __func__, cm->mode); 2233 continue; 2234 } 2235 if (isChanBitMaskZero(channelBM)) 2236 continue; 2237 /* 2238 * Setup special handling for HT40 channels; e.g. 2239 * 5G HT40 channels require 40Mhz channel separation. 2240 */ 2241 hi_adj = (cm->mode == HAL_MODE_11NA_HT40PLUS || 2242 cm->mode == HAL_MODE_11NG_HT40PLUS) ? -20 : 0; 2243 low_adj = (cm->mode == HAL_MODE_11NA_HT40MINUS || 2244 cm->mode == HAL_MODE_11NG_HT40MINUS) ? 20 : 0; 2245 channelSep = (cm->mode == HAL_MODE_11NA_HT40PLUS || 2246 cm->mode == HAL_MODE_11NA_HT40MINUS) ? 40 : 0; 2247 2248 for (b = 0; b < 64*BMLEN; b++) { 2249 if (!IS_BIT_SET(b, channelBM)) 2250 continue; 2251 fband = &freqs[b]; 2252 lastc = 0; 2253 2254 ath_add_regclassid(regclassids, maxregids, 2255 nregids, fband->regClassId); 2256 2257 for (c = fband->lowChannel + low_adj; 2258 c <= fband->highChannel + hi_adj; 2259 c += fband->channelSep) { 2260 HAL_CHANNEL_INTERNAL icv; 2261 2262 if (!(c_lo <= c && c <= c_hi)) { 2263 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2264 "%s: c %u out of range [%u..%u]\n", 2265 __func__, c, c_lo, c_hi); 2266 continue; 2267 } 2268 if ((fband->channelBW == CHANNEL_HALF_BW) && 2269 !is_halfchan_cap) { 2270 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2271 "%s: Skipping %u half rate channel\n", 2272 __func__, c); 2273 continue; 2274 } 2275 2276 if ((fband->channelBW == CHANNEL_QUARTER_BW) && 2277 !is_quarterchan_cap) { 2278 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2279 "%s: Skipping %u quarter rate channel\n", 2280 __func__, c); 2281 continue; 2282 } 2283 2284 if (((c+fband->channelSep)/2) > (maxChan+HALF_MAXCHANBW)) { 2285 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2286 "%s: c %u > maxChan %u\n", 2287 __func__, c, maxChan); 2288 continue; 2289 } 2290 if (next >= maxchans){ 2291 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2292 "%s: too many channels for channel table\n", 2293 __func__); 2294 goto done; 2295 } 2296 if ((fband->usePassScan & IS_ECM_CHAN) && 2297 !enableExtendedChannels) { 2298 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2299 "Skipping ecm channel\n"); 2300 continue; 2301 } 2302 /* XXX needs to be in ath_hal_checkchannel */ 2303 if ((rd->flags & NO_HOSTAP) && 2304 (AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP)) { 2305 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2306 "Skipping HOSTAP channel\n"); 2307 continue; 2308 } 2309 /* 2310 * Make sure that channel separation 2311 * meets the requirement. 2312 */ 2313 if (lastc && channelSep && 2314 (c-lastc) < channelSep) 2315 continue; 2316 2317 OS_MEMZERO(&icv, sizeof(icv)); 2318 icv.channel = c; 2319 icv.channelFlags = cm->flags; 2320 switch (fband->channelBW) { 2321 case CHANNEL_HALF_BW: 2322 icv.channelFlags |= CHANNEL_HALF; 2323 break; 2324 case CHANNEL_QUARTER_BW: 2325 icv.channelFlags |= CHANNEL_QUARTER; 2326 break; 2327 } 2328 2329 icv.maxRegTxPower = fband->powerDfs; 2330 icv.antennaMax = fband->antennaMax; 2331 icv.regDmnFlags = rd->flags; 2332 icv.conformanceTestLimit = ctl; 2333 if (fband->usePassScan & rd->pscan) 2334 icv.channelFlags |= CHANNEL_PASSIVE; 2335 else 2336 icv.channelFlags &= ~CHANNEL_PASSIVE; 2337 lastc = c; 2338 if (fband->useDfs & rd->dfsMask) { 2339 /* DFS and HT40 don't mix */ 2340 if (cm->mode == HAL_MODE_11NA_HT40PLUS || 2341 cm->mode == HAL_MODE_11NA_HT40MINUS) 2342 continue; 2343 icv.privFlags = CHANNEL_DFS; 2344 } else 2345 icv.privFlags = 0; 2346 if (rd->flags & LIMIT_FRAME_4MS) 2347 icv.privFlags |= CHANNEL_4MS_LIMIT; 2348 2349 ichans[next++] = icv; 2350 } 2351 } 2352 } 2353done: 2354 if (next != 0) { 2355 int i; 2356 2357 /* XXX maxchans set above so this cannot happen? */ 2358 if (next > N(AH_PRIVATE(ah)->ah_channels)) { 2359 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2360 "%s: too many channels %u; truncating to %u\n", 2361 __func__, next, 2362 (int) N(AH_PRIVATE(ah)->ah_channels)); 2363 next = N(AH_PRIVATE(ah)->ah_channels); 2364 } 2365 2366 /* 2367 * Keep a private copy of the channel list so we can 2368 * constrain future requests to only these channels 2369 */ 2370 ath_hal_sort(ichans, next, sizeof(HAL_CHANNEL_INTERNAL), 2371 chansort); 2372 AH_PRIVATE(ah)->ah_nchan = next; 2373 2374 /* 2375 * Copy the channel list to the public channel list 2376 */ 2377 for (i = 0; i < next; i++) { 2378 chans[i].channel = ichans[i].channel; 2379 chans[i].channelFlags = ichans[i].channelFlags; 2380 chans[i].privFlags = ichans[i].privFlags; 2381 chans[i].maxRegTxPower = ichans[i].maxRegTxPower; 2382 } 2383 /* 2384 * Retrieve power limits. 2385 */ 2386 ath_hal_getpowerlimits(ah, chans, next); 2387 for (i = 0; i < next; i++) { 2388 ichans[i].maxTxPower = chans[i].maxTxPower; 2389 ichans[i].minTxPower = chans[i].minTxPower; 2390 } 2391 } 2392 *nchans = next; 2393 /* XXX copy private setting to public area */ 2394 ah->ah_countryCode = AH_PRIVATE(ah)->ah_countryCode; 2395 return (next != 0); 2396#undef CHANNEL_HALF_BW 2397#undef CHANNEL_QUARTER_BW 2398} 2399 2400/* 2401 * Return whether or not the specified channel is ok to use 2402 * based on the current regulatory domain constraints and 2403 * DFS interference. 2404 */ 2405HAL_CHANNEL_INTERNAL * 2406ath_hal_checkchannel(struct ath_hal *ah, const HAL_CHANNEL *c) 2407{ 2408#define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) 2409 HAL_CHANNEL_INTERNAL *base, *cc; 2410 /* NB: be wary of user-specified channel flags */ 2411 int flags = c->channelFlags & CHAN_FLAGS; 2412 int n, lim, d; 2413 2414 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, 2415 "%s: channel %u/0x%x (0x%x) requested\n", 2416 __func__, c->channel, c->channelFlags, flags); 2417 2418 /* 2419 * Check current channel to avoid the lookup. 2420 */ 2421 cc = AH_PRIVATE(ah)->ah_curchan; 2422 if (cc != AH_NULL && cc->channel == c->channel && 2423 (cc->channelFlags & CHAN_FLAGS) == flags) { 2424 if ((cc->privFlags & CHANNEL_INTERFERENCE) && 2425 (cc->channelFlags & CHANNEL_DFS)) 2426 return AH_NULL; 2427 else 2428 return cc; 2429 } 2430 2431 /* binary search based on known sorting order */ 2432 base = AH_PRIVATE(ah)->ah_channels; 2433 n = AH_PRIVATE(ah)->ah_nchan; 2434 /* binary search based on known sorting order */ 2435 for (lim = n; lim != 0; lim >>= 1) { 2436 cc = &base[lim>>1]; 2437 d = c->channel - cc->channel; 2438 if (d == 0) { 2439 if ((cc->channelFlags & CHAN_FLAGS) == flags) { 2440 if ((cc->privFlags & CHANNEL_INTERFERENCE) && 2441 (cc->channelFlags & CHANNEL_DFS)) 2442 return AH_NULL; 2443 else 2444 return cc; 2445 } 2446 d = flags - (cc->channelFlags & CHAN_FLAGS); 2447 } 2448 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: channel %u/0x%x d %d\n", 2449 __func__, cc->channel, cc->channelFlags, d); 2450 if (d > 0) { 2451 base = cc + 1; 2452 lim--; 2453 } 2454 } 2455 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: no match for %u/0x%x\n", 2456 __func__, c->channel, c->channelFlags); 2457 return AH_NULL; 2458#undef CHAN_FLAGS 2459} 2460 2461/* 2462 * Return the max allowed antenna gain and apply any regulatory 2463 * domain specific changes. 2464 * 2465 * NOTE: a negative reduction is possible in RD's that only 2466 * measure radiated power (e.g., ETSI) which would increase 2467 * that actual conducted output power (though never beyond 2468 * the calibrated target power). 2469 */ 2470u_int 2471ath_hal_getantennareduction(struct ath_hal *ah, HAL_CHANNEL *chan, u_int twiceGain) 2472{ 2473 HAL_CHANNEL_INTERNAL *ichan=AH_NULL; 2474 int8_t antennaMax; 2475 2476 if ((ichan = ath_hal_checkchannel(ah, chan)) != AH_NULL) { 2477 antennaMax = twiceGain - ichan->antennaMax*2; 2478 return (antennaMax < 0) ? 0 : antennaMax; 2479 } else { 2480 /* Failed to find the correct index - may be a debug channel */ 2481 return 0; 2482 } 2483} 2484 2485 2486/* XXX - maybe move ctl decision into channel set area or 2487 into the tables so no decision is needed in the code */ 2488 2489#define isWwrSKU(_ah) \ 2490 ((getEepromRD((_ah)) & WORLD_SKU_MASK) == WORLD_SKU_PREFIX || \ 2491 getEepromRD(_ah) == WORLD) 2492 2493 2494/* 2495 * Return the test group from the specified channel from 2496 * the regulatory table. 2497 * 2498 * TODO: CTL for 11B CommonMode when regulatory domain is unknown 2499 */ 2500u_int 2501ath_hal_getctl(struct ath_hal *ah, HAL_CHANNEL *chan) 2502{ 2503 u_int ctl = NO_CTL; 2504 HAL_CHANNEL_INTERNAL *ichan; 2505 2506 /* Special CTL to signify WWR SKU without a known country */ 2507 if (AH_PRIVATE(ah)->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)) { 2508 if (IS_CHAN_B(chan)) { 2509 ctl = SD_NO_CTL | CTL_11B; 2510 } else if (IS_CHAN_G(chan)) { 2511 ctl = SD_NO_CTL | CTL_11G; 2512 } else if (IS_CHAN_108G(chan)) { 2513 ctl = SD_NO_CTL | CTL_108G; 2514 } else if (IS_CHAN_T(chan)) { 2515 ctl = SD_NO_CTL | CTL_TURBO; 2516 } else { 2517 ctl = SD_NO_CTL | CTL_11A; 2518 } 2519 } else { 2520 if ((ichan = ath_hal_checkchannel(ah, chan)) != AH_NULL) { 2521 ctl = ichan->conformanceTestLimit; 2522 /* limit 11G OFDM power */ 2523 if (IS_CHAN_PUREG(chan) && 2524 (ctl & CTL_MODE_M) == CTL_11B) 2525 ctl = (ctl &~ CTL_MODE_M) | CTL_11G; 2526 } 2527 } 2528 return ctl; 2529} 2530 2531/* 2532 * Return whether or not a noise floor check is required in 2533 * the current regulatory domain for the specified channel. 2534 */ 2535HAL_BOOL 2536ath_hal_getnfcheckrequired(struct ath_hal *ah, HAL_CHANNEL *chan) 2537{ 2538 HAL_CHANNEL_INTERNAL *ichan; 2539 2540 if ((ichan = ath_hal_checkchannel(ah, chan)) != AH_NULL) 2541 return ((ichan->regDmnFlags & NEED_NFC) ? AH_TRUE : AH_FALSE); 2542 return AH_FALSE; 2543} 2544 2545/* 2546 * Insertion sort. 2547 */ 2548#define swap(_a, _b, _size) { \ 2549 uint8_t *s = _b; \ 2550 int i = _size; \ 2551 do { \ 2552 uint8_t tmp = *_a; \ 2553 *_a++ = *s; \ 2554 *s++ = tmp; \ 2555 } while (--i); \ 2556 _a -= _size; \ 2557} 2558 2559static void 2560ath_hal_sort(void *a, size_t n, size_t size, ath_hal_cmp_t *cmp) 2561{ 2562 uint8_t *aa = a; 2563 uint8_t *ai, *t; 2564 2565 for (ai = aa+size; --n >= 1; ai += size) 2566 for (t = ai; t > aa; t -= size) { 2567 uint8_t *u = t - size; 2568 if (cmp(u, t) <= 0) 2569 break; 2570 swap(u, t, size); 2571 } 2572} 2573