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