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