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