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