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.2 2008/12/11 05:30:29 alc 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, 0 },
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
chansort(const void * a,const void * b)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
getEepromRD(struct ath_hal * ah)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
isChanBitMaskZero(const uint64_t * bitmask)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
isEepromValid(struct ath_hal * ah)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
isCountryCodeValid(struct ath_hal * ah,HAL_CTRY_CODE cc)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
ath_hal_getwmodesnreg(struct ath_hal * ah,const COUNTRY_CODE_TO_ENUM_RD * country,const REG_DOMAIN * rd5GHz)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
ath_hal_getwirelessmodes(struct ath_hal * ah,HAL_CTRY_CODE cc)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
ath_hal_ispublicsafetysku(struct ath_hal * ah)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
ath_hal_isgsmsku(struct ath_hal * ah)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*
findCountry(HAL_CTRY_CODE countryCode)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
getDefaultCountry(struct ath_hal * ah)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
isValidRegDmn(int regDmn,REG_DOMAIN * rd)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, ®Domains[i],
2251 sizeof(REG_DOMAIN));
2252 }
2253 return AH_TRUE;
2254 }
2255 }
2256 return AH_FALSE;
2257 }
2258
2259 static HAL_BOOL
isValidRegDmnPair(int regDmnPair)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
getWmRD(struct ath_hal * ah,COUNTRY_CODE_TO_ENUM_RD * country,uint16_t channelFlag,REG_DOMAIN * rd)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 = ®DomainPairs[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
IS_BIT_SET(int bit,const uint64_t bitmask[])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
ath_add_regclassid(uint8_t * regclassids,u_int maxregids,u_int * nregids,uint8_t regclassid)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
ath_hal_init_channels(struct ath_hal * ah,HAL_CHANNEL * chans,u_int maxchans,u_int * nchans,uint8_t * regclassids,u_int maxregids,u_int * nregids,HAL_CTRY_CODE cc,u_int modeSelect,HAL_BOOL enableOutdoor,HAL_BOOL enableExtendedChannels)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 = ®Dmn5GhzTurboFreq[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 = ®Dmn5GhzFreq[0];
2514 ctl = rd->conformanceTestLimit;
2515 break;
2516 case HAL_MODE_11B:
2517 rd = &rd2GHz;
2518 channelBM = rd->chan11b;
2519 freqs = ®Dmn2GhzFreq[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 = ®Dmn2Ghz11gFreq[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 = ®Dmn2Ghz11gTurboFreq[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 = ®Dmn5GhzTurboFreq[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 *
ath_hal_checkchannel(struct ath_hal * ah,const HAL_CHANNEL * c)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
ath_hal_getantennareduction(struct ath_hal * ah,HAL_CHANNEL * chan,u_int twiceGain)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
ath_hal_getctl(struct ath_hal * ah,HAL_CHANNEL * chan)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
ath_hal_getnfcheckrequired(struct ath_hal * ah,HAL_CHANNEL * chan)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
ath_hal_sort(void * a,size_t n,size_t size,ath_hal_cmp_t * cmp)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 }
2862