ah_regdomain.c revision 185377
1/*
2 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
3 * Copyright (c) 2005-2006 Atheros Communications, Inc.
4 * All rights reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * $Id: ah_regdomain.c,v 1.17 2008/11/10 04:08:00 sam Exp $
19 */
20#include "opt_ah.h"
21
22#include "ah.h"
23#include "ah_internal.h"
24#include "ah_eeprom.h"
25#include "ah_devid.h"
26
27/*
28 * XXX this code needs a audit+review
29 */
30
31/* used throughout this file... */
32#define	N(a)	(sizeof (a) / sizeof (a[0]))
33
34#define HAL_MODE_11A_TURBO	HAL_MODE_108A
35#define HAL_MODE_11G_TURBO	HAL_MODE_108G
36
37/* 10MHz is half the 11A bandwidth used to determine upper edge freq
38   of the outdoor channel */
39#define HALF_MAXCHANBW		10
40
41/*
42 * Used to set the RegDomain bitmask which chooses which frequency
43 * band specs are used.
44 */
45
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 */
49
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)))}
75
76/*
77 * Country/Region Codes
78 * Numbering from ISO 3166
79 */
80enum 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) */
137
138    CTRY_JAPAN7		      = 4007,	 /* Japan (J7) */
139    CTRY_JAPAN8		      = 4008,	 /* Japan (J8) */
140    CTRY_JAPAN9		      = 4009,	 /* Japan (J9) */
141
142    CTRY_JAPAN10	      = 4010,	 /* Japan (J10) */
143    CTRY_JAPAN11	      = 4011,	 /* Japan (J11) */
144    CTRY_JAPAN12	      = 4012,	 /* Japan (J12) */
145
146    CTRY_JAPAN13	      = 4013,	 /* Japan (J13) */
147    CTRY_JAPAN14	      = 4014,	 /* Japan (J14) */
148    CTRY_JAPAN15	      = 4015,	 /* Japan (J15) */
149
150    CTRY_JAPAN16	      = 4016,	 /* Japan (J16) */
151    CTRY_JAPAN17	      = 4017,	 /* Japan (J17) */
152    CTRY_JAPAN18	      = 4018,	 /* Japan (J18) */
153
154    CTRY_JAPAN19	      = 4019,	 /* Japan (J19) */
155    CTRY_JAPAN20	      = 4020,	 /* Japan (J20) */
156    CTRY_JAPAN21	      = 4021,	 /* Japan (J21) */
157
158    CTRY_JAPAN22	      = 4022,	 /* Japan (J22) */
159    CTRY_JAPAN23	      = 4023,	 /* Japan (J23) */
160    CTRY_JAPAN24	      = 4024,	 /* Japan (J24) */
161
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 */
224};
225
226
227/* Mask to check whether a domain is a multidomain or a single
228   domain */
229
230#define MULTI_DOMAIN_MASK 0xFF00
231
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.
236 */
237
238enum EnumRd {
239	/*
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.
248	 */
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 */
256
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 */
263
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) */
273
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) */
287
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 */
299
300	/*
301	 * World mode SKUs
302	 */
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) */
309
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 */
313
314	WOR9_WORLD	= 0x69,		/* World9 (WO9 SKU) */
315	WORA_WORLD	= 0x6A,		/* WorldA (WOA SKU) */
316
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 */
320
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 */
324
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 */
328
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 */
332
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 */
336
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 */
340
341	/* Following definitions are used only by s/w to map old
342 	 * Japan SKUs.
343	 */
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 */
352
353	/*
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.
359	 */
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 */
368
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 */
378
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,
384
385	APLD		= 0x0D50,	/* South Korea */
386
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,
399
400	NULL1		= 0x0198,
401	WORLD		= 0x0199,
402	DEBUG_REG_DMN	= 0x01ff,
403};
404
405#define	WORLD_SKU_MASK		0x00F0
406#define	WORLD_SKU_PREFIX	0x0060
407
408enum {					/* conformance test limits */
409	FCC	= 0x10,
410	MKK	= 0x40,
411	ETSI	= 0x30,
412};
413
414/*
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
418 * 0
419 */
420
421enum {
422	NO_REQ			= 0x00000000,
423	DISALLOW_ADHOC_11A	= 0x00000001,
424	DISALLOW_ADHOC_11A_TURB	= 0x00000002,
425	NEED_NFC		= 0x00000004,
426
427	ADHOC_PER_11D		= 0x00000008,  /* Start Ad-Hoc mode */
428	ADHOC_NO_11A		= 0x00000010,
429
430	PUBLIC_SAFETY_DOMAIN	= 0x00000020, 	/* public safety domain */
431	LIMIT_FRAME_4MS 	= 0x00000040, 	/* 4msec limit on the frame length */
432
433	NO_HOSTAP		= 0x00000080,	/* No HOSTAP mode opereation */
434};
435
436/*
437 * The following describe the bit masks for different passive scan
438 * capability/requirements per regdomain.
439 */
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
459
460/*
461 * THE following table is the mapping of regdomain pairs specified by
462 * an 8 bit regdomain value to the individual unitary reg domains
463 */
464
465typedef 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;
483
484static 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 },
489
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 },
496
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 },
503
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 },
506
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 },
517
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,  },
522
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 },
529
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 },
532
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 },
540
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 },
547
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 },
552
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 },
557
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 },
562
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 },
567
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 },
570
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 },
583};
584
585/*
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
589 */
590
591#define	NO_INTERSECT_REQ	0xFFFFFFFF
592#define	NO_UNION_REQ		0
593#define	MAX_MAPS		2
594
595struct ccmap {
596	char isoName[3];
597	HAL_CTRY_CODE countryCode;
598};
599
600
601/*
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.
605 */
606
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
614
615#define	YES	AH_TRUE
616#define	NO	AH_FALSE
617
618typedef 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;
630
631static 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 },
687
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 },
691
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 },
695
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 },
699
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 },
703
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 },
707
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 },
711
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 }
770};
771
772typedef 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;
787
788/* Bit masks for DFS per regdomain */
789
790enum {
791	NO_DFS   = 0x0000000000000000ULL,
792	DFS_FCC3 = 0x0000000000000001ULL,
793	DFS_ETSI = 0x0000000000000002ULL,
794	DFS_MKK4 = 0x0000000000000004ULL,
795};
796
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
801 */
802
803/*
804 * 5GHz 11A channel tags
805 */
806
807enum {
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,
817
818	F1_5120_5240,
819
820	F1_5170_5230,
821	F2_5170_5230,
822
823	F1_5180_5240,
824	F2_5180_5240,
825	F3_5180_5240,
826	F4_5180_5240,
827	F5_5180_5240,
828	F6_5180_5240,
829
830	F1_5180_5320,
831
832	F1_5240_5280,
833
834	F1_5260_5280,
835
836	F1_5260_5320,
837	F2_5260_5320,
838	F3_5260_5320,
839	F4_5260_5320,
840	F5_5260_5320,
841	F6_5260_5320,
842
843	F1_5260_5700,
844
845	F1_5280_5320,
846
847	F1_5500_5620,
848
849	F1_5500_5700,
850	F2_5500_5700,
851	F3_5500_5700,
852	F4_5500_5700,
853
854	F1_5745_5805,
855	F2_5745_5805,
856	F3_5745_5805,
857
858	F1_5745_5825,
859	F2_5745_5825,
860	F3_5745_5825,
861	F4_5745_5825,
862	F5_5745_5825,
863	F6_5745_5825,
864
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,
875};
876
877static 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 */
887
888	{ 5120, 5240, 5,  6, 20, 20, NO_DFS, NO_PSCAN, 0 },				/* F1_5120_5240 */
889
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 */
892
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 */
899
900	{ 5180, 5320, 20, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0 },				/* F1_5180_5320 */
901
902	{ 5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI, 0 },		/* F1_5240_5280 */
903
904	{ 5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 },	/* F1_5260_5280 */
905
906	{ 5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 },	/* F1_5260_5320 */
907
908	{ 5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3 , 0 },
909	/* F2_5260_5320 */
910
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 */
915
916	{ 5260, 5700, 5,  6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0 },		/* F1_5260_5700 */
917
918	{ 5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0 },		/* F1_5280_5320 */
919
920	{ 5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0 },				/* F1_5500_5620 */
921
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 */
927
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 */
937
938	/*
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.
942	 */
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 */
953};
954
955/*
956 * 5GHz Turbo (dynamic & static) tags
957 */
958
959enum {
960	T1_5130_5210,
961	T1_5250_5330,
962	T1_5370_5490,
963	T1_5530_5650,
964
965	T1_5150_5190,
966	T1_5230_5310,
967	T1_5350_5470,
968	T1_5510_5670,
969
970	T1_5200_5240,
971	T2_5200_5240,
972	T1_5210_5210,
973	T2_5210_5210,
974
975	T1_5280_5280,
976	T2_5280_5280,
977	T1_5250_5250,
978	T1_5290_5290,
979	T1_5250_5290,
980	T2_5250_5290,
981
982	T1_5540_5660,
983	T1_5760_5800,
984	T2_5760_5800,
985
986	T1_5765_5805,
987
988	WT1_5210_5250,
989	WT1_5290_5290,
990	WT1_5540_5660,
991	WT1_5760_5800,
992};
993
994static 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 */
999
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 */
1004
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 */
1009
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 */
1016
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 */
1020
1021	{ 5765, 5805, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0},	/* T1_5765_5805 */
1022
1023	/*
1024	 * Below are the WWR frequencies
1025	 */
1026
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 */
1031};
1032
1033/*
1034 * 2GHz 11b channel tags
1035 */
1036enum {
1037	F1_2312_2372,
1038	F2_2312_2372,
1039
1040	F1_2412_2472,
1041	F2_2412_2472,
1042	F3_2412_2472,
1043
1044	F1_2412_2462,
1045	F2_2412_2462,
1046
1047	F1_2432_2442,
1048
1049	F1_2457_2472,
1050
1051	F1_2467_2472,
1052
1053	F1_2484_2484,
1054	F2_2484_2484,
1055
1056	F1_2512_2732,
1057
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,
1070};
1071
1072static 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 */
1075
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 */
1079
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 */
1082
1083	{ 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},	/* F1_2432_2442 */
1084
1085	{ 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},	/* F1_2457_2472 */
1086
1087	{ 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0}, /* F1_2467_2472 */
1088
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 */
1091
1092	{ 2512, 2732, 5,  6, 20, 5, NO_DFS, NO_PSCAN, 0},	/* F1_2512_2732 */
1093
1094	/*
1095	 * WWR have powers opened up to 20dBm.  Limits should often come from CTL/Max powers
1096	 */
1097
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 */
1110};
1111
1112/*
1113 * 2GHz 11g channel tags
1114 */
1115
1116enum {
1117	G1_2312_2372,
1118	G2_2312_2372,
1119
1120	G1_2412_2472,
1121	G2_2412_2472,
1122	G3_2412_2472,
1123
1124	G1_2412_2462,
1125	G2_2412_2462,
1126
1127	G1_2432_2442,
1128
1129	G1_2457_2472,
1130
1131	G1_2512_2732,
1132
1133	G1_2467_2472 ,
1134
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,
1145
1146	S1_907_922_5,
1147	S1_907_922_10,
1148	S1_912_917,
1149
1150	S2_907_922_5,
1151	S2_907_922_10,
1152	S2_912_917,
1153};
1154
1155static 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 */
1158
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 */
1162
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 */
1165
1166	{ 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},	/* G1_2432_2442 */
1167
1168	{ 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},	/* G1_2457_2472 */
1169
1170	{ 2512, 2732, 5,  6, 20, 5, NO_DFS, NO_PSCAN, 0},	/* G1_2512_2732 */
1171
1172	{ 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0 }, /* G1_2467_2472 */
1173
1174	/*
1175	 * WWR open up the power to 20dBm
1176	 */
1177
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 */
1188};
1189
1190/*
1191 * 2GHz Dynamic turbo tags
1192 */
1193
1194enum {
1195	T1_2312_2372,
1196	T1_2437_2437,
1197	T2_2437_2437,
1198	T3_2437_2437,
1199	T1_2512_2732
1200};
1201
1202static 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 */
1208};
1209
1210typedef 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;
1230
1231static REG_DOMAIN regDomains[] = {
1232
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)},
1240
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},
1248
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},
1256
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},
1264
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},
1272
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},
1280
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},
1288
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},
1296
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},
1304
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},
1312
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},
1320
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},
1328
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},
1336
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},
1344
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},
1352
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},
1360
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},
1368
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},
1376
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},
1384
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},
1392
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},
1400
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},
1409
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},
1418
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},
1427
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},
1436
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},
1445
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},
1454
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},
1463
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},
1472
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},
1481
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)},
1489
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)},
1497
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)},
1505
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)},
1513
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)},
1521
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)},
1529
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)},
1537
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)},
1545
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)},
1553
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)},
1561
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)},
1569
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)},
1577
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)},
1585
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)},
1593
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)},
1601
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)},
1609
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)},
1617
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)},
1625
1626	{NULL1, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ,
1627	 BMZERO,
1628	 BMZERO,
1629	 BMZERO,
1630	 BMZERO,
1631	 BMZERO,
1632	 BMZERO}
1633};
1634
1635struct cmode {
1636	u_int	mode;
1637	u_int	flags;
1638};
1639
1640static 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},
1653};
1654
1655static int
1656chansort(const void *a, const void *b)
1657{
1658#define CHAN_FLAGS	(CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
1659	const HAL_CHANNEL_INTERNAL *ca = a;
1660	const HAL_CHANNEL_INTERNAL *cb = b;
1661
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
1667}
1668typedef int ath_hal_cmp_t(const void *, const void *);
1669static	void ath_hal_sort(void *a, size_t n, size_t es, ath_hal_cmp_t *cmp);
1670static COUNTRY_CODE_TO_ENUM_RD* findCountry(HAL_CTRY_CODE countryCode);
1671static HAL_BOOL getWmRD(struct ath_hal *ah, COUNTRY_CODE_TO_ENUM_RD *country, uint16_t channelFlag, REG_DOMAIN *rd);
1672
1673
1674static uint16_t
1675getEepromRD(struct ath_hal *ah)
1676{
1677	return AH_PRIVATE(ah)->ah_currentRD &~ WORLDWIDE_ROAMING_FLAG;
1678}
1679
1680/*
1681 * Test to see if the bitmask array is all zeros
1682 */
1683static HAL_BOOL
1684isChanBitMaskZero(uint64_t *bitmask)
1685{
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);
1694}
1695
1696/*
1697 * Return whether or not the regulatory domain/country in EEPROM
1698 * is acceptable.
1699 */
1700static HAL_BOOL
1701isEepromValid(struct ath_hal *ah)
1702{
1703	uint16_t rd = getEepromRD(ah);
1704	int i;
1705
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;
1715	}
1716	HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1717	    "%s: invalid regulatory domain/country code 0x%x\n", __func__, rd);
1718	return AH_FALSE;
1719}
1720
1721/*
1722 * Returns whether or not the specified country code
1723 * is allowed by the EEPROM setting
1724 */
1725static HAL_BOOL
1726isCountryCodeValid(struct ath_hal *ah, HAL_CTRY_CODE cc)
1727{
1728	uint16_t rd;
1729
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);
1740
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;
1758		}
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;
1766		}
1767	}
1768	return AH_FALSE;
1769}
1770
1771/*
1772 * Return the mask of available modes based on the hardware
1773 * capabilities and the specified country code and reg domain.
1774 */
1775static u_int
1776ath_hal_getwmodesnreg(struct ath_hal *ah, COUNTRY_CODE_TO_ENUM_RD *country,
1777			 REG_DOMAIN *rd5GHz)
1778{
1779	u_int modesAvail;
1780
1781	/* Get modes that HW is capable of */
1782	modesAvail = ath_hal_getWirelessModes(ah);
1783
1784	HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
1785	    "%s: wireless modes 0x%x cc %u rd %u\n",
1786	    __func__, modesAvail, country->countryCode, country->regDmnEnum);
1787
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);
1794	}
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;
1799	}
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;
1804	}
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;
1809	}
1810
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;
1815	}
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;
1820	}
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;
1825	}
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;
1830	}
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;
1835	}
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;
1840	}
1841
1842	return modesAvail;
1843}
1844
1845/*
1846 * Return the mask of available modes based on the hardware
1847 * capabilities and the specified country code.
1848 */
1849
1850u_int
1851ath_hal_getwirelessmodes(struct ath_hal *ah, HAL_CTRY_CODE cc)
1852{
1853	COUNTRY_CODE_TO_ENUM_RD *country = AH_NULL;
1854	u_int mode = 0;
1855	REG_DOMAIN rd;
1856
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);
1861	}
1862	return mode;
1863}
1864
1865/*
1866 * Return if device is public safety.
1867 */
1868HAL_BOOL
1869ath_hal_ispublicsafetysku(struct ath_hal *ah)
1870{
1871	uint16_t rd = getEepromRD(ah);
1872
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;
1882	}
1883	return AH_FALSE;
1884}
1885
1886/*
1887 * Find the pointer to the country element in the country table
1888 * corresponding to the country code
1889 */
1890static COUNTRY_CODE_TO_ENUM_RD*
1891findCountry(HAL_CTRY_CODE countryCode)
1892{
1893	int i;
1894
1895	for (i = 0; i < N(allCountries); i++) {
1896		if (allCountries[i].countryCode == countryCode)
1897			return &allCountries[i];
1898	}
1899	return AH_NULL;		/* Not found */
1900}
1901
1902/*
1903 * Calculate a default country based on the EEPROM setting.
1904 */
1905static HAL_CTRY_CODE
1906getDefaultCountry(struct ath_hal *ah)
1907{
1908	uint16_t rd;
1909	int i;
1910
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;
1915
1916		country = findCountry(cc);
1917		if (country != AH_NULL)
1918			return cc;
1919	}
1920	/*
1921	 * Check reg domains that have only one country
1922	 */
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);
1929		}
1930	return CTRY_DEFAULT;
1931}
1932
1933static HAL_BOOL
1934isValidRegDmn(int regDmn, REG_DOMAIN *rd)
1935{
1936	int i;
1937
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));
1943			}
1944			return AH_TRUE;
1945		}
1946	}
1947	return AH_FALSE;
1948}
1949
1950static HAL_BOOL
1951isValidRegDmnPair(int regDmnPair)
1952{
1953	int i;
1954
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;
1960	}
1961	return AH_FALSE;
1962}
1963
1964/*
1965 * Return the Wireless Mode Regulatory Domain based
1966 * on the country code and the wireless mode.
1967 */
1968static HAL_BOOL
1969getWmRD(struct ath_hal *ah, COUNTRY_CODE_TO_ENUM_RD *country,
1970	uint16_t channelFlag, REG_DOMAIN *rd)
1971{
1972	int regDmn;
1973	REG_DMN_PAIR_MAPPING *regPair;
1974	uint64_t flags;
1975
1976	if (country->countryCode == CTRY_DEFAULT) {
1977		uint16_t rdnum = getEepromRD(ah);
1978
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;
1993
1994		for (i = 0; i < N(regDomainPairs); i++) {
1995			if (regDomainPairs[i].regDmnEnum == regDmn) {
1996				regPair = &regDomainPairs[i];
1997				break;
1998			}
1999		}
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;
2005		}
2006		if (channelFlag & CHANNEL_2GHZ) {
2007			regDmn = regPair->regDmn2GHz;
2008			flags = regPair->flags2GHz;
2009		} else {
2010			regDmn = regPair->regDmn5GHz;
2011			flags = regPair->flags5GHz;
2012		}
2013	}
2014
2015	/*
2016	 * We either started with a unitary reg domain or we've found the
2017	 * unitary reg domain of the pair
2018	 */
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;
2031	}
2032}
2033
2034static HAL_BOOL
2035IS_BIT_SET(int bit, const uint64_t bitmask[])
2036{
2037	int byteOffset, bitnum;
2038	uint64_t val;
2039
2040	byteOffset = bit/64;
2041	bitnum = bit - byteOffset*64;
2042	val = ((uint64_t) 1) << bitnum;
2043	return (bitmask[byteOffset] & val) != 0;
2044}
2045
2046/* Add given regclassid into regclassids array upto max of maxregids */
2047static void
2048ath_add_regclassid(uint8_t *regclassids, u_int maxregids,
2049	u_int *nregids, uint8_t regclassid)
2050{
2051	int i;
2052
2053	/* Is regclassid valid? */
2054	if (regclassid == 0)
2055		return;
2056
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;
2064		}
2065	}
2066}
2067
2068/*
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.
2073 */
2074
2075HAL_BOOL
2076ath_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)
2081{
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;
2093
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" : "");
2097
2098	/*
2099	 * Validate the EEPROM setting and setup defaults
2100	 */
2101	if (!isEepromValid(ah)) {
2102		/*
2103		 * Don't return any channels if the EEPROM has an
2104		 * invalid regulatory domain/country code setting.
2105		 */
2106		HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2107		    "%s: invalid EEPROM contents\n",__func__);
2108		return AH_FALSE;
2109	}
2110
2111	AH_PRIVATE(ah)->ah_countryCode = getDefaultCountry(ah);
2112
2113#ifndef AH_SUPPORT_11D
2114	if (AH_PRIVATE(ah)->ah_countryCode == CTRY_DEFAULT) {
2115#endif
2116		/*
2117		 * We now have enough state to validate any country code
2118		 * passed in by the caller.
2119		 */
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;
2125		}
2126		AH_PRIVATE(ah)->ah_countryCode = cc & COUNTRY_CODE_MASK;
2127#ifndef AH_SUPPORT_11D
2128	}
2129#endif
2130
2131	/* Get pointers to the country element and the reg domain elements */
2132	country = findCountry(AH_PRIVATE(ah)->ah_countryCode);
2133
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;
2138	}
2139
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;
2145	}
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;
2151	}
2152
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;
2157
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;
2167
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;
2173		}
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;
2179		}
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;
2186		}
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;
2234		}
2235		if (isChanBitMaskZero(channelBM))
2236			continue;
2237		/*
2238		 * Setup special handling for HT40 channels; e.g.
2239		 * 5G HT40 channels require 40Mhz channel separation.
2240		 */
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;
2247
2248		for (b = 0; b < 64*BMLEN; b++) {
2249			if (!IS_BIT_SET(b, channelBM))
2250				continue;
2251			fband = &freqs[b];
2252			lastc = 0;
2253
2254			ath_add_regclassid(regclassids, maxregids,
2255					nregids, fband->regClassId);
2256
2257			for (c = fband->lowChannel + low_adj;
2258			     c <= fband->highChannel + hi_adj;
2259			     c += fband->channelSep) {
2260				HAL_CHANNEL_INTERNAL icv;
2261
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;
2267				}
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;
2274				}
2275
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;
2282				}
2283
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;
2289				}
2290				if (next >= maxchans){
2291					HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2292					    "%s: too many channels for channel table\n",
2293					    __func__);
2294					goto done;
2295				}
2296				if ((fband->usePassScan & IS_ECM_CHAN) &&
2297				    !enableExtendedChannels) {
2298					HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2299					    "Skipping ecm channel\n");
2300					continue;
2301				}
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;
2308				}
2309				/*
2310				 * Make sure that channel separation
2311				 * meets the requirement.
2312				 */
2313				if (lastc && channelSep &&
2314				    (c-lastc) < channelSep)
2315					continue;
2316
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;
2327				}
2328
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;
2348
2349				ichans[next++] = icv;
2350			}
2351		}
2352	}
2353done:
2354	if (next != 0) {
2355		int i;
2356
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);
2364		}
2365
2366		/*
2367		 * Keep a private copy of the channel list so we can
2368		 * constrain future requests to only these channels
2369		 */
2370		ath_hal_sort(ichans, next, sizeof(HAL_CHANNEL_INTERNAL),
2371		    chansort);
2372		AH_PRIVATE(ah)->ah_nchan = next;
2373
2374		/*
2375		 * Copy the channel list to the public channel list
2376		 */
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;
2382		}
2383		/*
2384		 * Retrieve power limits.
2385		 */
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;
2390		}
2391	}
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
2398}
2399
2400/*
2401 * Return whether or not the specified channel is ok to use
2402 * based on the current regulatory domain constraints and
2403 * DFS interference.
2404 */
2405HAL_CHANNEL_INTERNAL *
2406ath_hal_checkchannel(struct ath_hal *ah, const HAL_CHANNEL *c)
2407{
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;
2413
2414	HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
2415	    "%s: channel %u/0x%x (0x%x) requested\n",
2416	    __func__, c->channel, c->channelFlags, flags);
2417
2418	/*
2419	 * Check current channel to avoid the lookup.
2420	 */
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;
2429	}
2430
2431	/* binary search based on known sorting order */
2432	base = AH_PRIVATE(ah)->ah_channels;
2433	n = AH_PRIVATE(ah)->ah_nchan;
2434	/* binary search based on known sorting order */
2435	for (lim = n; lim != 0; lim >>= 1) {
2436		cc = &base[lim>>1];
2437		d = c->channel - cc->channel;
2438		if (d == 0) {
2439			if ((cc->channelFlags & CHAN_FLAGS) == flags) {
2440				if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
2441				    (cc->channelFlags & CHANNEL_DFS))
2442					return AH_NULL;
2443				else
2444					return cc;
2445			}
2446			d = flags - (cc->channelFlags & CHAN_FLAGS);
2447		}
2448		HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: channel %u/0x%x d %d\n",
2449		    __func__, cc->channel, cc->channelFlags, d);
2450		if (d > 0) {
2451			base = cc + 1;
2452			lim--;
2453		}
2454	}
2455	HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: no match for %u/0x%x\n",
2456	   __func__, c->channel, c->channelFlags);
2457	return AH_NULL;
2458#undef CHAN_FLAGS
2459}
2460
2461/*
2462 * Return the max allowed antenna gain and apply any regulatory
2463 * domain specific changes.
2464 *
2465 * NOTE: a negative reduction is possible in RD's that only
2466 * measure radiated power (e.g., ETSI) which would increase
2467 * that actual conducted output power (though never beyond
2468 * the calibrated target power).
2469 */
2470u_int
2471ath_hal_getantennareduction(struct ath_hal *ah, HAL_CHANNEL *chan, u_int twiceGain)
2472{
2473	HAL_CHANNEL_INTERNAL *ichan=AH_NULL;
2474	int8_t antennaMax;
2475
2476	if ((ichan = ath_hal_checkchannel(ah, chan)) != AH_NULL) {
2477		antennaMax = twiceGain - ichan->antennaMax*2;
2478		return (antennaMax < 0) ? 0 : antennaMax;
2479	} else {
2480		/* Failed to find the correct index - may be a debug channel */
2481		return 0;
2482	}
2483}
2484
2485
2486/* XXX - maybe move ctl decision into channel set area or
2487 into the tables so no decision is needed in the code */
2488
2489#define isWwrSKU(_ah) \
2490	((getEepromRD((_ah)) & WORLD_SKU_MASK) == WORLD_SKU_PREFIX || \
2491	  getEepromRD(_ah) == WORLD)
2492
2493
2494/*
2495 * Return the test group from the specified channel from
2496 * the regulatory table.
2497 *
2498 * TODO: CTL for 11B CommonMode when regulatory domain is unknown
2499 */
2500u_int
2501ath_hal_getctl(struct ath_hal *ah, HAL_CHANNEL *chan)
2502{
2503	u_int ctl = NO_CTL;
2504	HAL_CHANNEL_INTERNAL *ichan;
2505
2506	/* Special CTL to signify WWR SKU without a known country */
2507	if (AH_PRIVATE(ah)->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)) {
2508		if (IS_CHAN_B(chan)) {
2509			ctl = SD_NO_CTL | CTL_11B;
2510		} else if (IS_CHAN_G(chan)) {
2511			ctl = SD_NO_CTL | CTL_11G;
2512		} else if (IS_CHAN_108G(chan)) {
2513			ctl = SD_NO_CTL | CTL_108G;
2514		} else if (IS_CHAN_T(chan)) {
2515			ctl = SD_NO_CTL | CTL_TURBO;
2516		} else {
2517			ctl = SD_NO_CTL | CTL_11A;
2518		}
2519	} else {
2520		if ((ichan = ath_hal_checkchannel(ah, chan)) != AH_NULL) {
2521			ctl = ichan->conformanceTestLimit;
2522			/* limit 11G OFDM power */
2523			if (IS_CHAN_PUREG(chan) &&
2524			    (ctl & CTL_MODE_M) == CTL_11B)
2525				ctl = (ctl &~ CTL_MODE_M) | CTL_11G;
2526		}
2527	}
2528	return ctl;
2529}
2530
2531/*
2532 * Return whether or not a noise floor check is required in
2533 * the current regulatory domain for the specified channel.
2534 */
2535HAL_BOOL
2536ath_hal_getnfcheckrequired(struct ath_hal *ah, HAL_CHANNEL *chan)
2537{
2538	HAL_CHANNEL_INTERNAL *ichan;
2539
2540	if ((ichan = ath_hal_checkchannel(ah, chan)) != AH_NULL)
2541		return ((ichan->regDmnFlags & NEED_NFC) ? AH_TRUE : AH_FALSE);
2542	return AH_FALSE;
2543}
2544
2545/*
2546 * Insertion sort.
2547 */
2548#define swap(_a, _b, _size) {			\
2549	uint8_t *s = _b;			\
2550	int i = _size;				\
2551	do {					\
2552		uint8_t tmp = *_a;		\
2553		*_a++ = *s;			\
2554		*s++ = tmp;			\
2555	} while (--i);				\
2556	_a -= _size;				\
2557}
2558
2559static void
2560ath_hal_sort(void *a, size_t n, size_t size, ath_hal_cmp_t *cmp)
2561{
2562	uint8_t *aa = a;
2563	uint8_t *ai, *t;
2564
2565	for (ai = aa+size; --n >= 1; ai += size)
2566		for (t = ai; t > aa; t -= size) {
2567			uint8_t *u = t - size;
2568			if (cmp(u, t) <= 0)
2569				break;
2570			swap(u, t, size);
2571		}
2572}
2573