]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/dev/ath/ath_hal/ah_regdomain.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / dev / ath / ath_hal / ah_regdomain.c
1 /*
2  * Copyright (c) 2002-2008 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  * $Id: ah_regdomain.c,v 1.24 2008/11/27 22:29:27 sam Exp $
19  */
20 #include "opt_ah.h"
21
22 #include "ah.h"
23 #include "ah_internal.h"
24 #include "ah_eeprom.h"
25 #include "ah_devid.h"
26
27 /*
28  * XXX this code needs a audit+review
29  */
30
31 /* used throughout this file... */
32 #define N(a)    (sizeof (a) / sizeof (a[0]))
33
34 #define HAL_MODE_11A_TURBO      HAL_MODE_108A
35 #define HAL_MODE_11G_TURBO      HAL_MODE_108G
36
37 /* 10MHz is half the 11A bandwidth used to determine upper edge freq
38    of the outdoor channel */
39 #define HALF_MAXCHANBW          10
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
78 /*
79  * Country/Region Codes
80  * Numbering from ISO 3166
81  */
82 enum {
83     CTRY_ALBANIA              = 8,       /* Albania */
84     CTRY_ALGERIA              = 12,      /* Algeria */
85     CTRY_ARGENTINA            = 32,      /* Argentina */
86     CTRY_ARMENIA              = 51,      /* Armenia */
87     CTRY_AUSTRALIA            = 36,      /* Australia */
88     CTRY_AUSTRIA              = 40,      /* Austria */
89     CTRY_AZERBAIJAN           = 31,      /* Azerbaijan */
90     CTRY_BAHRAIN              = 48,      /* Bahrain */
91     CTRY_BELARUS              = 112,     /* Belarus */
92     CTRY_BELGIUM              = 56,      /* Belgium */
93     CTRY_BELIZE               = 84,      /* Belize */
94     CTRY_BOLIVIA              = 68,      /* Bolivia */
95     CTRY_BRAZIL               = 76,      /* Brazil */
96     CTRY_BRUNEI_DARUSSALAM    = 96,      /* Brunei Darussalam */
97     CTRY_BULGARIA             = 100,     /* Bulgaria */
98     CTRY_CANADA               = 124,     /* Canada */
99     CTRY_CHILE                = 152,     /* Chile */
100     CTRY_CHINA                = 156,     /* People's Republic of China */
101     CTRY_COLOMBIA             = 170,     /* Colombia */
102     CTRY_COSTA_RICA           = 188,     /* Costa Rica */
103     CTRY_CROATIA              = 191,     /* Croatia */
104     CTRY_CYPRUS               = 196,
105     CTRY_CZECH                = 203,     /* Czech Republic */
106     CTRY_DENMARK              = 208,     /* Denmark */
107     CTRY_DOMINICAN_REPUBLIC   = 214,     /* Dominican Republic */
108     CTRY_ECUADOR              = 218,     /* Ecuador */
109     CTRY_EGYPT                = 818,     /* Egypt */
110     CTRY_EL_SALVADOR          = 222,     /* El Salvador */
111     CTRY_ESTONIA              = 233,     /* Estonia */
112     CTRY_FAEROE_ISLANDS       = 234,     /* Faeroe Islands */
113     CTRY_FINLAND              = 246,     /* Finland */
114     CTRY_FRANCE               = 250,     /* France */
115     CTRY_FRANCE2              = 255,     /* France2 */
116     CTRY_GEORGIA              = 268,     /* Georgia */
117     CTRY_GERMANY              = 276,     /* Germany */
118     CTRY_GREECE               = 300,     /* Greece */
119     CTRY_GUATEMALA            = 320,     /* Guatemala */
120     CTRY_HONDURAS             = 340,     /* Honduras */
121     CTRY_HONG_KONG            = 344,     /* Hong Kong S.A.R., P.R.C. */
122     CTRY_HUNGARY              = 348,     /* Hungary */
123     CTRY_ICELAND              = 352,     /* Iceland */
124     CTRY_INDIA                = 356,     /* India */
125     CTRY_INDONESIA            = 360,     /* Indonesia */
126     CTRY_IRAN                 = 364,     /* Iran */
127     CTRY_IRAQ                 = 368,     /* Iraq */
128     CTRY_IRELAND              = 372,     /* Ireland */
129     CTRY_ISRAEL               = 376,     /* Israel */
130     CTRY_ITALY                = 380,     /* Italy */
131     CTRY_JAMAICA              = 388,     /* Jamaica */
132     CTRY_JAPAN                = 392,     /* Japan */
133     CTRY_JAPAN1               = 393,     /* Japan (JP1) */
134     CTRY_JAPAN2               = 394,     /* Japan (JP0) */
135     CTRY_JAPAN3               = 395,     /* Japan (JP1-1) */
136     CTRY_JAPAN4               = 396,     /* Japan (JE1) */
137     CTRY_JAPAN5               = 397,     /* Japan (JE2) */
138     CTRY_JAPAN6               = 399,     /* Japan (JP6) */
139
140     CTRY_JAPAN7               = 4007,    /* Japan (J7) */
141     CTRY_JAPAN8               = 4008,    /* Japan (J8) */
142     CTRY_JAPAN9               = 4009,    /* Japan (J9) */
143
144     CTRY_JAPAN10              = 4010,    /* Japan (J10) */
145     CTRY_JAPAN11              = 4011,    /* Japan (J11) */
146     CTRY_JAPAN12              = 4012,    /* Japan (J12) */
147
148     CTRY_JAPAN13              = 4013,    /* Japan (J13) */
149     CTRY_JAPAN14              = 4014,    /* Japan (J14) */
150     CTRY_JAPAN15              = 4015,    /* Japan (J15) */
151
152     CTRY_JAPAN16              = 4016,    /* Japan (J16) */
153     CTRY_JAPAN17              = 4017,    /* Japan (J17) */
154     CTRY_JAPAN18              = 4018,    /* Japan (J18) */
155
156     CTRY_JAPAN19              = 4019,    /* Japan (J19) */
157     CTRY_JAPAN20              = 4020,    /* Japan (J20) */
158     CTRY_JAPAN21              = 4021,    /* Japan (J21) */
159
160     CTRY_JAPAN22              = 4022,    /* Japan (J22) */
161     CTRY_JAPAN23              = 4023,    /* Japan (J23) */
162     CTRY_JAPAN24              = 4024,    /* Japan (J24) */
163  
164     CTRY_JORDAN               = 400,     /* Jordan */
165     CTRY_KAZAKHSTAN           = 398,     /* Kazakhstan */
166     CTRY_KENYA                = 404,     /* Kenya */
167     CTRY_KOREA_NORTH          = 408,     /* North Korea */
168     CTRY_KOREA_ROC            = 410,     /* South Korea */
169     CTRY_KOREA_ROC2           = 411,     /* South Korea */
170     CTRY_KOREA_ROC3           = 412,     /* South Korea */
171     CTRY_KUWAIT               = 414,     /* Kuwait */
172     CTRY_LATVIA               = 428,     /* Latvia */
173     CTRY_LEBANON              = 422,     /* Lebanon */
174     CTRY_LIBYA                = 434,     /* Libya */
175     CTRY_LIECHTENSTEIN        = 438,     /* Liechtenstein */
176     CTRY_LITHUANIA            = 440,     /* Lithuania */
177     CTRY_LUXEMBOURG           = 442,     /* Luxembourg */
178     CTRY_MACAU                = 446,     /* Macau */
179     CTRY_MACEDONIA            = 807,     /* the Former Yugoslav Republic of Macedonia */
180     CTRY_MALAYSIA             = 458,     /* Malaysia */
181     CTRY_MALTA                = 470,     /* Malta */
182     CTRY_MEXICO               = 484,     /* Mexico */
183     CTRY_MONACO               = 492,     /* Principality of Monaco */
184     CTRY_MOROCCO              = 504,     /* Morocco */
185     CTRY_NETHERLANDS          = 528,     /* Netherlands */
186     CTRY_NEW_ZEALAND          = 554,     /* New Zealand */
187     CTRY_NICARAGUA            = 558,     /* Nicaragua */
188     CTRY_NORWAY               = 578,     /* Norway */
189     CTRY_OMAN                 = 512,     /* Oman */
190     CTRY_PAKISTAN             = 586,     /* Islamic Republic of Pakistan */
191     CTRY_PANAMA               = 591,     /* Panama */
192     CTRY_PARAGUAY             = 600,     /* Paraguay */
193     CTRY_PERU                 = 604,     /* Peru */
194     CTRY_PHILIPPINES          = 608,     /* Republic of the Philippines */
195     CTRY_POLAND               = 616,     /* Poland */
196     CTRY_PORTUGAL             = 620,     /* Portugal */
197     CTRY_PUERTO_RICO          = 630,     /* Puerto Rico */
198     CTRY_QATAR                = 634,     /* Qatar */
199     CTRY_ROMANIA              = 642,     /* Romania */
200     CTRY_RUSSIA               = 643,     /* Russia */
201     CTRY_SAUDI_ARABIA         = 682,     /* Saudi Arabia */
202     CTRY_SINGAPORE            = 702,     /* Singapore */
203     CTRY_SLOVAKIA             = 703,     /* Slovak Republic */
204     CTRY_SLOVENIA             = 705,     /* Slovenia */
205     CTRY_SOUTH_AFRICA         = 710,     /* South Africa */
206     CTRY_SPAIN                = 724,     /* Spain */
207     CTRY_SR9                  = 5000,    /* Ubiquiti SR9 (900MHz/GSM) */
208     CTRY_SWEDEN               = 752,     /* Sweden */
209     CTRY_SWITZERLAND          = 756,     /* Switzerland */
210     CTRY_SYRIA                = 760,     /* Syria */
211     CTRY_TAIWAN               = 158,     /* Taiwan */
212     CTRY_THAILAND             = 764,     /* Thailand */
213     CTRY_TRINIDAD_Y_TOBAGO    = 780,     /* Trinidad y Tobago */
214     CTRY_TUNISIA              = 788,     /* Tunisia */
215     CTRY_TURKEY               = 792,     /* Turkey */
216     CTRY_UAE                  = 784,     /* U.A.E. */
217     CTRY_UKRAINE              = 804,     /* Ukraine */
218     CTRY_UNITED_KINGDOM       = 826,     /* United Kingdom */
219     CTRY_UNITED_STATES        = 840,     /* United States */
220     CTRY_UNITED_STATES_FCC49  = 842,     /* United States (Public Safety)*/
221     CTRY_URUGUAY              = 858,     /* Uruguay */
222     CTRY_UZBEKISTAN           = 860,     /* Uzbekistan */
223     CTRY_VENEZUELA            = 862,     /* Venezuela */
224     CTRY_VIET_NAM             = 704,     /* Viet Nam */
225     CTRY_XR9                  = 5001,    /* Ubiquiti XR9 (900MHz/GSM) */
226     CTRY_GZ901                = 5002,    /* Zcomax GZ-901 (900MHz/GSM) */
227     CTRY_YEMEN                = 887,     /* Yemen */
228     CTRY_ZIMBABWE             = 716      /* Zimbabwe */
229 };
230
231
232 /*
233  * Mask to check whether a domain is a multidomain or a single domain
234  */
235 #define MULTI_DOMAIN_MASK 0xFF00
236
237 /*
238  * Enumerated Regulatory Domain Information 8 bit values indicate that
239  * the regdomain is really a pair of unitary regdomains.  12 bit values
240  * are the real unitary regdomains and are the only ones which have the
241  * frequency bitmasks and flags set.
242  */
243 enum {
244         /*
245          * The following regulatory domain definitions are
246          * found in the EEPROM. Each regulatory domain
247          * can operate in either a 5GHz or 2.4GHz wireless mode or
248          * both 5GHz and 2.4GHz wireless modes.
249          * In general, the value holds no special
250          * meaning and is used to decode into either specific
251          * 2.4GHz or 5GHz wireless mode for that particular
252          * regulatory domain.
253          */
254         NO_ENUMRD       = 0x00,
255         NULL1_WORLD     = 0x03,         /* For 11b-only countries (no 11a allowed) */
256         NULL1_ETSIB     = 0x07,         /* Israel */
257         NULL1_ETSIC     = 0x08,
258         FCC1_FCCA       = 0x10,         /* USA */
259         FCC1_WORLD      = 0x11,         /* Hong Kong */
260         FCC4_FCCA       = 0x12,         /* USA - Public Safety */
261         FCC5_FCCB       = 0x13,         /* USA w/ 1/2 and 1/4 width channels */
262
263         FCC2_FCCA       = 0x20,         /* Canada */
264         FCC2_WORLD      = 0x21,         /* Australia & HK */
265         FCC2_ETSIC      = 0x22,
266         FRANCE_RES      = 0x31,         /* Legacy France for OEM */
267         FCC3_FCCA       = 0x3A,         /* USA & Canada w/5470 band, 11h, DFS enabled */
268         FCC3_WORLD      = 0x3B,         /* USA & Canada w/5470 band, 11h, DFS enabled */
269
270         ETSI1_WORLD     = 0x37,
271         ETSI3_ETSIA     = 0x32,         /* France (optional) */
272         ETSI2_WORLD     = 0x35,         /* Hungary & others */
273         ETSI3_WORLD     = 0x36,         /* France & others */
274         ETSI4_WORLD     = 0x30,
275         ETSI4_ETSIC     = 0x38,
276         ETSI5_WORLD     = 0x39,
277         ETSI6_WORLD     = 0x34,         /* Bulgaria */
278         ETSI_RESERVED   = 0x33,         /* Reserved (Do not used) */
279
280         MKK1_MKKA       = 0x40,         /* Japan (JP1) */
281         MKK1_MKKB       = 0x41,         /* Japan (JP0) */
282         APL4_WORLD      = 0x42,         /* Singapore */
283         MKK2_MKKA       = 0x43,         /* Japan with 4.9G channels */
284         APL_RESERVED    = 0x44,         /* Reserved (Do not used)  */
285         APL2_WORLD      = 0x45,         /* Korea */
286         APL2_APLC       = 0x46,
287         APL3_WORLD      = 0x47,
288         MKK1_FCCA       = 0x48,         /* Japan (JP1-1) */
289         APL2_APLD       = 0x49,         /* Korea with 2.3G channels */
290         MKK1_MKKA1      = 0x4A,         /* Japan (JE1) */
291         MKK1_MKKA2      = 0x4B,         /* Japan (JE2) */
292         MKK1_MKKC       = 0x4C,         /* Japan (MKK1_MKKA,except Ch14) */
293
294         APL3_FCCA       = 0x50,
295         APL1_WORLD      = 0x52,         /* Latin America */
296         APL1_FCCA       = 0x53,
297         APL1_APLA       = 0x54,
298         APL1_ETSIC      = 0x55,
299         APL2_ETSIC      = 0x56,         /* Venezuela */
300         APL5_WORLD      = 0x58,         /* Chile */
301         APL6_WORLD      = 0x5B,         /* Singapore */
302         APL7_FCCA   = 0x5C,     /* Taiwan 5.47 Band */
303         APL8_WORLD  = 0x5D,     /* Malaysia 5GHz */
304         APL9_WORLD  = 0x5E,     /* Korea 5GHz */
305
306         /*
307          * World mode SKUs
308          */
309         WOR0_WORLD      = 0x60,         /* World0 (WO0 SKU) */
310         WOR1_WORLD      = 0x61,         /* World1 (WO1 SKU) */
311         WOR2_WORLD      = 0x62,         /* World2 (WO2 SKU) */
312         WOR3_WORLD      = 0x63,         /* World3 (WO3 SKU) */
313         WOR4_WORLD      = 0x64,         /* World4 (WO4 SKU) */  
314         WOR5_ETSIC      = 0x65,         /* World5 (WO5 SKU) */    
315
316         WOR01_WORLD     = 0x66,         /* World0-1 (WW0-1 SKU) */
317         WOR02_WORLD     = 0x67,         /* World0-2 (WW0-2 SKU) */
318         EU1_WORLD       = 0x68,         /* Same as World0-2 (WW0-2 SKU), except active scan ch1-13. No ch14 */
319
320         WOR9_WORLD      = 0x69,         /* World9 (WO9 SKU) */  
321         WORA_WORLD      = 0x6A,         /* WorldA (WOA SKU) */  
322
323         MKK3_MKKB       = 0x80,         /* Japan UNI-1 even + MKKB */
324         MKK3_MKKA2      = 0x81,         /* Japan UNI-1 even + MKKA2 */
325         MKK3_MKKC       = 0x82,         /* Japan UNI-1 even + MKKC */
326
327         MKK4_MKKB       = 0x83,         /* Japan UNI-1 even + UNI-2 + MKKB */
328         MKK4_MKKA2      = 0x84,         /* Japan UNI-1 even + UNI-2 + MKKA2 */
329         MKK4_MKKC       = 0x85,         /* Japan UNI-1 even + UNI-2 + MKKC */
330
331         MKK5_MKKB       = 0x86,         /* Japan UNI-1 even + UNI-2 + mid-band + MKKB */
332         MKK5_MKKA2      = 0x87,         /* Japan UNI-1 even + UNI-2 + mid-band + MKKA2 */
333         MKK5_MKKC       = 0x88,         /* Japan UNI-1 even + UNI-2 + mid-band + MKKC */
334
335         MKK6_MKKB       = 0x89,         /* Japan UNI-1 even + UNI-1 odd MKKB */
336         MKK6_MKKA2      = 0x8A,         /* Japan UNI-1 even + UNI-1 odd + MKKA2 */
337         MKK6_MKKC       = 0x8B,         /* Japan UNI-1 even + UNI-1 odd + MKKC */
338
339         MKK7_MKKB       = 0x8C,         /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKB */
340         MKK7_MKKA2      = 0x8D,         /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA2 */
341         MKK7_MKKC       = 0x8E,         /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKC */
342
343         MKK8_MKKB       = 0x8F,         /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKB */
344         MKK8_MKKA2      = 0x90,         /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKA2 */
345         MKK8_MKKC       = 0x91,         /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKC */
346
347         /* Following definitions are used only by s/w to map old
348          * Japan SKUs.
349          */
350         MKK3_MKKA       = 0xF0,         /* Japan UNI-1 even + MKKA */
351         MKK3_MKKA1      = 0xF1,         /* Japan UNI-1 even + MKKA1 */
352         MKK3_FCCA       = 0xF2,         /* Japan UNI-1 even + FCCA */
353         MKK4_MKKA       = 0xF3,         /* Japan UNI-1 even + UNI-2 + MKKA */
354         MKK4_MKKA1      = 0xF4,         /* Japan UNI-1 even + UNI-2 + MKKA1 */
355         MKK4_FCCA       = 0xF5,         /* Japan UNI-1 even + UNI-2 + FCCA */
356         MKK9_MKKA       = 0xF6,         /* Japan UNI-1 even + 4.9GHz */
357         MKK10_MKKA      = 0xF7,         /* Japan UNI-1 even + UNI-2 + 4.9GHz */
358
359         /*
360          * Regulator domains ending in a number (e.g. APL1,
361          * MK1, ETSI4, etc) apply to 5GHz channel and power
362          * information.  Regulator domains ending in a letter
363          * (e.g. APLA, FCCA, etc) apply to 2.4GHz channel and
364          * power information.
365          */
366         APL1            = 0x0150,       /* LAT & Asia */
367         APL2            = 0x0250,       /* LAT & Asia */
368         APL3            = 0x0350,       /* Taiwan */
369         APL4            = 0x0450,       /* Jordan */
370         APL5            = 0x0550,       /* Chile */
371         APL6            = 0x0650,       /* Singapore */
372         APL8            = 0x0850,       /* Malaysia */
373         APL9            = 0x0950,       /* Korea (South) ROC 3 */
374
375         ETSI1           = 0x0130,       /* Europe & others */
376         ETSI2           = 0x0230,       /* Europe & others */
377         ETSI3           = 0x0330,       /* Europe & others */
378         ETSI4           = 0x0430,       /* Europe & others */
379         ETSI5           = 0x0530,       /* Europe & others */
380         ETSI6           = 0x0630,       /* Europe & others */
381         ETSIA           = 0x0A30,       /* France */
382         ETSIB           = 0x0B30,       /* Israel */
383         ETSIC           = 0x0C30,       /* Latin America */
384
385         FCC1            = 0x0110,       /* US & others */
386         FCC2            = 0x0120,       /* Canada, Australia & New Zealand */
387         FCC3            = 0x0160,       /* US w/new middle band & DFS */    
388         FCC4            = 0x0165,       /* US Public Safety */
389         FCC5            = 0x0166,       /* US w/ 1/2 and 1/4 width channels */
390         FCCA            = 0x0A10,        
391         FCCB            = 0x0A11,       /* US w/ 1/2 and 1/4 width channels */
392
393         APLD            = 0x0D50,       /* South Korea */
394
395         MKK1            = 0x0140,       /* Japan (UNI-1 odd)*/
396         MKK2            = 0x0240,       /* Japan (4.9 GHz + UNI-1 odd) */
397         MKK3            = 0x0340,       /* Japan (UNI-1 even) */
398         MKK4            = 0x0440,       /* Japan (UNI-1 even + UNI-2) */
399         MKK5            = 0x0540,       /* Japan (UNI-1 even + UNI-2 + mid-band) */
400         MKK6            = 0x0640,       /* Japan (UNI-1 odd + UNI-1 even) */
401         MKK7            = 0x0740,       /* Japan (UNI-1 odd + UNI-1 even + UNI-2 */
402         MKK8            = 0x0840,       /* Japan (UNI-1 odd + UNI-1 even + UNI-2 + mid-band) */
403         MKK9            = 0x0940,       /* Japan (UNI-1 even + 4.9 GHZ) */
404         MKK10           = 0x0B40,       /* Japan (UNI-1 even + UNI-2 + 4.9 GHZ) */
405         MKKA            = 0x0A40,       /* Japan */
406         MKKC            = 0x0A50,
407
408         NULL1           = 0x0198,
409         WORLD           = 0x0199,
410         SR9_WORLD       = 0x0298,
411         XR9_WORLD       = 0x0299,
412         GZ901_WORLD     = 0x029a,
413         DEBUG_REG_DMN   = 0x01ff,
414 };
415
416 #define WORLD_SKU_MASK          0x00F0
417 #define WORLD_SKU_PREFIX        0x0060
418
419 enum {                                  /* conformance test limits */
420         FCC     = 0x10,
421         MKK     = 0x40,
422         ETSI    = 0x30,
423 };
424
425 /*
426  * The following are flags for different requirements per reg domain.
427  * These requirements are either inhereted from the reg domain pair or
428  * from the unitary reg domain if the reg domain pair flags value is 0
429  */
430 enum {
431         NO_REQ                  = 0x00000000,   /* NB: must be zero */
432         DISALLOW_ADHOC_11A      = 0x00000001,
433         DISALLOW_ADHOC_11A_TURB = 0x00000002,
434         NEED_NFC                = 0x00000004,
435         ADHOC_PER_11D           = 0x00000008,  /* Start Ad-Hoc mode */
436         ADHOC_NO_11A            = 0x00000010,
437         LIMIT_FRAME_4MS         = 0x00000020,   /* 4msec limit on frame length*/
438         NO_HOSTAP               = 0x00000040,   /* No HOSTAP mode opereation */
439 };
440
441 /*
442  * The following describe the bit masks for different passive scan
443  * capability/requirements per regdomain.
444  */
445 #define NO_PSCAN        0x0ULL                  /* NB: must be zero */
446 #define PSCAN_FCC       0x0000000000000001ULL
447 #define PSCAN_FCC_T     0x0000000000000002ULL
448 #define PSCAN_ETSI      0x0000000000000004ULL
449 #define PSCAN_MKK1      0x0000000000000008ULL
450 #define PSCAN_MKK2      0x0000000000000010ULL
451 #define PSCAN_MKKA      0x0000000000000020ULL
452 #define PSCAN_MKKA_G    0x0000000000000040ULL
453 #define PSCAN_ETSIA     0x0000000000000080ULL
454 #define PSCAN_ETSIB     0x0000000000000100ULL
455 #define PSCAN_ETSIC     0x0000000000000200ULL
456 #define PSCAN_WWR       0x0000000000000400ULL
457 #define PSCAN_MKKA1     0x0000000000000800ULL
458 #define PSCAN_MKKA1_G   0x0000000000001000ULL
459 #define PSCAN_MKKA2     0x0000000000002000ULL
460 #define PSCAN_MKKA2_G   0x0000000000004000ULL
461 #define PSCAN_MKK3      0x0000000000008000ULL
462 #define PSCAN_DEFER     0x7FFFFFFFFFFFFFFFULL
463 #define IS_ECM_CHAN     0x8000000000000000ULL
464
465 /*
466  * THE following table is the mapping of regdomain pairs specified by
467  * an 8 bit regdomain value to the individual unitary reg domains
468  */
469 typedef struct {
470         HAL_REG_DOMAIN regDmnEnum;      /* 16 bit reg domain pair */
471         HAL_REG_DOMAIN regDmn5GHz;      /* 5GHz reg domain */
472         HAL_REG_DOMAIN regDmn2GHz;      /* 2GHz reg domain */
473         uint32_t flags5GHz;             /* Requirements flags (AdHoc
474                                            disallow, noise floor cal needed,
475                                            etc) */
476         uint32_t flags2GHz;             /* Requirements flags (AdHoc
477                                            disallow, noise floor cal needed,
478                                            etc) */
479         uint64_t pscanMask;             /* Passive Scan flags which
480                                            can override unitary domain
481                                            passive scan flags.  This
482                                            value is used as a mask on
483                                            the unitary flags*/
484         uint16_t singleCC;              /* Country code of single country if
485                                            a one-on-one mapping exists */
486 }  REG_DMN_PAIR_MAPPING;
487
488 static REG_DMN_PAIR_MAPPING regDomainPairs[] = {
489         {NO_ENUMRD,     DEBUG_REG_DMN,  DEBUG_REG_DMN, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
490         {NULL1_WORLD,   NULL1,          WORLD,          NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
491         {NULL1_ETSIB,   NULL1,          ETSIB,          NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
492         {NULL1_ETSIC,   NULL1,          ETSIC,          NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
493
494         {FCC2_FCCA,     FCC2,           FCCA,           NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
495         {FCC2_WORLD,    FCC2,           WORLD,          NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
496         {FCC2_ETSIC,    FCC2,           ETSIC,          NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
497         {FCC3_FCCA,     FCC3,           FCCA,           NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
498         {FCC3_WORLD,    FCC3,           WORLD,          NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
499         {FCC4_FCCA,     FCC4,           FCCA,           DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
500         {FCC5_FCCB,     FCC5,           FCCB,           NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
501
502         {ETSI1_WORLD,   ETSI1,          WORLD,          DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
503         {ETSI2_WORLD,   ETSI2,          WORLD,          DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
504         {ETSI3_WORLD,   ETSI3,          WORLD,          DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
505         {ETSI4_WORLD,   ETSI4,          WORLD,          DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
506         {ETSI5_WORLD,   ETSI5,          WORLD,          DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
507         {ETSI6_WORLD,   ETSI6,          WORLD,          DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
508
509         {ETSI3_ETSIA,   ETSI3,          WORLD,          DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
510         {FRANCE_RES,    ETSI3,          WORLD,          NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
511
512         {FCC1_WORLD,    FCC1,           WORLD,          NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
513         {FCC1_FCCA,     FCC1,           FCCA,           NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
514         {APL1_WORLD,    APL1,           WORLD,          NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
515         {APL2_WORLD,    APL2,           WORLD,          NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
516         {APL3_WORLD,    APL3,           WORLD,          NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
517         {APL4_WORLD,    APL4,           WORLD,          NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
518         {APL5_WORLD,    APL5,           WORLD,          NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
519         {APL6_WORLD,    APL6,           WORLD,          NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
520         {APL8_WORLD,    APL8,           WORLD,          NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
521         {APL9_WORLD,    APL9,           WORLD,          NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
522
523         {APL3_FCCA,     APL3,           FCCA,           NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
524         {APL1_ETSIC,    APL1,           ETSIC,          NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
525         {APL2_ETSIC,    APL2,           ETSIC,          NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
526         {APL2_APLD,     APL2,           APLD,           NO_REQ, NO_REQ, PSCAN_DEFER,  },
527
528         {MKK1_MKKA,     MKK1,           MKKA,           DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA, CTRY_JAPAN },
529         {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 },
530         {MKK1_FCCA,     MKK1,           FCCA,           DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN2 },
531         {MKK1_MKKA1,    MKK1,           MKKA,           DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN4 },
532         {MKK1_MKKA2,    MKK1,           MKKA,           DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN5 },
533         {MKK1_MKKC,     MKK1,           MKKC,           DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN6 },
534
535         /* MKK2 */
536         {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 },
537
538         /* MKK3 */
539         {MKK3_MKKA,     MKK3,   MKKA,   DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC , PSCAN_MKKA, 0 },
540         {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 },
541         {MKK3_MKKA1,    MKK3,   MKKA,   DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA1 | PSCAN_MKKA1_G, 0 },
542         {MKK3_MKKA2,MKK3,               MKKA,           DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN8 },
543         {MKK3_MKKC,     MKK3,           MKKC,           DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, CTRY_JAPAN9 },
544         {MKK3_FCCA,     MKK3,   FCCA,   DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, 0 },
545
546         /* MKK4 */
547         {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 },
548         {MKK4_MKKA1,    MKK4,   MKKA,   DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, 0 },
549         {MKK4_MKKA2,    MKK4,           MKKA,           DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 |PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11 },
550         {MKK4_MKKC,     MKK4,           MKKC,           DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN12 },
551         {MKK4_FCCA,     MKK4,   FCCA,   DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, 0 },
552
553         /* MKK5 */
554         {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 },
555         {MKK5_MKKA2,MKK5,               MKKA,           DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN14 },
556         {MKK5_MKKC,     MKK5,           MKKC,           DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN15 },
557
558         /* MKK6 */
559         {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 },
560         {MKK6_MKKA2,    MKK6,           MKKA,           DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN17 },
561         {MKK6_MKKC,     MKK6,           MKKC,           DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN18 },
562
563         /* MKK7 */
564         {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 },
565         {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 },
566         {MKK7_MKKC,     MKK7,           MKKC,           DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN21 },
567
568         /* MKK8 */
569         {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 },
570         {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 },
571         {MKK8_MKKC,     MKK8,           MKKC,           DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 , CTRY_JAPAN24 },
572
573         {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, 0 },
574         {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, 0 },
575
576                 /* These are super domains */
577         {WOR0_WORLD,    WOR0_WORLD,     WOR0_WORLD,     NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
578         {WOR1_WORLD,    WOR1_WORLD,     WOR1_WORLD,     DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
579         {WOR2_WORLD,    WOR2_WORLD,     WOR2_WORLD,     DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
580         {WOR3_WORLD,    WOR3_WORLD,     WOR3_WORLD,     NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
581         {WOR4_WORLD,    WOR4_WORLD,     WOR4_WORLD,     DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
582         {WOR5_ETSIC,    WOR5_ETSIC,     WOR5_ETSIC,     DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
583         {WOR01_WORLD,   WOR01_WORLD,    WOR01_WORLD,    NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
584         {WOR02_WORLD,   WOR02_WORLD,    WOR02_WORLD,    NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
585         {EU1_WORLD,     EU1_WORLD,      EU1_WORLD,      NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
586         {WOR9_WORLD,    WOR9_WORLD,     WOR9_WORLD,     DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
587         {WORA_WORLD,    WORA_WORLD,     WORA_WORLD,     DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
588         {SR9_WORLD,     NULL1,          SR9_WORLD,      NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_SR9 },
589         {XR9_WORLD,     NULL1,          XR9_WORLD,      NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_XR9 },
590         {GZ901_WORLD,   NULL1,          GZ901_WORLD,    NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_GZ901 },
591 };
592
593 /* 
594  * The following tables are the master list for all different freqeuncy
595  * bands with the complete matrix of all possible flags and settings
596  * for each band if it is used in ANY reg domain.
597  */
598
599 #define DEF_REGDMN              FCC1_FCCA
600 #define DEF_DMN_5               FCC1
601 #define DEF_DMN_2               FCCA
602 #define COUNTRY_ERD_FLAG        0x8000
603 #define WORLDWIDE_ROAMING_FLAG  0x4000
604 #define SUPER_DOMAIN_MASK       0x0fff
605 #define COUNTRY_CODE_MASK       0x3fff
606
607 #define YES     AH_TRUE
608 #define NO      AH_FALSE
609
610 typedef struct {
611         HAL_CTRY_CODE           countryCode;       
612         HAL_REG_DOMAIN          regDmnEnum;
613         HAL_BOOL                allow11g;
614         HAL_BOOL                allow11aTurbo;
615         HAL_BOOL                allow11gTurbo;
616         HAL_BOOL                allow11ng20;
617         HAL_BOOL                allow11ng40;
618         HAL_BOOL                allow11na20;
619         HAL_BOOL                allow11na40;
620         uint16_t                outdoorChanStart;
621 } COUNTRY_CODE_TO_ENUM_RD;
622
623 static COUNTRY_CODE_TO_ENUM_RD allCountries[] = {
624     {CTRY_DEBUG,       NO_ENUMRD,       YES, YES, YES, YES,YES, YES,YES, 7000 },
625     {CTRY_DEFAULT,     DEF_REGDMN,      YES, YES, YES, YES,YES, YES,YES, 7000 },
626     {CTRY_ALBANIA,     NULL1_WORLD,     YES,  NO, YES, YES, NO,  NO, NO, 7000 },
627     {CTRY_ALGERIA,     NULL1_WORLD,     YES,  NO, YES, YES, NO,  NO, NO, 7000 },
628     {CTRY_ARGENTINA,   APL3_WORLD,       NO,  NO,  NO,  NO, NO,  NO, NO, 7000 },
629     {CTRY_ARMENIA,     ETSI4_WORLD,     YES,  NO, YES, YES,YES,  NO, NO, 7000 },
630     {CTRY_AUSTRALIA,   FCC2_WORLD,      YES, YES, YES, YES,YES, YES,YES, 7000 },
631     {CTRY_AUSTRIA,     ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
632     {CTRY_AZERBAIJAN,  ETSI4_WORLD,     YES, YES, YES, YES,YES, YES,YES, 7000 },
633     {CTRY_BAHRAIN,     APL6_WORLD,      YES,  NO, YES, YES,YES, YES, NO, 7000 },
634     {CTRY_BELARUS,     NULL1_WORLD,     YES,  NO, YES, YES,YES, YES, NO, 7000 },
635     {CTRY_BELGIUM,     ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
636     {CTRY_BELIZE,      APL1_ETSIC,      YES, YES, YES, YES,YES, YES,YES, 7000 },
637     {CTRY_BOLIVIA,     APL1_ETSIC,      YES, YES, YES, YES,YES, YES,YES, 7000 },
638     {CTRY_BRAZIL,      FCC3_WORLD,      YES,  NO,  NO, YES, NO, YES, NO, 7000 },
639     {CTRY_BRUNEI_DARUSSALAM,APL1_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
640     {CTRY_BULGARIA,    ETSI6_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
641     {CTRY_CANADA,      FCC2_FCCA,       YES, YES, YES, YES,YES, YES,YES, 7000 },
642     {CTRY_CHILE,       APL6_WORLD,      YES, YES, YES, YES,YES, YES,YES, 7000 },
643     {CTRY_CHINA,       APL1_WORLD,      YES, YES, YES, YES,YES, YES,YES, 7000 },
644     {CTRY_COLOMBIA,    FCC1_FCCA,       YES,  NO, YES, YES,YES, YES, NO, 7000 },
645     {CTRY_COSTA_RICA,  NULL1_WORLD,     YES,  NO, YES, YES,YES, YES, NO, 7000 },
646     {CTRY_CROATIA,     ETSI3_WORLD,     YES,  NO, YES, YES,YES, YES, NO, 7000 },
647     {CTRY_CYPRUS,      ETSI1_WORLD,     YES, YES, YES, YES,YES, YES,YES, 7000 },
648     {CTRY_CZECH,       ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
649     {CTRY_DENMARK,     ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
650     {CTRY_DOMINICAN_REPUBLIC,FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
651     {CTRY_ECUADOR,     NULL1_WORLD,     NO,   NO,  NO,  NO, NO,  NO, NO, 7000 },
652     {CTRY_EGYPT,       ETSI3_WORLD,     YES,  NO, YES, YES,YES, YES, NO, 7000 },
653     {CTRY_EL_SALVADOR, NULL1_WORLD,     YES,  NO, YES, YES,YES,  NO, NO, 7000 },
654     {CTRY_ESTONIA,     ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
655     {CTRY_FINLAND,     ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
656     {CTRY_FRANCE,      ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
657     {CTRY_FRANCE2,     ETSI3_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
658     {CTRY_GEORGIA,     ETSI4_WORLD,     YES, YES, YES, YES,YES, YES,YES, 7000 },
659     {CTRY_GERMANY,     ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
660     {CTRY_GREECE,      ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
661     {CTRY_GUATEMALA,   FCC1_FCCA,       YES, YES, YES, YES,YES, YES,YES, 7000 },
662     {CTRY_GZ901,       GZ901_WORLD,     YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
663     {CTRY_HONDURAS,    NULL1_WORLD,     YES, NO,  YES, YES,YES, YES, NO, 7000 },
664     {CTRY_HONG_KONG,   FCC2_WORLD,      YES, YES, YES, YES,YES, YES,YES, 7000 },
665     {CTRY_HUNGARY,     ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
666     {CTRY_ICELAND,     ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
667     {CTRY_INDIA,       APL6_WORLD,      YES,  NO, YES, YES,YES, YES, NO, 7000 },
668     {CTRY_INDONESIA,   APL1_WORLD,      YES,  NO, YES, YES,YES, YES, NO, 7000 },
669     {CTRY_IRAN,        APL1_WORLD,      YES, YES, YES, YES,YES, YES,YES, 7000 },
670     {CTRY_IRELAND,     ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
671     {CTRY_ISRAEL,      NULL1_WORLD,     YES,  NO, YES, YES,YES, YES, NO, 7000 },
672     {CTRY_ITALY,       ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
673     {CTRY_JAPAN,       MKK1_MKKA,       YES,  NO,  NO, YES, NO, YES, NO, 7000 },
674     {CTRY_JAPAN1,      MKK1_MKKB,       YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
675     {CTRY_JAPAN2,      MKK1_FCCA,       YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
676     {CTRY_JAPAN3,      MKK2_MKKA,       YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
677     {CTRY_JAPAN4,      MKK1_MKKA1,      YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
678     {CTRY_JAPAN5,      MKK1_MKKA2,      YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
679     {CTRY_JAPAN6,      MKK1_MKKC,       YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
680
681     {CTRY_JAPAN7,      MKK3_MKKB,       YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
682     {CTRY_JAPAN8,      MKK3_MKKA2,      YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
683     {CTRY_JAPAN9,      MKK3_MKKC,       YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
684
685     {CTRY_JAPAN10,     MKK4_MKKB,       YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
686     {CTRY_JAPAN11,     MKK4_MKKA2,      YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
687     {CTRY_JAPAN12,     MKK4_MKKC,       YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
688
689     {CTRY_JAPAN13,     MKK5_MKKB,       YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
690     {CTRY_JAPAN14,     MKK5_MKKA2,      YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
691     {CTRY_JAPAN15,     MKK5_MKKC,       YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
692
693     {CTRY_JAPAN16,     MKK6_MKKB,       YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
694     {CTRY_JAPAN17,     MKK6_MKKA2,      YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
695     {CTRY_JAPAN18,     MKK6_MKKC,       YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
696
697     {CTRY_JAPAN19,     MKK7_MKKB,       YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
698     {CTRY_JAPAN20,     MKK7_MKKA2,      YES,  NO,  NO, YES, NO, YES, NO, 7000 },
699     {CTRY_JAPAN21,     MKK7_MKKC,       YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
700
701     {CTRY_JAPAN22,     MKK8_MKKB,       YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
702     {CTRY_JAPAN23,     MKK8_MKKA2,      YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
703     {CTRY_JAPAN24,     MKK8_MKKC,       YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
704
705     {CTRY_JORDAN,      APL4_WORLD,      YES,  NO, YES, YES,YES, YES, NO, 7000 },
706     {CTRY_KAZAKHSTAN,  NULL1_WORLD,     YES,  NO, YES, YES,YES,  NO, NO, 7000 },
707     {CTRY_KOREA_NORTH, APL2_WORLD,      YES, YES, YES, YES,YES, YES,YES, 7000 },
708     {CTRY_KOREA_ROC,   APL2_WORLD,      YES,  NO,  NO, YES, NO, YES, NO, 7000 },
709     {CTRY_KOREA_ROC2,  APL2_WORLD,      YES,  NO,  NO, YES, NO, YES, NO, 7000 },
710     {CTRY_KOREA_ROC3,  APL9_WORLD,      YES,  NO,  NO, YES, NO, YES, NO, 7000 },
711     {CTRY_KUWAIT,      NULL1_WORLD,     YES,  NO, YES, YES,YES, YES, NO, 7000 },
712     {CTRY_LATVIA,      ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
713     {CTRY_LEBANON,     NULL1_WORLD,     YES,  NO, YES, YES,YES, YES, NO, 7000 },
714     {CTRY_LIECHTENSTEIN,ETSI1_WORLD,    YES,  NO, YES, YES,YES, YES,YES, 7000 },
715     {CTRY_LITHUANIA,   ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
716     {CTRY_LUXEMBOURG,  ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
717     {CTRY_MACAU,       FCC2_WORLD,      YES, YES, YES, YES,YES, YES,YES, 7000 },
718     {CTRY_MACEDONIA,   NULL1_WORLD,     YES,  NO, YES, YES,YES,  NO, NO, 7000 },
719     {CTRY_MALAYSIA,    APL8_WORLD,      YES,  NO,  NO, YES, NO, YES, NO, 7000 },
720     {CTRY_MALTA,       ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
721     {CTRY_MEXICO,      FCC1_FCCA,       YES, YES, YES, YES,YES, YES,YES, 7000 },
722     {CTRY_MONACO,      ETSI4_WORLD,     YES, YES, YES, YES,YES, YES,YES, 7000 },
723     {CTRY_MOROCCO,     NULL1_WORLD,     YES,  NO, YES, YES,YES,  NO, NO, 7000 },
724     {CTRY_NETHERLANDS, ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
725     {CTRY_NEW_ZEALAND, FCC2_ETSIC,      YES,  NO, YES, YES,YES, YES,YES, 7000 },
726     {CTRY_NORWAY,      ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
727     {CTRY_OMAN,        APL6_WORLD,      YES,  NO, YES, YES,YES, YES, NO, 7000 },
728     {CTRY_PAKISTAN,    NULL1_WORLD,     YES,  NO, YES, YES,YES,  NO, NO, 7000 },
729     {CTRY_PANAMA,      FCC1_FCCA,       YES, YES, YES, YES,YES, YES,YES, 7000 },
730     {CTRY_PERU,        APL1_WORLD,      YES,  NO, YES, YES,YES, YES, NO, 7000 },
731     {CTRY_PHILIPPINES, FCC3_WORLD,      YES, YES, YES, YES,YES, YES,YES, 7000 },
732     {CTRY_POLAND,      ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
733     {CTRY_PORTUGAL,    ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
734     {CTRY_PUERTO_RICO, FCC1_FCCA,       YES, YES, YES, YES,YES, YES,YES, 7000 },
735     {CTRY_QATAR,       NULL1_WORLD,     YES,  NO, YES, YES,YES,  NO, NO, 7000 },
736     {CTRY_ROMANIA,     NULL1_WORLD,     YES,  NO, YES, YES,YES,  NO, NO, 7000 },
737     {CTRY_RUSSIA,      NULL1_WORLD,     YES,  NO, YES, YES,YES,  NO, NO, 7000 },
738     {CTRY_SAUDI_ARABIA,FCC2_WORLD,      YES,  NO, YES, YES,YES, YES, NO, 7000 },
739     {CTRY_SINGAPORE,   APL6_WORLD,      YES, YES, YES, YES,YES, YES,YES, 7000 },
740     {CTRY_SLOVAKIA,    ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
741     {CTRY_SLOVENIA,    ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
742     {CTRY_SOUTH_AFRICA,FCC3_WORLD,      YES,  NO, YES, YES,YES, YES, NO, 7000 },
743     {CTRY_SPAIN,       ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
744     {CTRY_SR9,         SR9_WORLD,       YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
745     {CTRY_SWEDEN,      ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
746     {CTRY_SWITZERLAND, ETSI1_WORLD,     YES,  NO, YES, YES,YES, YES,YES, 7000 },
747     {CTRY_SYRIA,       NULL1_WORLD,     YES,  NO, YES, YES,YES, YES, NO, 7000 },
748     {CTRY_TAIWAN,      APL3_FCCA,       YES, YES, YES, YES,YES, YES,YES, 7000 },
749     {CTRY_THAILAND,    NULL1_WORLD,     YES,  NO, YES, YES,YES,  NO, NO, 7000 },
750     {CTRY_TRINIDAD_Y_TOBAGO,ETSI4_WORLD,YES,  NO, YES, YES,YES, YES, NO, 7000 },
751     {CTRY_TUNISIA,     ETSI3_WORLD,     YES,  NO, YES, YES,YES, YES, NO, 7000 },
752     {CTRY_TURKEY,      ETSI3_WORLD,     YES,  NO, YES, YES,YES, YES, NO, 7000 },
753     {CTRY_UKRAINE,     NULL1_WORLD,     YES,  NO, YES, YES,YES,  NO, NO, 7000 },
754     {CTRY_UAE,         NULL1_WORLD,     YES,  NO, YES, YES,YES,  NO, NO, 7000 },
755     {CTRY_UNITED_KINGDOM, ETSI1_WORLD,  YES,  NO, YES, YES,YES, YES, NO, 7000 },
756     {CTRY_UNITED_STATES, FCC1_FCCA,     YES, YES, YES, YES,YES, YES,YES, 5825 },
757     {CTRY_UNITED_STATES_FCC49,FCC4_FCCA,YES, YES, YES, YES,YES, YES,YES, 7000 },
758     {CTRY_URUGUAY,     FCC1_WORLD,      YES,  NO, YES, YES,YES, YES, NO, 7000 },
759     {CTRY_UZBEKISTAN,  FCC3_FCCA,       YES, YES, YES, YES,YES, YES,YES, 7000 },
760     {CTRY_VENEZUELA,   APL2_ETSIC,      YES,  NO, YES, YES,YES, YES, NO, 7000 },
761     {CTRY_VIET_NAM,    NULL1_WORLD,     YES,  NO, YES, YES,YES,  NO, NO, 7000 },
762     {CTRY_XR9,         XR9_WORLD,       YES,  NO,  NO,  NO, NO,  NO, NO, 7000 },
763     {CTRY_YEMEN,       NULL1_WORLD,     YES,  NO, YES, YES,YES,  NO, NO, 7000 },
764     {CTRY_ZIMBABWE,    NULL1_WORLD,     YES,  NO, YES, YES,YES,  NO, NO, 7000 }
765 };
766
767 /* Bit masks for DFS per regdomain */
768 enum {
769         NO_DFS   = 0x0000000000000000ULL,       /* NB: must be zero */
770         DFS_FCC3 = 0x0000000000000001ULL,
771         DFS_ETSI = 0x0000000000000002ULL,
772         DFS_MKK4 = 0x0000000000000004ULL,
773 };
774
775 #define AFTER(x)        ((x)+1)
776
777 /*
778  * Frequency band collections are defined using bitmasks.  Each bit
779  * in a mask is the index of an entry in one of the following tables.
780  * Bitmasks are BMLEN*64 bits so if a table grows beyond that the bit
781  * vectors must be enlarged or the tables split somehow (e.g. split
782  * 1/2 and 1/4 rate channels into a separate table).
783  *
784  * Beware of ordering; the indices are defined relative to the preceding
785  * entry so if things get off there will be confusion.  A good way to
786  * check the indices is to collect them in a switch statement in a stub
787  * function so the compiler checks for duplicates.
788  */
789
790 typedef struct {
791         uint16_t        lowChannel;     /* Low channel center in MHz */
792         uint16_t        highChannel;    /* High Channel center in MHz */
793         uint8_t         powerDfs;       /* Max power (dBm) for channel
794                                            range when using DFS */
795         uint8_t         antennaMax;     /* Max allowed antenna gain */
796         uint8_t         channelBW;      /* Bandwidth of the channel */
797         uint8_t         channelSep;     /* Channel separation within
798                                            the band */
799         uint64_t        useDfs;         /* Use DFS in the RegDomain
800                                            if corresponding bit is set */
801         uint64_t        usePassScan;    /* Use Passive Scan in the RegDomain
802                                            if corresponding bit is set */
803         uint8_t         regClassId;     /* Regulatory class id */
804 } REG_DMN_FREQ_BAND;
805
806 /*
807  * 5GHz 11A channel tags
808  */
809 static REG_DMN_FREQ_BAND regDmn5GhzFreq[] = {
810         { 4915, 4925, 23, 0, 10,  5, NO_DFS, PSCAN_MKK2, 16 },
811 #define F1_4915_4925    0
812         { 4935, 4945, 23, 0, 10,  5, NO_DFS, PSCAN_MKK2, 16 },
813 #define F1_4935_4945    AFTER(F1_4915_4925)
814         { 4920, 4980, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 7 },
815 #define F1_4920_4980    AFTER(F1_4935_4945)
816         { 4942, 4987, 27, 6,  5,  5, NO_DFS, PSCAN_FCC, 0 },
817 #define F1_4942_4987    AFTER(F1_4920_4980)
818         { 4945, 4985, 30, 6, 10,  5, NO_DFS, PSCAN_FCC, 0 },
819 #define F1_4945_4985    AFTER(F1_4942_4987)
820         { 4950, 4980, 33, 6, 20,  5, NO_DFS, PSCAN_FCC, 0 },
821 #define F1_4950_4980    AFTER(F1_4945_4985)
822         { 5035, 5040, 23, 0, 10,  5, NO_DFS, PSCAN_MKK2, 12 },
823 #define F1_5035_5040    AFTER(F1_4950_4980)
824         { 5040, 5080, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 2 },
825 #define F1_5040_5080    AFTER(F1_5035_5040)
826         { 5055, 5055, 23, 0, 10,  5, NO_DFS, PSCAN_MKK2, 12 },
827 #define F1_5055_5055    AFTER(F1_5040_5080)
828
829         { 5120, 5240, 5,  6, 20, 20, NO_DFS, NO_PSCAN, 0 },
830 #define F1_5120_5240    AFTER(F1_5055_5055)
831         { 5120, 5240, 5,  6, 10, 10, NO_DFS, NO_PSCAN, 0 },
832 #define F2_5120_5240    AFTER(F1_5120_5240)
833         { 5120, 5240, 5,  6,  5,  5, NO_DFS, NO_PSCAN, 0 },
834 #define F3_5120_5240    AFTER(F2_5120_5240)
835
836         { 5170, 5230, 23, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1 },
837 #define F1_5170_5230    AFTER(F3_5120_5240)
838         { 5170, 5230, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1 },
839 #define F2_5170_5230    AFTER(F1_5170_5230)
840
841         { 5180, 5240, 15, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 },
842 #define F1_5180_5240    AFTER(F2_5170_5230)
843         { 5180, 5240, 17, 6, 20, 20, NO_DFS, PSCAN_FCC, 1 },
844 #define F2_5180_5240    AFTER(F1_5180_5240)
845         { 5180, 5240, 18, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 },
846 #define F3_5180_5240    AFTER(F2_5180_5240)
847         { 5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 },
848 #define F4_5180_5240    AFTER(F3_5180_5240)
849         { 5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 },
850 #define F5_5180_5240    AFTER(F4_5180_5240)
851         { 5180, 5240, 23, 6, 20, 20, NO_DFS, PSCAN_FCC, 0 },
852 #define F6_5180_5240    AFTER(F5_5180_5240)
853         { 5180, 5240, 17, 6, 20, 10, NO_DFS, PSCAN_FCC, 1 },
854 #define F7_5180_5240    AFTER(F6_5180_5240)
855         { 5180, 5240, 17, 6, 20,  5, NO_DFS, PSCAN_FCC, 1 },
856 #define F8_5180_5240    AFTER(F7_5180_5240)
857
858         { 5180, 5320, 20, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0 },
859 #define F1_5180_5320    AFTER(F8_5180_5240)
860
861         { 5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI, 0 },
862 #define F1_5240_5280    AFTER(F1_5180_5320)
863
864         { 5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 },
865 #define F1_5260_5280    AFTER(F1_5240_5280)
866
867         { 5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 },
868 #define F1_5260_5320    AFTER(F1_5260_5280)
869
870         { 5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3 , 0 },
871 #define F2_5260_5320    AFTER(F1_5260_5320)
872
873         { 5260, 5320, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 },
874 #define F3_5260_5320    AFTER(F2_5260_5320)
875         { 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 },
876 #define F4_5260_5320    AFTER(F3_5260_5320)
877         { 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0 },
878 #define F5_5260_5320    AFTER(F4_5260_5320)
879         { 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
880 #define F6_5260_5320    AFTER(F5_5260_5320)
881         { 5260, 5320, 23, 6, 20, 10, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 },
882 #define F7_5260_5320    AFTER(F6_5260_5320)
883         { 5260, 5320, 23, 6, 20,  5, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 },
884 #define F8_5260_5320    AFTER(F7_5260_5320)
885
886         { 5260, 5700, 5,  6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0 },
887 #define F1_5260_5700    AFTER(F8_5260_5320)
888         { 5260, 5700, 5,  6, 10, 10, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0 },
889 #define F2_5260_5700    AFTER(F1_5260_5700)
890         { 5260, 5700, 5,  6,  5,  5, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0 },
891 #define F3_5260_5700    AFTER(F2_5260_5700)
892
893         { 5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0 },
894 #define F1_5280_5320    AFTER(F3_5260_5700)
895
896         { 5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0 },
897 #define F1_5500_5620    AFTER(F1_5280_5320)
898
899         { 5500, 5700, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 4 },
900 #define F1_5500_5700    AFTER(F1_5500_5620)
901         { 5500, 5700, 27, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 },
902 #define F2_5500_5700    AFTER(F1_5500_5700)
903         { 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 },
904 #define F3_5500_5700    AFTER(F2_5500_5700)
905         { 5500, 5700, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_MKK3 | PSCAN_FCC, 0 },
906 #define F4_5500_5700    AFTER(F3_5500_5700)
907
908         { 5745, 5805, 23, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
909 #define F1_5745_5805    AFTER(F4_5500_5700)
910         { 5745, 5805, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0 },
911 #define F2_5745_5805    AFTER(F1_5745_5805)
912         { 5745, 5805, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0 },
913 #define F3_5745_5805    AFTER(F2_5745_5805)
914         { 5745, 5825, 5,  6, 20, 20, NO_DFS, NO_PSCAN, 0 },
915 #define F1_5745_5825    AFTER(F3_5745_5805)
916         { 5745, 5825, 17, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
917 #define F2_5745_5825    AFTER(F1_5745_5825)
918         { 5745, 5825, 20, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
919 #define F3_5745_5825    AFTER(F2_5745_5825)
920         { 5745, 5825, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
921 #define F4_5745_5825    AFTER(F3_5745_5825)
922         { 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 3 },
923 #define F5_5745_5825    AFTER(F4_5745_5825)
924         { 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0 },
925 #define F6_5745_5825    AFTER(F5_5745_5825)
926         { 5745, 5825, 5,  6, 10, 10, NO_DFS, NO_PSCAN, 0 },
927 #define F7_5745_5825    AFTER(F6_5745_5825)
928         { 5745, 5825, 5,  6,  5,  5, NO_DFS, NO_PSCAN, 0 },
929 #define F8_5745_5825    AFTER(F7_5745_5825)
930         { 5745, 5825, 30, 6, 20, 10, NO_DFS, NO_PSCAN, 3 },
931 #define F9_5745_5825    AFTER(F8_5745_5825)
932         { 5745, 5825, 30, 6, 20,  5, NO_DFS, NO_PSCAN, 3 },
933 #define F10_5745_5825   AFTER(F9_5745_5825)
934
935         /*
936          * Below are the world roaming channels
937          * All WWR domains have no power limit, instead use the card's CTL
938          * or max power settings.
939          */
940         { 4920, 4980, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 },
941 #define W1_4920_4980    AFTER(F10_5745_5825)
942         { 5040, 5080, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 },
943 #define W1_5040_5080    AFTER(W1_4920_4980)
944         { 5170, 5230, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 },
945 #define W1_5170_5230    AFTER(W1_5040_5080)
946         { 5180, 5240, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 },
947 #define W1_5180_5240    AFTER(W1_5170_5230)
948         { 5260, 5320, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 },
949 #define W1_5260_5320    AFTER(W1_5180_5240)
950         { 5745, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 },
951 #define W1_5745_5825    AFTER(W1_5260_5320)
952         { 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 },
953 #define W1_5500_5700    AFTER(W1_5745_5825)
954         { 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN,  0 },
955 #define W2_5260_5320    AFTER(W1_5500_5700)
956         { 5180, 5240, 30, 0, 20, 20, NO_DFS, NO_PSCAN,  0 },
957 #define W2_5180_5240    AFTER(W2_5260_5320)
958         { 5825, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 },
959 #define W2_5825_5825    AFTER(W2_5180_5240)
960 };
961
962 /*
963  * 5GHz Turbo (dynamic & static) tags
964  */
965 static REG_DMN_FREQ_BAND regDmn5GhzTurboFreq[] = {
966         { 5130, 5210, 5,  6, 40, 40, NO_DFS, NO_PSCAN, 0},
967 #define T1_5130_5210    0
968         { 5250, 5330, 5,  6, 40, 40, DFS_FCC3, NO_PSCAN, 0},
969 #define T1_5250_5330    AFTER(T1_5130_5210)
970         { 5370, 5490, 5,  6, 40, 40, NO_DFS, NO_PSCAN, 0},
971 #define T1_5370_5490    AFTER(T1_5250_5330)
972         { 5530, 5650, 5,  6, 40, 40, DFS_FCC3, NO_PSCAN, 0},
973 #define T1_5530_5650    AFTER(T1_5370_5490)
974
975         { 5150, 5190, 5,  6, 40, 40, NO_DFS, NO_PSCAN, 0},
976 #define T1_5150_5190    AFTER(T1_5530_5650)
977         { 5230, 5310, 5,  6, 40, 40, DFS_FCC3, NO_PSCAN, 0},
978 #define T1_5230_5310    AFTER(T1_5150_5190)
979         { 5350, 5470, 5,  6, 40, 40, NO_DFS, NO_PSCAN, 0},
980 #define T1_5350_5470    AFTER(T1_5230_5310)
981         { 5510, 5670, 5,  6, 40, 40, DFS_FCC3, NO_PSCAN, 0},
982 #define T1_5510_5670    AFTER(T1_5350_5470)
983
984         { 5200, 5240, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
985 #define T1_5200_5240    AFTER(T1_5510_5670)
986         { 5200, 5240, 23, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
987 #define T2_5200_5240    AFTER(T1_5200_5240)
988         { 5210, 5210, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
989 #define T1_5210_5210    AFTER(T2_5200_5240)
990         { 5210, 5210, 23, 0, 40, 40, NO_DFS, NO_PSCAN, 0},
991 #define T2_5210_5210    AFTER(T1_5210_5210)
992
993         { 5280, 5280, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
994 #define T1_5280_5280    AFTER(T2_5210_5210)
995         { 5280, 5280, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
996 #define T2_5280_5280    AFTER(T1_5280_5280)
997         { 5250, 5250, 17, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
998 #define T1_5250_5250    AFTER(T2_5280_5280)
999         { 5290, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
1000 #define T1_5290_5290    AFTER(T1_5250_5250)
1001         { 5250, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
1002 #define T1_5250_5290    AFTER(T1_5290_5290)
1003         { 5250, 5290, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
1004 #define T2_5250_5290    AFTER(T1_5250_5290)
1005
1006         { 5540, 5660, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
1007 #define T1_5540_5660    AFTER(T2_5250_5290)
1008         { 5760, 5800, 20, 0, 40, 40, NO_DFS, NO_PSCAN, 0},
1009 #define T1_5760_5800    AFTER(T1_5540_5660)
1010         { 5760, 5800, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
1011 #define T2_5760_5800    AFTER(T1_5760_5800)
1012
1013         { 5765, 5805, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
1014 #define T1_5765_5805    AFTER(T2_5760_5800)
1015
1016         /*
1017          * Below are the WWR frequencies
1018          */
1019         { 5210, 5250, 15, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
1020 #define WT1_5210_5250   AFTER(T1_5765_5805)
1021         { 5290, 5290, 18, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
1022 #define WT1_5290_5290   AFTER(WT1_5210_5250)
1023         { 5540, 5660, 20, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
1024 #define WT1_5540_5660   AFTER(WT1_5290_5290)
1025         { 5760, 5800, 20, 0, 40, 40, NO_DFS, PSCAN_WWR, 0},
1026 #define WT1_5760_5800   AFTER(WT1_5540_5660)
1027 };
1028
1029 /*
1030  * 2GHz 11b channel tags
1031  */
1032 static REG_DMN_FREQ_BAND regDmn2GhzFreq[] = {
1033         { 2312, 2372, 5,  6, 20, 5, NO_DFS, NO_PSCAN, 0},
1034 #define F1_2312_2372    0
1035         { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1036 #define F2_2312_2372    AFTER(F1_2312_2372)
1037
1038         { 2412, 2472, 5,  6, 20, 5, NO_DFS, NO_PSCAN, 0},
1039 #define F1_2412_2472    AFTER(F2_2312_2372)
1040         { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
1041 #define F2_2412_2472    AFTER(F1_2412_2472)
1042         { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1043 #define F3_2412_2472    AFTER(F2_2412_2472)
1044
1045         { 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1046 #define F1_2412_2462    AFTER(F3_2412_2472)
1047         { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
1048 #define F2_2412_2462    AFTER(F1_2412_2462)
1049
1050         { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1051 #define F1_2432_2442    AFTER(F2_2412_2462)
1052
1053         { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1054 #define F1_2457_2472    AFTER(F1_2432_2442)
1055
1056         { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0},
1057 #define F1_2467_2472    AFTER(F1_2457_2472)
1058
1059         { 2484, 2484, 5,  6, 20, 5, NO_DFS, NO_PSCAN, 0},
1060 #define F1_2484_2484    AFTER(F1_2467_2472)
1061         { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 0},
1062 #define F2_2484_2484    AFTER(F1_2484_2484)
1063
1064         { 2512, 2732, 5,  6, 20, 5, NO_DFS, NO_PSCAN, 0},
1065 #define F1_2512_2732    AFTER(F2_2484_2484)
1066
1067         /*
1068          * WWR have powers opened up to 20dBm.
1069          * Limits should often come from CTL/Max powers
1070          */
1071         { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1072 #define W1_2312_2372    AFTER(F1_2512_2732)
1073         { 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1074 #define W1_2412_2412    AFTER(W1_2312_2372)
1075         { 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1076 #define W1_2417_2432    AFTER(W1_2412_2412)
1077         { 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1078 #define W1_2437_2442    AFTER(W1_2417_2432)
1079         { 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1080 #define W1_2447_2457    AFTER(W1_2437_2442)
1081         { 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1082 #define W1_2462_2462    AFTER(W1_2447_2457)
1083         { 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
1084 #define W1_2467_2467    AFTER(W1_2462_2462)
1085         { 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
1086 #define W2_2467_2467    AFTER(W1_2467_2467)
1087         { 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
1088 #define W1_2472_2472    AFTER(W2_2467_2467)
1089         { 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
1090 #define W2_2472_2472    AFTER(W1_2472_2472)
1091         { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
1092 #define W1_2484_2484    AFTER(W2_2472_2472)
1093         { 2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
1094 #define W2_2484_2484    AFTER(W1_2484_2484)
1095 };
1096
1097 /*
1098  * 2GHz 11g channel tags
1099  */
1100 static REG_DMN_FREQ_BAND regDmn2Ghz11gFreq[] = {
1101         { 2312, 2372, 5,  6, 20, 5, NO_DFS, NO_PSCAN, 0},
1102 #define G1_2312_2372    0
1103         { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1104 #define G2_2312_2372    AFTER(G1_2312_2372)
1105         { 2312, 2372, 5,  6, 10, 5, NO_DFS, NO_PSCAN, 0},
1106 #define G3_2312_2372    AFTER(G2_2312_2372)
1107         { 2312, 2372, 5,  6,  5, 5, NO_DFS, NO_PSCAN, 0},
1108 #define G4_2312_2372    AFTER(G3_2312_2372)
1109
1110         { 2412, 2472, 5,  6, 20, 5, NO_DFS, NO_PSCAN, 0},
1111 #define G1_2412_2472    AFTER(G4_2312_2372)
1112         { 2412, 2472, 20, 0, 20, 5,  NO_DFS, PSCAN_MKKA_G, 0},
1113 #define G2_2412_2472    AFTER(G1_2412_2472)
1114         { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1115 #define G3_2412_2472    AFTER(G2_2412_2472)
1116         { 2412, 2472, 5,  6, 10, 5, NO_DFS, NO_PSCAN, 0},
1117 #define G4_2412_2472    AFTER(G3_2412_2472)
1118         { 2412, 2472, 5,  6,  5, 5, NO_DFS, NO_PSCAN, 0},
1119 #define G5_2412_2472    AFTER(G4_2412_2472)
1120
1121         { 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1122 #define G1_2412_2462    AFTER(G5_2412_2472)
1123         { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
1124 #define G2_2412_2462    AFTER(G1_2412_2462)
1125         { 2412, 2462, 27, 6, 10, 5, NO_DFS, NO_PSCAN, 0},
1126 #define G3_2412_2462    AFTER(G2_2412_2462)
1127         { 2412, 2462, 27, 6,  5, 5, NO_DFS, NO_PSCAN, 0},
1128 #define G4_2412_2462    AFTER(G3_2412_2462)
1129         
1130         { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1131 #define G1_2432_2442    AFTER(G4_2412_2462)
1132
1133         { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1134 #define G1_2457_2472    AFTER(G1_2432_2442)
1135
1136         { 2512, 2732, 5,  6, 20, 5, NO_DFS, NO_PSCAN, 0},
1137 #define G1_2512_2732    AFTER(G1_2457_2472)
1138         { 2512, 2732, 5,  6, 10, 5, NO_DFS, NO_PSCAN, 0},
1139 #define G2_2512_2732    AFTER(G1_2512_2732)
1140         { 2512, 2732, 5,  6,  5, 5, NO_DFS, NO_PSCAN, 0},
1141 #define G3_2512_2732    AFTER(G2_2512_2732)
1142
1143         { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0 },
1144 #define G1_2467_2472    AFTER(G3_2512_2732)
1145
1146         /*
1147          * WWR open up the power to 20dBm
1148          */
1149         { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1150 #define WG1_2312_2372   AFTER(G1_2467_2472)
1151         { 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1152 #define WG1_2412_2412   AFTER(WG1_2312_2372)
1153         { 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1154 #define WG1_2417_2432   AFTER(WG1_2412_2412)
1155         { 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1156 #define WG1_2437_2442   AFTER(WG1_2417_2432)
1157         { 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1158 #define WG1_2447_2457   AFTER(WG1_2437_2442)
1159         { 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1160 #define WG1_2462_2462   AFTER(WG1_2447_2457)
1161         { 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
1162 #define WG1_2467_2467   AFTER(WG1_2462_2462)
1163         { 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
1164 #define WG2_2467_2467   AFTER(WG1_2467_2467)
1165         { 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
1166 #define WG1_2472_2472   AFTER(WG2_2467_2467)
1167         { 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
1168 #define WG2_2472_2472   AFTER(WG1_2472_2472)
1169
1170         /*
1171          * Mapping for 900MHz cards like Ubiquiti SR9 and XR9
1172          * and ZComax GZ-901.
1173          */
1174         { 2422, 2437, 30, 0,  5, 5, NO_DFS, PSCAN_FCC, 0 },
1175 #define S1_907_922_5    AFTER(WG2_2472_2472)
1176         { 2422, 2437, 30, 0, 10, 5, NO_DFS, PSCAN_FCC, 0 },
1177 #define S1_907_922_10   AFTER(S1_907_922_5)
1178         { 2427, 2432, 30, 0, 20, 5, NO_DFS, PSCAN_FCC, 0 },
1179 #define S1_912_917      AFTER(S1_907_922_10)
1180         { 2427, 2442, 30, 0,  5, 5, NO_DFS, PSCAN_FCC, 0 },
1181 #define S2_907_922_5    AFTER(S1_912_917)
1182         { 2427, 2442, 30, 0, 10, 5, NO_DFS, PSCAN_FCC, 0 },
1183 #define S2_907_922_10   AFTER(S2_907_922_5)
1184         { 2432, 2437, 30, 0, 20, 5, NO_DFS, PSCAN_FCC, 0 },
1185 #define S2_912_917      AFTER(S2_907_922_10)
1186         { 2452, 2467, 30, 0,  5, 5, NO_DFS, PSCAN_FCC, 0 },
1187 #define S1_908_923_5    AFTER(S2_912_917)
1188         { 2457, 2467, 30, 0, 10, 5, NO_DFS, PSCAN_FCC, 0 },
1189 #define S1_913_918_10   AFTER(S1_908_923_5)
1190         { 2457, 2467, 30, 0, 20, 5, NO_DFS, PSCAN_FCC, 0 },
1191 #define S1_913_918      AFTER(S1_913_918_10)
1192 };
1193
1194 /*
1195  * 2GHz Dynamic turbo tags
1196  */
1197 static REG_DMN_FREQ_BAND regDmn2Ghz11gTurboFreq[] = {
1198         { 2312, 2372, 5,  6, 40, 40, NO_DFS, NO_PSCAN, 0},
1199 #define T1_2312_2372    0
1200         { 2437, 2437, 5,  6, 40, 40, NO_DFS, NO_PSCAN, 0},
1201 #define T1_2437_2437    AFTER(T1_2312_2372)
1202         { 2437, 2437, 20, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
1203 #define T2_2437_2437    AFTER(T1_2437_2437)
1204         { 2437, 2437, 18, 6, 40, 40, NO_DFS, PSCAN_WWR, 0},
1205 #define T3_2437_2437    AFTER(T2_2437_2437)
1206         { 2512, 2732, 5,  6, 40, 40, NO_DFS, NO_PSCAN, 0},
1207 #define T1_2512_2732    AFTER(T3_2437_2437)
1208 };
1209
1210 typedef struct regDomain {
1211         uint16_t regDmnEnum;            /* value from EnumRd table */
1212         uint8_t conformanceTestLimit;
1213         uint32_t flags;                 /* Requirement flags (AdHoc disallow,
1214                                            noise floor cal needed, etc) */
1215         uint64_t dfsMask;               /* DFS bitmask for 5Ghz tables */
1216         uint64_t pscan;                 /* Bitmask for passive scan */
1217         chanbmask_t chan11a;            /* 11a channels */
1218         chanbmask_t chan11a_turbo;      /* 11a static turbo channels */
1219         chanbmask_t chan11a_dyn_turbo;  /* 11a dynamic turbo channels */
1220         chanbmask_t chan11a_half;       /* 11a 1/2 width channels */
1221         chanbmask_t chan11a_quarter;    /* 11a 1/4 width channels */
1222         chanbmask_t chan11b;            /* 11b channels */
1223         chanbmask_t chan11g;            /* 11g channels */
1224         chanbmask_t chan11g_turbo;      /* 11g dynamic turbo channels */
1225         chanbmask_t chan11g_half;       /* 11g 1/2 width channels */
1226         chanbmask_t chan11g_quarter;    /* 11g 1/4 width channels */
1227 } REG_DOMAIN;
1228
1229 static REG_DOMAIN regDomains[] = {
1230
1231         {.regDmnEnum            = DEBUG_REG_DMN,
1232          .conformanceTestLimit  = FCC,
1233          .dfsMask               = DFS_FCC3,
1234          .chan11a               = BM3(F1_5120_5240, F1_5260_5700, F1_5745_5825),
1235          .chan11a_half          = BM3(F2_5120_5240, F2_5260_5700, F7_5745_5825),
1236          .chan11a_quarter       = BM3(F3_5120_5240, F3_5260_5700, F8_5745_5825),
1237          .chan11a_turbo         = BM8(T1_5130_5210,
1238                                       T1_5250_5330,
1239                                       T1_5370_5490,
1240                                       T1_5530_5650,
1241                                       T1_5150_5190,
1242                                       T1_5230_5310,
1243                                       T1_5350_5470,
1244                                       T1_5510_5670),
1245          .chan11a_dyn_turbo     = BM4(T1_5200_5240,
1246                                       T1_5280_5280,
1247                                       T1_5540_5660,
1248                                       T1_5765_5805),
1249          .chan11b               = BM4(F1_2312_2372,
1250                                       F1_2412_2472,
1251                                       F1_2484_2484,
1252                                       F1_2512_2732),
1253          .chan11g               = BM3(G1_2312_2372, G1_2412_2472, G1_2512_2732),
1254          .chan11g_turbo         = BM3(T1_2312_2372, T1_2437_2437, T1_2512_2732),
1255          .chan11g_half          = BM3(G2_2312_2372, G4_2412_2472, G2_2512_2732),
1256          .chan11g_quarter       = BM3(G3_2312_2372, G5_2412_2472, G3_2512_2732),
1257         },
1258
1259         {.regDmnEnum            = APL1,
1260          .conformanceTestLimit  = FCC,
1261          .chan11a               = BM1(F4_5745_5825),
1262         },
1263
1264         {.regDmnEnum            = APL2,
1265          .conformanceTestLimit  = FCC,
1266          .chan11a               = BM1(F1_5745_5805),
1267         },
1268
1269         {.regDmnEnum            = APL3,
1270          .conformanceTestLimit  = FCC,
1271          .chan11a               = BM2(F1_5280_5320, F2_5745_5805),
1272         },
1273
1274         {.regDmnEnum            = APL4,
1275          .conformanceTestLimit  = FCC,
1276          .chan11a               = BM2(F4_5180_5240, F3_5745_5825),
1277         },
1278
1279         {.regDmnEnum            = APL5,
1280          .conformanceTestLimit  = FCC,
1281          .chan11a               = BM1(F2_5745_5825),
1282         },
1283
1284         {.regDmnEnum            = APL6,
1285          .conformanceTestLimit  = ETSI,
1286          .dfsMask               = DFS_ETSI,
1287          .pscan                 = PSCAN_FCC_T | PSCAN_FCC,
1288          .chan11a               = BM3(F4_5180_5240, F2_5260_5320, F3_5745_5825),
1289          .chan11a_turbo         = BM3(T2_5210_5210, T1_5250_5290, T1_5760_5800),
1290         },
1291
1292         {.regDmnEnum            = APL8,
1293          .conformanceTestLimit  = ETSI,
1294          .flags                 = DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB,
1295          .chan11a               = BM2(F6_5260_5320, F4_5745_5825),
1296         },
1297
1298         {.regDmnEnum            = APL9,
1299          .conformanceTestLimit  = ETSI,
1300          .dfsMask               = DFS_ETSI,
1301          .pscan                 = PSCAN_ETSI,
1302          .flags                 = DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB,
1303          .chan11a               = BM3(F1_5180_5320, F1_5500_5620, F3_5745_5805),
1304         },
1305
1306         {.regDmnEnum            = ETSI1,
1307          .conformanceTestLimit  = ETSI,
1308          .dfsMask               = DFS_ETSI,
1309          .pscan                 = PSCAN_ETSI,
1310          .flags                 = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1311          .chan11a               = BM3(W2_5180_5240, F2_5260_5320, F2_5500_5700),
1312         },
1313
1314         {.regDmnEnum            = ETSI2,
1315          .conformanceTestLimit  = ETSI,
1316          .dfsMask               = DFS_ETSI,
1317          .pscan                 = PSCAN_ETSI,
1318          .flags                 = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1319          .chan11a               = BM1(F3_5180_5240),
1320         },
1321
1322         {.regDmnEnum            = ETSI3,
1323          .conformanceTestLimit  = ETSI,
1324          .dfsMask               = DFS_ETSI,
1325          .pscan                 = PSCAN_ETSI,
1326          .flags                 = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1327          .chan11a               = BM2(W2_5180_5240, F2_5260_5320),
1328         },
1329
1330         {.regDmnEnum            = ETSI4,
1331          .conformanceTestLimit  = ETSI,
1332          .dfsMask               = DFS_ETSI,
1333          .pscan                 = PSCAN_ETSI,
1334          .flags                 = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1335          .chan11a               = BM2(F3_5180_5240, F1_5260_5320),
1336         },
1337
1338         {.regDmnEnum            = ETSI5,
1339          .conformanceTestLimit  = ETSI,
1340          .dfsMask               = DFS_ETSI,
1341          .pscan                 = PSCAN_ETSI,
1342          .flags                 = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1343          .chan11a               = BM1(F1_5180_5240),
1344         },
1345
1346         {.regDmnEnum            = ETSI6,
1347          .conformanceTestLimit  = ETSI,
1348          .dfsMask               = DFS_ETSI,
1349          .pscan                 = PSCAN_ETSI,
1350          .flags                 = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1351          .chan11a               = BM3(F5_5180_5240, F1_5260_5280, F3_5500_5700),
1352         },
1353
1354         {.regDmnEnum            = FCC1,
1355          .conformanceTestLimit  = FCC,
1356          .chan11a               = BM3(F2_5180_5240, F4_5260_5320, F5_5745_5825),
1357          .chan11a_turbo         = BM3(T1_5210_5210, T2_5250_5290, T2_5760_5800),
1358          .chan11a_dyn_turbo     = BM3(T1_5200_5240, T1_5280_5280, T1_5765_5805),
1359         },
1360
1361         {.regDmnEnum            = FCC2,
1362          .conformanceTestLimit  = FCC,
1363          .chan11a               = BM3(F6_5180_5240, F5_5260_5320, F6_5745_5825),
1364          .chan11a_dyn_turbo     = BM3(T2_5200_5240, T1_5280_5280, T1_5765_5805),
1365         },
1366
1367         {.regDmnEnum            = FCC3,
1368          .conformanceTestLimit  = FCC,
1369          .dfsMask               = DFS_FCC3,
1370          .pscan                 = PSCAN_FCC | PSCAN_FCC_T,
1371          .chan11a               = BM4(F2_5180_5240,
1372                                       F3_5260_5320,
1373                                       F1_5500_5700,
1374                                       F5_5745_5825),
1375          .chan11a_turbo         = BM4(T1_5210_5210,
1376                                       T1_5250_5250,
1377                                       T1_5290_5290,
1378                                       T2_5760_5800),
1379          .chan11a_dyn_turbo     = BM3(T1_5200_5240, T2_5280_5280, T1_5540_5660),
1380         },
1381
1382         {.regDmnEnum            = FCC4,
1383          .conformanceTestLimit  = FCC,
1384          .dfsMask               = DFS_FCC3,
1385          .pscan                 = PSCAN_FCC | PSCAN_FCC_T,
1386          .chan11a               = BM1(F1_4950_4980),
1387          .chan11a_half          = BM1(F1_4945_4985),
1388          .chan11a_quarter       = BM1(F1_4942_4987),
1389         },
1390
1391         /* FCC1 w/ 1/2 and 1/4 width channels */
1392         {.regDmnEnum            = FCC5,
1393          .conformanceTestLimit  = FCC,
1394          .chan11a               = BM3(F2_5180_5240, F4_5260_5320, F5_5745_5825),
1395          .chan11a_turbo         = BM3(T1_5210_5210, T2_5250_5290, T2_5760_5800),
1396          .chan11a_dyn_turbo     = BM3(T1_5200_5240, T1_5280_5280, T1_5765_5805),
1397          .chan11a_half          = BM3(F7_5180_5240, F7_5260_5320, F9_5745_5825),
1398          .chan11a_quarter       = BM3(F8_5180_5240, F8_5260_5320,F10_5745_5825),
1399         },
1400
1401         {.regDmnEnum            = MKK1,
1402          .conformanceTestLimit  = MKK,
1403          .pscan                 = PSCAN_MKK1,
1404          .flags                 = DISALLOW_ADHOC_11A_TURB,
1405          .chan11a               = BM1(F1_5170_5230),
1406         },
1407
1408         {.regDmnEnum            = MKK2,
1409          .conformanceTestLimit  = MKK,
1410          .pscan                 = PSCAN_MKK2,
1411          .flags                 = DISALLOW_ADHOC_11A_TURB,
1412          .chan11a               = BM3(F1_4920_4980, F1_5040_5080, F1_5170_5230),
1413         .chan11a_half           = BM4(F1_4915_4925,
1414                                       F1_4935_4945,
1415                                       F1_5035_5040,
1416                                       F1_5055_5055),
1417         },
1418
1419         /* UNI-1 even */
1420         {.regDmnEnum            = MKK3,
1421          .conformanceTestLimit  = MKK,
1422          .pscan                 = PSCAN_MKK3,
1423          .flags                 = DISALLOW_ADHOC_11A_TURB,
1424          .chan11a               = BM1(F4_5180_5240),
1425         },
1426
1427         /* UNI-1 even + UNI-2 */
1428         {.regDmnEnum            = MKK4,
1429          .conformanceTestLimit  = MKK,
1430          .dfsMask               = DFS_MKK4,
1431          .pscan                 = PSCAN_MKK3,
1432          .flags                 = DISALLOW_ADHOC_11A_TURB,
1433          .chan11a               = BM2(F4_5180_5240, F2_5260_5320),
1434         },
1435
1436         /* UNI-1 even + UNI-2 + mid-band */
1437         {.regDmnEnum            = MKK5,
1438          .conformanceTestLimit  = MKK,
1439          .dfsMask               = DFS_MKK4,
1440          .pscan                 = PSCAN_MKK3,
1441          .flags                 = DISALLOW_ADHOC_11A_TURB,
1442          .chan11a               = BM3(F4_5180_5240, F2_5260_5320, F4_5500_5700),
1443         },
1444
1445         /* UNI-1 odd + even */
1446         {.regDmnEnum            = MKK6,
1447          .conformanceTestLimit  = MKK,
1448          .pscan                 = PSCAN_MKK1,
1449          .flags                 = DISALLOW_ADHOC_11A_TURB,
1450          .chan11a               = BM2(F2_5170_5230, F4_5180_5240),
1451         },
1452
1453         /* UNI-1 odd + UNI-1 even + UNI-2 */
1454         {.regDmnEnum            = MKK7,
1455          .conformanceTestLimit  = MKK,
1456          .dfsMask               = DFS_MKK4,
1457          .pscan                 = PSCAN_MKK1 | PSCAN_MKK3,
1458          .flags                 = DISALLOW_ADHOC_11A_TURB,
1459          .chan11a               = BM3(F1_5170_5230, F4_5180_5240, F2_5260_5320),
1460         },
1461
1462         /* UNI-1 odd + UNI-1 even + UNI-2 + mid-band */
1463         {.regDmnEnum            = MKK8,
1464          .conformanceTestLimit  = MKK,
1465          .dfsMask               = DFS_MKK4,
1466          .pscan                 = PSCAN_MKK1 | PSCAN_MKK3,
1467          .flags                 = DISALLOW_ADHOC_11A_TURB,
1468          .chan11a               = BM4(F1_5170_5230,
1469                                       F4_5180_5240,
1470                                       F2_5260_5320,
1471                                       F4_5500_5700),
1472         },
1473
1474         /* UNI-1 even + 4.9 GHZ */
1475         {.regDmnEnum            = MKK9,
1476          .conformanceTestLimit  = MKK,
1477          .pscan                 = PSCAN_MKK3,
1478          .flags                 = DISALLOW_ADHOC_11A_TURB,
1479          .chan11a               = BM7(F1_4915_4925,
1480                                       F1_4935_4945,
1481                                       F1_4920_4980,
1482                                       F1_5035_5040,
1483                                       F1_5055_5055,
1484                                       F1_5040_5080,
1485                                       F4_5180_5240),
1486         },
1487
1488         /* UNI-1 even + UNI-2 + 4.9 GHZ */
1489         {.regDmnEnum            = MKK10,
1490          .conformanceTestLimit  = MKK,
1491          .dfsMask               = DFS_MKK4,
1492          .pscan                 = PSCAN_MKK3,
1493          .flags                 = DISALLOW_ADHOC_11A_TURB,
1494          .chan11a               = BM8(F1_4915_4925,
1495                                       F1_4935_4945,
1496                                       F1_4920_4980,
1497                                       F1_5035_5040,
1498                                       F1_5055_5055,
1499                                       F1_5040_5080,
1500                                       F4_5180_5240,
1501                                       F2_5260_5320),
1502         },
1503
1504         /* Defined here to use when 2G channels are authorised for country K2 */
1505         {.regDmnEnum            = APLD,
1506          .conformanceTestLimit  = NO_CTL,
1507          .chan11b               = BM2(F2_2312_2372,F2_2412_2472),
1508          .chan11g               = BM2(G2_2312_2372,G2_2412_2472),
1509         },
1510
1511         {.regDmnEnum            = ETSIA,
1512          .conformanceTestLimit  = NO_CTL,
1513          .pscan                 = PSCAN_ETSIA,
1514          .flags                 = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1515          .chan11b               = BM1(F1_2457_2472),
1516          .chan11g               = BM1(G1_2457_2472),
1517          .chan11g_turbo         = BM1(T2_2437_2437)
1518         },
1519
1520         {.regDmnEnum            = ETSIB,
1521          .conformanceTestLimit  = ETSI,
1522          .pscan                 = PSCAN_ETSIB,
1523          .flags                 = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1524          .chan11b               = BM1(F1_2432_2442),
1525          .chan11g               = BM1(G1_2432_2442),
1526          .chan11g_turbo         = BM1(T2_2437_2437)
1527         },
1528
1529         {.regDmnEnum            = ETSIC,
1530          .conformanceTestLimit  = ETSI,
1531          .pscan                 = PSCAN_ETSIC,
1532          .flags                 = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1533          .chan11b               = BM1(F3_2412_2472),
1534          .chan11g               = BM1(G3_2412_2472),
1535          .chan11g_turbo         = BM1(T2_2437_2437)
1536         },
1537
1538         {.regDmnEnum            = FCCA,
1539          .conformanceTestLimit  = FCC,
1540          .chan11b               = BM1(F1_2412_2462),
1541          .chan11g               = BM1(G1_2412_2462),
1542          .chan11g_turbo         = BM1(T2_2437_2437),
1543         },
1544
1545         /* FCCA w/ 1/2 and 1/4 width channels */
1546         {.regDmnEnum            = FCCB,
1547          .conformanceTestLimit  = FCC,
1548          .chan11b               = BM1(F1_2412_2462),
1549          .chan11g               = BM1(G1_2412_2462),
1550          .chan11g_turbo         = BM1(T2_2437_2437),
1551          .chan11g_half          = BM1(G3_2412_2462),
1552          .chan11g_quarter       = BM1(G4_2412_2462),
1553         },
1554
1555         {.regDmnEnum            = MKKA,
1556          .conformanceTestLimit  = MKK,
1557          .pscan                 = PSCAN_MKKA | PSCAN_MKKA_G
1558                                 | PSCAN_MKKA1 | PSCAN_MKKA1_G
1559                                 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
1560          .flags                 = DISALLOW_ADHOC_11A_TURB,
1561          .chan11b               = BM3(F2_2412_2462, F1_2467_2472, F2_2484_2484),
1562          .chan11g               = BM2(G2_2412_2462, G1_2467_2472),
1563          .chan11g_turbo         = BM1(T2_2437_2437)
1564         },
1565
1566         {.regDmnEnum            = MKKC,
1567          .conformanceTestLimit  = MKK,
1568          .chan11b               = BM1(F2_2412_2472),
1569          .chan11g               = BM1(G2_2412_2472),
1570          .chan11g_turbo         = BM1(T2_2437_2437)
1571         },
1572
1573         {.regDmnEnum            = WORLD,
1574          .conformanceTestLimit  = ETSI,
1575          .chan11b               = BM1(F2_2412_2472),
1576          .chan11g               = BM1(G2_2412_2472),
1577          .chan11g_turbo         = BM1(T2_2437_2437)
1578         },
1579
1580         {.regDmnEnum            = WOR0_WORLD,
1581          .conformanceTestLimit  = NO_CTL,
1582          .dfsMask               = DFS_FCC3 | DFS_ETSI,
1583          .pscan                 = PSCAN_WWR,
1584          .flags                 = ADHOC_PER_11D,
1585          .chan11a               = BM5(W1_5260_5320,
1586                                       W1_5180_5240,
1587                                       W1_5170_5230,
1588                                       W1_5745_5825,
1589                                       W1_5500_5700),
1590          .chan11a_turbo         = BM3(WT1_5210_5250,
1591                                       WT1_5290_5290,
1592                                       WT1_5760_5800),
1593          .chan11b               = BM8(W1_2412_2412,
1594                                       W1_2437_2442,
1595                                       W1_2462_2462,
1596                                       W1_2472_2472,
1597                                       W1_2417_2432,
1598                                       W1_2447_2457,
1599                                       W1_2467_2467,
1600                                       W1_2484_2484),
1601          .chan11g               = BM7(WG1_2412_2412,
1602                                       WG1_2437_2442,
1603                                       WG1_2462_2462,
1604                                       WG1_2472_2472,
1605                                       WG1_2417_2432,
1606                                       WG1_2447_2457,
1607                                       WG1_2467_2467),
1608          .chan11g_turbo         = BM1(T3_2437_2437)
1609         },
1610
1611         {.regDmnEnum            = WOR01_WORLD,
1612          .conformanceTestLimit  = NO_CTL,
1613          .dfsMask               = DFS_FCC3 | DFS_ETSI,
1614          .pscan                 = PSCAN_WWR,
1615          .flags                 = ADHOC_PER_11D,
1616          .chan11a               = BM5(W1_5260_5320,
1617                                       W1_5180_5240,
1618                                       W1_5170_5230,
1619                                       W1_5745_5825,
1620                                       W1_5500_5700),
1621          .chan11a_turbo         = BM3(WT1_5210_5250,
1622                                       WT1_5290_5290,
1623                                       WT1_5760_5800),
1624          .chan11b               = BM5(W1_2412_2412,
1625                                       W1_2437_2442,
1626                                       W1_2462_2462,
1627                                       W1_2417_2432,
1628                                       W1_2447_2457),
1629          .chan11g               = BM5(WG1_2412_2412,
1630                                       WG1_2437_2442,
1631                                       WG1_2462_2462,
1632                                       WG1_2417_2432,
1633                                       WG1_2447_2457),
1634          .chan11g_turbo         = BM1(T3_2437_2437)},
1635
1636         {.regDmnEnum            = WOR02_WORLD,
1637          .conformanceTestLimit  = NO_CTL,
1638          .dfsMask               = DFS_FCC3 | DFS_ETSI,
1639          .pscan                 = PSCAN_WWR,
1640          .flags                 = ADHOC_PER_11D,
1641          .chan11a               = BM5(W1_5260_5320,
1642                                       W1_5180_5240,
1643                                       W1_5170_5230,
1644                                       W1_5745_5825,
1645                                       W1_5500_5700),
1646          .chan11a_turbo         = BM3(WT1_5210_5250,
1647                                       WT1_5290_5290,
1648                                       WT1_5760_5800),
1649          .chan11b               = BM7(W1_2412_2412,
1650                                       W1_2437_2442,
1651                                       W1_2462_2462,
1652                                       W1_2472_2472,
1653                                       W1_2417_2432,
1654                                       W1_2447_2457,
1655                                       W1_2467_2467),
1656          .chan11g               = BM7(WG1_2412_2412,
1657                                       WG1_2437_2442,
1658                                       WG1_2462_2462,
1659                                       WG1_2472_2472,
1660                                       WG1_2417_2432,
1661                                       WG1_2447_2457,
1662                                       WG1_2467_2467),
1663          .chan11g_turbo         = BM1(T3_2437_2437)},
1664
1665         {.regDmnEnum            = EU1_WORLD,
1666          .conformanceTestLimit  = NO_CTL,
1667          .dfsMask               = DFS_FCC3 | DFS_ETSI,
1668          .pscan                 = PSCAN_WWR,
1669          .flags                 = ADHOC_PER_11D,
1670          .chan11a               = BM5(W1_5260_5320,
1671                                       W1_5180_5240,
1672                                       W1_5170_5230,
1673                                       W1_5745_5825,
1674                                       W1_5500_5700),
1675          .chan11a_turbo         = BM3(WT1_5210_5250,
1676                                       WT1_5290_5290,
1677                                       WT1_5760_5800),
1678          .chan11b               = BM7(W1_2412_2412,
1679                                       W1_2437_2442,
1680                                       W1_2462_2462,
1681                                       W2_2472_2472,
1682                                       W1_2417_2432,
1683                                       W1_2447_2457,
1684                                       W2_2467_2467),
1685          .chan11g               = BM7(WG1_2412_2412,
1686                                       WG1_2437_2442,
1687                                       WG1_2462_2462,
1688                                       WG2_2472_2472,
1689                                       WG1_2417_2432,
1690                                       WG1_2447_2457,
1691                                       WG2_2467_2467),
1692          .chan11g_turbo         = BM1(T3_2437_2437)},
1693
1694         {.regDmnEnum            = WOR1_WORLD,
1695          .conformanceTestLimit  = NO_CTL,
1696          .dfsMask               = DFS_FCC3 | DFS_ETSI,
1697          .pscan                 = PSCAN_WWR,
1698          .flags                 = ADHOC_NO_11A,
1699          .chan11a               = BM5(W1_5260_5320,
1700                                       W1_5180_5240,
1701                                       W1_5170_5230,
1702                                       W1_5745_5825,
1703                                       W1_5500_5700),
1704          .chan11b               = BM8(W1_2412_2412,
1705                                       W1_2437_2442,
1706                                       W1_2462_2462,
1707                                       W1_2472_2472,
1708                                       W1_2417_2432,
1709                                       W1_2447_2457,
1710                                       W1_2467_2467,
1711                                       W1_2484_2484),
1712          .chan11g               = BM7(WG1_2412_2412,
1713                                       WG1_2437_2442,
1714                                       WG1_2462_2462,
1715                                       WG1_2472_2472,
1716                                       WG1_2417_2432,
1717                                       WG1_2447_2457,
1718                                       WG1_2467_2467),
1719          .chan11g_turbo         = BM1(T3_2437_2437)
1720         },
1721
1722         {.regDmnEnum            = WOR2_WORLD,
1723          .conformanceTestLimit  = NO_CTL,
1724          .dfsMask               = DFS_FCC3 | DFS_ETSI,
1725          .pscan                 = PSCAN_WWR,
1726          .flags                 = ADHOC_NO_11A,
1727          .chan11a               = BM5(W1_5260_5320,
1728                                       W1_5180_5240,
1729                                       W1_5170_5230,
1730                                       W1_5745_5825,
1731                                       W1_5500_5700),
1732          .chan11a_turbo         = BM3(WT1_5210_5250,
1733                                       WT1_5290_5290,
1734                                       WT1_5760_5800),
1735          .chan11b               = BM8(W1_2412_2412,
1736                                       W1_2437_2442,
1737                                       W1_2462_2462,
1738                                       W1_2472_2472,
1739                                       W1_2417_2432,
1740                                       W1_2447_2457,
1741                                       W1_2467_2467,
1742                                       W1_2484_2484),
1743          .chan11g               = BM7(WG1_2412_2412,
1744                                       WG1_2437_2442,
1745                                       WG1_2462_2462,
1746                                       WG1_2472_2472,
1747                                       WG1_2417_2432,
1748                                       WG1_2447_2457,
1749                                       WG1_2467_2467),
1750          .chan11g_turbo         = BM1(T3_2437_2437)},
1751
1752         {.regDmnEnum            = WOR3_WORLD,
1753          .conformanceTestLimit  = NO_CTL,
1754          .dfsMask               = DFS_FCC3 | DFS_ETSI,
1755          .pscan                 = PSCAN_WWR,
1756          .flags                 = ADHOC_PER_11D,
1757          .chan11a               = BM4(W1_5260_5320,
1758                                       W1_5180_5240,
1759                                       W1_5170_5230,
1760                                       W1_5745_5825),
1761          .chan11a_turbo         = BM3(WT1_5210_5250,
1762                                       WT1_5290_5290,
1763                                       WT1_5760_5800),
1764          .chan11b               = BM7(W1_2412_2412,
1765                                       W1_2437_2442,
1766                                       W1_2462_2462,
1767                                       W1_2472_2472,
1768                                       W1_2417_2432,
1769                                       W1_2447_2457,
1770                                       W1_2467_2467),
1771          .chan11g               = BM7(WG1_2412_2412,
1772                                       WG1_2437_2442,
1773                                       WG1_2462_2462,
1774                                       WG1_2472_2472,
1775                                       WG1_2417_2432,
1776                                       WG1_2447_2457,
1777                                       WG1_2467_2467),
1778          .chan11g_turbo         = BM1(T3_2437_2437)},
1779
1780         {.regDmnEnum            = WOR4_WORLD,
1781          .conformanceTestLimit  = NO_CTL,
1782          .dfsMask               = DFS_FCC3 | DFS_ETSI,
1783          .pscan                 = PSCAN_WWR,
1784          .flags                 = ADHOC_NO_11A,
1785          .chan11a               = BM4(W2_5260_5320,
1786                                       W2_5180_5240,
1787                                       F2_5745_5805,
1788                                       W2_5825_5825),
1789          .chan11a_turbo         = BM3(WT1_5210_5250,
1790                                       WT1_5290_5290,
1791                                       WT1_5760_5800),
1792          .chan11b               = BM5(W1_2412_2412,
1793                                       W1_2437_2442,
1794                                       W1_2462_2462,
1795                                       W1_2417_2432,
1796                                       W1_2447_2457),
1797          .chan11g               = BM5(WG1_2412_2412,
1798                                       WG1_2437_2442,
1799                                       WG1_2462_2462,
1800                                       WG1_2417_2432,
1801                                       WG1_2447_2457),
1802          .chan11g_turbo         = BM1(T3_2437_2437)},
1803
1804         {.regDmnEnum            = WOR5_ETSIC,
1805          .conformanceTestLimit  = NO_CTL,
1806          .dfsMask               = DFS_FCC3 | DFS_ETSI,
1807          .pscan                 = PSCAN_WWR,
1808          .flags                 = ADHOC_NO_11A,
1809          .chan11a               = BM3(W1_5260_5320, W2_5180_5240, F6_5745_5825),
1810          .chan11b               = BM7(W1_2412_2412,
1811                                       W1_2437_2442,
1812                                       W1_2462_2462,
1813                                       W2_2472_2472,
1814                                       W1_2417_2432,
1815                                       W1_2447_2457,
1816                                       W2_2467_2467),
1817          .chan11g               = BM7(WG1_2412_2412,
1818                                       WG1_2437_2442,
1819                                       WG1_2462_2462,
1820                                       WG2_2472_2472,
1821                                       WG1_2417_2432,
1822                                       WG1_2447_2457,
1823                                       WG2_2467_2467),
1824          .chan11g_turbo         = BM1(T3_2437_2437)},
1825
1826         {.regDmnEnum            = WOR9_WORLD,
1827          .conformanceTestLimit  = NO_CTL,
1828          .dfsMask               = DFS_FCC3 | DFS_ETSI,
1829          .pscan                 = PSCAN_WWR,
1830          .flags                 = ADHOC_NO_11A,
1831          .chan11a               = BM4(W1_5260_5320,
1832                                       W1_5180_5240,
1833                                       W1_5745_5825,
1834                                       W1_5500_5700),
1835          .chan11a_turbo         = BM3(WT1_5210_5250,
1836                                       WT1_5290_5290,
1837                                       WT1_5760_5800),
1838          .chan11b               = BM5(W1_2412_2412,
1839                                       W1_2437_2442,
1840                                       W1_2462_2462,
1841                                       W1_2417_2432,
1842                                       W1_2447_2457),
1843          .chan11g               = BM5(WG1_2412_2412,
1844                                       WG1_2437_2442,
1845                                       WG1_2462_2462,
1846                                       WG1_2417_2432,
1847                                       WG1_2447_2457),
1848          .chan11g_turbo         = BM1(T3_2437_2437)},
1849
1850         {.regDmnEnum            = WORA_WORLD,
1851          .conformanceTestLimit  = NO_CTL,
1852          .dfsMask               = DFS_FCC3 | DFS_ETSI,
1853          .pscan                 = PSCAN_WWR,
1854          .flags                 = ADHOC_NO_11A,
1855          .chan11a               = BM4(W1_5260_5320,
1856                                       W1_5180_5240,
1857                                       W1_5745_5825,
1858                                       W1_5500_5700),
1859          .chan11b               = BM7(W1_2412_2412,
1860                                       W1_2437_2442,
1861                                       W1_2462_2462,
1862                                       W1_2472_2472,
1863                                       W1_2417_2432,
1864                                       W1_2447_2457,
1865                                       W1_2467_2467),
1866          .chan11g               = BM7(WG1_2412_2412,
1867                                       WG1_2437_2442,
1868                                       WG1_2462_2462,
1869                                       WG1_2472_2472,
1870                                       WG1_2417_2432,
1871                                       WG1_2447_2457,
1872                                       WG1_2467_2467),
1873          .chan11g_turbo         = BM1(T3_2437_2437)},
1874
1875         {.regDmnEnum            = SR9_WORLD,
1876          .conformanceTestLimit  = NO_CTL,
1877          .pscan                 = PSCAN_FCC | PSCAN_FCC_T,
1878          .chan11g               = BM1(S1_912_917),
1879          .chan11g_half          = BM1(S1_907_922_10),
1880          .chan11g_quarter       = BM1(S1_907_922_5),
1881         },
1882
1883         {.regDmnEnum            = XR9_WORLD,
1884          .conformanceTestLimit  = NO_CTL,
1885          .pscan                 = PSCAN_FCC | PSCAN_FCC_T,
1886          .chan11g               = BM1(S2_912_917),
1887          .chan11g_half          = BM1(S2_907_922_10),
1888          .chan11g_quarter       = BM1(S2_907_922_5),
1889         },
1890
1891         {.regDmnEnum            = GZ901_WORLD,
1892          .conformanceTestLimit  = NO_CTL,
1893          .pscan                 = PSCAN_FCC | PSCAN_FCC_T,
1894          .chan11g               = BM1(S1_913_918),
1895          .chan11g_half          = BM1(S1_913_918_10),
1896          .chan11g_quarter       = BM1(S1_908_923_5),
1897         },
1898
1899         {.regDmnEnum            = NULL1,
1900          .conformanceTestLimit  = NO_CTL,
1901         }
1902 };
1903
1904 struct cmode {
1905         u_int   mode;
1906         u_int   flags;
1907 };
1908
1909 static const struct cmode modes[] = {
1910         { HAL_MODE_TURBO,       CHANNEL_ST},    /* NB: 11a Static Turbo */
1911         { HAL_MODE_11A,         CHANNEL_A},
1912         { HAL_MODE_11B,         CHANNEL_B},
1913         { HAL_MODE_11G,         CHANNEL_G},
1914         { HAL_MODE_11G_TURBO,   CHANNEL_108G},
1915         { HAL_MODE_11A_TURBO,   CHANNEL_108A},
1916         { HAL_MODE_11A_QUARTER_RATE,    CHANNEL_A | CHANNEL_QUARTER},
1917         { HAL_MODE_11A_HALF_RATE,       CHANNEL_A | CHANNEL_HALF},
1918         { HAL_MODE_11G_QUARTER_RATE,    CHANNEL_G | CHANNEL_QUARTER},
1919         { HAL_MODE_11G_HALF_RATE,       CHANNEL_G | CHANNEL_HALF},
1920         { HAL_MODE_11NG_HT20,   CHANNEL_G_HT20},
1921         { HAL_MODE_11NG_HT40PLUS,       CHANNEL_G_HT40PLUS},
1922         { HAL_MODE_11NG_HT40MINUS,      CHANNEL_G_HT40MINUS},
1923         { HAL_MODE_11NA_HT20,   CHANNEL_A_HT20},
1924         { HAL_MODE_11NA_HT40PLUS,       CHANNEL_A_HT40PLUS},
1925         { HAL_MODE_11NA_HT40MINUS,      CHANNEL_A_HT40MINUS},
1926 };
1927
1928 static int
1929 chansort(const void *a, const void *b)
1930 {
1931 #define CHAN_FLAGS      (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
1932         const HAL_CHANNEL_INTERNAL *ca = a;
1933         const HAL_CHANNEL_INTERNAL *cb = b;
1934
1935         return (ca->channel == cb->channel) ?
1936                 (ca->channelFlags & CHAN_FLAGS) -
1937                         (cb->channelFlags & CHAN_FLAGS) :
1938                 ca->channel - cb->channel;
1939 #undef CHAN_FLAGS
1940 }
1941 typedef int ath_hal_cmp_t(const void *, const void *);
1942 static  void ath_hal_sort(void *a, size_t n, size_t es, ath_hal_cmp_t *cmp);
1943 static COUNTRY_CODE_TO_ENUM_RD* findCountry(HAL_CTRY_CODE countryCode);
1944 static HAL_BOOL getWmRD(struct ath_hal *ah, COUNTRY_CODE_TO_ENUM_RD *country, uint16_t channelFlag, REG_DOMAIN *rd);
1945
1946
1947 static uint16_t
1948 getEepromRD(struct ath_hal *ah)
1949 {
1950         return AH_PRIVATE(ah)->ah_currentRD &~ WORLDWIDE_ROAMING_FLAG;
1951 }
1952
1953 /*
1954  * Test to see if the bitmask array is all zeros
1955  */
1956 static HAL_BOOL
1957 isChanBitMaskZero(const uint64_t *bitmask)
1958 {
1959 #if BMLEN > 2
1960 #error  "add more cases"
1961 #endif
1962 #if BMLEN > 1
1963         if (bitmask[1] != 0)
1964                 return AH_FALSE;
1965 #endif
1966         return (bitmask[0] == 0);
1967 }
1968
1969 /*
1970  * Return whether or not the regulatory domain/country in EEPROM
1971  * is acceptable.
1972  */
1973 static HAL_BOOL
1974 isEepromValid(struct ath_hal *ah)
1975 {
1976         uint16_t rd = getEepromRD(ah);
1977         int i;
1978
1979         if (rd & COUNTRY_ERD_FLAG) {
1980                 uint16_t cc = rd &~ COUNTRY_ERD_FLAG;
1981                 for (i = 0; i < N(allCountries); i++)
1982                         if (allCountries[i].countryCode == cc)
1983                                 return AH_TRUE;
1984         } else {
1985                 for (i = 0; i < N(regDomainPairs); i++)
1986                         if (regDomainPairs[i].regDmnEnum == rd)
1987                                 return AH_TRUE;
1988         }
1989         HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1990             "%s: invalid regulatory domain/country code 0x%x\n", __func__, rd);
1991         return AH_FALSE;
1992 }
1993
1994 /*
1995  * Returns whether or not the specified country code
1996  * is allowed by the EEPROM setting
1997  */
1998 static HAL_BOOL
1999 isCountryCodeValid(struct ath_hal *ah, HAL_CTRY_CODE cc)
2000 {
2001         uint16_t rd;
2002
2003         /* Default setting requires no checks */
2004         if (cc == CTRY_DEFAULT)
2005                 return AH_TRUE;
2006 #ifdef AH_DEBUG_COUNTRY
2007         if (cc == CTRY_DEBUG)
2008                 return AH_TRUE;
2009 #endif
2010         rd = getEepromRD(ah);
2011         HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: EEPROM regdomain 0x%x\n",
2012             __func__, rd);
2013
2014         if (rd & COUNTRY_ERD_FLAG) {
2015                 /* EEP setting is a country - config shall match */
2016                 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2017                     "%s: EEPROM setting is country code %u\n", __func__,
2018                     rd &~ COUNTRY_ERD_FLAG);
2019                 return (cc == (rd & ~COUNTRY_ERD_FLAG));
2020         } else if (rd == DEBUG_REG_DMN || rd == NO_ENUMRD) {
2021                 /* Set to Debug or AllowAnyCountry mode - allow any setting */
2022                 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: rd %d allowed\n",
2023                     __func__, rd);
2024                 return AH_TRUE;
2025 #ifdef AH_SUPPORT_11D
2026         } else  if ((rd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) {
2027                 int i;
2028                 for (i=0; i < N(allCountries); i++) {
2029                         if (cc == allCountries[i].countryCode)
2030                                 return AH_TRUE;
2031                 }
2032 #endif
2033         } else {
2034                 int i;
2035                 for (i = 0; i < N(allCountries); i++) {
2036                         if (cc == allCountries[i].countryCode &&
2037                             allCountries[i].regDmnEnum == rd)
2038                                 return AH_TRUE;
2039                 }
2040         }
2041         return AH_FALSE;
2042 }
2043
2044 /*
2045  * Return the mask of available modes based on the hardware
2046  * capabilities and the specified country code and reg domain.
2047  */
2048 static u_int
2049 ath_hal_getwmodesnreg(struct ath_hal *ah,
2050     const COUNTRY_CODE_TO_ENUM_RD *country, const REG_DOMAIN *rd5GHz)
2051 {
2052 #define HAL_MODE_11G_ALL \
2053         (HAL_MODE_11G | HAL_MODE_11G_TURBO | HAL_MODE_11G_QUARTER_RATE | \
2054          HAL_MODE_11G_HALF_RATE)
2055 #define HAL_MODE_11A_ALL \
2056         (HAL_MODE_11A | HAL_MODE_11A_TURBO | HAL_MODE_TURBO | \
2057          HAL_MODE_11A_QUARTER_RATE | HAL_MODE_11A_HALF_RATE)
2058         u_int modesAvail;
2059
2060         /* Get modes that HW is capable of */
2061         modesAvail = ath_hal_getWirelessModes(ah);
2062
2063         HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2064             "%s: wireless modes 0x%x cc %u rd %u\n",
2065             __func__, modesAvail, country->countryCode, country->regDmnEnum);
2066
2067         /* Check country regulations for allowed modes */
2068         if (!country->allow11g && (modesAvail & HAL_MODE_11G_ALL)) {
2069                 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2070                     "%s: disallow all 11g\n", __func__);
2071                 modesAvail &= ~HAL_MODE_11G_ALL;
2072         }
2073         if (isChanBitMaskZero(rd5GHz->chan11a) &&
2074             (modesAvail & HAL_MODE_11A_ALL)) {
2075                 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2076                     "%s: disallow all 11a\n", __func__);
2077                 modesAvail &= ~HAL_MODE_11A_ALL;
2078         }
2079         if ((modesAvail & (HAL_MODE_11A_TURBO | HAL_MODE_TURBO)) &&
2080             !country->allow11aTurbo) {
2081                 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2082                     "%s: disallow 11aTurbo\n", __func__);
2083                 modesAvail &= ~(HAL_MODE_11A_TURBO | HAL_MODE_TURBO);
2084         }
2085         if ((modesAvail & HAL_MODE_11G_TURBO) && !country->allow11gTurbo) {
2086                 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2087                     "%s: disallow 11gTurbo\n", __func__);
2088                 modesAvail &= ~HAL_MODE_11G_TURBO;
2089         }
2090
2091         /* Check 11n operation */
2092         if ((modesAvail & HAL_MODE_11NG_HT20) && !country->allow11ng20) {
2093                 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2094                     "%s: disallow 11g HT20\n", __func__);
2095                 modesAvail &= ~HAL_MODE_11NG_HT20;
2096         }
2097         if ((modesAvail & HAL_MODE_11NA_HT20) && !country->allow11na20) {
2098                 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2099                     "%s: disallow 11a HT20\n", __func__);
2100                 modesAvail &= ~HAL_MODE_11NA_HT20;
2101         }
2102         if ((modesAvail & HAL_MODE_11NG_HT40PLUS) && !country->allow11ng40) {
2103                 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2104                     "%s: disallow 11g HT40+\n", __func__);
2105                 modesAvail &= ~HAL_MODE_11NG_HT40PLUS;
2106         }
2107         if ((modesAvail & HAL_MODE_11NG_HT40MINUS) && !country->allow11ng40) {
2108                 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2109                     "%s: disallow 11g HT40-\n", __func__);
2110                 modesAvail &= ~HAL_MODE_11NG_HT40MINUS;
2111         }
2112         if ((modesAvail & HAL_MODE_11NA_HT40PLUS) && !country->allow11na40) {
2113                 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2114                     "%s: disallow 11a HT40+\n", __func__);
2115                 modesAvail &= ~HAL_MODE_11NA_HT40PLUS;
2116         }
2117         if ((modesAvail & HAL_MODE_11NA_HT40MINUS) && !country->allow11na40) {
2118                 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2119                     "%s: disallow 11a HT40-\n", __func__);
2120                 modesAvail &= ~HAL_MODE_11NA_HT40MINUS;
2121         }
2122
2123         return modesAvail;
2124 #undef HAL_MODE_11A_ALL
2125 #undef HAL_MODE_11G_ALL
2126 }
2127
2128 /*
2129  * Return the mask of available modes based on the hardware
2130  * capabilities and the specified country code.
2131  */
2132
2133 u_int
2134 ath_hal_getwirelessmodes(struct ath_hal *ah, HAL_CTRY_CODE cc)
2135 {
2136         COUNTRY_CODE_TO_ENUM_RD *country = AH_NULL;
2137         u_int mode = 0;
2138         REG_DOMAIN rd;
2139         
2140         country = findCountry(cc);
2141         if (country != AH_NULL) {
2142                 if (getWmRD(ah, country, ~CHANNEL_2GHZ, &rd))
2143                         mode = ath_hal_getwmodesnreg(ah, country, &rd);
2144         }
2145         return mode;
2146 }
2147
2148 /*
2149  * Return if device is public safety.
2150  */
2151 HAL_BOOL
2152 ath_hal_ispublicsafetysku(struct ath_hal *ah)
2153 {
2154         uint16_t rd = getEepromRD(ah);
2155
2156         switch (rd) {
2157         case FCC4_FCCA:
2158         case CTRY_UNITED_STATES_FCC49 | COUNTRY_ERD_FLAG:
2159                 return AH_TRUE;
2160         case DEBUG_REG_DMN:
2161         case NO_ENUMRD:
2162                 if (AH_PRIVATE(ah)->ah_countryCode == CTRY_UNITED_STATES_FCC49)
2163                         return AH_TRUE;
2164                 break;
2165         }
2166         return AH_FALSE;
2167 }
2168
2169 /*
2170  * Return if device is actually operating in 900 MHz band.
2171  */
2172 HAL_BOOL
2173 ath_hal_isgsmsku(struct ath_hal *ah)
2174 {
2175         uint16_t rd = getEepromRD(ah);
2176
2177         switch (rd) {
2178         case SR9_WORLD:
2179         case XR9_WORLD:
2180         case GZ901_WORLD:
2181         case CTRY_SR9 | COUNTRY_ERD_FLAG:
2182         case CTRY_XR9 | COUNTRY_ERD_FLAG:
2183         case CTRY_GZ901 | COUNTRY_ERD_FLAG:
2184                 return AH_TRUE;
2185         case DEBUG_REG_DMN:
2186         case NO_ENUMRD:
2187                 return AH_PRIVATE(ah)->ah_countryCode == CTRY_SR9
2188                        || AH_PRIVATE(ah)->ah_countryCode == CTRY_XR9
2189                        || AH_PRIVATE(ah)->ah_countryCode == CTRY_GZ901
2190                        ;
2191         }
2192         return AH_FALSE;
2193 }
2194
2195 /*
2196  * Find the pointer to the country element in the country table
2197  * corresponding to the country code
2198  */
2199 static COUNTRY_CODE_TO_ENUM_RD*
2200 findCountry(HAL_CTRY_CODE countryCode)
2201 {
2202         int i;
2203
2204         for (i = 0; i < N(allCountries); i++) {
2205                 if (allCountries[i].countryCode == countryCode)
2206                         return &allCountries[i];
2207         }
2208         return AH_NULL;         /* Not found */
2209 }
2210
2211 /*
2212  * Calculate a default country based on the EEPROM setting.
2213  */
2214 static HAL_CTRY_CODE
2215 getDefaultCountry(struct ath_hal *ah)
2216 {
2217         uint16_t rd;
2218         int i;
2219
2220         rd = getEepromRD(ah);
2221         if (rd & COUNTRY_ERD_FLAG) {
2222                 COUNTRY_CODE_TO_ENUM_RD *country = AH_NULL;
2223                 uint16_t cc = rd & ~COUNTRY_ERD_FLAG;
2224                 
2225                 country = findCountry(cc);
2226                 if (country != AH_NULL)
2227                         return cc;
2228         }
2229         /*
2230          * Check reg domains that have only one country
2231          */
2232         for (i = 0; i < N(regDomainPairs); i++)
2233                 if (regDomainPairs[i].regDmnEnum == rd) {
2234                         if (regDomainPairs[i].singleCC != 0)
2235                                 return regDomainPairs[i].singleCC;
2236                         else
2237                                 i = N(regDomainPairs);
2238                 }
2239         return CTRY_DEFAULT;
2240 }
2241
2242 static HAL_BOOL
2243 isValidRegDmn(int regDmn, REG_DOMAIN *rd)
2244 {
2245         int i;
2246
2247         for (i = 0; i < N(regDomains); i++) {
2248                 if (regDomains[i].regDmnEnum == regDmn) {
2249                         if (rd != AH_NULL) {
2250                                 OS_MEMCPY(rd, &regDomains[i],
2251                                           sizeof(REG_DOMAIN));
2252                         }
2253                         return AH_TRUE;
2254                 }
2255         }
2256         return AH_FALSE;
2257 }
2258
2259 static HAL_BOOL
2260 isValidRegDmnPair(int regDmnPair)
2261 {
2262         int i;
2263
2264         if (regDmnPair == NO_ENUMRD)
2265                 return AH_FALSE;
2266         for (i = 0; i < N(regDomainPairs); i++) {
2267                 if (regDomainPairs[i].regDmnEnum == regDmnPair)
2268                         return AH_TRUE;
2269         }
2270         return AH_FALSE;
2271 }
2272
2273 /*
2274  * Return the Wireless Mode Regulatory Domain based
2275  * on the country code and the wireless mode.
2276  */
2277 static HAL_BOOL
2278 getWmRD(struct ath_hal *ah, COUNTRY_CODE_TO_ENUM_RD *country,
2279         uint16_t channelFlag, REG_DOMAIN *rd)
2280 {
2281         int regDmn;
2282         REG_DMN_PAIR_MAPPING *regPair;
2283         uint64_t flags;
2284
2285         if (country->countryCode == CTRY_DEFAULT) {
2286                 uint16_t rdnum = getEepromRD(ah);
2287
2288                 if ((rdnum & COUNTRY_ERD_FLAG) == 0) {
2289                         if (isValidRegDmn(rdnum, AH_NULL) ||
2290                             isValidRegDmnPair(rdnum))
2291                                 regDmn = rdnum;
2292                         else
2293                                 regDmn = country->regDmnEnum;
2294                 } else
2295                         regDmn = country->regDmnEnum;
2296         } else
2297                 regDmn = country->regDmnEnum;
2298         regPair = AH_NULL;
2299         flags = NO_REQ;
2300         if ((regDmn & MULTI_DOMAIN_MASK) == 0) {
2301                 int i;
2302
2303                 for (i = 0; i < N(regDomainPairs); i++) {
2304                         if (regDomainPairs[i].regDmnEnum == regDmn) {
2305                                 regPair = &regDomainPairs[i];
2306                                 break;
2307                         }
2308                 }
2309                 if (regPair == AH_NULL) {
2310                         HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2311                             "%s: Failed to find reg domain pair %u\n",
2312                             __func__, regDmn);
2313                         return AH_FALSE;
2314                 }
2315                 if (channelFlag & CHANNEL_2GHZ) {
2316                         regDmn = regPair->regDmn2GHz;
2317                         flags = regPair->flags2GHz;
2318                 } else {
2319                         regDmn = regPair->regDmn5GHz;
2320                         flags = regPair->flags5GHz;
2321                 }
2322         }
2323
2324         /*
2325          * We either started with a unitary reg domain or we've found the 
2326          * unitary reg domain of the pair
2327          */
2328         if (isValidRegDmn(regDmn, rd)) {
2329                 if (regPair != AH_NULL)
2330                         rd->pscan &= regPair->pscanMask;
2331                 if ((country->regDmnEnum & MULTI_DOMAIN_MASK) == 0 &&
2332                     flags != NO_REQ)
2333                         rd->flags = flags;
2334                 return AH_TRUE;
2335         } else {
2336                 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2337                     "%s: Failed to find unitary reg domain %u\n", __func__,
2338                     country->regDmnEnum);
2339                 return AH_FALSE;
2340         }
2341 }
2342
2343 static HAL_BOOL
2344 IS_BIT_SET(int bit, const uint64_t bitmask[])
2345 {
2346         int byteOffset, bitnum;
2347         uint64_t val;
2348
2349         byteOffset = bit/64;
2350         bitnum = bit - byteOffset*64;
2351         val = ((uint64_t) 1) << bitnum;
2352         return (bitmask[byteOffset] & val) != 0;
2353 }
2354         
2355 /* Add given regclassid into regclassids array upto max of maxregids */
2356 static void
2357 ath_add_regclassid(uint8_t *regclassids, u_int maxregids,
2358         u_int *nregids, uint8_t regclassid)
2359 {
2360         int i;
2361
2362         /* Is regclassid valid? */
2363         if (regclassid == 0)
2364                 return;
2365
2366         for (i = 0; i < maxregids; i++) {
2367                 if (regclassids[i] == regclassid)       /* already present */
2368                         return;
2369                 if (regclassids[i] == 0) {              /* free slot */
2370                         regclassids[i] = regclassid;
2371                         (*nregids)++;
2372                         return;
2373                 }
2374         }
2375 }
2376
2377 /*
2378  * Setup the channel list based on the information in the EEPROM and
2379  * any supplied country code.  Note that we also do a bunch of EEPROM
2380  * verification here and setup certain regulatory-related access
2381  * control data used later on.
2382  */
2383
2384 HAL_BOOL
2385 ath_hal_init_channels(struct ath_hal *ah,
2386                       HAL_CHANNEL *chans, u_int maxchans, u_int *nchans,
2387                       uint8_t *regclassids, u_int maxregids, u_int *nregids,
2388                       HAL_CTRY_CODE cc, u_int modeSelect,
2389                       HAL_BOOL enableOutdoor, HAL_BOOL enableExtendedChannels)
2390 {
2391 #define CHANNEL_HALF_BW         10
2392 #define CHANNEL_QUARTER_BW      5
2393         u_int modesAvail;
2394         uint16_t maxChan;
2395         COUNTRY_CODE_TO_ENUM_RD *country = AH_NULL;
2396         REG_DOMAIN rd5GHz, rd2GHz;
2397         const struct cmode *cm;
2398         HAL_CHANNEL_INTERNAL *ichans = &AH_PRIVATE(ah)->ah_channels[0];
2399         int next, b;
2400         uint8_t ctl;
2401
2402         HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: cc %u mode 0x%x%s%s\n",
2403             __func__, cc, modeSelect, enableOutdoor? " Enable outdoor" : " ",
2404             enableExtendedChannels ? " Enable ecm" : "");
2405
2406         /*
2407          * Validate the EEPROM setting and setup defaults
2408          */
2409         if (!isEepromValid(ah)) {
2410                 /*
2411                  * Don't return any channels if the EEPROM has an
2412                  * invalid regulatory domain/country code setting.
2413                  */
2414                 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2415                     "%s: invalid EEPROM contents\n",__func__);
2416                 return AH_FALSE;
2417         }
2418
2419         AH_PRIVATE(ah)->ah_countryCode = getDefaultCountry(ah);
2420
2421 #ifndef AH_SUPPORT_11D
2422         if (AH_PRIVATE(ah)->ah_countryCode == CTRY_DEFAULT) {
2423 #endif
2424                 /* 
2425                  * We now have enough state to validate any country code
2426                  * passed in by the caller.
2427                  */
2428                 if (!isCountryCodeValid(ah, cc)) {
2429                         /* NB: Atheros silently ignores invalid country codes */
2430                         HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2431                             "%s: invalid country code %d\n", __func__, cc);
2432                         return AH_FALSE;
2433                 }
2434                 AH_PRIVATE(ah)->ah_countryCode = cc & COUNTRY_CODE_MASK;
2435 #ifndef AH_SUPPORT_11D
2436         }
2437 #endif
2438
2439         /* Get pointers to the country element and the reg domain elements */
2440         country = findCountry(AH_PRIVATE(ah)->ah_countryCode);
2441         
2442         if (country == AH_NULL) {
2443                 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "NULL Country!, cc= %d\n",
2444                     AH_PRIVATE(ah)->ah_countryCode);
2445                 return AH_FALSE;
2446         }
2447
2448         if (!getWmRD(ah, country, ~CHANNEL_2GHZ, &rd5GHz)) {
2449                 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2450                     "%s: no unitary 5GHz regdomain for country %u\n",
2451                      __func__, AH_PRIVATE(ah)->ah_countryCode);
2452                 return AH_FALSE;
2453         }
2454         if (!getWmRD(ah, country, CHANNEL_2GHZ, &rd2GHz)) {
2455                 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2456                     "%s: no unitary 2GHz regdomain for country %u\n",
2457                     __func__, AH_PRIVATE(ah)->ah_countryCode);
2458                 return AH_FALSE;
2459         }
2460
2461         modesAvail = ath_hal_getwmodesnreg(ah, country, &rd5GHz);
2462         maxChan = !enableOutdoor ? country->outdoorChanStart : 7000;
2463
2464         if (maxchans > N(AH_PRIVATE(ah)->ah_channels))
2465                 maxchans = N(AH_PRIVATE(ah)->ah_channels);
2466         next = 0;
2467         for (cm = modes; cm < &modes[N(modes)]; cm++) {
2468                 uint16_t c, c_hi, c_lo;
2469                 uint64_t *channelBM = AH_NULL;
2470                 REG_DOMAIN *rd = AH_NULL;
2471                 REG_DMN_FREQ_BAND *fband = AH_NULL,*freqs;
2472                 int low_adj, hi_adj, channelSep, lastc;
2473
2474                 if ((cm->mode & modeSelect) == 0) {
2475                         HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2476                             "%s: skip mode 0x%x flags 0x%x\n",
2477                             __func__, cm->mode, cm->flags);
2478                         continue;
2479                 }
2480                 if ((cm->mode & modesAvail) == 0) {
2481                         HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2482                             "%s: !avail mode 0x%x (0x%x) flags 0x%x\n",
2483                             __func__, modesAvail, cm->mode, cm->flags);
2484                         continue;
2485                 }
2486                 if (!ath_hal_getChannelEdges(ah, cm->flags, &c_lo, &c_hi)) {
2487                         /* channel not supported by hardware, skip it */
2488                         HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2489                             "%s: channels 0x%x not supported by hardware\n",
2490                             __func__,cm->flags);
2491                         continue;
2492                 }
2493                 switch (cm->mode) {
2494                 case HAL_MODE_TURBO:
2495                         rd = &rd5GHz;
2496                         channelBM = rd->chan11a_turbo;
2497                         freqs = &regDmn5GhzTurboFreq[0];
2498                         ctl = rd->conformanceTestLimit | CTL_TURBO;
2499                         break;
2500                 case HAL_MODE_11A:
2501                 case HAL_MODE_11A_HALF_RATE:
2502                 case HAL_MODE_11A_QUARTER_RATE:
2503                 case HAL_MODE_11NA_HT20:
2504                 case HAL_MODE_11NA_HT40PLUS:
2505                 case HAL_MODE_11NA_HT40MINUS:
2506                         rd = &rd5GHz;
2507                         if (cm->mode == HAL_MODE_11A_HALF_RATE)
2508                                 channelBM = rd->chan11a_half;
2509                         else if (cm->mode == HAL_MODE_11A_QUARTER_RATE)
2510                                 channelBM = rd->chan11a_quarter;
2511                         else
2512                                 channelBM = rd->chan11a;
2513                         freqs = &regDmn5GhzFreq[0];
2514                         ctl = rd->conformanceTestLimit;
2515                         break;
2516                 case HAL_MODE_11B:
2517                         rd = &rd2GHz;
2518                         channelBM = rd->chan11b;
2519                         freqs = &regDmn2GhzFreq[0];
2520                         ctl = rd->conformanceTestLimit | CTL_11B;
2521                         break;
2522                 case HAL_MODE_11G:
2523                 case HAL_MODE_11G_HALF_RATE:
2524                 case HAL_MODE_11G_QUARTER_RATE:
2525                 case HAL_MODE_11NG_HT20:
2526                 case HAL_MODE_11NG_HT40PLUS:
2527                 case HAL_MODE_11NG_HT40MINUS:
2528                         rd = &rd2GHz;
2529                         if (cm->mode == HAL_MODE_11G_HALF_RATE)
2530                                 channelBM = rd->chan11g_half;
2531                         else if (cm->mode == HAL_MODE_11G_QUARTER_RATE)
2532                                 channelBM = rd->chan11g_quarter;
2533                         else
2534                                 channelBM = rd->chan11g;
2535                         freqs = &regDmn2Ghz11gFreq[0];
2536                         ctl = rd->conformanceTestLimit | CTL_11G;
2537                         break;
2538                 case HAL_MODE_11G_TURBO:
2539                         rd = &rd2GHz;
2540                         channelBM = rd->chan11g_turbo;
2541                         freqs = &regDmn2Ghz11gTurboFreq[0];
2542                         ctl = rd->conformanceTestLimit | CTL_108G;
2543                         break;
2544                 case HAL_MODE_11A_TURBO:
2545                         rd = &rd5GHz;
2546                         channelBM = rd->chan11a_dyn_turbo;
2547                         freqs = &regDmn5GhzTurboFreq[0];
2548                         ctl = rd->conformanceTestLimit | CTL_108G;
2549                         break;
2550                 default:
2551                         HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2552                             "%s: Unkonwn HAL mode 0x%x\n", __func__, cm->mode);
2553                         continue;
2554                 }
2555                 if (isChanBitMaskZero(channelBM))
2556                         continue;
2557                 /*
2558                  * Setup special handling for HT40 channels; e.g.
2559                  * 5G HT40 channels require 40Mhz channel separation.
2560                  */
2561                 hi_adj = (cm->mode == HAL_MODE_11NA_HT40PLUS ||
2562                     cm->mode == HAL_MODE_11NG_HT40PLUS) ? -20 : 0;
2563                 low_adj = (cm->mode == HAL_MODE_11NA_HT40MINUS || 
2564                     cm->mode == HAL_MODE_11NG_HT40MINUS) ? 20 : 0;
2565                 channelSep = (cm->mode == HAL_MODE_11NA_HT40PLUS ||
2566                     cm->mode == HAL_MODE_11NA_HT40MINUS) ? 40 : 0;
2567
2568                 for (b = 0; b < 64*BMLEN; b++) {
2569                         if (!IS_BIT_SET(b, channelBM))
2570                                 continue;
2571                         fband = &freqs[b];
2572                         lastc = 0;
2573
2574                         ath_add_regclassid(regclassids, maxregids, 
2575                                         nregids, fband->regClassId);
2576
2577                         for (c = fband->lowChannel + low_adj;
2578                              c <= fband->highChannel + hi_adj;
2579                              c += fband->channelSep) {
2580                                 HAL_CHANNEL_INTERNAL icv;
2581                                 
2582                                 if (!(c_lo <= c && c <= c_hi)) {
2583                                         HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2584                                             "%s: c %u out of range [%u..%u]\n",
2585                                             __func__, c, c_lo, c_hi);
2586                                         continue;
2587                                 }
2588                                 if (((c+fband->channelSep)/2) > (maxChan+HALF_MAXCHANBW)) {
2589                                         HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2590                                             "%s: c %u > maxChan %u\n",
2591                                             __func__, c, maxChan);
2592                                         continue;
2593                                 }
2594                                 if (next >= maxchans){
2595                                         HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2596                                             "%s: too many channels for channel table\n",
2597                                             __func__);
2598                                         goto done;
2599                                 }
2600                                 if ((fband->usePassScan & IS_ECM_CHAN) &&
2601                                     !enableExtendedChannels) {
2602                                         HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2603                                             "Skipping ecm channel\n");
2604                                         continue;
2605                                 }
2606                                 /* XXX needs to be in ath_hal_checkchannel */
2607                                 if ((rd->flags & NO_HOSTAP) && 
2608                                     (AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP)) {
2609                                         HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2610                                             "Skipping HOSTAP channel\n");
2611                                         continue;
2612                                 }
2613                                 /*
2614                                  * Make sure that channel separation
2615                                  * meets the requirement.
2616                                  */
2617                                 if (lastc && channelSep &&
2618                                     (c-lastc) < channelSep)
2619                                         continue;
2620
2621                                 OS_MEMZERO(&icv, sizeof(icv));
2622                                 icv.channel = c;
2623                                 icv.channelFlags = cm->flags;
2624                                 icv.maxRegTxPower = fband->powerDfs;
2625                                 icv.antennaMax = fband->antennaMax;
2626                                 icv.regDmnFlags = rd->flags;
2627                                 icv.conformanceTestLimit = ctl;
2628                                 if (fband->usePassScan & rd->pscan)
2629                                         icv.channelFlags |= CHANNEL_PASSIVE;
2630                                 else
2631                                         icv.channelFlags &= ~CHANNEL_PASSIVE;
2632                                 lastc = c;
2633                                 if (fband->useDfs & rd->dfsMask) {
2634                                         /* DFS and HT40 don't mix */
2635                                         if (cm->mode == HAL_MODE_11NA_HT40PLUS ||
2636                                             cm->mode == HAL_MODE_11NA_HT40MINUS)
2637                                                 continue;
2638                                         icv.privFlags = CHANNEL_DFS;
2639                                 } else
2640                                         icv.privFlags = 0;
2641                                 if (rd->flags & LIMIT_FRAME_4MS)
2642                                         icv.privFlags |= CHANNEL_4MS_LIMIT;
2643
2644                                 ichans[next++] = icv;
2645                         }
2646                 }
2647         }
2648 done:
2649         if (next != 0) {
2650                 int i;
2651
2652                 /* XXX maxchans set above so this cannot happen? */
2653                 if (next > N(AH_PRIVATE(ah)->ah_channels)) {
2654                         HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2655                             "%s: too many channels %u; truncating to %u\n",
2656                             __func__, next,
2657                             (int) N(AH_PRIVATE(ah)->ah_channels));
2658                         next = N(AH_PRIVATE(ah)->ah_channels);
2659                 }
2660
2661                 /*
2662                  * Keep a private copy of the channel list so we can
2663                  * constrain future requests to only these channels
2664                  */
2665                 ath_hal_sort(ichans, next, sizeof(HAL_CHANNEL_INTERNAL),
2666                     chansort);
2667                 AH_PRIVATE(ah)->ah_nchan = next;
2668
2669                 /*
2670                  * Copy the channel list to the public channel list
2671                  */
2672                 for (i = 0; i < next; i++) {
2673                         chans[i].channel = ichans[i].channel;
2674                         chans[i].channelFlags = ichans[i].channelFlags;
2675                         chans[i].privFlags = ichans[i].privFlags;
2676                         chans[i].maxRegTxPower = ichans[i].maxRegTxPower;
2677                 }
2678                 /*
2679                  * Retrieve power limits.
2680                  */
2681                 ath_hal_getpowerlimits(ah, chans, next);
2682                 for (i = 0; i < next; i++) {
2683                         ichans[i].maxTxPower = chans[i].maxTxPower;
2684                         ichans[i].minTxPower = chans[i].minTxPower;
2685                 }
2686         }
2687         *nchans = next;
2688         /* XXX copy private setting to public area */
2689         ah->ah_countryCode = AH_PRIVATE(ah)->ah_countryCode;
2690         return (next != 0);
2691 #undef CHANNEL_HALF_BW
2692 #undef CHANNEL_QUARTER_BW
2693 }
2694
2695 /*
2696  * Return whether or not the specified channel is ok to use
2697  * based on the current regulatory domain constraints and 
2698  * DFS interference.
2699  */
2700 HAL_CHANNEL_INTERNAL *
2701 ath_hal_checkchannel(struct ath_hal *ah, const HAL_CHANNEL *c)
2702 {
2703 #define CHAN_FLAGS      (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
2704         HAL_CHANNEL_INTERNAL *base, *cc;
2705         /* NB: be wary of user-specified channel flags */
2706         int flags = c->channelFlags & CHAN_FLAGS;
2707         int n, lim, d;
2708
2709         /*
2710          * Check current channel to avoid the lookup.
2711          */
2712         cc = AH_PRIVATE(ah)->ah_curchan;
2713         if (cc != AH_NULL && cc->channel == c->channel &&
2714             (cc->channelFlags & CHAN_FLAGS) == flags) {
2715                 if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
2716                     (cc->channelFlags & CHANNEL_DFS))
2717                         return AH_NULL;
2718                 else
2719                         return cc;
2720         }
2721
2722         /* binary search based on known sorting order */
2723         base = AH_PRIVATE(ah)->ah_channels;
2724         n = AH_PRIVATE(ah)->ah_nchan;
2725         /* binary search based on known sorting order */
2726         for (lim = n; lim != 0; lim >>= 1) {
2727                 cc = &base[lim>>1];
2728                 d = c->channel - cc->channel;
2729                 if (d == 0) {
2730                         if ((cc->channelFlags & CHAN_FLAGS) == flags) {
2731                                 if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
2732                                     (cc->channelFlags & CHANNEL_DFS))
2733                                         return AH_NULL;
2734                                 else
2735                                         return cc;
2736                         }
2737                         d = flags - (cc->channelFlags & CHAN_FLAGS);
2738                 }
2739                 if (d > 0) {
2740                         base = cc + 1;
2741                         lim--;
2742                 }
2743         }
2744         HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: no match for %u/0x%x\n",
2745            __func__, c->channel, c->channelFlags);
2746         return AH_NULL;
2747 #undef CHAN_FLAGS
2748 }
2749
2750 /*
2751  * Return the max allowed antenna gain and apply any regulatory
2752  * domain specific changes.
2753  *
2754  * NOTE: a negative reduction is possible in RD's that only
2755  * measure radiated power (e.g., ETSI) which would increase
2756  * that actual conducted output power (though never beyond
2757  * the calibrated target power).
2758  */
2759 u_int
2760 ath_hal_getantennareduction(struct ath_hal *ah, HAL_CHANNEL *chan, u_int twiceGain)
2761 {
2762         HAL_CHANNEL_INTERNAL *ichan=AH_NULL;
2763         int8_t antennaMax;
2764
2765         if ((ichan = ath_hal_checkchannel(ah, chan)) != AH_NULL) {
2766                 antennaMax = twiceGain - ichan->antennaMax*2;
2767                 return (antennaMax < 0) ? 0 : antennaMax;
2768         } else {
2769                 /* Failed to find the correct index - may be a debug channel */
2770                 return 0;
2771         }
2772 }
2773
2774
2775 /* XXX - maybe move ctl decision into channel set area or
2776  into the tables so no decision is needed in the code */
2777
2778 #define isWwrSKU(_ah) \
2779         ((getEepromRD((_ah)) & WORLD_SKU_MASK) == WORLD_SKU_PREFIX || \
2780           getEepromRD(_ah) == WORLD)
2781
2782
2783 /*
2784  * Return the test group from the specified channel from
2785  * the regulatory table.
2786  *
2787  * TODO: CTL for 11B CommonMode when regulatory domain is unknown
2788  */
2789 u_int
2790 ath_hal_getctl(struct ath_hal *ah, HAL_CHANNEL *chan)
2791 {
2792         u_int ctl = NO_CTL;
2793         HAL_CHANNEL_INTERNAL *ichan;
2794
2795         /* Special CTL to signify WWR SKU without a known country */
2796         if (AH_PRIVATE(ah)->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)) {
2797                 if (IS_CHAN_B(chan)) {
2798                         ctl = SD_NO_CTL | CTL_11B;
2799                 } else if (IS_CHAN_G(chan)) {
2800                         ctl = SD_NO_CTL | CTL_11G;
2801                 } else if (IS_CHAN_108G(chan)) {
2802                         ctl = SD_NO_CTL | CTL_108G;
2803                 } else if (IS_CHAN_T(chan)) {
2804                         ctl = SD_NO_CTL | CTL_TURBO;
2805                 } else {
2806                         ctl = SD_NO_CTL | CTL_11A;
2807                 }
2808         } else {
2809                 if ((ichan = ath_hal_checkchannel(ah, chan)) != AH_NULL) {
2810                         ctl = ichan->conformanceTestLimit;
2811                         /* limit 11G OFDM power */
2812                         if (IS_CHAN_PUREG(chan) &&
2813                             (ctl & CTL_MODE_M) == CTL_11B)
2814                                 ctl = (ctl &~ CTL_MODE_M) | CTL_11G;
2815                 }
2816         }
2817         return ctl;
2818 }
2819
2820 /*
2821  * Return whether or not a noise floor check is required in
2822  * the current regulatory domain for the specified channel.
2823  */
2824 HAL_BOOL
2825 ath_hal_getnfcheckrequired(struct ath_hal *ah, HAL_CHANNEL *chan)
2826 {
2827         HAL_CHANNEL_INTERNAL *ichan;
2828
2829         if ((ichan = ath_hal_checkchannel(ah, chan)) != AH_NULL)
2830                 return ((ichan->regDmnFlags & NEED_NFC) ? AH_TRUE : AH_FALSE);
2831         return AH_FALSE;
2832 }
2833
2834 /*
2835  * Insertion sort.
2836  */
2837 #define swap(_a, _b, _size) {                   \
2838         uint8_t *s = _b;                        \
2839         int i = _size;                          \
2840         do {                                    \
2841                 uint8_t tmp = *_a;              \
2842                 *_a++ = *s;                     \
2843                 *s++ = tmp;                     \
2844         } while (--i);                          \
2845         _a -= _size;                            \
2846 }
2847
2848 static void
2849 ath_hal_sort(void *a, size_t n, size_t size, ath_hal_cmp_t *cmp)
2850 {
2851         uint8_t *aa = a;
2852         uint8_t *ai, *t;
2853
2854         for (ai = aa+size; --n >= 1; ai += size)
2855                 for (t = ai; t > aa; t -= size) {
2856                         uint8_t *u = t - size;
2857                         if (cmp(u, t) <= 0)
2858                                 break;
2859                         swap(u, t, size);
2860                 }
2861 }