2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
3 * Copyright (c) 2005-2006 Atheros Communications, Inc.
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.
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.
18 * $FreeBSD: head/sys/dev/ath/ath_hal/ah_regdomain.c 199491 2009-11-18 18:48:18Z rpaulo $
25 #include <netproto/802_11/_ieee80211.h>
26 #include <netproto/802_11/ieee80211_regdomain.h>
28 #include "ah_internal.h"
29 #include "ah_eeprom.h"
33 * XXX this code needs a audit+review
36 /* used throughout this file... */
37 #define N(a) (sizeof (a) / sizeof (a[0]))
39 #define HAL_MODE_11A_TURBO HAL_MODE_108A
40 #define HAL_MODE_11G_TURBO HAL_MODE_108G
43 * BMLEN defines the size of the bitmask used to hold frequency
44 * band specifications. Note this must agree with the BM macro
45 * definition that's used to setup initializers. See also further
48 #define BMLEN 2 /* 2 x 64 bits in each channel bitmask */
49 typedef uint64_t chanbmask_t[BMLEN];
52 (((_a) >= 0 && (_a) < 64 ? (((uint64_t) 1)<<(_a)) : (uint64_t) 0))
54 (((_a) > 63 && (_a) < 128 ? (((uint64_t) 1)<<((_a)-64)) : (uint64_t) 0))
55 #define BM1(_fa) { W0(_fa), W1(_fa) }
56 #define BM2(_fa, _fb) { W0(_fa) | W0(_fb), W1(_fa) | W1(_fb) }
57 #define BM3(_fa, _fb, _fc) \
58 { W0(_fa) | W0(_fb) | W0(_fc), W1(_fa) | W1(_fb) | W1(_fc) }
59 #define BM4(_fa, _fb, _fc, _fd) \
60 { W0(_fa) | W0(_fb) | W0(_fc) | W0(_fd), \
61 W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) }
62 #define BM5(_fa, _fb, _fc, _fd, _fe) \
63 { W0(_fa) | W0(_fb) | W0(_fc) | W0(_fd) | W0(_fe), \
64 W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) | W1(_fe) }
65 #define BM6(_fa, _fb, _fc, _fd, _fe, _ff) \
66 { W0(_fa) | W0(_fb) | W0(_fc) | W0(_fd) | W0(_fe) | W0(_ff), \
67 W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) | W1(_fe) | W1(_ff) }
68 #define BM7(_fa, _fb, _fc, _fd, _fe, _ff, _fg) \
69 { W0(_fa) | W0(_fb) | W0(_fc) | W0(_fd) | W0(_fe) | W0(_ff) | \
71 W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) | W1(_fe) | W1(_ff) | \
73 #define BM8(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh) \
74 { W0(_fa) | W0(_fb) | W0(_fc) | W0(_fd) | W0(_fe) | W0(_ff) | \
76 W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) | W1(_fe) | W1(_ff) | \
78 #define BM9(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh, _fi) \
79 { W0(_fa) | W0(_fb) | W0(_fc) | W0(_fd) | W0(_fe) | W0(_ff) | \
80 W0(_fg) | W0(_fh) | W0(_fi) , \
81 W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) | W1(_fe) | W1(_ff) | \
82 W1(_fg) | W1(_fh) | W1(_fi) }
85 * Mask to check whether a domain is a multidomain or a single domain
87 #define MULTI_DOMAIN_MASK 0xFF00
90 * Enumerated Regulatory Domain Information 8 bit values indicate that
91 * the regdomain is really a pair of unitary regdomains. 12 bit values
92 * are the real unitary regdomains and are the only ones which have the
93 * frequency bitmasks and flags set.
97 * The following regulatory domain definitions are
98 * found in the EEPROM. Each regulatory domain
99 * can operate in either a 5GHz or 2.4GHz wireless mode or
100 * both 5GHz and 2.4GHz wireless modes.
101 * In general, the value holds no special
102 * meaning and is used to decode into either specific
103 * 2.4GHz or 5GHz wireless mode for that particular
107 NULL1_WORLD = 0x03, /* For 11b-only countries (no 11a allowed) */
108 NULL1_ETSIB = 0x07, /* Israel */
110 FCC1_FCCA = 0x10, /* USA */
111 FCC1_WORLD = 0x11, /* Hong Kong */
112 FCC4_FCCA = 0x12, /* USA - Public Safety */
113 FCC5_FCCB = 0x13, /* USA w/ 1/2 and 1/4 width channels */
115 FCC2_FCCA = 0x20, /* Canada */
116 FCC2_WORLD = 0x21, /* Australia & HK */
118 FRANCE_RES = 0x31, /* Legacy France for OEM */
119 FCC3_FCCA = 0x3A, /* USA & Canada w/5470 band, 11h, DFS enabled */
120 FCC3_WORLD = 0x3B, /* USA & Canada w/5470 band, 11h, DFS enabled */
123 ETSI3_ETSIA = 0x32, /* France (optional) */
124 ETSI2_WORLD = 0x35, /* Hungary & others */
125 ETSI3_WORLD = 0x36, /* France & others */
129 ETSI6_WORLD = 0x34, /* Bulgaria */
130 ETSI_RESERVED = 0x33, /* Reserved (Do not used) */
132 MKK1_MKKA = 0x40, /* Japan (JP1) */
133 MKK1_MKKB = 0x41, /* Japan (JP0) */
134 APL4_WORLD = 0x42, /* Singapore */
135 MKK2_MKKA = 0x43, /* Japan with 4.9G channels */
136 APL_RESERVED = 0x44, /* Reserved (Do not used) */
137 APL2_WORLD = 0x45, /* Korea */
140 MKK1_FCCA = 0x48, /* Japan (JP1-1) */
141 APL2_APLD = 0x49, /* Korea with 2.3G channels */
142 MKK1_MKKA1 = 0x4A, /* Japan (JE1) */
143 MKK1_MKKA2 = 0x4B, /* Japan (JE2) */
144 MKK1_MKKC = 0x4C, /* Japan (MKK1_MKKA,except Ch14) */
147 APL1_WORLD = 0x52, /* Latin America */
151 APL2_ETSIC = 0x56, /* Venezuela */
152 APL5_WORLD = 0x58, /* Chile */
153 APL6_WORLD = 0x5B, /* Singapore */
154 APL7_FCCA = 0x5C, /* Taiwan 5.47 Band */
155 APL8_WORLD = 0x5D, /* Malaysia 5GHz */
156 APL9_WORLD = 0x5E, /* Korea 5GHz */
161 WOR0_WORLD = 0x60, /* World0 (WO0 SKU) */
162 WOR1_WORLD = 0x61, /* World1 (WO1 SKU) */
163 WOR2_WORLD = 0x62, /* World2 (WO2 SKU) */
164 WOR3_WORLD = 0x63, /* World3 (WO3 SKU) */
165 WOR4_WORLD = 0x64, /* World4 (WO4 SKU) */
166 WOR5_ETSIC = 0x65, /* World5 (WO5 SKU) */
168 WOR01_WORLD = 0x66, /* World0-1 (WW0-1 SKU) */
169 WOR02_WORLD = 0x67, /* World0-2 (WW0-2 SKU) */
170 EU1_WORLD = 0x68, /* Same as World0-2 (WW0-2 SKU), except active scan ch1-13. No ch14 */
172 WOR9_WORLD = 0x69, /* World9 (WO9 SKU) */
173 WORA_WORLD = 0x6A, /* WorldA (WOA SKU) */
174 WORB_WORLD = 0x6B, /* WorldB (WOB SKU) */
176 MKK3_MKKB = 0x80, /* Japan UNI-1 even + MKKB */
177 MKK3_MKKA2 = 0x81, /* Japan UNI-1 even + MKKA2 */
178 MKK3_MKKC = 0x82, /* Japan UNI-1 even + MKKC */
180 MKK4_MKKB = 0x83, /* Japan UNI-1 even + UNI-2 + MKKB */
181 MKK4_MKKA2 = 0x84, /* Japan UNI-1 even + UNI-2 + MKKA2 */
182 MKK4_MKKC = 0x85, /* Japan UNI-1 even + UNI-2 + MKKC */
184 MKK5_MKKB = 0x86, /* Japan UNI-1 even + UNI-2 + mid-band + MKKB */
185 MKK5_MKKA2 = 0x87, /* Japan UNI-1 even + UNI-2 + mid-band + MKKA2 */
186 MKK5_MKKC = 0x88, /* Japan UNI-1 even + UNI-2 + mid-band + MKKC */
188 MKK6_MKKB = 0x89, /* Japan UNI-1 even + UNI-1 odd MKKB */
189 MKK6_MKKA2 = 0x8A, /* Japan UNI-1 even + UNI-1 odd + MKKA2 */
190 MKK6_MKKC = 0x8B, /* Japan UNI-1 even + UNI-1 odd + MKKC */
192 MKK7_MKKB = 0x8C, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKB */
193 MKK7_MKKA2 = 0x8D, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA2 */
194 MKK7_MKKC = 0x8E, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKC */
196 MKK8_MKKB = 0x8F, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKB */
197 MKK8_MKKA2 = 0x90, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKA2 */
198 MKK8_MKKC = 0x91, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKC */
200 /* Following definitions are used only by s/w to map old
203 MKK3_MKKA = 0xF0, /* Japan UNI-1 even + MKKA */
204 MKK3_MKKA1 = 0xF1, /* Japan UNI-1 even + MKKA1 */
205 MKK3_FCCA = 0xF2, /* Japan UNI-1 even + FCCA */
206 MKK4_MKKA = 0xF3, /* Japan UNI-1 even + UNI-2 + MKKA */
207 MKK4_MKKA1 = 0xF4, /* Japan UNI-1 even + UNI-2 + MKKA1 */
208 MKK4_FCCA = 0xF5, /* Japan UNI-1 even + UNI-2 + FCCA */
209 MKK9_MKKA = 0xF6, /* Japan UNI-1 even + 4.9GHz */
210 MKK10_MKKA = 0xF7, /* Japan UNI-1 even + UNI-2 + 4.9GHz */
213 * Regulator domains ending in a number (e.g. APL1,
214 * MK1, ETSI4, etc) apply to 5GHz channel and power
215 * information. Regulator domains ending in a letter
216 * (e.g. APLA, FCCA, etc) apply to 2.4GHz channel and
219 APL1 = 0x0150, /* LAT & Asia */
220 APL2 = 0x0250, /* LAT & Asia */
221 APL3 = 0x0350, /* Taiwan */
222 APL4 = 0x0450, /* Jordan */
223 APL5 = 0x0550, /* Chile */
224 APL6 = 0x0650, /* Singapore */
225 APL8 = 0x0850, /* Malaysia */
226 APL9 = 0x0950, /* Korea (South) ROC 3 */
228 ETSI1 = 0x0130, /* Europe & others */
229 ETSI2 = 0x0230, /* Europe & others */
230 ETSI3 = 0x0330, /* Europe & others */
231 ETSI4 = 0x0430, /* Europe & others */
232 ETSI5 = 0x0530, /* Europe & others */
233 ETSI6 = 0x0630, /* Europe & others */
234 ETSIA = 0x0A30, /* France */
235 ETSIB = 0x0B30, /* Israel */
236 ETSIC = 0x0C30, /* Latin America */
238 FCC1 = 0x0110, /* US & others */
239 FCC2 = 0x0120, /* Canada, Australia & New Zealand */
240 FCC3 = 0x0160, /* US w/new middle band & DFS */
241 FCC4 = 0x0165, /* US Public Safety */
242 FCC5 = 0x0166, /* US w/ 1/2 and 1/4 width channels */
244 FCCB = 0x0A11, /* US w/ 1/2 and 1/4 width channels */
246 APLD = 0x0D50, /* South Korea */
248 MKK1 = 0x0140, /* Japan (UNI-1 odd)*/
249 MKK2 = 0x0240, /* Japan (4.9 GHz + UNI-1 odd) */
250 MKK3 = 0x0340, /* Japan (UNI-1 even) */
251 MKK4 = 0x0440, /* Japan (UNI-1 even + UNI-2) */
252 MKK5 = 0x0540, /* Japan (UNI-1 even + UNI-2 + mid-band) */
253 MKK6 = 0x0640, /* Japan (UNI-1 odd + UNI-1 even) */
254 MKK7 = 0x0740, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 */
255 MKK8 = 0x0840, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 + mid-band) */
256 MKK9 = 0x0940, /* Japan (UNI-1 even + 4.9 GHZ) */
257 MKK10 = 0x0B40, /* Japan (UNI-1 even + UNI-2 + 4.9 GHZ) */
258 MKKA = 0x0A40, /* Japan */
263 DEBUG_REG_DMN = 0x01ff,
266 #define WORLD_SKU_MASK 0x00F0
267 #define WORLD_SKU_PREFIX 0x0060
269 enum { /* conformance test limits */
276 * The following are flags for different requirements per reg domain.
277 * These requirements are either inhereted from the reg domain pair or
278 * from the unitary reg domain if the reg domain pair flags value is 0
281 NO_REQ = 0x00000000, /* NB: must be zero */
282 DISALLOW_ADHOC_11A = 0x00000001, /* adhoc not allowed in 5GHz */
283 DISALLOW_ADHOC_11A_TURB = 0x00000002, /* not allowed w/ 5GHz turbo */
284 NEED_NFC = 0x00000004, /* need noise floor check */
285 ADHOC_PER_11D = 0x00000008, /* must receive 11d beacon */
286 LIMIT_FRAME_4MS = 0x00000020, /* 4msec tx burst limit */
287 NO_HOSTAP = 0x00000040, /* No HOSTAP mode opereation */
291 * The following describe the bit masks for different passive scan
292 * capability/requirements per regdomain.
294 #define NO_PSCAN 0x0ULL /* NB: must be zero */
295 #define PSCAN_FCC 0x0000000000000001ULL
296 #define PSCAN_FCC_T 0x0000000000000002ULL
297 #define PSCAN_ETSI 0x0000000000000004ULL
298 #define PSCAN_MKK1 0x0000000000000008ULL
299 #define PSCAN_MKK2 0x0000000000000010ULL
300 #define PSCAN_MKKA 0x0000000000000020ULL
301 #define PSCAN_MKKA_G 0x0000000000000040ULL
302 #define PSCAN_ETSIA 0x0000000000000080ULL
303 #define PSCAN_ETSIB 0x0000000000000100ULL
304 #define PSCAN_ETSIC 0x0000000000000200ULL
305 #define PSCAN_WWR 0x0000000000000400ULL
306 #define PSCAN_MKKA1 0x0000000000000800ULL
307 #define PSCAN_MKKA1_G 0x0000000000001000ULL
308 #define PSCAN_MKKA2 0x0000000000002000ULL
309 #define PSCAN_MKKA2_G 0x0000000000004000ULL
310 #define PSCAN_MKK3 0x0000000000008000ULL
311 #define PSCAN_DEFER 0x7FFFFFFFFFFFFFFFULL
312 #define IS_ECM_CHAN 0x8000000000000000ULL
315 * THE following table is the mapping of regdomain pairs specified by
316 * an 8 bit regdomain value to the individual unitary reg domains
318 typedef struct regDomainPair {
319 HAL_REG_DOMAIN regDmnEnum; /* 16 bit reg domain pair */
320 HAL_REG_DOMAIN regDmn5GHz; /* 5GHz reg domain */
321 HAL_REG_DOMAIN regDmn2GHz; /* 2GHz reg domain */
322 uint32_t flags5GHz; /* Requirements flags (AdHoc
323 disallow, noise floor cal needed,
325 uint32_t flags2GHz; /* Requirements flags (AdHoc
326 disallow, noise floor cal needed,
328 uint64_t pscanMask; /* Passive Scan flags which
329 can override unitary domain
330 passive scan flags. This
331 value is used as a mask on
333 uint16_t singleCC; /* Country code of single country if
334 a one-on-one mapping exists */
335 } REG_DMN_PAIR_MAPPING;
337 static REG_DMN_PAIR_MAPPING regDomainPairs[] = {
338 {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
339 {NULL1_WORLD, NULL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
340 {NULL1_ETSIB, NULL1, ETSIB, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
341 {NULL1_ETSIC, NULL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
343 {FCC2_FCCA, FCC2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
344 {FCC2_WORLD, FCC2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
345 {FCC2_ETSIC, FCC2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
346 {FCC3_FCCA, FCC3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
347 {FCC3_WORLD, FCC3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
348 {FCC4_FCCA, FCC4, FCCA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
349 {FCC5_FCCB, FCC5, FCCB, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
351 {ETSI1_WORLD, ETSI1, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
352 {ETSI2_WORLD, ETSI2, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
353 {ETSI3_WORLD, ETSI3, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
354 {ETSI4_WORLD, ETSI4, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
355 {ETSI5_WORLD, ETSI5, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
356 {ETSI6_WORLD, ETSI6, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
358 {ETSI3_ETSIA, ETSI3, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
359 {FRANCE_RES, ETSI3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
361 {FCC1_WORLD, FCC1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
362 {FCC1_FCCA, FCC1, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
363 {APL1_WORLD, APL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
364 {APL2_WORLD, APL2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
365 {APL3_WORLD, APL3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
366 {APL4_WORLD, APL4, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
367 {APL5_WORLD, APL5, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
368 {APL6_WORLD, APL6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
369 {APL8_WORLD, APL8, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
370 {APL9_WORLD, APL9, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
372 {APL3_FCCA, APL3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
373 {APL1_ETSIC, APL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
374 {APL2_ETSIC, APL2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
375 {APL2_APLD, APL2, APLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
377 {MKK1_MKKA, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA, CTRY_JAPAN },
378 {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 },
379 {MKK1_FCCA, MKK1, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN2 },
380 {MKK1_MKKA1, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN4 },
381 {MKK1_MKKA2, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN5 },
382 {MKK1_MKKC, MKK1, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN6 },
385 {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 },
388 {MKK3_MKKA, MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC , PSCAN_MKKA, CTRY_DEFAULT },
389 {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 },
390 {MKK3_MKKA1, MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_DEFAULT },
391 {MKK3_MKKA2,MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN8 },
392 {MKK3_MKKC, MKK3, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, CTRY_JAPAN9 },
393 {MKK3_FCCA, MKK3, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, CTRY_DEFAULT },
396 {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 },
397 {MKK4_MKKA1, MKK4, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_DEFAULT },
398 {MKK4_MKKA2, MKK4, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 |PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11 },
399 {MKK4_MKKC, MKK4, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN12 },
400 {MKK4_FCCA, MKK4, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_DEFAULT },
403 {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 },
404 {MKK5_MKKA2,MKK5, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN14 },
405 {MKK5_MKKC, MKK5, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN15 },
408 {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 },
409 {MKK6_MKKA2, MKK6, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN17 },
410 {MKK6_MKKC, MKK6, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN18 },
413 {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 },
414 {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 },
415 {MKK7_MKKC, MKK7, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN21 },
418 {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 },
419 {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 },
420 {MKK8_MKKC, MKK8, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 , CTRY_JAPAN24 },
422 {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 },
423 {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 },
425 /* These are super domains */
426 {WOR0_WORLD, WOR0_WORLD, WOR0_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
427 {WOR1_WORLD, WOR1_WORLD, WOR1_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
428 {WOR2_WORLD, WOR2_WORLD, WOR2_WORLD, DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
429 {WOR3_WORLD, WOR3_WORLD, WOR3_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
430 {WOR4_WORLD, WOR4_WORLD, WOR4_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
431 {WOR5_ETSIC, WOR5_ETSIC, WOR5_ETSIC, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
432 {WOR01_WORLD, WOR01_WORLD, WOR01_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
433 {WOR02_WORLD, WOR02_WORLD, WOR02_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
434 {EU1_WORLD, EU1_WORLD, EU1_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
435 {WOR9_WORLD, WOR9_WORLD, WOR9_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
436 {WORA_WORLD, WORA_WORLD, WORA_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
437 {WORB_WORLD, WORB_WORLD, WORB_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, CTRY_DEFAULT },
441 * The following tables are the master list for all different freqeuncy
442 * bands with the complete matrix of all possible flags and settings
443 * for each band if it is used in ANY reg domain.
446 #define DEF_REGDMN FCC1_FCCA
447 #define COUNTRY_ERD_FLAG 0x8000
448 #define WORLDWIDE_ROAMING_FLAG 0x4000
451 HAL_CTRY_CODE countryCode;
452 HAL_REG_DOMAIN regDmnEnum;
453 } COUNTRY_CODE_TO_ENUM_RD;
455 static COUNTRY_CODE_TO_ENUM_RD allCountries[] = {
456 { CTRY_DEBUG, NO_ENUMRD },
457 { CTRY_DEFAULT, DEF_REGDMN },
458 { CTRY_ALBANIA, NULL1_WORLD },
459 { CTRY_ALGERIA, NULL1_WORLD },
460 { CTRY_ARGENTINA, APL3_WORLD },
461 { CTRY_ARMENIA, ETSI4_WORLD },
462 { CTRY_AUSTRALIA, FCC2_WORLD },
463 { CTRY_AUSTRIA, ETSI1_WORLD },
464 { CTRY_AZERBAIJAN, ETSI4_WORLD },
465 { CTRY_BAHRAIN, APL6_WORLD },
466 { CTRY_BELARUS, NULL1_WORLD },
467 { CTRY_BELGIUM, ETSI1_WORLD },
468 { CTRY_BELIZE, APL1_ETSIC },
469 { CTRY_BOLIVIA, APL1_ETSIC },
470 { CTRY_BRAZIL, FCC3_WORLD },
471 { CTRY_BRUNEI_DARUSSALAM,APL1_WORLD },
472 { CTRY_BULGARIA, ETSI6_WORLD },
473 { CTRY_CANADA, FCC2_FCCA },
474 { CTRY_CHILE, APL6_WORLD },
475 { CTRY_CHINA, APL1_WORLD },
476 { CTRY_COLOMBIA, FCC1_FCCA },
477 { CTRY_COSTA_RICA, NULL1_WORLD },
478 { CTRY_CROATIA, ETSI3_WORLD },
479 { CTRY_CYPRUS, ETSI1_WORLD },
480 { CTRY_CZECH, ETSI1_WORLD },
481 { CTRY_DENMARK, ETSI1_WORLD },
482 { CTRY_DOMINICAN_REPUBLIC,FCC1_FCCA },
483 { CTRY_ECUADOR, NULL1_WORLD },
484 { CTRY_EGYPT, ETSI3_WORLD },
485 { CTRY_EL_SALVADOR, NULL1_WORLD },
486 { CTRY_ESTONIA, ETSI1_WORLD },
487 { CTRY_FINLAND, ETSI1_WORLD },
488 { CTRY_FRANCE, ETSI1_WORLD },
489 { CTRY_FRANCE2, ETSI3_WORLD },
490 { CTRY_GEORGIA, ETSI4_WORLD },
491 { CTRY_GERMANY, ETSI1_WORLD },
492 { CTRY_GREECE, ETSI1_WORLD },
493 { CTRY_GUATEMALA, FCC1_FCCA },
494 { CTRY_HONDURAS, NULL1_WORLD },
495 { CTRY_HONG_KONG, FCC2_WORLD },
496 { CTRY_HUNGARY, ETSI1_WORLD },
497 { CTRY_ICELAND, ETSI1_WORLD },
498 { CTRY_INDIA, APL6_WORLD },
499 { CTRY_INDONESIA, APL1_WORLD },
500 { CTRY_IRAN, APL1_WORLD },
501 { CTRY_IRELAND, ETSI1_WORLD },
502 { CTRY_ISRAEL, NULL1_WORLD },
503 { CTRY_ITALY, ETSI1_WORLD },
504 { CTRY_JAPAN, MKK1_MKKA },
505 { CTRY_JAPAN1, MKK1_MKKB },
506 { CTRY_JAPAN2, MKK1_FCCA },
507 { CTRY_JAPAN3, MKK2_MKKA },
508 { CTRY_JAPAN4, MKK1_MKKA1 },
509 { CTRY_JAPAN5, MKK1_MKKA2 },
510 { CTRY_JAPAN6, MKK1_MKKC },
512 { CTRY_JAPAN7, MKK3_MKKB },
513 { CTRY_JAPAN8, MKK3_MKKA2 },
514 { CTRY_JAPAN9, MKK3_MKKC },
516 { CTRY_JAPAN10, MKK4_MKKB },
517 { CTRY_JAPAN11, MKK4_MKKA2 },
518 { CTRY_JAPAN12, MKK4_MKKC },
520 { CTRY_JAPAN13, MKK5_MKKB },
521 { CTRY_JAPAN14, MKK5_MKKA2 },
522 { CTRY_JAPAN15, MKK5_MKKC },
524 { CTRY_JAPAN16, MKK6_MKKB },
525 { CTRY_JAPAN17, MKK6_MKKA2 },
526 { CTRY_JAPAN18, MKK6_MKKC },
528 { CTRY_JAPAN19, MKK7_MKKB },
529 { CTRY_JAPAN20, MKK7_MKKA2 },
530 { CTRY_JAPAN21, MKK7_MKKC },
532 { CTRY_JAPAN22, MKK8_MKKB },
533 { CTRY_JAPAN23, MKK8_MKKA2 },
534 { CTRY_JAPAN24, MKK8_MKKC },
536 { CTRY_JORDAN, APL4_WORLD },
537 { CTRY_KAZAKHSTAN, NULL1_WORLD },
538 { CTRY_KOREA_NORTH, APL2_WORLD },
539 { CTRY_KOREA_ROC, APL2_WORLD },
540 { CTRY_KOREA_ROC2, APL2_WORLD },
541 { CTRY_KOREA_ROC3, APL9_WORLD },
542 { CTRY_KUWAIT, NULL1_WORLD },
543 { CTRY_LATVIA, ETSI1_WORLD },
544 { CTRY_LEBANON, NULL1_WORLD },
545 { CTRY_LIECHTENSTEIN,ETSI1_WORLD },
546 { CTRY_LITHUANIA, ETSI1_WORLD },
547 { CTRY_LUXEMBOURG, ETSI1_WORLD },
548 { CTRY_MACAU, FCC2_WORLD },
549 { CTRY_MACEDONIA, NULL1_WORLD },
550 { CTRY_MALAYSIA, APL8_WORLD },
551 { CTRY_MALTA, ETSI1_WORLD },
552 { CTRY_MEXICO, FCC1_FCCA },
553 { CTRY_MONACO, ETSI4_WORLD },
554 { CTRY_MOROCCO, NULL1_WORLD },
555 { CTRY_NETHERLANDS, ETSI1_WORLD },
556 { CTRY_NEW_ZEALAND, FCC2_ETSIC },
557 { CTRY_NORWAY, ETSI1_WORLD },
558 { CTRY_OMAN, APL6_WORLD },
559 { CTRY_PAKISTAN, NULL1_WORLD },
560 { CTRY_PANAMA, FCC1_FCCA },
561 { CTRY_PERU, APL1_WORLD },
562 { CTRY_PHILIPPINES, FCC3_WORLD },
563 { CTRY_POLAND, ETSI1_WORLD },
564 { CTRY_PORTUGAL, ETSI1_WORLD },
565 { CTRY_PUERTO_RICO, FCC1_FCCA },
566 { CTRY_QATAR, NULL1_WORLD },
567 { CTRY_ROMANIA, NULL1_WORLD },
568 { CTRY_RUSSIA, NULL1_WORLD },
569 { CTRY_SAUDI_ARABIA,FCC2_WORLD },
570 { CTRY_SINGAPORE, APL6_WORLD },
571 { CTRY_SLOVAKIA, ETSI1_WORLD },
572 { CTRY_SLOVENIA, ETSI1_WORLD },
573 { CTRY_SOUTH_AFRICA,FCC3_WORLD },
574 { CTRY_SPAIN, ETSI1_WORLD },
575 { CTRY_SWEDEN, ETSI1_WORLD },
576 { CTRY_SWITZERLAND, ETSI1_WORLD },
577 { CTRY_SYRIA, NULL1_WORLD },
578 { CTRY_TAIWAN, APL3_FCCA },
579 { CTRY_THAILAND, FCC3_WORLD },
580 { CTRY_TRINIDAD_Y_TOBAGO,ETSI4_WORLD },
581 { CTRY_TUNISIA, ETSI3_WORLD },
582 { CTRY_TURKEY, ETSI3_WORLD },
583 { CTRY_UKRAINE, NULL1_WORLD },
584 { CTRY_UAE, NULL1_WORLD },
585 { CTRY_UNITED_KINGDOM, ETSI1_WORLD },
586 { CTRY_UNITED_STATES, FCC1_FCCA },
587 { CTRY_UNITED_STATES_FCC49,FCC4_FCCA },
588 { CTRY_URUGUAY, FCC1_WORLD },
589 { CTRY_UZBEKISTAN, FCC3_FCCA },
590 { CTRY_VENEZUELA, APL2_ETSIC },
591 { CTRY_VIET_NAM, NULL1_WORLD },
592 { CTRY_ZIMBABWE, NULL1_WORLD }
595 /* Bit masks for DFS per regdomain */
597 NO_DFS = 0x0000000000000000ULL, /* NB: must be zero */
598 DFS_FCC3 = 0x0000000000000001ULL,
599 DFS_ETSI = 0x0000000000000002ULL,
600 DFS_MKK4 = 0x0000000000000004ULL,
603 #define AFTER(x) ((x)+1)
606 * Frequency band collections are defined using bitmasks. Each bit
607 * in a mask is the index of an entry in one of the following tables.
608 * Bitmasks are BMLEN*64 bits so if a table grows beyond that the bit
609 * vectors must be enlarged or the tables split somehow (e.g. split
610 * 1/2 and 1/4 rate channels into a separate table).
612 * Beware of ordering; the indices are defined relative to the preceding
613 * entry so if things get off there will be confusion. A good way to
614 * check the indices is to collect them in a switch statement in a stub
615 * function so the compiler checks for duplicates.
619 uint16_t lowChannel; /* Low channel center in MHz */
620 uint16_t highChannel; /* High Channel center in MHz */
621 uint8_t powerDfs; /* Max power (dBm) for channel
622 range when using DFS */
623 uint8_t antennaMax; /* Max allowed antenna gain */
624 uint8_t channelBW; /* Bandwidth of the channel */
625 uint8_t channelSep; /* Channel separation within
627 uint64_t useDfs; /* Use DFS in the RegDomain
628 if corresponding bit is set */
629 uint64_t usePassScan; /* Use Passive Scan in the RegDomain
630 if corresponding bit is set */
634 * 5GHz 11A channel tags
636 static REG_DMN_FREQ_BAND regDmn5GhzFreq[] = {
637 { 4915, 4925, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2 },
638 #define F1_4915_4925 0
639 { 4935, 4945, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2 },
640 #define F1_4935_4945 AFTER(F1_4915_4925)
641 { 4920, 4980, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2 },
642 #define F1_4920_4980 AFTER(F1_4935_4945)
643 { 4942, 4987, 27, 6, 5, 5, NO_DFS, PSCAN_FCC },
644 #define F1_4942_4987 AFTER(F1_4920_4980)
645 { 4945, 4985, 30, 6, 10, 5, NO_DFS, PSCAN_FCC },
646 #define F1_4945_4985 AFTER(F1_4942_4987)
647 { 4950, 4980, 33, 6, 20, 5, NO_DFS, PSCAN_FCC },
648 #define F1_4950_4980 AFTER(F1_4945_4985)
649 { 5035, 5040, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2 },
650 #define F1_5035_5040 AFTER(F1_4950_4980)
651 { 5040, 5080, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2 },
652 #define F1_5040_5080 AFTER(F1_5035_5040)
653 { 5055, 5055, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2 },
654 #define F1_5055_5055 AFTER(F1_5040_5080)
656 { 5120, 5240, 5, 6, 20, 20, NO_DFS, NO_PSCAN },
657 #define F1_5120_5240 AFTER(F1_5055_5055)
658 { 5120, 5240, 5, 6, 10, 10, NO_DFS, NO_PSCAN },
659 #define F2_5120_5240 AFTER(F1_5120_5240)
660 { 5120, 5240, 5, 6, 5, 5, NO_DFS, NO_PSCAN },
661 #define F3_5120_5240 AFTER(F2_5120_5240)
663 { 5170, 5230, 23, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2 },
664 #define F1_5170_5230 AFTER(F3_5120_5240)
665 { 5170, 5230, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2 },
666 #define F2_5170_5230 AFTER(F1_5170_5230)
668 { 5180, 5240, 15, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI },
669 #define F1_5180_5240 AFTER(F2_5170_5230)
670 { 5180, 5240, 17, 6, 20, 20, NO_DFS, PSCAN_FCC },
671 #define F2_5180_5240 AFTER(F1_5180_5240)
672 { 5180, 5240, 18, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI },
673 #define F3_5180_5240 AFTER(F2_5180_5240)
674 { 5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI },
675 #define F4_5180_5240 AFTER(F3_5180_5240)
676 { 5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI },
677 #define F5_5180_5240 AFTER(F4_5180_5240)
678 { 5180, 5240, 23, 6, 20, 20, NO_DFS, PSCAN_FCC },
679 #define F6_5180_5240 AFTER(F5_5180_5240)
680 { 5180, 5240, 17, 6, 20, 10, NO_DFS, PSCAN_FCC },
681 #define F7_5180_5240 AFTER(F6_5180_5240)
682 { 5180, 5240, 17, 6, 20, 5, NO_DFS, PSCAN_FCC },
683 #define F8_5180_5240 AFTER(F7_5180_5240)
684 { 5180, 5320, 20, 6, 20, 20, DFS_ETSI, PSCAN_ETSI },
686 #define F1_5180_5320 AFTER(F8_5180_5240)
687 { 5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI },
689 #define F1_5240_5280 AFTER(F1_5180_5320)
690 { 5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI },
692 #define F1_5260_5280 AFTER(F1_5240_5280)
693 { 5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI },
695 #define F1_5260_5320 AFTER(F1_5260_5280)
696 { 5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3 },
697 #define F2_5260_5320 AFTER(F1_5260_5320)
699 { 5260, 5320, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
700 #define F3_5260_5320 AFTER(F2_5260_5320)
701 { 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
702 #define F4_5260_5320 AFTER(F3_5260_5320)
703 { 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
704 #define F5_5260_5320 AFTER(F4_5260_5320)
705 { 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN },
706 #define F6_5260_5320 AFTER(F5_5260_5320)
707 { 5260, 5320, 23, 6, 20, 10, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
708 #define F7_5260_5320 AFTER(F6_5260_5320)
709 { 5260, 5320, 23, 6, 20, 5, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
710 #define F8_5260_5320 AFTER(F7_5260_5320)
712 { 5260, 5700, 5, 6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN },
713 #define F1_5260_5700 AFTER(F8_5260_5320)
714 { 5260, 5700, 5, 6, 10, 10, DFS_FCC3 | DFS_ETSI, NO_PSCAN },
715 #define F2_5260_5700 AFTER(F1_5260_5700)
716 { 5260, 5700, 5, 6, 5, 5, DFS_FCC3 | DFS_ETSI, NO_PSCAN },
717 #define F3_5260_5700 AFTER(F2_5260_5700)
719 { 5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
720 #define F1_5280_5320 AFTER(F3_5260_5700)
722 { 5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI },
723 #define F1_5500_5620 AFTER(F1_5280_5320)
725 { 5500, 5700, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC },
726 #define F1_5500_5700 AFTER(F1_5500_5620)
727 { 5500, 5700, 27, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI },
728 #define F2_5500_5700 AFTER(F1_5500_5700)
729 { 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI },
730 #define F3_5500_5700 AFTER(F2_5500_5700)
731 { 5500, 5700, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_MKK3 | PSCAN_FCC },
732 #define F4_5500_5700 AFTER(F3_5500_5700)
734 { 5745, 5805, 23, 0, 20, 20, NO_DFS, NO_PSCAN },
735 #define F1_5745_5805 AFTER(F4_5500_5700)
736 { 5745, 5805, 30, 6, 20, 20, NO_DFS, NO_PSCAN },
737 #define F2_5745_5805 AFTER(F1_5745_5805)
738 { 5745, 5805, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI },
739 #define F3_5745_5805 AFTER(F2_5745_5805)
740 { 5745, 5825, 5, 6, 20, 20, NO_DFS, NO_PSCAN },
741 #define F1_5745_5825 AFTER(F3_5745_5805)
742 { 5745, 5825, 17, 0, 20, 20, NO_DFS, NO_PSCAN },
743 #define F2_5745_5825 AFTER(F1_5745_5825)
744 { 5745, 5825, 20, 0, 20, 20, NO_DFS, NO_PSCAN },
745 #define F3_5745_5825 AFTER(F2_5745_5825)
746 { 5745, 5825, 30, 0, 20, 20, NO_DFS, NO_PSCAN },
747 #define F4_5745_5825 AFTER(F3_5745_5825)
748 { 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN },
749 #define F5_5745_5825 AFTER(F4_5745_5825)
750 { 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN },
751 #define F6_5745_5825 AFTER(F5_5745_5825)
752 { 5745, 5825, 5, 6, 10, 10, NO_DFS, NO_PSCAN },
753 #define F7_5745_5825 AFTER(F6_5745_5825)
754 { 5745, 5825, 5, 6, 5, 5, NO_DFS, NO_PSCAN },
755 #define F8_5745_5825 AFTER(F7_5745_5825)
756 { 5745, 5825, 30, 6, 20, 10, NO_DFS, NO_PSCAN },
757 #define F9_5745_5825 AFTER(F8_5745_5825)
758 { 5745, 5825, 30, 6, 20, 5, NO_DFS, NO_PSCAN },
759 #define F10_5745_5825 AFTER(F9_5745_5825)
762 * Below are the world roaming channels
763 * All WWR domains have no power limit, instead use the card's CTL
764 * or max power settings.
766 { 4920, 4980, 30, 0, 20, 20, NO_DFS, PSCAN_WWR },
767 #define W1_4920_4980 AFTER(F10_5745_5825)
768 { 5040, 5080, 30, 0, 20, 20, NO_DFS, PSCAN_WWR },
769 #define W1_5040_5080 AFTER(W1_4920_4980)
770 { 5170, 5230, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
771 #define W1_5170_5230 AFTER(W1_5040_5080)
772 { 5180, 5240, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
773 #define W1_5180_5240 AFTER(W1_5170_5230)
774 { 5260, 5320, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
775 #define W1_5260_5320 AFTER(W1_5180_5240)
776 { 5745, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR },
777 #define W1_5745_5825 AFTER(W1_5260_5320)
778 { 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
779 #define W1_5500_5700 AFTER(W1_5745_5825)
780 { 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN },
781 #define W2_5260_5320 AFTER(W1_5500_5700)
782 { 5180, 5240, 30, 0, 20, 20, NO_DFS, NO_PSCAN },
783 #define W2_5180_5240 AFTER(W2_5260_5320)
784 { 5825, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR },
785 #define W2_5825_5825 AFTER(W2_5180_5240)
789 * 5GHz Turbo (dynamic & static) tags
791 static REG_DMN_FREQ_BAND regDmn5GhzTurboFreq[] = {
792 { 5130, 5210, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
793 #define T1_5130_5210 0
794 { 5250, 5330, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN },
795 #define T1_5250_5330 AFTER(T1_5130_5210)
796 { 5370, 5490, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
797 #define T1_5370_5490 AFTER(T1_5250_5330)
798 { 5530, 5650, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN },
799 #define T1_5530_5650 AFTER(T1_5370_5490)
801 { 5150, 5190, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
802 #define T1_5150_5190 AFTER(T1_5530_5650)
803 { 5230, 5310, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN },
804 #define T1_5230_5310 AFTER(T1_5150_5190)
805 { 5350, 5470, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
806 #define T1_5350_5470 AFTER(T1_5230_5310)
807 { 5510, 5670, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN },
808 #define T1_5510_5670 AFTER(T1_5350_5470)
810 { 5200, 5240, 17, 6, 40, 40, NO_DFS, NO_PSCAN },
811 #define T1_5200_5240 AFTER(T1_5510_5670)
812 { 5200, 5240, 23, 6, 40, 40, NO_DFS, NO_PSCAN },
813 #define T2_5200_5240 AFTER(T1_5200_5240)
814 { 5210, 5210, 17, 6, 40, 40, NO_DFS, NO_PSCAN },
815 #define T1_5210_5210 AFTER(T2_5200_5240)
816 { 5210, 5210, 23, 0, 40, 40, NO_DFS, NO_PSCAN },
817 #define T2_5210_5210 AFTER(T1_5210_5210)
819 { 5280, 5280, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T },
820 #define T1_5280_5280 AFTER(T2_5210_5210)
821 { 5280, 5280, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T },
822 #define T2_5280_5280 AFTER(T1_5280_5280)
823 { 5250, 5250, 17, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T },
824 #define T1_5250_5250 AFTER(T2_5280_5280)
825 { 5290, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T },
826 #define T1_5290_5290 AFTER(T1_5250_5250)
827 { 5250, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T },
828 #define T1_5250_5290 AFTER(T1_5290_5290)
829 { 5250, 5290, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T },
830 #define T2_5250_5290 AFTER(T1_5250_5290)
832 { 5540, 5660, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T },
833 #define T1_5540_5660 AFTER(T2_5250_5290)
834 { 5760, 5800, 20, 0, 40, 40, NO_DFS, NO_PSCAN },
835 #define T1_5760_5800 AFTER(T1_5540_5660)
836 { 5760, 5800, 30, 6, 40, 40, NO_DFS, NO_PSCAN },
837 #define T2_5760_5800 AFTER(T1_5760_5800)
839 { 5765, 5805, 30, 6, 40, 40, NO_DFS, NO_PSCAN },
840 #define T1_5765_5805 AFTER(T2_5760_5800)
843 * Below are the WWR frequencies
845 { 5210, 5250, 15, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
846 #define WT1_5210_5250 AFTER(T1_5765_5805)
847 { 5290, 5290, 18, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
848 #define WT1_5290_5290 AFTER(WT1_5210_5250)
849 { 5540, 5660, 20, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR },
850 #define WT1_5540_5660 AFTER(WT1_5290_5290)
851 { 5760, 5800, 20, 0, 40, 40, NO_DFS, PSCAN_WWR },
852 #define WT1_5760_5800 AFTER(WT1_5540_5660)
856 * 2GHz 11b channel tags
858 static REG_DMN_FREQ_BAND regDmn2GhzFreq[] = {
859 { 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
860 #define F1_2312_2372 0
861 { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
862 #define F2_2312_2372 AFTER(F1_2312_2372)
864 { 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
865 #define F1_2412_2472 AFTER(F2_2312_2372)
866 { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA },
867 #define F2_2412_2472 AFTER(F1_2412_2472)
868 { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN },
869 #define F3_2412_2472 AFTER(F2_2412_2472)
871 { 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN },
872 #define F1_2412_2462 AFTER(F3_2412_2472)
873 { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA },
874 #define F2_2412_2462 AFTER(F1_2412_2462)
876 { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
877 #define F1_2432_2442 AFTER(F2_2412_2462)
879 { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
880 #define F1_2457_2472 AFTER(F1_2432_2442)
882 { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA },
883 #define F1_2467_2472 AFTER(F1_2457_2472)
885 { 2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
886 #define F1_2484_2484 AFTER(F1_2467_2472)
887 { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2 },
888 #define F2_2484_2484 AFTER(F1_2484_2484)
890 { 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
891 #define F1_2512_2732 AFTER(F2_2484_2484)
894 * WWR have powers opened up to 20dBm.
895 * Limits should often come from CTL/Max powers
897 { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
898 #define W1_2312_2372 AFTER(F1_2512_2732)
899 { 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
900 #define W1_2412_2412 AFTER(W1_2312_2372)
901 { 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
902 #define W1_2417_2432 AFTER(W1_2412_2412)
903 { 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
904 #define W1_2437_2442 AFTER(W1_2417_2432)
905 { 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
906 #define W1_2447_2457 AFTER(W1_2437_2442)
907 { 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
908 #define W1_2462_2462 AFTER(W1_2447_2457)
909 { 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN },
910 #define W1_2467_2467 AFTER(W1_2462_2462)
911 { 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN },
912 #define W2_2467_2467 AFTER(W1_2467_2467)
913 { 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN },
914 #define W1_2472_2472 AFTER(W2_2467_2467)
915 { 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN },
916 #define W2_2472_2472 AFTER(W1_2472_2472)
917 { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN },
918 #define W1_2484_2484 AFTER(W2_2472_2472)
919 { 2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN },
920 #define W2_2484_2484 AFTER(W1_2484_2484)
924 * 2GHz 11g channel tags
926 static REG_DMN_FREQ_BAND regDmn2Ghz11gFreq[] = {
927 { 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
928 #define G1_2312_2372 0
929 { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
930 #define G2_2312_2372 AFTER(G1_2312_2372)
931 { 2312, 2372, 5, 6, 10, 5, NO_DFS, NO_PSCAN },
932 #define G3_2312_2372 AFTER(G2_2312_2372)
933 { 2312, 2372, 5, 6, 5, 5, NO_DFS, NO_PSCAN },
934 #define G4_2312_2372 AFTER(G3_2312_2372)
936 { 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
937 #define G1_2412_2472 AFTER(G4_2312_2372)
938 { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G },
939 #define G2_2412_2472 AFTER(G1_2412_2472)
940 { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN },
941 #define G3_2412_2472 AFTER(G2_2412_2472)
942 { 2412, 2472, 5, 6, 10, 5, NO_DFS, NO_PSCAN },
943 #define G4_2412_2472 AFTER(G3_2412_2472)
944 { 2412, 2472, 5, 6, 5, 5, NO_DFS, NO_PSCAN },
945 #define G5_2412_2472 AFTER(G4_2412_2472)
947 { 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN },
948 #define G1_2412_2462 AFTER(G5_2412_2472)
949 { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G },
950 #define G2_2412_2462 AFTER(G1_2412_2462)
951 { 2412, 2462, 27, 6, 10, 5, NO_DFS, NO_PSCAN },
952 #define G3_2412_2462 AFTER(G2_2412_2462)
953 { 2412, 2462, 27, 6, 5, 5, NO_DFS, NO_PSCAN },
954 #define G4_2412_2462 AFTER(G3_2412_2462)
956 { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
957 #define G1_2432_2442 AFTER(G4_2412_2462)
959 { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
960 #define G1_2457_2472 AFTER(G1_2432_2442)
962 { 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN },
963 #define G1_2512_2732 AFTER(G1_2457_2472)
964 { 2512, 2732, 5, 6, 10, 5, NO_DFS, NO_PSCAN },
965 #define G2_2512_2732 AFTER(G1_2512_2732)
966 { 2512, 2732, 5, 6, 5, 5, NO_DFS, NO_PSCAN },
967 #define G3_2512_2732 AFTER(G2_2512_2732)
969 { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA },
970 #define G1_2467_2472 AFTER(G3_2512_2732)
973 * WWR open up the power to 20dBm
975 { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
976 #define WG1_2312_2372 AFTER(G1_2467_2472)
977 { 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
978 #define WG1_2412_2412 AFTER(WG1_2312_2372)
979 { 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
980 #define WG1_2417_2432 AFTER(WG1_2412_2412)
981 { 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
982 #define WG1_2437_2442 AFTER(WG1_2417_2432)
983 { 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
984 #define WG1_2447_2457 AFTER(WG1_2437_2442)
985 { 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN },
986 #define WG1_2462_2462 AFTER(WG1_2447_2457)
987 { 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN },
988 #define WG1_2467_2467 AFTER(WG1_2462_2462)
989 { 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN },
990 #define WG2_2467_2467 AFTER(WG1_2467_2467)
991 { 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN },
992 #define WG1_2472_2472 AFTER(WG2_2467_2467)
993 { 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN },
994 #define WG2_2472_2472 AFTER(WG1_2472_2472)
998 * 2GHz Dynamic turbo tags
1000 static REG_DMN_FREQ_BAND regDmn2Ghz11gTurboFreq[] = {
1001 { 2312, 2372, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
1002 #define T1_2312_2372 0
1003 { 2437, 2437, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
1004 #define T1_2437_2437 AFTER(T1_2312_2372)
1005 { 2437, 2437, 20, 6, 40, 40, NO_DFS, NO_PSCAN },
1006 #define T2_2437_2437 AFTER(T1_2437_2437)
1007 { 2437, 2437, 18, 6, 40, 40, NO_DFS, PSCAN_WWR },
1008 #define T3_2437_2437 AFTER(T2_2437_2437)
1009 { 2512, 2732, 5, 6, 40, 40, NO_DFS, NO_PSCAN },
1010 #define T1_2512_2732 AFTER(T3_2437_2437)
1013 typedef struct regDomain {
1014 uint16_t regDmnEnum; /* value from EnumRd table */
1015 uint8_t conformanceTestLimit;
1016 uint32_t flags; /* Requirement flags (AdHoc disallow,
1017 noise floor cal needed, etc) */
1018 uint64_t dfsMask; /* DFS bitmask for 5Ghz tables */
1019 uint64_t pscan; /* Bitmask for passive scan */
1020 chanbmask_t chan11a; /* 11a channels */
1021 chanbmask_t chan11a_turbo; /* 11a static turbo channels */
1022 chanbmask_t chan11a_dyn_turbo; /* 11a dynamic turbo channels */
1023 chanbmask_t chan11a_half; /* 11a 1/2 width channels */
1024 chanbmask_t chan11a_quarter; /* 11a 1/4 width channels */
1025 chanbmask_t chan11b; /* 11b channels */
1026 chanbmask_t chan11g; /* 11g channels */
1027 chanbmask_t chan11g_turbo; /* 11g dynamic turbo channels */
1028 chanbmask_t chan11g_half; /* 11g 1/2 width channels */
1029 chanbmask_t chan11g_quarter; /* 11g 1/4 width channels */
1032 static REG_DOMAIN regDomains[] = {
1034 {.regDmnEnum = DEBUG_REG_DMN,
1035 .conformanceTestLimit = FCC,
1036 .dfsMask = DFS_FCC3,
1037 .chan11a = BM4(F1_4950_4980,
1041 .chan11a_half = BM4(F1_4945_4985,
1045 .chan11a_quarter = BM4(F1_4942_4987,
1049 .chan11a_turbo = BM8(T1_5130_5210,
1057 .chan11a_dyn_turbo = BM4(T1_5200_5240,
1061 .chan11b = BM4(F1_2312_2372,
1065 .chan11g = BM3(G1_2312_2372, G1_2412_2472, G1_2512_2732),
1066 .chan11g_turbo = BM3(T1_2312_2372, T1_2437_2437, T1_2512_2732),
1067 .chan11g_half = BM3(G2_2312_2372, G4_2412_2472, G2_2512_2732),
1068 .chan11g_quarter = BM3(G3_2312_2372, G5_2412_2472, G3_2512_2732),
1071 {.regDmnEnum = APL1,
1072 .conformanceTestLimit = FCC,
1073 .chan11a = BM1(F4_5745_5825),
1076 {.regDmnEnum = APL2,
1077 .conformanceTestLimit = FCC,
1078 .chan11a = BM1(F1_5745_5805),
1081 {.regDmnEnum = APL3,
1082 .conformanceTestLimit = FCC,
1083 .chan11a = BM2(F1_5280_5320, F2_5745_5805),
1086 {.regDmnEnum = APL4,
1087 .conformanceTestLimit = FCC,
1088 .chan11a = BM2(F4_5180_5240, F3_5745_5825),
1091 {.regDmnEnum = APL5,
1092 .conformanceTestLimit = FCC,
1093 .chan11a = BM1(F2_5745_5825),
1096 {.regDmnEnum = APL6,
1097 .conformanceTestLimit = ETSI,
1098 .dfsMask = DFS_ETSI,
1099 .pscan = PSCAN_FCC_T | PSCAN_FCC,
1100 .chan11a = BM3(F4_5180_5240, F2_5260_5320, F3_5745_5825),
1101 .chan11a_turbo = BM3(T2_5210_5210, T1_5250_5290, T1_5760_5800),
1104 {.regDmnEnum = APL8,
1105 .conformanceTestLimit = ETSI,
1106 .flags = DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB,
1107 .chan11a = BM2(F6_5260_5320, F4_5745_5825),
1110 {.regDmnEnum = APL9,
1111 .conformanceTestLimit = ETSI,
1112 .dfsMask = DFS_ETSI,
1113 .pscan = PSCAN_ETSI,
1114 .flags = DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB,
1115 .chan11a = BM3(F1_5180_5320, F1_5500_5620, F3_5745_5805),
1118 {.regDmnEnum = ETSI1,
1119 .conformanceTestLimit = ETSI,
1120 .dfsMask = DFS_ETSI,
1121 .pscan = PSCAN_ETSI,
1122 .flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1123 .chan11a = BM3(W2_5180_5240, F2_5260_5320, F2_5500_5700),
1126 {.regDmnEnum = ETSI2,
1127 .conformanceTestLimit = ETSI,
1128 .dfsMask = DFS_ETSI,
1129 .pscan = PSCAN_ETSI,
1130 .flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1131 .chan11a = BM1(F3_5180_5240),
1134 {.regDmnEnum = ETSI3,
1135 .conformanceTestLimit = ETSI,
1136 .dfsMask = DFS_ETSI,
1137 .pscan = PSCAN_ETSI,
1138 .flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1139 .chan11a = BM2(W2_5180_5240, F2_5260_5320),
1142 {.regDmnEnum = ETSI4,
1143 .conformanceTestLimit = ETSI,
1144 .dfsMask = DFS_ETSI,
1145 .pscan = PSCAN_ETSI,
1146 .flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1147 .chan11a = BM2(F3_5180_5240, F1_5260_5320),
1150 {.regDmnEnum = ETSI5,
1151 .conformanceTestLimit = ETSI,
1152 .dfsMask = DFS_ETSI,
1153 .pscan = PSCAN_ETSI,
1154 .flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1155 .chan11a = BM1(F1_5180_5240),
1158 {.regDmnEnum = ETSI6,
1159 .conformanceTestLimit = ETSI,
1160 .dfsMask = DFS_ETSI,
1161 .pscan = PSCAN_ETSI,
1162 .flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1163 .chan11a = BM3(F5_5180_5240, F1_5260_5280, F3_5500_5700),
1166 {.regDmnEnum = FCC1,
1167 .conformanceTestLimit = FCC,
1168 .chan11a = BM3(F2_5180_5240, F4_5260_5320, F5_5745_5825),
1169 .chan11a_turbo = BM3(T1_5210_5210, T2_5250_5290, T2_5760_5800),
1170 .chan11a_dyn_turbo = BM3(T1_5200_5240, T1_5280_5280, T1_5765_5805),
1173 {.regDmnEnum = FCC2,
1174 .conformanceTestLimit = FCC,
1175 .chan11a = BM3(F6_5180_5240, F5_5260_5320, F6_5745_5825),
1176 .chan11a_dyn_turbo = BM3(T2_5200_5240, T1_5280_5280, T1_5765_5805),
1179 {.regDmnEnum = FCC3,
1180 .conformanceTestLimit = FCC,
1181 .dfsMask = DFS_FCC3,
1182 .pscan = PSCAN_FCC | PSCAN_FCC_T,
1183 .chan11a = BM4(F2_5180_5240,
1187 .chan11a_turbo = BM4(T1_5210_5210,
1191 .chan11a_dyn_turbo = BM3(T1_5200_5240, T2_5280_5280, T1_5540_5660),
1194 {.regDmnEnum = FCC4,
1195 .conformanceTestLimit = FCC,
1196 .dfsMask = DFS_FCC3,
1197 .pscan = PSCAN_FCC | PSCAN_FCC_T,
1198 .chan11a = BM1(F1_4950_4980),
1199 .chan11a_half = BM1(F1_4945_4985),
1200 .chan11a_quarter = BM1(F1_4942_4987),
1203 /* FCC1 w/ 1/2 and 1/4 width channels */
1204 {.regDmnEnum = FCC5,
1205 .conformanceTestLimit = FCC,
1206 .chan11a = BM3(F2_5180_5240, F4_5260_5320, F5_5745_5825),
1207 .chan11a_turbo = BM3(T1_5210_5210, T2_5250_5290, T2_5760_5800),
1208 .chan11a_dyn_turbo = BM3(T1_5200_5240, T1_5280_5280, T1_5765_5805),
1209 .chan11a_half = BM3(F7_5180_5240, F7_5260_5320, F9_5745_5825),
1210 .chan11a_quarter = BM3(F8_5180_5240, F8_5260_5320,F10_5745_5825),
1213 {.regDmnEnum = MKK1,
1214 .conformanceTestLimit = MKK,
1215 .pscan = PSCAN_MKK1,
1216 .flags = DISALLOW_ADHOC_11A_TURB,
1217 .chan11a = BM1(F1_5170_5230),
1220 {.regDmnEnum = MKK2,
1221 .conformanceTestLimit = MKK,
1222 .pscan = PSCAN_MKK2,
1223 .flags = DISALLOW_ADHOC_11A_TURB,
1224 .chan11a = BM3(F1_4920_4980, F1_5040_5080, F1_5170_5230),
1225 .chan11a_half = BM4(F1_4915_4925,
1232 {.regDmnEnum = MKK3,
1233 .conformanceTestLimit = MKK,
1234 .pscan = PSCAN_MKK3,
1235 .flags = DISALLOW_ADHOC_11A_TURB,
1236 .chan11a = BM1(F4_5180_5240),
1239 /* UNI-1 even + UNI-2 */
1240 {.regDmnEnum = MKK4,
1241 .conformanceTestLimit = MKK,
1242 .dfsMask = DFS_MKK4,
1243 .pscan = PSCAN_MKK3,
1244 .flags = DISALLOW_ADHOC_11A_TURB,
1245 .chan11a = BM2(F4_5180_5240, F2_5260_5320),
1248 /* UNI-1 even + UNI-2 + mid-band */
1249 {.regDmnEnum = MKK5,
1250 .conformanceTestLimit = MKK,
1251 .dfsMask = DFS_MKK4,
1252 .pscan = PSCAN_MKK3,
1253 .flags = DISALLOW_ADHOC_11A_TURB,
1254 .chan11a = BM3(F4_5180_5240, F2_5260_5320, F4_5500_5700),
1257 /* UNI-1 odd + even */
1258 {.regDmnEnum = MKK6,
1259 .conformanceTestLimit = MKK,
1260 .pscan = PSCAN_MKK1,
1261 .flags = DISALLOW_ADHOC_11A_TURB,
1262 .chan11a = BM2(F2_5170_5230, F4_5180_5240),
1265 /* UNI-1 odd + UNI-1 even + UNI-2 */
1266 {.regDmnEnum = MKK7,
1267 .conformanceTestLimit = MKK,
1268 .dfsMask = DFS_MKK4,
1269 .pscan = PSCAN_MKK1 | PSCAN_MKK3,
1270 .flags = DISALLOW_ADHOC_11A_TURB,
1271 .chan11a = BM3(F1_5170_5230, F4_5180_5240, F2_5260_5320),
1274 /* UNI-1 odd + UNI-1 even + UNI-2 + mid-band */
1275 {.regDmnEnum = MKK8,
1276 .conformanceTestLimit = MKK,
1277 .dfsMask = DFS_MKK4,
1278 .pscan = PSCAN_MKK1 | PSCAN_MKK3,
1279 .flags = DISALLOW_ADHOC_11A_TURB,
1280 .chan11a = BM4(F1_5170_5230,
1286 /* UNI-1 even + 4.9 GHZ */
1287 {.regDmnEnum = MKK9,
1288 .conformanceTestLimit = MKK,
1289 .pscan = PSCAN_MKK3,
1290 .flags = DISALLOW_ADHOC_11A_TURB,
1291 .chan11a = BM7(F1_4915_4925,
1300 /* UNI-1 even + UNI-2 + 4.9 GHZ */
1301 {.regDmnEnum = MKK10,
1302 .conformanceTestLimit = MKK,
1303 .dfsMask = DFS_MKK4,
1304 .pscan = PSCAN_MKK3,
1305 .flags = DISALLOW_ADHOC_11A_TURB,
1306 .chan11a = BM8(F1_4915_4925,
1316 /* Defined here to use when 2G channels are authorised for country K2 */
1317 {.regDmnEnum = APLD,
1318 .conformanceTestLimit = NO_CTL,
1319 .chan11b = BM2(F2_2312_2372,F2_2412_2472),
1320 .chan11g = BM2(G2_2312_2372,G2_2412_2472),
1323 {.regDmnEnum = ETSIA,
1324 .conformanceTestLimit = NO_CTL,
1325 .pscan = PSCAN_ETSIA,
1326 .flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1327 .chan11b = BM1(F1_2457_2472),
1328 .chan11g = BM1(G1_2457_2472),
1329 .chan11g_turbo = BM1(T2_2437_2437)
1332 {.regDmnEnum = ETSIB,
1333 .conformanceTestLimit = ETSI,
1334 .pscan = PSCAN_ETSIB,
1335 .flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1336 .chan11b = BM1(F1_2432_2442),
1337 .chan11g = BM1(G1_2432_2442),
1338 .chan11g_turbo = BM1(T2_2437_2437)
1341 {.regDmnEnum = ETSIC,
1342 .conformanceTestLimit = ETSI,
1343 .pscan = PSCAN_ETSIC,
1344 .flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1345 .chan11b = BM1(F3_2412_2472),
1346 .chan11g = BM1(G3_2412_2472),
1347 .chan11g_turbo = BM1(T2_2437_2437)
1350 {.regDmnEnum = FCCA,
1351 .conformanceTestLimit = FCC,
1352 .chan11b = BM1(F1_2412_2462),
1353 .chan11g = BM1(G1_2412_2462),
1354 .chan11g_turbo = BM1(T2_2437_2437),
1357 /* FCCA w/ 1/2 and 1/4 width channels */
1358 {.regDmnEnum = FCCB,
1359 .conformanceTestLimit = FCC,
1360 .chan11b = BM1(F1_2412_2462),
1361 .chan11g = BM1(G1_2412_2462),
1362 .chan11g_turbo = BM1(T2_2437_2437),
1363 .chan11g_half = BM1(G3_2412_2462),
1364 .chan11g_quarter = BM1(G4_2412_2462),
1367 {.regDmnEnum = MKKA,
1368 .conformanceTestLimit = MKK,
1369 .pscan = PSCAN_MKKA | PSCAN_MKKA_G
1370 | PSCAN_MKKA1 | PSCAN_MKKA1_G
1371 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
1372 .flags = DISALLOW_ADHOC_11A_TURB,
1373 .chan11b = BM3(F2_2412_2462, F1_2467_2472, F2_2484_2484),
1374 .chan11g = BM2(G2_2412_2462, G1_2467_2472),
1375 .chan11g_turbo = BM1(T2_2437_2437)
1378 {.regDmnEnum = MKKC,
1379 .conformanceTestLimit = MKK,
1380 .chan11b = BM1(F2_2412_2472),
1381 .chan11g = BM1(G2_2412_2472),
1382 .chan11g_turbo = BM1(T2_2437_2437)
1385 {.regDmnEnum = WORLD,
1386 .conformanceTestLimit = ETSI,
1387 .chan11b = BM1(F2_2412_2472),
1388 .chan11g = BM1(G2_2412_2472),
1389 .chan11g_turbo = BM1(T2_2437_2437)
1392 {.regDmnEnum = WOR0_WORLD,
1393 .conformanceTestLimit = NO_CTL,
1394 .dfsMask = DFS_FCC3 | DFS_ETSI,
1396 .flags = ADHOC_PER_11D,
1397 .chan11a = BM5(W1_5260_5320,
1402 .chan11a_turbo = BM3(WT1_5210_5250,
1405 .chan11b = BM8(W1_2412_2412,
1413 .chan11g = BM7(WG1_2412_2412,
1420 .chan11g_turbo = BM1(T3_2437_2437)
1423 {.regDmnEnum = WOR01_WORLD,
1424 .conformanceTestLimit = NO_CTL,
1425 .dfsMask = DFS_FCC3 | DFS_ETSI,
1427 .flags = ADHOC_PER_11D,
1428 .chan11a = BM5(W1_5260_5320,
1433 .chan11a_turbo = BM3(WT1_5210_5250,
1436 .chan11b = BM5(W1_2412_2412,
1441 .chan11g = BM5(WG1_2412_2412,
1446 .chan11g_turbo = BM1(T3_2437_2437)},
1448 {.regDmnEnum = WOR02_WORLD,
1449 .conformanceTestLimit = NO_CTL,
1450 .dfsMask = DFS_FCC3 | DFS_ETSI,
1452 .flags = ADHOC_PER_11D,
1453 .chan11a = BM5(W1_5260_5320,
1458 .chan11a_turbo = BM3(WT1_5210_5250,
1461 .chan11b = BM7(W1_2412_2412,
1468 .chan11g = BM7(WG1_2412_2412,
1475 .chan11g_turbo = BM1(T3_2437_2437)},
1477 {.regDmnEnum = EU1_WORLD,
1478 .conformanceTestLimit = NO_CTL,
1479 .dfsMask = DFS_FCC3 | DFS_ETSI,
1481 .flags = ADHOC_PER_11D,
1482 .chan11a = BM5(W1_5260_5320,
1487 .chan11a_turbo = BM3(WT1_5210_5250,
1490 .chan11b = BM7(W1_2412_2412,
1497 .chan11g = BM7(WG1_2412_2412,
1504 .chan11g_turbo = BM1(T3_2437_2437)},
1506 {.regDmnEnum = WOR1_WORLD,
1507 .conformanceTestLimit = NO_CTL,
1508 .dfsMask = DFS_FCC3 | DFS_ETSI,
1510 .flags = DISALLOW_ADHOC_11A,
1511 .chan11a = BM5(W1_5260_5320,
1516 .chan11b = BM8(W1_2412_2412,
1524 .chan11g = BM7(WG1_2412_2412,
1531 .chan11g_turbo = BM1(T3_2437_2437)
1534 {.regDmnEnum = WOR2_WORLD,
1535 .conformanceTestLimit = NO_CTL,
1536 .dfsMask = DFS_FCC3 | DFS_ETSI,
1538 .flags = DISALLOW_ADHOC_11A,
1539 .chan11a = BM5(W1_5260_5320,
1544 .chan11a_turbo = BM3(WT1_5210_5250,
1547 .chan11b = BM8(W1_2412_2412,
1555 .chan11g = BM7(WG1_2412_2412,
1562 .chan11g_turbo = BM1(T3_2437_2437)},
1564 {.regDmnEnum = WOR3_WORLD,
1565 .conformanceTestLimit = NO_CTL,
1566 .dfsMask = DFS_FCC3 | DFS_ETSI,
1568 .flags = ADHOC_PER_11D,
1569 .chan11a = BM4(W1_5260_5320,
1573 .chan11a_turbo = BM3(WT1_5210_5250,
1576 .chan11b = BM7(W1_2412_2412,
1583 .chan11g = BM7(WG1_2412_2412,
1590 .chan11g_turbo = BM1(T3_2437_2437)},
1592 {.regDmnEnum = WOR4_WORLD,
1593 .conformanceTestLimit = NO_CTL,
1594 .dfsMask = DFS_FCC3 | DFS_ETSI,
1596 .flags = DISALLOW_ADHOC_11A,
1597 .chan11a = BM4(W2_5260_5320,
1601 .chan11a_turbo = BM3(WT1_5210_5250,
1604 .chan11b = BM5(W1_2412_2412,
1609 .chan11g = BM5(WG1_2412_2412,
1614 .chan11g_turbo = BM1(T3_2437_2437)},
1616 {.regDmnEnum = WOR5_ETSIC,
1617 .conformanceTestLimit = NO_CTL,
1618 .dfsMask = DFS_FCC3 | DFS_ETSI,
1620 .flags = DISALLOW_ADHOC_11A,
1621 .chan11a = BM3(W1_5260_5320, W2_5180_5240, F6_5745_5825),
1622 .chan11b = BM7(W1_2412_2412,
1629 .chan11g = BM7(WG1_2412_2412,
1636 .chan11g_turbo = BM1(T3_2437_2437)},
1638 {.regDmnEnum = WOR9_WORLD,
1639 .conformanceTestLimit = NO_CTL,
1640 .dfsMask = DFS_FCC3 | DFS_ETSI,
1642 .flags = DISALLOW_ADHOC_11A,
1643 .chan11a = BM4(W1_5260_5320,
1647 .chan11a_turbo = BM3(WT1_5210_5250,
1650 .chan11b = BM5(W1_2412_2412,
1655 .chan11g = BM5(WG1_2412_2412,
1660 .chan11g_turbo = BM1(T3_2437_2437)},
1662 {.regDmnEnum = WORA_WORLD,
1663 .conformanceTestLimit = NO_CTL,
1664 .dfsMask = DFS_FCC3 | DFS_ETSI,
1666 .flags = DISALLOW_ADHOC_11A,
1667 .chan11a = BM4(W1_5260_5320,
1671 .chan11b = BM7(W1_2412_2412,
1678 .chan11g = BM7(WG1_2412_2412,
1685 .chan11g_turbo = BM1(T3_2437_2437)},
1687 {.regDmnEnum = WORB_WORLD,
1688 .conformanceTestLimit = NO_CTL,
1689 .dfsMask = DFS_FCC3 | DFS_ETSI,
1691 .flags = DISALLOW_ADHOC_11A,
1692 .chan11a = BM4(W1_5260_5320,
1696 .chan11b = BM7(W1_2412_2412,
1703 .chan11g = BM7(WG1_2412_2412,
1710 .chan11g_turbo = BM1(T3_2437_2437)},
1712 {.regDmnEnum = NULL1,
1713 .conformanceTestLimit = NO_CTL,
1722 static const struct cmode modes[] = {
1723 { HAL_MODE_TURBO, IEEE80211_CHAN_ST },
1724 { HAL_MODE_11A, IEEE80211_CHAN_A },
1725 { HAL_MODE_11B, IEEE80211_CHAN_B },
1726 { HAL_MODE_11G, IEEE80211_CHAN_G },
1727 { HAL_MODE_11G_TURBO, IEEE80211_CHAN_108G },
1728 { HAL_MODE_11A_TURBO, IEEE80211_CHAN_108A },
1729 { HAL_MODE_11A_QUARTER_RATE,
1730 IEEE80211_CHAN_A | IEEE80211_CHAN_QUARTER },
1731 { HAL_MODE_11A_HALF_RATE,
1732 IEEE80211_CHAN_A | IEEE80211_CHAN_HALF },
1733 { HAL_MODE_11G_QUARTER_RATE,
1734 IEEE80211_CHAN_G | IEEE80211_CHAN_QUARTER },
1735 { HAL_MODE_11G_HALF_RATE,
1736 IEEE80211_CHAN_G | IEEE80211_CHAN_HALF },
1737 { HAL_MODE_11NG_HT20, IEEE80211_CHAN_G | IEEE80211_CHAN_HT20 },
1738 { HAL_MODE_11NG_HT40PLUS,
1739 IEEE80211_CHAN_G | IEEE80211_CHAN_HT40U },
1740 { HAL_MODE_11NG_HT40MINUS,
1741 IEEE80211_CHAN_G | IEEE80211_CHAN_HT40D },
1742 { HAL_MODE_11NA_HT20, IEEE80211_CHAN_A | IEEE80211_CHAN_HT20 },
1743 { HAL_MODE_11NA_HT40PLUS,
1744 IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U },
1745 { HAL_MODE_11NA_HT40MINUS,
1746 IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D },
1749 static OS_INLINE uint16_t
1750 getEepromRD(struct ath_hal *ah)
1752 return AH_PRIVATE(ah)->ah_currentRD &~ WORLDWIDE_ROAMING_FLAG;
1756 * Test to see if the bitmask array is all zeros
1759 isChanBitMaskZero(const uint64_t *bitmask)
1762 #error "add more cases"
1765 if (bitmask[1] != 0)
1768 return (bitmask[0] == 0);
1772 * Return whether or not the regulatory domain/country in EEPROM
1776 isEepromValid(struct ath_hal *ah)
1778 uint16_t rd = getEepromRD(ah);
1781 if (rd & COUNTRY_ERD_FLAG) {
1782 uint16_t cc = rd &~ COUNTRY_ERD_FLAG;
1783 for (i = 0; i < N(allCountries); i++)
1784 if (allCountries[i].countryCode == cc)
1787 for (i = 0; i < N(regDomainPairs); i++)
1788 if (regDomainPairs[i].regDmnEnum == rd)
1791 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1792 "%s: invalid regulatory domain/country code 0x%x\n", __func__, rd);
1797 * Find the pointer to the country element in the country table
1798 * corresponding to the country code
1800 static COUNTRY_CODE_TO_ENUM_RD*
1801 findCountry(HAL_CTRY_CODE countryCode)
1805 for (i = 0; i < N(allCountries); i++) {
1806 if (allCountries[i].countryCode == countryCode)
1807 return &allCountries[i];
1813 findRegDmn(int regDmn)
1817 for (i = 0; i < N(regDomains); i++) {
1818 if (regDomains[i].regDmnEnum == regDmn)
1819 return ®Domains[i];
1824 static REG_DMN_PAIR_MAPPING *
1825 findRegDmnPair(int regDmnPair)
1829 if (regDmnPair != NO_ENUMRD) {
1830 for (i = 0; i < N(regDomainPairs); i++) {
1831 if (regDomainPairs[i].regDmnEnum == regDmnPair)
1832 return ®DomainPairs[i];
1839 * Calculate a default country based on the EEPROM setting.
1841 static HAL_CTRY_CODE
1842 getDefaultCountry(struct ath_hal *ah)
1844 REG_DMN_PAIR_MAPPING *regpair;
1847 rd = getEepromRD(ah);
1848 if (rd & COUNTRY_ERD_FLAG) {
1849 COUNTRY_CODE_TO_ENUM_RD *country;
1850 uint16_t cc = rd & ~COUNTRY_ERD_FLAG;
1851 country = findCountry(cc);
1852 if (country != AH_NULL)
1856 * Check reg domains that have only one country
1858 regpair = findRegDmnPair(rd);
1859 return (regpair != AH_NULL) ? regpair->singleCC : CTRY_DEFAULT;
1863 IS_BIT_SET(int bit, const uint64_t bitmask[])
1865 int byteOffset, bitnum;
1868 byteOffset = bit/64;
1869 bitnum = bit - byteOffset*64;
1870 val = ((uint64_t) 1) << bitnum;
1871 return (bitmask[byteOffset] & val) != 0;
1875 getregstate(struct ath_hal *ah, HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn,
1876 COUNTRY_CODE_TO_ENUM_RD **pcountry,
1877 REG_DOMAIN **prd2GHz, REG_DOMAIN **prd5GHz)
1879 COUNTRY_CODE_TO_ENUM_RD *country;
1880 REG_DOMAIN *rd5GHz, *rd2GHz;
1882 if (cc == CTRY_DEFAULT && regDmn == SKU_NONE) {
1884 * Validate the EEPROM setting and setup defaults
1886 if (!isEepromValid(ah)) {
1888 * Don't return any channels if the EEPROM has an
1889 * invalid regulatory domain/country code setting.
1891 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1892 "%s: invalid EEPROM contents\n",__func__);
1893 return HAL_EEBADREG;
1896 cc = getDefaultCountry(ah);
1897 country = findCountry(cc);
1898 if (country == AH_NULL) {
1899 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1900 "NULL Country!, cc %d\n", cc);
1903 regDmn = country->regDmnEnum;
1904 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: EEPROM cc %u rd 0x%x\n",
1905 __func__, cc, regDmn);
1907 if (country->countryCode == CTRY_DEFAULT) {
1909 * Check EEPROM; SKU may be for a country, single
1910 * domain, or multiple domains (WWR).
1912 uint16_t rdnum = getEepromRD(ah);
1913 if ((rdnum & COUNTRY_ERD_FLAG) == 0 &&
1914 (findRegDmn(rdnum) != AH_NULL ||
1915 findRegDmnPair(rdnum) != AH_NULL)) {
1917 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1918 "%s: EEPROM rd 0x%x\n", __func__, rdnum);
1922 country = findCountry(cc);
1923 if (country == AH_NULL) {
1924 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1925 "unknown country, cc %d\n", cc);
1928 if (regDmn == SKU_NONE)
1929 regDmn = country->regDmnEnum;
1930 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: cc %u rd 0x%x\n",
1931 __func__, cc, regDmn);
1935 * Setup per-band state.
1937 if ((regDmn & MULTI_DOMAIN_MASK) == 0) {
1938 REG_DMN_PAIR_MAPPING *regpair = findRegDmnPair(regDmn);
1939 if (regpair == AH_NULL) {
1940 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1941 "%s: no reg domain pair %u for country %u\n",
1942 __func__, regDmn, country->countryCode);
1945 rd5GHz = findRegDmn(regpair->regDmn5GHz);
1946 if (rd5GHz == AH_NULL) {
1947 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1948 "%s: no 5GHz reg domain %u for country %u\n",
1949 __func__, regpair->regDmn5GHz, country->countryCode);
1952 rd2GHz = findRegDmn(regpair->regDmn2GHz);
1953 if (rd2GHz == AH_NULL) {
1954 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1955 "%s: no 2GHz reg domain %u for country %u\n",
1956 __func__, regpair->regDmn2GHz, country->countryCode);
1960 rd5GHz = rd2GHz = findRegDmn(regDmn);
1961 if (rd2GHz == AH_NULL) {
1962 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1963 "%s: no unitary reg domain %u for country %u\n",
1964 __func__, regDmn, country->countryCode);
1968 if (pcountry != AH_NULL)
1969 *pcountry = country;
1976 * Construct the channel list for the specified regulatory config.
1979 getchannels(struct ath_hal *ah,
1980 struct ieee80211_channel chans[], u_int maxchans, int *nchans,
1981 u_int modeSelect, HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn,
1982 HAL_BOOL enableExtendedChannels,
1983 COUNTRY_CODE_TO_ENUM_RD **pcountry,
1984 REG_DOMAIN **prd2GHz, REG_DOMAIN **prd5GHz)
1986 #define CHANNEL_HALF_BW 10
1987 #define CHANNEL_QUARTER_BW 5
1988 #define HAL_MODE_11A_ALL \
1989 (HAL_MODE_11A | HAL_MODE_11A_TURBO | HAL_MODE_TURBO | \
1990 HAL_MODE_11A_QUARTER_RATE | HAL_MODE_11A_HALF_RATE)
1991 REG_DOMAIN *rd5GHz, *rd2GHz;
1993 const struct cmode *cm;
1994 struct ieee80211_channel *ic;
1998 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: cc %u regDmn 0x%x mode 0x%x%s\n",
1999 __func__, cc, regDmn, modeSelect,
2000 enableExtendedChannels ? " ecm" : "");
2002 status = getregstate(ah, cc, regDmn, pcountry, &rd2GHz, &rd5GHz);
2003 if (status != HAL_OK)
2006 /* get modes that HW is capable of */
2007 modesAvail = ath_hal_getWirelessModes(ah);
2008 /* optimize work below if no 11a channels */
2009 if (isChanBitMaskZero(rd5GHz->chan11a) &&
2010 (modesAvail & HAL_MODE_11A_ALL)) {
2011 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2012 "%s: disallow all 11a\n", __func__);
2013 modesAvail &= ~HAL_MODE_11A_ALL;
2018 for (cm = modes; cm < &modes[N(modes)]; cm++) {
2019 uint16_t c, c_hi, c_lo;
2020 uint64_t *channelBM = AH_NULL;
2021 REG_DMN_FREQ_BAND *fband = AH_NULL,*freqs;
2022 int low_adj, hi_adj, channelSep, lastc;
2027 if ((cm->mode & modeSelect) == 0) {
2028 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2029 "%s: skip mode 0x%x flags 0x%x\n",
2030 __func__, cm->mode, cm->flags);
2033 if ((cm->mode & modesAvail) == 0) {
2034 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2035 "%s: !avail mode 0x%x (0x%x) flags 0x%x\n",
2036 __func__, modesAvail, cm->mode, cm->flags);
2039 if (!ath_hal_getChannelEdges(ah, cm->flags, &c_lo, &c_hi)) {
2040 /* channel not supported by hardware, skip it */
2041 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2042 "%s: channels 0x%x not supported by hardware\n",
2043 __func__,cm->flags);
2047 case HAL_MODE_TURBO:
2048 case HAL_MODE_11A_TURBO:
2049 rdflags = rd5GHz->flags;
2050 dfsMask = rd5GHz->dfsMask;
2051 pscan = rd5GHz->pscan;
2052 if (cm->mode == HAL_MODE_TURBO)
2053 channelBM = rd5GHz->chan11a_turbo;
2055 channelBM = rd5GHz->chan11a_dyn_turbo;
2056 freqs = ®Dmn5GhzTurboFreq[0];
2058 case HAL_MODE_11G_TURBO:
2059 rdflags = rd2GHz->flags;
2060 dfsMask = rd2GHz->dfsMask;
2061 pscan = rd2GHz->pscan;
2062 channelBM = rd2GHz->chan11g_turbo;
2063 freqs = ®Dmn2Ghz11gTurboFreq[0];
2066 case HAL_MODE_11A_HALF_RATE:
2067 case HAL_MODE_11A_QUARTER_RATE:
2068 case HAL_MODE_11NA_HT20:
2069 case HAL_MODE_11NA_HT40PLUS:
2070 case HAL_MODE_11NA_HT40MINUS:
2071 rdflags = rd5GHz->flags;
2072 dfsMask = rd5GHz->dfsMask;
2073 pscan = rd5GHz->pscan;
2074 if (cm->mode == HAL_MODE_11A_HALF_RATE)
2075 channelBM = rd5GHz->chan11a_half;
2076 else if (cm->mode == HAL_MODE_11A_QUARTER_RATE)
2077 channelBM = rd5GHz->chan11a_quarter;
2079 channelBM = rd5GHz->chan11a;
2080 freqs = ®Dmn5GhzFreq[0];
2084 case HAL_MODE_11G_HALF_RATE:
2085 case HAL_MODE_11G_QUARTER_RATE:
2086 case HAL_MODE_11NG_HT20:
2087 case HAL_MODE_11NG_HT40PLUS:
2088 case HAL_MODE_11NG_HT40MINUS:
2089 rdflags = rd2GHz->flags;
2090 dfsMask = rd2GHz->dfsMask;
2091 pscan = rd2GHz->pscan;
2092 if (cm->mode == HAL_MODE_11G_HALF_RATE)
2093 channelBM = rd2GHz->chan11g_half;
2094 else if (cm->mode == HAL_MODE_11G_QUARTER_RATE)
2095 channelBM = rd2GHz->chan11g_quarter;
2096 else if (cm->mode == HAL_MODE_11B)
2097 channelBM = rd2GHz->chan11b;
2099 channelBM = rd2GHz->chan11g;
2100 if (cm->mode == HAL_MODE_11B)
2101 freqs = ®Dmn2GhzFreq[0];
2103 freqs = ®Dmn2Ghz11gFreq[0];
2106 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2107 "%s: Unkonwn HAL mode 0x%x\n", __func__, cm->mode);
2110 if (isChanBitMaskZero(channelBM))
2113 * Setup special handling for HT40 channels; e.g.
2114 * 5G HT40 channels require 40Mhz channel separation.
2116 hi_adj = (cm->mode == HAL_MODE_11NA_HT40PLUS ||
2117 cm->mode == HAL_MODE_11NG_HT40PLUS) ? -20 : 0;
2118 low_adj = (cm->mode == HAL_MODE_11NA_HT40MINUS ||
2119 cm->mode == HAL_MODE_11NG_HT40MINUS) ? 20 : 0;
2120 channelSep = (cm->mode == HAL_MODE_11NA_HT40PLUS ||
2121 cm->mode == HAL_MODE_11NA_HT40MINUS) ? 40 : 0;
2123 for (b = 0; b < 64*BMLEN; b++) {
2124 if (!IS_BIT_SET(b, channelBM))
2129 for (c = fband->lowChannel + low_adj;
2130 c <= fband->highChannel + hi_adj;
2131 c += fband->channelSep) {
2132 if (!(c_lo <= c && c <= c_hi)) {
2133 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2134 "%s: c %u out of range [%u..%u]\n",
2135 __func__, c, c_lo, c_hi);
2138 if (next >= maxchans){
2139 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2140 "%s: too many channels for channel table\n",
2144 if ((fband->usePassScan & IS_ECM_CHAN) &&
2145 !enableExtendedChannels) {
2146 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2147 "skip ecm channel\n");
2150 if ((fband->useDfs & dfsMask) &&
2151 (cm->flags & IEEE80211_CHAN_HT40)) {
2152 /* NB: DFS and HT40 don't mix */
2153 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2154 "skip HT40 chan, DFS required\n");
2158 * Make sure that channel separation
2159 * meets the requirement.
2161 if (lastc && channelSep &&
2162 (c-lastc) < channelSep)
2166 OS_MEMZERO(ic, sizeof(*ic));
2168 ic->ic_flags = cm->flags;
2169 ic->ic_maxregpower = fband->powerDfs;
2170 ath_hal_getpowerlimits(ah, ic);
2171 ic->ic_maxantgain = fband->antennaMax;
2172 if (fband->usePassScan & pscan)
2173 ic->ic_flags |= IEEE80211_CHAN_PASSIVE;
2174 if (fband->useDfs & dfsMask)
2175 ic->ic_flags |= IEEE80211_CHAN_DFS;
2176 if (IEEE80211_IS_CHAN_5GHZ(ic) &&
2177 (rdflags & DISALLOW_ADHOC_11A))
2178 ic->ic_flags |= IEEE80211_CHAN_NOADHOC;
2179 if (IEEE80211_IS_CHAN_TURBO(ic) &&
2180 (rdflags & DISALLOW_ADHOC_11A_TURB))
2181 ic->ic_flags |= IEEE80211_CHAN_NOADHOC;
2182 if (rdflags & NO_HOSTAP)
2183 ic->ic_flags |= IEEE80211_CHAN_NOHOSTAP;
2184 if (rdflags & LIMIT_FRAME_4MS)
2185 ic->ic_flags |= IEEE80211_CHAN_4MSXMIT;
2186 if (rdflags & NEED_NFC)
2187 ic->ic_flags |= CHANNEL_NFCREQUIRED;
2195 /* NB: pcountry set above by getregstate */
2196 if (prd2GHz != AH_NULL)
2198 if (prd5GHz != AH_NULL)
2201 #undef HAL_MODE_11A_ALL
2202 #undef CHANNEL_HALF_BW
2203 #undef CHANNEL_QUARTER_BW
2207 * Retrieve a channel list without affecting runtime state.
2210 ath_hal_getchannels(struct ath_hal *ah,
2211 struct ieee80211_channel chans[], u_int maxchans, int *nchans,
2212 u_int modeSelect, HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn,
2213 HAL_BOOL enableExtendedChannels)
2215 return getchannels(ah, chans, maxchans, nchans, modeSelect,
2216 cc, regDmn, enableExtendedChannels, AH_NULL, AH_NULL, AH_NULL);
2220 * Handle frequency mapping from 900Mhz range to 2.4GHz range
2221 * for GSM radios. This is done when we need the h/w frequency
2222 * and the channel is marked IEEE80211_CHAN_GSM.
2225 ath_hal_mapgsm(int sku, int freq)
2229 if (sku == SKU_GZ901)
2233 HALDEBUG(AH_NULL, HAL_DEBUG_ANY,
2234 "%s: cannot map freq %u unknown gsm sku %u\n",
2235 __func__, freq, sku);
2240 * Setup the internal/private channel state given a table of
2241 * net80211 channels. We collapse entries for the same frequency
2242 * and record the frequency for doing noise floor processing
2243 * where we don't have net80211 channel context.
2246 assignPrivateChannels(struct ath_hal *ah,
2247 struct ieee80211_channel chans[], int nchans, int sku)
2249 HAL_CHANNEL_INTERNAL *ic;
2250 int i, j, next, freq;
2253 for (i = 0; i < nchans; i++) {
2254 struct ieee80211_channel *c = &chans[i];
2255 for (j = i-1; j >= 0; j--)
2256 if (chans[j].ic_freq == c->ic_freq) {
2257 c->ic_devdata = chans[j].ic_devdata;
2261 /* new entry, assign a private channel entry */
2262 if (next >= N(AH_PRIVATE(ah)->ah_channels)) {
2263 HALDEBUG(ah, HAL_DEBUG_ANY,
2264 "%s: too many channels, max %zu\n",
2265 __func__, N(AH_PRIVATE(ah)->ah_channels));
2269 * Handle frequency mapping for 900MHz devices.
2270 * The hardware uses 2.4GHz frequencies that are
2271 * down-converted. The 802.11 layer uses the
2274 freq = IEEE80211_IS_CHAN_GSM(c) ?
2275 ath_hal_mapgsm(sku, c->ic_freq) : c->ic_freq;
2277 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2278 "%s: private[%3u] %u/0x%x -> channel %u\n",
2279 __func__, next, c->ic_freq, c->ic_flags, freq);
2281 ic = &AH_PRIVATE(ah)->ah_channels[next];
2283 * NB: This clears privFlags which means ancillary
2284 * code like ANI and IQ calibration will be
2285 * restarted and re-setup any per-channel state.
2287 OS_MEMZERO(ic, sizeof(*ic));
2289 c->ic_devdata = next;
2293 AH_PRIVATE(ah)->ah_nchan = next;
2294 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: %u public, %u private channels\n",
2295 __func__, nchans, next);
2300 * Setup the channel list based on the information in the EEPROM.
2303 ath_hal_init_channels(struct ath_hal *ah,
2304 struct ieee80211_channel chans[], u_int maxchans, int *nchans,
2305 u_int modeSelect, HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn,
2306 HAL_BOOL enableExtendedChannels)
2308 COUNTRY_CODE_TO_ENUM_RD *country;
2309 REG_DOMAIN *rd5GHz, *rd2GHz;
2312 status = getchannels(ah, chans, maxchans, nchans, modeSelect,
2313 cc, regDmn, enableExtendedChannels, &country, &rd2GHz, &rd5GHz);
2314 if (status == HAL_OK &&
2315 assignPrivateChannels(ah, chans, *nchans, AH_PRIVATE(ah)->ah_currentRD)) {
2316 AH_PRIVATE(ah)->ah_rd2GHz = rd2GHz;
2317 AH_PRIVATE(ah)->ah_rd5GHz = rd5GHz;
2319 ah->ah_countryCode = country->countryCode;
2320 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: cc %u\n",
2321 __func__, ah->ah_countryCode);
2323 status = HAL_EINVAL;
2328 * Set the channel list.
2331 ath_hal_set_channels(struct ath_hal *ah,
2332 struct ieee80211_channel chans[], int nchans,
2333 HAL_CTRY_CODE cc, HAL_REG_DOMAIN rd)
2335 COUNTRY_CODE_TO_ENUM_RD *country;
2336 REG_DOMAIN *rd5GHz, *rd2GHz;
2344 * Map 900MHz sku's. The frequencies will be mapped
2345 * according to the sku to compensate for the down-converter.
2346 * We use the FCC for these sku's as the mapped channel
2347 * list is known compatible (will need to change if/when
2348 * vendors do different mapping in different locales).
2350 status = getregstate(ah, CTRY_DEFAULT, SKU_FCC,
2351 &country, &rd2GHz, &rd5GHz);
2354 status = getregstate(ah, cc, rd,
2355 &country, &rd2GHz, &rd5GHz);
2356 rd = AH_PRIVATE(ah)->ah_currentRD;
2359 if (status == HAL_OK && assignPrivateChannels(ah, chans, nchans, rd)) {
2360 AH_PRIVATE(ah)->ah_rd2GHz = rd2GHz;
2361 AH_PRIVATE(ah)->ah_rd5GHz = rd5GHz;
2363 ah->ah_countryCode = country->countryCode;
2364 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: cc %u\n",
2365 __func__, ah->ah_countryCode);
2367 status = HAL_EINVAL;
2373 * Return the internal channel corresponding to a public channel.
2374 * NB: normally this routine is inline'd (see ah_internal.h)
2376 HAL_CHANNEL_INTERNAL *
2377 ath_hal_checkchannel(struct ath_hal *ah, const struct ieee80211_channel *c)
2379 HAL_CHANNEL_INTERNAL *cc = &AH_PRIVATE(ah)->ah_channels[c->ic_devdata];
2381 if (c->ic_devdata < AH_PRIVATE(ah)->ah_nchan &&
2382 (c->ic_freq == cc->channel || IEEE80211_IS_CHAN_GSM(c)))
2384 if (c->ic_devdata >= AH_PRIVATE(ah)->ah_nchan) {
2385 HALDEBUG(ah, HAL_DEBUG_ANY,
2386 "%s: bad mapping, devdata %u nchans %u\n",
2387 __func__, c->ic_devdata, AH_PRIVATE(ah)->ah_nchan);
2388 HALASSERT(c->ic_devdata < AH_PRIVATE(ah)->ah_nchan);
2390 HALDEBUG(ah, HAL_DEBUG_ANY,
2391 "%s: no match for %u/0x%x devdata %u channel %u\n",
2392 __func__, c->ic_freq, c->ic_flags, c->ic_devdata,
2394 HALASSERT(c->ic_freq == cc->channel || IEEE80211_IS_CHAN_GSM(c));
2398 #endif /* AH_DEBUG */
2400 #define isWwrSKU(_ah) \
2401 ((getEepromRD((_ah)) & WORLD_SKU_MASK) == WORLD_SKU_PREFIX || \
2402 getEepromRD(_ah) == WORLD)
2405 * Return the test group for the specific channel based on
2406 * the current regulatory setup.
2409 ath_hal_getctl(struct ath_hal *ah, const struct ieee80211_channel *c)
2413 if (AH_PRIVATE(ah)->ah_rd2GHz == AH_PRIVATE(ah)->ah_rd5GHz ||
2414 (ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)))
2416 else if (IEEE80211_IS_CHAN_2GHZ(c))
2417 ctl = AH_PRIVATE(ah)->ah_rd2GHz->conformanceTestLimit;
2419 ctl = AH_PRIVATE(ah)->ah_rd5GHz->conformanceTestLimit;
2420 if (IEEE80211_IS_CHAN_B(c))
2421 return ctl | CTL_11B;
2422 if (IEEE80211_IS_CHAN_G(c))
2423 return ctl | CTL_11G;
2424 if (IEEE80211_IS_CHAN_108G(c))
2425 return ctl | CTL_108G;
2426 if (IEEE80211_IS_CHAN_TURBO(c))
2427 return ctl | CTL_TURBO;
2428 if (IEEE80211_IS_CHAN_A(c))
2429 return ctl | CTL_11A;
2434 * Return the max allowed antenna gain and apply any regulatory
2435 * domain specific changes.
2437 * NOTE: a negative reduction is possible in RD's that only
2438 * measure radiated power (e.g., ETSI) which would increase
2439 * that actual conducted output power (though never beyond
2440 * the calibrated target power).
2443 ath_hal_getantennareduction(struct ath_hal *ah,
2444 const struct ieee80211_channel *chan, u_int twiceGain)
2446 int8_t antennaMax = twiceGain - chan->ic_maxantgain*2;
2447 return (antennaMax < 0) ? 0 : antennaMax;