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