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