revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / networks / atheros5000 / hal / ah_regdomain.c
bloba593eb753c07d0c79605113999a6ccb645e7d234
1 /*
2 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
3 * Copyright (c) 2005-2006 Atheros Communications, Inc.
4 * All rights reserved.
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 * $Id$
20 #include "opt_ah.h"
22 #include "ah.h"
23 #include "ah_internal.h"
24 #include "ah_eeprom.h"
25 #include "ah_devid.h"
28 * XXX this code needs a audit+review
31 /* used throughout this file... */
32 #define N(a) (sizeof (a) / sizeof (a[0]))
34 #define HAL_MODE_11A_TURBO HAL_MODE_108A
35 #define HAL_MODE_11G_TURBO HAL_MODE_108G
37 /* 10MHz is half the 11A bandwidth used to determine upper edge freq
38 of the outdoor channel */
39 #define HALF_MAXCHANBW 10
41 /*
42 * Used to set the RegDomain bitmask which chooses which frequency
43 * band specs are used.
46 #define BMLEN 2 /* Use 2 64 bit uint for channel bitmask
47 NB: Must agree with macro below (BM) */
48 #define BMZERO {(uint64_t) 0, (uint64_t) 0} /* BMLEN zeros */
50 #define BM(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh, _fi, _fj, _fk, _fl) \
51 {((((_fa >= 0) && (_fa < 64)) ? (((uint64_t) 1) << _fa) : (uint64_t) 0) | \
52 (((_fb >= 0) && (_fb < 64)) ? (((uint64_t) 1) << _fb) : (uint64_t) 0) | \
53 (((_fc >= 0) && (_fc < 64)) ? (((uint64_t) 1) << _fc) : (uint64_t) 0) | \
54 (((_fd >= 0) && (_fd < 64)) ? (((uint64_t) 1) << _fd) : (uint64_t) 0) | \
55 (((_fe >= 0) && (_fe < 64)) ? (((uint64_t) 1) << _fe) : (uint64_t) 0) | \
56 (((_ff >= 0) && (_ff < 64)) ? (((uint64_t) 1) << _ff) : (uint64_t) 0) | \
57 (((_fg >= 0) && (_fg < 64)) ? (((uint64_t) 1) << _fg) : (uint64_t) 0) | \
58 (((_fh >= 0) && (_fh < 64)) ? (((uint64_t) 1) << _fh) : (uint64_t) 0) | \
59 (((_fi >= 0) && (_fi < 64)) ? (((uint64_t) 1) << _fi) : (uint64_t) 0) | \
60 (((_fj >= 0) && (_fj < 64)) ? (((uint64_t) 1) << _fj) : (uint64_t) 0) | \
61 (((_fk >= 0) && (_fk < 64)) ? (((uint64_t) 1) << _fk) : (uint64_t) 0) | \
62 (((_fl >= 0) && (_fl < 64)) ? (((uint64_t) 1) << _fl) : (uint64_t) 0) | \
63 ((((_fa > 63) && (_fa < 128)) ? (((uint64_t) 1) << (_fa - 64)) : (uint64_t) 0) | \
64 (((_fb > 63) && (_fb < 128)) ? (((uint64_t) 1) << (_fb - 64)) : (uint64_t) 0) | \
65 (((_fc > 63) && (_fc < 128)) ? (((uint64_t) 1) << (_fc - 64)) : (uint64_t) 0) | \
66 (((_fd > 63) && (_fd < 128)) ? (((uint64_t) 1) << (_fd - 64)) : (uint64_t) 0) | \
67 (((_fe > 63) && (_fe < 128)) ? (((uint64_t) 1) << (_fe - 64)) : (uint64_t) 0) | \
68 (((_ff > 63) && (_ff < 128)) ? (((uint64_t) 1) << (_ff - 64)) : (uint64_t) 0) | \
69 (((_fg > 63) && (_fg < 128)) ? (((uint64_t) 1) << (_fg - 64)) : (uint64_t) 0) | \
70 (((_fh > 63) && (_fh < 128)) ? (((uint64_t) 1) << (_fh - 64)) : (uint64_t) 0) | \
71 (((_fi > 63) && (_fi < 128)) ? (((uint64_t) 1) << (_fi - 64)) : (uint64_t) 0) | \
72 (((_fj > 63) && (_fj < 128)) ? (((uint64_t) 1) << (_fj - 64)) : (uint64_t) 0) | \
73 (((_fk > 63) && (_fk < 128)) ? (((uint64_t) 1) << (_fk - 64)) : (uint64_t) 0) | \
74 (((_fl > 63) && (_fl < 128)) ? (((uint64_t) 1) << (_fl - 64)) : (uint64_t) 0)))}
77 * Country/Region Codes
78 * Numbering from ISO 3166
80 enum CountryCode {
81 CTRY_ALBANIA = 8, /* Albania */
82 CTRY_ALGERIA = 12, /* Algeria */
83 CTRY_ARGENTINA = 32, /* Argentina */
84 CTRY_ARMENIA = 51, /* Armenia */
85 CTRY_AUSTRALIA = 36, /* Australia */
86 CTRY_AUSTRIA = 40, /* Austria */
87 CTRY_AZERBAIJAN = 31, /* Azerbaijan */
88 CTRY_BAHRAIN = 48, /* Bahrain */
89 CTRY_BELARUS = 112, /* Belarus */
90 CTRY_BELGIUM = 56, /* Belgium */
91 CTRY_BELIZE = 84, /* Belize */
92 CTRY_BOLIVIA = 68, /* Bolivia */
93 CTRY_BRAZIL = 76, /* Brazil */
94 CTRY_BRUNEI_DARUSSALAM = 96, /* Brunei Darussalam */
95 CTRY_BULGARIA = 100, /* Bulgaria */
96 CTRY_CANADA = 124, /* Canada */
97 CTRY_CHILE = 152, /* Chile */
98 CTRY_CHINA = 156, /* People's Republic of China */
99 CTRY_COLOMBIA = 170, /* Colombia */
100 CTRY_COSTA_RICA = 188, /* Costa Rica */
101 CTRY_CROATIA = 191, /* Croatia */
102 CTRY_CYPRUS = 196,
103 CTRY_CZECH = 203, /* Czech Republic */
104 CTRY_DENMARK = 208, /* Denmark */
105 CTRY_DOMINICAN_REPUBLIC = 214, /* Dominican Republic */
106 CTRY_ECUADOR = 218, /* Ecuador */
107 CTRY_EGYPT = 818, /* Egypt */
108 CTRY_EL_SALVADOR = 222, /* El Salvador */
109 CTRY_ESTONIA = 233, /* Estonia */
110 CTRY_FAEROE_ISLANDS = 234, /* Faeroe Islands */
111 CTRY_FINLAND = 246, /* Finland */
112 CTRY_FRANCE = 250, /* France */
113 CTRY_FRANCE2 = 255, /* France2 */
114 CTRY_GEORGIA = 268, /* Georgia */
115 CTRY_GERMANY = 276, /* Germany */
116 CTRY_GREECE = 300, /* Greece */
117 CTRY_GUATEMALA = 320, /* Guatemala */
118 CTRY_HONDURAS = 340, /* Honduras */
119 CTRY_HONG_KONG = 344, /* Hong Kong S.A.R., P.R.C. */
120 CTRY_HUNGARY = 348, /* Hungary */
121 CTRY_ICELAND = 352, /* Iceland */
122 CTRY_INDIA = 356, /* India */
123 CTRY_INDONESIA = 360, /* Indonesia */
124 CTRY_IRAN = 364, /* Iran */
125 CTRY_IRAQ = 368, /* Iraq */
126 CTRY_IRELAND = 372, /* Ireland */
127 CTRY_ISRAEL = 376, /* Israel */
128 CTRY_ITALY = 380, /* Italy */
129 CTRY_JAMAICA = 388, /* Jamaica */
130 CTRY_JAPAN = 392, /* Japan */
131 CTRY_JAPAN1 = 393, /* Japan (JP1) */
132 CTRY_JAPAN2 = 394, /* Japan (JP0) */
133 CTRY_JAPAN3 = 395, /* Japan (JP1-1) */
134 CTRY_JAPAN4 = 396, /* Japan (JE1) */
135 CTRY_JAPAN5 = 397, /* Japan (JE2) */
136 CTRY_JAPAN6 = 399, /* Japan (JP6) */
138 CTRY_JAPAN7 = 4007, /* Japan (J7) */
139 CTRY_JAPAN8 = 4008, /* Japan (J8) */
140 CTRY_JAPAN9 = 4009, /* Japan (J9) */
142 CTRY_JAPAN10 = 4010, /* Japan (J10) */
143 CTRY_JAPAN11 = 4011, /* Japan (J11) */
144 CTRY_JAPAN12 = 4012, /* Japan (J12) */
146 CTRY_JAPAN13 = 4013, /* Japan (J13) */
147 CTRY_JAPAN14 = 4014, /* Japan (J14) */
148 CTRY_JAPAN15 = 4015, /* Japan (J15) */
150 CTRY_JAPAN16 = 4016, /* Japan (J16) */
151 CTRY_JAPAN17 = 4017, /* Japan (J17) */
152 CTRY_JAPAN18 = 4018, /* Japan (J18) */
154 CTRY_JAPAN19 = 4019, /* Japan (J19) */
155 CTRY_JAPAN20 = 4020, /* Japan (J20) */
156 CTRY_JAPAN21 = 4021, /* Japan (J21) */
158 CTRY_JAPAN22 = 4022, /* Japan (J22) */
159 CTRY_JAPAN23 = 4023, /* Japan (J23) */
160 CTRY_JAPAN24 = 4024, /* Japan (J24) */
162 CTRY_JORDAN = 400, /* Jordan */
163 CTRY_KAZAKHSTAN = 398, /* Kazakhstan */
164 CTRY_KENYA = 404, /* Kenya */
165 CTRY_KOREA_NORTH = 408, /* North Korea */
166 CTRY_KOREA_ROC = 410, /* South Korea */
167 CTRY_KOREA_ROC2 = 411, /* South Korea */
168 CTRY_KOREA_ROC3 = 412, /* South Korea */
169 CTRY_KUWAIT = 414, /* Kuwait */
170 CTRY_LATVIA = 428, /* Latvia */
171 CTRY_LEBANON = 422, /* Lebanon */
172 CTRY_LIBYA = 434, /* Libya */
173 CTRY_LIECHTENSTEIN = 438, /* Liechtenstein */
174 CTRY_LITHUANIA = 440, /* Lithuania */
175 CTRY_LUXEMBOURG = 442, /* Luxembourg */
176 CTRY_MACAU = 446, /* Macau */
177 CTRY_MACEDONIA = 807, /* the Former Yugoslav Republic of Macedonia */
178 CTRY_MALAYSIA = 458, /* Malaysia */
179 CTRY_MALTA = 470, /* Malta */
180 CTRY_MEXICO = 484, /* Mexico */
181 CTRY_MONACO = 492, /* Principality of Monaco */
182 CTRY_MOROCCO = 504, /* Morocco */
183 CTRY_NETHERLANDS = 528, /* Netherlands */
184 CTRY_NEW_ZEALAND = 554, /* New Zealand */
185 CTRY_NICARAGUA = 558, /* Nicaragua */
186 CTRY_NORWAY = 578, /* Norway */
187 CTRY_OMAN = 512, /* Oman */
188 CTRY_PAKISTAN = 586, /* Islamic Republic of Pakistan */
189 CTRY_PANAMA = 591, /* Panama */
190 CTRY_PARAGUAY = 600, /* Paraguay */
191 CTRY_PERU = 604, /* Peru */
192 CTRY_PHILIPPINES = 608, /* Republic of the Philippines */
193 CTRY_POLAND = 616, /* Poland */
194 CTRY_PORTUGAL = 620, /* Portugal */
195 CTRY_PUERTO_RICO = 630, /* Puerto Rico */
196 CTRY_QATAR = 634, /* Qatar */
197 CTRY_ROMANIA = 642, /* Romania */
198 CTRY_RUSSIA = 643, /* Russia */
199 CTRY_SAUDI_ARABIA = 682, /* Saudi Arabia */
200 CTRY_SINGAPORE = 702, /* Singapore */
201 CTRY_SLOVAKIA = 703, /* Slovak Republic */
202 CTRY_SLOVENIA = 705, /* Slovenia */
203 CTRY_SOUTH_AFRICA = 710, /* South Africa */
204 CTRY_SPAIN = 724, /* Spain */
205 CTRY_SWEDEN = 752, /* Sweden */
206 CTRY_SWITZERLAND = 756, /* Switzerland */
207 CTRY_SYRIA = 760, /* Syria */
208 CTRY_TAIWAN = 158, /* Taiwan */
209 CTRY_THAILAND = 764, /* Thailand */
210 CTRY_TRINIDAD_Y_TOBAGO = 780, /* Trinidad y Tobago */
211 CTRY_TUNISIA = 788, /* Tunisia */
212 CTRY_TURKEY = 792, /* Turkey */
213 CTRY_UAE = 784, /* U.A.E. */
214 CTRY_UKRAINE = 804, /* Ukraine */
215 CTRY_UNITED_KINGDOM = 826, /* United Kingdom */
216 CTRY_UNITED_STATES = 840, /* United States */
217 CTRY_UNITED_STATES_FCC49 = 842, /* United States (Public Safety)*/
218 CTRY_URUGUAY = 858, /* Uruguay */
219 CTRY_UZBEKISTAN = 860, /* Uzbekistan */
220 CTRY_VENEZUELA = 862, /* Venezuela */
221 CTRY_VIET_NAM = 704, /* Viet Nam */
222 CTRY_YEMEN = 887, /* Yemen */
223 CTRY_ZIMBABWE = 716 /* Zimbabwe */
227 /* Mask to check whether a domain is a multidomain or a single
228 domain */
230 #define MULTI_DOMAIN_MASK 0xFF00
232 /* Enumerated Regulatory Domain Information 8 bit values indicate that
233 * the regdomain is really a pair of unitary regdomains. 12 bit values
234 * are the real unitary regdomains and are the only ones which have the
235 * frequency bitmasks and flags set.
238 enum EnumRd {
240 * The following regulatory domain definitions are
241 * found in the EEPROM. Each regulatory domain
242 * can operate in either a 5GHz or 2.4GHz wireless mode or
243 * both 5GHz and 2.4GHz wireless modes.
244 * In general, the value holds no special
245 * meaning and is used to decode into either specific
246 * 2.4GHz or 5GHz wireless mode for that particular
247 * regulatory domain.
249 NO_ENUMRD = 0x00,
250 NULL1_WORLD = 0x03, /* For 11b-only countries (no 11a allowed) */
251 NULL1_ETSIB = 0x07, /* Israel */
252 NULL1_ETSIC = 0x08,
253 FCC1_FCCA = 0x10, /* USA */
254 FCC1_WORLD = 0x11, /* Hong Kong */
255 FCC4_FCCA = 0x12, /* USA - Public Safety */
257 FCC2_FCCA = 0x20, /* Canada */
258 FCC2_WORLD = 0x21, /* Australia & HK */
259 FCC2_ETSIC = 0x22,
260 FRANCE_RES = 0x31, /* Legacy France for OEM */
261 FCC3_FCCA = 0x3A, /* USA & Canada w/5470 band, 11h, DFS enabled */
262 FCC3_WORLD = 0x3B, /* USA & Canada w/5470 band, 11h, DFS enabled */
264 ETSI1_WORLD = 0x37,
265 ETSI3_ETSIA = 0x32, /* France (optional) */
266 ETSI2_WORLD = 0x35, /* Hungary & others */
267 ETSI3_WORLD = 0x36, /* France & others */
268 ETSI4_WORLD = 0x30,
269 ETSI4_ETSIC = 0x38,
270 ETSI5_WORLD = 0x39,
271 ETSI6_WORLD = 0x34, /* Bulgaria */
272 ETSI_RESERVED = 0x33, /* Reserved (Do not used) */
274 MKK1_MKKA = 0x40, /* Japan (JP1) */
275 MKK1_MKKB = 0x41, /* Japan (JP0) */
276 APL4_WORLD = 0x42, /* Singapore */
277 MKK2_MKKA = 0x43, /* Japan with 4.9G channels */
278 APL_RESERVED = 0x44, /* Reserved (Do not used) */
279 APL2_WORLD = 0x45, /* Korea */
280 APL2_APLC = 0x46,
281 APL3_WORLD = 0x47,
282 MKK1_FCCA = 0x48, /* Japan (JP1-1) */
283 APL2_APLD = 0x49, /* Korea with 2.3G channels */
284 MKK1_MKKA1 = 0x4A, /* Japan (JE1) */
285 MKK1_MKKA2 = 0x4B, /* Japan (JE2) */
286 MKK1_MKKC = 0x4C, /* Japan (MKK1_MKKA,except Ch14) */
288 APL3_FCCA = 0x50,
289 APL1_WORLD = 0x52, /* Latin America */
290 APL1_FCCA = 0x53,
291 APL1_APLA = 0x54,
292 APL1_ETSIC = 0x55,
293 APL2_ETSIC = 0x56, /* Venezuela */
294 APL5_WORLD = 0x58, /* Chile */
295 APL6_WORLD = 0x5B, /* Singapore */
296 APL7_FCCA = 0x5C, /* Taiwan 5.47 Band */
297 APL8_WORLD = 0x5D, /* Malaysia 5GHz */
298 APL9_WORLD = 0x5E, /* Korea 5GHz */
301 * World mode SKUs
303 WOR0_WORLD = 0x60, /* World0 (WO0 SKU) */
304 WOR1_WORLD = 0x61, /* World1 (WO1 SKU) */
305 WOR2_WORLD = 0x62, /* World2 (WO2 SKU) */
306 WOR3_WORLD = 0x63, /* World3 (WO3 SKU) */
307 WOR4_WORLD = 0x64, /* World4 (WO4 SKU) */
308 WOR5_ETSIC = 0x65, /* World5 (WO5 SKU) */
310 WOR01_WORLD = 0x66, /* World0-1 (WW0-1 SKU) */
311 WOR02_WORLD = 0x67, /* World0-2 (WW0-2 SKU) */
312 EU1_WORLD = 0x68, /* Same as World0-2 (WW0-2 SKU), except active scan ch1-13. No ch14 */
314 WOR9_WORLD = 0x69, /* World9 (WO9 SKU) */
315 WORA_WORLD = 0x6A, /* WorldA (WOA SKU) */
317 MKK3_MKKB = 0x80, /* Japan UNI-1 even + MKKB */
318 MKK3_MKKA2 = 0x81, /* Japan UNI-1 even + MKKA2 */
319 MKK3_MKKC = 0x82, /* Japan UNI-1 even + MKKC */
321 MKK4_MKKB = 0x83, /* Japan UNI-1 even + UNI-2 + MKKB */
322 MKK4_MKKA2 = 0x84, /* Japan UNI-1 even + UNI-2 + MKKA2 */
323 MKK4_MKKC = 0x85, /* Japan UNI-1 even + UNI-2 + MKKC */
325 MKK5_MKKB = 0x86, /* Japan UNI-1 even + UNI-2 + mid-band + MKKB */
326 MKK5_MKKA2 = 0x87, /* Japan UNI-1 even + UNI-2 + mid-band + MKKA2 */
327 MKK5_MKKC = 0x88, /* Japan UNI-1 even + UNI-2 + mid-band + MKKC */
329 MKK6_MKKB = 0x89, /* Japan UNI-1 even + UNI-1 odd MKKB */
330 MKK6_MKKA2 = 0x8A, /* Japan UNI-1 even + UNI-1 odd + MKKA2 */
331 MKK6_MKKC = 0x8B, /* Japan UNI-1 even + UNI-1 odd + MKKC */
333 MKK7_MKKB = 0x8C, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKB */
334 MKK7_MKKA2 = 0x8D, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA2 */
335 MKK7_MKKC = 0x8E, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKC */
337 MKK8_MKKB = 0x8F, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKB */
338 MKK8_MKKA2 = 0x90, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKA2 */
339 MKK8_MKKC = 0x91, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKC */
341 /* Following definitions are used only by s/w to map old
342 * Japan SKUs.
344 MKK3_MKKA = 0xF0, /* Japan UNI-1 even + MKKA */
345 MKK3_MKKA1 = 0xF1, /* Japan UNI-1 even + MKKA1 */
346 MKK3_FCCA = 0xF2, /* Japan UNI-1 even + FCCA */
347 MKK4_MKKA = 0xF3, /* Japan UNI-1 even + UNI-2 + MKKA */
348 MKK4_MKKA1 = 0xF4, /* Japan UNI-1 even + UNI-2 + MKKA1 */
349 MKK4_FCCA = 0xF5, /* Japan UNI-1 even + UNI-2 + FCCA */
350 MKK9_MKKA = 0xF6, /* Japan UNI-1 even + 4.9GHz */
351 MKK10_MKKA = 0xF7, /* Japan UNI-1 even + UNI-2 + 4.9GHz */
354 * Regulator domains ending in a number (e.g. APL1,
355 * MK1, ETSI4, etc) apply to 5GHz channel and power
356 * information. Regulator domains ending in a letter
357 * (e.g. APLA, FCCA, etc) apply to 2.4GHz channel and
358 * power information.
360 APL1 = 0x0150, /* LAT & Asia */
361 APL2 = 0x0250, /* LAT & Asia */
362 APL3 = 0x0350, /* Taiwan */
363 APL4 = 0x0450, /* Jordan */
364 APL5 = 0x0550, /* Chile */
365 APL6 = 0x0650, /* Singapore */
366 APL8 = 0x0850, /* Malaysia */
367 APL9 = 0x0950, /* Korea (South) ROC 3 */
369 ETSI1 = 0x0130, /* Europe & others */
370 ETSI2 = 0x0230, /* Europe & others */
371 ETSI3 = 0x0330, /* Europe & others */
372 ETSI4 = 0x0430, /* Europe & others */
373 ETSI5 = 0x0530, /* Europe & others */
374 ETSI6 = 0x0630, /* Europe & others */
375 ETSIA = 0x0A30, /* France */
376 ETSIB = 0x0B30, /* Israel */
377 ETSIC = 0x0C30, /* Latin America */
379 FCC1 = 0x0110, /* US & others */
380 FCC2 = 0x0120, /* Canada, Australia & New Zealand */
381 FCC3 = 0x0160, /* US w/new middle band & DFS */
382 FCC4 = 0x0165, /* US Public Safety */
383 FCCA = 0x0A10,
385 APLD = 0x0D50, /* South Korea */
387 MKK1 = 0x0140, /* Japan (UNI-1 odd)*/
388 MKK2 = 0x0240, /* Japan (4.9 GHz + UNI-1 odd) */
389 MKK3 = 0x0340, /* Japan (UNI-1 even) */
390 MKK4 = 0x0440, /* Japan (UNI-1 even + UNI-2) */
391 MKK5 = 0x0540, /* Japan (UNI-1 even + UNI-2 + mid-band) */
392 MKK6 = 0x0640, /* Japan (UNI-1 odd + UNI-1 even) */
393 MKK7 = 0x0740, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 */
394 MKK8 = 0x0840, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 + mid-band) */
395 MKK9 = 0x0940, /* Japan (UNI-1 even + 4.9 GHZ) */
396 MKK10 = 0x0B40, /* Japan (UNI-1 even + UNI-2 + 4.9 GHZ) */
397 MKKA = 0x0A40, /* Japan */
398 MKKC = 0x0A50,
400 NULL1 = 0x0198,
401 WORLD = 0x0199,
402 DEBUG_REG_DMN = 0x01ff,
405 #define WORLD_SKU_MASK 0x00F0
406 #define WORLD_SKU_PREFIX 0x0060
408 enum { /* conformance test limits */
409 FCC = 0x10,
410 MKK = 0x40,
411 ETSI = 0x30,
415 * The following are flags for different requirements per reg domain.
416 * These requirements are either inhereted from the reg domain pair or
417 * from the unitary reg domain if the reg domain pair flags value is
421 enum {
422 NO_REQ = 0x00000000,
423 DISALLOW_ADHOC_11A = 0x00000001,
424 DISALLOW_ADHOC_11A_TURB = 0x00000002,
425 NEED_NFC = 0x00000004,
427 ADHOC_PER_11D = 0x00000008, /* Start Ad-Hoc mode */
428 ADHOC_NO_11A = 0x00000010,
430 PUBLIC_SAFETY_DOMAIN = 0x00000020, /* public safety domain */
431 LIMIT_FRAME_4MS = 0x00000040, /* 4msec limit on the frame length */
433 NO_HOSTAP = 0x00000080, /* No HOSTAP mode opereation */
437 * The following describe the bit masks for different passive scan
438 * capability/requirements per regdomain.
440 #define NO_PSCAN 0x0ULL
441 #define PSCAN_FCC 0x0000000000000001ULL
442 #define PSCAN_FCC_T 0x0000000000000002ULL
443 #define PSCAN_ETSI 0x0000000000000004ULL
444 #define PSCAN_MKK1 0x0000000000000008ULL
445 #define PSCAN_MKK2 0x0000000000000010ULL
446 #define PSCAN_MKKA 0x0000000000000020ULL
447 #define PSCAN_MKKA_G 0x0000000000000040ULL
448 #define PSCAN_ETSIA 0x0000000000000080ULL
449 #define PSCAN_ETSIB 0x0000000000000100ULL
450 #define PSCAN_ETSIC 0x0000000000000200ULL
451 #define PSCAN_WWR 0x0000000000000400ULL
452 #define PSCAN_MKKA1 0x0000000000000800ULL
453 #define PSCAN_MKKA1_G 0x0000000000001000ULL
454 #define PSCAN_MKKA2 0x0000000000002000ULL
455 #define PSCAN_MKKA2_G 0x0000000000004000ULL
456 #define PSCAN_MKK3 0x0000000000008000ULL
457 #define PSCAN_DEFER 0x7FFFFFFFFFFFFFFFULL
458 #define IS_ECM_CHAN 0x8000000000000000ULL
461 * THE following table is the mapping of regdomain pairs specified by
462 * an 8 bit regdomain value to the individual unitary reg domains
465 typedef struct reg_dmn_pair_mapping {
466 HAL_REG_DOMAIN regDmnEnum; /* 16 bit reg domain pair */
467 HAL_REG_DOMAIN regDmn5GHz; /* 5GHz reg domain */
468 HAL_REG_DOMAIN regDmn2GHz; /* 2GHz reg domain */
469 uint32_t flags5GHz; /* Requirements flags (AdHoc
470 disallow, noise floor cal needed,
471 etc) */
472 uint32_t flags2GHz; /* Requirements flags (AdHoc
473 disallow, noise floor cal needed,
474 etc) */
475 uint64_t pscanMask; /* Passive Scan flags which
476 can override unitary domain
477 passive scan flags. This
478 value is used as a mask on
479 the unitary flags*/
480 uint16_t singleCC; /* Country code of single country if
481 a one-on-one mapping exists */
482 } REG_DMN_PAIR_MAPPING;
484 static REG_DMN_PAIR_MAPPING regDomainPairs[] = {
485 {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
486 {NULL1_WORLD, NULL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
487 {NULL1_ETSIB, NULL1, ETSIB, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
488 {NULL1_ETSIC, NULL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
490 {FCC2_FCCA, FCC2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
491 {FCC2_WORLD, FCC2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
492 {FCC2_ETSIC, FCC2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
493 {FCC3_FCCA, FCC3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
494 {FCC3_WORLD, FCC3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
495 {FCC4_FCCA, FCC4, FCCA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
497 {ETSI1_WORLD, ETSI1, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
498 {ETSI2_WORLD, ETSI2, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
499 {ETSI3_WORLD, ETSI3, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
500 {ETSI4_WORLD, ETSI4, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
501 {ETSI5_WORLD, ETSI5, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
502 {ETSI6_WORLD, ETSI6, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
504 {ETSI3_ETSIA, ETSI3, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
505 {FRANCE_RES, ETSI3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
507 {FCC1_WORLD, FCC1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
508 {FCC1_FCCA, FCC1, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
509 {APL1_WORLD, APL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
510 {APL2_WORLD, APL2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
511 {APL3_WORLD, APL3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
512 {APL4_WORLD, APL4, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
513 {APL5_WORLD, APL5, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
514 {APL6_WORLD, APL6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
515 {APL8_WORLD, APL8, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
516 {APL9_WORLD, APL9, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
518 {APL3_FCCA, APL3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
519 {APL1_ETSIC, APL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
520 {APL2_ETSIC, APL2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
521 {APL2_APLD, APL2, APLD, NO_REQ, NO_REQ, PSCAN_DEFER, },
523 {MKK1_MKKA, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA, CTRY_JAPAN },
524 {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 },
525 {MKK1_FCCA, MKK1, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN2 },
526 {MKK1_MKKA1, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN4 },
527 {MKK1_MKKA2, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN5 },
528 {MKK1_MKKC, MKK1, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN6 },
530 /* MKK2 */
531 {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 },
533 /* MKK3 */
534 {MKK3_MKKA, MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC , PSCAN_MKKA, 0 },
535 {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 },
536 {MKK3_MKKA1, MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA1 | PSCAN_MKKA1_G, 0 },
537 {MKK3_MKKA2,MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN8 },
538 {MKK3_MKKC, MKK3, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, CTRY_JAPAN9 },
539 {MKK3_FCCA, MKK3, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, 0 },
541 /* MKK4 */
542 {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 },
543 {MKK4_MKKA1, MKK4, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, 0 },
544 {MKK4_MKKA2, MKK4, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 |PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11 },
545 {MKK4_MKKC, MKK4, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN12 },
546 {MKK4_FCCA, MKK4, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, 0 },
548 /* MKK5 */
549 {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 },
550 {MKK5_MKKA2,MKK5, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN14 },
551 {MKK5_MKKC, MKK5, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN15 },
553 /* MKK6 */
554 {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 },
555 {MKK6_MKKA2, MKK6, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN17 },
556 {MKK6_MKKC, MKK6, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN18 },
558 /* MKK7 */
559 {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 },
560 {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 },
561 {MKK7_MKKC, MKK7, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN21 },
563 /* MKK8 */
564 {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 },
565 {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 },
566 {MKK8_MKKC, MKK8, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 , CTRY_JAPAN24 },
568 {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 },
569 {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 },
571 /* These are super domains */
572 {WOR0_WORLD, WOR0_WORLD, WOR0_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
573 {WOR1_WORLD, WOR1_WORLD, WOR1_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
574 {WOR2_WORLD, WOR2_WORLD, WOR2_WORLD, DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
575 {WOR3_WORLD, WOR3_WORLD, WOR3_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
576 {WOR4_WORLD, WOR4_WORLD, WOR4_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
577 {WOR5_ETSIC, WOR5_ETSIC, WOR5_ETSIC, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
578 {WOR01_WORLD, WOR01_WORLD, WOR01_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
579 {WOR02_WORLD, WOR02_WORLD, WOR02_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
580 {EU1_WORLD, EU1_WORLD, EU1_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
581 {WOR9_WORLD, WOR9_WORLD, WOR9_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
582 {WORA_WORLD, WORA_WORLD, WORA_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
586 * The following table of vendor specific regdomain pairs and
587 * additional flags used to modify the flags5GHz and flags2GHz
588 * of the original regdomain
591 #define NO_INTERSECT_REQ 0xFFFFFFFF
592 #define NO_UNION_REQ 0
593 #define MAX_MAPS 2
595 struct ccmap {
596 char isoName[3];
597 HAL_CTRY_CODE countryCode;
602 * The following table is the master list for all different freqeuncy
603 * bands with the complete matrix of all possible flags and settings
604 * for each band if it is used in ANY reg domain.
607 #define DEF_REGDMN FCC1_FCCA
608 #define DEF_DMN_5 FCC1
609 #define DEF_DMN_2 FCCA
610 #define COUNTRY_ERD_FLAG 0x8000
611 #define WORLDWIDE_ROAMING_FLAG 0x4000
612 #define SUPER_DOMAIN_MASK 0x0fff
613 #define COUNTRY_CODE_MASK 0x3fff
615 #define YES AH_TRUE
616 #define NO AH_FALSE
618 typedef struct {
619 HAL_CTRY_CODE countryCode;
620 HAL_REG_DOMAIN regDmnEnum;
621 HAL_BOOL allow11g;
622 HAL_BOOL allow11aTurbo;
623 HAL_BOOL allow11gTurbo;
624 HAL_BOOL allow11ng20;
625 HAL_BOOL allow11ng40;
626 HAL_BOOL allow11na20;
627 HAL_BOOL allow11na40;
628 uint16_t outdoorChanStart;
629 } COUNTRY_CODE_TO_ENUM_RD;
631 static COUNTRY_CODE_TO_ENUM_RD allCountries[] = {
632 {CTRY_DEBUG, NO_ENUMRD, YES, YES, YES, YES,YES, YES,YES, 7000 },
633 {CTRY_DEFAULT, DEF_REGDMN, YES, YES, YES, YES,YES, YES,YES, 7000 },
634 {CTRY_ALBANIA, NULL1_WORLD, YES, NO, YES, YES, NO, NO, NO, 7000 },
635 {CTRY_ALGERIA, NULL1_WORLD, YES, NO, YES, YES, NO, NO, NO, 7000 },
636 {CTRY_ARGENTINA, APL3_WORLD, NO, NO, NO, NO, NO, NO, NO, 7000 },
637 {CTRY_ARMENIA, ETSI4_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
638 {CTRY_AUSTRALIA, FCC2_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
639 {CTRY_AUSTRIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
640 {CTRY_AZERBAIJAN, ETSI4_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
641 {CTRY_BAHRAIN, APL6_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
642 {CTRY_BELARUS, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
643 {CTRY_BELGIUM, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
644 {CTRY_BELIZE, APL1_ETSIC, YES, YES, YES, YES,YES, YES,YES, 7000 },
645 {CTRY_BOLIVIA, APL1_ETSIC, YES, YES, YES, YES,YES, YES,YES, 7000 },
646 {CTRY_BRAZIL, FCC3_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 },
647 {CTRY_BRUNEI_DARUSSALAM,APL1_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
648 {CTRY_BULGARIA, ETSI6_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
649 {CTRY_CANADA, FCC2_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
650 {CTRY_CHILE, APL6_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
651 {CTRY_CHINA, APL1_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
652 {CTRY_COLOMBIA, FCC1_FCCA, YES, NO, YES, YES,YES, YES, NO, 7000 },
653 {CTRY_COSTA_RICA, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
654 {CTRY_CROATIA, ETSI3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
655 {CTRY_CYPRUS, ETSI1_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
656 {CTRY_CZECH, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
657 {CTRY_DENMARK, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
658 {CTRY_DOMINICAN_REPUBLIC,FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
659 {CTRY_ECUADOR, NULL1_WORLD, NO, NO, NO, NO, NO, NO, NO, 7000 },
660 {CTRY_EGYPT, ETSI3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
661 {CTRY_EL_SALVADOR, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
662 {CTRY_ESTONIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
663 {CTRY_FINLAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
664 {CTRY_FRANCE, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
665 {CTRY_FRANCE2, ETSI3_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
666 {CTRY_GEORGIA, ETSI4_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
667 {CTRY_GERMANY, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
668 {CTRY_GREECE, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
669 {CTRY_GUATEMALA, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
670 {CTRY_HONDURAS, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
671 {CTRY_HONG_KONG, FCC2_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
672 {CTRY_HUNGARY, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
673 {CTRY_ICELAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
674 {CTRY_INDIA, APL6_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
675 {CTRY_INDONESIA, APL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
676 {CTRY_IRAN, APL1_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
677 {CTRY_IRELAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
678 {CTRY_ISRAEL, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
679 {CTRY_ITALY, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
680 {CTRY_JAPAN, MKK1_MKKA, YES, NO, NO, YES, NO, YES, NO, 7000 },
681 {CTRY_JAPAN1, MKK1_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
682 {CTRY_JAPAN2, MKK1_FCCA, YES, NO, NO, NO, NO, NO, NO, 7000 },
683 {CTRY_JAPAN3, MKK2_MKKA, YES, NO, NO, NO, NO, NO, NO, 7000 },
684 {CTRY_JAPAN4, MKK1_MKKA1, YES, NO, NO, NO, NO, NO, NO, 7000 },
685 {CTRY_JAPAN5, MKK1_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 },
686 {CTRY_JAPAN6, MKK1_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
688 {CTRY_JAPAN7, MKK3_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
689 {CTRY_JAPAN8, MKK3_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 },
690 {CTRY_JAPAN9, MKK3_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
692 {CTRY_JAPAN10, MKK4_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
693 {CTRY_JAPAN11, MKK4_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 },
694 {CTRY_JAPAN12, MKK4_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
696 {CTRY_JAPAN13, MKK5_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
697 {CTRY_JAPAN14, MKK5_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 },
698 {CTRY_JAPAN15, MKK5_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
700 {CTRY_JAPAN16, MKK6_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
701 {CTRY_JAPAN17, MKK6_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 },
702 {CTRY_JAPAN18, MKK6_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
704 {CTRY_JAPAN19, MKK7_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
705 {CTRY_JAPAN20, MKK7_MKKA2, YES, NO, NO, YES, NO, YES, NO, 7000 },
706 {CTRY_JAPAN21, MKK7_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
708 {CTRY_JAPAN22, MKK8_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
709 {CTRY_JAPAN23, MKK8_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 },
710 {CTRY_JAPAN24, MKK8_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
712 {CTRY_JORDAN, APL4_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
713 {CTRY_KAZAKHSTAN, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
714 {CTRY_KOREA_NORTH, APL2_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
715 {CTRY_KOREA_ROC, APL2_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 },
716 {CTRY_KOREA_ROC2, APL2_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 },
717 {CTRY_KOREA_ROC3, APL9_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 },
718 {CTRY_KUWAIT, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
719 {CTRY_LATVIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
720 {CTRY_LEBANON, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
721 {CTRY_LIECHTENSTEIN,ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
722 {CTRY_LITHUANIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
723 {CTRY_LUXEMBOURG, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
724 {CTRY_MACAU, FCC2_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
725 {CTRY_MACEDONIA, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
726 {CTRY_MALAYSIA, APL8_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 },
727 {CTRY_MALTA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
728 {CTRY_MEXICO, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
729 {CTRY_MONACO, ETSI4_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
730 {CTRY_MOROCCO, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
731 {CTRY_NETHERLANDS, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
732 {CTRY_NEW_ZEALAND, FCC2_ETSIC, YES, NO, YES, YES,YES, YES,YES, 7000 },
733 {CTRY_NORWAY, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
734 {CTRY_OMAN, APL6_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
735 {CTRY_PAKISTAN, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
736 {CTRY_PANAMA, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
737 {CTRY_PERU, APL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
738 {CTRY_PHILIPPINES, FCC3_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
739 {CTRY_POLAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
740 {CTRY_PORTUGAL, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
741 {CTRY_PUERTO_RICO, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
742 {CTRY_QATAR, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
743 {CTRY_ROMANIA, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
744 {CTRY_RUSSIA, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
745 {CTRY_SAUDI_ARABIA,FCC2_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
746 {CTRY_SINGAPORE, APL6_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
747 {CTRY_SLOVAKIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
748 {CTRY_SLOVENIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
749 {CTRY_SOUTH_AFRICA,FCC3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
750 {CTRY_SPAIN, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
751 {CTRY_SWEDEN, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
752 {CTRY_SWITZERLAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
753 {CTRY_SYRIA, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
754 {CTRY_TAIWAN, APL3_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
755 {CTRY_THAILAND, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
756 {CTRY_TRINIDAD_Y_TOBAGO,ETSI4_WORLD,YES, NO, YES, YES,YES, YES, NO, 7000 },
757 {CTRY_TUNISIA, ETSI3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
758 {CTRY_TURKEY, ETSI3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
759 {CTRY_UKRAINE, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
760 {CTRY_UAE, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
761 {CTRY_UNITED_KINGDOM, ETSI1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
762 {CTRY_UNITED_STATES, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 5825 },
763 {CTRY_UNITED_STATES_FCC49,FCC4_FCCA,YES, YES, YES, YES,YES, YES,YES, 7000 },
764 {CTRY_URUGUAY, FCC1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
765 {CTRY_UZBEKISTAN, FCC3_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
766 {CTRY_VENEZUELA, APL2_ETSIC, YES, NO, YES, YES,YES, YES, NO, 7000 },
767 {CTRY_VIET_NAM, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
768 {CTRY_YEMEN, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
769 {CTRY_ZIMBABWE, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 }
772 typedef struct RegDmnFreqBand {
773 uint16_t lowChannel; /* Low channel center in MHz */
774 uint16_t highChannel; /* High Channel center in MHz */
775 uint8_t powerDfs; /* Max power (dBm) for channel
776 range when using DFS */
777 uint8_t antennaMax; /* Max allowed antenna gain */
778 uint8_t channelBW; /* Bandwidth of the channel */
779 uint8_t channelSep; /* Channel separation within
780 the band */
781 uint64_t useDfs; /* Use DFS in the RegDomain
782 if corresponding bit is set */
783 uint64_t usePassScan; /* Use Passive Scan in the RegDomain
784 if corresponding bit is set */
785 uint8_t regClassId; /* Regulatory class id */
786 } REG_DMN_FREQ_BAND;
788 /* Bit masks for DFS per regdomain */
790 enum {
791 NO_DFS = 0x0000000000000000ULL,
792 DFS_FCC3 = 0x0000000000000001ULL,
793 DFS_ETSI = 0x0000000000000002ULL,
794 DFS_MKK4 = 0x0000000000000004ULL,
797 /* The table of frequency bands is indexed by a bitmask. The ordering
798 * must be consistent with the enum below. When adding a new
799 * frequency band, be sure to match the location in the enum with the
800 * comments
804 * 5GHz 11A channel tags
807 enum {
808 F1_4915_4925,
809 F1_4935_4945,
810 F1_4920_4980,
811 F1_4942_4987,
812 F1_4945_4985,
813 F1_4950_4980,
814 F1_5035_5040,
815 F1_5040_5080,
816 F1_5055_5055,
818 F1_5120_5240,
820 F1_5170_5230,
821 F2_5170_5230,
823 F1_5180_5240,
824 F2_5180_5240,
825 F3_5180_5240,
826 F4_5180_5240,
827 F5_5180_5240,
828 F6_5180_5240,
830 F1_5180_5320,
832 F1_5240_5280,
834 F1_5260_5280,
836 F1_5260_5320,
837 F2_5260_5320,
838 F3_5260_5320,
839 F4_5260_5320,
840 F5_5260_5320,
841 F6_5260_5320,
843 F1_5260_5700,
845 F1_5280_5320,
847 F1_5500_5620,
849 F1_5500_5700,
850 F2_5500_5700,
851 F3_5500_5700,
852 F4_5500_5700,
854 F1_5745_5805,
855 F2_5745_5805,
856 F3_5745_5805,
858 F1_5745_5825,
859 F2_5745_5825,
860 F3_5745_5825,
861 F4_5745_5825,
862 F5_5745_5825,
863 F6_5745_5825,
865 W1_4920_4980,
866 W1_5040_5080,
867 W1_5170_5230,
868 W1_5180_5240,
869 W1_5260_5320,
870 W1_5745_5825,
871 W1_5500_5700,
872 W2_5260_5320,
873 W2_5180_5240,
874 W2_5825_5825,
877 static REG_DMN_FREQ_BAND regDmn5GhzFreq[] = {
878 { 4915, 4925, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16 }, /* F1_4915_4925 */
879 { 4935, 4945, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16 }, /* F1_4935_4945 */
880 { 4920, 4980, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 7 }, /* F1_4920_4980 */
881 { 4942, 4987, 27, 6, 5, 5, NO_DFS, PSCAN_FCC, 0 }, /* F1_4942_4987 */
882 { 4945, 4985, 30, 6, 10, 5, NO_DFS, PSCAN_FCC, 0 }, /* F1_4945_4985 */
883 { 4950, 4980, 33, 6, 20, 5, NO_DFS, PSCAN_FCC, 0 }, /* F1_4950_4980 */
884 { 5035, 5040, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12 }, /* F1_5035_5040 */
885 { 5040, 5080, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 2 }, /* F1_5040_5080 */
886 { 5055, 5055, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12 }, /* F1_5055_5055 */
888 { 5120, 5240, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F1_5120_5240 */
890 { 5170, 5230, 23, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1 }, /* F1_5170_5230 */
891 { 5170, 5230, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1 }, /* F2_5170_5230 */
893 { 5180, 5240, 15, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F1_5180_5240 */
894 { 5180, 5240, 17, 6, 20, 20, NO_DFS, PSCAN_FCC, 1 }, /* F2_5180_5240 */
895 { 5180, 5240, 18, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F3_5180_5240 */
896 { 5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F4_5180_5240 */
897 { 5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F5_5180_5240 */
898 { 5180, 5240, 23, 6, 20, 20, NO_DFS, PSCAN_FCC, 0 }, /* F6_5180_5240 */
900 { 5180, 5320, 20, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0 }, /* F1_5180_5320 */
902 { 5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F1_5240_5280 */
904 { 5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F1_5260_5280 */
906 { 5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F1_5260_5320 */
908 { 5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3 , 0 },
909 /* F2_5260_5320 */
911 { 5260, 5320, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 }, /* F3_5260_5320 */
912 { 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 }, /* F4_5260_5320 */
913 { 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0 }, /* F5_5260_5320 */
914 { 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F6_5260_5320 */
916 { 5260, 5700, 5, 6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0 }, /* F1_5260_5700 */
918 { 5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0 }, /* F1_5280_5320 */
920 { 5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0 }, /* F1_5500_5620 */
922 { 5500, 5700, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 4 }, /* F1_5500_5700 */
923 { 5500, 5700, 27, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F2_5500_5700 */
924 { 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 }, /* F3_5500_5700 */
925 { 5500, 5700, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_MKK3 | PSCAN_FCC, 0 },
926 /* F4_5500_5700 */
928 { 5745, 5805, 23, 0, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F1_5745_5805 */
929 { 5745, 5805, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F2_5745_5805 */
930 { 5745, 5805, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0 }, /* F3_5745_5805 */
931 { 5745, 5825, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F1_5745_5825 */
932 { 5745, 5825, 17, 0, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F2_5745_5825 */
933 { 5745, 5825, 20, 0, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F3_5745_5825 */
934 { 5745, 5825, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F4_5745_5825 */
935 { 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 3 }, /* F5_5745_5825 */
936 { 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F6_5745_5825 */
939 * Below are the world roaming channels
940 * All WWR domains have no power limit, instead use the card's CTL
941 * or max power settings.
943 { 4920, 4980, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 }, /* W1_4920_4980 */
944 { 5040, 5080, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 }, /* W1_5040_5080 */
945 { 5170, 5230, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 }, /* W1_5170_5230 */
946 { 5180, 5240, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 }, /* W1_5180_5240 */
947 { 5260, 5320, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 }, /* W1_5260_5320 */
948 { 5745, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 }, /* W1_5745_5825 */
949 { 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 }, /* W1_5500_5700 */
950 { 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* W2_5260_5320 */
951 { 5180, 5240, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* W2_5180_5240 */
952 { 5825, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 }, /* W2_5825_5825 */
956 * 5GHz Turbo (dynamic & static) tags
959 enum {
960 T1_5130_5210,
961 T1_5250_5330,
962 T1_5370_5490,
963 T1_5530_5650,
965 T1_5150_5190,
966 T1_5230_5310,
967 T1_5350_5470,
968 T1_5510_5670,
970 T1_5200_5240,
971 T2_5200_5240,
972 T1_5210_5210,
973 T2_5210_5210,
975 T1_5280_5280,
976 T2_5280_5280,
977 T1_5250_5250,
978 T1_5290_5290,
979 T1_5250_5290,
980 T2_5250_5290,
982 T1_5540_5660,
983 T1_5760_5800,
984 T2_5760_5800,
986 T1_5765_5805,
988 WT1_5210_5250,
989 WT1_5290_5290,
990 WT1_5540_5660,
991 WT1_5760_5800,
994 static REG_DMN_FREQ_BAND regDmn5GhzTurboFreq[] = {
995 { 5130, 5210, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_5130_5210 */
996 { 5250, 5330, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0}, /* T1_5250_5330 */
997 { 5370, 5490, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_5370_5490 */
998 { 5530, 5650, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0}, /* T1_5530_5650 */
1000 { 5150, 5190, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_5150_5190 */
1001 { 5230, 5310, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0}, /* T1_5230_5310 */
1002 { 5350, 5470, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_5350_5470 */
1003 { 5510, 5670, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0}, /* T1_5510_5670 */
1005 { 5200, 5240, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_5200_5240 */
1006 { 5200, 5240, 23, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T2_5200_5240 */
1007 { 5210, 5210, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_5210_5210 */
1008 { 5210, 5210, 23, 0, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T2_5210_5210 */
1010 { 5280, 5280, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0}, /* T1_5280_5280 */
1011 { 5280, 5280, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0}, /* T2_5280_5280 */
1012 { 5250, 5250, 17, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0}, /* T1_5250_5250 */
1013 { 5290, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0}, /* T1_5290_5290 */
1014 { 5250, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0}, /* T1_5250_5290 */
1015 { 5250, 5290, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0}, /* T2_5250_5290 */
1017 { 5540, 5660, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0}, /* T1_5540_5660 */
1018 { 5760, 5800, 20, 0, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_5760_5800 */
1019 { 5760, 5800, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T2_5760_5800 */
1021 { 5765, 5805, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_5765_5805 */
1024 * Below are the WWR frequencies
1027 { 5210, 5250, 15, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0}, /* WT1_5210_5250 */
1028 { 5290, 5290, 18, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0}, /* WT1_5290_5290 */
1029 { 5540, 5660, 20, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0}, /* WT1_5540_5660 */
1030 { 5760, 5800, 20, 0, 40, 40, NO_DFS, PSCAN_WWR, 0}, /* WT1_5760_5800 */
1034 * 2GHz 11b channel tags
1036 enum {
1037 F1_2312_2372,
1038 F2_2312_2372,
1040 F1_2412_2472,
1041 F2_2412_2472,
1042 F3_2412_2472,
1044 F1_2412_2462,
1045 F2_2412_2462,
1047 F1_2432_2442,
1049 F1_2457_2472,
1051 F1_2467_2472,
1053 F1_2484_2484,
1054 F2_2484_2484,
1056 F1_2512_2732,
1058 W1_2312_2372,
1059 W1_2412_2412,
1060 W1_2417_2432,
1061 W1_2437_2442,
1062 W1_2447_2457,
1063 W1_2462_2462,
1064 W1_2467_2467,
1065 W2_2467_2467,
1066 W1_2472_2472,
1067 W2_2472_2472,
1068 W1_2484_2484,
1069 W2_2484_2484,
1072 static REG_DMN_FREQ_BAND regDmn2GhzFreq[] = {
1073 { 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2312_2372 */
1074 { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F2_2312_2372 */
1076 { 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2412_2472 */
1077 { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0}, /* F2_2412_2472 */
1078 { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F3_2412_2472 */
1080 { 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2412_2462 */
1081 { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0}, /* F2_2412_2462 */
1083 { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2432_2442 */
1085 { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2457_2472 */
1087 { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0}, /* F1_2467_2472 */
1089 { 2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2484_2484 */
1090 { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 0}, /* F2_2484_2484 */
1092 { 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* F1_2512_2732 */
1095 * WWR have powers opened up to 20dBm. Limits should often come from CTL/Max powers
1098 { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* W1_2312_2372 */
1099 { 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* W1_2412_2412 */
1100 { 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* W1_2417_2432 */
1101 { 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* W1_2437_2442 */
1102 { 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* W1_2447_2457 */
1103 { 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* W1_2462_2462 */
1104 { 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0}, /* W1_2467_2467 */
1105 { 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0}, /* W2_2467_2467 */
1106 { 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0}, /* W1_2472_2472 */
1107 { 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0}, /* W2_2472_2472 */
1108 { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0}, /* W1_2484_2484 */
1109 { 2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0}, /* W2_2484_2484 */
1113 * 2GHz 11g channel tags
1116 enum {
1117 G1_2312_2372,
1118 G2_2312_2372,
1120 G1_2412_2472,
1121 G2_2412_2472,
1122 G3_2412_2472,
1124 G1_2412_2462,
1125 G2_2412_2462,
1127 G1_2432_2442,
1129 G1_2457_2472,
1131 G1_2512_2732,
1133 G1_2467_2472 ,
1135 WG1_2312_2372,
1136 WG1_2412_2412,
1137 WG1_2417_2432,
1138 WG1_2437_2442,
1139 WG1_2447_2457,
1140 WG1_2462_2462,
1141 WG1_2467_2467,
1142 WG2_2467_2467,
1143 WG1_2472_2472,
1144 WG2_2472_2472,
1146 S1_907_922_5,
1147 S1_907_922_10,
1148 S1_912_917,
1150 S2_907_922_5,
1151 S2_907_922_10,
1152 S2_912_917,
1155 static REG_DMN_FREQ_BAND regDmn2Ghz11gFreq[] = {
1156 { 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G1_2312_2372 */
1157 { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G2_2312_2372 */
1159 { 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G1_2412_2472 */
1160 { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0}, /* G2_2412_2472 */
1161 { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G3_2412_2472 */
1163 { 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G1_2412_2462 */
1164 { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0}, /* G2_2412_2462 */
1166 { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G1_2432_2442 */
1168 { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G1_2457_2472 */
1170 { 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, /* G1_2512_2732 */
1172 { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0 }, /* G1_2467_2472 */
1175 * WWR open up the power to 20dBm
1178 { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* WG1_2312_2372 */
1179 { 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* WG1_2412_2412 */
1180 { 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* WG1_2417_2432 */
1181 { 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* WG1_2437_2442 */
1182 { 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* WG1_2447_2457 */
1183 { 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, /* WG1_2462_2462 */
1184 { 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0}, /* WG1_2467_2467 */
1185 { 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0}, /* WG2_2467_2467 */
1186 { 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0}, /* WG1_2472_2472 */
1187 { 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0}, /* WG2_2472_2472 */
1191 * 2GHz Dynamic turbo tags
1194 enum {
1195 T1_2312_2372,
1196 T1_2437_2437,
1197 T2_2437_2437,
1198 T3_2437_2437,
1199 T1_2512_2732
1202 static REG_DMN_FREQ_BAND regDmn2Ghz11gTurboFreq[] = {
1203 { 2312, 2372, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_2312_2372 */
1204 { 2437, 2437, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_2437_2437 */
1205 { 2437, 2437, 20, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T2_2437_2437 */
1206 { 2437, 2437, 18, 6, 40, 40, NO_DFS, PSCAN_WWR, 0}, /* T3_2437_2437 */
1207 { 2512, 2732, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0}, /* T1_2512_2732 */
1210 typedef struct regDomain {
1211 uint16_t regDmnEnum; /* value from EnumRd table */
1212 uint8_t conformanceTestLimit;
1213 uint64_t dfsMask; /* DFS bitmask for 5Ghz tables */
1214 uint64_t pscan; /* Bitmask for passive scan */
1215 uint32_t flags; /* Requirement flags (AdHoc disallow, noise
1216 floor cal needed, etc) */
1217 uint64_t chan11a[BMLEN];/* 128 bit bitmask for channel/band
1218 selection */
1219 uint64_t chan11a_turbo[BMLEN];/* 128 bit bitmask for channel/band
1220 selection */
1221 uint64_t chan11a_dyn_turbo[BMLEN]; /* 128 bit bitmask for channel/band
1222 selection */
1223 uint64_t chan11b[BMLEN];/* 128 bit bitmask for channel/band
1224 selection */
1225 uint64_t chan11g[BMLEN];/* 128 bit bitmask for channel/band
1226 selection */
1227 uint64_t chan11g_turbo[BMLEN];/* 128 bit bitmask for channel/band
1228 selection */
1229 } REG_DOMAIN;
1231 static REG_DOMAIN regDomains[] = {
1233 {DEBUG_REG_DMN, FCC, DFS_FCC3, NO_PSCAN, NO_REQ,
1234 BM(F1_5120_5240, F1_5260_5700, F1_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1235 BM(T1_5130_5210, T1_5250_5330, T1_5370_5490, T1_5530_5650, T1_5150_5190, T1_5230_5310, T1_5350_5470, T1_5510_5670, -1, -1, -1, -1),
1236 BM(T1_5200_5240, T1_5280_5280, T1_5540_5660, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1),
1237 BM(F1_2312_2372, F1_2412_2472, F1_2484_2484, F1_2512_2732, -1, -1, -1, -1, -1, -1, -1, -1),
1238 BM(G1_2312_2372, G1_2412_2472, G1_2512_2732, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1239 BM(T1_2312_2372, T1_2437_2437, T1_2512_2732, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1241 {APL1, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1242 BM(F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1243 BMZERO,
1244 BMZERO,
1245 BMZERO,
1246 BMZERO,
1247 BMZERO},
1249 {APL2, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1250 BM(F1_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1251 BMZERO,
1252 BMZERO,
1253 BMZERO,
1254 BMZERO,
1255 BMZERO},
1257 {APL3, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1258 BM(F1_5280_5320, F2_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1259 BMZERO,
1260 BMZERO,
1261 BMZERO,
1262 BMZERO,
1263 BMZERO},
1265 {APL4, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1266 BM(F4_5180_5240, F3_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1267 BMZERO,
1268 BMZERO,
1269 BMZERO,
1270 BMZERO,
1271 BMZERO},
1273 {APL5, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1274 BM(F2_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1275 BMZERO,
1276 BMZERO,
1277 BMZERO,
1278 BMZERO,
1279 BMZERO},
1281 {APL6, ETSI, DFS_ETSI, PSCAN_FCC_T | PSCAN_FCC , NO_REQ,
1282 BM(F4_5180_5240, F2_5260_5320, F3_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1283 BM(T2_5210_5210, T1_5250_5290, T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1284 BMZERO,
1285 BMZERO,
1286 BMZERO,
1287 BMZERO},
1289 {APL8, ETSI, NO_DFS, NO_PSCAN, DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB,
1290 BM(F6_5260_5320, F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1291 BMZERO,
1292 BMZERO,
1293 BMZERO,
1294 BMZERO,
1295 BMZERO},
1297 {APL9, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB,
1298 BM(F1_5180_5320, F1_5500_5620, F3_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1299 BMZERO,
1300 BMZERO,
1301 BMZERO,
1302 BMZERO,
1303 BMZERO},
1305 {ETSI1, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1306 BM(W2_5180_5240, F2_5260_5320, F2_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1307 BMZERO,
1308 BMZERO,
1309 BMZERO,
1310 BMZERO,
1311 BMZERO},
1313 {ETSI2, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1314 BM(F3_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1315 BMZERO,
1316 BMZERO,
1317 BMZERO,
1318 BMZERO,
1319 BMZERO},
1321 {ETSI3, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1322 BM(W2_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1323 BMZERO,
1324 BMZERO,
1325 BMZERO,
1326 BMZERO,
1327 BMZERO},
1329 {ETSI4, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1330 BM(F3_5180_5240, F1_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1331 BMZERO,
1332 BMZERO,
1333 BMZERO,
1334 BMZERO,
1335 BMZERO},
1337 {ETSI5, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1338 BM(F1_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1339 BMZERO,
1340 BMZERO,
1341 BMZERO,
1342 BMZERO,
1343 BMZERO},
1345 {ETSI6, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1346 BM(F5_5180_5240, F1_5260_5280, F3_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1347 BMZERO,
1348 BMZERO,
1349 BMZERO,
1350 BMZERO,
1351 BMZERO},
1353 {FCC1, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1354 BM(F2_5180_5240, F4_5260_5320, F5_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1355 BM(T1_5210_5210, T2_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1356 BM(T1_5200_5240, T1_5280_5280, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1357 BMZERO,
1358 BMZERO,
1359 BMZERO},
1361 {FCC2, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1362 BM(F6_5180_5240, F5_5260_5320, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1363 BM(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1364 BM(T2_5200_5240, T1_5280_5280, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1365 BMZERO,
1366 BMZERO,
1367 BMZERO},
1369 {FCC3, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ,
1370 BM(F2_5180_5240, F3_5260_5320, F1_5500_5700, F5_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1),
1371 BM(T1_5210_5210, T1_5250_5250, T1_5290_5290, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1),
1372 BM(T1_5200_5240, T2_5280_5280, T1_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1373 BMZERO,
1374 BMZERO,
1375 BMZERO},
1377 {FCC4, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ,
1378 BM(F1_4942_4987, F1_4945_4985, F1_4950_4980, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1379 BMZERO,
1380 BMZERO,
1381 BMZERO,
1382 BMZERO,
1383 BMZERO},
1385 {MKK1, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
1386 BM(F1_5170_5230, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1387 BMZERO,
1388 BMZERO,
1389 BMZERO,
1390 BMZERO,
1391 BMZERO},
1393 {MKK2, MKK, NO_DFS, PSCAN_MKK2, DISALLOW_ADHOC_11A_TURB,
1394 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040, F1_5055_5055, F1_5040_5080, F1_5170_5230, -1, -1, -1, -1, -1),
1395 BMZERO,
1396 BMZERO,
1397 BMZERO,
1398 BMZERO,
1399 BMZERO},
1401 /* UNI-1 even */
1402 {MKK3, MKK, NO_DFS, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
1403 BM(F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1404 BMZERO,
1405 BMZERO,
1406 BMZERO,
1407 BMZERO,
1408 BMZERO},
1410 /* UNI-1 even + UNI-2 */
1411 {MKK4, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
1412 BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1413 BMZERO,
1414 BMZERO,
1415 BMZERO,
1416 BMZERO,
1417 BMZERO},
1419 /* UNI-1 even + UNI-2 + mid-band */
1420 {MKK5, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
1421 BM(F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1422 BMZERO,
1423 BMZERO,
1424 BMZERO,
1425 BMZERO,
1426 BMZERO},
1428 /* UNI-1 odd + even */
1429 {MKK6, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
1430 BM(F2_5170_5230, F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1431 BMZERO,
1432 BMZERO,
1433 BMZERO,
1434 BMZERO,
1435 BMZERO},
1437 /* UNI-1 odd + UNI-1 even + UNI-2 */
1438 {MKK7, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3 , DISALLOW_ADHOC_11A_TURB,
1439 BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1440 BMZERO,
1441 BMZERO,
1442 BMZERO,
1443 BMZERO,
1444 BMZERO},
1446 /* UNI-1 odd + UNI-1 even + UNI-2 + mid-band */
1447 {MKK8, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3 , DISALLOW_ADHOC_11A_TURB,
1448 BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1),
1449 BMZERO,
1450 BMZERO,
1451 BMZERO,
1452 BMZERO,
1453 BMZERO},
1455 /* UNI-1 even + 4.9 GHZ */
1456 {MKK9, MKK, NO_DFS, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
1457 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040, F1_5055_5055, F1_5040_5080, F4_5180_5240, -1, -1, -1, -1, -1),
1458 BMZERO,
1459 BMZERO,
1460 BMZERO,
1461 BMZERO,
1462 BMZERO},
1464 /* UNI-1 even + UNI-2 + 4.9 GHZ */
1465 {MKK10, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
1466 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040, F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320, -1, -1, -1, -1),
1467 BMZERO,
1468 BMZERO,
1469 BMZERO,
1470 BMZERO,
1471 BMZERO},
1473 /* Defined here to use when 2G channels are authorised for country K2 */
1474 {APLD, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ,
1475 BMZERO,
1476 BMZERO,
1477 BMZERO,
1478 BM(F2_2312_2372,F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1479 BM(G2_2312_2372,G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1480 BMZERO},
1482 {ETSIA, NO_CTL, NO_DFS, PSCAN_ETSIA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1483 BMZERO,
1484 BMZERO,
1485 BMZERO,
1486 BM(F1_2457_2472,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1487 BM(G1_2457_2472,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1488 BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1490 {ETSIB, ETSI, NO_DFS, PSCAN_ETSIB, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1491 BMZERO,
1492 BMZERO,
1493 BMZERO,
1494 BM(F1_2432_2442,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1),
1495 BM(G1_2432_2442,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1),
1496 BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1498 {ETSIC, ETSI, NO_DFS, PSCAN_ETSIC, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1499 BMZERO,
1500 BMZERO,
1501 BMZERO,
1502 BM(F3_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1),
1503 BM(G3_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1),
1504 BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1506 {FCCA, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1507 BMZERO,
1508 BMZERO,
1509 BMZERO,
1510 BM(F1_2412_2462,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1),
1511 BM(G1_2412_2462,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1),
1512 BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1514 {MKKA, MKK, NO_DFS, PSCAN_MKKA | PSCAN_MKKA_G | PSCAN_MKKA1 | PSCAN_MKKA1_G | PSCAN_MKKA2 | PSCAN_MKKA2_G, DISALLOW_ADHOC_11A_TURB,
1515 BMZERO,
1516 BMZERO,
1517 BMZERO,
1518 BM(F2_2412_2462, F1_2467_2472, F2_2484_2484, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1519 BM(G2_2412_2462, G1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1520 BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1522 {MKKC, MKK, NO_DFS, NO_PSCAN, NO_REQ,
1523 BMZERO,
1524 BMZERO,
1525 BMZERO,
1526 BM(F2_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1),
1527 BM(G2_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1),
1528 BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1530 {WORLD, ETSI, NO_DFS, NO_PSCAN, NO_REQ,
1531 BMZERO,
1532 BMZERO,
1533 BMZERO,
1534 BM(F2_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1),
1535 BM(G2_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1),
1536 BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1538 {WOR0_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
1539 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
1540 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1541 BMZERO,
1542 BM(W1_2412_2412,W1_2437_2442,W1_2462_2462,W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, -1, -1),
1543 BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462,WG1_2472_2472,WG1_2417_2432,WG1_2447_2457,WG1_2467_2467, -1, -1, -1, -1, -1),
1544 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1546 {WOR01_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
1547 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
1548 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1549 BMZERO,
1550 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432, W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
1551 BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG1_2417_2432, WG1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
1552 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1554 {WOR02_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
1555 BM(W1_5260_5320, W1_5180_5240,W1_5170_5230,W1_5745_5825,W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
1556 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1557 BMZERO,
1558 BM(W1_2412_2412,W1_2437_2442,W1_2462_2462, W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
1559 BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462, WG1_2472_2472,WG1_2417_2432, WG1_2447_2457, WG1_2467_2467, -1, -1, -1, -1, -1),
1560 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1562 {EU1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
1563 BM(W1_5260_5320, W1_5180_5240,W1_5170_5230,W1_5745_5825,W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
1564 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1565 BMZERO,
1566 BM(W1_2412_2412,W1_2437_2442,W1_2462_2462, W2_2472_2472,W1_2417_2432, W1_2447_2457, W2_2467_2467, -1, -1, -1, -1, -1),
1567 BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462, WG2_2472_2472,WG1_2417_2432, WG1_2447_2457, WG2_2467_2467, -1, -1, -1, -1, -1),
1568 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1570 {WOR1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1571 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
1572 BMZERO,
1573 BMZERO,
1574 BM(W1_2412_2412,W1_2437_2442,W1_2462_2462,W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, -1, -1),
1575 BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462,WG1_2472_2472,WG1_2417_2432,WG1_2447_2457,WG1_2467_2467, -1, -1, -1, -1, -1),
1576 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1578 {WOR2_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1579 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
1580 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1581 BMZERO,
1582 BM(W1_2412_2412,W1_2437_2442,W1_2462_2462,W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, -1, -1),
1583 BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462,WG1_2472_2472,WG1_2417_2432,WG1_2447_2457,WG1_2467_2467, -1, -1, -1, -1, -1),
1584 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1586 {WOR3_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
1587 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1),
1588 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1589 BMZERO,
1590 BM(W1_2412_2412,W1_2437_2442,W1_2462_2462,W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
1591 BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462,WG1_2472_2472,WG1_2417_2432,WG1_2447_2457,WG1_2467_2467,-1, -1, -1, -1, -1),
1592 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1594 {WOR4_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1595 BM(W2_5260_5320, W2_5180_5240, F2_5745_5805, W2_5825_5825, -1, -1, -1, -1, -1, -1, -1, -1),
1596 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1597 BMZERO,
1598 BM(W1_2412_2412,W1_2437_2442,W1_2462_2462, W1_2417_2432,W1_2447_2457,-1, -1, -1, -1, -1, -1, -1),
1599 BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462, WG1_2417_2432,WG1_2447_2457,-1, -1, -1, -1, -1, -1, -1),
1600 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1602 {WOR5_ETSIC, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1603 BM(W1_5260_5320, W2_5180_5240, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1604 BMZERO,
1605 BMZERO,
1606 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W2_2472_2472, W1_2417_2432, W1_2447_2457, W2_2467_2467, -1, -1, -1, -1, -1),
1607 BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG2_2472_2472, WG1_2417_2432, WG1_2447_2457, WG2_2467_2467, -1, -1, -1, -1, -1),
1608 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1610 {WOR9_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1611 BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1),
1612 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1613 BMZERO,
1614 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432, W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
1615 BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG1_2417_2432, WG1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
1616 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1618 {WORA_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1619 BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1),
1620 BMZERO,
1621 BMZERO,
1622 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
1623 BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG1_2472_2472, WG1_2417_2432, WG1_2447_2457, WG1_2467_2467, -1, -1, -1, -1, -1),
1624 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1626 {NULL1, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ,
1627 BMZERO,
1628 BMZERO,
1629 BMZERO,
1630 BMZERO,
1631 BMZERO,
1632 BMZERO}
1635 struct cmode {
1636 u_int mode;
1637 u_int flags;
1640 static const struct cmode modes[] = {
1641 { HAL_MODE_TURBO, CHANNEL_ST}, /* TURBO means 11a Static Turbo */
1642 { HAL_MODE_11A, CHANNEL_A},
1643 { HAL_MODE_11B, CHANNEL_B},
1644 { HAL_MODE_11G, CHANNEL_G},
1645 { HAL_MODE_11G_TURBO, CHANNEL_108G},
1646 { HAL_MODE_11A_TURBO, CHANNEL_108A},
1647 { HAL_MODE_11NG_HT20, CHANNEL_G_HT20},
1648 { HAL_MODE_11NG_HT40PLUS, CHANNEL_G_HT40PLUS},
1649 { HAL_MODE_11NG_HT40MINUS, CHANNEL_G_HT40MINUS},
1650 { HAL_MODE_11NA_HT20, CHANNEL_A_HT20},
1651 { HAL_MODE_11NA_HT40PLUS, CHANNEL_A_HT40PLUS},
1652 { HAL_MODE_11NA_HT40MINUS, CHANNEL_A_HT40MINUS},
1655 static int
1656 chansort(const void *a, const void *b)
1658 #define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
1659 const HAL_CHANNEL_INTERNAL *ca = a;
1660 const HAL_CHANNEL_INTERNAL *cb = b;
1662 return (ca->channel == cb->channel) ?
1663 (ca->channelFlags & CHAN_FLAGS) -
1664 (cb->channelFlags & CHAN_FLAGS) :
1665 ca->channel - cb->channel;
1666 #undef CHAN_FLAGS
1668 typedef int ath_hal_cmp_t(const void *, const void *);
1669 static void ath_hal_sort(void *a, size_t n, size_t es, ath_hal_cmp_t *cmp);
1670 static COUNTRY_CODE_TO_ENUM_RD* findCountry(HAL_CTRY_CODE countryCode);
1671 static HAL_BOOL getWmRD(struct ath_hal *ah, COUNTRY_CODE_TO_ENUM_RD *country, uint16_t channelFlag, REG_DOMAIN *rd);
1674 static uint16_t
1675 getEepromRD(struct ath_hal *ah)
1677 return AH_PRIVATE(ah)->ah_currentRD &~ WORLDWIDE_ROAMING_FLAG;
1681 * Test to see if the bitmask array is all zeros
1683 static HAL_BOOL
1684 isChanBitMaskZero(uint64_t *bitmask)
1686 #if BMLEN > 2
1687 #error "add more cases"
1688 #endif
1689 #if BMLEN > 1
1690 if (bitmask[1] != 0)
1691 return AH_FALSE;
1692 #endif
1693 return (bitmask[0] == 0);
1697 * Return whether or not the regulatory domain/country in EEPROM
1698 * is acceptable.
1700 static HAL_BOOL
1701 isEepromValid(struct ath_hal *ah)
1703 uint16_t rd = getEepromRD(ah);
1704 int i;
1706 if (rd & COUNTRY_ERD_FLAG) {
1707 uint16_t cc = rd &~ COUNTRY_ERD_FLAG;
1708 for (i = 0; i < N(allCountries); i++)
1709 if (allCountries[i].countryCode == cc)
1710 return AH_TRUE;
1711 } else {
1712 for (i = 0; i < N(regDomainPairs); i++)
1713 if (regDomainPairs[i].regDmnEnum == rd)
1714 return AH_TRUE;
1716 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1717 "%s: invalid regulatory domain/country code 0x%x\n", __func__, rd);
1718 return AH_FALSE;
1722 * Returns whether or not the specified country code
1723 * is allowed by the EEPROM setting
1725 static HAL_BOOL
1726 isCountryCodeValid(struct ath_hal *ah, HAL_CTRY_CODE cc)
1728 uint16_t rd;
1730 /* Default setting requires no checks */
1731 if (cc == CTRY_DEFAULT)
1732 return AH_TRUE;
1733 #ifdef AH_DEBUG_COUNTRY
1734 if (cc == CTRY_DEBUG)
1735 return AH_TRUE;
1736 #endif
1737 rd = getEepromRD(ah);
1738 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: EEPROM regdomain 0x%x\n",
1739 __func__, rd);
1741 if (rd & COUNTRY_ERD_FLAG) {
1742 /* EEP setting is a country - config shall match */
1743 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1744 "%s: EEPROM setting is country code %u\n", __func__,
1745 rd &~ COUNTRY_ERD_FLAG);
1746 return (cc == (rd & ~COUNTRY_ERD_FLAG));
1747 } else if (rd == DEBUG_REG_DMN || rd == NO_ENUMRD) {
1748 /* Set to Debug or AllowAnyCountry mode - allow any setting */
1749 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: rd %d allowed\n",
1750 __func__, rd);
1751 return AH_TRUE;
1752 #ifdef AH_SUPPORT_11D
1753 } else if ((rd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) {
1754 int i;
1755 for (i=0; i < N(allCountries); i++) {
1756 if (cc == allCountries[i].countryCode)
1757 return AH_TRUE;
1759 #endif
1760 } else {
1761 int i;
1762 for (i = 0; i < N(allCountries); i++) {
1763 if (cc == allCountries[i].countryCode &&
1764 allCountries[i].regDmnEnum == rd)
1765 return AH_TRUE;
1768 return AH_FALSE;
1772 * Return the mask of available modes based on the hardware
1773 * capabilities and the specified country code and reg domain.
1775 static u_int
1776 ath_hal_getwmodesnreg(struct ath_hal *ah, COUNTRY_CODE_TO_ENUM_RD *country,
1777 REG_DOMAIN *rd5GHz)
1779 u_int modesAvail;
1781 /* Get modes that HW is capable of */
1782 modesAvail = ath_hal_getWirelessModes(ah);
1784 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1785 "%s: wireless modes 0x%x cc %u rd %u\n",
1786 __func__, modesAvail, country->countryCode, country->regDmnEnum);
1788 /* Check country regulations for allowed modes */
1789 if ((modesAvail & (HAL_MODE_11A_TURBO|HAL_MODE_TURBO)) &&
1790 !country->allow11aTurbo) {
1791 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1792 "%s: disallow 11aTurbo\n", __func__);
1793 modesAvail &= ~(HAL_MODE_11A_TURBO | HAL_MODE_TURBO);
1795 if ((modesAvail & HAL_MODE_11G_TURBO) && !country->allow11gTurbo) {
1796 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1797 "%s: disallow 11gTurbo\n", __func__);
1798 modesAvail &= ~HAL_MODE_11G_TURBO;
1800 if ((modesAvail & HAL_MODE_11G) && !country->allow11g) {
1801 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1802 "%s: disallow 11g\n", __func__);
1803 modesAvail &= ~HAL_MODE_11G;
1805 if ((modesAvail & HAL_MODE_11A) && isChanBitMaskZero(rd5GHz->chan11a)) {
1806 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1807 "%s: disallow 11a\n", __func__);
1808 modesAvail &= ~HAL_MODE_11A;
1811 if ((modesAvail & HAL_MODE_11NG_HT20) && !country->allow11ng20) {
1812 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1813 "%s: disallow 11g HT20\n", __func__);
1814 modesAvail &= ~HAL_MODE_11NG_HT20;
1816 if ((modesAvail & HAL_MODE_11NA_HT20) && !country->allow11na20) {
1817 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1818 "%s: disallow 11a HT20\n", __func__);
1819 modesAvail &= ~HAL_MODE_11NA_HT20;
1821 if ((modesAvail & HAL_MODE_11NG_HT40PLUS) && !country->allow11ng40) {
1822 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1823 "%s: disallow 11g HT40+\n", __func__);
1824 modesAvail &= ~HAL_MODE_11NG_HT40PLUS;
1826 if ((modesAvail & HAL_MODE_11NG_HT40MINUS) && !country->allow11ng40) {
1827 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1828 "%s: disallow 11g HT40-\n", __func__);
1829 modesAvail &= ~HAL_MODE_11NG_HT40MINUS;
1831 if ((modesAvail & HAL_MODE_11NA_HT40PLUS) && !country->allow11na40) {
1832 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1833 "%s: disallow 11a HT40+\n", __func__);
1834 modesAvail &= ~HAL_MODE_11NA_HT40PLUS;
1836 if ((modesAvail & HAL_MODE_11NA_HT40MINUS) && !country->allow11na40) {
1837 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1838 "%s: disallow 11a HT40-\n", __func__);
1839 modesAvail &= ~HAL_MODE_11NA_HT40MINUS;
1842 return modesAvail;
1846 * Return the mask of available modes based on the hardware
1847 * capabilities and the specified country code.
1850 u_int
1851 ath_hal_getwirelessmodes(struct ath_hal *ah, HAL_CTRY_CODE cc)
1853 COUNTRY_CODE_TO_ENUM_RD *country = AH_NULL;
1854 u_int mode = 0;
1855 REG_DOMAIN rd;
1857 country = findCountry(cc);
1858 if (country != AH_NULL) {
1859 if (getWmRD(ah, country, ~CHANNEL_2GHZ, &rd))
1860 mode = ath_hal_getwmodesnreg(ah, country, &rd);
1862 return mode;
1866 * Return if device is public safety.
1868 HAL_BOOL
1869 ath_hal_ispublicsafetysku(struct ath_hal *ah)
1871 uint16_t rd = getEepromRD(ah);
1873 switch (rd) {
1874 case FCC4_FCCA:
1875 case CTRY_UNITED_STATES_FCC49 | COUNTRY_ERD_FLAG:
1876 return AH_TRUE;
1877 case DEBUG_REG_DMN:
1878 case NO_ENUMRD:
1879 if (AH_PRIVATE(ah)->ah_countryCode == CTRY_UNITED_STATES_FCC49)
1880 return AH_TRUE;
1881 break;
1883 return AH_FALSE;
1887 * Find the pointer to the country element in the country table
1888 * corresponding to the country code
1890 static COUNTRY_CODE_TO_ENUM_RD*
1891 findCountry(HAL_CTRY_CODE countryCode)
1893 int i;
1895 for (i = 0; i < N(allCountries); i++) {
1896 if (allCountries[i].countryCode == countryCode)
1897 return &allCountries[i];
1899 return AH_NULL; /* Not found */
1903 * Calculate a default country based on the EEPROM setting.
1905 static HAL_CTRY_CODE
1906 getDefaultCountry(struct ath_hal *ah)
1908 uint16_t rd;
1909 int i;
1911 rd = getEepromRD(ah);
1912 if (rd & COUNTRY_ERD_FLAG) {
1913 COUNTRY_CODE_TO_ENUM_RD *country = AH_NULL;
1914 uint16_t cc = rd & ~COUNTRY_ERD_FLAG;
1916 country = findCountry(cc);
1917 if (country != AH_NULL)
1918 return cc;
1921 * Check reg domains that have only one country
1923 for (i = 0; i < N(regDomainPairs); i++)
1924 if (regDomainPairs[i].regDmnEnum == rd) {
1925 if (regDomainPairs[i].singleCC != 0)
1926 return regDomainPairs[i].singleCC;
1927 else
1928 i = N(regDomainPairs);
1930 return CTRY_DEFAULT;
1933 static HAL_BOOL
1934 isValidRegDmn(int regDmn, REG_DOMAIN *rd)
1936 int i;
1938 for (i = 0; i < N(regDomains); i++) {
1939 if (regDomains[i].regDmnEnum == regDmn) {
1940 if (rd != AH_NULL) {
1941 OS_MEMCPY(rd, &regDomains[i],
1942 sizeof(REG_DOMAIN));
1944 return AH_TRUE;
1947 return AH_FALSE;
1950 static HAL_BOOL
1951 isValidRegDmnPair(int regDmnPair)
1953 int i;
1955 if (regDmnPair == NO_ENUMRD)
1956 return AH_FALSE;
1957 for (i = 0; i < N(regDomainPairs); i++) {
1958 if (regDomainPairs[i].regDmnEnum == regDmnPair)
1959 return AH_TRUE;
1961 return AH_FALSE;
1965 * Return the Wireless Mode Regulatory Domain based
1966 * on the country code and the wireless mode.
1968 static HAL_BOOL
1969 getWmRD(struct ath_hal *ah, COUNTRY_CODE_TO_ENUM_RD *country,
1970 uint16_t channelFlag, REG_DOMAIN *rd)
1972 int regDmn;
1973 REG_DMN_PAIR_MAPPING *regPair;
1974 uint64_t flags;
1976 if (country->countryCode == CTRY_DEFAULT) {
1977 uint16_t rdnum = getEepromRD(ah);
1979 if ((rdnum & COUNTRY_ERD_FLAG) == 0) {
1980 if (isValidRegDmn(rdnum, AH_NULL) ||
1981 isValidRegDmnPair(rdnum))
1982 regDmn = rdnum;
1983 else
1984 regDmn = country->regDmnEnum;
1985 } else
1986 regDmn = country->regDmnEnum;
1987 } else
1988 regDmn = country->regDmnEnum;
1989 regPair = AH_NULL;
1990 flags = NO_REQ;
1991 if ((regDmn & MULTI_DOMAIN_MASK) == 0) {
1992 int i;
1994 for (i = 0; i < N(regDomainPairs); i++) {
1995 if (regDomainPairs[i].regDmnEnum == regDmn) {
1996 regPair = &regDomainPairs[i];
1997 break;
2000 if (regPair == AH_NULL) {
2001 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2002 "%s: Failed to find reg domain pair %u\n",
2003 __func__, regDmn);
2004 return AH_FALSE;
2006 if (channelFlag & CHANNEL_2GHZ) {
2007 regDmn = regPair->regDmn2GHz;
2008 flags = regPair->flags2GHz;
2009 } else {
2010 regDmn = regPair->regDmn5GHz;
2011 flags = regPair->flags5GHz;
2016 * We either started with a unitary reg domain or we've found the
2017 * unitary reg domain of the pair
2019 if (isValidRegDmn(regDmn, rd)) {
2020 if (regPair != AH_NULL)
2021 rd->pscan &= regPair->pscanMask;
2022 if ((country->regDmnEnum & MULTI_DOMAIN_MASK) == 0 &&
2023 flags != NO_REQ)
2024 rd->flags = flags;
2025 return AH_TRUE;
2026 } else {
2027 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2028 "%s: Failed to find unitary reg domain %u\n", __func__,
2029 country->regDmnEnum);
2030 return AH_FALSE;
2034 static HAL_BOOL
2035 IS_BIT_SET(int bit, const uint64_t bitmask[])
2037 int byteOffset, bitnum;
2038 uint64_t val;
2040 byteOffset = bit/64;
2041 bitnum = bit - byteOffset*64;
2042 val = ((uint64_t) 1) << bitnum;
2043 return (bitmask[byteOffset] & val) != 0;
2046 /* Add given regclassid into regclassids array upto max of maxregids */
2047 static void
2048 ath_add_regclassid(uint8_t *regclassids, u_int maxregids,
2049 u_int *nregids, uint8_t regclassid)
2051 int i;
2053 /* Is regclassid valid? */
2054 if (regclassid == 0)
2055 return;
2057 for (i = 0; i < maxregids; i++) {
2058 if (regclassids[i] == regclassid) /* already present */
2059 return;
2060 if (regclassids[i] == 0) { /* free slot */
2061 regclassids[i] = regclassid;
2062 (*nregids)++;
2063 return;
2069 * Setup the channel list based on the information in the EEPROM and
2070 * any supplied country code. Note that we also do a bunch of EEPROM
2071 * verification here and setup certain regulatory-related access
2072 * control data used later on.
2075 HAL_BOOL
2076 ath_hal_init_channels(struct ath_hal *ah,
2077 HAL_CHANNEL *chans, u_int maxchans, u_int *nchans,
2078 uint8_t *regclassids, u_int maxregids, u_int *nregids,
2079 HAL_CTRY_CODE cc, u_int modeSelect,
2080 HAL_BOOL enableOutdoor, HAL_BOOL enableExtendedChannels)
2082 #define CHANNEL_HALF_BW 10
2083 #define CHANNEL_QUARTER_BW 5
2084 u_int modesAvail;
2085 uint16_t maxChan;
2086 COUNTRY_CODE_TO_ENUM_RD *country = AH_NULL;
2087 REG_DOMAIN rd5GHz, rd2GHz;
2088 const struct cmode *cm;
2089 HAL_CHANNEL_INTERNAL *ichans = &AH_PRIVATE(ah)->ah_channels[0];
2090 int next, b;
2091 uint8_t ctl;
2092 int is_quarterchan_cap, is_halfchan_cap;
2094 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: cc %u mode 0x%x%s%s\n",
2095 __func__, cc, modeSelect, enableOutdoor? " Enable outdoor" : " ",
2096 enableExtendedChannels ? " Enable ecm" : "");
2099 * Validate the EEPROM setting and setup defaults
2101 if (!isEepromValid(ah)) {
2103 * Don't return any channels if the EEPROM has an
2104 * invalid regulatory domain/country code setting.
2106 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2107 "%s: invalid EEPROM contents\n",__func__);
2108 return AH_FALSE;
2111 AH_PRIVATE(ah)->ah_countryCode = getDefaultCountry(ah);
2113 #ifndef AH_SUPPORT_11D
2114 if (AH_PRIVATE(ah)->ah_countryCode == CTRY_DEFAULT) {
2115 #endif
2117 * We now have enough state to validate any country code
2118 * passed in by the caller.
2120 if (!isCountryCodeValid(ah, cc)) {
2121 /* NB: Atheros silently ignores invalid country codes */
2122 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2123 "%s: invalid country code %d\n", __func__, cc);
2124 return AH_FALSE;
2126 AH_PRIVATE(ah)->ah_countryCode = cc & COUNTRY_CODE_MASK;
2127 #ifndef AH_SUPPORT_11D
2129 #endif
2131 /* Get pointers to the country element and the reg domain elements */
2132 country = findCountry(AH_PRIVATE(ah)->ah_countryCode);
2134 if (country == AH_NULL) {
2135 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "NULL Country!, cc= %d\n",
2136 AH_PRIVATE(ah)->ah_countryCode);
2137 return AH_FALSE;
2140 if (!getWmRD(ah, country, ~CHANNEL_2GHZ, &rd5GHz)) {
2141 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2142 "%s: no unitary 5GHz regdomain for country %u\n",
2143 __func__, AH_PRIVATE(ah)->ah_countryCode);
2144 return AH_FALSE;
2146 if (!getWmRD(ah, country, CHANNEL_2GHZ, &rd2GHz)) {
2147 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2148 "%s: no unitary 2GHz regdomain for country %u\n",
2149 __func__, AH_PRIVATE(ah)->ah_countryCode);
2150 return AH_FALSE;
2153 modesAvail = ath_hal_getwmodesnreg(ah, country, &rd5GHz);
2154 maxChan = !enableOutdoor ? country->outdoorChanStart : 7000;
2155 is_halfchan_cap = AH_PRIVATE(ah)->ah_caps.halChanHalfRate;
2156 is_quarterchan_cap = AH_PRIVATE(ah)->ah_caps.halChanQuarterRate;
2158 if (maxchans > N(AH_PRIVATE(ah)->ah_channels))
2159 maxchans = N(AH_PRIVATE(ah)->ah_channels);
2160 next = 0;
2161 for (cm = modes; cm < &modes[N(modes)]; cm++) {
2162 uint16_t c, c_hi, c_lo;
2163 uint64_t *channelBM = AH_NULL;
2164 REG_DOMAIN *rd = AH_NULL;
2165 REG_DMN_FREQ_BAND *fband = AH_NULL,*freqs;
2166 int low_adj, hi_adj, channelSep, lastc;
2168 if ((cm->mode & modeSelect) == 0) {
2169 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2170 "%s: skip mode 0x%x flags 0x%x\n",
2171 __func__, cm->mode, cm->flags);
2172 continue;
2174 if ((cm->mode & modesAvail) == 0) {
2175 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2176 "%s: !avail mode 0x%x (0x%x) flags 0x%x\n",
2177 __func__, modesAvail, cm->mode, cm->flags);
2178 continue;
2180 if (!ath_hal_getChannelEdges(ah, cm->flags, &c_lo, &c_hi)) {
2181 /* channel not supported by hardware, skip it */
2182 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2183 "%s: channels 0x%x not supported by hardware\n",
2184 __func__,cm->flags);
2185 continue;
2187 switch (cm->mode) {
2188 case HAL_MODE_TURBO:
2189 rd = &rd5GHz;
2190 channelBM = rd->chan11a_turbo;
2191 freqs = &regDmn5GhzTurboFreq[0];
2192 ctl = rd->conformanceTestLimit | CTL_TURBO;
2193 break;
2194 case HAL_MODE_11A:
2195 case HAL_MODE_11NA_HT20:
2196 case HAL_MODE_11NA_HT40PLUS:
2197 case HAL_MODE_11NA_HT40MINUS:
2198 rd = &rd5GHz;
2199 channelBM = rd->chan11a;
2200 freqs = &regDmn5GhzFreq[0];
2201 ctl = rd->conformanceTestLimit;
2202 break;
2203 case HAL_MODE_11B:
2204 rd = &rd2GHz;
2205 channelBM = rd->chan11b;
2206 freqs = &regDmn2GhzFreq[0];
2207 ctl = rd->conformanceTestLimit | CTL_11B;
2208 break;
2209 case HAL_MODE_11G:
2210 case HAL_MODE_11NG_HT20:
2211 case HAL_MODE_11NG_HT40PLUS:
2212 case HAL_MODE_11NG_HT40MINUS:
2213 rd = &rd2GHz;
2214 channelBM = rd->chan11g;
2215 freqs = &regDmn2Ghz11gFreq[0];
2216 ctl = rd->conformanceTestLimit | CTL_11G;
2217 break;
2218 case HAL_MODE_11G_TURBO:
2219 rd = &rd2GHz;
2220 channelBM = rd->chan11g_turbo;
2221 freqs = &regDmn2Ghz11gTurboFreq[0];
2222 ctl = rd->conformanceTestLimit | CTL_108G;
2223 break;
2224 case HAL_MODE_11A_TURBO:
2225 rd = &rd5GHz;
2226 channelBM = rd->chan11a_dyn_turbo;
2227 freqs = &regDmn5GhzTurboFreq[0];
2228 ctl = rd->conformanceTestLimit | CTL_108G;
2229 break;
2230 default:
2231 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2232 "%s: Unkonwn HAL mode 0x%x\n", __func__, cm->mode);
2233 continue;
2235 if (isChanBitMaskZero(channelBM))
2236 continue;
2238 * Setup special handling for HT40 channels; e.g.
2239 * 5G HT40 channels require 40Mhz channel separation.
2241 hi_adj = (cm->mode == HAL_MODE_11NA_HT40PLUS ||
2242 cm->mode == HAL_MODE_11NG_HT40PLUS) ? -20 : 0;
2243 low_adj = (cm->mode == HAL_MODE_11NA_HT40MINUS ||
2244 cm->mode == HAL_MODE_11NG_HT40MINUS) ? 20 : 0;
2245 channelSep = (cm->mode == HAL_MODE_11NA_HT40PLUS ||
2246 cm->mode == HAL_MODE_11NA_HT40MINUS) ? 40 : 0;
2248 for (b = 0; b < 64*BMLEN; b++) {
2249 if (!IS_BIT_SET(b, channelBM))
2250 continue;
2251 fband = &freqs[b];
2252 lastc = 0;
2254 ath_add_regclassid(regclassids, maxregids,
2255 nregids, fband->regClassId);
2257 for (c = fband->lowChannel + low_adj;
2258 c <= fband->highChannel + hi_adj;
2259 c += fband->channelSep) {
2260 HAL_CHANNEL_INTERNAL icv;
2262 if (!(c_lo <= c && c <= c_hi)) {
2263 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2264 "%s: c %u out of range [%u..%u]\n",
2265 __func__, c, c_lo, c_hi);
2266 continue;
2268 if ((fband->channelBW == CHANNEL_HALF_BW) &&
2269 !is_halfchan_cap) {
2270 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2271 "%s: Skipping %u half rate channel\n",
2272 __func__, c);
2273 continue;
2276 if ((fband->channelBW == CHANNEL_QUARTER_BW) &&
2277 !is_quarterchan_cap) {
2278 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2279 "%s: Skipping %u quarter rate channel\n",
2280 __func__, c);
2281 continue;
2284 if (((c+fband->channelSep)/2) > (maxChan+HALF_MAXCHANBW)) {
2285 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2286 "%s: c %u > maxChan %u\n",
2287 __func__, c, maxChan);
2288 continue;
2290 if (next >= maxchans){
2291 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2292 "%s: too many channels for channel table\n",
2293 __func__);
2294 goto done;
2296 if ((fband->usePassScan & IS_ECM_CHAN) &&
2297 !enableExtendedChannels) {
2298 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2299 "Skipping ecm channel\n");
2300 continue;
2302 /* XXX needs to be in ath_hal_checkchannel */
2303 if ((rd->flags & NO_HOSTAP) &&
2304 (AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP)) {
2305 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2306 "Skipping HOSTAP channel\n");
2307 continue;
2310 * Make sure that channel separation
2311 * meets the requirement.
2313 if (lastc && channelSep &&
2314 (c-lastc) < channelSep)
2315 continue;
2317 OS_MEMZERO(&icv, sizeof(icv));
2318 icv.channel = c;
2319 icv.channelFlags = cm->flags;
2320 switch (fband->channelBW) {
2321 case CHANNEL_HALF_BW:
2322 icv.channelFlags |= CHANNEL_HALF;
2323 break;
2324 case CHANNEL_QUARTER_BW:
2325 icv.channelFlags |= CHANNEL_QUARTER;
2326 break;
2329 icv.maxRegTxPower = fband->powerDfs;
2330 icv.antennaMax = fband->antennaMax;
2331 icv.regDmnFlags = rd->flags;
2332 icv.conformanceTestLimit = ctl;
2333 if (fband->usePassScan & rd->pscan)
2334 icv.channelFlags |= CHANNEL_PASSIVE;
2335 else
2336 icv.channelFlags &= ~CHANNEL_PASSIVE;
2337 lastc = c;
2338 if (fband->useDfs & rd->dfsMask) {
2339 /* DFS and HT40 don't mix */
2340 if (cm->mode == HAL_MODE_11NA_HT40PLUS ||
2341 cm->mode == HAL_MODE_11NA_HT40MINUS)
2342 continue;
2343 icv.privFlags = CHANNEL_DFS;
2344 } else
2345 icv.privFlags = 0;
2346 if (rd->flags & LIMIT_FRAME_4MS)
2347 icv.privFlags |= CHANNEL_4MS_LIMIT;
2349 ichans[next++] = icv;
2353 done:
2354 if (next != 0) {
2355 int i;
2357 /* XXX maxchans set above so this cannot happen? */
2358 if (next > N(AH_PRIVATE(ah)->ah_channels)) {
2359 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2360 "%s: too many channels %u; truncating to %u\n",
2361 __func__, next,
2362 (int) N(AH_PRIVATE(ah)->ah_channels));
2363 next = N(AH_PRIVATE(ah)->ah_channels);
2367 * Keep a private copy of the channel list so we can
2368 * constrain future requests to only these channels
2370 ath_hal_sort(ichans, next, sizeof(HAL_CHANNEL_INTERNAL),
2371 chansort);
2372 AH_PRIVATE(ah)->ah_nchan = next;
2375 * Copy the channel list to the public channel list
2377 for (i = 0; i < next; i++) {
2378 chans[i].channel = ichans[i].channel;
2379 chans[i].channelFlags = ichans[i].channelFlags;
2380 chans[i].privFlags = ichans[i].privFlags;
2381 chans[i].maxRegTxPower = ichans[i].maxRegTxPower;
2384 * Retrieve power limits.
2386 ath_hal_getpowerlimits(ah, chans, next);
2387 for (i = 0; i < next; i++) {
2388 ichans[i].maxTxPower = chans[i].maxTxPower;
2389 ichans[i].minTxPower = chans[i].minTxPower;
2392 *nchans = next;
2393 /* XXX copy private setting to public area */
2394 ah->ah_countryCode = AH_PRIVATE(ah)->ah_countryCode;
2395 return (next != 0);
2396 #undef CHANNEL_HALF_BW
2397 #undef CHANNEL_QUARTER_BW
2401 * Return whether or not the specified channel is ok to use
2402 * based on the current regulatory domain constraints and
2403 * DFS interference.
2405 HAL_CHANNEL_INTERNAL *
2406 ath_hal_checkchannel(struct ath_hal *ah, const HAL_CHANNEL *c)
2408 #define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
2409 HAL_CHANNEL_INTERNAL *base, *cc;
2410 /* NB: be wary of user-specified channel flags */
2411 int flags = c->channelFlags & CHAN_FLAGS;
2412 int n, lim, d;
2414 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2415 "%s: channel %u/0x%x (0x%x) requested\n",
2416 __func__, c->channel, c->channelFlags, flags);
2419 * Check current channel to avoid the lookup.
2421 cc = AH_PRIVATE(ah)->ah_curchan;
2422 if (cc != AH_NULL && cc->channel == c->channel &&
2423 (cc->channelFlags & CHAN_FLAGS) == flags) {
2424 if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
2425 (cc->channelFlags & CHANNEL_DFS))
2426 return AH_NULL;
2427 else
2428 return cc;
2431 /* binary search based on known sorting order */
2432 base = AH_PRIVATE(ah)->ah_channels;
2433 n = AH_PRIVATE(ah)->ah_nchan;
2434 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: channels=%u\n",
2435 __func__, n);
2436 /* binary search based on known sorting order */
2437 for (lim = n; lim != 0; lim >>= 1) {
2438 cc = &base[lim>>1];
2439 d = c->channel - cc->channel;
2440 if (d == 0) {
2441 if ((cc->channelFlags & CHAN_FLAGS) == flags) {
2442 if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
2443 (cc->channelFlags & CHANNEL_DFS))
2444 return AH_NULL;
2445 else
2446 return cc;
2448 d = flags - (cc->channelFlags & CHAN_FLAGS);
2450 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: channel %u/0x%x d %d\n",
2451 __func__, cc->channel, cc->channelFlags, d);
2452 if (d > 0) {
2453 base = cc + 1;
2454 lim--;
2457 HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: no match for %u/0x%x\n",
2458 __func__, c->channel, c->channelFlags);
2459 return AH_NULL;
2460 #undef CHAN_FLAGS
2464 * Return the max allowed antenna gain and apply any regulatory
2465 * domain specific changes.
2467 * NOTE: a negative reduction is possible in RD's that only
2468 * measure radiated power (e.g., ETSI) which would increase
2469 * that actual conducted output power (though never beyond
2470 * the calibrated target power).
2472 u_int
2473 ath_hal_getantennareduction(struct ath_hal *ah, HAL_CHANNEL *chan, u_int twiceGain)
2475 HAL_CHANNEL_INTERNAL *ichan=AH_NULL;
2476 int8_t antennaMax;
2478 if ((ichan = ath_hal_checkchannel(ah, chan)) != AH_NULL) {
2479 antennaMax = twiceGain - ichan->antennaMax*2;
2480 return (antennaMax < 0) ? 0 : antennaMax;
2481 } else {
2482 /* Failed to find the correct index - may be a debug channel */
2483 return 0;
2488 /* XXX - maybe move ctl decision into channel set area or
2489 into the tables so no decision is needed in the code */
2491 #define isWwrSKU(_ah) \
2492 ((getEepromRD((_ah)) & WORLD_SKU_MASK) == WORLD_SKU_PREFIX || \
2493 getEepromRD(_ah) == WORLD)
2497 * Return the test group from the specified channel from
2498 * the regulatory table.
2500 * TODO: CTL for 11B CommonMode when regulatory domain is unknown
2502 u_int
2503 ath_hal_getctl(struct ath_hal *ah, HAL_CHANNEL *chan)
2505 u_int ctl = NO_CTL;
2506 HAL_CHANNEL_INTERNAL *ichan;
2508 /* Special CTL to signify WWR SKU without a known country */
2509 if (AH_PRIVATE(ah)->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)) {
2510 if (IS_CHAN_B(chan)) {
2511 ctl = SD_NO_CTL | CTL_11B;
2512 } else if (IS_CHAN_G(chan)) {
2513 ctl = SD_NO_CTL | CTL_11G;
2514 } else if (IS_CHAN_108G(chan)) {
2515 ctl = SD_NO_CTL | CTL_108G;
2516 } else if (IS_CHAN_T(chan)) {
2517 ctl = SD_NO_CTL | CTL_TURBO;
2518 } else {
2519 ctl = SD_NO_CTL | CTL_11A;
2521 } else {
2522 if ((ichan = ath_hal_checkchannel(ah, chan)) != AH_NULL) {
2523 ctl = ichan->conformanceTestLimit;
2524 /* limit 11G OFDM power */
2525 if (IS_CHAN_PUREG(chan) &&
2526 (ctl & CTL_MODE_M) == CTL_11B)
2527 ctl = (ctl &~ CTL_MODE_M) | CTL_11G;
2530 return ctl;
2534 * Return whether or not a noise floor check is required in
2535 * the current regulatory domain for the specified channel.
2537 HAL_BOOL
2538 ath_hal_getnfcheckrequired(struct ath_hal *ah, HAL_CHANNEL *chan)
2540 HAL_CHANNEL_INTERNAL *ichan;
2542 if ((ichan = ath_hal_checkchannel(ah, chan)) != AH_NULL)
2543 return ((ichan->regDmnFlags & NEED_NFC) ? AH_TRUE : AH_FALSE);
2544 return AH_FALSE;
2548 * Insertion sort.
2550 #define swap(_a, _b, _size) { \
2551 uint8_t *s = _b; \
2552 int i = _size; \
2553 do { \
2554 uint8_t tmp = *_a; \
2555 *_a++ = *s; \
2556 *s++ = tmp; \
2557 } while (--i); \
2558 _a -= _size; \
2561 static void
2562 ath_hal_sort(void *a, size_t n, size_t size, ath_hal_cmp_t *cmp)
2564 uint8_t *aa = a;
2565 uint8_t *ai, *t;
2567 for (ai = aa+size; --n >= 1; ai += size)
2568 for (t = ai; t > aa; t -= size) {
2569 uint8_t *u = t - size;
2570 if (cmp(u, t) <= 0)
2571 break;
2572 swap(u, t, size);