Include wl_high.ko module
[tomato.git] / release / src-rt / wl / sys / wlc_channel.c
blobac83f069d6a7f36e928c97fe633dffac6025cb8e
1 /*
2 * Common interface to channel definitions.
3 * Copyright (C) 2010, Broadcom Corporation
4 * All Rights Reserved.
5 *
6 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
7 * the contents of this file may not be disclosed to third parties, copied
8 * or duplicated in any form, in whole or in part, without the prior
9 * written permission of Broadcom Corporation.
11 * $Id: wlc_channel.c,v 1.322.2.57 2011-02-11 05:42:13 Exp $
14 #include <wlc_cfg.h>
15 #include <typedefs.h>
16 #include <bcmdefs.h>
17 #include <osl.h>
18 #include <bcmutils.h>
19 #include <siutils.h>
20 #include <bcmendian.h>
21 #include <proto/802.11.h>
22 #include <proto/wpa.h>
23 #include <sbconfig.h>
24 #include <pcicfg.h>
25 #include <bcmsrom.h>
26 #include <wlioctl.h>
27 #include <epivers.h>
28 #ifdef BCMSUP_PSK
29 #include <proto/eapol.h>
30 #include <bcmwpa.h>
31 #endif /* BCMSUP_PSK */
32 #include <d11.h>
33 #include <wlc_rate.h>
34 #include <wlc_pub.h>
35 #include <wlc_key.h>
36 #include <wlc_bsscfg.h>
37 #include <wlc.h>
38 #include <wlc_bmac.h>
39 #include <wlc_phy_hal.h>
40 #include <wlc_scb.h>
41 #include <wl_export.h>
42 #include <wlc_ap.h>
43 #include <wlc_stf.h>
44 #include <wlc_channel.h>
46 typedef struct wlc_cm_band {
47 uint8 locale_flags; /* locale_info_t flags */
48 chanvec_t valid_channels; /* List of valid channels in the country */
49 #ifdef BAND5G
50 const chanvec_t *radar_channels; /* List of radar sensitive channels */
51 #endif
52 struct wlc_channel_txchain_limits chain_limits; /* per chain power limit */
53 uint8 PAD[4];
54 } wlc_cm_band_t;
56 struct wlc_cm_info {
57 wlc_pub_t *pub;
58 wlc_info_t *wlc;
59 char srom_ccode[WLC_CNTRY_BUF_SZ]; /* Country Code in SROM */
60 uint srom_regrev; /* Regulatory Rev for the SROM ccode */
61 const country_info_t *country; /* current country def */
62 char ccode[WLC_CNTRY_BUF_SZ]; /* current internal Country Code */
63 uint regrev; /* current Regulatory Revision */
64 char country_abbrev[WLC_CNTRY_BUF_SZ]; /* current advertised ccode */
65 wlc_cm_band_t bandstate[MAXBANDS]; /* per-band state (one per phy/radio) */
66 /* quiet channels currently for radar sensitivity or 11h support */
67 chanvec_t quiet_channels; /* channels on which we cannot transmit */
69 /* restricted channels */
70 chanvec_t restricted_channels; /* copy of the global restricted channels of the */
71 /* current local */
72 bool has_restricted_ch;
74 /* regulatory class */
75 rcvec_t valid_rcvec; /* List of valid regulatory class in the country */
76 const rcinfo_t *rcinfo_list[MAXRCLIST]; /* regulatory class info list */
79 static int wlc_channels_init(wlc_cm_info_t *wlc_cm, const country_info_t *country);
80 static void wlc_set_country_common(
81 wlc_cm_info_t *wlc_cm, const char* country_abbrev, const char* ccode, uint regrev,
82 const country_info_t *country);
83 static int wlc_country_aggregate_map(
84 wlc_cm_info_t *wlc_cm, const char *ccode, char *mapped_ccode, uint *mapped_regrev);
85 static const country_info_t* wlc_country_lookup_direct(const char* ccode, uint regrev);
86 static const country_info_t* wlc_countrycode_map(
87 wlc_cm_info_t *wlc_cm, const char *ccode, char *mapped_ccode, uint *mapped_regrev);
88 static void wlc_channels_commit(wlc_cm_info_t *wlc_cm);
89 static void wlc_chanspec_list(wlc_info_t *wlc, wl_uint32_list_t *list, chanspec_t chanspec_mask);
90 static bool wlc_buffalo_map_locale(struct wlc_info *wlc, const char* abbrev);
91 static bool wlc_japan_ccode(const char *ccode);
92 static bool wlc_us_ccode(const char *ccode);
93 static void wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t *wlc_cm,
94 txppr_t *txpwr, uint8 local_constraint_qdbm);
95 void wlc_locale_add_channels(chanvec_t *target, const chanvec_t *channels);
96 static void wlc_rcinfo_init(wlc_cm_info_t *wlc_cm);
97 static void wlc_regclass_vec_init(wlc_cm_info_t *wlc_cm);
98 #ifdef WL11N
99 static const locale_mimo_info_t * wlc_get_mimo_2g(uint8 locale_idx);
100 static const locale_mimo_info_t * wlc_get_mimo_5g(uint8 locale_idx);
101 #endif /* WL11N */
102 static void wlc_upd_restricted_chanspec_flag(wlc_cm_info_t *wlc_cm);
103 static int wlc_channel_update_txchain_offsets(wlc_cm_info_t *wlc_cm, txppr_t *txpwr);
104 #if defined(BCMDBG) || defined(BCMDBG_DUMP)
105 static int wlc_channel_dump_reg_ppr(void *handle, struct bcmstrbuf *b);
106 static int wlc_channel_dump_reg_local_ppr(void *handle, struct bcmstrbuf *b);
107 static int wlc_channel_dump_srom_ppr(void *handle, struct bcmstrbuf *b);
108 static int wlc_channel_dump_margin(void *handle, struct bcmstrbuf *b);
109 #endif
111 typedef void (*wlc_channel_mapfn_t)(void *context, uint8 *a, uint8 *b);
113 /* QDB() macro takes a dB value and converts to a quarter dB value */
114 #ifdef QDB
115 #undef QDB
116 #endif
117 #define QDB(n) ((n) * WLC_TXPWR_DB_FACTOR)
119 /* Regulatory Matrix Spreadsheet (CLM) MIMO v3.8.6.4
120 * + CLM v4.1.3
121 * + CLM v4.2.4
122 * + CLM v4.3.1 (Item-1 only EU/9 and Q2/4)
123 * + CLM v4.3.3
124 * + CLMv 4.3.4_3x3 changes(Skip changes for a13/14).
125 * + CLMv 4.4.4_3x3 ALl changes except Item-2 and Item-4
126 * + CLMv 4.5.3_3x3 changes for Item-5(Cisco Evora (change AP3500i to Evora)).
127 * + CLMv 4.5.3_3x3 changes for Item-3(Create US/61 for BCM94331HM, based on US/53 power levels).
128 * + CLMv 4.5.5 3x3 (changes from Create US/63 only)
129 * + CLMv 4.5.6 3x3 changes(An6-3 for Cisco E1200/E1550)
130 * + CLMv 4.4.4 3x3 changes(Create EU/13 (locales 3r-5, 3rn-4)
131 * + CLMv 4.5.3 3x3 changes(Create IL/4 (locale 13-3) for Juniper AX411)
136 * Some common channel sets
139 /* No channels */
140 static const chanvec_t chanvec_none = {
141 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00}
147 /* All 2.4 GHz HW channels */
148 const chanvec_t chanvec_all_2G = {
149 {0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0x00, 0x00, 0x00, 0x00}
155 /* All 5 GHz HW channels */
156 const chanvec_t chanvec_all_5G = {
157 {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x11, 0x11,
158 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11,
159 0x11, 0x11, 0x20, 0x22, 0x22, 0x00, 0x00, 0x11,
160 0x11, 0x11, 0x11, 0x01}
163 /* Regulatory Matrix Spreadsheet (CLM) MIMO v3.1 ** WITH MODIFICATIONS ** */
165 /* Parts of CLM v3.7.4 have been incoporated to support a high gain
166 * antenna system. The additions are the differences added between
167 * CLM v3.7.3 and v3.7.4.
168 * Adding country revisions: JP/7 US/29 X0/6 X3/5 X1/5 X2/5
169 * Adding supporting locales: 3l, 3jn_1, ,,,
171 * Adding the changes introduced in CLM v3.7.7, v3.7.8, and v3.7.9
172 * Adding the changes introduced in CLM v4.2.3
173 * Adding the changes introduced in CLM v4.3.3
177 * Radar channel sets
180 /* No radar */
181 #define radar_set_none chanvec_none
183 #ifdef BAND5G
184 static const chanvec_t radar_set1 = { /* Channels 52 - 64, 100 - 140 */
185 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, /* 52 - 60 */
186 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, /* 64, 100 - 124 */
187 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128 - 140 */
188 0x00, 0x00, 0x00, 0x00}
190 #endif /* BAND5G */
193 * Restricted channel sets
196 #define restricted_set_none chanvec_none
198 /* Channels 34, 38, 42, 46 */
199 static const chanvec_t restricted_set_japan_legacy = {
200 {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203 0x00, 0x00, 0x00, 0x00}
206 /* Channels 12, 13 */
207 static const chanvec_t restricted_set_2g_short = {
208 {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211 0x00, 0x00, 0x00, 0x00}
214 /* Channel 165 */
215 static const chanvec_t restricted_chan_165 = {
216 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
218 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
219 0x00, 0x00, 0x00, 0x00}
222 /* Channels 36 - 48 & 149 - 165 */
223 static const chanvec_t restricted_low_hi = {
224 {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00,
225 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
226 0x00, 0x00, 0x20, 0x22, 0x22, 0x00, 0x00, 0x00,
227 0x00, 0x00, 0x00, 0x00}
230 /* Channels 12 - 14 */
231 static const chanvec_t restricted_set_12_13_14 = {
232 {0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
233 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
234 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
235 0x00, 0x00, 0x00, 0x00}
238 /* Channels 52-64, 100-140 and 149-165 */
239 static const chanvec_t restricted_set_52_above = {
240 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11,
241 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11,
242 0x11, 0x11, 0x20, 0x22, 0x22, 0x00, 0x00, 0x00,
243 0x00, 0x00, 0x00, 0x00}
247 #define WLC_REGCLASS_USA_2G_20MHZ 12
248 #define WLC_REGCLASS_EUR_2G_20MHZ 4
249 #define WLC_REGCLASS_JPN_2G_20MHZ 30
250 #define WLC_REGCLASS_JPN_2G_20MHZ_CH14 31
252 #ifdef WL11N
254 * bit map of supported regulatory class for USA, Europe & Japan
256 static const rcvec_t rclass_us = { /* 1-5, 12, 22-25, 27-30, 32-33 */
257 {0x3e, 0x10, 0xc0, 0x7b, 0x03}
259 static const rcvec_t rclass_eu = { /* 1-4, 5-12 */
260 {0xfe, 0x1f, 0x00, 0x00, 0x00}
262 static const rcvec_t rclass_jp = { /* 1, 30-32 */
263 {0x01, 0x00, 0x00, 0xc0, 0x01}
265 #endif /* WL11N */
267 #ifdef BAND5G
269 * channel to regulatory class map for USA
271 static const rcinfo_t rcinfo_us_20 = {
274 { 36, 1}, { 40, 1}, { 44, 1}, { 48, 1}, { 52, 2}, { 56, 2}, { 60, 2}, { 64, 2},
275 {100, 4}, {104, 4}, {108, 4}, {112, 4}, {116, 4}, {120, 4}, {124, 4}, {128, 4},
276 {132, 4}, {136, 4}, {140, 4}, {149, 3}, {153, 3}, {157, 3}, {161, 3}, {165, 5}
279 #endif /* BAND5G */
281 #ifdef WL11N
282 /* control channel at lower sb */
283 static const rcinfo_t rcinfo_us_40lower = {
286 { 1, 32}, { 2, 32}, { 3, 32}, { 4, 32}, { 5, 32}, { 6, 32}, { 7, 32}, { 36, 22},
287 { 44, 22}, { 52, 23}, { 60, 23}, {100, 24}, {108, 24}, {116, 24}, {124, 24}, {132, 24},
288 {149, 25}, {157, 25}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}
291 /* control channel at upper sb */
292 static const rcinfo_t rcinfo_us_40upper = {
295 { 5, 33}, { 6, 33}, { 7, 33}, { 8, 33}, { 9, 33}, { 10, 33}, { 11, 33}, { 40, 27},
296 { 48, 27}, { 56, 28}, { 64, 28}, {104, 29}, {112, 29}, {120, 29}, {128, 29}, {136, 29},
297 {153, 30}, {161, 30}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}
300 #endif /* WL11N */
302 #ifdef BAND5G
304 * channel to regulatory class map for Europe
306 static const rcinfo_t rcinfo_eu_20 = {
309 { 36, 1}, { 40, 1}, { 44, 1}, { 48, 1}, { 52, 2}, { 56, 2}, { 60, 2}, { 64, 2},
310 {100, 3}, {104, 3}, {108, 3}, {112, 3}, {116, 3}, {120, 3}, {124, 3}, {128, 3},
311 {132, 3}, {136, 3}, {140, 3}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}
314 #endif /* BAND5G */
316 #ifdef WL11N
317 static const rcinfo_t rcinfo_eu_40lower = {
320 { 1, 11}, { 2, 11}, { 3, 11}, { 4, 11}, { 5, 11}, { 6, 11}, { 7, 11}, { 8, 11},
321 { 9, 11}, { 36, 5}, { 44, 5}, { 52, 6}, { 60, 6}, {100, 7}, {108, 7}, {116, 7},
322 {124, 7}, {132, 7}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}
325 static const rcinfo_t rcinfo_eu_40upper = {
328 { 5, 12}, { 6, 12}, { 7, 12}, { 8, 12}, { 9, 12}, { 10, 12}, { 11, 12}, { 12, 12},
329 { 13, 12}, { 40, 8}, { 48, 8}, { 56, 9}, { 64, 9}, {104, 10}, {112, 10}, {120, 10},
330 {128, 10}, {136, 10}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}
333 #endif /* WL11N */
335 #ifdef BAND5G
337 * channel to regulatory class map for Japan
339 static const rcinfo_t rcinfo_jp_20 = {
342 { 34, 1}, { 38, 1}, { 42, 1}, { 46, 1}, { 52, 32}, { 56, 32}, { 60, 32}, { 64, 32},
343 { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
344 { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}
347 #endif /* BAND5G */
349 #ifdef WL11N
350 static const rcinfo_t rcinfo_jp_40 = {
353 { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
354 { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
355 { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}
358 #endif
360 #ifdef WL11D
362 /* All 5 GHz channels restricted */
363 #define restricted_set_11d_5G chanvec_all_5G
365 /* All 2.4 GHz channels restricted */
366 #define restricted_set_11d_2G chanvec_all_2G
368 #endif /* WL11D */
370 #define LOCALE_CHAN_01_11 (1<<0)
371 #define LOCALE_CHAN_12_13 (1<<1)
372 #define LOCALE_CHAN_14 (1<<2)
373 #define LOCALE_SET_5G_LOW_JP1 (1<<3) /* 34-48, step 2 */
374 #define LOCALE_SET_5G_LOW_JP2 (1<<4) /* 34-46, step 4 */
375 #define LOCALE_SET_5G_LOW1 (1<<5) /* 36-48, step 4 */
376 #define LOCALE_SET_5G_LOW2 (1<<6) /* 52 */
377 #define LOCALE_SET_5G_LOW3 (1<<7) /* 56-64, step 4 */
378 #define LOCALE_SET_5G_MID1 (1<<8) /* 100-116, step 4 */
379 #define LOCALE_SET_5G_MID2 (1<<9) /* 120-124, step 4 */
380 #define LOCALE_SET_5G_MID3 (1<<10) /* 128 */
381 #define LOCALE_SET_5G_HIGH1 (1<<11) /* 132-140, step 4 */
382 #define LOCALE_SET_5G_HIGH2 (1<<12) /* 149-161, step 4 */
383 #define LOCALE_SET_5G_HIGH3 (1<<13) /* 165 */
384 #define LOCALE_CHAN_52_140_ALL (1<<14)
385 #define LOCALE_SET_5G_HIGH4 (1<<15) /* 184-216 */
387 #define LOCALE_CHAN_36_64 LOCALE_SET_5G_LOW1 | LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3
388 #define LOCALE_CHAN_52_64 LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3
389 #define LOCALE_CHAN_100_124 LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2
390 #define LOCALE_CHAN_100_140 \
391 LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1
392 #define LOCALE_CHAN_149_165 LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3
393 #define LOCALE_CHAN_184_216 LOCALE_SET_5G_HIGH4
395 #define LOCALE_CHAN_01_14 (LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13 | LOCALE_CHAN_14)
397 #define LOCALE_RADAR_SET_NONE 0
398 #define LOCALE_RADAR_SET_1 1
400 #define LOCALE_RESTRICTED_NONE 0
401 #define LOCALE_RESTRICTED_SET_2G_SHORT 1
402 #define LOCALE_RESTRICTED_CHAN_165 2
403 #define LOCALE_CHAN_ALL_5G 3
404 #define LOCALE_RESTRICTED_JAPAN_LEGACY 4
405 #define LOCALE_RESTRICTED_11D_2G 5
406 #define LOCALE_RESTRICTED_11D_5G 6
407 #define LOCALE_RESTRICTED_LOW_HI 7
408 #define LOCALE_RESTRICTED_12_13_14 8
409 #define LOCALE_RESTRICTED_52_ABOVE 9
411 #define IS_CCODE_REV(cm, cntry, rev) (!strncmp(cm->ccode, cntry, WLC_CNTRY_BUF_SZ) && \
412 (cm->regrev == (rev)))
414 /* global memory to provide working buffer for expanded locale */
416 #ifdef BAND5G /* RADAR */
417 static const chanvec_t * g_table_radar_set[] =
419 &chanvec_none,
420 &radar_set1
422 #endif
424 static const chanvec_t * g_table_restricted_chan[] =
426 &chanvec_none, /* restricted_set_none */
427 &restricted_set_2g_short,
428 &restricted_chan_165,
429 &chanvec_all_5G,
430 &restricted_set_japan_legacy,
431 &chanvec_all_2G, /* restricted_set_11d_2G */
432 &chanvec_all_5G, /* restricted_set_11d_5G */
433 &restricted_low_hi,
434 &restricted_set_12_13_14,
435 &restricted_set_52_above
438 static const chanvec_t locale_2g_01_11 = {
439 {0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
440 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
441 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442 0x00, 0x00, 0x00, 0x00}
444 static const chanvec_t locale_2g_12_13 = {
445 {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
446 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
447 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
448 0x00, 0x00, 0x00, 0x00}
450 static const chanvec_t locale_2g_14 = {
451 {0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
453 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
454 0x00, 0x00, 0x00, 0x00}
457 static const chanvec_t locale_5g_LOW_JP1 = {
458 {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00,
459 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
461 0x00, 0x00, 0x00, 0x00}
463 static const chanvec_t locale_5g_LOW_JP2 = {
464 {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
465 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
466 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
467 0x00, 0x00, 0x00, 0x00}
469 static const chanvec_t locale_5g_LOW1 = {
470 {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00,
471 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
472 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473 0x00, 0x00, 0x00, 0x00}
475 static const chanvec_t locale_5g_LOW2 = {
476 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
477 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
478 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
479 0x00, 0x00, 0x00, 0x00}
481 static const chanvec_t locale_5g_LOW3 = {
482 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
483 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
484 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
485 0x00, 0x00, 0x00, 0x00}
487 static const chanvec_t locale_5g_MID1 = {
488 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
489 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x00,
490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
491 0x00, 0x00, 0x00, 0x00}
493 static const chanvec_t locale_5g_MID2 = {
494 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
495 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
496 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
497 0x00, 0x00, 0x00, 0x00}
499 static const chanvec_t locale_5g_MID3 = {
500 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
501 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
502 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
503 0x00, 0x00, 0x00, 0x00}
505 static const chanvec_t locale_5g_HIGH1 = {
506 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
507 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
508 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
509 0x00, 0x00, 0x00, 0x00}
511 static const chanvec_t locale_5g_HIGH2 = {
512 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
513 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
514 0x00, 0x00, 0x20, 0x22, 0x02, 0x00, 0x00, 0x00,
515 0x00, 0x00, 0x00, 0x00}
517 static const chanvec_t locale_5g_HIGH3 = {
518 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
519 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
520 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
521 0x00, 0x00, 0x00, 0x00}
523 static const chanvec_t locale_5g_52_140_ALL = {
524 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11,
525 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
526 0x11, 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
527 0x00, 0x00, 0x00, 0x00}
529 static const chanvec_t locale_5g_HIGH4 = {
530 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
531 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
532 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
533 0x11, 0x11, 0x11, 0x11}
536 static const chanvec_t * g_table_locale_base[] =
538 &locale_2g_01_11,
539 &locale_2g_12_13,
540 &locale_2g_14,
541 &locale_5g_LOW_JP1,
542 &locale_5g_LOW_JP2,
543 &locale_5g_LOW1,
544 &locale_5g_LOW2,
545 &locale_5g_LOW3,
546 &locale_5g_MID1,
547 &locale_5g_MID2,
548 &locale_5g_MID3,
549 &locale_5g_HIGH1,
550 &locale_5g_HIGH2,
551 &locale_5g_HIGH3,
552 &locale_5g_52_140_ALL,
553 &locale_5g_HIGH4
555 void wlc_locale_add_channels(chanvec_t *target, const chanvec_t *channels)
557 uint8 i;
558 for (i = 0; i < sizeof(chanvec_t); i++) {
559 target->vec[i] |= channels->vec[i];
563 void wlc_locale_get_channels(const locale_info_t * locale, chanvec_t *channels)
565 uint8 i;
567 bzero(channels, sizeof(chanvec_t));
569 for (i = 0; i < ARRAYSIZE(g_table_locale_base); i++) {
570 if (locale->valid_channels & (1<<i)) {
571 wlc_locale_add_channels(channels, g_table_locale_base[i]);
577 * Locale Definitions - 2.4 GHz
580 #ifdef BAND2G
581 static const locale_info_t locale_a = { /* locale a. channel 1 - 11 */
582 LOCALE_CHAN_01_11,
583 LOCALE_RADAR_SET_NONE,
584 LOCALE_RESTRICTED_NONE,
585 #if 1 /* ASUS modify */
586 {QDB(17.5), QDB(20), QDB(17.5),
587 QDB(15.5), QDB(18), /* 16.5 dBm */ 62},
588 #else
589 {QDB(19), QDB(19), QDB(19),
590 QDB(19), QDB(19), /* 16.5 dBm */ 66},
591 #endif
592 {30, 30, 30, 0},
593 WLC_PEAK_CONDUCTED
596 static const locale_info_t locale_a_1 = { /* locale a. channel 1 - 11 */
597 LOCALE_CHAN_01_11,
598 LOCALE_RADAR_SET_NONE,
599 LOCALE_RESTRICTED_NONE,
600 {QDB(19), QDB(19), QDB(19),
601 QDB(15), QDB(17), QDB(16)},
602 {30, 30, 30, 0},
603 WLC_PEAK_CONDUCTED
606 static const locale_info_t locale_a_2 = { /* locale a. channel 1 - 11 */
607 LOCALE_CHAN_01_11,
608 LOCALE_RADAR_SET_NONE,
609 LOCALE_RESTRICTED_NONE,
610 {QDB(19), QDB(19), QDB(19),
611 QDB(18), QDB(18), QDB(18)},
612 {30, 30, 30, 0},
613 WLC_PEAK_CONDUCTED
616 static const locale_info_t locale_a_3 = { /* locale a_3. channel 1 - 11 */
617 LOCALE_CHAN_01_11,
618 LOCALE_RADAR_SET_NONE,
619 LOCALE_RESTRICTED_NONE,
620 {QDB(15), QDB(17), QDB(15),
621 QDB(13), QDB(17), QDB(13)},
622 {30, 30, 30, 0},
623 WLC_PEAK_CONDUCTED
626 static const locale_info_t locale_a_5 = { /* locale a_5. channel 1 - 11 */
627 LOCALE_CHAN_01_11,
628 LOCALE_RADAR_SET_NONE,
629 LOCALE_RESTRICTED_NONE,
630 { /* 16.5 */ 66, 66, 66,
631 /* 12.5 */ 50, /* 16.5 */ 66, 66},
632 {30, 30, 30, 0},
633 WLC_PEAK_CONDUCTED
636 static const locale_info_t locale_a_6 = { /* locale a_6. channel 1 - 11 */
637 LOCALE_CHAN_01_11,
638 LOCALE_RADAR_SET_NONE,
639 LOCALE_RESTRICTED_NONE,
640 {QDB(20), QDB(20), QDB(20),
641 QDB(17), QDB(17), QDB(16)},
642 {30, 30, 30, 0},
643 WLC_PEAK_CONDUCTED
646 static const locale_info_t locale_a1 = { /* locale a. channel 1 - 11 */
647 LOCALE_CHAN_01_11,
648 LOCALE_RADAR_SET_NONE,
649 LOCALE_RESTRICTED_NONE,
650 {QDB(18), QDB(19), QDB(18),
651 QDB(19), QDB(19), /* 16.5 dBm */ 66},
652 {30, 30, 30, 0},
653 WLC_PEAK_CONDUCTED
656 /* CLM v1.12.2.3 has separate power targets for 2.4G OFDM ch 11 and 12/13.
657 * Express ch 12/13 limits here and fixup in wlc_channel_reg_limits().
658 * CLM v2.1.3 has 2.4G CCK allowed but OFDM prohibited, express CCK here and
659 * hack for OFDM in wlc_phy.c
661 static const locale_info_t locale_a2 = { /* locale a. channel 1 - 14 */
662 LOCALE_CHAN_01_14,
663 LOCALE_RADAR_SET_NONE,
664 LOCALE_RESTRICTED_12_13_14,
665 {QDB(19), QDB(19), QDB(12),
666 QDB(19), QDB(19), QDB(11)},
667 {30, 30, 30, 0},
668 WLC_PEAK_CONDUCTED
671 static const locale_info_t locale_a3 = { /* locale a3. channel 1 - 11 */
672 LOCALE_CHAN_01_11,
673 LOCALE_RADAR_SET_NONE,
674 LOCALE_RESTRICTED_NONE,
675 {QDB(18), QDB(19), QDB(18),
676 QDB(17), QDB(19), QDB(16)},
677 {30, 30, 30, 0},
678 WLC_PEAK_CONDUCTED
681 /* CLM v3.1 has separate power targets for 2.4G CCK/OFDM ch 3-9 and 2/10.
682 * Express ch 3-9 limits here and fixup 2/10 in wlc_channel_reg_limits().
684 static const locale_info_t locale_a3_1 = { /* locale a3. channel 1 - 11 */
685 LOCALE_CHAN_01_11,
686 LOCALE_RADAR_SET_NONE,
687 LOCALE_RESTRICTED_NONE,
688 {QDB(18), QDB(19), QDB(18),
689 QDB(14), QDB(17), QDB(12)},
690 {30, 30, 30, 0},
691 WLC_PEAK_CONDUCTED
694 /* CLM v7.0 has separate power targets for 2.4G CCK/OFDM ch 3-9 and 2/10.
695 * Express ch 3-9 limits here and fixup 2/10 in wlc_channel_reg_limits().
697 static const locale_info_t locale_a4 = { /* locale a4. channel 1 - 11 */
698 LOCALE_CHAN_01_11,
699 LOCALE_RADAR_SET_NONE,
700 LOCALE_RESTRICTED_NONE,
701 { QDB(21), QDB(23), /* 20.5 dBm */ 82,
702 QDB(18), QDB(23), /* 16.5 dBm */ 66},
703 {30, 30, 30, 0},
704 WLC_PEAK_CONDUCTED
707 static const locale_info_t locale_a4_2 = { /* locale a4_2. channel 1 - 11 */
708 LOCALE_CHAN_01_11,
709 LOCALE_RADAR_SET_NONE,
710 LOCALE_RESTRICTED_NONE,
711 { QDB(21), QDB(23), QDB(21),
712 QDB(18), QDB(23), QDB(18)},
713 {30, 30, 30, 0},
714 WLC_PEAK_CONDUCTED
717 /* CLM v4.3.4 has separate power targets for 2.4G CCK/OFDM ch 3-9 and 2/10.
718 * Express ch 3-9 limits here and fixup 2/10 in wlc_channel_reg_limits().
720 static const locale_info_t locale_a4_3 = { /* locale a4_3. channel 1 - 11 */
721 LOCALE_CHAN_01_11,
722 LOCALE_RADAR_SET_NONE,
723 LOCALE_RESTRICTED_NONE,
724 { QDB(19), QDB(23), QDB(19),
725 QDB(16), QDB(23), QDB(16)},
726 {30, 30, 30, 0},
727 WLC_PEAK_CONDUCTED
730 /* CLM v4.8.2 has separate power targets for 2.4G CCK/OFDM ch 3-9 and 2/10.
731 * Express ch 3-9 limits here and fixup 2/10 in wlc_channel_reg_limits().
734 static const locale_info_t locale_a4_4 = { /* locale a4_4. channel 1 - 11 */
735 LOCALE_CHAN_01_11,
736 LOCALE_RADAR_SET_NONE,
737 LOCALE_RESTRICTED_NONE,
738 { /* 22.5 */ 90, /* 26.5 */ 106, /* 22.5 */ 90,
739 /* 18.5 */ 74, /* 25.5 */ 102, /* 18.5 */ 74 },
740 {30, 30, 30, 0},
741 WLC_PEAK_CONDUCTED
744 /* CLM v2.1.1 has separate power targets for 2.4G CCK/OFDM ch 2, 3-9 and 10.
745 * Express ch 2-9 limits here and fixup 10 in wlc_channel_reg_limits().
747 static const locale_info_t locale_a5 = { /* locale a5. channel 1 - 11 */
748 LOCALE_CHAN_01_11,
749 LOCALE_RADAR_SET_NONE,
750 LOCALE_RESTRICTED_NONE,
751 { /* 19.5 dBm */ 78, QDB(21), QDB(18),
752 QDB(17), QDB(20), QDB(17)},
753 {30, 30, 30, 0},
754 WLC_PEAK_CONDUCTED
757 static const locale_info_t locale_a5_1 = { /* locale a5_1. channel 1 - 11 */
758 LOCALE_CHAN_01_11,
759 LOCALE_RADAR_SET_NONE,
760 LOCALE_RESTRICTED_NONE,
761 { QDB(18), QDB(18), QDB(18),
762 QDB(14), QDB(18), QDB(14)},
763 {30, 30, 30, 0},
764 WLC_PEAK_CONDUCTED
767 /* CLM v2.1.4 has separate power targets for 2.4G CCK/OFDM ch 2, 3-9 and 10.
768 * Express ch 3-9 limits here and fixup 10 in wlc_channel_reg_limits().
770 static const locale_info_t locale_a6 = { /* locale a5. channel 1 - 11 */
771 LOCALE_CHAN_01_11,
772 LOCALE_RADAR_SET_NONE,
773 LOCALE_RESTRICTED_NONE,
774 { QDB(20), QDB(21), /* 19.5 dBm */ 78,
775 /* 16.5 dBm */ 66, QDB(21), /* 16.5 dBm */ 66},
776 {30, 30, 30, 0},
777 WLC_PEAK_CONDUCTED
780 /* CLM v3.2 has separate power targets for 2.4G CCK/OFDM ch 2, 3-9 and 10.
781 * Express ch 3-9 limits here and fixup 10 in wlc_channel_reg_limits().
783 static const locale_info_t locale_a6_1 = { /* locale a5. channel 1 - 11 */
784 LOCALE_CHAN_01_11,
785 LOCALE_RADAR_SET_NONE,
786 LOCALE_RESTRICTED_NONE,
787 { QDB(20), QDB(21), /* 18.5 dBm */ 74,
788 QDB(14), QDB(21), QDB(14)},
789 {30, 30, 30, 0},
790 WLC_PEAK_CONDUCTED
793 /* CLM v3.7 has separate power targets for 2.4G CCK/OFDM ch 2, 3-9 and 10.
794 * Express ch 3-9 limits here and fixup 10 in wlc_channel_reg_limits().
796 static const locale_info_t locale_a6_2 = { /* locale a6_2. channel 1 - 11 */
797 LOCALE_CHAN_01_11,
798 LOCALE_RADAR_SET_NONE,
799 LOCALE_RESTRICTED_NONE,
800 { /* 18.5 dBm */ 74, /* 21.5 dBm */ 86, 74,
801 QDB(14), QDB(19), QDB(14)},
802 {30, 30, 30, 0},
803 WLC_PEAK_CONDUCTED
806 static const locale_info_t locale_a6_3 = { /* locale a6_3. channel 1 - 11 */
807 LOCALE_CHAN_01_11,
808 LOCALE_RADAR_SET_NONE,
809 LOCALE_RESTRICTED_NONE,
810 { /* 21.5 dBm */ 86, 86, 86,
811 /* 17.5 */ 70, /* 21.5 dBm */ 86, 70},
812 {30, 30, 30, 0},
813 WLC_PEAK_CONDUCTED
816 static const locale_info_t locale_a6_8 = { /* locale a6_8. channel 1 - 11 */
817 LOCALE_CHAN_01_11,
818 LOCALE_RADAR_SET_NONE,
819 LOCALE_RESTRICTED_NONE,
820 { QDB(19), QDB(20), /* 20.5 dBm */ 82,
821 QDB(15), /* 21.5 dBm */ 86, QDB(18)},
822 {30, 30, 30, 0},
823 WLC_PEAK_CONDUCTED
826 static const locale_info_t locale_a7 = { /* locale a7 channel 1 - 11 */
827 LOCALE_CHAN_01_11,
828 LOCALE_RADAR_SET_NONE,
829 LOCALE_RESTRICTED_NONE,
830 {QDB(19), QDB(19), QDB(17),
831 QDB(18), QDB(19), /* 13.5 dBm */ 54},
832 {30, 30, 30, 0},
833 WLC_PEAK_CONDUCTED
836 /* CLM v2.3 has separate power targets for 2.4G OFDM ch 2, 3, 4-8, 9 and 10.
837 * Express ch 4-8 limits here and fixup others in wlc_channel_reg_limits().
839 static const locale_info_t locale_a9 = { /* locale a9 channel 1 - 11 */
840 LOCALE_CHAN_01_11,
841 LOCALE_RADAR_SET_NONE,
842 LOCALE_RESTRICTED_NONE,
843 {QDB(19), QDB(19), QDB(18),
844 QDB(13), QDB(18), QDB(13)},
845 {30, 30, 30, 0},
846 WLC_PEAK_CONDUCTED
849 static const locale_info_t locale_a10 = { /* locale a9 channel 1 - 11 */
850 LOCALE_CHAN_01_11,
851 LOCALE_RADAR_SET_NONE,
852 LOCALE_RESTRICTED_NONE,
853 {QDB(17), QDB(17), QDB(17),
854 QDB(17), QDB(17), QDB(17)},
855 {30, 30, 30, 0},
856 WLC_PEAK_CONDUCTED
859 static const locale_info_t locale_a10_1 = {
860 LOCALE_CHAN_01_11,
861 LOCALE_RADAR_SET_NONE,
862 LOCALE_RESTRICTED_NONE,
863 { QDB(17), QDB(17), QDB(17),
864 /* 14.5 */ 58, /* 16.5 dBm */ 66, 58},
865 {30, 30, 30, 0},
866 WLC_PEAK_CONDUCTED
869 static const locale_info_t locale_a10_2 = {
870 LOCALE_CHAN_01_11,
871 LOCALE_RADAR_SET_NONE,
872 LOCALE_RESTRICTED_NONE,
873 { /* 16.5 dBm */ 66, 66, 66,
874 QDB(14), /* 14.5 */ 58, 58},
875 {30, 30, 30, 0},
876 WLC_PEAK_CONDUCTED
879 static const locale_info_t locale_a10_3 = {
880 LOCALE_CHAN_01_11,
881 LOCALE_RADAR_SET_NONE,
882 LOCALE_RESTRICTED_NONE,
883 { QDB(18), QDB(18), QDB(18),
884 /* 15.5 */ 62, QDB(16), QDB(16)},
885 {30, 30, 30, 0},
886 WLC_PEAK_CONDUCTED
889 static const locale_info_t locale_a11 = {
890 LOCALE_CHAN_01_11,
891 LOCALE_RADAR_SET_NONE,
892 LOCALE_RESTRICTED_NONE,
893 { /* 16.5 */ 66, 66, 66,
894 QDB(13), 66, /* 12.75 */ 51},
895 {30, 30, 30, 0},
896 WLC_PEAK_CONDUCTED
899 static const locale_info_t locale_a12 = { /* locale a12 channel 1 - 11 */
900 LOCALE_CHAN_01_11,
901 LOCALE_RADAR_SET_NONE,
902 LOCALE_RESTRICTED_NONE,
903 {QDB(17), QDB(17), QDB(14),
904 QDB(10), QDB(10), QDB(10)},
905 {30, 30, 30, 0},
906 WLC_PEAK_CONDUCTED
909 /* CLM 4.3.3 added Locale A14, Chan 1-11, both CCK & OFDM Express Conducted */
910 static const locale_info_t locale_a14 = { /* locale a14 channel 1 - 11 */
911 LOCALE_CHAN_01_11,
912 LOCALE_RADAR_SET_NONE,
913 LOCALE_RESTRICTED_NONE,
914 { /* 18.5 dBm */ 74, QDB(19), QDB(17),
915 /* 17.5 dBm */70, 70, QDB(15)},
916 {30, 30, 30, 0},
917 WLC_PEAK_CONDUCTED
920 static const locale_info_t locale_a20 = { /* locale a20. channel 1 - 11 */
921 LOCALE_CHAN_01_11,
922 LOCALE_RADAR_SET_NONE,
923 LOCALE_RESTRICTED_NONE,
924 {QDB(19), QDB(19), QDB(19),
925 QDB(14), QDB(19), QDB(14)},
926 {30, 30, 30, 0},
927 WLC_PEAK_CONDUCTED
930 static const locale_info_t locale_b = { /* locale b. channel 1 - 13 */
931 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
932 LOCALE_RADAR_SET_NONE,
933 LOCALE_RESTRICTED_NONE,
934 {QDB(19), QDB(19), QDB(19),
935 QDB(19), QDB(19), QDB(19)},
936 {20, 20, 20, 0},
937 WLC_EIRP | WLC_FILT_WAR
940 static const locale_info_t locale_b_1 = { /* locale b. channel 1 - 13 */
941 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
942 LOCALE_RADAR_SET_NONE,
943 LOCALE_RESTRICTED_NONE,
944 {QDB(19), QDB(19), QDB(19),
945 QDB(18), QDB(18), QDB(18)},
946 {20, 20, 20, 0},
947 WLC_EIRP
950 static const locale_info_t locale_b_2 = { /* locale b. channel 1 - 13 */
951 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
952 LOCALE_RADAR_SET_NONE,
953 LOCALE_RESTRICTED_NONE,
954 {QDB(17), QDB(18), QDB(17),
955 QDB(17), QDB(18), QDB(17)},
956 {20, 20, 20, 0},
957 WLC_PEAK_CONDUCTED
960 static const locale_info_t locale_b_3 = { /* locale b_3. channel 1 - 13 */
961 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
962 LOCALE_RADAR_SET_NONE,
963 LOCALE_RESTRICTED_NONE,
964 { /* 14.5 */ 58, 58, 58,
965 58, 58, 58},
966 {20, 20, 20, 0},
967 WLC_PEAK_CONDUCTED
970 static const locale_info_t locale_b_4 = { /* locale b_4. channel 1 - 13 */
971 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
972 LOCALE_RADAR_SET_NONE,
973 LOCALE_RESTRICTED_NONE,
974 { QDB(16), QDB(16), QDB(16),
975 /* 16.5 */ 66, 66, 66},
976 {20, 20, 20, 0},
977 WLC_PEAK_CONDUCTED
980 static const locale_info_t locale_b_9 = { /* locale b_9. channel 1 - 13 */
981 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
982 LOCALE_RADAR_SET_NONE,
983 LOCALE_RESTRICTED_NONE,
984 { QDB(18), QDB(18), QDB(18),
985 QDB(18), QDB(18), QDB(18)},
986 {20, 20, 20, 0},
987 WLC_PEAK_CONDUCTED
990 static const locale_info_t locale_b_11 = { /* locale b_11. channel 1 - 13 */
991 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
992 LOCALE_RADAR_SET_NONE,
993 LOCALE_RESTRICTED_NONE,
994 { /* 16.5 */ 66, 66, 66,
995 /* 16.5 */ 66, 66, 66},
996 {20, 20, 20, 0},
997 WLC_PEAK_CONDUCTED
1000 static const locale_info_t locale_b_5 = { /* locale b_5. channel 1 - 13 */
1001 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1002 LOCALE_RADAR_SET_NONE,
1003 LOCALE_RESTRICTED_NONE,
1004 {QDB(19), QDB(19), QDB(19),
1005 QDB(19), QDB(19), QDB(19)},
1006 {20, 20, 20, 0},
1007 WLC_PEAK_CONDUCTED
1010 static const locale_info_t locale_b_6 = { /* locale b_6. channel 1 - 13 */
1011 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1012 LOCALE_RADAR_SET_NONE,
1013 LOCALE_RESTRICTED_NONE,
1014 {QDB(18), QDB(18), QDB(18),
1015 QDB(18), QDB(18), QDB(18)},
1016 {20, 20, 20, 0},
1017 WLC_PEAK_CONDUCTED
1020 static const locale_info_t locale_b_7 = { /* locale b_7. channel 1 - 13 */
1021 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1022 LOCALE_RADAR_SET_NONE,
1023 LOCALE_RESTRICTED_NONE,
1024 {QDB(17), QDB(17), QDB(17),
1025 QDB(17), QDB(17), QDB(17)},
1026 {20, 20, 20, 0},
1027 WLC_PEAK_CONDUCTED
1030 static const locale_info_t locale_b_8 = { /* locale b_8. channel 1 - 13 */
1031 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1032 LOCALE_RADAR_SET_NONE,
1033 LOCALE_RESTRICTED_NONE,
1034 {QDB(16), QDB(16), QDB(16),
1035 QDB(16), QDB(16), QDB(16)},
1036 {20, 20, 20, 0},
1037 WLC_PEAK_CONDUCTED
1040 static const locale_info_t locale_b2 = { /* locale b. channel 1 - 14 */
1041 LOCALE_CHAN_01_14,
1042 LOCALE_RADAR_SET_NONE,
1043 LOCALE_RESTRICTED_12_13_14,
1044 {QDB(19), QDB(19), QDB(19),
1045 QDB(19), QDB(19), QDB(19)},
1046 {20, 20, 20, 0},
1047 WLC_EIRP
1050 static const locale_info_t locale_b2_1 = { /* locale b. channel 1 - 14 */
1051 LOCALE_CHAN_01_14,
1052 LOCALE_RADAR_SET_NONE,
1053 LOCALE_RESTRICTED_12_13_14,
1054 {QDB(16), QDB(16), QDB(12),
1055 QDB(14), QDB(16), QDB(11)},
1056 {20, 20, 20, 0},
1057 WLC_PEAK_CONDUCTED
1060 static const locale_info_t locale_b2_2 = { /* locale b. channel 1 - 14 */
1061 LOCALE_CHAN_01_14,
1062 LOCALE_RADAR_SET_NONE,
1063 LOCALE_RESTRICTED_12_13_14,
1064 {QDB(16), QDB(16), QDB(12),
1065 QDB(16), QDB(16), QDB(11)},
1066 {20, 20, 20, 0},
1067 WLC_PEAK_CONDUCTED
1070 static const locale_info_t locale_b2_3 = { /* locale b. channel 1 - 14 */
1071 LOCALE_CHAN_01_14,
1072 LOCALE_RADAR_SET_NONE,
1073 LOCALE_RESTRICTED_12_13_14,
1074 {QDB(16), QDB(16), QDB(16),
1075 QDB(16), QDB(16), QDB(16)},
1076 {20, 20, 20, 0},
1077 WLC_PEAK_CONDUCTED
1080 static const locale_info_t locale_b2_4 = { /* locale b. channel 1 - 13 */
1081 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1082 LOCALE_RADAR_SET_NONE,
1083 LOCALE_RESTRICTED_12_13_14,
1084 {QDB(15), QDB(15), QDB(15),
1085 /* 13.5 dBm */ 54, 54, 54},
1086 {20, 20, 20, 0},
1087 WLC_PEAK_CONDUCTED
1090 static const locale_info_t locale_b2_5 = { /* locale b. channel 1 - 13 */
1091 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1092 LOCALE_RADAR_SET_NONE,
1093 LOCALE_RESTRICTED_12_13_14,
1094 {QDB(16), QDB(16), QDB(16),
1095 QDB(16), QDB(16), QDB(16)},
1096 {20, 20, 20, 0},
1097 WLC_PEAK_CONDUCTED
1100 static const locale_info_t locale_b2_6 = { /* locale b. channel 1 - 13 */
1101 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1102 LOCALE_RADAR_SET_NONE,
1103 LOCALE_RESTRICTED_12_13_14,
1104 {QDB(16), QDB(16), QDB(12),
1105 QDB(16), QDB(16), QDB(11)},
1106 {20, 20, 20, 0},
1107 WLC_PEAK_CONDUCTED
1111 /* CLM 1.12.4 has locale b3. EIRP for CCK but conducted for OFDM
1112 * Express EIRP here and fixup OFDM in wlc_channel_reg_limits().
1114 static const locale_info_t locale_b3 = {
1115 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1116 LOCALE_RADAR_SET_NONE,
1117 LOCALE_RESTRICTED_NONE,
1118 {QDB(19), QDB(19), QDB(19),
1119 QDB(11), QDB(16), QDB(11)},
1120 {20, 20, 20, 0},
1121 WLC_EIRP
1124 static const locale_info_t locale_b3_1 = { /* locale b. channel 1 - 14 */
1125 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1126 LOCALE_RADAR_SET_NONE,
1127 LOCALE_RESTRICTED_NONE,
1128 {QDB(15), QDB(15), QDB(15),
1129 QDB(15), QDB(15), QDB(15)},
1130 {20, 20, 20, 0},
1131 WLC_PEAK_CONDUCTED
1134 static const locale_info_t locale_b3_2 = { /* locale b. channel 1 - 13 */
1135 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1136 LOCALE_RADAR_SET_NONE,
1137 LOCALE_RESTRICTED_NONE,
1138 {QDB(13), QDB(13), QDB(13),
1139 0, 0, 0},
1140 {20, 20, 20, 0},
1141 WLC_PEAK_CONDUCTED
1144 /* CLM 2.1.1 has locale b4. EIRP for CCK but conducted for OFDM
1145 * Express EIRP here and fixup OFDM in wlc_channel_reg_limits().
1147 static const locale_info_t locale_b4 = {
1148 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1149 LOCALE_RADAR_SET_NONE,
1150 LOCALE_RESTRICTED_NONE,
1151 {QDB(19), QDB(19), QDB(19),
1152 QDB(16), QDB(17), QDB(16)},
1153 {20, 20, 20, 0},
1154 WLC_EIRP
1157 static const locale_info_t locale_b5 = { /* locale b5. channel 1 - 14 */
1158 LOCALE_CHAN_01_14,
1159 LOCALE_RADAR_SET_NONE,
1160 LOCALE_RESTRICTED_12_13_14,
1161 { /* 16.5 dBm */ 66, /* 16.5 dBm */ 66, /* 16.5 dBm */ 66,
1162 /* 15.5 dBm */ 62, /* 16.5 dBm */ 66, /* 16.5 dBm */ 66},
1163 {20, 20, 20, 0},
1164 WLC_PEAK_CONDUCTED
1167 /* CLM v2.8 has separate power targets for 2.4G CCK/OFDM ch 11-14.
1168 * Express some limits here and fixup in wlc_channel_reg_limits().
1170 static const locale_info_t locale_b5_2 = { /* locale b5-2. channel 1 - 14 */
1171 LOCALE_CHAN_01_14,
1172 LOCALE_RADAR_SET_NONE,
1173 LOCALE_RESTRICTED_12_13_14,
1174 {QDB(16), QDB(16), QDB(16),
1175 /* 12.5 dBm */ 50, QDB(15), /* 12.5 dBm */ 50},
1176 {20, 20, 20, 0},
1177 WLC_PEAK_CONDUCTED
1180 /* Locale B5-3 has separate power targets for 2.4G OFDM ch 12-13.
1181 * Express some limits here and fixup in wlc_channel_reg_limits().
1183 static const locale_info_t locale_b5_3 = { /* locale b5-3. channel 1 - 14 */
1184 LOCALE_CHAN_01_14,
1185 LOCALE_RADAR_SET_NONE,
1186 LOCALE_RESTRICTED_12_13_14,
1187 { /* 16.5 */ 66, 66, 66,
1188 QDB(13), 66, 66},
1189 {20, 20, 20, 0},
1190 WLC_PEAK_CONDUCTED
1193 static const locale_info_t locale_b5_4 = { /* locale b5-4. channel 1 - 14 */
1194 LOCALE_CHAN_01_14,
1195 LOCALE_RADAR_SET_NONE,
1196 LOCALE_RESTRICTED_12_13_14,
1197 { /* 16.5 */ 66, 66, 66,
1198 66, 66, 66},
1199 {20, 20, 20, 0},
1200 WLC_PEAK_CONDUCTED
1203 static const locale_info_t locale_c = { /* locale c. channel 1 - 14 */
1204 LOCALE_CHAN_01_14,
1205 LOCALE_RADAR_SET_NONE,
1206 LOCALE_RESTRICTED_NONE,
1207 {QDB(19), QDB(19), QDB(19),
1208 QDB(19), QDB(19), QDB(19)},
1209 /* Tx Max Power is given as 10dBm/MHz. To translate to max power for 20 MHz channel width:
1210 * 10dBm/MHz * 20MHz
1211 * 10dBm + dB(20)
1212 * 10dBm + 10*log10(20)
1213 * 10dBm + 13dB
1214 * = 23 dBm
1216 {23, 23, 23, 0},
1217 WLC_EIRP
1220 static const locale_info_t locale_c_1 = { /* locale c-1. channel 1 - 14 */
1221 LOCALE_CHAN_01_14,
1222 LOCALE_RADAR_SET_NONE,
1223 LOCALE_RESTRICTED_NONE,
1224 {QDB(15), QDB(15), QDB(15),
1225 QDB(15), QDB(15), QDB(15)},
1226 /* Tx Max Power is given as 10dBm/MHz. To translate to max power for 20 MHz channel width:
1227 * 10dBm/MHz * 20MHz
1228 * 10dBm + dB(20)
1229 * 10dBm + 10*log10(20)
1230 * 10dBm + 13dB
1231 * = 23 dBm
1233 {23, 23, 23, 0},
1234 WLC_PEAK_CONDUCTED
1237 static const locale_info_t locale_c_2 = { /* locale c-2. channel 1 - 14 */
1238 LOCALE_CHAN_01_14,
1239 LOCALE_RADAR_SET_NONE,
1240 LOCALE_RESTRICTED_NONE,
1241 { /* 16.5 */ 66, 66, 66,
1242 66, 66, 66},
1243 {23, 23, 23, 0},
1244 WLC_PEAK_CONDUCTED
1247 static const locale_info_t locale_c_5 = { /* locale c-5. channel 1 - 13 */
1248 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1249 LOCALE_RADAR_SET_NONE,
1250 LOCALE_RESTRICTED_NONE,
1251 { /* 15.5 */ 62, 62, 62,
1252 /* 17.5 */ 70, 70, 70},
1253 {23, 23, 23, 0},
1254 WLC_PEAK_CONDUCTED
1257 static const locale_info_t locale_c_4 = { /* locale c-4. channel 1 - 14 */
1258 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1259 LOCALE_RADAR_SET_NONE,
1260 LOCALE_RESTRICTED_NONE,
1261 { /* 13.5 */ 54, 54, 54,
1262 QDB(14), QDB(14), QDB(14)},
1263 {23, 23, 23, 0},
1264 WLC_PEAK_CONDUCTED
1267 static const locale_info_t locale_f = { /* locale f. no channel */
1269 LOCALE_RADAR_SET_NONE,
1270 LOCALE_RESTRICTED_NONE,
1271 {0, 0, 0,
1272 0, 0, 0},
1273 {0, 0, 0, 0},
1274 WLC_PEAK_CONDUCTED
1277 static const locale_info_t locale_g = { /* locale g. channel 1 - 13 */
1278 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1279 LOCALE_RADAR_SET_NONE,
1280 LOCALE_RESTRICTED_NONE,
1281 {QDB(23), QDB(23), QDB(23),
1282 QDB(23), QDB(23), QDB(23)},
1283 {23, 23, 23, 0},
1284 WLC_EIRP
1287 static const locale_info_t locale_h = { /* locale h. channel 1 - 13 */
1288 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1289 LOCALE_RADAR_SET_NONE,
1290 LOCALE_RESTRICTED_NONE,
1291 {QDB(25), QDB(25), QDB(25),
1292 QDB(25), QDB(25), QDB(25)},
1293 {36, 36, 36, 0},
1294 WLC_EIRP
1297 static const locale_info_t locale_i = { /* locale i. channel 1 - 13 */
1298 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1299 LOCALE_RADAR_SET_NONE,
1300 LOCALE_RESTRICTED_SET_2G_SHORT,
1301 {QDB(19), QDB(19), QDB(19),
1302 QDB(19), QDB(19), QDB(19)},
1303 {20, 20, 20, 0},
1304 WLC_EIRP | WLC_FILT_WAR
1307 static const locale_info_t locale_i_1 = { /* locale i_1. channel 1 - 13 */
1308 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1309 LOCALE_RADAR_SET_NONE,
1310 LOCALE_RESTRICTED_SET_2G_SHORT,
1311 {QDB(15), QDB(15), QDB(15),
1312 QDB(14), QDB(16), QDB(16)},
1313 {20, 20, 20, 0},
1314 WLC_PEAK_CONDUCTED
1317 static const locale_info_t locale_j = { /* locale j. channel 1 - 11 */
1318 LOCALE_CHAN_01_11,
1319 LOCALE_RADAR_SET_NONE,
1320 LOCALE_RESTRICTED_NONE,
1321 {QDB(19), QDB(19), QDB(19),
1322 QDB(19), QDB(19), QDB(19)},
1323 {20, 20, 20, 0},
1324 WLC_EIRP
1327 /* CLM 2.0 has locale b3. EIRP for CCK but conducted for OFDM
1328 * Express EIRP here and fixup OFDM in wlc_channel_reg_limits().
1330 static const locale_info_t locale_k = { /* locale k. channel 1 - 13 */
1331 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1332 LOCALE_RADAR_SET_NONE,
1333 LOCALE_RESTRICTED_NONE,
1334 {QDB(19), QDB(19), QDB(19),
1335 QDB(14), QDB(16), QDB(16)},
1336 {20, 20, 20, 0},
1337 WLC_EIRP
1340 static const locale_info_t locale_k_1 = { /* locale k_1. channel 1 - 13 */
1341 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1342 LOCALE_RADAR_SET_NONE,
1343 LOCALE_RESTRICTED_NONE,
1344 { /* 16.5 */ 66, 66, 66,
1345 66, 66, 66},
1346 {20, 20, 20, 0},
1347 WLC_PEAK_CONDUCTED
1350 static const locale_info_t locale_k_3 = { /* locale k_3. channel 1 - 13 */
1351 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1352 LOCALE_RADAR_SET_NONE,
1353 LOCALE_RESTRICTED_NONE,
1354 { /* 17.5 */ 70, 70, 70,
1355 QDB(18), QDB(18), QDB(18)},
1356 {20, 20, 20, 0},
1357 WLC_PEAK_CONDUCTED
1360 static const locale_info_t locale_k_4 = { /* locale k_4. channel 1 - 13 */
1361 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1362 LOCALE_RADAR_SET_NONE,
1363 LOCALE_RESTRICTED_NONE,
1364 { /* 16.5 */ 66, 66, 66,
1365 66, 66, 66},
1366 {20, 20, 20, 0},
1367 WLC_PEAK_CONDUCTED
1370 /* same as locale_c except no ch 14 */
1371 static const locale_info_t locale_c1 = { /* locale c. channel 1 - 13 */
1372 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
1373 LOCALE_RADAR_SET_NONE,
1374 LOCALE_RESTRICTED_NONE,
1375 {QDB(19), QDB(19), QDB(19),
1376 QDB(19), QDB(19), QDB(19)},
1377 /* Tx Max Power is given as 10dBm/MHz. To translate to max power for 20 MHz channel width:
1378 * 10dBm/MHz * 20MHz
1379 * 10dBm + dB(20)
1380 * 10dBm + 10*log10(20)
1381 * 10dBm + 13dB
1382 * = 23 dBm
1384 {23, 23, 23, 0},
1385 WLC_EIRP
1388 static const locale_info_t locale_2G_band_all = { /* locale testing. channel 1 - 14 */
1389 LOCALE_CHAN_01_14,
1390 LOCALE_RADAR_SET_NONE,
1391 LOCALE_RESTRICTED_NONE,
1392 {QDB(30), QDB(30), QDB(30),
1393 QDB(30), QDB(30), QDB(30)},
1394 {30, 30, 30, 0},
1395 WLC_PEAK_CONDUCTED
1397 #endif /* BAND2G */
1400 * Locale Definitions - 5 GHz
1403 #ifdef BAND5G
1404 /* a band locale table */
1405 static const locale_info_t locale_1 = { /* locale 1. channel 36 - 48, 52 - 64, 149 - 165 */
1406 LOCALE_CHAN_36_64 | LOCALE_CHAN_149_165,
1407 LOCALE_RADAR_SET_1,
1408 LOCALE_RESTRICTED_NONE,
1409 {QDB(14), /* 17.5 */ 70, /* 14.5 */ 58, 0, /* 17.5 */ 70},
1410 {17, 24, 24, 0, 30},
1411 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
1414 static const locale_info_t locale_1a = { /* locale 1a. channel 36 - 48, 52 - 64, 149 - 165 */
1415 LOCALE_CHAN_36_64 | LOCALE_CHAN_149_165,
1416 LOCALE_RADAR_SET_1,
1417 LOCALE_RESTRICTED_CHAN_165,
1418 {QDB(14), /* 17.5 */ 70, /* 14.5 */ 58, 0, /* 17.5 */ 70},
1419 {17, 24, 24, 0, 30},
1420 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
1423 static const locale_info_t locale_1c = { /* locale 1c. channel 36 - 48, 52 - 64, 149 - 165 */
1424 LOCALE_CHAN_36_64 | LOCALE_CHAN_149_165,
1425 LOCALE_RADAR_SET_1,
1426 LOCALE_RESTRICTED_NONE,
1427 {QDB(13), /* 17.5 */ 70, /* 14.5 */ 58, 0, /* 17.5 */ 70},
1428 {17, 24, 24, 0, 30},
1429 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
1432 static const locale_info_t locale_1r = { /* locale 1r. channel 36 - 48, 52 - 64, 149 - 165 */
1433 LOCALE_CHAN_36_64 | LOCALE_CHAN_149_165,
1434 LOCALE_RADAR_SET_1,
1435 LOCALE_CHAN_ALL_5G,
1436 {QDB(14), /* 17.5 */ 70, /* 14.5 */ 58, 0, /* 17.5 */ 70},
1437 {17, 24, 24, 0, 30},
1438 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
1441 static const locale_info_t locale_2 = { /* locale 2. channel 36 - 48, 52 - 64, 149 - 165 */
1442 LOCALE_CHAN_36_64 | LOCALE_SET_5G_HIGH1 | LOCALE_SET_5G_HIGH2,
1443 LOCALE_RADAR_SET_1,
1444 LOCALE_RESTRICTED_NONE,
1445 {QDB(16), QDB(16), QDB(16), QDB(16), QDB(16)},
1446 {23, 24, 24, 0, 30},
1447 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
1450 static const locale_info_t locale_3 = { /* locale 3. channel 36 - 48, 52 - 64, 100 - 140 */
1451 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140,
1452 LOCALE_RADAR_SET_1,
1453 LOCALE_RESTRICTED_NONE,
1454 {QDB(21), QDB(21), QDB(21), QDB(21), 0},
1455 {23, 23, 23, 30, 0},
1456 WLC_EIRP | WLC_DFS_EU
1459 /* CLM v4.6.6 */
1460 static const locale_info_t locale_3_1 = {
1461 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140,
1462 LOCALE_RADAR_SET_1,
1463 LOCALE_RESTRICTED_NONE,
1464 {74, 74, 74, 86, 0},
1465 {23, 23, 23, 30, 0},
1466 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1469 static const locale_info_t locale_3b = { /* locale 3b. channel 36 - 48, 52 - 64, 100 - 140 */
1470 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140,
1471 LOCALE_RADAR_SET_1,
1472 LOCALE_RESTRICTED_NONE,
1473 { /* 20.5 */ 82, 82, 82, 82, 0},
1474 {23, 23, 23, 30, 0},
1475 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1478 static const locale_info_t locale_3d = { /* locale 3d. channel 36 - 48, 52 - 64, 100 - 140 */
1479 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140,
1480 LOCALE_RADAR_SET_1,
1481 LOCALE_RESTRICTED_NONE,
1482 { /* 15.5 */ 62, 62, 62, /* 14.5 */ 58, 0},
1483 {23, 23, 23, 30, 0},
1484 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1487 /* locale 3j. channel 36 - 48, 52 - 64, 100 - 140 */
1488 static const locale_info_t locale_3j = {
1489 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140,
1490 LOCALE_RADAR_SET_1,
1491 LOCALE_RESTRICTED_NONE,
1492 {QDB(14), QDB(14), QDB(14), QDB(15), 0},
1493 {23, 23, 23, 30, 0},
1494 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
1497 /* locale 3j-1. channel 36 - 48, 52 - 64, 100 - 140 */
1498 static const locale_info_t locale_3j_1 = {
1499 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140,
1500 LOCALE_RADAR_SET_1,
1501 LOCALE_RESTRICTED_NONE,
1502 { /* 15.5 */ 62, 62, 62, /* 16.5 */ 66, 0},
1503 {23, 23, 23, 30, 0},
1504 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
1507 /* locale 3j-3. channel 36 - 48, 52 - 64, 100 - 140 */
1508 static const locale_info_t locale_3j_3 = {
1509 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140,
1510 LOCALE_RADAR_SET_1,
1511 LOCALE_RESTRICTED_NONE,
1512 { /* 15.5 */ 62, 62, 62, /* 14.5 */ 58, 0},
1513 {23, 23, 23, 30, 0},
1514 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
1517 /* locale 3j-4. channel 36 - 48, 52 - 64, 100 - 140 */
1518 static const locale_info_t locale_3j_4 = {
1519 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140,
1520 LOCALE_RADAR_SET_1,
1521 LOCALE_RESTRICTED_NONE,
1522 { /* 13.5 */ 54, 54, 54, 54, 0},
1523 {23, 23, 23, 30, 0},
1524 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
1527 /* locale 3j-5. channel 36 - 48, 52 - 64, 100 - 140 */
1528 static const locale_info_t locale_3j_5 = {
1529 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140,
1530 LOCALE_RADAR_SET_1,
1531 LOCALE_RESTRICTED_NONE,
1532 { QDB(15), QDB(10), QDB(10), QDB(16), 0},
1533 {23, 23, 23, 30, 0},
1534 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
1537 /* locale 3j-8. channel 36 - 48, 52 - 64, 100 - 140 */
1538 static const locale_info_t locale_3j_8 = {
1539 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140,
1540 LOCALE_RADAR_SET_1,
1541 LOCALE_RESTRICTED_NONE,
1542 { QDB(21), QDB(21), QDB(21), QDB(21), 0},
1543 {23, 23, 23, 30, 0},
1544 WLC_EIRP | WLC_DFS_FCC
1547 /* 100-116 has different power than 132-140, fixup in wlc_channel_reg_limits(). */
1548 /* locale 3l. channel 36 - 48, 52 - 64, 100 - 116, 132 - 140 */
1549 static const locale_info_t locale_3l = {
1550 LOCALE_CHAN_36_64 | LOCALE_SET_5G_MID1 | LOCALE_SET_5G_HIGH1,
1551 LOCALE_RADAR_SET_1,
1552 LOCALE_RESTRICTED_NONE,
1553 { /* 13.5 dBm */ 54, 54, QDB(13), QDB(13), 0},
1554 {23, 23, 23, 30, 0},
1555 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1558 /* locale 3l_1. channel 36 - 48, 52 - 64, 100 - 140 */
1559 static const locale_info_t locale_3l_1 = {
1560 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140,
1561 LOCALE_RADAR_SET_1,
1562 LOCALE_RESTRICTED_NONE,
1563 { /* 13.5 dBm */ 54, 54, 54, 54, 0},
1564 {23, 23, 23, 30, 0},
1565 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1569 /* locale 3r. channel 36 - 48, 52 - 64, 100 - 116, 132 - 140 */
1570 static const locale_info_t locale_3r = {
1571 LOCALE_CHAN_36_64 | LOCALE_SET_5G_MID1 | LOCALE_SET_5G_HIGH1,
1572 LOCALE_RADAR_SET_1,
1573 LOCALE_RESTRICTED_NONE,
1574 {QDB(21), QDB(21), QDB(21), QDB(21), 0},
1575 {23, 23, 23, 30, 0},
1576 WLC_EIRP | WLC_DFS_EU
1579 /* locale 3r_4. channel 36 - 48, 52 - 64, 100 - 116, 132 - 140 */
1580 static const locale_info_t locale_3r_4 = {
1581 LOCALE_CHAN_36_64 | LOCALE_SET_5G_MID1 | LOCALE_SET_5G_HIGH1,
1582 LOCALE_RADAR_SET_NONE,
1583 LOCALE_RESTRICTED_NONE,
1584 { QDB(16), QDB(16), QDB(16), QDB(16), 0},
1585 {23, 23, 23, 30, 0},
1586 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1589 /* locale 3r_5. channel 36 - 48, 52 - 64, 100 - 116, 132 - 140 */
1590 static const locale_info_t locale_3r_5 = {
1591 LOCALE_CHAN_36_64 | LOCALE_SET_5G_MID1 | LOCALE_SET_5G_HIGH1,
1592 LOCALE_RADAR_SET_NONE,
1593 LOCALE_RESTRICTED_NONE,
1594 { QDB(21), QDB(21), QDB(21), QDB(28), 0},
1595 {23, 23, 23, 30, 0},
1596 WLC_EIRP | WLC_DFS_EU
1599 /* locale 3s. channel 36 - 48, 52 - 64, 100 - 116, 132 - 140 */
1600 static const locale_info_t locale_3s = {
1601 LOCALE_CHAN_36_64 | LOCALE_SET_5G_MID1 | LOCALE_SET_5G_HIGH1,
1602 LOCALE_RADAR_SET_NONE,
1603 LOCALE_RESTRICTED_NONE,
1604 { QDB(21), QDB(21), QDB(21), QDB(21), 0},
1605 {23, 23, 23, 30, 0},
1606 WLC_EIRP | WLC_DFS_EU
1609 static const locale_info_t locale_4 = { /* locale 4. channel 34 - 46 */
1610 LOCALE_SET_5G_LOW_JP2,
1611 LOCALE_RADAR_SET_NONE,
1612 LOCALE_RESTRICTED_NONE,
1613 {QDB(21), 0, 0, 0, 0},
1614 {23, 0, 0, 0, 0},
1615 WLC_EIRP
1618 static const locale_info_t locale_5 = { /* locale 5. channel 36 - 48, 52 - 64, 149 - 165 */
1619 LOCALE_CHAN_36_64 | LOCALE_CHAN_149_165,
1620 LOCALE_RADAR_SET_1,
1621 LOCALE_RESTRICTED_NONE,
1622 {QDB(21), QDB(21), QDB(21), 0, QDB(21)},
1623 {23, 23, 23, 0, 30},
1624 WLC_EIRP | WLC_DFS_EU
1627 /* locale 5a. channel 36 - 48, 52 - 64, 100 - 116, 132 - 140, 149 - 165 */
1628 static const locale_info_t locale_5a = {
1629 LOCALE_CHAN_36_64 | LOCALE_SET_5G_MID1 | LOCALE_SET_5G_HIGH1 | LOCALE_CHAN_149_165,
1630 LOCALE_RADAR_SET_1,
1631 LOCALE_RESTRICTED_NONE,
1632 {QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)},
1633 {23, 23, 23, 30, 30},
1634 WLC_EIRP | WLC_DFS_EU
1637 /* locale 5l. channel 36 - 48, 52 - 64, 149 - 165 */
1638 static const locale_info_t locale_5l = {
1639 LOCALE_CHAN_36_64 | LOCALE_CHAN_149_165,
1640 LOCALE_RADAR_SET_1,
1641 LOCALE_RESTRICTED_NONE,
1642 { /* 13.5 dBm */ 54, 54, QDB(13), 0, QDB(15)},
1643 {23, 23, 23, 0, 30},
1644 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1647 /* locale 5l_1. channel 36 - 48, 52 - 64, 149 - 165 */
1648 static const locale_info_t locale_5l_1 = {
1649 LOCALE_CHAN_36_64 | LOCALE_CHAN_149_165,
1650 LOCALE_RADAR_SET_1,
1651 LOCALE_RESTRICTED_NONE,
1652 { /* 13.5 dBm */ 54, 54, 54, 0, QDB(15)},
1653 {23, 23, 23, 0, 30},
1654 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1657 /* locale 5l_2. channel 36 - 48, 52 - 64, 149 - 165 */
1658 static const locale_info_t locale_5l_2 = {
1659 LOCALE_CHAN_36_64 | LOCALE_CHAN_149_165,
1660 LOCALE_RADAR_SET_1,
1661 LOCALE_RESTRICTED_NONE,
1662 { QDB(15), QDB(15), QDB(15), 0, QDB(16)},
1663 {23, 23, 23, 0, 30},
1664 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1667 /* locale 6. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
1668 static const locale_info_t locale_6 = {
1669 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
1670 LOCALE_RADAR_SET_1,
1671 LOCALE_RESTRICTED_NONE,
1672 {QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)},
1673 {23, 23, 23, 24, 30},
1674 WLC_EIRP | WLC_DFS_FCC
1677 /* locale 6a_1. channel 36 - 48, 52 - 64, 149 - 165 */
1678 static const locale_info_t locale_6a_1 = {
1679 LOCALE_CHAN_36_64 | LOCALE_CHAN_149_165,
1680 LOCALE_RADAR_SET_1,
1681 LOCALE_RESTRICTED_NONE,
1682 {QDB(15), QDB(15), QDB(15), 0, QDB(17)},
1683 {23, 23, 23, 0, 30},
1684 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
1687 /* locale 6a. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
1688 static const locale_info_t locale_6a = {
1689 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
1690 LOCALE_RADAR_SET_1,
1691 LOCALE_RESTRICTED_NONE,
1692 { /* 13.5 */ 54, 54, 54, 54, QDB(15)},
1693 {23, 23, 23, 24, 30},
1694 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
1697 static const locale_info_t locale_7 = { /* locale 7. 149 - 165 */
1698 LOCALE_CHAN_149_165,
1699 LOCALE_RADAR_SET_NONE,
1700 LOCALE_RESTRICTED_NONE,
1701 {0, 0, 0, 0, QDB(21)},
1702 {0, 0, 0, 0, 27},
1703 WLC_EIRP
1706 static const locale_info_t locale_7c = { /* locale 7c. 149 - 165 */
1707 LOCALE_CHAN_149_165,
1708 LOCALE_RADAR_SET_NONE,
1709 LOCALE_RESTRICTED_NONE,
1710 {0, 0, 0, 0, QDB(21)},
1711 {0, 0, 0, 0, 27},
1712 WLC_EIRP
1715 static const locale_info_t locale_7c_1 = { /* locale 7c_1. 149 - 165 */
1716 LOCALE_CHAN_149_165,
1717 LOCALE_RADAR_SET_NONE,
1718 LOCALE_RESTRICTED_NONE,
1719 {0, 0, 0, 0, QDB(17)},
1720 {0, 0, 0, 0, 27},
1721 WLC_PEAK_CONDUCTED
1724 static const locale_info_t locale_8 = { /* locale 8. channel 56 - 64, 149 - 165 */
1725 #if 1 /* ASUS modify */
1726 LOCALE_CHAN_149_165,
1727 LOCALE_RADAR_SET_NONE,
1728 LOCALE_RESTRICTED_NONE,
1729 {0, 0, 0, 0, QDB(23)},
1730 {0, 0, 0, 0, 30},
1731 WLC_PEAK_CONDUCTED
1732 #else
1733 LOCALE_SET_5G_LOW3 | LOCALE_CHAN_149_165,
1734 LOCALE_RADAR_SET_1,
1735 LOCALE_RESTRICTED_NONE,
1736 {0, QDB(17), QDB(17), 0, QDB(17)},
1737 {0, 24, 24, 0, 30},
1738 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
1739 #endif
1742 /* locale 8. channel 56 - 64, 100 - 140, 149 - 165 */
1743 static const locale_info_t locale_8a = {
1744 LOCALE_SET_5G_LOW3 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
1745 LOCALE_RADAR_SET_1,
1746 LOCALE_RESTRICTED_NONE,
1747 {0, QDB(14), QDB(14), QDB(17), QDB(17)},
1748 {0, 17, 17, 24, 30},
1749 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
1752 /* locale 8a_1. channel 56 - 64, 100 - 140, 149 - 165 */
1753 static const locale_info_t locale_8a_1 = {
1754 LOCALE_SET_5G_LOW3 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
1755 LOCALE_RADAR_SET_1,
1756 LOCALE_RESTRICTED_NONE,
1757 {0, QDB(15), QDB(15), QDB(17), QDB(17)},
1758 {0, 17, 17, 24, 30},
1759 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
1762 /* locale 8b. channel 56 - 64, 100 - 140, 149 - 165,
1763 * channel 100, 140 need fixup in wlc_channel_reg_limits()
1765 static const locale_info_t locale_8b = { /* locale 8. channel 56 - 64, 149 - 165 */
1766 LOCALE_SET_5G_LOW3 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
1767 LOCALE_RADAR_SET_1,
1768 LOCALE_RESTRICTED_NONE,
1769 {0, /* 13.5 */ 54, 54, QDB(17), /* 17.5 */ 70},
1770 {0, 17, 17, 24, 30},
1771 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
1774 static const locale_info_t locale_9 = { /* locale 9. channel 149 - 161 */
1775 LOCALE_SET_5G_HIGH2,
1776 LOCALE_RADAR_SET_NONE,
1777 LOCALE_RESTRICTED_NONE,
1778 {0, 0, 0, 0, QDB(21)},
1779 {0, 0, 0, 0, 27},
1780 WLC_EIRP
1783 static const locale_info_t locale_9h = { /* locale 9h. channel 149 - 161 */
1784 LOCALE_SET_5G_HIGH2,
1785 LOCALE_RADAR_SET_NONE,
1786 LOCALE_RESTRICTED_NONE,
1787 {0, 0, 0, 0, QDB(23)},
1788 {0, 0, 0, 0, 33},
1789 WLC_PEAK_CONDUCTED
1792 static const locale_info_t locale_10 = { /* locale 10. channel 36 - 48, 149 - 165 */
1793 LOCALE_SET_5G_LOW1 | LOCALE_CHAN_149_165,
1794 LOCALE_RADAR_SET_NONE,
1795 LOCALE_RESTRICTED_NONE,
1796 {QDB(19), 0, 0, 0, QDB(19)},
1797 {20, 0, 0, 0, 20},
1798 WLC_EIRP
1801 static const locale_info_t locale_11 = {
1802 /* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
1803 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
1804 LOCALE_RADAR_SET_1,
1805 LOCALE_CHAN_ALL_5G,
1806 {QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)},
1807 {23, 17, 17, 23, 30},
1808 WLC_EIRP | WLC_DFS_EU
1811 static const locale_info_t locale_11_1 = {
1812 /* locale 11_1. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
1813 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
1814 LOCALE_RADAR_SET_1,
1815 LOCALE_CHAN_ALL_5G,
1816 {50 /* 12.5 dbm */, 50 /* 12.5 dbm */, 50 /* 12.5 dbm */,\
1817 50 /* 12.5 dbm */, 50 /* 12.5 dbm */},
1818 {23, 23, 23, 23, 30},
1819 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1822 static const locale_info_t locale_11_2 = {
1823 /* locale 11_2. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
1824 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
1825 LOCALE_RADAR_SET_1,
1826 LOCALE_CHAN_ALL_5G,
1827 { QDB(14), QDB(15), QDB(14), QDB(15), QDB(15)},
1828 {23, 23, 23, 23, 30},
1829 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1832 static const locale_info_t locale_11_3 = {
1833 /* locale 11_3. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
1834 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
1835 LOCALE_RADAR_SET_1,
1836 LOCALE_CHAN_ALL_5G,
1837 { QDB(14), 58, 58, QDB(15), 70},
1838 {23, 23, 23, 23, 30},
1839 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1842 static const locale_info_t locale_11_4 = {
1843 /* locale 11_4. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
1844 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
1845 LOCALE_RADAR_SET_1,
1846 LOCALE_RESTRICTED_52_ABOVE,
1847 { QDB(14), 58, 58, QDB(15), 70},
1848 {23, 23, 23, 23, 30},
1849 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1852 /* locale 11l. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
1853 static const locale_info_t locale_11l = {
1854 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
1855 LOCALE_RADAR_SET_1,
1856 LOCALE_CHAN_ALL_5G,
1857 { /* 13.5 dBm */ 54, /* 12.5 dBm */ 50, 50, QDB(15), QDB(15)},
1858 {23, 17, 17, 23, 30},
1859 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1862 /* locale 11l_1 channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
1863 static const locale_info_t locale_11l_1 = {
1864 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
1865 LOCALE_RADAR_SET_1,
1866 LOCALE_CHAN_ALL_5G,
1867 { /* 13.5 dBm */ 54, 54, 54, QDB(15), QDB(15)},
1868 {23, 17, 17, 23, 30},
1869 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1872 static const locale_info_t locale_12 = { /* locale 12. channel 149 - 161 */
1873 LOCALE_SET_5G_HIGH2,
1874 LOCALE_RADAR_SET_NONE,
1875 LOCALE_RESTRICTED_NONE,
1876 {0, 0, 0, 0, QDB(18)},
1877 {0, 0, 0, 0, 20},
1878 WLC_EIRP
1881 static const locale_info_t locale_13 = { /* locale 13. channel 36 - 48, 52 - 64 */
1882 LOCALE_CHAN_36_64,
1883 LOCALE_RADAR_SET_1,
1884 LOCALE_RESTRICTED_NONE,
1885 {QDB(21), QDB(21), QDB(21), 0, 0},
1886 {23, 23, 23, 0, 0},
1887 WLC_EIRP | WLC_DFS_EU
1890 static const locale_info_t locale_13_1 = { /* locale 13_1. channel 36 - 48, 52 - 64 */
1891 LOCALE_CHAN_36_64,
1892 LOCALE_RADAR_SET_1,
1893 LOCALE_RESTRICTED_NONE,
1894 { /* 13.5 */ 54, 54, 54, 0, 0},
1895 {23, 23, 23, 0, 0},
1896 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1899 static const locale_info_t locale_13_2 = { /* locale 13_2. channel 36 - 48, 52 - 64 */
1900 LOCALE_CHAN_36_64,
1901 LOCALE_RADAR_SET_1,
1902 LOCALE_RESTRICTED_NONE,
1903 {QDB(16), QDB(16), QDB(16), 0, 0},
1904 {23, 23, 23, 0, 0},
1905 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1908 static const locale_info_t locale_13_3 = { /* locale 13_3. channel 36 - 48, 52 - 64 */
1909 LOCALE_CHAN_36_64,
1910 LOCALE_RADAR_SET_1,
1911 LOCALE_RESTRICTED_NONE,
1912 { /* 15.5 */ 62, 62, 62, 0, 0},
1913 {23, 23, 23, 0, 0},
1914 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1917 static const locale_info_t locale_14 = { /* locale 14. channel 36 - 48, 52 - 64, 149 - 165 */
1918 LOCALE_CHAN_36_64 | LOCALE_CHAN_149_165,
1919 LOCALE_RADAR_SET_1,
1920 LOCALE_RESTRICTED_NONE,
1921 {QDB(21), QDB(21), QDB(21), 0, QDB(21)},
1922 {21, 21, 21, 0, 21},
1923 WLC_EIRP | WLC_DFS_EU
1926 static const locale_info_t locale_14a = { /* locale 14a. channel 36 - 48, 52 - 64, 149 - 165 */
1927 LOCALE_CHAN_36_64 | LOCALE_CHAN_149_165,
1928 LOCALE_RADAR_SET_1,
1929 LOCALE_RESTRICTED_NONE,
1930 { /* 13.5 */ 54, 54, 54, 0, QDB(15)},
1931 {21, 21, 21, 0, 21},
1932 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1935 static const locale_info_t locale_15 = { /* locale 15. no channel */
1937 LOCALE_RADAR_SET_NONE,
1938 LOCALE_RESTRICTED_NONE,
1939 {0, 0, 0, 0, 0},
1940 {0, 0, 0, 0, 0},
1941 WLC_PEAK_CONDUCTED
1944 static const locale_info_t locale_16 = { /* locale 16. channel 36 - 48, 52 - 64, 149 - 161 */
1945 LOCALE_CHAN_36_64 | LOCALE_SET_5G_HIGH2,
1946 LOCALE_RADAR_SET_1,
1947 LOCALE_RESTRICTED_NONE,
1948 { /* 16.5 */ 66, 66, 66, 0, 66},
1949 {23, 23, 23, 0, 23},
1950 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1953 static const locale_info_t locale_16a = { /* locale 16a. channel 36 - 48, 52 - 64, 149 - 161 */
1954 LOCALE_CHAN_36_64 | LOCALE_SET_5G_HIGH2,
1955 LOCALE_RADAR_SET_1,
1956 LOCALE_RESTRICTED_NONE,
1957 { /* 13.5 */ 54, 54, 54, 0, QDB(15)},
1958 {23, 23, 23, 0, 23},
1959 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1962 static const locale_info_t locale_17 = { /* locale 17. channel 36 - 48, 52 - 64, 149 - 165 */
1963 LOCALE_CHAN_36_64 | LOCALE_CHAN_149_165,
1964 LOCALE_RADAR_SET_1,
1965 LOCALE_RESTRICTED_NONE,
1966 { /* 16.5 */ 66, 66, 66, 0, QDB(16)},
1967 {23, 23, 23, 0, 20},
1968 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1971 static const locale_info_t locale_17a = { /* locale 17. channel 36 - 48, 52 - 64, 149 - 165 */
1972 LOCALE_CHAN_36_64 | LOCALE_CHAN_149_165,
1973 LOCALE_RADAR_SET_1,
1974 LOCALE_RESTRICTED_NONE,
1975 { /* 13.5 */ 54, 54, 54, 0, QDB(15)},
1976 {23, 23, 23, 0, 20},
1977 WLC_PEAK_CONDUCTED | WLC_DFS_EU
1980 static const locale_info_t locale_18 = { /* locale 18. channel 36 - 48 */
1981 LOCALE_SET_5G_LOW1,
1982 LOCALE_RADAR_SET_NONE,
1983 LOCALE_RESTRICTED_NONE,
1984 {QDB(21), 0, 0, 0, 0},
1985 {23, 0, 0, 0, 0},
1986 WLC_EIRP
1989 static const locale_info_t locale_18_2 = { /* locale 18_2. channel 36 - 48 */
1990 LOCALE_SET_5G_LOW1,
1991 LOCALE_RADAR_SET_NONE,
1992 LOCALE_RESTRICTED_NONE,
1993 {QDB(15), 0, 0, 0, 0},
1994 {23, 0, 0, 0, 0},
1995 WLC_PEAK_CONDUCTED
1998 static const locale_info_t locale_18l= { /* locale 18l channel 36 - 48 */
1999 LOCALE_SET_5G_LOW1,
2000 LOCALE_RADAR_SET_NONE,
2001 LOCALE_RESTRICTED_NONE,
2002 {QDB(14), 0, 0, 0, 0},
2003 {20, 0, 0, 0, 0},
2004 WLC_PEAK_CONDUCTED
2007 static const locale_info_t locale_19 = {
2008 /* locale 19. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
2009 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
2010 LOCALE_RADAR_SET_1,
2011 LOCALE_RESTRICTED_NONE,
2012 {QDB(14), /* 17.5 */ 70, /* 14.5 */ 58, QDB(17), /* 17.5 */ 70},
2013 {17, 24, 24, 24, 30},
2014 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2017 static const locale_info_t locale_19_1 = {
2018 /* locale 19-1. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
2019 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
2020 LOCALE_RADAR_SET_1,
2021 LOCALE_RESTRICTED_NONE,
2022 {QDB(14), QDB(17), QDB(14), QDB(13), QDB(17)},
2023 {17, 24, 24, 24, 30},
2024 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2027 static const locale_info_t locale_19_2 = {
2028 /* locale 19-2. channel 36 - 64, 100 - 140, 149 - 165 */
2029 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
2030 LOCALE_RADAR_SET_1,
2031 LOCALE_RESTRICTED_NONE,
2032 {QDB(14), QDB(16), QDB(16), QDB(17), /* 20.5 */ 82},
2033 {17, 24, 24, 24, 30},
2034 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2037 static const locale_info_t locale_19_3 = {
2038 /* locale 19-2. channel 36 - 64, 100 - 140, 149 - 165 */
2039 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
2040 LOCALE_RADAR_SET_1,
2041 LOCALE_RESTRICTED_NONE,
2042 {QDB(14), QDB(16), QDB(14), QDB(16), QDB(16)},
2043 {17, 24, 24, 24, 30},
2044 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2047 static const locale_info_t locale_19_4 = {
2048 /* locale 19-4. channel 36, 40 - 48, 52-60, 64, 100, 104 - 140, 149 - 165 */
2049 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
2050 LOCALE_RADAR_SET_1,
2051 LOCALE_RESTRICTED_NONE,
2052 { /* 15.5 */ 62 , 62, QDB(13), /* 14.5 */ 58, 58},
2053 {17, 24, 24, 24, 24},
2054 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2057 static const locale_info_t locale_19a = {
2058 /* locale 19. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
2059 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
2060 LOCALE_RADAR_SET_1,
2061 LOCALE_RESTRICTED_CHAN_165,
2062 {QDB(14), /* 17.5 */ 70, /* 14.5 */ 58, QDB(17), /* 17.5 */ 70},
2063 {17, 24, 24, 24, 30},
2064 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2067 static const locale_info_t locale_19r = {
2068 /* locale 19. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
2069 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
2070 LOCALE_RADAR_SET_1,
2071 LOCALE_RESTRICTED_CHAN_165,
2072 {QDB(14), /* 17.5 */ 70, /* 14.5 */ 58, QDB(17), /* 17.5 */ 70},
2073 {17, 24, 24, 24, 30},
2074 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2077 static const locale_info_t locale_19h_2 = {
2078 /* locale 19h_2. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
2079 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
2080 LOCALE_RADAR_SET_1,
2081 LOCALE_RESTRICTED_NONE,
2082 { /* 15.5 */ 62, /* 21.5 */ 86, /* 20.5 */ 82, 86, 86},
2083 {17, 24, 24, 24, 30},
2084 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2087 static const locale_info_t locale_19b = {
2088 /* locale 19. channel 36 - 48, 52 - 64, 100 - 140 */
2089 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140,
2090 LOCALE_RADAR_SET_1,
2091 LOCALE_RESTRICTED_NONE,
2092 {QDB(14), /* 17.5 */ 70, /* 14.5 */ 58, QDB(17), 0},
2093 {17, 24, 24, 24, 30},
2094 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2097 static const locale_info_t locale_19a_1 = {
2098 /* locale 19-1. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
2099 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
2100 LOCALE_RADAR_SET_1,
2101 LOCALE_RESTRICTED_NONE,
2102 {QDB(14), QDB(15), QDB(14), QDB(15), QDB(15)},
2103 {17, 24, 24, 24, 30},
2104 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2107 static const locale_info_t locale_19h_1 = {
2108 /* locale 19h_1. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
2109 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
2110 LOCALE_RADAR_SET_1,
2111 LOCALE_RESTRICTED_NONE,
2112 {QDB(14), /* 17.5 */ 70, /* 15.5 */ 62, /* 16.5 */ 66, /* 18.5 */ 74},
2113 {17, 24, 24, 24, 30},
2114 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2117 /* Channel 140 gets overriden */
2118 static const locale_info_t locale_19l_1 = {
2119 /* locale 19l-1. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
2120 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
2121 LOCALE_RADAR_SET_1,
2122 LOCALE_RESTRICTED_CHAN_165,
2123 {QDB(14), /* 17.5 dBm */ 70, /* 14.5 dBm */ 58, QDB(17), /* 17.5 dBm */ 70},
2124 {17, 24, 24, 24, 30},
2125 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2128 /* Channels 100 and 140 get overriden */
2129 static const locale_info_t locale_19l_2 = {
2130 /* locale 19l-1. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
2131 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
2132 LOCALE_RADAR_SET_1,
2133 LOCALE_RESTRICTED_CHAN_165,
2134 {QDB(13), /* 17.5 dBm */ 70, /* 14.5 dBm */ 58, QDB(17), /* 17.5 dBm */ 70},
2135 {17, 24, 24, 24, 30},
2136 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2139 static const locale_info_t locale_20 = { /* locale 20. channel 100 - 140 */
2140 LOCALE_CHAN_100_140,
2141 LOCALE_RADAR_SET_1,
2142 LOCALE_RESTRICTED_NONE,
2143 {0, 0, 0, QDB(21), 0},
2144 {0, 0, 0, 30, 0},
2145 WLC_EIRP | WLC_DFS_FCC
2148 static const locale_info_t locale_21 = { /* locale 21. channel 52 - 64, 149 - 165 */
2149 LOCALE_CHAN_52_64 | LOCALE_CHAN_149_165,
2150 LOCALE_RADAR_SET_1,
2151 LOCALE_RESTRICTED_NONE,
2152 {0, QDB(15), QDB(15), 0, QDB(17)},
2153 {0, 21, 21, 0, 30},
2154 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2157 /* locale 22. channel 34, 36, 38, 40, 42, 44, 46, 48 */
2158 static const locale_info_t locale_22 = {
2159 LOCALE_SET_5G_LOW_JP1,
2160 LOCALE_RADAR_SET_1,
2161 LOCALE_RESTRICTED_JAPAN_LEGACY,
2162 {QDB(21), 0, 0, 0, 0},
2163 {23, 0, 0, 0, 0},
2164 WLC_EIRP | WLC_DFS_FCC
2167 static const locale_info_t locale_23 = {
2168 /* locale 23. channel 34, 36, 38, 40, 42, 44, 46, 48, 52-64 */
2169 LOCALE_SET_5G_LOW_JP1 | LOCALE_CHAN_52_64,
2170 LOCALE_RADAR_SET_1,
2171 LOCALE_RESTRICTED_JAPAN_LEGACY,
2172 {QDB(21), QDB(21), QDB(21), 0, 0},
2173 {23, 23, 23, 0, 0},
2174 WLC_EIRP | WLC_DFS_FCC
2177 static const locale_info_t locale_24 = {
2178 /* locale 24. channel 34, 36, 38, 40, 42, 44, 46, 48, 52-64, 100-140 */
2179 LOCALE_SET_5G_LOW_JP1 | LOCALE_CHAN_52_64 | LOCALE_CHAN_100_140,
2180 LOCALE_RADAR_SET_1,
2181 LOCALE_RESTRICTED_JAPAN_LEGACY,
2182 {QDB(21), QDB(21), QDB(21), QDB(21), 0},
2183 {23, 23, 23, 30, 0},
2184 WLC_EIRP | WLC_DFS_FCC
2187 static const locale_info_t locale_25 = {
2188 /* locale 25. channel 34 - 46, 36 - 48, 52 - 64, 100 - 124, 149 - 161 */
2189 LOCALE_SET_5G_LOW_JP1 | LOCALE_CHAN_52_64 | LOCALE_CHAN_100_124 | LOCALE_SET_5G_HIGH2,
2190 LOCALE_RADAR_SET_1,
2191 LOCALE_RESTRICTED_NONE,
2192 {QDB(12), QDB(16), QDB(16), QDB(16), QDB(16)},
2193 {17, 23, 23, 23, 23},
2194 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2197 static const locale_info_t locale_25h = {
2198 /* locale 25h. channel 36 - 48, 52 - 64, 100 - 124, 149 - 161 */
2199 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_124 | LOCALE_SET_5G_HIGH2,
2200 LOCALE_RADAR_SET_1,
2201 LOCALE_RESTRICTED_NONE,
2202 {QDB(15), QDB(16), QDB(16), QDB(16), QDB(16)},
2203 {17, 23, 23, 23, 23},
2204 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2207 static const locale_info_t locale_25l = {
2208 /* locale 25. channel 34 - 46, 36 - 48, 52 - 64, 100 - 124, 149 - 161 */
2209 LOCALE_SET_5G_LOW_JP1 | LOCALE_CHAN_52_64 | LOCALE_CHAN_100_124 | LOCALE_SET_5G_HIGH2,
2210 LOCALE_RADAR_SET_1,
2211 LOCALE_RESTRICTED_NONE,
2212 {QDB(12), QDB(15), QDB(15), QDB(15), QDB(15)},
2213 {17, 23, 23, 23, 23},
2214 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2217 static const locale_info_t locale_27 = { /* locale 27. channel 36 - 48, 149 - 165 */
2218 LOCALE_SET_5G_LOW1 | LOCALE_CHAN_149_165,
2219 LOCALE_RADAR_SET_NONE,
2220 LOCALE_RESTRICTED_NONE,
2221 {QDB(14), 0, 0, 0, QDB(17)},
2222 {17, 0, 0, 0, 30},
2223 WLC_PEAK_CONDUCTED
2226 static const locale_info_t locale_27b = { /* locale 27b. channel 36 - 48, 149 - 165 */
2227 LOCALE_SET_5G_LOW1 | LOCALE_CHAN_149_165,
2228 LOCALE_RADAR_SET_NONE,
2229 LOCALE_RESTRICTED_NONE,
2230 #if 1 /* ASUS modify */
2231 {QDB(17.5), 0, 0, 0, QDB(17.5)},
2232 #else
2233 {QDB(14), 0, 0, 0, QDB(23)},
2234 #endif
2235 {17, 0, 0, 0, 30},
2236 WLC_PEAK_CONDUCTED
2239 static const locale_info_t locale_27c = { /* locale 27c. channel 36 - 48, 149 - 161 */
2240 LOCALE_SET_5G_LOW1 | LOCALE_SET_5G_HIGH2,
2241 LOCALE_RADAR_SET_NONE,
2242 LOCALE_RESTRICTED_NONE,
2243 {QDB(14), 0, 0, 0, QDB(23)},
2244 {17, 0, 0, 0, 30},
2245 WLC_PEAK_CONDUCTED
2248 static const locale_info_t locale_27e = { /* locale 27e. channel 36 - 48, 149 - 161 */
2249 LOCALE_SET_5G_LOW1 | LOCALE_SET_5G_HIGH2,
2250 LOCALE_RADAR_SET_NONE,
2251 LOCALE_RESTRICTED_NONE,
2252 {QDB(15), 0, 0, 0, /* 21.5 dBm */ 86},
2253 {17, 0, 0, 0, 30},
2254 WLC_PEAK_CONDUCTED
2257 static const locale_info_t locale_28 = { /* locale 28. channel 36 - 48 */
2258 LOCALE_SET_5G_LOW1,
2259 LOCALE_RADAR_SET_NONE,
2260 LOCALE_RESTRICTED_NONE,
2261 {QDB(14), 0, 0, 0, 0},
2262 {17, 0, 0, 0, 0},
2263 WLC_PEAK_CONDUCTED
2266 static const locale_info_t locale_29 = {
2267 /* locale 29. channel 36 - 48, 52 - 64, 100 - 116, 132 - 140, 149 - 165 */
2268 LOCALE_CHAN_36_64 | LOCALE_SET_5G_MID1 | LOCALE_SET_5G_HIGH1 | LOCALE_CHAN_149_165,
2269 LOCALE_RADAR_SET_1,
2270 LOCALE_RESTRICTED_NONE,
2271 {QDB(14), QDB(16), QDB(16), QDB(16), QDB(16)},
2272 {23, 24, 24, 24, 30},
2273 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2276 static const locale_info_t locale_29a = {
2277 /* locale 29a. channel 36 - 48, 52 - 64, 100 - 116, 132 - 140, 149 - 165 */
2278 LOCALE_CHAN_36_64 | LOCALE_SET_5G_MID1 | LOCALE_SET_5G_HIGH1 | LOCALE_CHAN_149_165,
2279 LOCALE_RADAR_SET_1,
2280 LOCALE_RESTRICTED_NONE,
2281 {QDB(14), QDB(16), QDB(16), QDB(16), QDB(16)},
2282 {17, 24, 24, 24, 30},
2283 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2286 /* CLM v2.1 has separate power targets for 5G ch 104-116 and 100/132-140.
2287 * Express ch 104-116 limits here and fixup in wlc_channel_reg_limits().
2289 static const locale_info_t locale_29b = {
2290 /* locale 29b. channel 36 - 48, 52 - 64, 100 - 116, 132 - 140, 149 - 165 */
2291 LOCALE_CHAN_36_64 | LOCALE_SET_5G_MID1 | LOCALE_SET_5G_HIGH1 | LOCALE_CHAN_149_165,
2292 LOCALE_RADAR_SET_1,
2293 LOCALE_RESTRICTED_NONE,
2294 {QDB(14), QDB(15), QDB(15), /* 18.5 dBm */ 74, QDB(20)},
2295 {17, 24, 24, 24, 30},
2296 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2299 static const locale_info_t locale_29b_1 = {
2300 /* locale 29b. channel 36 - 48, 52 - 64, 100 - 116, 132 - 140, 149 - 165 */
2301 LOCALE_CHAN_36_64 | LOCALE_SET_5G_MID1 | LOCALE_SET_5G_HIGH1 | LOCALE_CHAN_149_165,
2302 LOCALE_RADAR_SET_1,
2303 LOCALE_RESTRICTED_NONE,
2304 {QDB(14), /* 20.5 dBm */ 82, 78, 82, QDB(23)},
2305 {17, 24, 24, 24, 30},
2306 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2309 /* CLM v4.8.2 has separate power targets for 5G ch 100 and 104-116, 132-136
2310 * and 140, express in whole range limits here and fixup in wlc_channel_reg_limits().
2312 static const locale_info_t locale_29b_3 = {
2313 /* locale 29b_3. channel 36 - 48, 52 - 64, 100 - 116, 132 - 140, 149 - 165 */
2314 LOCALE_CHAN_36_64 | LOCALE_SET_5G_MID1 | LOCALE_SET_5G_HIGH1 | LOCALE_CHAN_149_165,
2315 LOCALE_RADAR_SET_1,
2316 LOCALE_RESTRICTED_NONE,
2317 {QDB(15), /* 20.5 dBm */ 82, /* 19.5 */ 78, 82, /* 26.5 */ 106 },
2318 {17, 24, 24, 24, 30},
2319 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2322 static const locale_info_t locale_29c = {
2323 /* locale 29c. channel 36 - 48, 52 - 64, 100 - 116, 132 - 140, 149 - 165 */
2324 LOCALE_CHAN_36_64 | LOCALE_SET_5G_MID1 | LOCALE_SET_5G_HIGH1 | LOCALE_CHAN_149_165,
2325 LOCALE_RADAR_SET_1,
2326 LOCALE_RESTRICTED_NONE,
2327 {QDB(15), QDB(15), QDB(15), QDB(15), QDB(15)},
2328 {17, 24, 24, 24, 30},
2329 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2332 static const locale_info_t locale_29d = {
2333 /* locale 29d. channel 36 - 48, 52 - 64, 100 - 116, 132 - 140, 149 - 165 */
2334 LOCALE_CHAN_36_64 | LOCALE_SET_5G_MID1 | LOCALE_SET_5G_HIGH1 | LOCALE_CHAN_149_165,
2335 LOCALE_RADAR_SET_1,
2336 LOCALE_RESTRICTED_NONE,
2337 {QDB(14), /* 18.5 */ 74, 74, 74, /* 19.5 */ 78},
2338 {17, 24, 24, 24, 30},
2339 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2342 static const locale_info_t locale_29d_1 = {
2343 /* locale 29d_1. channel 36 - 48, 52 - 64, 100 - 116, 132 - 140, 149 - 165 */
2344 LOCALE_CHAN_36_64 | LOCALE_SET_5G_MID1 | LOCALE_SET_5G_HIGH1 | LOCALE_CHAN_149_165,
2345 LOCALE_RADAR_SET_1,
2346 LOCALE_RESTRICTED_NONE,
2347 { /* 15.5 dBm */ 62, /* 22.5 dBm */ 90, 90, 90, 90},
2348 {17, 24, 24, 24, 30},
2349 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2352 static const locale_info_t locale_29d_2 = {
2353 /* locale 29d_2. channel 36 - 48, 52 - 64, 100 - 116, 132 - 140, 149 - 165 */
2354 LOCALE_CHAN_36_64 | LOCALE_SET_5G_MID1 | LOCALE_SET_5G_HIGH1 | LOCALE_CHAN_149_165,
2355 LOCALE_RADAR_SET_1,
2356 LOCALE_RESTRICTED_NONE,
2357 {QDB(15), QDB(17), QDB(17), QDB(17), QDB(17)},
2358 {17, 24, 24, 24, 30},
2359 WLC_PEAK_CONDUCTED | WLC_DFS_FCC
2362 static const locale_info_t locale_31 = { /* locale 31. channel 36 - 48, 149 - 165 */
2363 LOCALE_SET_5G_LOW1 | LOCALE_CHAN_149_165,
2364 LOCALE_RADAR_SET_NONE,
2365 LOCALE_RESTRICTED_LOW_HI,
2366 {QDB(14), 0, 0, 0, QDB(15)},
2367 {17, 0, 0, 0, 20},
2368 WLC_PEAK_CONDUCTED
2371 #ifdef BCMDBG
2372 static const locale_info_t locale_5G_radar_only = { /* Channels 52 - 140 with US power */
2373 LOCALE_CHAN_52_140_ALL,
2374 LOCALE_RADAR_SET_1,
2375 LOCALE_RESTRICTED_NONE,
2376 {QDB(12), QDB(17), QDB(17), 0, QDB(17)},
2377 {20, 20, 20, 20, 20},
2378 WLC_PEAK_CONDUCTED | WLC_DFS_TPC
2380 #endif /* BCMDBG */
2382 /* All the channels we can do with a 2060ww */
2383 static const locale_info_t locale_5G_band_all = {
2384 LOCALE_SET_5G_LOW_JP1 | LOCALE_CHAN_52_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165 |
2385 LOCALE_CHAN_184_216,
2386 LOCALE_RADAR_SET_NONE,
2387 LOCALE_RESTRICTED_NONE,
2388 /* Don't throttle power due to regulatory */
2389 {QDB(30), QDB(30), QDB(30), QDB(30), QDB(30)},
2390 {30, 30, 30, 30, 30},
2391 WLC_PEAK_CONDUCTED
2393 #endif /* BAND5G */
2395 #ifdef WL11D
2397 #ifdef BAND2G
2398 /* 802.11d locale with all regulatory supported 2.4 GHz channels valid but marked as restricted
2399 * Channels: 1-14
2401 static const locale_info_t locale_11d_2G = {
2402 LOCALE_CHAN_01_14,
2403 LOCALE_RADAR_SET_NONE,
2404 LOCALE_RESTRICTED_11D_2G,
2405 {QDB(20), QDB(20), QDB(20),
2406 QDB(20), QDB(20), QDB(20)},
2407 {0, 0, 0, 0, 0}, /* public pwr limits unused for non-AP */
2408 WLC_PEAK_CONDUCTED
2410 #endif /* BAND2G */
2411 #ifdef BAND5G
2412 /* 802.11d locale with all regulatory supported 5 GHz channels valid but marked as restricted,
2413 * and the typical radar set, 52 - 64, 100 - 140
2414 * Channels:
2415 * 34, 38, 42, 46 (off-by-2 old Japan channels)
2416 * 36 - 48, 52 - 64, 100 - 140, 149 - 165
2418 static const locale_info_t locale_11d_5G = {
2419 LOCALE_SET_5G_LOW_JP1 | LOCALE_CHAN_52_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
2420 LOCALE_RADAR_SET_1,
2421 LOCALE_RESTRICTED_11D_5G,
2422 {QDB(17), QDB(20), QDB(20), QDB(30), QDB(20)},
2423 {0, 0, 0, 0, 0}, /* public pwr limits unused for non-AP */
2424 WLC_PEAK_CONDUCTED | WLC_DFS_TPC
2426 #endif /* BAND5G */
2428 #endif /* WL11D */
2431 #define LOCALE_2G_IDX_a 0
2432 #define LOCALE_2G_IDX_a1 1
2433 #define LOCALE_2G_IDX_a2 2
2434 #define LOCALE_2G_IDX_a3 3
2435 #define LOCALE_2G_IDX_b 4
2436 #define LOCALE_2G_IDX_b2 5
2437 #define LOCALE_2G_IDX_b3 6
2438 #define LOCALE_2G_IDX_c 7
2439 #define LOCALE_2G_IDX_f 8
2440 #define LOCALE_2G_IDX_g 9
2441 #define LOCALE_2G_IDX_h 10
2442 #define LOCALE_2G_IDX_i 11
2443 #define LOCALE_2G_IDX_j 12
2444 #define LOCALE_2G_IDX_k 13
2445 #define LOCALE_2G_IDX_c1 14
2446 #define LOCALE_2G_IDX_2G_band_all 15
2447 #define LOCALE_2G_IDX_a4 16
2448 #define LOCALE_2G_IDX_a5 17
2449 #define LOCALE_2G_IDX_b4 18
2450 #define LOCALE_2G_IDX_b5 19
2451 #define LOCALE_2G_IDX_a6 20
2452 #define LOCALE_2G_IDX_11d_2G 21
2453 #define LOCALE_2G_IDX_a7 22
2454 #define LOCALE_2G_IDX_a_2 23
2455 #define LOCALE_2G_IDX_a9 24
2456 #define LOCALE_2G_IDX_b2_1 25
2457 #define LOCALE_2G_IDX_b5_2 26
2458 #define LOCALE_2G_IDX_a3_1 27
2459 #define LOCALE_2G_IDX_b3_1 28
2460 #define LOCALE_2G_IDX_c_1 29
2461 #define LOCALE_2G_IDX_i_1 30
2462 #define LOCALE_2G_IDX_a_1 31
2463 #define LOCALE_2G_IDX_a6_1 32
2464 #define LOCALE_2G_IDX_a10 33
2465 #define LOCALE_2G_IDX_b2_2 34
2466 #define LOCALE_2G_IDX_b_1 35
2467 #define LOCALE_2G_IDX_b2_3 36
2468 #define LOCALE_2G_IDX_b2_4 37
2469 #define LOCALE_2G_IDX_a6_2 38
2470 #define LOCALE_2G_IDX_b5_3 39
2471 #define LOCALE_2G_IDX_b_2 40
2472 #define LOCALE_2G_IDX_a10_1 41
2473 #define LOCALE_2G_IDX_b2_5 42
2474 #define LOCALE_2G_IDX_a10_2 43
2475 #define LOCALE_2G_IDX_a10_3 44
2476 #define LOCALE_2G_IDX_b_3 45
2477 #define LOCALE_2G_IDX_b_4 46
2478 #define LOCALE_2G_IDX_a11 47
2479 #define LOCALE_2G_IDX_c_2 48
2480 #define LOCALE_2G_IDX_a5_1 49
2481 #define LOCALE_2G_IDX_b5_4 50
2482 #define LOCALE_2G_IDX_a_3 51
2483 #define LOCALE_2G_IDX_b_5 52
2484 #define LOCALE_2G_IDX_b_6 53
2485 #define LOCALE_2G_IDX_b_7 54
2486 #define LOCALE_2G_IDX_b_8 55
2487 #define LOCALE_2G_IDX_k_1 56
2488 #define LOCALE_2G_IDX_a12 57
2489 #define LOCALE_2G_IDX_a6_3 58
2490 #define LOCALE_2G_IDX_b_9 59
2491 #define LOCALE_2G_IDX_b2_6 60
2492 #define LOCALE_2G_IDX_k_3 61
2493 #define LOCALE_2G_IDX_b3_2 62
2494 #define LOCALE_2G_IDX_c_4 63
2495 #define LOCALE_2G_IDX_a14 64
2496 #define LOCALE_2G_IDX_b_11 65
2497 #define LOCALE_2G_IDX_a_5 66
2498 #define LOCALE_2G_IDX_a_6 67
2499 #define LOCALE_2G_IDX_a4_3 68
2500 #define LOCALE_2G_IDX_c_5 69
2501 #define LOCALE_2G_IDX_k_4 70
2502 #define LOCALE_2G_IDX_a4_2 71
2503 #define LOCALE_2G_IDX_a6_8 72
2504 #define LOCALE_2G_IDX_a4_4 73
2505 #define LOCALE_2G_IDX_a20 74
2508 static const locale_info_t * g_locale_2g_table[]=
2510 &locale_a,
2511 &locale_a1,
2512 &locale_a2,
2513 &locale_a3,
2514 &locale_b,
2515 &locale_b2,
2516 &locale_b3,
2517 &locale_c,
2518 &locale_f,
2519 &locale_g,
2520 &locale_h,
2521 &locale_i,
2522 &locale_j,
2523 &locale_k,
2524 &locale_c1,
2525 &locale_2G_band_all,
2526 &locale_a4,
2527 &locale_a5,
2528 &locale_b4,
2529 &locale_b5,
2530 &locale_a6,
2531 #if defined(BAND2G) && defined(WL11D)
2532 &locale_11d_2G,
2533 #else
2534 NULL,
2535 #endif /* WL11D && BAND2G */
2536 &locale_a7,
2537 &locale_a_2,
2538 &locale_a9,
2539 &locale_b2_1,
2540 &locale_b5_2,
2541 &locale_a3_1,
2542 &locale_b3_1,
2543 &locale_c_1,
2544 &locale_i_1,
2545 &locale_a_1,
2546 &locale_a6_1,
2547 &locale_a10,
2548 &locale_b2_2,
2549 &locale_b_1,
2550 &locale_b2_3,
2551 &locale_b2_4,
2552 &locale_a6_2,
2553 &locale_b5_3,
2554 &locale_b_2,
2555 &locale_a10_1,
2556 &locale_b2_5,
2557 &locale_a10_2,
2558 &locale_a10_3,
2559 &locale_b_3,
2560 &locale_b_4,
2561 &locale_a11,
2562 &locale_c_2,
2563 &locale_a5_1,
2564 &locale_b5_4,
2565 &locale_a_3,
2566 &locale_b_5,
2567 &locale_b_6,
2568 &locale_b_7,
2569 &locale_b_8,
2570 &locale_k_1,
2571 &locale_a12,
2572 &locale_a6_3,
2573 &locale_b_9,
2574 &locale_b2_6,
2575 &locale_k_3,
2576 &locale_b3_2,
2577 &locale_c_4,
2578 &locale_a14,
2579 &locale_b_11,
2580 &locale_a_5,
2581 &locale_a_6,
2582 &locale_a4_3,
2583 &locale_c_5,
2584 &locale_k_4,
2585 &locale_a4_2,
2586 &locale_a6_8,
2587 &locale_a4_4,
2588 &locale_a20
2592 #define LOCALE_5G_IDX_1 0
2593 #define LOCALE_5G_IDX_1a 1
2594 #define LOCALE_5G_IDX_1r 2
2595 #define LOCALE_5G_IDX_2 3
2596 #define LOCALE_5G_IDX_3 4
2597 #define LOCALE_5G_IDX_3a 4
2598 #define LOCALE_5G_IDX_3c 4
2599 #define LOCALE_5G_IDX_3r 5
2600 #define LOCALE_5G_IDX_4 6
2601 #define LOCALE_5G_IDX_5 7
2602 #define LOCALE_5G_IDX_5a 8
2603 #define LOCALE_5G_IDX_6 9
2604 #define LOCALE_5G_IDX_7 10
2605 #define LOCALE_5G_IDX_8 11
2606 #define LOCALE_5G_IDX_9 12
2607 #define LOCALE_5G_IDX_10 13
2608 #define LOCALE_5G_IDX_11 14
2609 #define LOCALE_5G_IDX_12 15
2610 #define LOCALE_5G_IDX_13 16
2611 #define LOCALE_5G_IDX_14 17
2612 #define LOCALE_5G_IDX_15 18
2613 #define LOCALE_5G_IDX_16 19
2614 #define LOCALE_5G_IDX_17 20
2615 #define LOCALE_5G_IDX_18 21
2616 #define LOCALE_5G_IDX_19 22
2617 #define LOCALE_5G_IDX_19a 23
2618 #define LOCALE_5G_IDX_19r 24
2619 #define LOCALE_5G_IDX_19b 25
2620 #define LOCALE_5G_IDX_20 26
2621 #define LOCALE_5G_IDX_21 27
2622 #define LOCALE_5G_IDX_22 28
2623 #define LOCALE_5G_IDX_23 29
2624 #define LOCALE_5G_IDX_24 30
2625 #define LOCALE_5G_IDX_25 31
2626 #define LOCALE_5G_IDX_27 32
2627 #define LOCALE_5G_IDX_28 33
2628 #define LOCALE_5G_IDX_29 34
2629 #define LOCALE_5G_IDX_29a 35
2630 #define LOCALE_5G_IDX_29c 36
2631 #define LOCALE_5G_IDX_29b_1 37
2632 #define LOCALE_5G_IDX_31 38
2633 #define LOCALE_5G_IDX_5G_band_all 39
2634 #define LOCALE_5G_IDX_11d_5G 40
2635 #define LOCALE_5G_IDX_7c 41
2636 #define LOCALE_5G_IDX_19h_2 42
2637 #define LOCALE_5G_IDX_27b 43
2638 #define LOCALE_5G_IDX_29b 44
2639 #define LOCALE_5G_IDX_5G_radar_only 45
2640 #define LOCALE_5G_IDX_25l 46
2641 #define LOCALE_5G_IDX_27c 47
2642 #define LOCALE_5G_IDX_19_1 48
2643 #define LOCALE_5G_IDX_19_2 49
2644 #define LOCALE_5G_IDX_19l_1 50
2645 #define LOCALE_5G_IDX_19l_2 51
2646 #define LOCALE_5G_IDX_3l 52
2647 #define LOCALE_5G_IDX_5l 53
2648 #define LOCALE_5G_IDX_8a 54
2649 #define LOCALE_5G_IDX_11_1 55
2650 #define LOCALE_5G_IDX_11_2 56
2651 #define LOCALE_5G_IDX_11l 57
2652 #define LOCALE_5G_IDX_3j 58
2653 #define LOCALE_5G_IDX_3j_1 59
2654 #define LOCALE_5G_IDX_19a_1 60
2655 #define LOCALE_5G_IDX_19_3 61
2656 #define LOCALE_5G_IDX_19h_1 62
2657 #define LOCALE_5G_IDX_29d 63
2658 #define LOCALE_5G_IDX_3b 64
2659 #define LOCALE_5G_IDX_1c 65
2660 #define LOCALE_5G_IDX_3j_4 66
2661 #define LOCALE_5G_IDX_3l_1 67
2662 #define LOCALE_5G_IDX_5l_1 68
2663 #define LOCALE_5G_IDX_6a 69
2664 #define LOCALE_5G_IDX_8b 70
2665 #define LOCALE_5G_IDX_11l_1 71
2666 #define LOCALE_5G_IDX_13_1 72
2667 #define LOCALE_5G_IDX_14a 73
2668 #define LOCALE_5G_IDX_16a 74
2669 #define LOCALE_5G_IDX_17a 75
2670 #define LOCALE_5G_IDX_18l 76
2671 #define LOCALE_5G_IDX_9h 77
2672 #define LOCALE_5G_IDX_11_3 78
2673 #define LOCALE_5G_IDX_11_4 79
2674 #define LOCALE_5G_IDX_3d 80
2675 #define LOCALE_5G_IDX_3j_3 81
2676 #define LOCALE_5G_IDX_19_4 82
2677 #define LOCALE_5G_IDX_3j_5 83
2678 #define LOCALE_5G_IDX_3r_4 84
2679 #define LOCALE_5G_IDX_5l_2 85
2680 #define LOCALE_5G_IDX_6a_1 86
2681 #define LOCALE_5G_IDX_7c_1 87
2682 #define LOCALE_5G_IDX_8a_1 88
2683 #define LOCALE_5G_IDX_13_2 89
2684 #define LOCALE_5G_IDX_25h 90
2685 #define LOCALE_5G_IDX_29d_2 91
2686 #define LOCALE_5G_IDX_3j_8 92
2687 #define LOCALE_5G_IDX_18_2 93
2688 #define LOCALE_5G_IDX_27e 94
2689 #define LOCALE_5G_IDX_3s 95
2690 #define LOCALE_5G_IDX_3r_5 96
2691 #define LOCALE_5G_IDX_13_3 97
2692 #define LOCALE_5G_IDX_29d_1 98
2693 #define LOCALE_5G_IDX_29b_3 99
2694 #define LOCALE_5G_IDX_3_1 100 /* CLM v4.6.6 */
2696 #ifdef BAND5G
2697 static const locale_info_t * g_locale_5g_table[]=
2699 &locale_1,
2700 &locale_1a,
2701 &locale_1r,
2702 &locale_2,
2703 &locale_3,
2704 &locale_3r,
2705 &locale_4,
2706 &locale_5,
2707 &locale_5a,
2708 &locale_6,
2709 &locale_7,
2710 &locale_8,
2711 &locale_9,
2712 &locale_10,
2713 &locale_11,
2714 &locale_12,
2715 &locale_13,
2716 &locale_14,
2717 &locale_15,
2718 &locale_16,
2719 &locale_17,
2720 &locale_18,
2721 &locale_19,
2722 &locale_19a,
2723 &locale_19r,
2724 &locale_19b,
2725 &locale_20,
2726 &locale_21,
2727 &locale_22,
2728 &locale_23,
2729 &locale_24,
2730 &locale_25,
2731 &locale_27,
2732 &locale_28,
2733 &locale_29,
2734 &locale_29a,
2735 &locale_29c,
2736 &locale_29b_1,
2737 &locale_31,
2738 &locale_5G_band_all,
2739 #ifdef WL11D
2740 &locale_11d_5G,
2741 #else
2742 NULL,
2743 #endif
2744 &locale_7c,
2745 &locale_19h_2,
2746 &locale_27b,
2747 &locale_29b,
2748 #ifdef BCMDBG
2749 &locale_5G_radar_only,
2750 #else
2751 NULL,
2752 #endif
2753 &locale_25l,
2754 &locale_27c,
2755 &locale_19_1,
2756 &locale_19_2,
2757 &locale_19l_1,
2758 &locale_19l_2,
2759 &locale_3l,
2760 &locale_5l,
2761 &locale_8a,
2762 &locale_11_1,
2763 &locale_11_2,
2764 &locale_11l,
2765 &locale_3j,
2766 &locale_3j_1,
2767 &locale_19a_1,
2768 &locale_19_3,
2769 &locale_19h_1,
2770 &locale_29d,
2771 &locale_3b,
2772 &locale_1c,
2773 &locale_3j_4,
2774 &locale_3l_1,
2775 &locale_5l_1,
2776 &locale_6a,
2777 &locale_8b,
2778 &locale_11l_1,
2779 &locale_13_1,
2780 &locale_14a,
2781 &locale_16a,
2782 &locale_17a,
2783 &locale_18l,
2784 &locale_9h,
2785 &locale_11_3,
2786 &locale_11_4,
2787 &locale_3d,
2788 &locale_3j_3,
2789 &locale_19_4,
2790 &locale_3j_5,
2791 &locale_3r_4,
2792 &locale_5l_2,
2793 &locale_6a_1,
2794 &locale_7c_1,
2795 &locale_8a_1,
2796 &locale_13_2,
2797 &locale_25h,
2798 &locale_29d_2,
2799 &locale_3j_8,
2800 &locale_18_2,
2801 &locale_27e,
2802 &locale_3s,
2803 &locale_3r_5,
2804 &locale_13_3,
2805 &locale_29d_1,
2806 &locale_29b_3,
2807 &locale_3_1 /* CLM v4.6.6 */
2810 #endif /* #ifdef BAND5G */
2813 /* unrestricted power locale for internal country "ALL" */
2814 static const locale_mimo_info_t locale_mimo_all = {
2815 {QDB(30), QDB(30), QDB(30), QDB(30), QDB(30),
2816 QDB(30), QDB(30), QDB(30), QDB(30), QDB(30),
2817 QDB(30), QDB(30), QDB(30), QDB(30)},
2818 {QDB(30), QDB(30), QDB(30), QDB(30), QDB(30),
2819 QDB(30), QDB(30), QDB(30), QDB(30), QDB(30),
2820 QDB(30), QDB(30), QDB(30), QDB(30)},
2825 * MIMO Locale Definitions - 2.4 GHz
2828 #ifdef WL11N
2829 static const locale_mimo_info_t locale_an1 = {
2830 {QDB(14), QDB(16), QDB(16), QDB(16), QDB(16),
2831 QDB(16), QDB(16), QDB(16), QDB(16), QDB(16),
2832 QDB(14), 0, 0},
2833 {0, 0, QDB(13), QDB(14), QDB(14),
2834 QDB(14), QDB(14), QDB(12), QDB(12), 0,
2835 0, 0, 0},
2839 /* CLM v3.4 has only SISO power targets. */
2840 static const locale_mimo_info_t locale_an_2 = {
2841 {QDB(18), QDB(18), QDB(18), QDB(18), QDB(18),
2842 QDB(18), QDB(18), QDB(18), QDB(18), QDB(18), QDB(18), 0, 0},
2843 {0, 0, QDB(15), QDB(16), QDB(16),
2844 QDB(16), QDB(16), QDB(16), QDB(16), 0, 0, 0, 0},
2848 /* CLM v1.11.5 has separate SISO/CDD power targets and per-MCS limits.
2849 * Express SISO limits here and fixup in wlc_channel_reg_limits().
2851 static const locale_mimo_info_t locale_an1_t1 = {
2852 {QDB(19), QDB(19), QDB(19), QDB(19), QDB(19),
2853 QDB(19), QDB(19), QDB(19), QDB(19), QDB(19), /* 16.5 dBm */ 66, 0, 0},
2854 {0, 0, /* 15.5 dBm */ 62, /* 16.5 dBm */ 66, 66,
2855 66, 66, /* 15.5 dBm */ 62, /* 14.5 dBm */ 58, 0, 0, 0, 0},
2859 /* CLM v1.11.5 has separate SISO/CDD power targets and per-MCS limits.
2860 * Express SISO limits here and fixup in wlc_channel_reg_limits().
2862 static const locale_mimo_info_t locale_an1_t2 = {
2863 {QDB(19), QDB(19), QDB(19), QDB(19), QDB(19),
2864 QDB(19), QDB(19), QDB(19), QDB(19), QDB(19), /* 16.5 dBm */ 66, 0, 0},
2865 {0, 0, /* 15.5 dBm */ 62, /* 16.5 dBm */ 66, 66,
2866 66, 66, /* 15.5 dBm */ 62, /* 14.5 dBm */ 58, 0, 0, 0, 0},
2870 /* CLM v3.4 has only SISO power targets. */
2871 static const locale_mimo_info_t locale_an1_t3 = {
2872 {QDB(17), QDB(19), QDB(19), QDB(19), QDB(19),
2873 QDB(19), QDB(19), QDB(19), QDB(19), QDB(19), QDB(16), 0, 0},
2874 {0, 0, QDB(15), QDB(17), QDB(17),
2875 QDB(17), QDB(17), QDB(17), QDB(14), 0, 0, 0, 0},
2879 /* CLM v3.0 has 40MHz per-MCS limits.
2880 * Express most limits here and fixup in wlc_channel_reg_limits().
2882 static const locale_mimo_info_t locale_an1_t4 = {
2883 {QDB(12), QDB(14), QDB(14), QDB(14), QDB(14),
2884 QDB(14), QDB(14), QDB(14), QDB(14), QDB(14), QDB(12), 0, 0},
2885 {0, 0, QDB(10), QDB(12), QDB(12),
2886 QDB(12), QDB(12), QDB(12), QDB(10), 0, 0, 0, 0},
2890 /* CLM v3.1 has separate SISO/CDD power targets and per-MCS limits.
2891 * Express SISO limits here and fixup in wlc_channel_reg_limits().
2893 static const locale_mimo_info_t locale_an1_t5 = {
2894 {QDB(14), QDB(16), QDB(17), QDB(17), QDB(17),
2895 QDB(17), QDB(17), QDB(17), QDB(17), QDB(15), QDB(12), 0, 0},
2896 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2897 WLC_NO_40MHZ
2900 static const locale_mimo_info_t locale_bn1_1 = {
2901 {QDB(11), QDB(11), QDB(11), QDB(11), QDB(11),
2902 QDB(11), QDB(11), QDB(11), QDB(11), QDB(11), QDB(11), QDB(11), QDB(11)},
2903 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2904 WLC_NO_40MHZ
2907 /* CLM v3.2 has Only SISO power targets and per-MCS limits. */
2908 static const locale_mimo_info_t locale_an6_1 = {
2909 {QDB(14), QDB(20), QDB(21), QDB(21), QDB(21),
2910 QDB(21), QDB(21), QDB(21), QDB(21), QDB(20), QDB(14), 0, 0},
2911 {0, 0, QDB(14), QDB(20), QDB(21),
2912 QDB(21), QDB(21), QDB(20), /* 14.5 dbm */ 58, 0, 0, 0, 0},
2916 /* CLM v4.3.4 has only CDD power target. */
2917 static const locale_mimo_info_t locale_an6_5 = {
2918 {QDB(16), QDB(19), QDB(22), QDB(22), QDB(22),
2919 QDB(22), QDB(22), QDB(22), QDB(22), QDB(19), QDB(16), 0, 0},
2920 {0, 0, /* 13.5 dbm */ 54, QDB(16), QDB(18),
2921 QDB(18), QDB(18), QDB(16), 54, 0, 0, 0, 0},
2925 /* CLM v4.3.4 has separate SISO/CDD power targets .
2926 * Express CDD limits here and fixup SISO in wlc_channel_reg_limits().
2928 static const locale_mimo_info_t locale_an6_6 = {
2929 {QDB(15), QDB(17), QDB(17), QDB(17), QDB(17),
2930 QDB(17), QDB(17), QDB(17), QDB(17), QDB(17), QDB(14), 0, 0},
2931 {0, 0, QDB(12), QDB(17), QDB(17),
2932 QDB(17), QDB(17), QDB(17), QDB(12), 0, 0, 0, 0},
2936 /* CLM v4.8.2 has separate SISO/CDD power targets .
2937 * Express CDD limits here and fixup SISO in wlc_channel_reg_limits().
2939 static const locale_mimo_info_t locale_an6_7 = {
2940 { /* 17.5 */ 70, /* 20.5 */ 82, QDB(23), QDB(23), QDB(23),
2941 QDB(23), QDB(23), QDB(23), QDB(23), /* 20.5 */ 82, /* 17.5 */ 70, 0, 0},
2942 {0, 0, /* 16.5 */ 66, /* 19.5 */ 78, /* 21.5 */ 86,
2943 86, 86, /* 19.5 */ 78, /* 16.5 */ 66, 0, 0, 0, 0},
2947 /* CLM v3.3 has Only SISO power targets and per-MCS limits. */
2948 static const locale_mimo_info_t locale_bn2_4 = {
2949 {QDB(16), QDB(16), QDB(16), QDB(16), QDB(16),
2950 QDB(16), QDB(16), QDB(16), QDB(16), QDB(16), QDB(16), QDB(16), /* 11.5 dbm */ 46},
2951 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
2952 WLC_NO_40MHZ
2955 /* CLM v3.4 has Only SISO power targets and per-MCS limits. */
2956 static const locale_mimo_info_t locale_bn2_5 = {
2957 { /* 13.5 dbm */ 54, 54, 54, 54, 54,
2958 54, 54, 54, 54, 54, 54, 54, 54},
2959 {0, 0, QDB(14), QDB(14), QDB(14), QDB(14), QDB(14), QDB(14), QDB(14),
2960 QDB(14), QDB(14), 0, 0},
2964 static const locale_mimo_info_t locale_an2 = {
2965 #if 1 /* ASUS modify */
2966 {QDB(15.5), /* 16.5 dBm = 66 qdBm */ 72, 72, 72, 72,
2967 72, 72, 72, 72, 72,
2968 /* 14.5 dBm */ 62, 0, 0},
2969 {0, 0, QDB(13.5), /* 14.5 dBm */ 70, 70,
2970 70, 70, /* 12.5 dBm */ 70, 54, 0,
2971 #else
2972 {QDB(15), /* 16.5 dBm = 66 qdBm */ 66, 66, 66, 66,
2973 66, 66, 66, 66, 66,
2974 /* 14.5 dBm */ 58, 0, 0},
2975 {0, 0, QDB(14), /* 14.5 dBm */ 58, 58,
2976 58, 58, /* 12.5 dBm */ 50, 50, 0,
2977 #endif
2978 0, 0, 0},
2982 static const locale_mimo_info_t locale_an2_1 = {
2983 {QDB(12), QDB(15), QDB(15), QDB(15), QDB(15),
2984 QDB(15), QDB(15), QDB(15), QDB(15), QDB(15),
2985 /* 11.5 */ 46, 0, 0},
2986 {0, 0, /* 10.5 */ 42, /* 12.5 */ 50, QDB(15),
2987 QDB(15), QDB(15), /* 13.5 */ 54, 46, 46,
2988 0, 0, 0},
2992 static const locale_mimo_info_t locale_an2_2 = {
2993 { /* 13.5 */ 54, QDB(14), QDB(14), QDB(14), QDB(14),
2994 QDB(14), QDB(14), QDB(14), QDB(14), QDB(14),
2995 QDB(14), 0, 0},
2996 {0, 0, QDB(10), QDB(10), QDB(10),
2997 QDB(10), QDB(10), QDB(10), /* 9.5 */ 38, 0,
2998 0, 0, 0},
3002 static const locale_mimo_info_t locale_an2_3 = {
3003 {QDB(15), /* 15.5 */ 62, 62, 62, 62,
3004 62, 62, 62, 62, 62,
3005 62, 0, 0},
3006 {0, 0, /* 11.5 */ 46, 46, 46,
3007 46, 46, 46, QDB(11), 0,
3008 0, 0, 0},
3012 static const locale_mimo_info_t locale_an2_4 = {
3013 {QDB(13), /* 15.5 */ 62, 62, 62, 62,
3014 62, 62, 62, 62, 62,
3015 QDB(13), 0, 0},
3016 {0, 0, QDB(12), QDB(14), QDB(14),
3017 QDB(14), QDB(14), QDB(14), QDB(12), 0,
3018 0, 0, 0},
3022 static const locale_mimo_info_t locale_an2_5 = {
3023 {QDB(11), /* 16.5 */ 66, 66, 66, 66,
3024 66, 66, 66, 66, 66,
3025 QDB(14), 0, 0},
3026 {0, 0, /* 9.5 */ 38, /* 15.5 */ 62, 62,
3027 62, 62, 62, /* 12.5 */ 50, 0,
3028 0, 0, 0},
3032 static const locale_mimo_info_t locale_an3 = {
3033 { /* 15.5 dBm */ 62, QDB(17), QDB(17), QDB(17), QDB(17),
3034 QDB(17), QDB(17), QDB(17), QDB(17), QDB(17),
3035 QDB(15), 0, 0},
3036 {0, 0, /* 14.5 dBm */ 58, 58, 58,
3037 58, 58, QDB(13), QDB(13), 0,
3038 0, 0, 0},
3042 static const locale_mimo_info_t locale_an4 = {
3043 { /* 16.5 dBm */ 66, /* 18.5 dBm */ 74, 74, 74, 74,
3044 74, 74, 74, 74, 74,
3045 QDB(16), 0, 0},
3046 {0, 0, QDB(15), /* 15.5 dBm */ 62, 62,
3047 62, 62, QDB(15), QDB(15), 0,
3048 0, 0, 0},
3052 static const locale_mimo_info_t locale_an5 = {
3053 { /* 16.5 dBm */ 66, QDB(20), QDB(22), QDB(22), QDB(22),
3054 QDB(22), QDB(22), QDB(22), QDB(22), QDB(18),
3055 /* 14.5 dBm */ 58, 0, 0},
3056 {0, 0, QDB(14), QDB(17), QDB(18),
3057 QDB(18), QDB(18), QDB(16), QDB(13), 0,
3058 0, 0, 0},
3062 /* CLM v2.1.1 has separate per-MCS limits at 40Mhz. Fixup in wlc_channel_reg_limits(). */
3063 static const locale_mimo_info_t locale_an6 = {
3064 { /* 16.5 dBm */ 66, /* 18.5 dBm */ 74, QDB(20), QDB(20), QDB(20),
3065 QDB(20), QDB(20), QDB(20), QDB(20), /* 18.5 dBm */ 74,
3066 /* 16.5 dBm */ 66, 0, 0},
3067 {0, 0, /* 17.5 dBm */ 70, /* 18.5 dBm */ 74, QDB(20),
3068 QDB(20), QDB(20), /* 18.5 dBm */ 74, /* 16.5 dBm */ 66, 0,
3069 0, 0, 0},
3073 /* CLM v2.3 has separate per-MCS limits at 40Mhz. Fixup in wlc_channel_reg_limits(). */
3074 static const locale_mimo_info_t locale_an6_2 = {
3075 { QDB(13), /* 15.5 dBm */ 62, QDB(16), QDB(17), QDB(17),
3076 QDB(17), QDB(17), QDB(17), QDB(17), /* 14.5 dBm */ 58,
3077 /* 12.5 dBm */ 50, 0, 0},
3078 {0, 0, QDB(12), /* 12.5 dBm */ 50, /* 13.5 dBm */ 54,
3079 54, 54, QDB(13), /* 12.5 dBm */ 50, 0,
3080 0, 0, 0},
3084 /* CLM v4.5.6 has only CDD/SDM limts for 20MHz and 40MHz. */
3085 static const locale_mimo_info_t locale_an6_3 = {
3086 { QDB(11), /* 15.5 dBm */ 62, QDB(16), QDB(17), QDB(17),
3087 QDB(17), QDB(17), QDB(17), QDB(17), /* 14.5 dBm */ 58,
3088 /* 13.5 dBm */ 54, 0, 0},
3089 {0, 0, QDB(10), /* 12.5 dBm */ 50, QDB(15),
3090 QDB(15), QDB(15), 58, /* 12.5 dBm */ 50, 0,
3091 0, 0, 0},
3095 static const locale_mimo_info_t locale_an6_4 = {
3096 { /* 16.5 dBm */ 66, QDB(18), QDB(21), QDB(21), QDB(21),
3097 QDB(21), QDB(21), QDB(21), QDB(21), /* 16.5 dBm */ 66,
3098 /* 14.5 dBm */ 58, 0, 0},
3099 {0, 0, QDB(14), QDB(15), QDB(17),
3100 QDB(17), QDB(17), QDB(15), QDB(13), 0,
3101 0, 0, 0},
3105 static const locale_mimo_info_t locale_an7 = {
3106 { QDB(16), QDB(20), QDB(21), QDB(21), QDB(21),
3107 QDB(21), QDB(21), QDB(21), QDB(21), QDB(20),
3108 QDB(16), 0, 0},
3109 {0, 0, QDB(14), QDB(17), QDB(19),
3110 QDB(19), QDB(19), QDB(17), QDB(13), 0,
3111 0, 0, 0},
3115 static const locale_mimo_info_t locale_an7_2 = {
3116 { QDB(13), QDB(19), QDB(20), QDB(20), QDB(20),
3117 QDB(20), QDB(20), QDB(20), QDB(20), QDB(19),
3118 QDB(13), 0, 0},
3119 {0, 0, QDB(13), QDB(15), QDB(16),
3120 QDB(16), QDB(16), QDB(15), QDB(13), 0,
3121 0, 0, 0},
3125 static const locale_mimo_info_t locale_an7_3 = {
3126 { /* 15.5 */ 62, /* 17.5 */ 70, /* 18.5 */ 74, /* 21.5 */ 86, 86,
3127 86, 86, 86, 86, 74,
3128 62, 0, 0},
3129 {0, 0, /* 14.5 */ 58, 58, 58,
3130 70, 58, 58, 58, 0,
3131 0, 0, 0},
3135 static const locale_mimo_info_t locale_an7_8 = {
3136 { QDB(15), /* 21.5 dBm */ 86, 86, 86, 86,
3137 86, 86, 86, 86, 86,
3138 QDB(18), 0, 0},
3139 {0, 0, QDB(14), QDB(18), QDB(18),
3140 QDB(18), QDB(18), QDB(18), /* 16.5dBm */ 66, 0, 0, 0, 0},
3144 static const locale_mimo_info_t locale_an8_t1 = {
3145 {QDB(14), QDB(16), QDB(19), QDB(19), QDB(19),
3146 QDB(19), QDB(19), QDB(19), QDB(19), QDB(14),
3147 QDB(11), 0, 0},
3148 {0, 0, QDB(13), QDB(14), QDB(14),
3149 QDB(14), QDB(14), QDB(14), /* 10.5 dBm */ 42, 0,
3150 0, 0, 0},
3154 /* CLM v2.7 has separate per-MCS limits at 40Mhz. Fixup in wlc_channel_reg_limits(). */
3155 static const locale_mimo_info_t locale_an8_t2 = {
3156 {QDB(14), QDB(16), QDB(19), QDB(19), QDB(19),
3157 QDB(19), QDB(19), QDB(19), QDB(19), /* 14.5 dBm */ 58,
3158 /* 12.5 dBm */ 50, 0, 0},
3159 {0, 0, QDB(13), QDB(14), QDB(14),
3160 QDB(14), QDB(14), QDB(14), QDB(14), 0,
3161 0, 0, 0},
3165 static const locale_mimo_info_t locale_an9_t1 = {
3166 {QDB(14), QDB(16), QDB(19), QDB(19), QDB(19),
3167 QDB(19), QDB(19), QDB(19), QDB(19), QDB(14),
3168 QDB(14), /* 13.5 dBm */ 54, QDB(12)},
3169 {0, 0, /* 13.5 dBm */ 54, /* 14.5 dBm */ 58, 58,
3170 58, 58, 58, QDB(12), QDB(13),
3171 QDB(7), 0, 0},
3175 static const locale_mimo_info_t locale_an10 = {
3176 {QDB(10), QDB(11), QDB(13), QDB(14), QDB(15),
3177 QDB(16), QDB(16), QDB(15), QDB(14), QDB(11),
3178 QDB(10), 0, 0},
3179 {0, 0, QDB(14), QDB(16), QDB(16),
3180 QDB(16), QDB(16), QDB(15), QDB(14), 0,
3181 0, 0, 0},
3185 static const locale_mimo_info_t locale_an2_21 = {
3186 {QDB(13), QDB(18), QDB(18), QDB(18), QDB(18),
3187 QDB(18), QDB(18), QDB(18), QDB(18), QDB(18),
3188 QDB(11), 0, 0},
3189 {0, 0, QDB(11), QDB(14), QDB(14),
3190 QDB(14), QDB(14), QDB(14), QDB(12), 0,
3191 0, 0, 0},
3195 static const locale_mimo_info_t locale_a_3n = {
3196 {QDB(11), QDB(15), /* 16.5 dBm */ 66, 66, 66,
3197 66, 66, 66, 66, QDB(15),
3198 /* 10.5 dBm */ 42, 0, 0},
3199 {0, 0, 0, 0, 0,
3200 0, 0, 0, 0, 0,
3201 0, 0, 0},
3205 static const locale_mimo_info_t locale_a1_3n = {
3206 {QDB(17), QDB(20), /* 22.5 dBm */ 90, 90, 90,
3207 90, 90, 90, 90, QDB(20),
3208 QDB(17), 0, 0},
3209 {0, 0, QDB(16), QDB(19), /* 22.5 dBm */ 90,
3210 90, 90, QDB(19), QDB(16), 0,
3211 0, 0, 0},
3215 static const locale_mimo_info_t locale_b2_3n = {
3216 {57 /* 14.25 dBm */, 57, 57, 57, 57,
3217 57, 57, 57, 57, 57,
3218 57, 57, 57},
3219 {0, 0, 57, 57, 57,
3220 57, 57, 57, 57, 57,
3221 57, 0, 0},
3225 /* CLM v3.7.2 has separate power targets for SISO/CDD.
3226 * Dfine CDD/SDM here, and fixup SISO in wlc_channel_reg_limits().
3228 static const locale_mimo_info_t locale_bn = {
3229 {QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3230 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3231 QDB(13), QDB(13), QDB(13)},
3232 {0, 0, QDB(13), QDB(13), QDB(13),
3233 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3234 QDB(13), 0, 0},
3238 static const locale_mimo_info_t locale_bn_1 = {
3239 {QDB(15), QDB(15), QDB(15), QDB(15), QDB(15),
3240 QDB(15), QDB(15), QDB(15), QDB(15), QDB(15),
3241 QDB(15), QDB(15), QDB(15)},
3242 {0, 0, QDB(15), QDB(15), QDB(15),
3243 QDB(15), QDB(15), QDB(15), QDB(15), QDB(15),
3244 QDB(15), 0, 0},
3248 static const locale_mimo_info_t locale_bn_2 = {
3249 {QDB(16), QDB(16), QDB(16), QDB(16), QDB(16),
3250 QDB(16), QDB(16), QDB(16), QDB(16), QDB(16),
3251 QDB(16), QDB(16), QDB(16)},
3252 {0, 0, QDB(16), QDB(16), QDB(16),
3253 QDB(16), QDB(16), QDB(16), QDB(16), QDB(16),
3254 QDB(16), 0, 0},
3258 static const locale_mimo_info_t locale_bn_3 = {
3259 {QDB(15), QDB(15), QDB(15), QDB(15), QDB(15),
3260 QDB(15), QDB(15), QDB(15), QDB(15), QDB(15),
3261 QDB(15), QDB(15), QDB(15)},
3262 {0, 0, QDB(15), QDB(15), QDB(15),
3263 QDB(15), QDB(15), QDB(15), QDB(15), QDB(15),
3264 QDB(15), 0, 0},
3268 static const locale_mimo_info_t locale_bn_4 = {
3269 {QDB(14), QDB(14), QDB(14), QDB(14), QDB(14),
3270 QDB(14), QDB(14), QDB(14), QDB(14), QDB(14),
3271 QDB(14), QDB(14), QDB(14)},
3272 {0, 0, QDB(14), QDB(14), QDB(14),
3273 QDB(14), QDB(14), QDB(14), QDB(14), QDB(14),
3274 QDB(14), 0, 0},
3278 static const locale_mimo_info_t locale_bn_5 = {
3279 {QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3280 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3281 QDB(13), QDB(13), QDB(13)},
3282 {0, 0, QDB(13), QDB(13), QDB(13),
3283 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3284 QDB(13), 0, 0},
3288 static const locale_mimo_info_t locale_bn_10 = {
3289 { /* 11.5 dBm */ 46, 46, 46, 46, 46,
3290 46, 46, 46, 46, 46,
3291 46, 46, 46},
3292 {0, 0, /* 13.5 */ 54, 54, 54,
3293 54, 54, 54, 54, 54,
3294 54, 0, 0},
3298 static const locale_mimo_info_t locale_bn_10_3n = {
3299 { /* 9.75 dBm */ 39, 39, 39, 39, 39,
3300 39, 39, 39, 39, 39,
3301 39, 39, 39},
3302 {0, 0, /* 11.75 dBm */ 47, 47, 47,
3303 47, 47, 47, 47, 47,
3304 47, 0, 0},
3308 static const locale_mimo_info_t locale_bn_9 = {
3309 { /* 13.5 dBm */ 54, 54, 54, 54, 54, 54,
3310 /* 13.5 dBm */ 54, 54, 54, 54, 54, 54, 54},
3311 {0, 0, /* 13.5 dBm */ 54, 54, 54,
3312 /* 13.5 dBm */ 54, 54, 54, 54, 54, 54,
3313 0, 0},
3318 static const locale_mimo_info_t locale_bn1 = {
3319 {QDB(10), QDB(13), QDB(13), QDB(13), QDB(13),
3320 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3321 QDB(13), QDB(13), QDB(13)},
3322 {0, 0, QDB(10), QDB(13), QDB(13),
3323 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3324 QDB(13), 0, 0},
3328 static const locale_mimo_info_t locale_bn2 = {
3329 { /* 8.5 dBm */ 34, QDB(13), QDB(13), QDB(13), QDB(13),
3330 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3331 QDB(13), QDB(13), /* 8.5 dBm */ 34},
3332 {0, 0, /* 8.5 dBm */ 34, QDB(13), QDB(13),
3333 QDB(13), QDB(13), QDB(13), /* 8.5 dBm */ 34, 34,
3334 34, 0, 0},
3338 static const locale_mimo_info_t locale_bn2_1 = {
3339 { QDB(9), QDB(13), QDB(13), QDB(13), QDB(13),
3340 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3341 QDB(13), QDB(13), QDB(9)},
3342 {0, 0, QDB(10), QDB(13), QDB(13),
3343 QDB(13), QDB(13), QDB(13), /* 11.5 dBm */46, 46,
3344 46, 0, 0},
3348 static const locale_mimo_info_t locale_bn2_2 = {
3349 { QDB(12), QDB(12), QDB(12), QDB(12), QDB(12),
3350 QDB(12), QDB(12), QDB(12), QDB(12), QDB(12),
3351 QDB(12), QDB(12), QDB(12)},
3352 {0, 0, QDB(12), QDB(12), QDB(12),
3353 QDB(12), QDB(12), QDB(12), QDB(12), QDB(12), QDB(12), 0, 0},
3357 /* CLM v3.3 has separate SISO/CDD power targets and per-MCS limits.
3358 * Express CDD limits here and fixup SISO in wlc_channel_reg_limits().
3360 static const locale_mimo_info_t locale_bn2_3 = {
3361 { QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3362 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3363 QDB(13), QDB(8), QDB(8)},
3364 {0, 0, QDB(13), QDB(13), QDB(13),
3365 QDB(13), QDB(13), QDB(13), /* 12.5 dBm */ 50, 0,
3366 0, 0, 0},
3370 /* CLM v3.8.2 has only CDD power targets. */
3371 static const locale_mimo_info_t locale_bn2_6 = {
3372 { /* 12.5 */ 50, QDB(15), QDB(15), QDB(15), QDB(15),
3373 QDB(15), QDB(15), QDB(15), QDB(15), QDB(15), QDB(15), QDB(15), 50},
3374 {0, 0, 50, QDB(15), QDB(15), QDB(15),
3375 QDB(15), QDB(15), QDB(15), QDB(15), QDB(13), 0, 0},
3379 /* CLM v4.1.3 has separate SISO/CDD power targets and per-MCS limits.
3380 * Express CDD limits here and fixup SISO in wlc_channel_reg_limits().
3382 static const locale_mimo_info_t locale_bn2_8 = {
3383 { QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3384 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3385 QDB(13), QDB(11), QDB(11)},
3386 {0, 0, QDB(13), QDB(13), QDB(13),
3387 QDB(13), QDB(13), QDB(13), /* 12.5 dBm */ 50, 0,
3388 0, 0, 0},
3393 static const locale_mimo_info_t locale_bn4 = {
3394 {QDB(13), QDB(13), QDB(14), QDB(14), QDB(14),
3395 QDB(14), QDB(14), QDB(14), QDB(14), QDB(14),
3396 QDB(14), QDB(13), QDB(13)},
3397 {0, 0, QDB(13), QDB(14), QDB(14),
3398 QDB(14), QDB(14), QDB(14), QDB(14), QDB(14),
3399 QDB(13), 0, 0},
3403 static const locale_mimo_info_t locale_bn7 = {
3404 {QDB(16), QDB(16), QDB(16), QDB(16), QDB(16),
3405 QDB(16), QDB(16), QDB(16), QDB(16), QDB(16),
3406 QDB(16), QDB(16), QDB(16)},
3407 {0, 0, QDB(16), QDB(16), QDB(16),
3408 QDB(16), QDB(16), QDB(16), QDB(16), QDB(16),
3409 QDB(16), 0, 0},
3410 WLC_EIRP
3413 static const locale_mimo_info_t locale_bn5_1 = {
3414 { /* 12.5 dBm */ 50, QDB(15), QDB(15), QDB(15), QDB(15),
3415 QDB(15), QDB(15), QDB(15), QDB(15), QDB(15),
3416 /* 12.5 dBm */ 50, QDB(15), QDB(15)},
3417 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
3418 WLC_NO_40MHZ
3421 /* CLM v3.7.2 has separate SISO/CDD power targets and per-MCS limits.
3422 * Express CDD limits here and fixup in wlc_channel_reg_limits().
3424 static const locale_mimo_info_t locale_cn = {
3425 {QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3426 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3427 QDB(13), QDB(13), QDB(13), QDB(13)},
3428 {0, 0, QDB(13), QDB(13), QDB(13),
3429 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3430 QDB(13), 0, 0},
3434 static const locale_mimo_info_t locale_cn_1 = {
3435 {QDB(11), QDB(11), QDB(11), QDB(11), QDB(11),
3436 QDB(11), QDB(11), QDB(11), QDB(11), QDB(11),
3437 QDB(11), QDB(11), QDB(11), QDB(11)},
3438 {0, 0, QDB(11), QDB(11), QDB(11),
3439 QDB(11), QDB(11), QDB(11), QDB(11), QDB(11),
3440 QDB(11), 0, 0},
3444 static const locale_mimo_info_t locale_cn_2 = {
3445 { /* 13.5 */ 54, 54, 54, 54,
3446 54, 54, 54, 54, 54,
3447 54, 54, 54, 54},
3448 {0, 0, /* 10.5 */ 42, 42, 42,
3449 42, 42, 42, 42, 42,
3450 42, 0, 0},
3454 /* CLM v4.3.4 has separate SISO/CDD power targets.
3455 * Express CDD limits here and fixup SISO in wlc_channel_reg_limits().
3457 static const locale_mimo_info_t locale_cn_3 = {
3458 { /* 15.5 */ 62, 62, 62, 62, 62,
3459 62, 62, 62, 62, 62,
3460 62, 62, 62, 62},
3461 {0, 0, /* 14.5 */ 58, 58, 58,
3462 58, 58, 58, 58, 58,
3463 58, 0, 0},
3467 static const locale_mimo_info_t locale_en = {
3468 {QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3469 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3470 QDB(13), QDB(13), QDB(13)},
3471 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
3472 WLC_NO_40MHZ
3475 static const locale_mimo_info_t locale_en2 = {
3476 {QDB(8), QDB(13), QDB(13), QDB(13), QDB(13),
3477 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3478 QDB(13), QDB(13), QDB(8)},
3479 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
3480 WLC_NO_40MHZ
3483 static const locale_mimo_info_t locale_en2_1 = {
3484 {QDB(12), QDB(12), QDB(12), QDB(12), QDB(12),
3485 QDB(12), QDB(12), QDB(12), QDB(12), QDB(12),
3486 QDB(12), QDB(12), QDB(12)},
3487 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
3488 WLC_NO_40MHZ
3491 static const locale_mimo_info_t locale_fn = {
3492 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
3493 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
3494 WLC_NO_MIMO
3497 static const locale_mimo_info_t locale_dn = {
3498 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
3499 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
3500 WLC_NO_MIMO
3503 static const locale_mimo_info_t locale_gn = {
3504 {QDB(16), QDB(16), QDB(16), QDB(16), QDB(16),
3505 QDB(16), QDB(16), QDB(16), QDB(16), QDB(16),
3506 QDB(16), QDB(16), QDB(16)},
3507 {QDB(16), QDB(16), QDB(16), QDB(16), QDB(16),
3508 QDB(16), QDB(16), QDB(16), QDB(16), QDB(16),
3509 QDB(16), QDB(16), QDB(16)},
3513 static const locale_mimo_info_t locale_hn = {
3514 {QDB(17), QDB(17), QDB(17), QDB(17), QDB(17),
3515 QDB(17), QDB(17), QDB(17), QDB(17), QDB(17),
3516 QDB(17), QDB(17), QDB(17)},
3517 {QDB(15), QDB(15), QDB(15), QDB(15), QDB(15),
3518 QDB(15), QDB(15), QDB(15), QDB(15), QDB(15),
3519 QDB(15), QDB(15), QDB(15)},
3523 static const locale_mimo_info_t locale_jn = {
3524 {QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3525 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3526 QDB(13), 0, 0},
3527 {0, 0, QDB(13), QDB(13), QDB(13),
3528 QDB(13), QDB(13), QDB(13), QDB(13), 0,
3529 0, 0, 0},
3533 static const locale_mimo_info_t locale_kn = {
3534 {QDB(9), QDB(13), QDB(13), QDB(13), QDB(13),
3535 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3536 QDB(13), QDB(13), QDB(9)},
3537 {0, 0, QDB(10), QDB(13), QDB(13),
3538 QDB(13), QDB(13), QDB(13), /* 11.5 dBm */ 46, 46,
3539 46, 0, 0},
3543 static const locale_mimo_info_t locale_kn1 = {
3544 {QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3545 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3546 QDB(13), QDB(13), QDB(13)},
3547 {0, 0, /* 11.5 dBm */ 46, QDB(13), QDB(13),
3548 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
3549 QDB(13), 0, 0},
3553 static const locale_mimo_info_t locale_kn2 = {
3554 {QDB(15), QDB(15), QDB(15), QDB(15), QDB(15),
3555 QDB(15), QDB(15), QDB(15), QDB(15), QDB(15),
3556 QDB(15), QDB(15), QDB(15)},
3557 {0, 0, QDB(15), QDB(15), QDB(15),
3558 QDB(15), QDB(15), QDB(15), QDB(15), QDB(15),
3559 QDB(15), 0, 0},
3563 static const locale_mimo_info_t locale_kn4 = {
3564 {QDB(18), QDB(18), QDB(18), QDB(18), QDB(18),
3565 QDB(18), QDB(18), QDB(18), QDB(18), QDB(18),
3566 QDB(18), QDB(18), QDB(18)},
3567 {0, 0, QDB(18), QDB(18), QDB(18),
3568 QDB(18), QDB(18), QDB(18), QDB(18), QDB(18),
3569 QDB(18), 0, 0},
3573 /* CLM v4.5.3 has separate SISO/CDD power targets.
3574 * Express CDD limits here and fixup SISO in wlc_channel_reg_limits().
3576 static const locale_mimo_info_t locale_kn5 = {
3577 { /* 13.5 dBm */ 54, 54, 54, 54, 54,
3578 54, 54, 54, 54, 54,
3579 54, 54, 54},
3580 {0, 0, 54, 54, 54,
3581 54, 54, 54, 54, 54,
3582 54, 0, 0},
3586 /* locale mimo 2g indexes */
3587 #define LOCALE_MIMO_IDX_an1 0
3588 #define LOCALE_MIMO_IDX_an1_t1 1
3589 #define LOCALE_MIMO_IDX_an1_t2 2
3590 #define LOCALE_MIMO_IDX_an2 3
3591 #define LOCALE_MIMO_IDX_an3 4
3592 #define LOCALE_MIMO_IDX_an4 5
3593 #define LOCALE_MIMO_IDX_bn 6
3594 #define LOCALE_MIMO_IDX_bn1 7
3595 #define LOCALE_MIMO_IDX_bn2 8
3596 #define LOCALE_MIMO_IDX_cn 9
3597 #define LOCALE_MIMO_IDX_en 10
3598 #define LOCALE_MIMO_IDX_en2 11
3599 #define LOCALE_MIMO_IDX_fn 12
3600 #define LOCALE_MIMO_IDX_gn 13
3601 #define LOCALE_MIMO_IDX_hn 14
3602 #define LOCALE_MIMO_IDX_jn 15
3603 #define LOCALE_MIMO_IDX_kn 16
3604 #define LOCALE_MIMO_IDX_an5 17
3605 #define LOCALE_MIMO_IDX_an6 18
3606 #define LOCALE_MIMO_IDX_bn4 19
3607 #define LOCALE_MIMO_IDX_an7 20
3608 #define LOCALE_MIMO_IDX_mimo_2g_all 21
3609 #define LOCALE_MIMO_IDX_an8_t1 22
3610 #define LOCALE_MIMO_IDX_an9_t1 23
3611 #define LOCALE_MIMO_IDX_kn1 24
3612 #define LOCALE_MIMO_IDX_an6_2 25
3613 #define LOCALE_MIMO_IDX_bn2_1 26
3614 #define LOCALE_MIMO_IDX_an8_t2 27
3615 #define LOCALE_MIMO_IDX_bn5_1 28
3616 #define LOCALE_MIMO_IDX_an1_t3 29
3617 #define LOCALE_MIMO_IDX_an1_t4 30
3618 #define LOCALE_MIMO_IDX_an1_t5 31
3619 #define LOCALE_MIMO_IDX_bn2_2 32
3620 #define LOCALE_MIMO_IDX_en2_1 33
3621 #define LOCALE_MIMO_IDX_an6_1 34
3622 #define LOCALE_MIMO_IDX_bn2_3 35
3623 #define LOCALE_MIMO_IDX_bn_1 36
3624 #define LOCALE_MIMO_IDX_bn2_4 37
3625 #define LOCALE_MIMO_IDX_an_2 38
3626 #define LOCALE_MIMO_IDX_bn2_5 39
3627 #define LOCALE_MIMO_IDX_an7_2 40
3628 #define LOCALE_MIMO_IDX_bn_2 41
3629 #define LOCALE_MIMO_IDX_an2_1 42
3630 #define LOCALE_MIMO_IDX_an2_2 43
3631 #define LOCALE_MIMO_IDX_an2_3 44
3632 #define LOCALE_MIMO_IDX_bn2_6 45
3633 #define LOCALE_MIMO_IDX_an6_3 46
3634 #define LOCALE_MIMO_IDX_kn2 47
3635 #define LOCALE_MIMO_IDX_an2_4 48
3636 #define LOCALE_MIMO_IDX_bn_3 49
3637 #define LOCALE_MIMO_IDX_bn_4 50
3638 #define LOCALE_MIMO_IDX_bn_5 51
3639 #define LOCALE_MIMO_IDX_an10 52
3640 #define LOCALE_MIMO_IDX_an7_3 53
3641 #define LOCALE_MIMO_IDX_bn2_8 54
3642 #define LOCALE_MIMO_IDX_kn4 55
3643 #define LOCALE_MIMO_IDX_bn1_1 56
3644 #define LOCALE_MIMO_IDX_dn 57
3645 #define LOCALE_MIMO_IDX_bn_9 58
3646 #define LOCALE_MIMO_IDX_cn_2 59
3647 #define LOCALE_MIMO_IDX_an2_5 60
3648 #define LOCALE_MIMO_IDX_an6_6 61
3649 #define LOCALE_MIMO_IDX_cn_3 62
3650 #define LOCALE_MIMO_IDX_an6_5 63
3651 #define LOCALE_MIMO_IDX_cn_1 64
3652 #define LOCALE_MIMO_IDX_kn5 65
3653 #define LOCALE_MIMO_IDX_an6_4 66
3654 #define LOCALE_MIMO_IDX_an6_4_3n 66 /* same as an6_4 */
3655 #define LOCALE_MIMO_IDX_bn_10 67
3656 #define LOCALE_MIMO_IDX_bn_10_3n 68
3657 #define LOCALE_MIMO_IDX_an7_8 69
3658 #define LOCALE_MIMO_IDX_bn7 70
3659 #define LOCALE_MIMO_IDX_a_3n 71
3660 #define LOCALE_MIMO_IDX_an6_7 72
3661 #define LOCALE_MIMO_IDX_a1_3n 73
3662 #define LOCALE_MIMO_IDX_an2_21 74
3663 #define LOCALE_MIMO_IDX_b2_3n 75
3666 static const locale_mimo_info_t * g_mimo_2g_table[]=
3668 &locale_an1,
3669 &locale_an1_t1,
3670 &locale_an1_t2,
3671 &locale_an2,
3672 &locale_an3,
3673 &locale_an4,
3674 &locale_bn,
3675 &locale_bn1,
3676 &locale_bn2,
3677 &locale_cn,
3678 &locale_en,
3679 &locale_en2,
3680 &locale_fn,
3681 &locale_gn,
3682 &locale_hn,
3683 &locale_jn,
3684 &locale_kn,
3685 &locale_an5,
3686 &locale_an6,
3687 &locale_bn4,
3688 &locale_an7,
3689 &locale_mimo_all,
3690 &locale_an8_t1,
3691 &locale_an9_t1,
3692 &locale_kn1,
3693 &locale_an6_2,
3694 &locale_bn2_1,
3695 &locale_an8_t2,
3696 &locale_bn5_1,
3697 &locale_an1_t3,
3698 &locale_an1_t4,
3699 &locale_an1_t5,
3700 &locale_bn2_2,
3701 &locale_en2_1,
3702 &locale_an6_1,
3703 &locale_bn2_3,
3704 &locale_bn_1,
3705 &locale_bn2_4,
3706 &locale_an_2,
3707 &locale_bn2_5,
3708 &locale_an7_2,
3709 &locale_bn_2,
3710 &locale_an2_1,
3711 &locale_an2_2,
3712 &locale_an2_3,
3713 &locale_bn2_6,
3714 &locale_an6_3,
3715 &locale_kn2,
3716 &locale_an2_4,
3717 &locale_bn_3,
3718 &locale_bn_4,
3719 &locale_bn_5,
3720 &locale_an10,
3721 &locale_an7_3,
3722 &locale_bn2_8,
3723 &locale_kn4,
3724 &locale_bn1_1,
3725 &locale_dn,
3726 &locale_bn_9,
3727 &locale_cn_2,
3728 &locale_an2_5,
3729 &locale_an6_6,
3730 &locale_cn_3,
3731 &locale_an6_5,
3732 &locale_cn_1,
3733 &locale_kn5,
3734 &locale_an6_4,
3735 &locale_bn_10,
3736 &locale_bn_10_3n,
3737 &locale_an7_8,
3738 &locale_bn7,
3739 &locale_a_3n,
3740 &locale_an6_7,
3741 &locale_a1_3n,
3742 &locale_an2_21,
3743 &locale_b2_3n
3748 * MIMO Locale Definitions - 5 GHz
3751 static const locale_mimo_info_t locale_1n = {
3752 { QDB(10), QDB(16), QDB(13), 0, QDB(15)},
3753 { QDB(12), /* 15.5 dBm */ 62, QDB(12), 0, QDB(15)},
3757 static const locale_mimo_info_t locale_1an = {
3758 { QDB(10), QDB(16), QDB(13), 0, QDB(15)},
3759 { QDB(12), /* 15.5 dBm */ 62, QDB(12), 0, QDB(15)},
3763 /* CLM 4.2.3 CDD only. per MCS power limit is fixed up in wlc_channel_reg_limits(). */
3764 static const locale_mimo_info_t locale_1cn = {
3765 { /* 6.5 */ 26, QDB(13), QDB(13), 0, QDB(17)},
3766 { QDB(9), /* 15.5 dBm */ 62, QDB(10), 0, QDB(18)},
3770 static const locale_mimo_info_t locale_2n = {
3771 { QDB(13), QDB(13), QDB(13), QDB(13), QDB(13)},
3772 { QDB(13), QDB(13), QDB(13), QDB(13), QDB(13)},
3776 static const locale_mimo_info_t locale_3_3n = {
3777 { QDB(16), QDB(16), QDB(16), QDB(16), 0},
3778 { QDB(18), QDB(18), QDB(18), QDB(18), 0},
3782 static const locale_mimo_info_t locale_3n = {
3783 { /* 12.5 dBm */ 50, 50, 50, /* 15.5 dBm */ 62, 0},
3784 {QDB(14), QDB(14), QDB(14), QDB(16), 0},
3788 /* CLM v4.6.6 */
3789 /* Fix up HT20 ch[100-102]=21dBm in wlc_channel_reg_limits() */
3790 static const locale_mimo_info_t locale_3n_1 = {
3791 {QDB(15), QDB(15), QDB(15), 86, 0},
3792 {QDB(15), QDB(15), QDB(15), 86, 0},
3796 static const locale_mimo_info_t locale_3an = {
3797 { /* 12.5 dBm */ 50, 50, 50, QDB(13), 0},
3798 {0, 0, 0, 0, 0},
3799 WLC_NO_40MHZ
3802 static const locale_mimo_info_t locale_3an_1 = {
3803 { /* 12.5 dBm */ 50, 50, 50, /* 13.5 dBm */ 54, 0},
3804 {QDB(14), QDB(14), QDB(14), QDB(16), 0},
3808 static const locale_mimo_info_t locale_3bn = {
3809 { /* 17.5 dBm */ 70, 70, 70, QDB(20), 0},
3810 { 70, 70, 70, QDB(18), 0},
3814 static const locale_mimo_info_t locale_3cn = {
3815 { /* 12.5 dBm */ 50, 50, 50, QDB(14), 0},
3816 {QDB(14), QDB(14), QDB(14), QDB(14), 0},
3820 static const locale_mimo_info_t locale_3dn = {
3821 { /* 15.5 dBm */ 62, 62, 62, /* 14.5 */ 58, 0},
3822 { /* 14.5 */ 58, 58, 58, /* 13.5 */ 54, 0},
3826 static const locale_mimo_info_t locale_3en = {
3827 { QDB(18), QDB(18), QDB(18), QDB(18), 0},
3828 { QDB(20), QDB(20), QDB(20), QDB(20), 0},
3829 WLC_EIRP | WLC_DFS_EU
3832 static const locale_mimo_info_t locale_3jn = {
3833 { /* 12.5 dBm */ 50, 50, 50, /* 15.5 dBm */ 62, 0},
3834 { /* 10.5 dBm */ 42, 42, 42, QDB(16), 0},
3838 static const locale_mimo_info_t locale_3jn_1 = {
3839 {QDB(10), QDB(10), QDB(10), /* 15.5 dBm */ 62, 0},
3840 {QDB(10), QDB(10), QDB(10), QDB(16), 0},
3844 static const locale_mimo_info_t locale_3jn_2 = {
3845 { /* 15.5 dBm */ 62, 62, 62, /* 14.5 dBm */ 58, 0},
3846 { /* 14.5 dBm */ 58, 58, 58, /* 13.5 dBm */ 54, 0},
3850 static const locale_mimo_info_t locale_3jn_3 = {
3851 {QDB(11), QDB(11), QDB(11), QDB(13), 0},
3852 { /* 10.5 */ 42, 42, 42, QDB(16), 0},
3856 static const locale_mimo_info_t locale_3jn_4 = {
3857 {QDB(12), QDB(8), QDB(8), QDB(16), 0},
3858 {QDB(10), QDB(8), QDB(8), QDB(16), 0},
3862 static const locale_mimo_info_t locale_3ln = {
3863 {QDB(11), QDB(11), /* 10.5 dBm */ 42, 42, 0},
3864 {QDB(13), /* 12.5 dBm */ 50, 50, /* 13.5 dBm */ 54, 0},
3868 static const locale_mimo_info_t locale_3ln_1 = {
3869 {QDB(11), QDB(11), QDB(11), QDB(11), 0},
3870 { /* 12.5 dBm */ 50, 50, 50, QDB(13), 0},
3874 static const locale_mimo_info_t locale_3rn = {
3875 { /* 12.5 dBm */ 50, 50, 50, /* 15.5 dBm */ 62, 0},
3876 {QDB(14), QDB(14), QDB(14), QDB(16), 0},
3880 static const locale_mimo_info_t locale_3rn_4 = {
3881 { QDB(18), QDB(18), QDB(18), QDB(25), 0},
3882 { QDB(18), QDB(18), QDB(18), QDB(25), 0},
3883 WLC_EIRP
3886 static const locale_mimo_info_t locale_3rn_3 = {
3887 { QDB(15), QDB(15), QDB(15), QDB(16), 0},
3888 { QDB(16), QDB(16), QDB(16), QDB(16), 0},
3892 static const locale_mimo_info_t locale_3sn = {
3893 { QDB(18), QDB(18), QDB(18), QDB(18), 0},
3894 { QDB(18), QDB(18), QDB(18), QDB(18), 0},
3895 WLC_EIRP
3898 static const locale_mimo_info_t locale_3tn = {
3899 { QDB(18), QDB(18), QDB(18), QDB(18), 0},
3900 { QDB(18), QDB(18), QDB(18), QDB(18), 0},
3901 WLC_EIRP
3904 static const locale_mimo_info_t locale_4n = {
3905 {0, 0, 0, 0, 0},
3906 {0, 0, 0, 0, 0},
3907 WLC_NO_MIMO
3910 static const locale_mimo_info_t locale_5n = {
3911 {QDB(13), QDB(13), QDB(13), 0, QDB(15)},
3912 {QDB(14), QDB(14), QDB(14), 0, QDB(15)},
3916 static const locale_mimo_info_t locale_5ln = {
3917 {QDB(11), QDB(11), /* 10.5 dBm */ 42, 0, QDB(15)},
3918 {QDB(13), /* 12.5 dBm */ 50, 50, 0, QDB(15)},
3922 static const locale_mimo_info_t locale_5ln_1 = {
3923 {QDB(11), QDB(11), QDB(11), 0, QDB(15)},
3924 { /* 12.5 dBm */ 50, 50, 50, 0, QDB(15)},
3928 static const locale_mimo_info_t locale_5ln_2 = {
3929 {QDB(12), QDB(12), QDB(12), 0, QDB(16)},
3930 {QDB(13), QDB(13), QDB(13), 0, QDB(16)},
3934 static const locale_mimo_info_t locale_5n_1 = {
3935 { /* 12.5 dBm */ 50, 50, 50, 0, QDB(17)},
3936 {QDB(14), QDB(14), QDB(14), 0, QDB(18)},
3940 static const locale_mimo_info_t locale_5an = {
3941 {QDB(13), QDB(13), QDB(13), QDB(15), QDB(15)},
3942 {QDB(14), QDB(14), QDB(14), QDB(15), QDB(15)},
3946 static const locale_mimo_info_t locale_6n = {
3947 {QDB(13), QDB(13), QDB(13), /* 15.5 dBm */ 62, QDB(15)},
3948 {QDB(14), QDB(14), QDB(14), QDB(16), QDB(15)},
3952 static const locale_mimo_info_t locale_6an = {
3953 {QDB(11), QDB(11), QDB(11), QDB(11), QDB(15)},
3954 { /* 12.5 */ 50, 50, 50, QDB(13), QDB(15)},
3958 static const locale_mimo_info_t locale_6an_1 = {
3959 {QDB(11), QDB(11), QDB(11), 0, QDB(17)},
3960 {QDB(14), QDB(15), QDB(15), 0, QDB(17)},
3964 static const locale_mimo_info_t locale_7n = {
3965 {0, 0, 0, 0, QDB(15)},
3966 {0, 0, 0, 0, QDB(15)},
3970 static const locale_mimo_info_t locale_7cn = {
3971 #if 1 /* ASUS modify */
3972 {0, 0, 0, 0, QDB(17.5)},
3973 {0, 0, 0, 0, QDB(17.5)},
3974 #else
3975 {0, 0, 0, 0, QDB(13)},
3976 {0, 0, 0, 0, QDB(13)},
3977 #endif
3981 static const locale_mimo_info_t locale_7cn_1 = {
3982 {0, 0, 0, 0, QDB(16)},
3983 {0, 0, 0, 0, QDB(16)},
3987 static const locale_mimo_info_t locale_8n = {
3988 #if 1 /* ASUS modify */
3989 {0, 0, 0, 0, QDB(17.5)},
3990 {0, 0, 0, 0, QDB(17.5)},
3991 #else
3992 {0, QDB(16), QDB(16), 0, QDB(15)},
3993 {0, /* 16.5 dBm */ 66, 66, 0, QDB(15)},
3994 #endif
3998 static const locale_mimo_info_t locale_8an = {
3999 {0, QDB(10), QDB(10), /* 16.5 dBm */ 66, QDB(17)},
4000 {0, QDB(12), QDB(12), /* 18.5 dBm */ 74, QDB(18)},
4004 static const locale_mimo_info_t locale_8an_1 = {
4005 {0, QDB(11), QDB(11), QDB(17), QDB(17)},
4006 {0, QDB(15), QDB(15), QDB(17), QDB(17)},
4010 static const locale_mimo_info_t locale_8bn = {
4011 {0, QDB(10), QDB(10), QDB(14), QDB(17)},
4012 {0, QDB(12), QDB(12), QDB(17), QDB(17)},
4016 /* CLM 4.2.3 per MCS power limit is fixed up in wlc_channel_reg_limits(). */
4017 static const locale_mimo_info_t locale_8cn = {
4018 {0, /* 6.5 */ 26, 26, /* 14.5 */ 58, QDB(17)},
4019 {0, QDB(9), QDB(17), QDB(18), QDB(18)},
4023 static const locale_mimo_info_t locale_9n = {
4024 {0, 0, 0, 0, QDB(15)},
4025 {0, 0, 0, 0, 0},
4026 WLC_NO_40MHZ
4029 static const locale_mimo_info_t locale_9hn = {
4030 {0, 0, 0, 0, QDB(23)},
4031 {0, 0, 0, 0, QDB(23)},
4035 static const locale_mimo_info_t locale_10n = {
4036 {QDB(10), 0, 0, 0, QDB(10)},
4037 {QDB(10), 0, 0, 0, QDB(10)},
4041 static const locale_mimo_info_t locale_11n = {
4042 { /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)},
4043 {QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)},
4047 static const locale_mimo_info_t locale_11ln = {
4048 {QDB(11), QDB(9), QDB(9), /* 10.5 dBm */ 42, QDB(15)},
4049 {QDB(13), /* 12.5 dBm */ 50, 50, /* 13.5 dBm */ 54, QDB(15)},
4053 /* CLM v4.1.3 has separate SISO/CDD power targets and per-MCS limits.
4054 * Express CDD limits here and fixup SISO in wlc_channel_reg_limits().
4056 /* CLM v4.1.3-2 defined Locale 11ln-2 and 11ln-3, which are only different
4057 * in restricted channels: 11ln-2 has restricted set2 and 11ln-3 has restricted
4058 * set 8. This difference will be reflected at the base locale info, so ony one
4059 * locale 11ln-2 is needed for mimo locale
4061 static const locale_mimo_info_t locale_11ln_2 = {
4062 {QDB(10), /* 12.5 dBm */ 50, 50, /* 15.5 dBm */ 62, QDB(17)},
4063 { /* 10.5 dBm */ 42, 42, 42, QDB(16), QDB(18)},
4067 /* CLM V4.2.3 per MCS power limit fixed in wlc_channel_reg_limit(). */
4068 static const locale_mimo_info_t locale_11ln_4 = {
4069 {QDB(13), QDB(13), /* 6.5 dBm */ 26, /* 14.5 dBm */ 58, QDB(17)},
4070 {QDB(13), QDB(13), QDB(9), QDB(17), QDB(18)},
4074 static const locale_mimo_info_t locale_12n = {
4075 {0, 0, 0, 0, QDB(10)},
4076 {0, 0, 0, 0, QDB(10)},
4080 static const locale_mimo_info_t locale_13n = {
4081 { /* 12.5 dBm */ 50, 50, 50, 0, 0},
4082 {QDB(14), QDB(14), QDB(14), 0, 0},
4086 static const locale_mimo_info_t locale_13n_2 = {
4087 { QDB(15), QDB(15), QDB(15), 0, 0},
4088 {QDB(16), QDB(16), QDB(16), 0, 0},
4092 static const locale_mimo_info_t locale_14n = {
4093 { QDB(21), QDB(21), QDB(21), 0, QDB(21)},
4094 {QDB(21), QDB(21), QDB(21), 0, QDB(21)},
4098 static const locale_mimo_info_t locale_13n_1 = {
4099 {QDB(11), QDB(11), QDB(11), 0, 0},
4100 { /* 12.5 */ 50, 50, 50, 0, 0},
4104 static const locale_mimo_info_t locale_14an = {
4105 {QDB(11), QDB(11), QDB(11), 0, QDB(15)},
4106 { /* 12.5 */ 50, 50, 50, 0, QDB(15)},
4110 static const locale_mimo_info_t locale_15n = {
4111 {0, 0, 0, 0, 0},
4112 {0, 0, 0, 0, 0},
4113 WLC_NO_MIMO
4116 static const locale_mimo_info_t locale_16n = {
4117 { /* 13.5 */ 54, 54, 54, 0, 54},
4118 { 54, 54, 54, 0, 54},
4123 static const locale_mimo_info_t locale_16an = {
4124 { QDB(11), QDB(11), QDB(11), 0, QDB(15)},
4125 { /* 12.5 */ 50, 50, 50, 0, QDB(15)},
4129 static const locale_mimo_info_t locale_17n = {
4130 { /* 12.5 dBm */ 50, 50, 50, 0, 50},
4131 {QDB(14), QDB(14), QDB(14), 0, QDB(14)},
4136 static const locale_mimo_info_t locale_17an = {
4137 {QDB(11), QDB(11), QDB(11), 0, QDB(15)},
4138 { /* 12.5 */ 50, 50, 50, 0, QDB(15)},
4142 static const locale_mimo_info_t locale_18n = {
4143 { /* 12.5 dBm */ 50, 0, 0, 0, 0},
4144 {0, 0, 0, 0, 0},
4145 WLC_NO_40MHZ
4148 static const locale_mimo_info_t locale_18n_1 = {
4149 { QDB(12), 0, 0, 0, 0},
4150 { QDB(14), 0, 0, 0, 0},
4154 static const locale_mimo_info_t locale_18n_1_3n = {
4155 { /* 10.25 dBm */ 41, 0, 0, 0, 0},
4156 { /* 12.25 dBm */ 49, 0, 0, 0, 0},
4160 static const locale_mimo_info_t locale_18bn = {
4161 { /* 13.5 dBm */ 54, 0, 0, 0, 0},
4162 {QDB(15), 0, 0, 0, 0},
4166 static const locale_mimo_info_t locale_18rn = {
4167 #if 1 /* ASUS modify */
4168 { /* 12.5 dBm */ QDB(17.5), 0, 0, 0, 0},
4169 {QDB(17.5), 0, 0, 0, 0},
4170 #else
4171 { /* 12.5 dBm */ 50, 0, 0, 0, 0},
4172 {QDB(14), 0, 0, 0, 0},
4173 #endif
4177 static const locale_mimo_info_t locale_18ln = {
4178 {QDB(10), 0, 0, 0, 0},
4179 {QDB(12), 0, 0, 0, 0},
4183 /* CLM v3.0 has separate power targets in the channel 100-140 range.
4184 * Use ch 100-102 here, and fixup channels 104-140 in wlc_channel_reg_limits().
4186 static const locale_mimo_info_t locale_19n = {
4187 {QDB(10), QDB(16), QDB(14), /* 16.5 dBm */ 66, QDB(17)},
4188 {QDB(12), QDB(17), QDB(12), /* 15.5 dBm */ 62, QDB(18)},
4192 /* CLM v3.0 has separate power targets for SISO/CDD and for the channel 100-140 range.
4193 * Use CDD/SDM and ch 100-102 here, and fixup SISO and channels 104-140 in wlc_channel_reg_limits().
4195 static const locale_mimo_info_t locale_19n_1 = {
4196 {QDB(10), QDB(17), QDB(16), /* 13.5 dBm */ 54, QDB(17)},
4197 {QDB(12), QDB(16), QDB(13), QDB(11), QDB(16)},
4201 /* CLM v3.7 has common power targets for SISO/CDD except for channels 36 - 48.
4202 * Use CDD/SDM here, and fixup SISO chan 36-48 in wlc_channel_reg_limits().
4205 static const locale_mimo_info_t locale_19n_2 = {
4206 {QDB(10), QDB(13), QDB(13), QDB(14), /* 20.5 */ 82},
4207 {QDB(12), QDB(14), QDB(13), QDB(14), /* 19.5 */ 78},
4211 static const locale_mimo_info_t locale_19n_3 = {
4212 {QDB(11), /* 14.5 */ 58, QDB(11), QDB(14), /* 14.5 */ 58},
4213 {QDB(9), /* 14.5 */ 58, QDB(9), QDB(13), /* 13.5 */ 54},
4217 /* CLM v3.4 has power targets only for SISO. */
4218 static const locale_mimo_info_t locale_11n_1 = {
4219 { /* 12.5 dBm */ 50, 50, 50, 50, 50},
4220 { /* 12.5 dBm */ 50, 50, 50, /* 13.5 dBm */ 54, 54},
4224 /* CLM v1.12.4.2 has 15.5 for channels 100-102/40MHz and 17 for channels 104-140/40MHz
4225 * used lower levels for channels 100-140 here, and fixup channels 104-140 in
4226 * wlc_channel_reg_limits().
4228 static const locale_mimo_info_t locale_19an = {
4229 {QDB(10), QDB(16), QDB(13), QDB(17), QDB(17)},
4230 {QDB(12), /* 15.5 dBm */ 62, QDB(12), /* 15.5 dBm */ 62, QDB(18)},
4234 /* CLM v1.12.2.2 has 16.5/15.5 for channels 100-102 and 16.5/18.5 for channels 104-140
4235 * used lower levels for channels 100-140 here, and fixup channels 104-140 in
4236 * wlc_channel_reg_limits().
4238 static const locale_mimo_info_t locale_19bn = {
4239 {QDB(10), QDB(16), QDB(13), /* 16.5 dBm */ 66, 0},
4240 {QDB(12), /* 15.5 dBm */ 62, QDB(12), /* 15.5 dBm */ 62, 0},
4244 /* CLM v3.0 has separate power targets in the 100-140 channel range.
4245 * Use ch 100-102 here, and fixup channels 104-140 in wlc_channel_reg_limits().
4247 static const locale_mimo_info_t locale_19cn = {
4248 {QDB(10), QDB(16), QDB(14), /* 16.5 dBm */ 66, QDB(17)},
4249 {QDB(12), QDB(17), /* 11.5 dBm */ 46, /* 15.5 dBm */ 62, QDB(18)},
4253 /* CLM v1.12.4 has separate SISO/CDD power targets and split 100-140 channel range.
4254 * Express rough CDD/SCM limits here and fixup in wlc_channel_reg_limits().
4256 static const locale_mimo_info_t locale_19ln = {
4257 { /* 9.5 dBm */ 38, QDB(15), QDB(13), QDB(14), QDB(17)},
4258 {QDB(12), /* 15.5 dBm */ 62, QDB(12), /* 15.5 dBm */ 62, QDB(17)},
4262 /* CLM v3.1 has separate SISO/CDD power targets and split 100-140 channel range.
4263 * Express rough CDD/SCM limits here and fixup in wlc_channel_reg_limits().
4265 static const locale_mimo_info_t locale_19ln_1 = {
4266 /* channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
4267 {QDB(10), QDB(16), QDB(13), /* 16.5 dBm */ 66, QDB(17)},
4268 {QDB(12), /* 15.5 dBm */ 62, /* 11.5 dBm */ 46, /* 18.5 dBm */ 74, QDB(18)},
4269 LOCALE_RESTRICTED_CHAN_165
4272 /* CLM v3.7.4 has separate SISO/CDD power targets and split 100-140 channel range.
4273 * Express rough CDD/SDM limits here and fixup in wlc_channel_reg_limits().
4275 static const locale_mimo_info_t locale_19ln_2 = {
4276 /* channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
4277 { QDB(7), QDB(13), QDB(13), QDB(13), QDB(17)},
4278 {QDB(9), /* 15.5 dBm */ 62, QDB(10), QDB(12), QDB(18)},
4279 LOCALE_RESTRICTED_CHAN_165
4282 /* CLM v3.8.5 has only CDD power targets */
4283 static const locale_mimo_info_t locale_19ln_3 = {
4284 /* channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
4285 {QDB(10), QDB(16), QDB(13), QDB(16), QDB(16)},
4286 {QDB(12), QDB(14), QDB(12), QDB(15), QDB(16)},
4290 /* CLM v4.2.3 per MCS CDD and SISO power targets is fixed up in wlc_channel_reg_limits(). */
4291 static const locale_mimo_info_t locale_19ln_4 = {
4292 /* channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
4293 { /* 6.5 */ 26, QDB(13), QDB(13), /* 14.5 */ 54, QDB(17)},
4294 {QDB(9), /* 15.5 */ 62, QDB(10), QDB(17), QDB(18)},
4298 /* CLM v1.11.5 has separate SISO/CDD power targets and split 100-140 channel range.
4299 * Express rough CDD/SCM limits here and fixup in wlc_channel_reg_limits().
4301 static const locale_mimo_info_t locale_19hn = {
4302 {QDB(10), QDB(16), QDB(13), /* 16.5 dBm */ 66, QDB(17)},
4303 {QDB(12), /* 15.5 dBm */ 62, QDB(12), /* 15.5 dBm */ 62, QDB(18)},
4307 /* CLM v3.8.6 has separate SISO/CDD power targets and split 100-140 channel range.
4308 * Express rough CDD/SCM limits here and fixup in wlc_channel_reg_limits().
4310 static const locale_mimo_info_t locale_19hn_1 = {
4311 {QDB(10), /* 17.5 */ 70, /* 15.5 */ 62, 70, /* 18.5 */ 74},
4312 {QDB(12), /* 16.5 dBm */ 66, /* 14.5 */ 58, 66, 70},
4316 static const locale_mimo_info_t locale_19hn_2 = {
4317 { /* 11.5 */ 46, /* 21.5 */ 86, /* 17.5 */ 70, 86, 86},
4318 { /* 13.5 */ 54, 86, /* 14.5 */ 58, 86, 86},
4322 /* CLM v1.12.2.2 has separate SISO/CDD power targets and split 100-140 channel range.
4323 * Express rough CDD/SCM limits here and fixup in wlc_channel_reg_limits().
4325 static const locale_mimo_info_t locale_19rn = {
4326 {QDB(10), QDB(16), QDB(13), /* 16.5 dBm */ 66, QDB(17)},
4327 {QDB(12), /* 15.5 dBm */ 62, QDB(12), /* 15.5 dBm */ 62, QDB(18)},
4331 static const locale_mimo_info_t locale_19_3n = {
4332 { /* 3.5 */ 14, QDB(12), QDB(12), /* 14.5 dBm */ 58, QDB(17)},
4333 {QDB(7), QDB(14), QDB(10), QDB(17), QDB(18)},
4337 static const locale_mimo_info_t locale_20n = {
4338 {0, 0, 0, /* 15.5 dBm */ 62, 0},
4339 {0, 0, 0, 0, 0},
4340 WLC_NO_40MHZ
4343 static const locale_mimo_info_t locale_21n = {
4344 {0, QDB(14), QDB(14), 0, QDB(14)},
4345 {0, QDB(14), QDB(14), 0, QDB(14)},
4349 static const locale_mimo_info_t locale_22n = {
4350 { /* 12.5 dBm */ 50, 0, 0, 0, 0},
4351 {0, 0, 0, 0, 0},
4352 WLC_NO_40MHZ
4355 static const locale_mimo_info_t locale_23n = {
4356 { /* 12.5 dBm */ 50, 50, 50, 0, 0},
4357 {0, 0, 0, 0, 0},
4358 WLC_NO_40MHZ
4361 static const locale_mimo_info_t locale_24n = {
4362 { /* 12.5 dBm */ 50, 50, 50, /* 15.5 dBm */ 62, 0},
4363 {0, 0, 0, 0, 0},
4364 WLC_NO_40MHZ
4367 static const locale_mimo_info_t locale_25n = {
4368 { QDB(9), QDB(13), QDB(13), QDB(13), QDB(13)},
4369 {0, 0, 0, 0, 0},
4370 WLC_NO_40MHZ
4373 static const locale_mimo_info_t locale_25hn = {
4374 {QDB(12), QDB(16), QDB(16), 0, 0},
4375 {QDB(15), QDB(16), QDB(16), 0, 0},
4379 static const locale_mimo_info_t locale_25kn = {
4380 { QDB(9), QDB(13), QDB(13), QDB(13), QDB(13)},
4381 { QDB(12), QDB(13), QDB(13), QDB(13), QDB(13)},
4385 static const locale_mimo_info_t locale_25ln = {
4386 { QDB(9), QDB(13), QDB(13), QDB(13), QDB(13)},
4387 { QDB(12), QDB(12), QDB(12), QDB(12), QDB(12)},
4391 static const locale_mimo_info_t locale_26n = {
4392 { /* 12.5 dBm */ 50, 50, 50, /* 15.5 dBm */ 62, 0},
4393 {0, 0, 0, 0, 0},
4394 WLC_NO_40MHZ
4397 static const locale_mimo_info_t locale_27n = {
4398 {QDB(10), 0, 0, 0, QDB(15)},
4399 {QDB(12), 0, 0, 0, QDB(15)},
4403 static const locale_mimo_info_t locale_27bn = {
4404 #if 1 /* ASUS modify */
4405 {QDB(17.5), 0, 0, 0, QDB(17.5)},
4406 {QDB(17.5), 0, 0, 0, /* 23.5 dBm */ 70},
4407 #else
4408 {QDB(10), 0, 0, 0, QDB(20)},
4409 {QDB(12), 0, 0, 0, /* 23.5 dBm */ 94},
4410 #endif
4414 static const locale_mimo_info_t locale_27cn = {
4415 { /* 11.5 dBm */ 46, 0, 0, 0, QDB(23)},
4416 {QDB(12), 0, 0, 0, QDB(23)},
4420 static const locale_mimo_info_t locale_27en = {
4421 { /* 11.5 dBm */ 46, 0, 0, 0, /* 21.5 dBm */ 86},
4422 {46, 0, 0, 0, 86},
4426 static const locale_mimo_info_t locale_28n = {
4427 {QDB(10), 0, 0, 0, 0},
4428 {QDB(12), 0, 0, 0, 0},
4432 /* CLM v1.12.1 has different SISO vs CDD/SDM limits for 29n.
4433 * Express CDD/SDM limits here and fixup SISO in wlc_channel_reg_limits().
4435 static const locale_mimo_info_t locale_29n = {
4436 {QDB(10), QDB(15), QDB(15), QDB(15), QDB(15)},
4437 {QDB(12), QDB(16), QDB(16), QDB(16), QDB(16)},
4441 static const locale_mimo_info_t locale_29_3n = {
4442 { /* 11.25 dBm */ 45, /* 15.5 dBm */ 62, QDB(15), /* 15.5 dBm */ 62, /* 24.75 dBm */ 99 },
4443 {QDB(13), QDB(18), /* 12.5 dBm */ 50, QDB(18), /* 24.75 dBm */ 99 },
4447 /* CLM v1.12.2.4 has different SISO vs CDD/SDM limits for 29n.
4448 * Express CDD/SDM limits here and fixup SISO in wlc_channel_reg_limits().
4450 static const locale_mimo_info_t locale_29an = {
4451 {QDB(10), QDB(15), QDB(15), QDB(15), QDB(15)},
4452 {QDB(12), QDB(16), QDB(16), QDB(16), QDB(16)},
4456 /* CLM v2.1 has different limits on 20Mhz ch 100-116 vs. 132-140 for 29n.
4457 * Express ch 132-140 limits here and fixup SISO in wlc_channel_reg_limits().
4459 static const locale_mimo_info_t locale_29bn = {
4460 {QDB(10), QDB(15), QDB(15), QDB(16), QDB(20)},
4461 {QDB(12), QDB(15), QDB(12), QDB(15), /* 23.5 dBm */ 94},
4465 static const locale_mimo_info_t locale_29bn_1 = {
4466 {46 /* 11.5 dBm */, 74 /* 18.5 dBm */, 74 , 82 /* 20.5 dBm */, QDB(23)},
4467 {QDB(12), 82, 66 /* 16.5 dBm */, 82, QDB(23)},
4471 /* CLM v4.8.2 has different limits on 20Mhz ch 100-116 vs. 132-140 for 29n.
4472 * Express ch 132-140 limits here and fixup SISO in wlc_channel_reg_limits().
4474 static const locale_mimo_info_t locale_29bn_3 = {
4475 {QDB(12), QDB(19), QDB(19), /* 20.5 dBm */ 82, /* 26.5 dBm */ 106 },
4476 {QDB(14), 82, 66 /* 16.5 dBm */, 82, 106},
4480 /* CLM v1.12.1 has different SISO vs CDD/SDM limits for 29n.
4481 * Express CDD/SDM limits here and fixup SISO in wlc_channel_reg_limits().
4483 static const locale_mimo_info_t locale_29cn = {
4484 {QDB(13), QDB(13), QDB(13), /* 12.5 dBm */ 50, QDB(13)},
4485 {QDB(13), /* 12.5 dBm */ 50, /* 12.5 dBm */ 50, /* 12.5 dBm */ 50, QDB(13)},
4489 static const locale_mimo_info_t locale_29dn = {
4490 {QDB(10), 58 /* 14.5 */, 58, /* 17.5 dBm */ 70, /* 19.5 */ 78},
4491 {QDB(12), 58, 58, 58, 78},
4495 /* CLM v3.8.15 has only CDD/SDM limits for 29dn_1. */
4496 static const locale_mimo_info_t locale_29dn_1 = {
4497 { /* 11.5 dBm */ 46, /* 20.5 dBm */ 82, 82, 82, /* 22.5 dBm */ 90},
4498 { /* 13.5 dBm */ 54, /* 22.5 dBm */ 90, 90, 90, 90},
4502 static const locale_mimo_info_t locale_29dn_2 = {
4503 {QDB(11), QDB(17), QDB(17), QDB(17), QDB(17)},
4504 {QDB(13), QDB(15), QDB(15), QDB(17), QDB(17)},
4508 static const locale_mimo_info_t locale_31n = {
4509 {QDB(10), 0, 0, 0, QDB(15)},
4510 {QDB(12), 0, 0, 0, QDB(15)},
4515 #define LOCALE_MIMO_IDX_1n 0
4516 #define LOCALE_MIMO_IDX_1an 1
4517 #define LOCALE_MIMO_IDX_2n 2
4518 #define LOCALE_MIMO_IDX_3n 3
4519 #define LOCALE_MIMO_IDX_3an 4
4520 #define LOCALE_MIMO_IDX_3jn 5
4521 #define LOCALE_MIMO_IDX_3rn 6
4522 #define LOCALE_MIMO_IDX_5n 7
4523 #define LOCALE_MIMO_IDX_5an 8
4524 #define LOCALE_MIMO_IDX_6n 9
4525 #define LOCALE_MIMO_IDX_7n 10
4526 #define LOCALE_MIMO_IDX_8n 11
4527 #define LOCALE_MIMO_IDX_9n 12
4528 #define LOCALE_MIMO_IDX_10n 13
4529 #define LOCALE_MIMO_IDX_11n 14
4530 #define LOCALE_MIMO_IDX_12n 15
4531 #define LOCALE_MIMO_IDX_13n 16
4532 #define LOCALE_MIMO_IDX_7cn 17
4533 #define LOCALE_MIMO_IDX_15n 18
4534 #define LOCALE_MIMO_IDX_16n 19
4535 #define LOCALE_MIMO_IDX_17n 20
4536 #define LOCALE_MIMO_IDX_18n 21
4537 #define LOCALE_MIMO_IDX_18rn 22
4538 #define LOCALE_MIMO_IDX_19n 23
4539 #define LOCALE_MIMO_IDX_19an 24
4540 #define LOCALE_MIMO_IDX_19bn 25
4541 #define LOCALE_MIMO_IDX_19hn 26
4542 #define LOCALE_MIMO_IDX_19ln 27
4543 #define LOCALE_MIMO_IDX_19rn 28
4544 #define LOCALE_MIMO_IDX_20n 29
4545 #define LOCALE_MIMO_IDX_21n 30
4546 #define LOCALE_MIMO_IDX_22n 31
4547 #define LOCALE_MIMO_IDX_23n 32
4548 #define LOCALE_MIMO_IDX_24n 33
4549 #define LOCALE_MIMO_IDX_25n 34
4550 #define LOCALE_MIMO_IDX_25kn 35
4551 #define LOCALE_MIMO_IDX_26n 36
4552 #define LOCALE_MIMO_IDX_27n 37
4553 #define LOCALE_MIMO_IDX_28n 38
4554 #define LOCALE_MIMO_IDX_29n 39
4555 #define LOCALE_MIMO_IDX_29an 40
4556 #define LOCALE_MIMO_IDX_29cn 41
4557 #define LOCALE_MIMO_IDX_29bn_1 42
4558 #define LOCALE_MIMO_IDX_8bn 43
4559 #define LOCALE_MIMO_IDX_31n 44
4560 #define LOCALE_MIMO_IDX_19hn_2 45
4561 #define LOCALE_MIMO_IDX_18bn 46
4562 #define LOCALE_MIMO_IDX_27bn 47
4563 #define LOCALE_MIMO_IDX_29bn 48
4564 #define LOCALE_MIMO_IDX_mimo_5g_all 49
4565 #define LOCALE_MIMO_IDX_3cn 50
4566 #define LOCALE_MIMO_IDX_25ln 51
4567 #define LOCALE_MIMO_IDX_27cn 52
4568 #define LOCALE_MIMO_IDX_19n_1 53
4569 #define LOCALE_MIMO_IDX_19cn 54
4570 #define LOCALE_MIMO_IDX_19ln_1 55
4571 #define LOCALE_MIMO_IDX_3an_1 56
4572 #define LOCALE_MIMO_IDX_5n_1 57
4573 #define LOCALE_MIMO_IDX_11n_1 58
4574 #define LOCALE_MIMO_IDX_8an 59
4575 #define LOCALE_MIMO_IDX_19n_2 60
4576 #define LOCALE_MIMO_IDX_11ln_2 61
4577 #define LOCALE_MIMO_IDX_3jn_1 62
4578 #define LOCALE_MIMO_IDX_3ln 63
4579 #define LOCALE_MIMO_IDX_5ln 64
4580 #define LOCALE_MIMO_IDX_11ln 65
4581 #define LOCALE_MIMO_IDX_19ln_2 66
4582 #define LOCALE_MIMO_IDX_14n 67
4583 #define LOCALE_MIMO_IDX_19ln_3 68
4584 #define LOCALE_MIMO_IDX_19hn_1 69
4585 #define LOCALE_MIMO_IDX_29dn 70
4586 #define LOCALE_MIMO_IDX_3bn 71
4587 #define LOCALE_MIMO_IDX_19ln_4 72
4588 #define LOCALE_MIMO_IDX_1cn 73
4589 #define LOCALE_MIMO_IDX_3jn_3 74
4590 #define LOCALE_MIMO_IDX_3ln_1 75
4591 #define LOCALE_MIMO_IDX_5ln_1 76
4592 #define LOCALE_MIMO_IDX_6an 77
4593 #define LOCALE_MIMO_IDX_8cn 78
4594 #define LOCALE_MIMO_IDX_11ln_4 79
4595 #define LOCALE_MIMO_IDX_13n_1 80
4596 #define LOCALE_MIMO_IDX_14an 81
4597 #define LOCALE_MIMO_IDX_16an 82
4598 #define LOCALE_MIMO_IDX_17an 83
4599 #define LOCALE_MIMO_IDX_18ln 84
4600 #define LOCALE_MIMO_IDX_9hn 85
4601 #define LOCALE_MIMO_IDX_4n 86
4602 #define LOCALE_MIMO_IDX_3dn 87
4603 #define LOCALE_MIMO_IDX_3jn_2 88
4604 #define LOCALE_MIMO_IDX_19n_3 89
4605 #define LOCALE_MIMO_IDX_3jn_4 90
4606 #define LOCALE_MIMO_IDX_3rn_3 91
4607 #define LOCALE_MIMO_IDX_5ln_2 92
4608 #define LOCALE_MIMO_IDX_6an_1 93
4609 #define LOCALE_MIMO_IDX_7cn_1 94
4610 #define LOCALE_MIMO_IDX_8an_1 95
4611 #define LOCALE_MIMO_IDX_13n_2 96
4612 #define LOCALE_MIMO_IDX_25hn 97
4613 #define LOCALE_MIMO_IDX_29dn_2 98
4614 #define LOCALE_MIMO_IDX_18n_1 99
4615 #define LOCALE_MIMO_IDX_27en 100
4616 #define LOCALE_MIMO_IDX_27en_3n 100 /* same as LOCALE_MIMO_IDX_27en */
4617 #define LOCALE_MIMO_IDX_18n_1_3n 101
4618 #define LOCALE_MIMO_IDX_3tn 102
4619 #define LOCALE_MIMO_IDX_3sn 103
4620 #define LOCALE_MIMO_IDX_19_3n 104
4621 #define LOCALE_MIMO_IDX_3rn_4 105
4622 #define LOCALE_MIMO_IDX_29dn_1 106
4623 #define LOCALE_MIMO_IDX_29bn_3 107
4624 #define LOCALE_MIMO_IDX_29_3n 108
4625 #define LOCALE_MIMO_IDX_3n_1 109 /* CLM v4.6.6 */
4626 #define LOCALE_MIMO_IDX_3en 110
4627 #define LOCALE_MIMO_IDX_3_3n 111
4630 /* 11ln-2 and 11ln-3 should be the same 11n locale, the difference in */
4631 /* restricted channels is reflected in the base locale info in the Country Info */
4632 #define LOCALE_MIMO_IDX_11ln_3 LOCALE_MIMO_IDX_11ln_2
4634 static const locale_mimo_info_t * g_mimo_5g_table[]=
4636 &locale_1n,
4637 &locale_1an,
4638 &locale_2n,
4639 &locale_3n,
4640 &locale_3an,
4641 &locale_3jn,
4642 &locale_3rn,
4643 &locale_5n,
4644 &locale_5an,
4645 &locale_6n,
4646 &locale_7n,
4647 &locale_8n,
4648 &locale_9n,
4649 &locale_10n,
4650 &locale_11n,
4651 &locale_12n,
4652 &locale_13n,
4653 &locale_7cn,
4654 &locale_15n,
4655 &locale_16n,
4656 &locale_17n,
4657 &locale_18n,
4658 &locale_18rn,
4659 &locale_19n,
4660 &locale_19an,
4661 &locale_19bn,
4662 &locale_19ln,
4663 &locale_19hn,
4664 &locale_19rn,
4665 &locale_20n,
4666 &locale_21n,
4667 &locale_22n,
4668 &locale_23n,
4669 &locale_24n,
4670 &locale_25n,
4671 &locale_25kn,
4672 &locale_26n,
4673 &locale_27n,
4674 &locale_28n,
4675 &locale_29n,
4676 &locale_29an,
4677 &locale_29cn,
4678 &locale_29bn_1,
4679 &locale_8bn,
4680 &locale_31n,
4681 &locale_19hn_2,
4682 &locale_18bn,
4683 &locale_27bn,
4684 &locale_29bn,
4685 &locale_mimo_all,
4686 &locale_3cn,
4687 &locale_25ln,
4688 &locale_27cn,
4689 &locale_19n_1,
4690 &locale_19cn,
4691 &locale_19ln_1,
4692 &locale_3an_1,
4693 &locale_5n_1,
4694 &locale_11n_1,
4695 &locale_8an,
4696 &locale_19n_2,
4697 &locale_11ln_2,
4698 &locale_3jn_1,
4699 &locale_3ln,
4700 &locale_5ln,
4701 &locale_11ln,
4702 &locale_19ln_2,
4703 &locale_14n,
4704 &locale_19ln_3,
4705 &locale_19hn_1,
4706 &locale_29dn,
4707 &locale_3bn,
4708 &locale_19ln_4,
4709 &locale_1cn,
4710 &locale_3jn_3,
4711 &locale_3ln_1,
4712 &locale_5ln_1,
4713 &locale_6an,
4714 &locale_8cn,
4715 &locale_11ln_4,
4716 &locale_13n_1,
4717 &locale_14an,
4718 &locale_16an,
4719 &locale_17an,
4720 &locale_18ln,
4721 &locale_9hn,
4722 &locale_4n,
4723 &locale_3dn,
4724 &locale_3jn_2,
4725 &locale_19n_3,
4726 &locale_3jn_4,
4727 &locale_3rn_3,
4728 &locale_5ln_2,
4729 &locale_6an_1,
4730 &locale_7cn_1,
4731 &locale_8an_1,
4732 &locale_13n_2,
4733 &locale_25hn,
4734 &locale_29dn_2,
4735 &locale_18n_1,
4736 &locale_27en,
4737 &locale_18n_1_3n,
4738 &locale_3tn,
4739 &locale_3sn,
4740 &locale_19_3n,
4741 &locale_3rn_4,
4742 &locale_29dn_1,
4743 &locale_29bn_3,
4744 &locale_29_3n,
4745 &locale_3n_1, /* CLM v4.6.6 */
4746 &locale_3en,
4747 &locale_3_3n
4750 #endif /* WL11N */
4752 #ifdef LC
4753 #undef LC
4754 #endif
4755 #define LC(id) LOCALE_MIMO_IDX_ ## id
4757 #ifdef LC_2G
4758 #undef LC_2G
4759 #endif
4760 #define LC_2G(id) LOCALE_2G_IDX_ ## id
4762 #ifdef LC_5G
4763 #undef LC_5G
4764 #endif
4765 #define LC_5G(id) LOCALE_5G_IDX_ ## id
4767 #ifdef WL11N
4768 #if defined(DBAND)
4769 #define LOCALES(band2, band5, mimo2, mimo5) {LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)}
4770 #elif defined(BAND2G)
4771 #define LOCALES(band2, band5, mimo2, mimo5) {LC_2G(band2), 0, LC(mimo2), 0}
4772 #elif defined(BAND5G)
4773 #define LOCALES(band2, band5, mimo2, mimo5) {0, LC_5G(band5), 0, LC(mimo5)}
4774 #else
4775 #error "Don't know how to define LOCALES() for WL11N"
4776 #endif
4777 #else /* !WL11N */
4778 #if defined(DBAND)
4779 #define LOCALES(band2, band5, mimo2, mimo5) {LC_2G(band2), LC_5G(band5)}
4780 #elif defined(BAND2G)
4781 #define LOCALES(band2, band5, mimo2, mimo5) {LC_2G(band2), 0}
4782 #elif defined(BAND5G)
4783 #define LOCALES(band2, band5, mimo2, mimo5) {0, LC_5G(band5)}
4784 #else
4785 #error "Don't know how to define LOCALES()"
4786 #endif
4787 #endif /* !WL11N */
4789 static const struct {
4790 char abbrev[WLC_CNTRY_BUF_SZ]; /* country abbreviation */
4791 country_info_t country;
4792 } cntry_locales[] = {
4793 {"AF", LOCALES(b, 18, fn, 15n)}, /* Afghanistan */
4794 {"AL", LOCALES(b, 3, bn, 3n)}, /* Albania */
4795 {"DZ", LOCALES(b, 13, fn, 15n)}, /* Algeria */
4796 {"AS", LOCALES(a, 19, an1_t1, 19n)}, /* American Samoa */
4797 {"AO", LOCALES(b, 15, fn, 15n)}, /* Angola */
4798 {"AI", LOCALES(b, 3, bn, 3n)}, /* Anguilla */
4799 {"AG", LOCALES(b, 19, bn, 19n)}, /* Antigua and Barbuda */
4800 {"AR", LOCALES(b, 21, bn, 21n)}, /* Argentina */
4801 {"AM", LOCALES(b, 15, fn, 15n)}, /* Armenia */
4802 {"AW", LOCALES(b, 3, bn, 3n)}, /* Aruba */
4803 {"AU", LOCALES(h, 5, hn, 5n)}, /* Australia */
4804 {"AT", LOCALES(b, 3, bn, 3n)}, /* Austria */
4805 {"AZ", LOCALES(b, 19, bn, 19n)}, /* Azerbaijan */
4806 {"BS", LOCALES(h, 2, fn, 15n)}, /* Bahamas */
4807 {"BH", LOCALES(b, 2, bn, 2n)}, /* Bahrain */
4808 {"0B", LOCALES(a, 19, an1_t1, 19n)}, /* Baker Island */
4809 {"BD", LOCALES(b, 7, bn, 7n)}, /* Bangladesh */
4810 {"BB", LOCALES(b, 2, fn, 15n)}, /* Barbados */
4811 {"BY", LOCALES(b, 3, fn, 15n)}, /* Belarus */
4812 {"BE", LOCALES(b, 3, bn, 3n)}, /* Belgium */
4813 {"BZ", LOCALES(b, 15, fn, 15n)}, /* Belize */
4814 {"BJ", LOCALES(b, 15, fn, 15n)}, /* Benin */
4815 {"BM", LOCALES(b, 3, bn, 3n)}, /* Bermuda */
4816 {"BT", LOCALES(b, 15, fn, 15n)}, /* Bhutan */
4817 {"BO", LOCALES(b, 15, fn, 15n)}, /* Bolivia */
4818 {"BA", LOCALES(b, 3, bn, 3n)}, /* Bosnia and Herzegovina */
4819 {"BW", LOCALES(b, 3, fn, 15n)}, /* Botswana */
4820 {"BR", LOCALES(b, 6, bn, 6n)}, /* Brazil */
4821 {"IO", LOCALES(b, 3, bn, 3n)}, /* British Indian Ocean Territory */
4822 {"BN", LOCALES(b, 15, fn, 15n)}, /* Brunei Darussalam */
4823 {"BG", LOCALES(b, 3, bn, 3n)}, /* Bulgaria */
4824 {"BF", LOCALES(b, 7, fn, 15n)}, /* Burkina Faso */
4825 {"BI", LOCALES(b, 15, fn, 15n)}, /* Burundi */
4826 {"KH", LOCALES(b, 6, bn, 6n)}, /* Cambodia */
4827 {"CM", LOCALES(b, 15, fn, 15n)}, /* Cameroon */
4828 {"CA", LOCALES(a, 2, an1_t1, 2n)}, /* Canada */
4829 {"CV", LOCALES(b, 3, fn, 15n)}, /* Cape Verde */
4830 {"KY", LOCALES(a, 19, an1_t1, 19n)}, /* Cayman Islands */
4831 {"CF", LOCALES(b, 15, fn, 15n)}, /* Central African Republic */
4832 {"TD", LOCALES(b, 15, fn, 15n)}, /* Chad */
4833 {"CL", LOCALES(b, 14, bn, 14n)}, /* Chile */
4834 {"CN", LOCALES(k, 7c, kn1, 7cn)}, /* China */
4835 {"CX", LOCALES(h, 5, hn, 5n)}, /* Christmas Island */
4836 {"CO", LOCALES(b, 19, bn, 19n)}, /* Colombia */
4837 {"KM", LOCALES(b, 15, fn, 15n)}, /* Comoros */
4838 {"CG", LOCALES(b, 15, fn, 15n)}, /* Congo */
4839 {"CD", LOCALES(b, 15, fn, 15n)}, /* Congo, The Democratic Republic Of The */
4840 {"CR", LOCALES(b, 19, bn, 19hn)}, /* Costa Rica */
4841 {"CI", LOCALES(b, 15, fn, 15n)}, /* Cote D'ivoire */
4842 {"HR", LOCALES(b, 3, bn, 3n)}, /* Croatia */
4843 {"CU", LOCALES(b, 9, fn, 15n)}, /* Cuba */
4844 {"CY", LOCALES(b, 3, bn, 3n)}, /* Cyprus */
4845 {"CZ", LOCALES(b, 3, bn, 3n)}, /* Czech Republic */
4846 {"DK", LOCALES(b, 3, bn, 3n)}, /* Denmark */
4847 {"DJ", LOCALES(b, 15, fn, 15n)}, /* Djibouti */
4848 {"DM", LOCALES(b, 19, fn, 15n)}, /* Dominica */
4849 {"DO", LOCALES(b, 19, fn, 15n)}, /* Dominican Republic */
4850 {"EC", LOCALES(b, 19, bn, 19n)}, /* Ecuador */
4851 {"EG", LOCALES(b, 5, bn, 5n)}, /* Egypt */
4852 {"SV", LOCALES(b, 1, bn, 1n)}, /* El Salvador */
4853 {"GQ", LOCALES(b, 15, fn, 15n)}, /* Equatorial Guinea */
4854 {"ER", LOCALES(b, 15, fn, 15n)}, /* Eritrea */
4855 {"EE", LOCALES(b, 3, bn, 3n)}, /* Estonia */
4856 {"ET", LOCALES(b, 3, bn, 3n)}, /* Ethiopia */
4857 {"FK", LOCALES(b, 6, fn, 15n)}, /* Falkland Islands (Malvinas) */
4858 {"FO", LOCALES(b, 3, bn, 3n)}, /* Faroe Islands */
4859 {"FJ", LOCALES(b, 15, fn, 15n)}, /* Fiji */
4860 {"FI", LOCALES(b, 3, bn, 3n)}, /* Finland */
4861 {"FR", LOCALES(b, 3, bn, 3n)}, /* France */
4862 {"GF", LOCALES(b, 3, bn, 3n)}, /* French Guina */
4863 {"PF", LOCALES(b, 3, bn, 3n)}, /* French Polynesia */
4864 {"TF", LOCALES(b, 3, bn, 3n)}, /* French Southern Territories */
4865 {"GA", LOCALES(b, 15, fn, 15n)}, /* Gabon */
4866 {"GM", LOCALES(b, 15, fn, 15n)}, /* Gambia */
4867 {"GE", LOCALES(b, 15, bn, 15n)}, /* Georgia */
4868 {"GH", LOCALES(b, 19, bn, 19n)}, /* Ghana */
4869 {"GI", LOCALES(b, 3, fn, 15n)}, /* Gibraltar */
4870 {"DE", LOCALES(b, 3, bn, 3n)}, /* Germany */
4871 {"GR", LOCALES(b, 3, bn, 3n)}, /* Greece */
4872 {"GD", LOCALES(b, 6, bn, 6n)}, /* Grenada */
4873 {"GP", LOCALES(b, 3, bn, 3n)}, /* Guadeloupe */
4874 {"GU", LOCALES(a, 19, an1_t1, 19n)}, /* Guam */
4875 {"GT", LOCALES(b, 1, fn, 15n)}, /* Guatemala */
4876 {"GG", LOCALES(b, 3, fn, 15n)}, /* Guernsey */
4877 {"GN", LOCALES(b, 15, fn, 15n)}, /* Guinea */
4878 {"GW", LOCALES(b, 15, fn, 15n)}, /* Guinea-bissau */
4879 {"GY", LOCALES(b, 15, fn, 15n)}, /* Guyana */
4880 {"HT", LOCALES(b, 1, fn, 15n)}, /* Haiti */
4881 {"VA", LOCALES(b, 3, bn, 3n)}, /* Holy See (Vatican City State) */
4882 {"HN", LOCALES(b, 7, bn, 7n)}, /* Honduras */
4883 {"HK", LOCALES(h, 6, hn, 6n)}, /* Hong Kong */
4884 {"HU", LOCALES(b, 3, bn, 3n)}, /* Hungary */
4885 {"IS", LOCALES(b, 3, bn, 3n)}, /* Iceland */
4886 {"IN", LOCALES(g, 5, gn, 5n)}, /* India */
4887 {"ID", LOCALES(b, 15, bn, 15n)}, /* Indonesia */
4888 {"IR", LOCALES(f, 9, fn, 15n)}, /* Iran, Islamic Republic Of */
4889 {"IQ", LOCALES(b, 15, fn, 15n)}, /* Iraq */
4890 {"IE", LOCALES(b, 3, bn, 3n)}, /* Ireland */
4891 {"IL", LOCALES(b, 13, bn, 13n)}, /* Israel */
4892 {"IT", LOCALES(b, 3, bn, 3n)}, /* Italy */
4893 {"JM", LOCALES(b, 7, bn, 7n)}, /* Jamaica */
4894 {"JP", LOCALES(c, 4, fn, 15n)}, /* Japan legacy definition, old 5GHz */
4895 {"J1", LOCALES(c1,18, fn, 15n)}, /* Japan_1 */
4896 {"J2", LOCALES(c1,13, fn, 15n)}, /* Japan_2 */
4897 {"J3", LOCALES(c1, 3, fn, 15n)}, /* Japan_3 */
4898 {"J4", LOCALES(c1,20, fn, 15n)}, /* Japan_4 */
4899 {"J5", LOCALES(c1,22, fn, 15n)}, /* Japan_5 */
4900 {"J6", LOCALES(c1,23, fn, 15n)}, /* Japan_6 */
4901 {"J7", LOCALES(c1,24, fn, 15n)}, /* Japan_7 */
4902 {"J8", LOCALES(c1, 4, fn, 15n)}, /* Japan_8 */
4903 {"J9", LOCALES(b, 23, cn, 23n)}, /* Japan_9 */
4904 {"J10", LOCALES(c1,23, cn, 23n)}, /* Japan_10 */
4905 {"JE", LOCALES(b, 3, fn, 15n)}, /* Jersey */
4906 {"JO", LOCALES(b, 18, bn, 18rn)}, /* Jordan */
4907 {"KZ", LOCALES(b, 19, bn, 19n)}, /* Kazakhstan */
4908 {"KE", LOCALES(b, 3, bn, 3rn)}, /* Kenya */
4909 {"KI", LOCALES(b, 6, fn, 15n)}, /* Kiribati */
4910 {"KR", LOCALES(b, 9, fn, 15n)}, /* Korea, Republic Of */
4911 {"KW", LOCALES(b, 15, bn, 15n)}, /* Kuwait */
4912 {"0A", LOCALES(b, 15, fn, 15n)}, /* Kosovo (No country code, use 0A) */
4913 {"KG", LOCALES(b, 15, fn, 15n)}, /* Kyrgyzstan */
4914 {"LA", LOCALES(b, 3, fn, 15n)}, /* Lao People's Democratic Repubic */
4915 {"LV", LOCALES(b, 3, bn, 3n)}, /* Latvia */
4916 {"LB", LOCALES(b, 12, bn, 12n)}, /* Lebanon */
4917 {"LS", LOCALES(b, 3, fn, 15n)}, /* Lesotho */
4918 {"LR", LOCALES(b, 15, fn, 15n)}, /* Liberia */
4919 {"LY", LOCALES(b, 15, fn, 15n)}, /* Libyan Arab Jamahiriya */
4920 {"LI", LOCALES(b, 3, bn, 3n)}, /* Liechtenstein */
4921 {"LT", LOCALES(b, 3, bn, 3n)}, /* Lithuania */
4922 {"LU", LOCALES(b, 3, bn, 3n)}, /* Luxembourg */
4923 {"MK", LOCALES(b, 3, bn, 3n)}, /* Macedonia, Former Yugoslav Republic Of */
4924 {"MG", LOCALES(b, 15, fn, 15n)}, /* Madagascar */
4925 {"MW", LOCALES(b, 9, bn, 9n)}, /* Malawi */
4926 {"MO", LOCALES(b, 12, fn, 15n)}, /* Macao */
4927 {"MY", LOCALES(g, 5, gn, 5n)}, /* Malaysia */
4928 {"MV", LOCALES(b, 17, bn, 17n)}, /* Maldives */
4929 {"ML", LOCALES(b, 15, fn, 15n)}, /* Mali */
4930 {"MT", LOCALES(b, 3, bn, 3n)}, /* Malta */
4931 {"IM", LOCALES(b, 3, fn, 15n)}, /* Man, Isle Of */
4932 {"MQ", LOCALES(b, 3, bn, 3n)}, /* Martinique */
4933 {"MR", LOCALES(b, 3, bn, 3n)}, /* Mauritania */
4934 {"MU", LOCALES(b, 3, bn, 3n)}, /* Mauritius */
4935 {"YT", LOCALES(b, 3, bn, 3n)}, /* Mayotte */
4936 {"MX", LOCALES(b, 13, bn, 13n)}, /* Mexico */
4937 {"FM", LOCALES(a, 19, fn, 15n)}, /* Micronesia, Federated States Of */
4938 {"MD", LOCALES(b, 3, bn, 3n)}, /* Moldova, Republic Of */
4939 {"MC", LOCALES(b, 3, bn, 3n)}, /* Monaco */
4940 {"MN", LOCALES(b, 15, fn, 15n)}, /* Mongolia */
4941 {"ME", LOCALES(b, 3, bn, 3n)}, /* Montenegro */
4942 {"MS", LOCALES(b, 3, bn, 3n)}, /* Montserrat */
4943 {"MA", LOCALES(b, 18, en, 15n)}, /* Morocco */
4944 {"MZ", LOCALES(b, 19, bn, 19n)}, /* Mozambique */
4945 {"MM", LOCALES(b, 15, fn, 15n)}, /* Myanmar */
4946 {"NA", LOCALES(b, 19, bn, 19n)}, /* Namibia */
4947 {"NR", LOCALES(b, 15, fn, 15n)}, /* Nauru */
4948 {"NP", LOCALES(g, 16, gn, 16n)}, /* Nepal */
4949 {"NL", LOCALES(b, 3, bn, 3n)}, /* Netherlands */
4950 {"AN", LOCALES(b, 3, bn, 3n)}, /* Netherlands Antilles */
4951 {"NC", LOCALES(b, 15, fn, 15n)}, /* New Caledonia */
4952 {"NZ", LOCALES(b, 6, bn, 6n)}, /* New Zealand */
4953 {"NI", LOCALES(b, 6, bn, 6n)}, /* Nicaragua */
4954 {"NE", LOCALES(b, 19, fn, 15n)}, /* Niger */
4955 {"NG", LOCALES(b, 8a, fn, 15n)}, /* Nigeria */
4956 {"NU", LOCALES(b, 19, fn, 15n)}, /* Niue */
4957 {"NF", LOCALES(h, 5, hn, 5n)}, /* Norfolk Island */
4958 {"MP", LOCALES(a, 19, fn, 15n)}, /* Northern Mariana Islands */
4959 {"NO", LOCALES(b, 3, bn, 3n)}, /* Norway */
4960 {"OM", LOCALES(b, 3, bn, 3n)}, /* Oman */
4961 {"PK", LOCALES(b, 7, bn, 7n)}, /* Pakistan */
4962 {"PW", LOCALES(b, 6, fn, 15n)}, /* Palau */
4963 {"PA", LOCALES(b, 1, bn, 1n)}, /* Panama */
4964 {"PG", LOCALES(b, 1, bn, 1n)}, /* Papua New Guinea */
4965 {"PY", LOCALES(b, 7, bn, 7n)}, /* Paraguay */
4966 {"PE", LOCALES(b, 19, bn, 19n)}, /* Peru */
4967 {"PH", LOCALES(b, 6, bn, 6n)}, /* Philippines */
4968 {"PL", LOCALES(b, 3, bn, 3n)}, /* Poland */
4969 {"PT", LOCALES(b, 3, bn, 3n)}, /* Portugal */
4970 {"PR", LOCALES(a, 19, an1_t1, 19n)}, /* Pueto Rico */
4971 {"QA", LOCALES(b, 12, bn, 12n)}, /* Qatar */
4972 {"RE", LOCALES(b, 3, bn, 3n)}, /* Reunion */
4973 {"RO", LOCALES(b, 3, bn, 3n)}, /* Romania */
4974 {"RW", LOCALES(b, 7, bn, 7n)}, /* Rwanda */
4975 {"KN", LOCALES(b, 7, fn, 15n)}, /* Saint Kitts and Nevis */
4976 {"LC", LOCALES(b, 15, fn, 15n)}, /* Saint Lucia */
4977 {"MF", LOCALES(b, 15, fn, 15n)}, /* Sanit Martin / Sint Marteen */
4978 {"RU", LOCALES(b, 15, fn, 15n)}, /* Russian Federation */
4979 {"PM", LOCALES(b, 13, fn, 15n)}, /* Saint Pierre and Miquelon */
4980 {"VC", LOCALES(b, 19, fn, 15n)}, /* Saint Vincent and The Grenadines */
4981 {"WS", LOCALES(b, 15, fn, 15n)}, /* Samoa */
4982 {"SM", LOCALES(b, 3, bn, 3n)}, /* San Marino */
4983 {"ST", LOCALES(b, 15, fn, 15n)}, /* Sao Tome and Principe */
4984 {"SA", LOCALES(b, 16, bn, 16n)}, /* Saudi Arabia */
4985 {"SN", LOCALES(b, 3, bn, 3n)}, /* Senegal */
4986 {"RS", LOCALES(b, 3, bn, 3n)}, /* Serbia */
4987 {"SC", LOCALES(b, 15, fn, 15n)}, /* Seychelles */
4988 {"SL", LOCALES(b, 15, fn, 15n)}, /* Sierra Leone */
4989 {"SG", LOCALES(g, 5, gn, 5n)}, /* Singapore */
4990 {"SK", LOCALES(b, 3, bn, 3n)}, /* Slovakia */
4991 {"SI", LOCALES(b, 3, bn, 3n)}, /* Slovenia */
4992 {"SB", LOCALES(b, 15, fn, 15n)}, /* Solomon Islands */
4993 {"SO", LOCALES(b, 15, fn, 15n)}, /* Somalia */
4994 {"ZA", LOCALES(b, 3, bn, 3n)}, /* South Africa */
4995 {"ES", LOCALES(b, 3, bn, 3n)}, /* Spain */
4996 {"LK", LOCALES(g, 6, gn, 6n)}, /* Sri Lanka */
4997 {"SR", LOCALES(b, 15, fn, 15n)}, /* Suriname */
4998 {"SZ", LOCALES(b, 15, fn, 15n)}, /* Swaziland */
4999 {"SE", LOCALES(b, 3, bn, 3n)}, /* Sweden */
5000 {"CH", LOCALES(b, 3, bn, 3n)}, /* Switzerland */
5001 {"SY", LOCALES(f, 12, fn, 15n)}, /* Syrian Arab Republic */
5002 {"TW", LOCALES(a, 8, an1_t1, 8n)}, /* Taiwan, Province Of China */
5003 {"TJ", LOCALES(b, 15, fn, 15n)}, /* Tajikistan */
5004 {"TZ", LOCALES(b, 12, fn, 15n)}, /* Tanzania, United Republic Of */
5005 {"TH", LOCALES(b, 6, bn, 6n)}, /* Thailand */
5006 {"TG", LOCALES(b, 15, fn, 15n)}, /* Togo */
5007 {"TO", LOCALES(b, 15, fn, 15n)}, /* Tonga */
5008 {"TT", LOCALES(b, 6, bn, 6n)}, /* Trinidad and Tobago */
5009 {"TN", LOCALES(b, 13, bn, 13n)}, /* Tunisia */
5010 {"TR", LOCALES(b, 13, bn, 13n)}, /* Turkey */
5011 {"TM", LOCALES(b, 15, fn, 15n)}, /* Turkmenistan */
5012 {"TC", LOCALES(b, 3, bn, 3n)}, /* Turks and Caicos Islands */
5013 {"TV", LOCALES(b, 15, fn, 15n)}, /* Tuvalu */
5014 {"UG", LOCALES(h, 3, fn, 15n)}, /* Uganda */
5015 {"UA", LOCALES(b, 15, fn, 15n)}, /* Ukraine */
5016 {"AE", LOCALES(b, 15, bn, 15n)}, /* United Arab Emirates */
5017 {"GB", LOCALES(b, 3, bn, 3n)}, /* United Kingdom */
5018 {"US", LOCALES(a, 1, an1_t1, 1n)}, /* United States */
5019 {"Q2", LOCALES(a, 27, an1_t1, 27n)}, /* United States (No DFS) */
5020 {"UM", LOCALES(a, 19, an1_t1, 19n)}, /* United States Minor Outlying Islands */
5021 {"UY", LOCALES(h, 6, hn, 6n)}, /* Uruguay */
5022 {"UZ", LOCALES(b, 15, fn, 15n)}, /* Uzbekistan */
5023 {"VU", LOCALES(b, 15, fn, 15n)}, /* Vanuatu */
5024 {"VE", LOCALES(b, 5, bn, 5n)}, /* Venezuela */
5025 {"VN", LOCALES(b, 13, bn, 13n)}, /* Viet Nam */
5026 {"VG", LOCALES(b, 3, bn, 3n)}, /* Virgin Islands, British */
5027 {"VI", LOCALES(a, 19, an1_t1, 19n)}, /* Virgin Islands, U.S. */
5028 {"WF", LOCALES(b, 3, bn, 3n)}, /* Wallis and Futuna */
5029 {"0C", LOCALES(b, 13, bn, 13n)}, /* West Bank */
5030 {"EH", LOCALES(b, 18, en, 15n)}, /* Western Sahara */
5031 {"YE", LOCALES(b, 15, fn, 15n)}, /* Yemen */
5032 {"ZM", LOCALES(g, 3, fn, 15n)}, /* Zambia */
5033 {"ZW", LOCALES(b, 19, bn, 19n)}, /* Zimbabwe */
5034 {"Z2", LOCALES(a, 19, fn, 15n)}, /* Country Z2 */
5035 {"XA", LOCALES(b, 11, fn, 15n)}, /* Europe / APAC 2005 */
5036 {"XB", LOCALES(a, 1r, fn, 15n)}, /* North and South America and Taiwan */
5037 {"X0", LOCALES(a1,1a, an1_t1, 1an)}, /* FCC Worldwide */
5038 {"X1", LOCALES(b, 5, bn, 5n)}, /* Worldwide APAC */
5039 {"X2", LOCALES(i, 11, bn, 11n)}, /* Worldwide RoW 2 */
5040 {"X3", LOCALES(b, 3, en, 3an)}, /* ETSI */
5041 {"EU", LOCALES(b, 18, bn, 18rn)}, /* European Union */
5042 {"XS", LOCALES(b2_6, 11_4, bn2_8, 11ln_3)}, /* Worldwide Safe Enhanced Mode Locale */
5043 {"XW", LOCALES(j, 31, jn, 31n)}, /* Worldwide Locale for Linux driver */
5044 {"XX", LOCALES(b2, 3, fn, 15n)}, /* Worldwide Locale (passive Ch12-14) */
5045 {"XY", LOCALES(b, 3, bn, 3n)}, /* Fake Country Code */
5046 {"XZ", LOCALES(b5, 15, fn, 15n)}, /* Worldwide Locale (passive Ch12-14) */
5047 {"XU", LOCALES(b_5, 3c, bn_2, 3cn)}, /* European Locale 0dBi antenna in 2.4GHz */
5048 {"XV", LOCALES(b2_1, 15, bn2_1, 15n)}, /* Worldwide Safe Mode Locale (passive Ch12-14) */
5049 /* following entries are for old or internal locales */
5050 #if defined(BCMDBG) || defined(WLTEST)
5051 {"ALL", LOCALES(2G_band_all, 5G_band_all, mimo_2g_all, mimo_5g_all)},
5052 #endif
5053 #ifdef BCMDBG
5054 {"RDR", LOCALES(f, 5G_radar_only, mimo_2g_all, mimo_5g_all)},
5055 #endif /* BCMDBG */
5056 #ifdef WL11D
5057 {"B2", LOCALES(11d_2G, 11d_5G, fn, 15n)}
5058 #endif
5061 const struct {
5062 char abbrev[3]; /* country abbreviation */
5063 uint8 rev; /* regulatory revision */
5064 country_info_t country;
5065 } cntry_rev_locales[] = {
5066 {"AR", 1, LOCALES(b, 19, bn, 19n)}, /* Argentina */
5067 {"AR", 2, LOCALES(b, 19a_1, fn, 15n)}, /* Argentina */
5068 {"AR", 4, LOCALES(b, 19l_2, bn1_1, 19ln_4)}, /* Argentina */
5069 {"AU", 1, LOCALES(b, 5a, fn, 15n)}, /* Australia */
5070 {"AU", 2, LOCALES(h, 5a, hn, 5an)}, /* Australia */
5071 {"AT", 1, LOCALES(b, 3c, bn, 3cn)}, /* Austria */
5072 {"AT", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Austria */
5073 {"BE", 1, LOCALES(b, 3c, bn, 3cn)}, /* Belgium */
5074 {"BE", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Belgium */
5075 {"BN", 1, LOCALES(g, 5, gn, 5n)}, /* Brunei Darussalam */
5076 {"BN", 2, LOCALES(b, 5, fn, 15n)}, /* Brunei Darussalam */
5077 {"BG", 1, LOCALES(b, 3c, bn, 3cn)}, /* Bulgaria */
5078 {"BG", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Bulgaria */
5079 {"BY", 1, LOCALES(b, 3l_1, fn, 15n)}, /* Belarus */
5080 {"BR", 1, LOCALES(b, 6a, bn1_1, 6an)}, /* Brazil */
5081 {"CA", 2, LOCALES(a, 29, an1_t2, 29n)}, /* Canada */
5082 {"CA", 3, LOCALES(a, 29a, an1_t2, 29an)}, /* Canada */
5083 {"CA", 4, LOCALES(a, 29c, an1_t2, 29cn)}, /* Canada */
5084 {"CA", 5, LOCALES(a4, 29b, an5, 29bn)}, /* Canada */
5085 {"CA", 6, LOCALES(a11, 19a_1, fn, 15n)}, /* Canada */
5086 {"CA", 7, LOCALES(a4, 29d, an5, 29dn)}, /* Canada */
5087 {"CA", 11, LOCALES(a3_1, 19l_2, an1_t5, 19ln_4)}, /* Canada */
5088 {"CN", 1, LOCALES(k_1, 7c, kn1, 7cn)}, /* China */
5089 {"CN", 3, LOCALES(c_4, 7c, bn1_1, 7cn)}, /* China */
5090 {"CN", 4, LOCALES(k_3, 7c, kn4, 7cn)}, /* China */
5091 {"CN", 5, LOCALES(k_4, 7c_1, kn5, 7cn_1)}, /* China */
5092 {"HR", 1, LOCALES(b, 3c, bn, 3cn)}, /* Croatia */
5093 {"HR", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Croatia */
5094 {"CY", 1, LOCALES(b, 3c, bn, 3cn)}, /* Cyprus */
5095 {"CY", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Cyprus */
5096 {"CZ", 1, LOCALES(b, 3c, bn, 3cn)}, /* Czech Republic */
5097 {"CZ", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Czech Republic */
5098 {"CL", 2, LOCALES(b, 14a, bn1_1, 15n)}, /* Chile */
5099 {"CO", 1, LOCALES(b, 18l, bn1_1, 18ln)}, /* Colombia */
5100 {"CR", 1, LOCALES(b, 19l_2, bn1_1, 19ln_4)}, /* Costa Rica */
5101 {"DK", 1, LOCALES(b, 3c, bn, 3cn)}, /* Denmark */
5102 {"DK", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Denmark */
5103 {"DE", 2, LOCALES(b, 3, bn, 3n)}, /* Germany */
5104 {"DE", 3, LOCALES(b, 3c, bn, 3cn)}, /* Germany */
5105 {"DE", 4, LOCALES(b_11, 3d, bn_9, 3dn)}, /* Germany Apple X21 */
5106 {"DE", 5, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Germany */
5107 {"EC", 1, LOCALES(b, 19l_2, bn1_1, 19ln_4)}, /* Ecuador */
5108 {"SV", 1, LOCALES(b, 1c, bn1_1, 1cn)}, /* El Salvador */
5109 {"EE", 1, LOCALES(b, 3c, bn, 3cn)}, /* Estonia */
5110 {"EE", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Estonia */
5111 {"EU", 2, LOCALES(b, 3r, bn, 3rn)}, /* Europeanwide AP (notch out weather band) */
5112 {"EU", 3, LOCALES(b4, 15, bn4, 15n)}, /* Europeanwide AP (notch out weather band) */
5113 {"EU", 4, LOCALES(b, 15, bn4, 15n)}, /* Europeanwide AP (Netgear WNR3500 v2) */
5114 {"EU", 5, LOCALES(b_9, 3b, bn_1, 3bn)}, /* Europeanwide AP (Netgear WND3400) */
5115 {"EU", 9, LOCALES(b_3, 18_2, bn_10, 18n_1)}, /* Europeanwide AP (Cisco Linksys E4200) */
5116 {"EU", 10, LOCALES(b_11, 15, fn, 15n)}, /* Europeanwide AP (HP Bianca) */
5117 {"EU", 11, LOCALES(b_11, 3r_4, kn5, 3rn_3)}, /* Europeanwide AP (Avaya AP 8120) */
5118 {"EU", 12, LOCALES(b, 3s, bn7, 3sn)}, /* Europeanwide AP (for Airties) */
5119 {"EU", 13, LOCALES(b, 3r_5, bn7, 3rn_4)}, /* Europeanwide AP (high power) */
5120 {"EU", 14, LOCALES(f, 3_1, fn, 3n_1)}, /* CLM v4.6.6 */
5121 {"FI", 1, LOCALES(b, 3c, bn, 3cn)}, /* Finland */
5122 {"FI", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Finland */
5123 {"FR", 1, LOCALES(b, 3c, bn, 3cn)}, /* France */
5124 {"FR", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* France */
5125 {"GR", 1, LOCALES(b, 3c, bn, 3cn)}, /* Greece */
5126 {"ID", 1, LOCALES(b, 9h, bn, 9hn)}, /* Indonesia */
5127 {"GR", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Greece */
5128 {"HU", 1, LOCALES(b, 3c, bn, 3cn)}, /* Hungary */
5129 {"HU", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Hungary */
5130 {"IS", 1, LOCALES(b, 3c, bn, 3cn)}, /* Iceland */
5131 {"IS", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Iceland */
5132 {"IN", 1, LOCALES(b, 5, fn, 15n)}, /* India */
5133 {"ID", 2, LOCALES(b, 9h, bn1_1, 9hn)}, /* Indonesia */
5134 {"IE", 1, LOCALES(b, 3c, bn, 3cn)}, /* Ireland */
5135 {"IE", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Ireland */
5136 {"IL", 2, LOCALES(b, 13_1, bn1_1, 13n_1)}, /* Israel */
5137 {"IL", 3, LOCALES(b_11, 13_2, kn5, 13n_2)}, /* Israel */
5138 {"IL", 4, LOCALES(b, 13_3, bn_5, 13n_1)}, /* Israel (Juniper AX411) */
5139 {"IT", 1, LOCALES(b, 3c, bn, 3cn)}, /* Italy */
5140 {"IT", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Italy */
5141 {"JP", 1, LOCALES(c, 23, cn, 23n)}, /* Japan */
5142 {"JP", 2, LOCALES(c, 24, cn, 24n)}, /* Japan */
5143 {"JP", 3, LOCALES(c, 3, cn, 3jn)}, /* Japan */
5144 {"JP", 4, LOCALES(c, 3, en, 3jn)}, /* Japan */
5145 {"JP", 5, LOCALES(b, 3, bn, 3jn)}, /* Japan */
5146 {"JP", 6, LOCALES(c_1, 3, cn, 3jn)}, /* Japan */
5147 {"JP", 7, LOCALES(c_1, 3j, cn, 3jn_1)}, /* Japan */
5148 {"JP", 8, LOCALES(c_2, 3j_1, fn, 15n)}, /* Japan */
5149 {"JP", 9, LOCALES(c, 3j_8, cn_1, 3jn)}, /* Japan */
5150 {"JP", 11, LOCALES(b_11, 3j_3, cn_2, 3jn_2)}, /* Japan */
5151 {"JP", 12, LOCALES(c_4, 3j_4, bn1_1, 3jn_3)}, /* Japan */
5152 {"JP", 13, LOCALES(c_4, 3j_4, bn1_1, 3jn_3)}, /* Japan */
5153 {"JP", 14, LOCALES(c_5, 3j_5, cn_3, 3jn_4)}, /* Japan */
5154 {"KR", 1, LOCALES(b, 25, fn, 15n)}, /* Korea, Republic Of (RegRev1) */
5155 {"KR", 2, LOCALES(k, 25, en2, 25n)}, /* Korea, Republic Of (RegRev2) */
5156 {"KR", 3, LOCALES(k, 25, kn, 25kn)}, /* Korea, Republic Of (RegRev3) */
5157 {"KR", 4, LOCALES(k, 25l, kn1, 25ln)}, /* Korea, Republic Of (RegRev4) */
5158 {"KR", 5, LOCALES(k, 25l, kn1, 25ln)}, /* Korea, Republic Of (RegRev5) */
5159 {"KR", 6, LOCALES(k, 25l, kn1, 25ln)}, /* Korea, Republic Of (RegRev6) */
5160 {"KR", 7, LOCALES(k, 25l, kn2, 25kn)}, /* Korea, Republic Of (RegRev7) */
5161 {"KR", 8, LOCALES(k_1, 25l, kn1, 25ln)}, /* Korea, Republic Of (RegRev8) */
5162 {"KR", 10, LOCALES(c_4, 25l, bn1_1, 25ln)}, /* Korea, Republic Of (RegRev10) */
5163 {"KR", 11, LOCALES(c_4, 25l, bn1_1, 25ln)}, /* Korea, Republic Of (RegRev11) */
5164 {"KR", 12, LOCALES(k_4, 25h, kn5, 25hn)}, /* Korea, Republic Of (RegRev12) */
5165 {"KW", 1, LOCALES(b, 13, bn, 13n)}, /* Kuwait */
5166 {"KW", 3, LOCALES(b, 13_1, bn1_1, 13n_1)}, /* Kuwait */
5167 {"LV", 1, LOCALES(b, 3c, bn, 3cn)}, /* Latvia */
5168 {"LV", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Latvia */
5169 {"LI", 1, LOCALES(b, 3c, bn, 3cn)}, /* Liechtenstein */
5170 {"LI", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Liechtenstein */
5171 {"LT", 1, LOCALES(b, 3c, bn, 3cn)}, /* Lithuania */
5172 {"LT", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Lithuania */
5173 {"LU", 1, LOCALES(b, 3c, bn, 3cn)}, /* Luxembourg */
5174 {"LU", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Luxembourg */
5175 {"MV", 1, LOCALES(b, 17a, bn1_1, 17an)}, /* Maldives */
5176 {"MY", 1, LOCALES(b, 5, fn, 15n)}, /* Malaysia */
5177 {"MT", 1, LOCALES(b, 3c, bn, 3cn)}, /* Malta */
5178 {"MT", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Malta */
5179 {"MX", 1, LOCALES(b, 2, bn, 2n)}, /* Mexico */
5180 {"MX", 2, LOCALES(b, 1c, bn1_1, 1cn)}, /* Mexico */
5181 {"MA", 1, LOCALES(b, 3, en, 26n)}, /* Morocco */
5182 {"NP", 1, LOCALES(b, 16, fn, 15n)}, /* Nepal */
5183 {"NL", 1, LOCALES(b, 3c, bn, 3cn)}, /* Netherlands */
5184 {"NL", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Netherlands */
5185 {"NO", 1, LOCALES(b, 3c, bn, 3cn)}, /* Norway */
5186 {"NO", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Norway */
5187 {"NZ", 1, LOCALES(a_6, 6a_1, an6_6, 6an_1)}, /* New Zeland - Cisco AP3500i */
5188 {"PY", 1, LOCALES(b, 6, bn, 6n)}, /* Paraguay */
5189 {"PK", 1, LOCALES(b, 7, bn1_1, 7n)}, /* Pakistan */
5190 {"PA", 1, LOCALES(g, 1c, gn, 1cn)}, /* Panama */
5191 {"PE", 2, LOCALES(b, 19l_2, bn1_1, 19ln_4)}, /* Peru */
5192 {"PH", 2, LOCALES(b, 6a, bn1_1, 6an)}, /* Philippines */
5193 {"PL", 1, LOCALES(b, 3c, bn, 3cn)}, /* Poland */
5194 {"PL", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Poland */
5195 {"PT", 1, LOCALES(b, 3c, bn, 3cn)}, /* Portugal */
5196 {"PT", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Portugal */
5197 {"PR", 2, LOCALES(a3_1, 19l_2, an1_t5, 19ln_4)}, /* Pueto Rico */
5198 {"Q1", 17, LOCALES(a20, 15, an2_21, 15n)}, /* United States */
5199 {"Q2", 2, LOCALES(a4, 27b, an5, 27bn)}, /* United States (No DFS) */
5200 {"Q2", 3, LOCALES(a4, 27c, an5, 27cn)}, /* United States (No DFS) */
5201 {"Q2", 4, LOCALES(a4_2, 27e, an6_4, 27en)}, /* United States (No DFS) */
5202 {"RO", 1, LOCALES(b, 3c, bn, 3cn)}, /* Romania */
5203 {"RO", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Romania */
5204 {"RU", 1, LOCALES(b, 5, fn, 15n)}, /* Russian Federation */
5205 {"RU", 2, LOCALES(b, 19, fn, 15n)}, /* Russian Federation */
5206 {"RU", 3, LOCALES(b, 19l_2, dn, 4n)}, /* Russian Federation */
5207 {"RU", 4, LOCALES(b_11, 2, kn5, 2n)}, /* Russian Federation */
5208 {"SA", 2, LOCALES(b, 15, bn1_1, 15n)}, /* Saudi Arabia */
5209 {"SG", 1, LOCALES(b_2, 15, bn_2, 15n)}, /* Singapore */
5210 {"SG", 2, LOCALES(b, 5, fn, 15n)}, /* Singapore */
5211 {"SG", 3, LOCALES(k_4, 5l_2, kn5, 5ln_2)}, /* Singapore */
5212 {"SK", 1, LOCALES(b, 3c, bn, 3cn)}, /* Slovakia */
5213 {"SK", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Slovakia */
5214 {"SI", 1, LOCALES(b, 3c, bn, 3cn)}, /* Slovenia */
5215 {"SI", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Slovenia */
5216 {"ES", 1, LOCALES(b, 3c, bn, 3cn)}, /* Spain */
5217 {"ES", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Spain */
5218 {"ZA", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* South Africa */
5219 {"SE", 1, LOCALES(b, 3c, bn, 3cn)}, /* Sweden */
5220 {"SE", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Sweden */
5221 {"CH", 1, LOCALES(b, 3c, bn, 3cn)}, /* Switzerland */
5222 {"CH", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* Switzerland */
5223 {"CH", 9, LOCALES(b_1, 15, bn_1, 15n)}, /* Switzerland */
5224 {"TW", 2, LOCALES(a, 8a, an1_t1, 8an)}, /* Taiwan, Province Of China */
5225 {"TW", 3, LOCALES(a, 8a, an1_t1, 8bn)}, /* Taiwan, Province Of China */
5226 {"TW", 4, LOCALES(a3_1, 8b, an1_t5, 8cn)}, /* Taiwan, Province Of China */
5227 {"TW", 5, LOCALES(a_6, 8a_1, an6_6, 8an_1)}, /* Taiwan, Province Of China */
5228 {"TH", 2, LOCALES(b, 6a, bn1_1, 6an)}, /* Thailand */
5229 {"TR", 3, LOCALES(b, 13_1, bn1_1, 13n_1)}, /* Turkey */
5230 {"TR", 4, LOCALES(b, 3, bn7, 3tn)}, /* Turkey (For Airties) */
5231 {"UA", 1, LOCALES(b, 13, fn, 15n)}, /* Ukraine */
5232 {"UA", 2, LOCALES(b, 5, en, 5n)}, /* Ukraine */
5233 {"UA", 3, LOCALES(b, 5, bn1_1, 5n)}, /* Ukraine */
5234 {"AE", 1, LOCALES(b, 3, bn, 3n)}, /* United Arab Emirates */
5235 {"AE", 3, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* United Arab Emirates */
5236 {"GB", 1, LOCALES(b, 3c, bn, 3cn)}, /* United Kingdom */
5237 {"GB", 2, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* United Kingdom */
5238 {"GB", 6, LOCALES(b, 3, bn7, 3en)}, /* United Kingdom */
5239 {"US", 2, LOCALES(a, 1, an2, 1n)}, /* United States */
5240 {"US", 3, LOCALES(a, 1, an3, 1n)}, /* United States */
5241 {"US", 4, LOCALES(a, 1, an4, 1n)}, /* United States */
5242 {"US", 5, LOCALES(a, 19, an1_t1, 19n)}, /* United States */
5243 {"US", 6, LOCALES(a, 19, an2, 19n)}, /* United States */
5244 {"US", 7, LOCALES(a, 19, an3, 19n)}, /* United States */
5245 {"US", 8, LOCALES(a, 19, an4, 19n)}, /* United States */
5246 {"US", 9, LOCALES(a, 28, an1_t1, 28n)}, /* United States (Low 5G Band only) */
5247 {"US", 10, LOCALES(a1, 19, an1_t2, 19hn)}, /* United States */
5248 {"US", 11, LOCALES(a1, 19b, an4, 19bn)}, /* United States */
5249 {"US", 12, LOCALES(a2, 1, an1_t1, 1n)}, /* United States */
5250 {"US", 13, LOCALES(a5, 15, an6, 15n)}, /* United States */
5251 {"US", 14, LOCALES(a6, 15, an7, 15n)}, /* United States */
5252 {"US", 15, LOCALES(a3, 19, an2, 19n)}, /* United States */
5253 {"US", 16, LOCALES(a7, 19, an8_t1, 19cn)}, /* United States */
5254 {"US", 17, LOCALES(b2_2, 19, bn2_3, 19n)}, /* United States */
5255 {"US", 18, LOCALES(a9, 15, an6_2, 15n)}, /* United States */
5256 {"US", 19, LOCALES(a6, 19, an8_t2, 19cn)}, /* United States */
5257 {"US", 20, LOCALES(a3, 19_1, an1_t3, 19n_1)}, /* United States */
5258 {"US", 21, LOCALES(a1, 15, an1_t4, 15n)}, /* United States */
5259 {"US", 22, LOCALES(a_1, 15, fn, 15n)}, /* United States */
5260 {"US", 23, LOCALES(a6_1, 15, an6_1, 15n)}, /* United States */
5261 {"US", 24, LOCALES(a4, 29b_1, an5, 29bn_1)}, /* United States */
5262 {"US", 25, LOCALES(b2_3, 15, bn2_4, 15n)}, /* United States */
5263 {"US", 26, LOCALES(a10_1, 15, an2_1, 15n)}, /* United States */
5264 {"US", 27, LOCALES(f, 19_2, fn, 19n_2)}, /* United States */
5265 {"US", 28, LOCALES(a6_2, 15, an7_2, 15n)}, /* United States */
5266 {"US", 29, LOCALES(a3_1, 19l_2, an1_t5, 19ln_2)}, /* United States */
5267 {"US", 30, LOCALES(b2_5, 15, bn2_4, 15n)}, /* United States */
5268 {"US", 31, LOCALES(a10_2, 15, an2_2, 15n)}, /* United States */
5269 {"US", 32, LOCALES(a10_3, 15, an2_3, 15n)}, /* United States */
5270 {"US", 33, LOCALES(a_2, 15, an_2, 15n)}, /* United States */
5271 {"US", 34, LOCALES(a11, 19a_1, fn, 15n)}, /* United States */
5272 {"US", 35, LOCALES(a_3, 19_3, an2_4, 19ln_3)}, /* United States */
5273 {"US", 36, LOCALES(a, 19h_1, an1_t1, 19hn_1)}, /* United States */
5274 {"US", 37, LOCALES(a12, 15, an10, 15n)}, /* United States */
5275 {"US", 38, LOCALES(a5_1, 15, an6_3, 15n)}, /* United States */
5276 {"US", 39, LOCALES(a6_3, 19h_2, an7_3, 19hn_2)}, /* United States */
5277 {"VN", 1, LOCALES(b, 13, bn1_1, 13n)}, /* Viet Nam regrev-1 */
5278 {"US", 45, LOCALES(a, 19h_2, an1_t1, 19hn_2)}, /* United States */
5279 {"US", 47, LOCALES(a4, 29d_1, an5, 29dn_1)}, /* United States */
5280 {"US", 49, LOCALES(a_5, 19_4, an2_5, 19n_3)}, /* United States */
5281 {"US", 50, LOCALES(a3_1, 19l_2, an1_t5, 19ln_4)}, /* United States */
5282 {"US", 53, LOCALES(a3_1, 19l_2, an1_t5, 19ln_2)}, /* United States */
5283 {"US", 54, LOCALES(a14, 15, fn, 15n)}, /* United States */
5284 {"US", 55, LOCALES(a4_3, 15, an6_5, 15n)}, /* United States */
5285 {"US", 56, LOCALES(a_6, 29d_2, an6_6, 29dn_2)}, /* United States */
5286 {"US", 61, LOCALES(a3_1, 19l_2, an1_t5, 19ln_2)}, /* United States */
5287 {"US", 63, LOCALES(a6_8, 15, an7_8, 15n)}, /* United States */
5288 {"US", 72, LOCALES(a3_1, 19l_2, an6_4, 19ln_2)}, /* United States */
5289 {"US", 73, LOCALES(a4_4, 29b_3, an6_7, 29bn_3)}, /* United States */
5290 {"VE", 1, LOCALES(g, 5, gn, 5n)}, /* Venezuela */
5291 {"VN", 1, LOCALES(b, 5, bn1_1, 5n)}, /* Viet Nam */
5292 {"XA", 1, LOCALES(b, 3, en, 3an)}, /* Europe / APAC == X3 for bad SROM for 4321 */
5293 {"X0", 2, LOCALES(a1, 19r, an1_t1, 19rn)}, /* FCC Worldwide */
5294 {"X0", 3, LOCALES(a1, 19a, an1_t1, 19an)}, /* FCC Worldwide */
5295 {"X0", 4, LOCALES(a3, 19a, an1_t1, 19ln)}, /* FCC Worldwide */
5296 {"X0", 5, LOCALES(a3_1, 19l_1, an1_t5, 19ln_1)}, /* FCC Worldwide */
5297 {"X0", 6, LOCALES(a3_1, 19l_2, an1_t5, 19ln_2)}, /* FCC Worldwide */
5298 {"X0", 7, LOCALES(a3_1, 19l_2, an1_t5, 19ln_4)}, /* FCC Worldwide */
5299 {"X0", 8, LOCALES(a3_1, 19l_2, an1_t5, 19ln_4)}, /* FCC Worldwide */
5300 {"X1", 2, LOCALES(b, 5, bn1, 5n)}, /* Worldwide APAC */
5301 {"X1", 3, LOCALES(b, 5, bn2, 5n)}, /* Worldwide APAC */
5302 {"X1", 4, LOCALES(b3_1, 5, bn2_2, 5n_1)}, /* Worldwide APAC */
5303 {"X1", 5, LOCALES(b3_1, 5l, bn2_2, 5ln)}, /* Worldwide APAC */
5304 {"X1", 6, LOCALES(b3_1, 5l_1, bn1_1, 5ln_1)}, /* Worldwide APAC */
5305 {"X1", 7, LOCALES(b3_1, 5l_1, bn1_1, 5ln_1)}, /* Worldwide APAC */
5306 {"X2", 2, LOCALES(i, 11, bn1, 11n)}, /* Worldwide RoW 2 */
5307 {"X2", 3, LOCALES(i, 11, bn2, 11n)}, /* Worldwide RoW 2 */
5308 {"X2", 4, LOCALES(i_1, 11, bn2_2, 11n)}, /* Worldwide RoW 2 */
5309 {"X2", 5, LOCALES(i_1, 11l, bn2_2, 11ln)}, /* Worldwide RoW 2 */
5310 {"X2", 6, LOCALES(i, 11l_1, bn1_1, 11ln_4)}, /* Worldwide RoW 2 */
5311 {"X2", 7, LOCALES(i, 11l_1, bn1_1, 11ln_4)}, /* Worldwide RoW 2 */
5312 {"X3", 1, LOCALES(b, 3, bn, 3an_1)}, /* ETSI */
5313 {"X3", 2, LOCALES(b, 3, bn1, 3an_1)}, /* ETSI */
5314 {"X3", 3, LOCALES(b3, 3, bn2, 3an_1)}, /* ETSI */
5315 {"X3", 4, LOCALES(b3_1, 3, bn2_2, 3an_1)}, /* ETSI */
5316 {"X3", 5, LOCALES(b3_1, 3l, bn2_2, 3ln)}, /* ETSI */
5317 {"X3", 6, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* ETSI */
5318 {"X3", 7, LOCALES(b, 3l_1, bn1_1, 3ln_1)}, /* ETSI */
5319 {"XX", 1, LOCALES(b5, 15, fn, 15n)}, /* Worldwide (passive Ch12-14), no MIMO */
5320 {"XX", 2, LOCALES(b5_2, 15, bn5_1, 15n)}, /* Worldwide (passive Ch12-14) */
5321 {"XX", 3, LOCALES(b5_4, 15, fn, 15n)}, /* Worldwide (passive Ch12-14) */
5322 {"XZ", 1, LOCALES(b2_4, 11_1, bn2_5, 11n_1)}, /* Worldwide (passive Ch12-14), passive 5G */
5323 {"XZ", 2, LOCALES(b5_3, 11_2, fn, 15n)}, /* Worldwide (passive Ch12-14), passive 5G */
5324 {"XY", 1, LOCALES(b_3, 15, bn2_2, 15n)}, /* Worldwide (passive Ch12-14), passive 5G */
5325 {"XY", 2, LOCALES(b_4, 15, bn2_6, 15n)}, /* Worldwide (passive Ch12-14), passive 5G */
5326 {"XU", 1, LOCALES(b_6, 3c, bn_3, 3cn)}, /* European locale, 1dBi antenna in 2.4GHz */
5327 {"XU", 2, LOCALES(b_7, 3c, bn_4, 3cn)}, /* European locale, 2dBi antenna in 2.4GHz */
5328 {"XU", 3, LOCALES(b_8, 3c, bn_5, 3cn)}, /* European locale, 3dBi antenna in 2.4GHz */
5329 {"XV", 1, LOCALES(b2_6, 11_3, bn2_8, 11ln_2)}, /* WW Safe Mode Locale */
5330 {"XT", 4, LOCALES(b2_5, 15, bn2_4, 15n)}, /* For BCM94319SDB */
5331 {"XT", 5, LOCALES(b2_5, 15, bn2_4, 15n)}, /* For BCM94319SDHMB */
5332 {"ww", 5, LOCALES(a_2, 15, an_2, 15n)}, /* For BCM94319USBWLN4L (HP Bellatrix) */
5333 {"ww", 6, LOCALES(a14, 15, fn, 15n)}, /* For BCM94336SDGP HP Bianca */
5336 /* generic country with no channels */
5337 static const country_info_t country_nochannel_locale =
5338 LOCALES(f, 15, fn, 15n);
5340 /* these countries use country_nochannel_locale, allowing no 802.11 channel/operation */
5341 static const char country_nochannel[][WLC_CNTRY_BUF_SZ] = {
5342 "AD", /* Andorra */
5343 "AQ", /* Antarctica */
5344 "AC", /* Ascension Island */
5345 "Z1", /* Ashmore and Cartier Islands */
5346 "BV", /* Bouvet Island */
5347 /* Channel Islands (Z1 duplicate) */
5348 "CP", /* Clipperton Island */
5349 "CC", /* Cocos (Keeling) Islands */
5350 "CK", /* Cook Islands */
5351 /* Coral Sea Islands (Z1 duplicate) */
5352 /* Diego Garcia (Z1 duplicate) */
5353 "GL", /* Greenland */
5354 /* Guantanamo Bay (Z1 duplicate) */
5355 "HM", /* Heard Island and Mcdonald Islands */
5356 /* Jan Mayen (Z1 duplicate) */
5357 "KP", /* Korea, Democratic People's Republic Of */
5358 "MH", /* Marshall Islands */
5359 "PS", /* Palestinian Territory, Occupied */
5360 "PN", /* Pitcairn */
5361 /* Rota Island (Z1 duplicate) */
5362 /* Saipan (Z1 duplicate) */
5363 "SH", /* Saint Helena */
5364 "GS", /* South Georgia and The South Sandwich Islands */
5365 "SD", /* Sudan */
5366 "SJ", /* Svalbard and Jan Mayen */
5367 "TL", /* Timor-leste (East Timor) */
5368 /* Tinian Island (Z1 duplicate) */
5369 "TK", /* Tokelau */
5370 "TA", /* Tristan Da Cunha */
5371 /* Wake Island (Z1 duplicate) */
5372 "YU", /* Yugoslavia */
5375 /* Regulatory Revision mapping support for aggregate country definitions */
5376 struct wlc_cc_map {
5377 char cc[WLC_CNTRY_BUF_SZ];
5378 char mapped_cc[WLC_CNTRY_BUF_SZ];
5379 uint8 mapped_rev;
5382 struct wlc_aggregate_cc_map_lookup {
5383 char cc[WLC_CNTRY_BUF_SZ];
5384 uint8 rev;
5385 const struct wlc_cc_map *map;
5388 static const struct wlc_cc_map cc_map_ww1[] = {
5389 {"US", "US", 1},
5390 {"JP", "JP", 1},
5391 {"KR", "KR", 1},
5392 {"BN", "BN", 1},
5393 {"CA", "CA", 1},
5394 {"MX", "MX", 1},
5395 {"RU", "RU", 1},
5396 {"TW", "TW", 1},
5397 {"AE", "AE", 1},
5398 {"AU", "AU", 2},
5399 {"", "", 0}
5402 static const struct wlc_cc_map cc_map_ww1_1[] = {
5403 {"XV", "XV", 1},
5404 {"US", "US", 1},
5405 {"JP", "JP", 1},
5406 {"KR", "KR", 1},
5407 {"BN", "BN", 1},
5408 {"CA", "CA", 1},
5409 {"MX", "MX", 1},
5410 {"RU", "RU", 1},
5411 {"TW", "TW", 1},
5412 {"AE", "AE", 1},
5413 {"AU", "AU", 2},
5414 {"", "", 0}
5418 static const struct wlc_cc_map cc_map_ww2[] = {
5419 {"XV", "XV", 1},
5420 {"US", "US", 5},
5421 {"JP", "JP", 3},
5422 {"KR", "KR", 3},
5423 {"BN", "BN", 1},
5424 {"CA", "CA", 2},
5425 {"MX", "MX", 1},
5426 {"RU", "RU", 1},
5427 {"TW", "TW", 2},
5428 {"AE", "AE", 1},
5429 {"KW", "KW", 1},
5430 {"", "", 0}
5433 static const struct wlc_cc_map cc_map_DE1[] = {
5434 {"US", "US", 1},
5435 {"JP", "JP", 1},
5436 {"", "", 0}
5439 static const struct wlc_cc_map cc_map_DE2[] = {
5440 {"US", "US", 5},
5441 {"JP", "JP", 5},
5442 {"KR", "KR", 3},
5443 {"BN", "BN", 1},
5444 {"CA", "CA", 2},
5445 {"MX", "MX", 1},
5446 {"RU", "RU", 1},
5447 {"TW", "TW", 2},
5448 {"AE", "AE", 1},
5449 {"KW", "KW", 1},
5450 {"", "", 0}
5453 static const struct wlc_cc_map cc_map_XA1[] = {
5454 {"US", "US", 1},
5455 {"JP", "JP", 1},
5456 {"KR", "KR", 2},
5457 {"BN", "BN", 1},
5458 {"MX", "MX", 1},
5459 {"RU", "RU", 1},
5460 {"AE", "AE", 1},
5461 {"", "", 0}
5464 static const struct wlc_cc_map cc_map_X_1[] = {
5465 {"US", "US", 1},
5466 {"JP", "JP", 1},
5467 {"KR", "KR", 2},
5468 {"BN", "BN", 1},
5469 {"MX", "MX", 1},
5470 {"RU", "RU", 1},
5471 {"AE", "AE", 1},
5472 {"", "", 0}
5475 static const struct wlc_cc_map cc_map_X_2[] = {
5476 {"US", "US", 10},
5477 {"JP", "JP", 3},
5478 {"KR", "KR", 3},
5479 {"CA", "CA", 2},
5480 {"BN", "BN", 1},
5481 {"MX", "MX", 1},
5482 {"RU", "RU", 1},
5483 {"TW", "TW", 2},
5484 {"AE", "AE", 1},
5485 {"", "", 0}
5488 static const struct wlc_cc_map cc_map_X_3[] = {
5489 {"US", "US", 10},
5490 {"JP", "JP", 4},
5491 {"KR", "KR", 3},
5492 {"CA", "CA", 2},
5493 {"BN", "BN", 1},
5494 {"MX", "MX", 1},
5495 {"RU", "RU", 1},
5496 {"TW", "TW", 1},
5497 {"AE", "AE", 1},
5498 {"", "", 0}
5501 static const struct wlc_cc_map cc_map_X_4[] = {
5502 {"US", "US", 10},
5503 {"JP", "JP", 3},
5504 {"KR", "KR", 3},
5505 {"CA", "CA", 2},
5506 {"BN", "BN", 1},
5507 {"MX", "MX", 1},
5508 {"RU", "RU", 1},
5509 {"TW", "TW", 3},
5510 {"AE", "AE", 1},
5511 {"", "", 0}
5514 static const struct wlc_cc_map cc_map_X_5[] = {
5515 {"US", "US", 16},
5516 {"JP", "JP", 6},
5517 {"KR", "KR", 4},
5518 {"BN", "BN", 1},
5519 {"CA", "CA", 2},
5520 {"MX", "MX", 1},
5521 {"RU", "RU", 2},
5522 {"TW", "TW", 3},
5523 {"AE", "AE", 1},
5524 {"AR", "AR", 1},
5525 {"PY", "PY", 1},
5526 {"AT", "AT", 1},
5527 {"BE", "BE", 1},
5528 {"BG", "BG", 1},
5529 {"HR", "HR", 1},
5530 {"CY", "CY", 1},
5531 {"CZ", "CZ", 1},
5532 {"DK", "DK", 1},
5533 {"EE", "EE", 1},
5534 {"FI", "FI", 1},
5535 {"FR", "FR", 1},
5536 {"DE", "DE", 3},
5537 {"GR", "GR", 1},
5538 {"HU", "HU", 1},
5539 {"IS", "IS", 1},
5540 {"IE", "IE", 1},
5541 {"IT", "IT", 1},
5542 {"LV", "LV", 1},
5543 {"LI", "LI", 1},
5544 {"LT", "LT", 1},
5545 {"LU", "LU", 1},
5546 {"MT", "MT", 1},
5547 {"NL", "NL", 1},
5548 {"NO", "NO", 1},
5549 {"PL", "PL", 1},
5550 {"PT", "PT", 1},
5551 {"RO", "RO", 1},
5552 {"SK", "SK", 1},
5553 {"SI", "SI", 1},
5554 {"ES", "ES", 1},
5555 {"SE", "SE", 1},
5556 {"CH", "CH", 1},
5557 {"GB", "GB", 1},
5558 {"", "", 0}
5561 static const struct wlc_cc_map cc_map_X_6[] = {
5562 {"US", "US", 29},
5563 {"JP", "JP", 7},
5564 {"KR", "KR", 6},
5565 {"BN", "BN", 1},
5566 {"CA", "CA", 2},
5567 {"MX", "MX", 1},
5568 {"RU", "RU", 2},
5569 {"TW", "TW", 3},
5570 {"AE", "AE", 1},
5571 {"AR", "AR", 1},
5572 {"PY", "PY", 1},
5573 {"AT", "AT", 1},
5574 {"BE", "BE", 1},
5575 {"BG", "BG", 1},
5576 {"HR", "HR", 1},
5577 {"CY", "CY", 1},
5578 {"CZ", "CZ", 1},
5579 {"DK", "DK", 1},
5580 {"EE", "EE", 1},
5581 {"FI", "FI", 1},
5582 {"FR", "FR", 1},
5583 {"DE", "DE", 3},
5584 {"GR", "GR", 1},
5585 {"HU", "HU", 1},
5586 {"IS", "IS", 1},
5587 {"IE", "IE", 1},
5588 {"IT", "IT", 1},
5589 {"LV", "LV", 1},
5590 {"LI", "LI", 1},
5591 {"LT", "LT", 1},
5592 {"LU", "LU", 1},
5593 {"MT", "MT", 1},
5594 {"NL", "NL", 1},
5595 {"NO", "NO", 1},
5596 {"PL", "PL", 1},
5597 {"PT", "PT", 1},
5598 {"RO", "RO", 1},
5599 {"SK", "SK", 1},
5600 {"SI", "SI", 1},
5601 {"ES", "ES", 1},
5602 {"SE", "SE", 1},
5603 {"CH", "CH", 1},
5604 {"GB", "GB", 1},
5605 {"", "", 0}
5608 static const struct wlc_cc_map cc_map_X_7[] = {
5609 {"US", "US", 50},
5610 {"JP", "JP", 12},
5611 {"KR", "KR", 10},
5612 {"BN", "BN", 1},
5613 {"CA", "CA", 11},
5614 {"MX", "MX", 2},
5615 {"MA", "MA", 0},
5616 {"RU", "RU", 3},
5617 {"TW", "TW", 4},
5618 {"AE", "AE", 3},
5619 {"UA", "UA", 3},
5620 {"KW", "KW", 3},
5621 {"AU", "AU", 2},
5622 {"CN", "CN", 3},
5623 {"IL", "IL", 2},
5624 {"PH", "PH", 2},
5625 {"ZA", "ZA", 2},
5626 {"ID", "ID", 2},
5627 {"PK", "PK", 1},
5628 {"VN", "VN", 1},
5629 {"SA", "SA", 2},
5630 {"MV", "MV", 1},
5631 {"AR", "AR", 4},
5632 {"BR", "BR", 1},
5633 {"CR", "CR", 1},
5634 {"CL", "CL", 2},
5635 {"CO", "CO", 1},
5636 {"EC", "EC", 1},
5637 {"SV", "SV", 1},
5638 {"PA", "PA", 1},
5639 {"PY", "PY", 1},
5640 {"PE", "PE", 2},
5641 {"PR", "PR", 2},
5642 {"VE", "VE", 1},
5643 {"AT", "AT", 2},
5644 {"BE", "BE", 2},
5645 {"BG", "BG", 2},
5646 {"HR", "HR", 2},
5647 {"CY", "CY", 2},
5648 {"CZ", "CZ", 2},
5649 {"DK", "DK", 2},
5650 {"EE", "EE", 2},
5651 {"FI", "FI", 2},
5652 {"FR", "FR", 2},
5653 {"DE", "DE", 5},
5654 {"GR", "GR", 2},
5655 {"HU", "HU", 2},
5656 {"IS", "IS", 2},
5657 {"IE", "IE", 2},
5658 {"IT", "IT", 2},
5659 {"LV", "LV", 2},
5660 {"LI", "LI", 2},
5661 {"LT", "LT", 2},
5662 {"LU", "LU", 2},
5663 {"MT", "MT", 2},
5664 {"NL", "NL", 2},
5665 {"NO", "NO", 2},
5666 {"PL", "PL", 2},
5667 {"PT", "PT", 2},
5668 {"RO", "RO", 2},
5669 {"SK", "SK", 2},
5670 {"SI", "SI", 2},
5671 {"ES", "ES", 2},
5672 {"SE", "SE", 1},
5673 {"CH", "CH", 1},
5674 {"GB", "GB", 1},
5675 {"TR", "TR", 3},
5676 {"BY", "BY", 1},
5677 {"", "", 0}
5681 static const struct wlc_cc_map cc_map_US12[] = {
5682 {"US", "US", 12},
5683 {"JP", "JP", 1},
5684 {"", "", 0}
5687 static const struct wlc_cc_map cc_map_US16[] = {
5688 {"JP", "JP", 3},
5689 {"KR", "KR", 4},
5690 {"BN", "BN", 1},
5691 {"CA", "CA", 2},
5692 {"MX", "MX", 1},
5693 {"MA", "MA", 1},
5694 {"RU", "RU", 1},
5695 {"TW", "TW", 2},
5696 {"AE", "AE", 1},
5697 {"KW", "KW", 1},
5698 {"AT", "AT", 1},
5699 {"BE", "BE", 1},
5700 {"BG", "BG", 1},
5701 {"HR", "HR", 1},
5702 {"CY", "CY", 1},
5703 {"CZ", "CZ", 1},
5704 {"DK", "DK", 1},
5705 {"EE", "EE", 1},
5706 {"FI", "FI", 1},
5707 {"FR", "FR", 1},
5708 {"DE", "DE", 3},
5709 {"GR", "GR", 1},
5710 {"HU", "HU", 1},
5711 {"IS", "IS", 1},
5712 {"IE", "IE", 1},
5713 {"IT", "IT", 1},
5714 {"LV", "LV", 1},
5715 {"LI", "LI", 1},
5716 {"LT", "LT", 1},
5717 {"LU", "LU", 1},
5718 {"MT", "MT", 1},
5719 {"NL", "NL", 1},
5720 {"NO", "NO", 1},
5721 {"PL", "PL", 1},
5722 {"PT", "PT", 1},
5723 {"RO", "RO", 1},
5724 {"SK", "SK", 1},
5725 {"SI", "SI", 1},
5726 {"ES", "ES", 1},
5727 {"SE", "SE", 1},
5728 {"CH", "CH", 1},
5729 {"GB", "GB", 1},
5730 {"", "", 0}
5733 static const struct wlc_cc_map cc_map_US25[] = {
5734 {"US", "US", 25},
5735 {"JP", "JP", 3},
5736 {"KR", "KR", 4},
5737 {"BN", "BN", 1},
5738 {"CA", "CA", 2},
5739 {"MX", "MX", 1},
5740 {"MA", "MA", 1},
5741 {"RU", "RU", 1},
5742 {"TW", "TW", 2},
5743 {"AE", "AE", 1},
5744 {"KW", "KW", 1},
5745 {"AR", "AR", 1},
5746 {"PY", "PY", 1},
5747 {"AT", "AT", 1},
5748 {"BE", "BE", 1},
5749 {"BG", "BG", 1},
5750 {"HR", "HR", 1},
5751 {"CY", "CY", 1},
5752 {"CZ", "CZ", 1},
5753 {"DK", "DK", 1},
5754 {"EE", "EE", 1},
5755 {"FI", "FI", 1},
5756 {"FR", "FR", 1},
5757 {"DE", "DE", 3},
5758 {"GR", "GR", 1},
5759 {"HU", "HU", 1},
5760 {"IS", "IS", 1},
5761 {"IE", "IE", 1},
5762 {"IT", "IT", 1},
5763 {"LV", "LV", 1},
5764 {"LI", "LI", 1},
5765 {"LT", "LT", 1},
5766 {"LU", "LU", 1},
5767 {"MT", "MT", 1},
5768 {"NL", "NL", 1},
5769 {"NO", "NO", 1},
5770 {"PL", "PL", 1},
5771 {"PT", "PT", 1},
5772 {"RO", "RO", 1},
5773 {"SK", "SK", 1},
5774 {"SI", "SI", 1},
5775 {"ES", "ES", 1},
5776 {"SE", "SE", 1},
5777 {"CH", "CH", 1},
5778 {"GB", "GB", 1},
5779 {"", "", 0}
5782 static const struct wlc_cc_map cc_map_ww4[] = {
5783 {"XV", "XV", 1},
5784 {"US", "US", 25},
5785 {"JP", "JP", 3},
5786 {"KR", "KR", 4},
5787 {"BN", "BN", 1},
5788 {"CA", "CA", 2},
5789 {"MX", "MX", 1},
5790 {"MA", "MA", 1},
5791 {"RU", "RU", 1},
5792 {"TW", "TW", 2},
5793 {"AE", "AE", 1},
5794 {"KW", "KW", 1},
5795 {"AR", "AR", 1},
5796 {"PY", "PY", 1},
5797 {"AT", "AT", 1},
5798 {"BE", "BE", 1},
5799 {"BG", "BG", 1},
5800 {"HR", "HR", 1},
5801 {"CY", "CY", 1},
5802 {"CZ", "CZ", 1},
5803 {"DK", "DK", 1},
5804 {"EE", "EE", 1},
5805 {"FI", "FI", 1},
5806 {"FR", "FR", 1},
5807 {"DE", "DE", 3},
5808 {"GR", "GR", 1},
5809 {"HU", "HU", 1},
5810 {"IS", "IS", 1},
5811 {"IE", "IE", 1},
5812 {"IT", "IT", 1},
5813 {"LV", "LV", 1},
5814 {"LI", "LI", 1},
5815 {"LT", "LT", 1},
5816 {"LU", "LU", 1},
5817 {"MT", "MT", 1},
5818 {"NL", "NL", 1},
5819 {"NO", "NO", 1},
5820 {"PL", "PL", 1},
5821 {"PT", "PT", 1},
5822 {"RO", "RO", 1},
5823 {"SK", "SK", 1},
5824 {"SI", "SI", 1},
5825 {"ES", "ES", 1},
5826 {"SE", "SE", 1},
5827 {"CH", "CH", 1},
5828 {"GB", "GB", 1},
5829 {"", "", 0}
5833 static struct wlc_cc_map cc_map_US33[] = {
5834 {"US", "US", 33},
5835 {"", "", 0}
5838 static const struct wlc_cc_map cc_map_ww3[] = {
5839 {"XV", "XV", 1},
5840 {"US", "US", 16},
5841 {"JP", "JP", 3},
5842 {"KR", "KR", 4},
5843 {"BN", "BN", 1},
5844 {"CA", "CA", 2},
5845 {"MX", "MX", 1},
5846 {"MA", "MA", 1},
5847 {"RU", "RU", 1},
5848 {"TW", "TW", 2},
5849 {"AE", "AE", 1},
5850 {"KW", "KW", 1},
5851 {"AT", "AT", 1},
5852 {"BE", "BE", 1},
5853 {"BG", "BG", 1},
5854 {"HR", "HR", 1},
5855 {"CY", "CY", 1},
5856 {"CZ", "CZ", 1},
5857 {"DK", "DK", 1},
5858 {"EE", "EE", 1},
5859 {"FI", "FI", 1},
5860 {"FR", "FR", 1},
5861 {"DE", "DE", 3},
5862 {"GR", "GR", 1},
5863 {"HU", "HU", 1},
5864 {"IS", "IS", 1},
5865 {"IE", "IE", 1},
5866 {"IT", "IT", 1},
5867 {"LV", "LV", 1},
5868 {"LI", "LI", 1},
5869 {"LT", "LT", 1},
5870 {"LU", "LU", 1},
5871 {"MT", "MT", 1},
5872 {"NL", "NL", 1},
5873 {"NO", "NO", 1},
5874 {"PL", "PL", 1},
5875 {"PT", "PT", 1},
5876 {"RO", "RO", 1},
5877 {"SK", "SK", 1},
5878 {"SI", "SI", 1},
5879 {"ES", "ES", 1},
5880 {"SE", "SE", 1},
5881 {"CH", "CH", 1},
5882 {"GB", "GB", 1},
5883 {"", "", 0}
5886 static const struct wlc_cc_map cc_map_DE3[] = {
5887 {"US", "US", 16},
5888 {"JP", "JP", 5},
5889 {"KR", "KR", 4},
5890 {"BN", "BN", 1},
5891 {"CA", "CA", 2},
5892 {"MX", "MX", 1},
5893 {"MA", "MA", 1},
5894 {"RU", "RU", 1},
5895 {"TW", "TW", 2},
5896 {"AE", "AE", 1},
5897 {"KW", "KW", 1},
5898 {"AT", "AT", 1},
5899 {"BE", "BE", 1},
5900 {"BG", "BG", 1},
5901 {"HR", "HR", 1},
5902 {"CY", "CY", 1},
5903 {"CZ", "CZ", 1},
5904 {"DK", "DK", 1},
5905 {"EE", "EE", 1},
5906 {"FI", "FI", 1},
5907 {"FR", "FR", 1},
5908 {"DE", "DE", 3},
5909 {"GR", "GR", 1},
5910 {"HU", "HU", 1},
5911 {"IS", "IS", 1},
5912 {"IE", "IE", 1},
5913 {"IT", "IT", 1},
5914 {"LV", "LV", 1},
5915 {"LI", "LI", 1},
5916 {"LT", "LT", 1},
5917 {"LU", "LU", 1},
5918 {"MT", "MT", 1},
5919 {"NL", "NL", 1},
5920 {"NO", "NO", 1},
5921 {"PL", "PL", 1},
5922 {"PT", "PT", 1},
5923 {"RO", "RO", 1},
5924 {"SK", "SK", 1},
5925 {"SI", "SI", 1},
5926 {"ES", "ES", 1},
5927 {"SE", "SE", 1},
5928 {"CH", "CH", 1},
5929 {"GB", "GB", 1},
5930 {"", "", 0}
5933 static const struct wlc_cc_map cc_map_US17[] = {
5934 {"US", "US", 17},
5935 {"JP", "JP", 3},
5936 {"KR", "KR", 4},
5937 {"BN", "BN", 1},
5938 {"CA", "CA", 2},
5939 {"MX", "MX", 1},
5940 {"MA", "MA", 1},
5941 {"RU", "RU", 1},
5942 {"TW", "TW", 2},
5943 {"AE", "AE", 1},
5944 {"UA", "UA", 0},
5945 {"KW", "KW", 1},
5946 {"AT", "AT", 1},
5947 {"BE", "BE", 1},
5948 {"BG", "BG", 1},
5949 {"HR", "HR", 1},
5950 {"CY", "CY", 1},
5951 {"CZ", "CZ", 1},
5952 {"DK", "DK", 1},
5953 {"EE", "EE", 1},
5954 {"FI", "FI", 1},
5955 {"FR", "FR", 1},
5956 {"DE", "DE", 3},
5957 {"GR", "GR", 1},
5958 {"HU", "HU", 1},
5959 {"IS", "IS", 1},
5960 {"IE", "IE", 1},
5961 {"IT", "IT", 1},
5962 {"LV", "LV", 1},
5963 {"LI", "LI", 1},
5964 {"LT", "LT", 1},
5965 {"LU", "LU", 1},
5966 {"MT", "MT", 1},
5967 {"NL", "NL", 1},
5968 {"NO", "NO", 1},
5969 {"PL", "PL", 1},
5970 {"PT", "PT", 1},
5971 {"RO", "RO", 1},
5972 {"SK", "SK", 1},
5973 {"SI", "SI", 1},
5974 {"ES", "ES", 1},
5975 {"SE", "SE", 1},
5976 {"CH", "CH", 1},
5977 {"GB", "GB", 1},
5978 {"", "", 0}
5981 static const struct wlc_cc_map cc_map_XZ_2[] = {
5982 {"US", "US", 34},
5983 {"JP", "JP", 8},
5984 {"KR", "KR", 8},
5985 {"BN", "BN", 2},
5986 {"CA", "CA", 6},
5987 {"MX", "MX", 1},
5988 {"MA", "MA", 1},
5989 {"RU", "RU", 1},
5990 {"TW", "TW", 3},
5991 {"AE", "AE", 1},
5992 {"KW", "KW", 1},
5993 {"AU", "AU", 1},
5994 {"SG", "SG", 2},
5995 {"IN", "IN", 1},
5996 {"MY", "MY", 1},
5997 {"NP", "NP", 1},
5998 {"CN", "CN", 1},
5999 {"AR", "AR", 2},
6000 {"PY", "PY", 1},
6001 {"AT", "AT", 1},
6002 {"BE", "BE", 1},
6003 {"BG", "BG", 1},
6004 {"HR", "HR", 1},
6005 {"CY", "CY", 1},
6006 {"CZ", "CZ", 1},
6007 {"DK", "DK", 1},
6008 {"EE", "EE", 1},
6009 {"FI", "FI", 1},
6010 {"FR", "FR", 1},
6011 {"DE", "DE", 3},
6012 {"GR", "GR", 1},
6013 {"HU", "HU", 1},
6014 {"IS", "IS", 1},
6015 {"IE", "IE", 1},
6016 {"IT", "IT", 1},
6017 {"LV", "LV", 1},
6018 {"LI", "LI", 1},
6019 {"LT", "LT", 1},
6020 {"LU", "LU", 1},
6021 {"MT", "MT", 1},
6022 {"NL", "NL", 1},
6023 {"NO", "NO", 1},
6024 {"PL", "PL", 1},
6025 {"PT", "PT", 1},
6026 {"RO", "RO", 1},
6027 {"SK", "SK", 1},
6028 {"SI", "SI", 1},
6029 {"ES", "ES", 1},
6030 {"SE", "SE", 1},
6031 {"CH", "CH", 1},
6032 {"GB", "GB", 1},
6033 {"", "", 0}
6036 static const struct wlc_aggregate_cc_map_lookup aggregate_cc_maps[] = {
6037 {"XA", 1, cc_map_XA1},
6038 {"X0", 1, cc_map_X_1},
6039 {"X1", 1, cc_map_X_1},
6040 {"X2", 1, cc_map_X_1},
6041 {"X3", 1, cc_map_X_1},
6042 {"X0", 2, cc_map_X_2},
6043 {"X1", 2, cc_map_X_2},
6044 {"X2", 2, cc_map_X_2},
6045 {"X3", 2, cc_map_X_2},
6046 {"X0", 3, cc_map_X_3},
6047 {"X1", 3, cc_map_X_4},
6048 {"X2", 3, cc_map_X_4},
6049 {"X3", 3, cc_map_X_4},
6050 {"X0", 4, cc_map_X_4},
6051 {"X0", 5, cc_map_X_5},
6052 {"X1", 4, cc_map_X_5},
6053 {"X2", 4, cc_map_X_5},
6054 {"X3", 4, cc_map_X_5},
6055 {"X0", 6, cc_map_X_6},
6056 {"X1", 5, cc_map_X_6},
6057 {"X2", 5, cc_map_X_6},
6058 {"X3", 5, cc_map_X_6},
6059 {"ww", 1, cc_map_ww1_1}, /* "ww" means SROM cc = \0\0 */
6060 {"X1", 6, cc_map_X_7},
6061 {"X2", 6, cc_map_X_7},
6062 {"X3", 6, cc_map_X_7},
6063 {"X0", 7, cc_map_X_7},
6064 {"X0", 8, cc_map_X_7}, /* placeholder for X0/8 4331 */
6065 {"US", 1, cc_map_ww1},
6066 {"IT", 1, cc_map_ww1},
6067 {"JP", 1, cc_map_ww1},
6068 {"CN", 1, cc_map_ww1},
6069 {"ID", 1, cc_map_ww1},
6070 {"GB", 1, cc_map_ww1},
6071 {"DE", 1, cc_map_DE1},
6072 {"US", 12, cc_map_US12},
6073 {"DE", 2, cc_map_DE2},
6074 {"ww", 2, cc_map_ww2}, /* "ww" means SROM cc = \0\0 */
6075 {"TR", 1, cc_map_DE2},
6076 {"ww", 3, cc_map_ww3}, /* "ww" means SROM cc = \0\0 */
6077 {"DE", 3, cc_map_DE3},
6078 {"US", 16, cc_map_US16},
6079 {"US", 17, cc_map_US17},
6080 {"US", 25, cc_map_US25},
6081 {"ww", 4, cc_map_ww4}, /* "ww" means SROM cc = \0\0 */
6082 {"ww", 5, cc_map_US33}, /* "ww" means SROM cc = \0\0 */
6083 {"XZ", 2, cc_map_XZ_2},
6084 {"", 0, NULL}
6087 /* 20MHz channel info for 40MHz pairing support */
6089 struct chan20_info {
6090 uint8 sb;
6091 uint8 adj_sbs;
6094 /* indicates adjacent channels that are allowed for a 40 Mhz channel and
6095 * those that permitted by the HT
6097 struct chan20_info chan20_info[] = {
6098 /* 11b/11g */
6099 /* 0 */ {1, (CH_UPPER_SB | CH_EWA_VALID)},
6100 /* 1 */ {2, (CH_UPPER_SB | CH_EWA_VALID)},
6101 /* 2 */ {3, (CH_UPPER_SB | CH_EWA_VALID)},
6102 /* 3 */ {4, (CH_UPPER_SB | CH_EWA_VALID)},
6103 /* 4 */ {5, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
6104 /* 5 */ {6, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
6105 /* 6 */ {7, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
6106 /* 7 */ {8, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
6107 /* 8 */ {9, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
6108 /* 9 */ {10, (CH_LOWER_SB | CH_EWA_VALID)},
6109 /* 10 */ {11, (CH_LOWER_SB | CH_EWA_VALID)},
6110 /* 11 */ {12, (CH_LOWER_SB)},
6111 /* 12 */ {13, (CH_LOWER_SB)},
6112 /* 13 */ {14, (CH_LOWER_SB)},
6114 /* 11a japan high */
6115 /* 14 */ {34, (CH_UPPER_SB)},
6116 /* 15 */ {38, (CH_LOWER_SB)},
6117 /* 16 */ {42, (CH_LOWER_SB)},
6118 /* 17 */ {46, (CH_LOWER_SB)},
6120 /* 11a usa low */
6121 /* 18 */ {36, (CH_UPPER_SB | CH_EWA_VALID)},
6122 /* 19 */ {40, (CH_LOWER_SB | CH_EWA_VALID)},
6123 /* 20 */ {44, (CH_UPPER_SB | CH_EWA_VALID)},
6124 /* 21 */ {48, (CH_LOWER_SB | CH_EWA_VALID)},
6125 /* 22 */ {52, (CH_UPPER_SB | CH_EWA_VALID)},
6126 /* 23 */ {56, (CH_LOWER_SB | CH_EWA_VALID)},
6127 /* 24 */ {60, (CH_UPPER_SB | CH_EWA_VALID)},
6128 /* 25 */ {64, (CH_LOWER_SB | CH_EWA_VALID)},
6130 /* 11a Europe */
6131 /* 26 */ {100, (CH_UPPER_SB | CH_EWA_VALID)},
6132 /* 27 */ {104, (CH_LOWER_SB | CH_EWA_VALID)},
6133 /* 28 */ {108, (CH_UPPER_SB | CH_EWA_VALID)},
6134 /* 29 */ {112, (CH_LOWER_SB | CH_EWA_VALID)},
6135 /* 30 */ {116, (CH_UPPER_SB | CH_EWA_VALID)},
6136 /* 31 */ {120, (CH_LOWER_SB | CH_EWA_VALID)},
6137 /* 32 */ {124, (CH_UPPER_SB | CH_EWA_VALID)},
6138 /* 33 */ {128, (CH_LOWER_SB | CH_EWA_VALID)},
6139 /* 34 */ {132, (CH_UPPER_SB | CH_EWA_VALID)},
6140 /* 35 */ {136, (CH_LOWER_SB | CH_EWA_VALID)},
6141 /* 36 */ {140, (CH_LOWER_SB)},
6143 /* 11a usa high, ref5 only */
6144 /* The 0x80 bit in pdiv means these are REF5, other entries are REF20 */
6145 /* 37 */ {149, (CH_UPPER_SB | CH_EWA_VALID)},
6146 /* 38 */ {153, (CH_LOWER_SB | CH_EWA_VALID)},
6147 /* 39 */ {157, (CH_UPPER_SB | CH_EWA_VALID)},
6148 /* 40 */ {161, (CH_LOWER_SB | CH_EWA_VALID)},
6149 /* 41 */ {165, (CH_LOWER_SB)},
6151 /* 11a japan */
6152 /* 42 */ {184, (CH_UPPER_SB)},
6153 /* 43 */ {188, (CH_LOWER_SB)},
6154 /* 44 */ {192, (CH_UPPER_SB)},
6155 /* 45 */ {196, (CH_LOWER_SB)},
6156 /* 46 */ {200, (CH_UPPER_SB)},
6157 /* 47 */ {204, (CH_LOWER_SB)},
6158 /* 48 */ {208, (CH_UPPER_SB)},
6159 /* 49 */ {212, (CH_LOWER_SB)},
6160 /* 50 */ {216, (CH_LOWER_SB)}
6163 /* country code mapping for SPROM rev 1 */
6164 static const char def_country[][WLC_CNTRY_BUF_SZ] = {
6165 "AU", /* Worldwide */
6166 "TH", /* Thailand */
6167 "IL", /* Israel */
6168 "JO", /* Jordan */
6169 "CN", /* China */
6170 "JP", /* Japan */
6171 "US", /* USA */
6172 "DE", /* Europe */
6173 "US", /* US Low Band, use US */
6174 "JP", /* Japan High Band, use Japan */
6177 /* autocountry default country code list */
6178 static const char def_autocountry[][WLC_CNTRY_BUF_SZ] = {
6179 "XY",
6180 "XA",
6181 "XB",
6182 "X0",
6183 "X1",
6184 "X2",
6185 "X3",
6186 "XS",
6187 "XV"
6191 const locale_info_t * wlc_get_locale_2g(uint8 locale_idx)
6193 #ifdef BAND2G
6194 if (locale_idx >= ARRAYSIZE(g_locale_2g_table)) {
6195 WL_ERROR(("wl%d: locale 2g index size out of range\n", locale_idx));
6196 return NULL;
6198 return g_locale_2g_table[locale_idx];
6199 #else
6200 return NULL;
6201 #endif
6204 const locale_info_t * wlc_get_locale_5g(uint8 locale_idx)
6206 #ifdef BAND5G
6207 if (locale_idx >= ARRAYSIZE(g_locale_5g_table)) {
6208 WL_ERROR(("wl%d: locale 5g index size out of range\n", locale_idx));
6209 return NULL;
6211 return g_locale_5g_table[locale_idx];
6212 #else
6213 return NULL;
6214 #endif
6217 #ifdef WL11N
6218 const locale_mimo_info_t * wlc_get_mimo_2g(uint8 locale_idx)
6220 if (locale_idx >= ARRAYSIZE(g_mimo_2g_table)) {
6221 WL_ERROR(("wl%d: mimo 2g index size out of range\n", locale_idx));
6222 return NULL;
6224 return g_mimo_2g_table[locale_idx];
6227 const locale_mimo_info_t * wlc_get_mimo_5g(uint8 locale_idx)
6229 if (locale_idx >= ARRAYSIZE(g_mimo_5g_table)) {
6230 WL_ERROR(("wl%d: mimo 5g index size out of range\n", locale_idx));
6231 return NULL;
6233 return g_mimo_5g_table[locale_idx];
6235 #endif /* #ifdef WL11N */
6237 static bool
6238 wlc_autocountry_lookup(char *cc)
6240 uint i;
6242 for (i = 0; i < ARRAYSIZE(def_autocountry); i++)
6243 if (!strcmp(def_autocountry[i], cc))
6244 return TRUE;
6246 return FALSE;
6249 wlc_cm_info_t *
6250 BCMATTACHFN(wlc_channel_mgr_attach)(wlc_info_t *wlc)
6252 wlc_cm_info_t *wlc_cm;
6253 char country_abbrev[WLC_CNTRY_BUF_SZ];
6254 const country_info_t *country;
6255 wlc_pub_t *pub = wlc->pub;
6256 #ifdef PCOEM_LINUXSTA
6257 bool use_row = TRUE;
6258 #endif
6260 WL_TRACE(("wl%d: wlc_channel_mgr_attach\n", wlc->pub->unit));
6262 if ((wlc_cm = (wlc_cm_info_t *)MALLOC(pub->osh, sizeof(wlc_cm_info_t))) == NULL) {
6263 WL_ERROR(("wl%d: %s: out of memory, malloced %d bytes", pub->unit,
6264 __FUNCTION__, MALLOCED(pub->osh)));
6265 return NULL;
6267 bzero((char *)wlc_cm, sizeof(wlc_cm_info_t));
6268 wlc_cm->pub = pub;
6269 wlc_cm->wlc = wlc;
6270 wlc->cmi = wlc_cm;
6272 /* init the per chain limits to max power so they have not effect */
6273 memset(&wlc_cm->bandstate[BAND_2G_INDEX].chain_limits, WLC_TXPWR_MAX,
6274 sizeof(struct wlc_channel_txchain_limits));
6275 memset(&wlc_cm->bandstate[BAND_5G_INDEX].chain_limits, WLC_TXPWR_MAX,
6276 sizeof(struct wlc_channel_txchain_limits));
6278 /* get the SPROM country code or local, required to initialize channel set below */
6279 bzero(country_abbrev, WLC_CNTRY_BUF_SZ);
6280 if (wlc->pub->sromrev > 1) {
6281 /* get country code */
6282 char *ccode = getvar(wlc->pub->vars, "ccode");
6283 if (ccode)
6284 strncpy(country_abbrev, ccode, WLC_CNTRY_BUF_SZ - 1);
6285 } else {
6286 uint locale_num;
6288 /* get locale */
6289 locale_num = (uint)getintvar(wlc->pub->vars, "cc");
6290 /* get mapped country */
6291 if (locale_num < ARRAYSIZE(def_country))
6292 strncpy(country_abbrev, def_country[locale_num],
6293 sizeof(country_abbrev) - 1);
6295 strncpy(wlc_cm->srom_ccode, country_abbrev, WLC_CNTRY_BUF_SZ - 1);
6296 wlc_cm->srom_regrev = getintvar(wlc->pub->vars, "regrev");
6298 /* For "some" apple boards with KR2, make them as KR3 as they have passed the
6299 * FCC test but with wrong SROM contents
6301 if ((pub->sih->boardvendor == VENDOR_APPLE) &&
6302 ((pub->sih->boardtype == BCM943224M93) ||
6303 (pub->sih->boardtype == BCM943224M93A))) {
6304 if ((wlc_cm->srom_regrev == 2) &&
6305 !strncmp(country_abbrev, "KR", WLC_CNTRY_BUF_SZ)) {
6306 wlc_cm->srom_regrev = 3;
6310 /* Correct SROM contents of an Apple board */
6311 if ((pub->sih->boardvendor == VENDOR_APPLE) &&
6312 (pub->sih->boardtype == 0x93) &&
6313 !strncmp(country_abbrev, "JP", WLC_CNTRY_BUF_SZ) &&
6314 (wlc_cm->srom_regrev == 4)) {
6315 wlc_cm->srom_regrev = 6;
6318 country = wlc_country_lookup(wlc, country_abbrev);
6320 /* default to US if country was not specified or not found */
6321 if (country == NULL) {
6322 strncpy(country_abbrev, "US", sizeof(country_abbrev) - 1);
6323 country = wlc_country_lookup(wlc, country_abbrev);
6326 ASSERT(country != NULL);
6328 /* save default country for exiting 11d regulatory mode */
6329 strncpy(wlc->country_default, country_abbrev, WLC_CNTRY_BUF_SZ - 1);
6331 /* initialize autocountry_default to driver default */
6332 if (wlc_autocountry_lookup(country_abbrev))
6333 strncpy(wlc->autocountry_default, country_abbrev, WLC_CNTRY_BUF_SZ - 1);
6334 else
6335 strncpy(wlc->autocountry_default, "B2", WLC_CNTRY_BUF_SZ - 1);
6337 #ifdef PCOEM_LINUXSTA
6338 if ((CHIPID(pub->sih->chip) != BCM4311_CHIP_ID) &&
6339 (CHIPID(pub->sih->chip) != BCM4312_CHIP_ID) &&
6340 (CHIPID(pub->sih->chip) != BCM4313_CHIP_ID) &&
6341 (CHIPID(pub->sih->chip) != BCM4321_CHIP_ID) &&
6342 (CHIPID(pub->sih->chip) != BCM4322_CHIP_ID) &&
6343 (CHIPID(pub->sih->chip) != BCM43224_CHIP_ID) &&
6344 (CHIPID(pub->sih->chip) != BCM43225_CHIP_ID) &&
6345 (CHIPID(pub->sih->chip) != BCM43421_CHIP_ID) &&
6346 (CHIPID(pub->sih->chip) != BCM4342_CHIP_ID) &&
6347 (CHIPID(pub->sih->chip) != BCM43131_CHIP_ID) &&
6348 (CHIPID(pub->sih->chip) != BCM43227_CHIP_ID) &&
6349 (CHIPID(pub->sih->chip) != BCM43228_CHIP_ID) &&
6350 (CHIPID(pub->sih->chip) != BCM43428_CHIP_ID)) {
6351 WL_ERROR(("wl%d: %s: Unsupported Chip (%x)\n", pub->unit, __FUNCTION__,
6352 pub->sih->chip));
6353 wlc->cmi = NULL;
6354 wlc_channel_mgr_detach(wlc_cm);
6355 return NULL;
6357 if ((pub->sih->boardvendor == VENDOR_HP) && (!bcmp(country_abbrev, "US", 2) ||
6358 !bcmp(country_abbrev, "JP", 2) || !bcmp(country_abbrev, "IL", 2)))
6359 use_row = FALSE;
6361 /* use RoW locale if set */
6362 if (use_row) {
6363 bzero(country_abbrev, WLC_CNTRY_BUF_SZ);
6364 strncpy(country_abbrev, "XW", WLC_CNTRY_BUF_SZ);
6367 /* Enable Auto Country Discovery */
6368 strncpy(wlc->autocountry_default, country_abbrev, WLC_CNTRY_BUF_SZ - 1);
6370 /* enable regulatory */
6371 wlc->_regulatory_domain = TRUE;
6372 #endif /* PCOEM_LINUXSTA */
6374 /* Calling set_countrycode() once do not generate any event, if called more than
6375 * once generates COUNTRY_CODE_CHANGED event which will cause the driver to crash
6376 * since bsscfg structure is still not initialized
6378 wlc_set_countrycode(wlc_cm, country_abbrev);
6380 #if defined(BCMDBG) || defined(BCMDBG_DUMP)
6381 wlc_dump_register(wlc->pub, "txpwr_reg",
6382 (dump_fn_t)wlc_channel_dump_reg_ppr, (void *)wlc_cm);
6383 wlc_dump_register(wlc->pub, "txpwr_local",
6384 (dump_fn_t)wlc_channel_dump_reg_local_ppr, (void *)wlc_cm);
6385 wlc_dump_register(wlc->pub, "txpwr_srom",
6386 (dump_fn_t)wlc_channel_dump_srom_ppr, (void *)wlc_cm);
6387 wlc_dump_register(wlc->pub, "txpwr_margin",
6388 (dump_fn_t)wlc_channel_dump_margin, (void *)wlc_cm);
6389 #endif /* BCMDBG || BCMDBG_DUMP */
6391 return wlc_cm;
6394 void
6395 BCMATTACHFN(wlc_channel_mgr_detach)(wlc_cm_info_t *wlc_cm)
6397 if (wlc_cm)
6398 MFREE(wlc_cm->pub->osh, wlc_cm, sizeof(wlc_cm_info_t));
6401 const char* wlc_channel_country_abbrev(wlc_cm_info_t *wlc_cm)
6403 return wlc_cm->country_abbrev;
6406 const char* wlc_channel_ccode(wlc_cm_info_t *wlc_cm)
6408 return wlc_cm->ccode;
6411 uint wlc_channel_regrev(wlc_cm_info_t *wlc_cm)
6413 return wlc_cm->regrev;
6416 uint8 wlc_channel_locale_flags(wlc_cm_info_t *wlc_cm)
6418 wlc_info_t *wlc = wlc_cm->wlc;
6420 return wlc_cm->bandstate[wlc->band->bandunit].locale_flags;
6423 uint8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, uint bandunit)
6425 return wlc_cm->bandstate[bandunit].locale_flags;
6429 * return the first valid chanspec for the locale, if one is not found and hw_fallback is true
6430 * then return the first h/w supported chanspec.
6432 chanspec_t
6433 wlc_default_chanspec(wlc_cm_info_t *wlc_cm, bool hw_fallback)
6435 wlc_info_t *wlc = wlc_cm->wlc;
6436 chanspec_t chspec;
6438 chspec = wlc_create_chspec(wlc, 0);
6439 /* try to find a chanspec thats valid in this locale */
6440 if ((chspec = wlc_next_chanspec(wlc_cm, chspec, CHAN_TYPE_ANY, 0)) == INVCHANSPEC)
6441 /* try to find a chanspec valid for this hardware */
6442 if (hw_fallback)
6443 chspec = wlc_phy_chanspec_band_firstch(wlc_cm->wlc->band->pi,
6444 wlc->band->bandtype);
6446 return chspec;
6450 * Return the next channel's chanspec.
6452 chanspec_t
6453 wlc_next_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t cur_chanspec, int type, bool any_band)
6455 uint8 ch;
6456 uint8 cur_chan = CHSPEC_CHANNEL(cur_chanspec);
6457 chanspec_t chspec;
6459 /* 0 is an invalid chspec, routines trying to find the first available channel should
6460 * now be using wlc_default_chanspec (above)
6462 ASSERT(cur_chanspec);
6464 /* Try all channels in current band */
6465 ch = cur_chan + 1;
6466 for (; ch <= MAXCHANNEL; ch++) {
6467 if (ch == MAXCHANNEL)
6468 ch = 0;
6469 if (ch == cur_chan)
6470 break;
6471 /* create the next channel spec */
6472 chspec = cur_chanspec & ~WL_CHANSPEC_CHAN_MASK;
6473 chspec |= ch;
6474 if (wlc_valid_chanspec(wlc_cm, chspec)) {
6475 if ((type == CHAN_TYPE_ANY) ||
6476 (type == CHAN_TYPE_CHATTY && !wlc_quiet_chanspec(wlc_cm, chspec)) ||
6477 (type == CHAN_TYPE_QUIET && wlc_quiet_chanspec(wlc_cm, chspec)))
6478 return chspec;
6482 if (!any_band)
6483 return ((chanspec_t)INVCHANSPEC);
6485 /* Couldn't find any in current band, try other band */
6486 ch = cur_chan + 1;
6487 for (; ch <= MAXCHANNEL; ch++) {
6488 if (ch == MAXCHANNEL)
6489 ch = 0;
6490 if (ch == cur_chan)
6491 break;
6493 /* create the next channel spec */
6494 chspec = cur_chanspec & ~(WL_CHANSPEC_CHAN_MASK | WL_CHANSPEC_BAND_MASK);
6495 chspec |= ch;
6496 if (CHANNEL_BANDUNIT(wlc, ch) == BAND_2G_INDEX)
6497 chspec |= WL_CHANSPEC_BAND_2G;
6498 else
6499 chspec |= WL_CHANSPEC_BAND_5G;
6500 if (wlc_valid_chanspec_db(wlc_cm, chspec)) {
6501 if ((type == CHAN_TYPE_ANY) ||
6502 (type == CHAN_TYPE_CHATTY && !wlc_quiet_chanspec(wlc_cm, chspec)) ||
6503 (type == CHAN_TYPE_QUIET && wlc_quiet_chanspec(wlc_cm, chspec)))
6504 return chspec;
6508 return ((chanspec_t)INVCHANSPEC);
6511 /* return chanvec for a given country code and band */
6512 bool
6513 wlc_channel_get_chanvec(struct wlc_info *wlc, const char* country_abbrev,
6514 int bandtype, chanvec_t *channels)
6516 const country_info_t *country;
6517 const locale_info_t *locale = NULL;
6519 country = wlc_country_lookup(wlc, country_abbrev);
6520 if (country == NULL)
6521 return FALSE;
6523 if (bandtype == WLC_BAND_2G)
6524 locale = wlc_get_locale_2g(country->locale_2G);
6525 else if (bandtype == WLC_BAND_5G)
6526 locale = wlc_get_locale_5g(country->locale_5G);
6527 if (locale == NULL)
6528 return FALSE;
6530 wlc_locale_get_channels(locale, channels);
6531 return TRUE;
6534 /* set the driver's current country and regulatory information using a country code
6535 * as the source. Lookup built in country information found with the country code.
6538 wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char* ccode)
6540 char country_abbrev[WLC_CNTRY_BUF_SZ];
6542 WL_NONE(("wl%d: %s: ccode \"%s\"\n", wlc_cm->wlc->pub->unit, __FUNCTION__, ccode));
6544 /* substitute an external ccode for some application specific built-in country codes,
6545 * othewise, use the given abbrev
6547 if (wlc_japan_ccode(ccode))
6548 strncpy(country_abbrev, "JP", WLC_CNTRY_BUF_SZ-1);
6549 else if (wlc_us_ccode(ccode))
6550 strncpy(country_abbrev, "US", WLC_CNTRY_BUF_SZ-1);
6551 else
6552 strncpy(country_abbrev, ccode, WLC_CNTRY_BUF_SZ-1);
6553 country_abbrev[WLC_CNTRY_BUF_SZ-1] = '\0';
6554 return wlc_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1);
6558 wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm,
6559 const char* country_abbrev,
6560 const char* ccode, int regrev)
6562 #ifdef BCMDBG
6563 wlc_info_t *wlc = wlc_cm->wlc;
6564 #endif
6565 const country_info_t *country;
6566 char mapped_ccode[WLC_CNTRY_BUF_SZ];
6567 uint mapped_regrev = 0;
6569 WL_NONE(("wl%d: %s: (country_abbrev \"%s\", ccode \"%s\", regrev %d) SPROM \"%s\"/%u\n",
6570 wlc->pub->unit, __FUNCTION__,
6571 country_abbrev, ccode, regrev, wlc_cm->srom_ccode, wlc_cm->srom_regrev));
6573 /* if regrev is -1, lookup the mapped country code,
6574 * otherwise use the ccode and regrev directly
6576 if (regrev == -1) {
6577 /* map the country code to a built-in country code, regrev, and country_info */
6578 country = wlc_countrycode_map(wlc_cm, ccode, mapped_ccode, &mapped_regrev);
6579 if (country)
6580 WL_NONE(("wl%d: %s: mapped to \"%s\"/%u\n",
6581 wlc->pub->unit, __FUNCTION__, ccode, mapped_regrev));
6582 else
6583 WL_NONE(("wl%d: %s: failed lookup\n",
6584 wlc->pub->unit, __FUNCTION__));
6585 } else {
6586 /* find the matching built-in country definition */
6587 country = wlc_country_lookup_direct(ccode, regrev);
6588 strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ-1);
6589 mapped_ccode[WLC_CNTRY_BUF_SZ-1] = '\0';
6590 mapped_regrev = regrev;
6593 if (country == NULL)
6594 return BCME_BADARG;
6596 /* set the driver state for the country */
6597 wlc_set_country_common(wlc_cm, country_abbrev, mapped_ccode, mapped_regrev, country);
6599 return 0;
6602 /* set the driver's current country and regulatory information using a country code
6603 * as the source. Look up built in country information found with the country code.
6605 static void
6606 wlc_set_country_common(wlc_cm_info_t *wlc_cm,
6607 const char* country_abbrev,
6608 const char* ccode, uint regrev, const country_info_t *country)
6610 #ifdef WL11N
6611 const locale_mimo_info_t * li_mimo;
6612 #endif
6613 const locale_info_t * locale;
6614 wlc_info_t *wlc = wlc_cm->wlc;
6615 const country_info_t *prev_country = wlc_cm->country;
6616 char prev_country_abbrev[WLC_CNTRY_BUF_SZ];
6618 ASSERT(country != NULL);
6620 /* save current country state */
6621 wlc_cm->country = country;
6623 bzero(&prev_country_abbrev, WLC_CNTRY_BUF_SZ);
6624 strncpy(prev_country_abbrev, wlc_cm->country_abbrev, WLC_CNTRY_BUF_SZ - 1);
6626 strncpy(wlc_cm->country_abbrev, country_abbrev, WLC_CNTRY_BUF_SZ-1);
6627 strncpy(wlc_cm->ccode, ccode, WLC_CNTRY_BUF_SZ-1);
6628 wlc_cm->regrev = regrev;
6630 #ifdef WL11N
6631 /* disable/restore nmode based on country regulations */
6632 li_mimo = BAND_5G(wlc->band->bandtype) ?
6633 wlc_get_mimo_5g(country->locale_mimo_5G) :
6634 wlc_get_mimo_2g(country->locale_mimo_2G);
6635 if (li_mimo && (li_mimo->flags & WLC_NO_MIMO)) {
6636 wlc_set_nmode(wlc, OFF);
6637 wlc->stf->no_cddstbc = TRUE;
6638 } else {
6639 wlc->stf->no_cddstbc = FALSE;
6640 if (N_ENAB(wlc->pub) != wlc->protection->nmode_user)
6641 wlc_set_nmode(wlc, wlc->protection->nmode_user);
6644 wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
6645 wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
6646 #endif /* WL11N */
6647 /* set or restore gmode as required by regulatory */
6648 locale = wlc_get_locale_2g(country->locale_2G);
6649 if (locale && (locale->flags & WLC_NO_OFDM))
6650 wlc_set_gmode(wlc, GMODE_LEGACY_B, FALSE);
6651 else
6652 wlc_set_gmode(wlc, wlc->protection->gmode_user, FALSE);
6654 #if defined(AP) && defined(RADAR)
6655 if ((NBANDS(wlc) == 2) || IS_SINGLEBAND_5G(wlc->deviceid)) {
6656 phy_radar_detect_mode_t mode;
6657 const locale_info_t * li;
6659 li = wlc_get_locale_5g(country->locale_5G);
6660 mode = ISDFS_EU(li->flags) ? RADAR_DETECT_MODE_EU:RADAR_DETECT_MODE_FCC;
6661 wlc_phy_radar_detect_mode_set(wlc->band->pi, mode);
6663 #endif /* AP && RADAR */
6665 wlc_channels_init(wlc_cm, country);
6667 /* Country code changed */
6668 if (prev_country &&
6669 strncmp(wlc_cm->country_abbrev, prev_country_abbrev,
6670 strlen(wlc_cm->country_abbrev)) != 0)
6671 wlc_mac_event(wlc, WLC_E_COUNTRY_CODE_CHANGED, NULL,
6672 0, 0, 0, wlc_cm->country_abbrev, strlen(wlc_cm->country_abbrev) + 1);
6674 return;
6677 /* Lookup a country info structure from a null terminated country code
6678 * The lookup is case sensitive.
6680 const country_info_t*
6681 wlc_country_lookup(struct wlc_info *wlc, const char* ccode)
6683 const country_info_t *country;
6684 char mapped_ccode[WLC_CNTRY_BUF_SZ];
6685 uint mapped_regrev;
6687 WL_NONE(("wl%d: %s: ccode \"%s\", SPROM \"%s\"/%u\n",
6688 wlc->pub->unit, __FUNCTION__, ccode, wlc->cmi->srom_ccode, wlc->cmi->srom_regrev));
6690 /* map the country code to a built-in country code, regrev, and country_info struct */
6691 country = wlc_countrycode_map(wlc->cmi, ccode, mapped_ccode, &mapped_regrev);
6693 if (country)
6694 WL_NONE(("wl%d: %s: mapped to \"%s\"/%u\n",
6695 wlc->pub->unit, __FUNCTION__, mapped_ccode, mapped_regrev));
6696 else
6697 WL_NONE(("wl%d: %s: failed lookup\n",
6698 wlc->pub->unit, __FUNCTION__));
6700 return country;
6703 static const country_info_t*
6704 wlc_countrycode_map(wlc_cm_info_t *wlc_cm, const char *ccode,
6705 char *mapped_ccode, uint *mapped_regrev)
6707 wlc_info_t *wlc = wlc_cm->wlc;
6708 const country_info_t *country;
6709 uint srom_regrev = wlc_cm->srom_regrev;
6710 const char *srom_ccode = wlc_cm->srom_ccode;
6711 int mapped;
6713 /* check for currently supported ccode size */
6714 if (strlen(ccode) > (WLC_CNTRY_BUF_SZ - 1)) {
6715 WL_ERROR(("wl%d: %s: ccode \"%s\" too long for match\n",
6716 wlc->pub->unit, __FUNCTION__, ccode));
6717 return NULL;
6720 /* default mapping is the given ccode and regrev 0 */
6721 strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ);
6722 *mapped_regrev = 0;
6724 /* Map locale for buffalo if needed */
6725 if (wlc_buffalo_map_locale(wlc, ccode)) {
6726 strncpy(mapped_ccode, "J10", WLC_CNTRY_BUF_SZ);
6727 country = wlc_country_lookup_direct(mapped_ccode, *mapped_regrev);
6728 if (country)
6729 return country;
6732 /* If the desired country code matches the srom country code,
6733 * then the mapped country is the srom regulatory rev.
6734 * Otherwise look for an aggregate mapping.
6736 if (!strcmp(srom_ccode, ccode)) {
6737 WL_NONE(("wl%d: %s: srom ccode and ccode \"%s\" match\n",
6738 wlc->pub->unit, __FUNCTION__, ccode));
6739 *mapped_regrev = srom_regrev;
6740 mapped = 0;
6741 } else {
6742 mapped = wlc_country_aggregate_map(wlc_cm, ccode, mapped_ccode, mapped_regrev);
6743 if (mapped)
6744 WL_NONE(("wl%d: %s: found aggregate mapping \"%s\"/%u\n",
6745 wlc->pub->unit, __FUNCTION__, mapped_ccode, *mapped_regrev));
6748 /* CLM 8.2, JAPAN
6749 * Use the regrev=1 Japan country definition by default for chips newer than
6750 * our d11 core rev 5 4306 chips, or for AP's of any vintage.
6751 * For STAs with a 4306, use the legacy Japan country def "JP/0".
6752 * Only do the conversion if JP/0 was not specified by a mapping or by an
6753 * sprom with a regrev:
6754 * Sprom has no specific info about JP's regrev if it's less than rev 3 or it does
6755 * not specify "JP" as its country code =>
6756 * (strcmp("JP", srom_ccode) || (wlc->pub->sromrev < 3))
6758 if (!strcmp("JP", mapped_ccode) && *mapped_regrev == 0 &&
6759 !mapped && (strcmp("JP", srom_ccode) || (wlc->pub->sromrev < 3)) &&
6760 (AP_ENAB(wlc->pub) || D11REV_GT(wlc->pub->corerev, 5))) {
6761 *mapped_regrev = 1;
6762 WL_NONE(("wl%d: %s: Using \"JP/1\" instead of legacy \"JP/0\" since we %s\n",
6763 wlc->pub->unit, __FUNCTION__,
6764 AP_ENAB(wlc->pub) ? "are operating as an AP" : "are newer than 4306"));
6767 WL_NONE(("wl%d: %s: searching for country using ccode/rev \"%s\"/%u\n",
6768 wlc->pub->unit, __FUNCTION__, mapped_ccode, *mapped_regrev));
6770 /* find the matching built-in country definition */
6771 country = wlc_country_lookup_direct(mapped_ccode, *mapped_regrev);
6773 /* if there is not an exact rev match, default to rev zero */
6774 if (country == NULL && *mapped_regrev != 0) {
6775 *mapped_regrev = 0;
6776 WL_NONE(("wl%d: %s: No country found, use base revision \"%s\"/%u\n",
6777 wlc->pub->unit, __FUNCTION__, mapped_ccode, *mapped_regrev));
6778 country = wlc_country_lookup_direct(mapped_ccode, *mapped_regrev);
6781 if (country == NULL)
6782 WL_NONE(("wl%d: %s: No country found, failed lookup\n",
6783 wlc->pub->unit, __FUNCTION__));
6785 return country;
6788 static int
6789 wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode,
6790 char *mapped_ccode, uint *mapped_regrev)
6792 #ifdef BCMDBG
6793 wlc_info_t *wlc = wlc_cm->wlc;
6794 #endif
6795 const struct wlc_aggregate_cc_map_lookup *cc_lookup;
6796 const struct wlc_cc_map *map;
6797 const char *srom_ccode = wlc_cm->srom_ccode;
6798 uint srom_regrev = (uint8)wlc_cm->srom_regrev;
6800 /* Use "ww", WorldWide, for the lookup value for '\0\0' */
6801 if (srom_ccode[0] == '\0')
6802 srom_ccode = "ww";
6804 /* Check for a match in the aggregate country list */
6805 WL_NONE(("wl%d: %s: searching for agg map for srom ccode/rev \"%s\"/%u\n",
6806 wlc->pub->unit, __FUNCTION__, srom_ccode, srom_regrev));
6808 map = NULL;
6809 for (cc_lookup = aggregate_cc_maps; cc_lookup->cc[0]; cc_lookup++) {
6810 if (!strcmp(srom_ccode, cc_lookup->cc) && srom_regrev == cc_lookup->rev) {
6811 map = cc_lookup->map;
6812 break;
6816 if (!map)
6817 WL_NONE(("wl%d: %s: no map for \"%s\"/%u\n",
6818 wlc->pub->unit, __FUNCTION__, srom_ccode, srom_regrev));
6819 else
6820 WL_NONE(("wl%d: %s: found map for \"%s\"/%u\n",
6821 wlc->pub->unit, __FUNCTION__, srom_ccode, srom_regrev));
6823 /* Check if the given country code is mapped in the cc_map */
6824 while (map && map->cc[0] != '\0') {
6825 WL_NONE(("wl%d: %s: checking match of \"%s\" with map \"%s\" -> \"%s\"/%u\n",
6826 wlc->pub->unit, __FUNCTION__, ccode,
6827 map->cc, map->mapped_cc, map->mapped_rev));
6828 /* if there is a match, use it to look up a country */
6829 if (!strcmp(map->cc, ccode)) {
6830 WL_NONE(("wl%d: %s: mapped lookup for \"%s\" found country \"%s\"/%u\n",
6831 wlc->pub->unit, __FUNCTION__,
6832 ccode, map->mapped_cc, map->mapped_rev));
6833 strncpy(mapped_ccode, map->mapped_cc, WLC_CNTRY_BUF_SZ);
6834 *mapped_regrev = map->mapped_rev;
6835 return TRUE;
6837 map++;
6840 return FALSE;
6843 /* Lookup a country info structure from a null terminated country
6844 * abbreviation and regrev directly with no translation.
6846 static const country_info_t*
6847 wlc_country_lookup_direct(const char* ccode, uint regrev)
6849 uint size, i;
6851 /* find a country in the regrev country table */
6852 size = ARRAYSIZE(cntry_rev_locales);
6853 for (i = 0; i < size; i++) {
6854 if (strcmp(ccode, cntry_rev_locales[i].abbrev) == 0 &&
6855 regrev == cntry_rev_locales[i].rev) {
6856 return &cntry_rev_locales[i].country;
6860 /* all other country def arrays are for regrev == 0, so if regrev is non-zero, fail */
6861 if (regrev > 0)
6862 return NULL;
6864 /* find matched table entry from country code */
6865 size = ARRAYSIZE(cntry_locales);
6866 for (i = 0; i < size; i++) {
6867 if (strcmp(ccode, cntry_locales[i].abbrev) == 0) {
6868 return &cntry_locales[i].country;
6872 /* search alternative country code list of countries that do not support
6873 * any 802.11 channels
6875 size = ARRAYSIZE(country_nochannel);
6876 for (i = 0; i < size; i++) {
6877 if (strcmp(ccode, country_nochannel[i]) == 0) {
6878 return &country_nochannel_locale;
6882 return NULL;
6885 #if defined(STA) && defined(WL11D)
6886 /* Lookup a country info structure considering only legal country codes as found in
6887 * a Country IE; two ascii alpha followed by " ", "I", or "O".
6888 * Do not match any user assigned application specifc codes that might be found in the driver table.
6890 const country_info_t*
6891 wlc_country_lookup_ext(wlc_info_t *wlc, const char *ccode)
6893 char country_str_lookup[WLC_CNTRY_BUF_SZ] = { 0 };
6895 /* only allow ascii alpha uppercase for the first 2 chars, and " ", "I", "O" for the 3rd */
6896 if (!((0x80 & ccode[0]) == 0 && bcm_isupper(ccode[0]) &&
6897 (0x80 & ccode[1]) == 0 && bcm_isupper(ccode[1]) &&
6898 (ccode[2] == ' ' || ccode[2] == 'I' || ccode[2] == 'O')))
6899 return NULL;
6901 /* for lookup in the driver table of country codes, only use the first
6902 * 2 chars, ignore the 3rd character " ", "I", "O" qualifier
6904 country_str_lookup[0] = ccode[0];
6905 country_str_lookup[1] = ccode[1];
6907 /* do not match ISO 3166-1 user assigned country codes that may be in the driver table */
6908 if (!strcmp("AA", country_str_lookup) || /* AA */
6909 !strcmp("ZZ", country_str_lookup) || /* ZZ */
6910 country_str_lookup[0] == 'X' || /* XA - XZ */
6911 (country_str_lookup[0] == 'Q' && /* QM - QZ */
6912 (country_str_lookup[1] >= 'M' && country_str_lookup[1] <= 'Z')))
6913 return NULL;
6915 #ifdef MACOSX
6916 if (!strcmp("NA", country_str_lookup))
6917 return NULL;
6918 #endif /* MACOSX */
6920 return wlc_country_lookup(wlc, country_str_lookup);
6922 #endif /* STA && WL11D */
6924 static int
6925 wlc_channels_init(wlc_cm_info_t *wlc_cm, const country_info_t *country)
6927 wlc_info_t *wlc = wlc_cm->wlc;
6928 uint i, j;
6929 wlcband_t * band;
6930 const locale_info_t * li;
6931 chanvec_t sup_chan;
6932 #ifdef WL11N
6933 const locale_mimo_info_t *li_mimo;
6934 #endif /* WL11N */
6936 #ifdef AP
6937 bzero(wlc->ap->chan_blocked, sizeof(wlc->ap->chan_blocked));
6938 #endif
6940 bzero(&wlc_cm->restricted_channels, sizeof(chanvec_t));
6942 band = wlc->band;
6943 for (i = 0; i < NBANDS(wlc); i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
6945 li = BAND_5G(band->bandtype) ?
6946 wlc_get_locale_5g(country->locale_5G) :
6947 wlc_get_locale_2g(country->locale_2G);
6948 wlc_cm->bandstate[band->bandunit].locale_flags = li->flags;
6949 #ifdef WL11N
6950 li_mimo = BAND_5G(band->bandtype) ?
6951 wlc_get_mimo_5g(country->locale_mimo_5G) :
6952 wlc_get_mimo_2g(country->locale_mimo_2G);
6954 /* merge the mimo non-mimo locale flags */
6955 wlc_cm->bandstate[band->bandunit].locale_flags |= li_mimo->flags;
6956 #endif /* WL11N */
6958 /* initialize restricted channels */
6959 for (j = 0; j < sizeof(chanvec_t); j++) {
6960 wlc_cm->restricted_channels.vec[j] |=
6961 g_table_restricted_chan[li->restricted_channels]->vec[j];
6963 #ifdef BAND5G /* RADAR */
6964 wlc_cm->bandstate[band->bandunit].radar_channels =
6965 g_table_radar_set[li->radar_channels];
6966 #endif
6968 /* set the channel availability,
6969 * masking out the channels that may not be supported on this phy
6971 wlc_phy_chanspec_band_validch(band->pi, band->bandtype, &sup_chan);
6972 wlc_locale_get_channels(li,
6973 &wlc_cm->bandstate[band->bandunit].valid_channels);
6974 for (j = 0; j < sizeof(chanvec_t); j++)
6975 wlc_cm->bandstate[band->bandunit].valid_channels.vec[j] &=
6976 sup_chan.vec[j];
6979 wlc_upd_restricted_chanspec_flag(wlc_cm);
6980 wlc_quiet_channels_reset(wlc_cm);
6981 wlc_channels_commit(wlc_cm);
6982 wlc_rcinfo_init(wlc_cm);
6983 wlc_regclass_vec_init(wlc_cm);
6985 return (0);
6988 /* Update the radio state (enable/disable) and tx power targets
6989 * based on a new set of channel/regulatory information
6991 static void
6992 wlc_channels_commit(wlc_cm_info_t *wlc_cm)
6994 wlc_info_t *wlc = wlc_cm->wlc;
6995 uint chan;
6996 txppr_t txpwr;
6998 /* search for the existence of any valid channel */
6999 for (chan = 0; chan < MAXCHANNEL; chan++) {
7000 if (VALID_CHANNEL20_DB(wlc, chan)) {
7001 break;
7004 if (chan == MAXCHANNEL)
7005 chan = INVCHANNEL;
7007 /* based on the channel search above, set or clear WL_RADIO_COUNTRY_DISABLE */
7008 if (chan == INVCHANNEL) {
7009 /* country/locale with no valid channels, set the radio disable bit */
7010 mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
7011 WL_ERROR(("wl%d: %s: no valid channel for \"%s\" nbands %d bandlocked %d\n",
7012 wlc->pub->unit, __FUNCTION__,
7013 wlc_cm->country_abbrev, NBANDS(wlc), wlc->bandlocked));
7014 } else if (mboolisset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE)) {
7015 /* country/locale with valid channel, clear the radio disable bit */
7016 mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
7019 /* Now that the country abbreviation is set, if the radio supports 2G, then
7020 * set channel 14 restrictions based on the new locale.
7022 if (NBANDS(wlc) > 1 || BAND_2G(wlc->band->bandtype)) {
7023 wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, wlc_japan(wlc) ? TRUE : FALSE);
7026 if (wlc->pub->up && chan != INVCHANNEL) {
7027 /* recompute tx power for new country info */
7030 /* Where do we get a good chanspec? wlc, phy, set it ourselves? */
7031 wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr);
7033 wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr, WLC_TXPWR_MAX);
7035 /* Where do we get a good chanspec? wlc, phy, set it ourselves? */
7036 wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec);
7040 /* reset the quiet channels vector to the union of the restricted and radar channel sets */
7041 void
7042 wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm)
7044 wlc_info_t *wlc = wlc_cm->wlc;
7045 uint i;
7046 wlcband_t *band;
7048 /* initialize quiet channels for restricted channels */
7049 bcopy(&wlc_cm->restricted_channels, &wlc_cm->quiet_channels, sizeof(chanvec_t));
7051 band = wlc->band;
7052 for (i = 0; i < NBANDS(wlc); i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
7053 #ifdef BAND5G /* RADAR */
7054 /* initialize quiet channels for radar if we are in spectrum management mode */
7055 if (WL11H_ENAB(wlc)) {
7056 uint j;
7057 const chanvec_t *chanvec;
7058 chanvec = wlc_cm->bandstate[band->bandunit].radar_channels;
7059 for (j = 0; j < sizeof(chanvec_t); j++)
7060 wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j];
7062 #endif
7066 bool
7067 wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec)
7069 return (N_ENAB(wlc_cm->wlc->pub) && CHSPEC_IS40(chspec) ?
7070 (isset(wlc_cm->quiet_channels.vec, LOWER_20_SB(CHSPEC_CHANNEL(chspec))) ||
7071 isset(wlc_cm->quiet_channels.vec, UPPER_20_SB(CHSPEC_CHANNEL(chspec)))) :
7072 isset(wlc_cm->quiet_channels.vec, CHSPEC_CHANNEL(chspec)));
7075 void
7076 wlc_set_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec)
7078 if (N_ENAB(wlc_cm->wlc->pub) && CHSPEC_IS40(chspec)) {
7079 setbit(wlc_cm->quiet_channels.vec, LOWER_20_SB(CHSPEC_CHANNEL(chspec)));
7080 setbit(wlc_cm->quiet_channels.vec, UPPER_20_SB(CHSPEC_CHANNEL(chspec)));
7081 } else
7082 setbit(wlc_cm->quiet_channels.vec, CHSPEC_CHANNEL(chspec));
7085 void
7086 wlc_clr_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec)
7088 if (N_ENAB(wlc_cm->wlc->pub) && CHSPEC_IS40(chspec)) {
7089 clrbit(wlc_cm->quiet_channels.vec, LOWER_20_SB(CHSPEC_CHANNEL(chspec)));
7090 clrbit(wlc_cm->quiet_channels.vec, UPPER_20_SB(CHSPEC_CHANNEL(chspec)));
7091 } else
7092 clrbit(wlc_cm->quiet_channels.vec, CHSPEC_CHANNEL(chspec));
7095 /* Is the channel valid for the current locale? (but don't consider channels not
7096 * available due to bandlocking)
7098 bool
7099 wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val)
7101 wlc_info_t *wlc = wlc_cm->wlc;
7103 return (VALID_CHANNEL20(wlc, val) ||
7104 (!wlc->bandlocked && VALID_CHANNEL20_IN_BAND(wlc, OTHERBANDUNIT(wlc), val)));
7107 /* Is the channel valid for the current locale and specified band? */
7108 bool
7109 wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, uint val)
7111 return ((val < MAXCHANNEL) && isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val));
7114 /* Is the channel valid for the current locale and current band? */
7115 bool
7116 wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val)
7118 wlc_info_t *wlc = wlc_cm->wlc;
7120 return ((val < MAXCHANNEL) &&
7121 isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec, val));
7124 /* Is the 40 MHz allowed for the current locale and specified band? */
7125 bool
7126 wlc_valid_40chanspec_in_band(wlc_cm_info_t *wlc_cm, uint bandunit)
7128 wlc_info_t *wlc = wlc_cm->wlc;
7130 return (((wlc_cm->bandstate[bandunit].locale_flags & (WLC_NO_MIMO | WLC_NO_40MHZ)) == 0) &&
7131 wlc->bandstate[bandunit]->mimo_cap_40);
7135 /* Set tx power limits */
7136 /* BMAC_NOTE: this only needs a chanspec so that it can choose which 20/40 limits
7137 * to save in phy state. Would not need this if we ether saved all the limits and
7138 * applied them only when we were on the correct channel, or we restricted this fn
7139 * to be called only when on the correct channel.
7141 static void
7142 wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t *wlc_cm,
7143 txppr_t *txpwr, uint8 local_constraint_qdbm)
7145 int j;
7146 #ifdef WL11N
7147 bool ishtphy = WLCISHTPHY(wlc_cm->wlc->band);
7148 uint8 *ptxpwr;
7149 #endif
7150 /* CCK Rates */
7151 for (j = 0; j < WL_NUM_RATES_CCK; j++) {
7152 txpwr->cck[j] = MIN(txpwr->cck[j], local_constraint_qdbm);
7155 /* 20 MHz Legacy OFDM SISO */
7156 for (j = 0; j < WL_NUM_RATES_OFDM; j++) {
7157 txpwr->ofdm[j] = MIN(txpwr->ofdm[j], local_constraint_qdbm);
7160 #ifdef WL11N
7161 /* 20 MHz Legacy OFDM CDD */
7162 for (j = 0; j < WL_NUM_RATES_OFDM; j++) {
7163 txpwr->ofdm_cdd[j] = MIN(txpwr->ofdm_cdd[j], local_constraint_qdbm);
7166 /* 40 MHz Legacy OFDM SISO */
7167 for (j = 0; j < WL_NUM_RATES_OFDM; j++) {
7168 txpwr->ofdm_40[j] = MIN(txpwr->ofdm_40[j], local_constraint_qdbm);
7171 /* 40 MHz Legacy OFDM CDD */
7172 for (j = 0; j < WL_NUM_RATES_OFDM; j++) {
7173 txpwr->ofdm_40_cdd[j] = MIN(txpwr->ofdm_40_cdd[j], local_constraint_qdbm);
7176 /* 20MHz MCS 0-7 SISO or 1 Nsts to 1 Tx */
7177 ptxpwr = ishtphy ? txpwr->u20.ht.s1x1 : txpwr->u20.n.siso;
7178 for (j = 0; j < WL_NUM_RATES_MCS_1STREAM; j++) {
7179 ptxpwr[j] = MIN(ptxpwr[j], local_constraint_qdbm);
7182 /* 20MHz MCS 0-7 CDD or 1 Nsts to 2 Tx */
7183 ptxpwr = ishtphy ? txpwr->u20.ht.s1x2 : txpwr->u20.n.cdd;
7184 for (j = 0; j < WL_NUM_RATES_MCS_1STREAM; j++) {
7185 txpwr->u20.n.cdd[j] = MIN(ptxpwr[j], local_constraint_qdbm);
7188 /* 20MHz MCS 0-7 STBC or 1 Nsts to 3 Tx */
7189 ptxpwr = ishtphy ? txpwr->ht.u20s1x3 : txpwr->u20.n.stbc;
7190 for (j = 0; j < WL_NUM_RATES_MCS_1STREAM; j++) {
7191 ptxpwr[j] = MIN(ptxpwr[j], local_constraint_qdbm);
7194 /* 20MHz MCS 8-15 MIMO or 2 Nsts to 2 Tx */
7195 ptxpwr = ishtphy ? txpwr->u20.ht.s2x2 : txpwr->u20.n.sdm;
7196 for (j = 0; j < WL_NUM_RATES_MCS_1STREAM; j++)
7197 ptxpwr[j] = MIN(ptxpwr[j], local_constraint_qdbm);
7199 /* 20MHz 2 Nsts to 3 Tx & 3 Nsts to 3 Tx */
7200 if (ishtphy) {
7201 ptxpwr = txpwr->ht.u20s2x3;
7202 for (j = 0; j < WL_NUM_RATES_MCS_1STREAM; j++) {
7203 ptxpwr[j] = MIN(ptxpwr[j], local_constraint_qdbm);
7205 ptxpwr = txpwr->u20.ht.s3x3;
7206 for (j = 0; j < WL_NUM_RATES_MCS_1STREAM; j++) {
7207 ptxpwr[j] = MIN(ptxpwr[j], local_constraint_qdbm);
7211 /* 40MHz MCS 0-7 SISO or 1 Nsts to 1 Tx */
7212 ptxpwr = ishtphy ? txpwr->u40.ht.s1x1 : txpwr->u40.n.siso;
7213 for (j = 0; j < WL_NUM_RATES_MCS_1STREAM; j++) {
7214 ptxpwr[j] = MIN(ptxpwr[j], local_constraint_qdbm);
7217 /* 40MHz MCS 0-7 CDD or 1 Nsts to 2 Tx */
7218 ptxpwr = ishtphy ? txpwr->u40.ht.s1x2 : txpwr->u40.n.cdd;
7219 for (j = 0; j < WL_NUM_RATES_MCS_1STREAM; j++) {
7220 ptxpwr[j] = MIN(ptxpwr[j], local_constraint_qdbm);
7223 /* 40MHz MCS 0-7 STBC or 1 Nsts to 3 Tx */
7224 ptxpwr = ishtphy ? txpwr->ht.u40s1x3 : txpwr->u40.n.stbc;
7225 for (j = 0; j < WL_NUM_RATES_MCS_1STREAM; j++) {
7226 ptxpwr[j] = MIN(ptxpwr[j], local_constraint_qdbm);
7229 /* 40MHz MCS 8-15 MIMO or 2 Nsts to 2 Tx */
7230 ptxpwr = ishtphy ? txpwr->u40.ht.s2x2 : txpwr->u40.n.sdm;
7231 for (j = 0; j < WL_NUM_RATES_MCS_1STREAM; j++)
7232 ptxpwr[j] = MIN(ptxpwr[j], local_constraint_qdbm);
7234 /* 20MHz 2 Nsts to 3 Tx & 3 Nsts to 3 Tx */
7235 if (ishtphy) {
7236 ptxpwr = txpwr->ht.u40s2x3;
7237 for (j = 0; j < WL_NUM_RATES_MCS_1STREAM; j++) {
7238 ptxpwr[j] = MIN(ptxpwr[j], local_constraint_qdbm);
7240 ptxpwr = txpwr->u40.ht.s3x3;
7241 for (j = 0; j < WL_NUM_RATES_MCS_1STREAM; j++) {
7242 ptxpwr[j] = MIN(ptxpwr[j], local_constraint_qdbm);
7245 /* 20in40MHz CCK */
7246 for (j = 0; j < WL_NUM_RATES_CCK; j++)
7247 txpwr->cck_20ul[j] = MIN(txpwr->cck_20ul[j], local_constraint_qdbm);
7249 /* 20in40MHz OFDM */
7250 for (j = 0; j < WL_NUM_RATES_OFDM; j++)
7251 txpwr->ofdm_20ul[j] = MIN(txpwr->ofdm_20ul[j], local_constraint_qdbm);
7253 /* 20in40MHz OFDM CDD */
7254 for (j = 0; j < WL_NUM_RATES_OFDM; j++)
7255 txpwr->ofdm_20ul_cdd[j] = MIN(txpwr->ofdm_20ul_cdd[j],
7256 local_constraint_qdbm);
7258 /* 20in40MHz 1 Nsts to 1 Tx */
7259 for (j = 0; j < WL_NUM_RATES_MCS_1STREAM; j++)
7260 txpwr->ht20ul.s1x1[j] = MIN(txpwr->ht20ul.s1x1[j], local_constraint_qdbm);
7262 /* 20in40MHz 1 Nsts to 2 Tx */
7263 for (j = 0; j < WL_NUM_RATES_MCS_1STREAM; j++)
7264 txpwr->ht20ul.s1x2[j] = MIN(txpwr->ht20ul.s1x2[j], local_constraint_qdbm);
7266 /* 20in40MHz 1 Nsts to 3 Tx */
7267 for (j = 0; j < WL_NUM_RATES_MCS_1STREAM; j++)
7268 txpwr->ht.ul20s1x3[j] = MIN(txpwr->ht.ul20s1x3[j], local_constraint_qdbm);
7270 /* 20in40MHz 2 Nsts to 2 Tx */
7271 for (j = 0; j < WL_NUM_RATES_MCS_1STREAM; j++)
7272 txpwr->ht20ul.s2x2[j] = MIN(txpwr->ht20ul.s2x2[j], local_constraint_qdbm);
7274 /* 40MHz MCS 2 Nsts to 3 Tx */
7275 for (j = 0; j < WL_NUM_RATES_MCS_1STREAM; j++)
7276 txpwr->ht.ul20s2x3[j] = MIN(txpwr->ht.ul20s2x3[j], local_constraint_qdbm);
7278 /* 40MHz MCS 3 Nsts to 3 Tx */
7279 for (j = 0; j < WL_NUM_RATES_MCS_1STREAM; j++)
7280 txpwr->ht20ul.s3x3[j] = MIN(txpwr->ht20ul.s3x3[j], local_constraint_qdbm);
7282 /* 40MHz MCS 32 */
7283 txpwr->mcs32 = MIN(txpwr->mcs32, local_constraint_qdbm);
7284 #endif /* WL11N */
7288 static void
7289 wlc_channel_txpower_limits(wlc_cm_info_t *wlc_cm, txppr_t *txpwr)
7291 uint8 local_constraint;
7292 wlc_info_t *wlc = wlc_cm->wlc;
7294 local_constraint = wlc_local_constraint_qdbm(wlc);
7296 wlc_channel_reg_limits(wlc_cm, wlc->chanspec, txpwr);
7298 wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, txpwr, local_constraint);
7301 void
7302 wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, uint8 local_constraint_qdbm)
7304 wlc_info_t *wlc = wlc_cm->wlc;
7305 txppr_t txpwr;
7307 wlc_channel_reg_limits(wlc_cm, chanspec, &txpwr);
7309 wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr, local_constraint_qdbm);
7311 wlc_channel_update_txchain_offsets(wlc_cm, &txpwr);
7313 wlc_bmac_set_chanspec(wlc->hw, chanspec, (wlc_quiet_chanspec(wlc_cm, chanspec) != 0),
7314 &txpwr);
7318 wlc_channel_set_txpower_limit(wlc_cm_info_t *wlc_cm, uint8 local_constraint_qdbm)
7320 wlc_info_t *wlc = wlc_cm->wlc;
7321 txppr_t txpwr;
7323 wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr);
7325 wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr, local_constraint_qdbm);
7327 wlc_channel_update_txchain_offsets(wlc_cm, &txpwr);
7329 wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec);
7331 return 0;
7334 void
7335 wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, txppr_t *txpwr)
7337 wlc_info_t *wlc = wlc_cm->wlc;
7338 uint i;
7339 uint chan;
7340 int maxpwr;
7341 int delta;
7342 const country_info_t *country;
7343 wlcband_t * band;
7344 const locale_info_t * li;
7345 int conducted_max;
7346 int conducted_ofdm_max;
7347 #ifdef WL11N
7348 const locale_mimo_info_t *li_mimo;
7349 int maxpwr20, maxpwr40;
7350 int maxpwr_idx;
7351 uint j;
7352 #endif /* WL11N */
7353 bool is_4331 = FALSE;
7354 bool filt_war = FALSE;
7356 if ((wlc->pub->sih->boardvendor == VENDOR_APPLE) &&
7357 ((wlc->pub->sih->boardtype == BCM94331X19) ||
7358 (wlc->pub->sih->boardtype == BCM94331PCIEBT3Ax_SSID)))
7359 is_4331 = TRUE;
7361 bzero(txpwr, sizeof(txppr_t));
7364 /* Lookup channel in autocountry_default if not in current country */
7365 if (!wlc_valid_chanspec_db(wlc_cm, chanspec)) {
7366 country = wlc_country_lookup(wlc, wlc->autocountry_default);
7367 if (country == NULL)
7368 return;
7370 else
7371 country = wlc_cm->country;
7372 chan = CHSPEC_CHANNEL(chanspec);
7373 band = wlc->bandstate[CHSPEC_WLCBANDUNIT(chanspec)];
7374 li = BAND_5G(band->bandtype) ?
7375 wlc_get_locale_5g(country->locale_5G) :
7376 wlc_get_locale_2g(country->locale_2G);
7378 #ifdef WL11N
7379 li_mimo = BAND_5G(band->bandtype) ?
7380 wlc_get_mimo_5g(country->locale_mimo_5G) :
7381 wlc_get_mimo_2g(country->locale_mimo_2G);
7382 #endif /* WL11N */
7384 /* The maxtxpwr for a locale may be specified using either a conducted limit
7385 * (measured before the antenna) or EIRP (measured after the antenna).
7386 * The WLC_EIRP flag is used to distinguish between the two cases.
7387 * The max power limits returned by this routine are all conducted values so
7388 * they might need to be adjusted to account for the board's antenna gain.
7391 /* Compute a delta to remove from the locale table value. In the EIRP case this
7392 * is simply the antenna gain and would typically be 0 in the conducted case. But
7393 * because we/Broadcom do not want to allow more than a 6 dB antennal gain to a
7394 * conducted locale's table value, the delta to remove can be the excess over 6 dB
7395 * of antenna gain.
7398 if (li->flags & WLC_EIRP) {
7399 delta = band->antgain;
7400 } else {
7401 delta = 0;
7402 if (band->antgain > QDB(6) && !is_4331)
7403 delta = band->antgain - QDB(6); /* Excess over 6 dB */
7406 if (is_4331 && (li->flags & WLC_FILT_WAR) && (chan == 1 || chan == 13))
7407 filt_war = TRUE;
7408 wlc_bmac_filter_war_upd(wlc->hw, filt_war);
7410 /* Need to set the txpwr_local_max to external reg max for
7411 * this channel as per the locale selected for AP.
7413 if (AP_ONLY(wlc->pub)) {
7414 wlc->txpwr_local_max = wlc_get_reg_max_power_for_channel(wlc->cmi,
7415 CHSPEC_CHANNEL(wlc->chanspec), TRUE);
7418 /* Some EIRP locales also have a conducted CCK or OFDM limit. */
7419 if (li == &locale_g) {
7420 conducted_max = QDB(22);
7421 conducted_ofdm_max = 82; /* 20.5 dBm */
7422 } else if (li == &locale_h || li == &locale_i) {
7423 conducted_max = QDB(22);
7424 conducted_ofdm_max = QDB(22);
7425 } else {
7426 conducted_max = WLC_TXPWR_MAX;
7427 conducted_ofdm_max = WLC_TXPWR_MAX;
7430 /* CCK txpwr limits for 2.4G band */
7431 if (BAND_2G(band->bandtype)) {
7432 maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_CCK(chan)];
7434 /* special cases for 2.4G CCK */
7435 if (li == &locale_a2) {
7436 if (chan == 11)
7437 maxpwr = QDB(19);
7438 else if (chan == 14)
7439 maxpwr = QDB(16);
7440 } else if (li == &locale_b2) {
7441 if (chan == 14)
7442 maxpwr = 54; /* 13.5 dBm */
7443 } else if (li == &locale_b2_1 || li == &locale_b2_2) {
7444 if (chan == 11 || chan == 14)
7445 maxpwr = QDB(16);
7446 } else if (li == &locale_b2_6) {
7447 if (chan == 11)
7448 maxpwr = QDB(16);
7449 } else if (li == &locale_b5) {
7450 if (chan == 14)
7451 maxpwr = 42; /* 10.5 dBm */
7452 } else if (li == &locale_a4 ||
7453 li == &locale_a4_2 ||
7454 li == &locale_a4_3) {
7455 if (chan == 2)
7456 maxpwr = QDB(22);
7457 else if (chan == 10)
7458 maxpwr = QDB(21);
7459 } else if (li == &locale_a4_4) {
7460 if ((chan == 2) || (chan == 10))
7461 maxpwr = 98; /* 24.5 dBm */
7462 } else if (li == &locale_a5) {
7463 if (chan == 10)
7464 maxpwr = QDB(20);
7465 } else if (li == &locale_b5_2) {
7466 if (chan == 14)
7467 maxpwr = QDB(10);
7468 } else if (li == &locale_b5_3 || li == &locale_c_2) {
7469 if (chan == 14)
7470 maxpwr = QDB(15);
7471 } else if (li == &locale_a12) {
7472 if (chan == 7 || chan == 8)
7473 maxpwr = QDB(16);
7474 if (chan == 9)
7475 maxpwr = QDB(12);
7476 if (chan == 10)
7477 maxpwr = QDB(15);
7480 maxpwr = maxpwr - delta;
7481 maxpwr = MAX(maxpwr, 0);
7482 maxpwr = MIN(maxpwr, conducted_max);
7484 for (i = 0; i < WL_NUM_RATES_CCK; i++)
7485 txpwr->cck[i] = (uint8)maxpwr;
7488 /* Some locales is EIRP for CCK and conducted for OFDM, fix for OFDM now */
7489 if (li == &locale_b3 || li == &locale_b4 || li == &locale_k ||
7490 li == &locale_b_1) {
7491 delta = 0;
7492 if (band->antgain > QDB(6))
7493 delta = band->antgain - QDB(6); /* Excess over 6 dB */
7496 /* OFDM txpwr limits for 2.4G or 5G bands */
7497 if (BAND_2G(band->bandtype)) {
7498 maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_OFDM(chan)];
7500 /* special cases for 2.4G OFDM */
7501 if (li == &locale_a2) {
7502 if (chan == 11)
7503 maxpwr = 66; /* 16.5 dBm */
7504 } else if (li == &locale_b2) {
7505 if (chan == 11)
7506 maxpwr = 70; /* 17.5 dBm */
7507 } else if (li == &locale_b2_1 || li == &locale_b2_2) {
7508 if (chan == 11)
7509 maxpwr = QDB(16);
7510 } else if (li == &locale_b2_3 || li == &locale_b2_5) {
7511 if (chan == 13)
7512 maxpwr = 46 /* 11.5 dBm */;
7513 } else if (li == &locale_b2_6) {
7514 if (chan == 11)
7515 maxpwr = QDB(16);
7516 } else if (li == &locale_k) {
7517 if (chan == 13)
7518 maxpwr = QDB(14);
7519 } else if (li == &locale_b5) {
7520 if (chan == 11)
7521 maxpwr = 62; /* 15.5 dBm */
7522 } else if (li == &locale_a4 || li == &locale_a4_2) {
7523 if (chan == 2 || chan == 10)
7524 maxpwr = QDB(20);
7525 } else if (li == &locale_a4_3) {
7526 if (chan == 2 || chan == 10)
7527 maxpwr = QDB(19);
7528 } else if (li == &locale_a4_4) {
7529 if (chan == 2 || chan == 10)
7530 maxpwr = 86; /* 21.5 dBm */
7531 } else if (li == &locale_a5) {
7532 if (chan == 2 || chan == 10)
7533 maxpwr = QDB(19);
7534 } else if (li == &locale_a5_1) {
7535 if (chan == 2 || chan == 10)
7536 maxpwr = QDB(16);
7537 } else if (li == &locale_a6_2) {
7538 if (chan == 2 || chan == 10)
7539 maxpwr = QDB(18);
7540 } else if (li == &locale_a6 || li == &locale_a6_1) {
7541 if (chan == 2 || chan == 10)
7542 maxpwr = QDB(20);
7543 } else if (li == &locale_a9) {
7544 if (chan == 2 || chan == 10)
7545 maxpwr = QDB(16);
7546 else if (chan == 3 || chan == 9)
7547 maxpwr = 70; /* 17.5 dBm */
7548 } else if (li == &locale_b5_2) {
7549 if (chan == 12 || chan == 13)
7550 maxpwr = QDB(15);
7551 } else if (li == &locale_b5_3) {
7552 if (chan == 11)
7553 maxpwr = 51; /* 12.75 */
7554 } else if (li == &locale_i_1) {
7555 if (chan == 12)
7556 maxpwr = QDB(16);
7557 if (chan == 13)
7558 maxpwr = QDB(14);
7559 } else if (li == &locale_a3_1) {
7560 if (chan == 2)
7561 maxpwr = QDB(16);
7562 else if (chan == 10)
7563 maxpwr = QDB(15);
7564 } else if (li == &locale_a12) {
7565 if (chan == 2)
7566 maxpwr = QDB(11);
7567 else if (chan == 3 || chan == 8)
7568 maxpwr = QDB(14);
7569 else if (chan == 4 || chan == 7)
7570 maxpwr = QDB(15);
7571 else if (chan == 5 || chan == 6)
7572 maxpwr = QDB(16);
7573 else if (chan == 9)
7574 maxpwr = QDB(12);
7576 } else {
7577 maxpwr = li->maxpwr[CHANNEL_POWER_IDX_5G(chan)];
7579 #ifdef BAND5G
7580 /* special cases for 5G OFDM */
7581 if (li == &locale_8b) {
7582 if (chan == 100) {
7583 maxpwr = 58; /* 14.5 dBm */
7584 } else if (chan >= 104 && chan <= 136) {
7585 maxpwr = QDB(17);
7586 } else if (chan == 140) {
7587 maxpwr = QDB(15);
7589 } else if (li == &locale_29b) {
7590 if (chan == 100) {
7591 maxpwr = 62; /* 15.5 dBm */
7592 } else if (chan >= 132 && chan <= 140) {
7593 maxpwr = QDB(20);
7595 } else if ((li == &locale_29b_1) || (li == &locale_29b_3)) {
7596 if (chan == 100) {
7597 maxpwr = 74; /* 18.5 dBm */
7598 } else if (chan == 140) {
7599 maxpwr = QDB(17);
7601 } else if (li == &locale_29d) {
7602 if (chan >= 132 && chan <= 140)
7603 maxpwr = 78 /* 19.5 */;
7604 } else if (li == &locale_11_2) {
7605 if (chan == 100) {
7606 maxpwr = QDB(14);
7608 } else if (li == &locale_19_1) {
7609 if (chan >= 104 && chan <= 136) {
7610 maxpwr = QDB(17);
7611 } else if (chan == 140) {
7612 maxpwr = 50; /* 12.5 dBm */
7614 } else if (li == &locale_19_2) {
7615 if (chan == 100 || chan == 140) {
7616 maxpwr = QDB(16);
7617 } else if (chan == 149 || chan == 165) {
7618 maxpwr = 78 /* 19.5 */;
7620 } else if (li == &locale_19h_1) {
7621 if (chan == 140) {
7622 maxpwr = 58 /* 14.5 */;
7624 } else if (li == &locale_19_3) {
7625 if (chan == 100) {
7626 maxpwr = QDB(13);
7628 } else if (li == &locale_19_4) {
7629 if (chan == 36) {
7630 maxpwr = QDB(13);
7632 if (chan == 100) {
7633 maxpwr = 62 /* 15.5 dBm */;
7635 } else if (li == &locale_19a_1) {
7636 if (chan == 100) {
7637 maxpwr = QDB(14);
7639 } else if (li == &locale_19l_1) {
7640 if (chan == 140) {
7641 maxpwr = QDB(15);
7643 } else if (li == &locale_19l_2) {
7644 if (chan == 100) {
7645 maxpwr = /* 14.5 dBm */ 58;
7646 } else if (chan == 140) {
7647 maxpwr = QDB(15);
7649 } else if (li == &locale_3l) {
7650 if (chan >= 132 && chan <= 140) {
7651 maxpwr = 54; /* 13.5 dBm */
7654 #endif /* BAND5G */
7657 maxpwr = maxpwr - delta;
7658 maxpwr = MAX(maxpwr, 0);
7659 maxpwr = MIN(maxpwr, conducted_ofdm_max);
7661 /* Keep OFDM lmit below CCK limit */
7662 if (BAND_2G(band->bandtype))
7663 maxpwr = MIN(maxpwr, txpwr->cck[0]);
7665 for (i = 0; i < WL_NUM_RATES_OFDM; i++) {
7666 txpwr->ofdm[i] = (uint8)maxpwr;
7669 #ifdef WL11N
7670 for (i = 0; i < WL_NUM_RATES_OFDM; i++) {
7671 /* OFDM 40 MHz SISO has the same power as the corresponding MCS0-7 rate unless
7672 * overriden by the locale specific code. We set this value to 0 as a
7673 * flag (presumably 0 dBm isn't a possibility) and then copy the MCS0-7 value
7674 * to the 40 MHz value if it wasn't explicitly set.
7676 txpwr->ofdm_40[i] = 0;
7678 txpwr->ofdm_cdd[i] = (uint8)maxpwr;
7680 /* OFDM 40 MHz CDD has the same power as the corresponding MCS0-7 rate unless
7681 * overriden by the locale specific code. We set this value to 0 as a
7682 * flag (presumably 0 dBm isn't a possibility) and then copy the MCS0-7 value
7683 * to the OFDM value if it wasn't explicitly set.
7685 txpwr->ofdm_40_cdd[i] = 0;
7687 #endif /* WL11N */
7689 #ifdef WL11N
7690 /* MIMO/HT specific limits */
7692 /* Compute a delta to remove from the locale table value. In the EIRP case this
7693 * is simply the antenna gain and would typically be 0 in the conducted case. But
7694 * because we/Broadcom do not want to allow more than a 6 dB antennal gain to a
7695 * conducted locale's table value, the delta to remove can be the excess over 6 dB
7696 * of antenna gain.
7699 if (li_mimo->flags & WLC_EIRP) {
7700 delta = band->antgain;
7701 } else {
7702 delta = 0;
7703 if (band->antgain > QDB(6))
7704 delta = band->antgain - QDB(6); /* Excess over 6 dB */
7707 if (BAND_2G(band->bandtype))
7708 maxpwr_idx = (chan - 1);
7709 else
7710 maxpwr_idx = CHANNEL_POWER_IDX_5G(chan);
7712 maxpwr20 = li_mimo->maxpwr20[maxpwr_idx];
7713 maxpwr40 = li_mimo->maxpwr40[maxpwr_idx];
7715 if (li_mimo == &locale_3bn) {
7716 if (chan == 100) {
7717 maxpwr20 = QDB(20);
7718 maxpwr40 = QDB(18);
7722 if (li_mimo == &locale_8an) {
7723 if (chan >= 100 && chan <= 102) {
7724 maxpwr40 = 62; /* 15.5 dBm */
7728 if (li_mimo == &locale_8bn) {
7729 if (chan >= 100 && chan <= 102) {
7730 maxpwr40 = 62; /* 15.5 dBm */
7734 /* Fix channel only splits here */
7735 if (li_mimo == &locale_8cn) {
7736 if (chan >= 100 && chan <= 108) {
7737 maxpwr20 = QDB(13);
7738 maxpwr40 = QDB(12);
7739 } else if (chan >= 110 && chan <= 132) {
7740 maxpwr20 = 58; /* 14.5 dBm */
7741 maxpwr40 = QDB(17);
7742 } else if (chan >= 134 && chan <= 136) {
7743 maxpwr20 = 58; /* 14.5 dBm */
7744 maxpwr20 = 62; /* 15.5 dBm */
7745 } else if (chan == 140) {
7746 maxpwr20 = 54; /* 13.5 dBm */
7747 maxpwr40 = QDB(18); /* 13.5 dBm */
7750 if (li_mimo == &locale_19n ||
7751 li_mimo == &locale_19an ||
7752 li_mimo == &locale_19bn ||
7753 li_mimo == &locale_19hn ||
7754 li_mimo == &locale_19ln ||
7755 li_mimo == &locale_19rn) {
7756 /* Fixup 100-102, 104-140 channel split */
7757 if (chan >= 104 && chan <= 140) {
7758 if (li_mimo == &locale_19bn ||
7759 li_mimo == &locale_19hn ||
7760 li_mimo == &locale_19rn)
7761 maxpwr20 = 66; /* 16.5 dBm */
7762 else
7763 maxpwr20 = QDB(17);
7765 if (li_mimo == &locale_19an ||
7766 li_mimo == &locale_19ln)
7767 maxpwr40 = QDB(17);
7768 else
7769 maxpwr40 = 74; /* 18.5 dBm */
7773 if (li_mimo == &locale_19hn_2) {
7774 if (chan >= 100 && chan <= 102) {
7775 maxpwr20 = 82; /* 20.5 */
7776 maxpwr40 = QDB(18);
7777 } else if (chan == 60) {
7778 maxpwr20 = 82; /* 20.5 */
7779 maxpwr40 = 86; /* 21.5 */
7783 if (li_mimo == &locale_19n_1) {
7784 if (chan >= 104 && chan <= 136) {
7785 maxpwr20 = QDB(17);
7786 maxpwr40 = QDB(16);
7787 } else if (chan == 140) {
7788 maxpwr20 = 54; /* 13.5 dBm */
7789 maxpwr40 = 0;
7793 if (li_mimo == &locale_19n_2) {
7794 if (chan >= 100 && chan <= 102) {
7795 maxpwr20 = QDB(13);
7796 maxpwr40 = QDB(13);
7797 } else if (chan >= 128 && chan <= 136) {
7798 maxpwr20 = QDB(14);
7799 maxpwr40 = QDB(13);
7800 } else if (chan >= 159 && chan <= 161) {
7801 maxpwr20 = 82 /* 20.5 */;
7802 maxpwr40 = 82;
7803 } else if (chan == 140) {
7804 maxpwr20 = QDB(13);
7805 maxpwr40 = 0;
7806 } else if (chan == 165) {
7807 maxpwr20 = 78 /* 19.5 */;
7808 maxpwr40 = 0;
7809 } else if (chan == 149) {
7810 maxpwr20 = QDB(18);
7811 maxpwr40 = 0;
7815 if (li_mimo == &locale_19n_3) {
7816 if (chan >= 40 && chan <= 48) {
7817 maxpwr20 = 58; /* 14.5 dBm */
7818 maxpwr40 = 58; /* 14.5 dBm */
7819 } else if (chan >= 104 && chan <= 140) {
7820 maxpwr20 = 58; /* 14.5 dBm */
7821 maxpwr40 = 54; /* 13.5 dBm */
7825 if (li_mimo == &locale_29bn) {
7826 if (chan == 100) {
7827 maxpwr20 = QDB(16);
7828 maxpwr40 = QDB(13);
7829 } else if (chan >= 104 && chan <= 116) {
7830 maxpwr20 = QDB(16);
7831 maxpwr40 = QDB(15);
7835 if (li_mimo == &locale_29dn) {
7836 if (chan >= 132 && chan <= 140) {
7837 maxpwr20 = 74 /* 18.5 */;
7838 maxpwr40 = 62 /* 15.5 */;
7842 if (li_mimo == &locale_19hn_1) {
7843 if (chan == 140) {
7844 maxpwr20 = 58 /* 14.5 */;
7845 maxpwr40 = 0;
7846 } else if (chan >= 100 && chan <= 102) {
7847 maxpwr20 = 58 /* 14.5 */;
7848 maxpwr40 = 58 /* 14.5 */;
7849 } else if (chan >= 134 && chan <= 136) {
7850 maxpwr20 = 70 /* 17.5 */;
7851 maxpwr40 = 70 /* 17.5 */;
7855 if (li_mimo == &locale_29bn_1) {
7856 if (chan == 100) {
7857 maxpwr20 = QDB(18);
7858 maxpwr40 = QDB(16);
7859 } else if (chan == 140) {
7860 maxpwr20 = 66 /* 16.5 */;
7861 maxpwr40 = 0;
7862 } else if (chan >= 132 && chan <= 136) {
7863 maxpwr40 = 74; /* 18.5 dBm */
7867 if (li_mimo == &locale_29bn_3) {
7868 if (chan == 100) {
7869 maxpwr20 = QDB(18);
7870 maxpwr40 = QDB(16);
7871 } else if (chan == 140) {
7872 maxpwr20 = 66 /* 16.5 */;
7873 maxpwr40 = 0;
7874 } else if (chan >= 132 && chan <= 136) {
7875 maxpwr40 = QDB(19);
7879 if (li_mimo == &locale_19ln_1) {
7880 if (chan >= 100 && chan <= 108) {
7881 maxpwr20 = QDB(13);
7882 maxpwr40 = QDB(12);
7884 if (chan >= 110 && chan <= 132) {
7885 maxpwr40 = 70; /* 18.5 dBm */
7887 if (chan >= 134 && chan <= 136) {
7888 maxpwr40 = 62; /* 15.5 dBm */
7890 if (chan == 140) {
7891 maxpwr20 = 54; /* 13.5 dBm */
7892 maxpwr40 = QDB(18);
7894 if (chan >= 149 && chan < 165) {
7895 maxpwr20 = QDB(17);
7899 if (li_mimo == &locale_19ln_2) {
7900 if (chan >= 110 && chan <= 132) {
7901 maxpwr20 = /* 14.5 dBm */ 58;
7902 maxpwr40 = QDB(17);
7904 if (chan >= 134 && chan <= 136) {
7905 maxpwr20 = /* 14.5 dBm */ 58;
7906 maxpwr40 = 62; /* 15.5 dBm */
7908 if (chan == 140) {
7909 maxpwr20 = 54; /* 13.5 dBm */
7910 maxpwr40 = QDB(18);
7914 if (li_mimo == &locale_19ln_3) {
7915 if (chan >= 100 && chan <= 102) {
7916 maxpwr20 = QDB(16);
7917 maxpwr40 = QDB(13);
7921 if (li_mimo == &locale_3ln ||
7922 li_mimo == &locale_11ln) {
7923 if (chan >= 132 && chan <= 140) {
7924 maxpwr20 = QDB(11);
7928 if (li_mimo == &locale_6an_1) {
7929 if (chan >= 36 && chan <= 38) {
7930 maxpwr40 = QDB(13);
7931 } else if (chan >= 52 && chan <= 54) {
7932 maxpwr40 = QDB(17);
7936 if (li_mimo == &locale_8an_1) {
7937 if (chan >= 100 && chan <= 102) {
7938 maxpwr20 = QDB(17);
7939 maxpwr40 = QDB(15);
7943 if (li_mimo == &locale_29dn_2) {
7944 if (chan >= 52 && chan <= 54) {
7945 maxpwr20 = QDB(17);
7946 maxpwr40 = QDB(17);
7947 } else if (chan >= 100 && chan <= 108) {
7948 maxpwr20 = QDB(17);
7949 maxpwr40 = QDB(15);
7953 if (li_mimo == &locale_25hn) {
7954 if ((chan >= 100 && chan <= 124)||
7955 (chan >= 149 && chan <= 161)) {
7956 maxpwr20 = QDB(16);
7957 maxpwr40 = QDB(16);
7961 /* CLM v4.6.6 */
7962 if (li_mimo == &locale_3n_1) {
7963 if (chan >= 100 && chan <= 102) {
7964 maxpwr20 = QDB(21);
7968 maxpwr20 = maxpwr20 - delta;
7969 maxpwr20 = MAX(maxpwr20, 0);
7970 maxpwr40 = maxpwr40 - delta;
7971 maxpwr40 = MAX(maxpwr40, 0);
7973 /* First fill in the tx power limits based solely on the internal local table
7974 * structure. Then modify those values for locales that can't be fully described
7975 * by the current table structure.
7978 /* Fill in the MCS 0-7 (SISO) rates */
7979 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
7981 /* 20 MHz has the same power as the corresponding OFDM rate unless
7982 * overriden by the locale specific code.
7984 txpwr->u20.n.siso[i] = txpwr->ofdm[i];
7986 /* 40 MHz has the same power as the corresponding CDD rate unless
7987 * overriden by the locale specific code. Because we don't know
7988 * the CDD value yet, the locale specific code and set it, and
7989 * because the locale specific code might want a different
7990 * value for MCS 0-7 SISO vs. CDD, we set this value to 0 as a
7991 * flag (presumably 0 dBm isn't a possibility) and then copy the CDD value
7992 * to the SISO value if it wasn't explicitly set.
7994 txpwr->u40.n.siso[i] = 0;
7997 /* Fill in the MCS 0-7 CDD rates */
7998 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
7999 txpwr->u20.n.cdd[i] = (uint8)maxpwr20;
8000 txpwr->u40.n.cdd[i] = (uint8)maxpwr40;
8003 /* These locales have SISO expressed in the table and override CDD later */
8004 if (li_mimo == &locale_an1_t1 ||
8005 li_mimo == &locale_an1_t2 ||
8006 li_mimo == &locale_an1_t3 ||
8007 li_mimo == &locale_an1_t5 ||
8008 li_mimo == &locale_an2_5 ||
8009 li_mimo == &locale_an6_1 ||
8010 li_mimo == &locale_an6_6 ||
8011 li_mimo == &locale_bn2_3 ||
8012 li_mimo == &locale_bn2_8 ||
8013 li_mimo == &locale_bn ||
8014 li_mimo == &locale_cn ||
8015 li_mimo == &locale_cn_3 ||
8016 li_mimo == &locale_bn2_4 ||
8017 li_mimo == &locale_bn_9 ||
8018 li_mimo == &locale_an_2 ||
8019 li_mimo == &locale_an7_8 ||
8020 li_mimo == &locale_kn5) {
8022 if (li_mimo == &locale_bn2_3) {
8023 maxpwr20 = QDB(16);
8024 maxpwr40 = 0;
8026 if (chan == 3) {
8027 maxpwr40 = QDB(15);
8028 } else if (chan >= 4 && chan <= 8) {
8029 maxpwr40 = QDB(16);
8030 } else if (chan == 9) {
8031 maxpwr40 = QDB(14);
8032 } else if (chan == 12 || chan == 13) {
8033 maxpwr20 = QDB(11);
8037 if (li_mimo == &locale_bn2_8) {
8038 maxpwr20 = QDB(16);
8039 maxpwr40 = 0;
8041 if (chan == 3) {
8042 maxpwr40 = 54; /* 13.5 QDB */
8043 } else if (chan >= 4 && chan <= 8) {
8044 maxpwr40 = QDB(16);
8045 } else if (chan == 9) {
8046 maxpwr40 = QDB(13);
8047 } else if (chan == 12 || chan == 13) {
8048 maxpwr20 = QDB(11);
8052 if (li_mimo == &locale_bn_9 ||
8053 li_mimo == &locale_kn5) {
8054 maxpwr20 = 66; /* 16.5 dBm */
8056 if (chan >= 3 && chan <= 11) {
8057 if (li_mimo == &locale_bn_9)
8058 maxpwr40 = 54; /* 13.5 QDB */
8059 else if (li_mimo == &locale_kn5)
8060 maxpwr40 = 66; /* 16.5 dBm */
8064 if (li_mimo == &locale_an2_5) {
8065 if (chan == 1) {
8066 maxpwr20 = 50; /* 12.5 dBm */
8068 if (chan == 11) {
8069 maxpwr20 = 66; /* 16.5 dBm */
8071 if (chan == 3) {
8072 maxpwr40 = QDB(11);
8074 if (chan == 9) {
8075 maxpwr40 = 58; /* 14.5 dBm */
8080 if (li_mimo == &locale_bn || li_mimo == &locale_cn) {
8081 maxpwr20 = QDB(16);
8082 maxpwr40 = 0;
8084 if (chan >= 3 && chan <= 11) {
8085 maxpwr40 = QDB(16);
8089 if (li_mimo == &locale_cn_3) {
8090 maxpwr20 = 70; /* 17.5 dBm */
8091 maxpwr40 = 0;
8093 if (chan >= 3 && chan <= 11) {
8094 maxpwr40 = 70; /* 17.5 dBm */
8098 if (li_mimo == &locale_an6_6) {
8099 maxpwr20 = QDB(17);
8100 maxpwr40 = 0;
8102 if (chan == 11)
8103 maxpwr20 = QDB(16);
8104 if (chan == 3 || chan == 9)
8105 maxpwr40 = QDB(14);
8106 else if (chan >= 4 && chan <= 8)
8107 maxpwr20 = QDB(17);
8110 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8111 txpwr->u20.n.siso[i] = (uint8)maxpwr20;
8112 txpwr->u40.n.siso[i] = (uint8)maxpwr40;
8116 /* Fill in the MCS 0-7 STBC rates */
8117 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8118 /* MCS0-7 20 and 40 MHz STBC rates have the same powers as the corresponding
8119 * MCS0-7 20 and 40 MHz CDD rates unless overriden by the locale specific code.
8120 * We set this value to 0 as a flag (presumably 0 dBm isn't a possibility)
8121 * and then copy the CDD values to the STBC values if they weren't explicitly set.
8123 txpwr->u20.n.stbc[i] = 0;
8124 txpwr->u40.n.stbc[i] = 0;
8127 /* Fill in the MCS 8-15 SDM rates */
8128 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8129 txpwr->u20.n.sdm[i] = (uint8)maxpwr20;
8130 txpwr->u40.n.sdm[i] = (uint8)maxpwr40;
8133 /* Fill in MCS32 */
8134 txpwr->mcs32 = (uint8)maxpwr40;
8136 /* Now override the N enable limits for those locales where
8137 * the defaults are not correct.
8140 if (li_mimo == &locale_an1_t1 ||
8141 li_mimo == &locale_an1_t2 ||
8142 li_mimo == &locale_an1_t5) {
8143 uint max_low_mcs, max_mid_mcs, max_high_mcs;
8145 /* Fixup CDD/SDM and per-MCS */
8146 max_low_mcs = 0;
8147 max_mid_mcs = 0;
8148 max_high_mcs = 0;
8150 if (li_mimo == &locale_an1_t1) {
8151 if (chan == 1) {
8152 maxpwr20 = QDB(14);
8153 } else if (chan == 2) {
8154 maxpwr20 = QDB(16);
8155 } else if (chan == 3) {
8156 maxpwr20 = QDB(19);
8157 max_low_mcs = QDB(13);
8158 max_mid_mcs = QDB(14);
8159 max_high_mcs = 58; /* 14.5 dBm */
8160 } else if (chan >= 4 && chan <= 8) {
8161 maxpwr20 = QDB(19);
8162 max_low_mcs = QDB(14);
8163 max_mid_mcs = QDB(15);
8164 max_high_mcs = 62; /* 15.5 dBm */
8165 } else if (chan == 9) {
8166 maxpwr20 = QDB(19);
8167 max_low_mcs = QDB(12);
8168 max_mid_mcs = QDB(13);
8169 max_high_mcs = 54; /* 13.5 dBm */
8170 } else if (chan == 10) {
8171 maxpwr20 = QDB(16);
8172 } else if (chan == 11) {
8173 maxpwr20 = QDB(14);
8175 } else if (li_mimo == &locale_an1_t2) {
8176 if (chan == 1) {
8177 maxpwr20 = QDB(14);
8178 } else if (chan == 2) {
8179 maxpwr20 = 62; /* 15.5 dBm */
8180 } else if (chan == 3) {
8181 maxpwr20 = QDB(19);
8182 max_low_mcs = 50; /* 12.5 dBm */
8183 max_mid_mcs = 54; /* 13.5 dBm */
8184 max_high_mcs = QDB(14);
8185 } else if (chan >= 4 && chan <= 8) {
8186 maxpwr20 = QDB(19);
8187 max_low_mcs = QDB(13);
8188 max_mid_mcs = QDB(14);
8189 max_high_mcs = 58; /* 14.5 dBm */
8190 } else if (chan == 9) {
8191 maxpwr20 = 74; /* 18.5 dBm */
8192 max_low_mcs = QDB(12);
8193 max_mid_mcs = QDB(13);
8194 max_high_mcs = 54; /* 13.5 dBm */
8195 } else if (chan == 10) {
8196 maxpwr20 = 62; /* 15.5 dBm */
8197 } else if (chan == 11) {
8198 maxpwr20 = 54; /* 13.5 dBm */
8200 } else if (li_mimo == &locale_an1_t5) {
8201 if (chan == 1) {
8202 maxpwr20 = QDB(11);
8203 } else if (chan == 2) {
8204 maxpwr20 = QDB(15);
8205 } else if (chan >= 3 && chan <= 8) {
8206 maxpwr20 = QDB(17);
8207 } else if (chan == 9) {
8208 maxpwr20 = 66; /* 16.5 dBm */
8209 } else if (chan == 10) {
8210 maxpwr20 = QDB(15);
8211 } else if (chan == 11) {
8212 maxpwr20 = 42; /* 10.5 dBm */
8216 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8217 txpwr->u20.n.cdd[i] = (uint8)maxpwr20;
8219 /* MCS 0-4 are in the low set
8220 * MCS 5-7 are in the mid set
8222 if (i <= 4)
8223 txpwr->u40.n.cdd[i] = (uint8)max_low_mcs;
8224 else
8225 txpwr->u40.n.cdd[i] = (uint8)max_mid_mcs;
8228 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8229 txpwr->u20.n.sdm[i] = (uint8)maxpwr20;
8231 /* MCS 8-11 (i: 0-3) are in the mid set
8232 * MCS 12-15 (i: 4-7) are in the high set
8234 if (i <= 3)
8235 txpwr->u40.n.sdm[i] = (uint8)max_mid_mcs;
8236 else
8237 txpwr->u40.n.sdm[i] = (uint8)max_high_mcs;
8241 /* Fixup 40Mhz per-mcs limits */
8242 if (li_mimo == &locale_an1_t4 ||
8243 li_mimo == &locale_an6 ||
8244 li_mimo == &locale_an6_2) {
8245 uint max_low_mcs, max_mid_mcs, max_high_mcs;
8247 /* Fixup per-MCS */
8248 max_low_mcs = 0;
8249 max_mid_mcs = 0;
8250 max_high_mcs = 0;
8252 if (li_mimo == &locale_an1_t4) {
8253 if (chan == 3 || chan == 9) {
8254 max_low_mcs = QDB(10);
8255 max_mid_mcs = QDB(11);
8256 max_high_mcs = 46; /* 11.5 dBm */
8257 } else if (chan >= 4 && chan <= 8) {
8258 max_low_mcs = QDB(12);
8259 max_mid_mcs = QDB(13);
8260 max_high_mcs = 54; /* 13.5 dBm */
8262 } else if (li_mimo == &locale_an6) {
8263 if (chan == 3) {
8264 max_low_mcs = 66; /* 16.5 dBm */
8265 max_mid_mcs = 70; /* 17.5 dBm */
8266 max_high_mcs = QDB(18);
8267 } else if (chan == 4) {
8268 max_low_mcs = 70; /* 17.5 dBm */
8269 max_mid_mcs = 74; /* 18.5 dBm */
8270 max_high_mcs = QDB(19);
8271 } else if (chan >= 5 && chan <= 7) {
8272 max_low_mcs = QDB(19);
8273 max_mid_mcs = QDB(20);
8274 max_high_mcs = 82; /* 20.5 dBm */
8275 } else if (chan == 8) {
8276 max_low_mcs = 70; /* 17.5 dBm */
8277 max_mid_mcs = 74; /* 18.5 dBm */
8278 max_high_mcs = QDB(19);
8279 } else if (chan == 9) {
8280 max_low_mcs = 62; /* 15.5 dBm */
8281 max_mid_mcs = 66; /* 16.5 dBm */
8282 max_high_mcs = QDB(17);
8284 } else if (li_mimo == &locale_an6_2) {
8285 if (chan == 3) {
8286 max_low_mcs = 46; /* 11.5 dBm */
8287 max_mid_mcs = QDB(12);
8288 max_high_mcs = 50; /* 12.5 dBm */
8289 } else if (chan == 4) {
8290 max_low_mcs = QDB(12);
8291 max_mid_mcs = 50; /* 12.5 dBm */
8292 max_high_mcs = QDB(13);
8293 } else if (chan >= 5 && chan <= 7) {
8294 max_low_mcs = 50; /* 12.5 dBm */
8295 max_mid_mcs = 54; /* 13.5 dBm */
8296 max_high_mcs = 58; /* 14.5 dBm */
8297 } else if (chan == 8) {
8298 max_low_mcs = QDB(12);
8299 max_mid_mcs = QDB(13);
8300 max_high_mcs = QDB(14);
8301 } else if (chan == 9) {
8302 max_low_mcs = 46; /* 11.5 dBm */
8303 max_mid_mcs = 50; /* 12.5 dBm */
8304 max_high_mcs = 54; /* 13.5 dBm */
8308 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8309 /* MCS 0-4 are in the low set
8310 * MCS 5-7 are in the mid set
8312 if (i <= 4)
8313 txpwr->u40.n.cdd[i] = (uint8)max_low_mcs;
8314 else
8315 txpwr->u40.n.cdd[i] = (uint8)max_mid_mcs;
8318 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8319 /* MCS 8-11 (i: 0-3) are in the mid set
8320 * MCS 12-15 (i: 4-7) are in the high set
8322 if (i <= 3)
8323 txpwr->u40.n.sdm[i] = (uint8)max_mid_mcs;
8324 else
8325 txpwr->u40.n.sdm[i] = (uint8)max_high_mcs;
8329 /* Per MCS fixup for CLM 4.2.3 */
8330 if ((li_mimo == &locale_1cn) || (li_mimo == &locale_8cn) ||
8331 (li_mimo == &locale_19ln_4) || (li_mimo == &locale_11ln_4)) {
8332 uint max_low_mcs, max_mid_mcs, max_high_mcs, max_mid_mcs_sdm;
8334 max_low_mcs = 0;
8335 max_mid_mcs = 0;
8336 max_high_mcs = 0;
8337 max_mid_mcs_sdm = 0;
8338 if ((((li_mimo == &locale_1cn) || (li_mimo == &locale_19ln_4)) &&
8339 (chan >= 36 && chan <= 48)) || (((li_mimo == &locale_11ln_4) ||
8340 (li_mimo == &locale_8cn)) && (chan >= 56 && chan <= 64))) {
8341 max_low_mcs = 26; /* 6.5 dBm */
8342 max_mid_mcs = 26; /* MCS 4-7 */
8343 max_mid_mcs_sdm = QDB(10); /* MCS 7-11 (SDM) */
8344 max_high_mcs = QDB(11);
8346 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8347 /* MCS 0-4 are in the low set
8348 * MCS 5-7 are in the mid set
8350 if (i <= 4)
8351 txpwr->u20.n.cdd[i] = (uint8)max_low_mcs;
8352 else
8353 txpwr->u20.n.cdd[i] = (uint8)max_mid_mcs;
8356 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8357 /* MCS 8-11 (i: 0-3) are in the mid set
8358 * MCS 12-15 (i: 4-7) are in the high set
8360 if (i <= 3)
8361 txpwr->u20.n.sdm[i] = (uint8)max_mid_mcs_sdm;
8362 else
8363 txpwr->u20.n.sdm[i] = (uint8)max_high_mcs;
8366 /* fixup 40MHz */
8367 if ((((li_mimo == &locale_1cn) || (li_mimo == &locale_19ln_4)) &&
8368 (chan >= 36 && chan <= 48)) || (((li_mimo == &locale_11ln_4) ||
8369 (li_mimo == &locale_8cn)) && (chan >= 56 && chan <= 64))) {
8370 max_low_mcs = QDB(9);
8371 max_mid_mcs = QDB(9);
8372 max_mid_mcs_sdm = QDB(12); /* MCS 7-11 (SDM) */
8373 max_high_mcs = QDB(14);
8375 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8376 /* MCS 0-4 are in the low set
8377 * MCS 5-7 are in the mid set
8379 if (i <= 4)
8380 txpwr->u40.n.cdd[i] = (uint8)max_low_mcs;
8381 else
8382 txpwr->u40.n.cdd[i] = (uint8)max_mid_mcs;
8385 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8386 /* MCS 8-11 (i: 0-3) are in the mid set
8387 * MCS 12-15 (i: 4-7) are in the high set
8389 if (i <= 3)
8390 txpwr->u40.n.sdm[i] = (uint8)max_mid_mcs_sdm;
8391 else
8392 txpwr->u40.n.sdm[i] = (uint8)max_high_mcs;
8397 /* Per MCS fixup for CLM 4.8.2 */
8398 if ((li_mimo == &locale_29bn_3) && (chan >= 36 && chan <= 48)) {
8399 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8400 txpwr->u20.n.cdd[i] = QDB(10);
8401 txpwr->u40.n.cdd[i] = QDB(12);
8406 /* Fixup 40Mhz per-mcs limits */
8407 if (li_mimo == &locale_an8_t2) {
8408 uint max_low_mcs, max_mid_mcs, max_high_mcs, max_mid_mcs_sdm;
8410 /* Fixup per-MCS */
8411 max_low_mcs = 0;
8412 max_mid_mcs = 0;
8413 max_high_mcs = 0;
8414 max_mid_mcs_sdm = 0;
8416 if (chan == 3) {
8417 max_low_mcs = QDB(13);
8418 max_mid_mcs = QDB(14);
8419 max_high_mcs = 58; /* 14.5 dBm */
8420 } else if (chan >= 4 && chan <= 8) {
8421 max_low_mcs = QDB(14);
8422 max_mid_mcs = QDB(15);
8423 max_high_mcs = 62; /* 15.5 dBm */
8424 } else if (chan == 9) {
8425 max_low_mcs = QDB(13);
8426 max_mid_mcs = QDB(14);
8427 max_high_mcs = 58; /* 14.5 dBm */
8430 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8431 /* MCS 0-4 are in the low set
8432 * MCS 5-7 are in the mid set
8434 if (i <= 4)
8435 txpwr->u40.n.cdd[i] = (uint8)max_low_mcs;
8436 else
8437 txpwr->u40.n.cdd[i] = (uint8)max_mid_mcs;
8440 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8441 /* MCS 8-11 (i: 0-3) are in the mid set
8442 * MCS 12-15 (i: 4-7) are in the high set
8444 if (i <= 3)
8445 txpwr->u40.n.sdm[i] = (uint8)max_mid_mcs;
8446 else
8447 txpwr->u40.n.sdm[i] = (uint8)max_high_mcs;
8451 if (li_mimo == &locale_11ln_2) {
8452 maxpwr20 = 0;
8453 maxpwr40 = 0;
8455 /* Fixup SISO */
8456 if (chan >= 36 && chan <= 48) {
8457 maxpwr20 = QDB(14);
8458 maxpwr40 = QDB(13);
8459 } else if (chan >= 52 && chan <= 64) {
8460 maxpwr20 = 58; /* 14.5 dBm */
8461 maxpwr40 = QDB(13);
8462 } else if (chan >= 100 && chan <= 140) {
8463 maxpwr20 = QDB(15);
8464 maxpwr40 = QDB(16);
8465 } else if (chan >= 149 && chan <= 165) {
8466 maxpwr20 = 70; /* 17.5 dBm */
8467 maxpwr40 = QDB(18);
8469 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8470 txpwr->u20.n.siso[i] = (uint8)maxpwr20;
8471 txpwr->u40.n.siso[i] = (uint8)maxpwr40;
8475 if (li_mimo == &locale_19n_1 ||
8476 li_mimo == &locale_19n_2 ||
8477 li_mimo == &locale_3jn_4 ||
8478 li_mimo == &locale_3rn_3 ||
8479 li_mimo == &locale_5ln_2 ||
8480 li_mimo == &locale_6an_1 ||
8481 li_mimo == &locale_7cn_1 ||
8482 li_mimo == &locale_8an_1 ||
8483 li_mimo == &locale_13n_2 ||
8484 li_mimo == &locale_25hn ||
8485 li_mimo == &locale_29dn_2 ||
8486 li_mimo == &locale_3en ||
8487 li_mimo == &locale_bn7 ||
8488 li_mimo == &locale_2n) {
8489 /* Fixup SISO */
8491 if (li_mimo == &locale_19n_1) {
8492 maxpwr20 = 0;
8493 maxpwr40 = 0;
8495 if (chan >= 36 && chan <= 44) {
8496 maxpwr20 = QDB(14);
8497 maxpwr40 = QDB(14);
8498 } else if (chan >= 46 && chan <= 48) {
8499 maxpwr20 = QDB(17);
8500 maxpwr40 = QDB(16);
8501 } else if (chan >= 52 && chan <= 60) {
8502 maxpwr20 = QDB(14);
8503 maxpwr40 = QDB(16);
8504 } else if (chan >= 62 && chan <= 64) {
8505 maxpwr20 = QDB(13);
8506 maxpwr40 = QDB(14);
8507 } else if (chan >= 100 && chan <= 108) {
8508 maxpwr20 = QDB(17);
8509 maxpwr40 = QDB(14);
8510 } else if (chan >= 110 && chan <= 140) {
8511 maxpwr20 = 50; /* 12.5 dBm */
8512 maxpwr40 = QDB(16);
8513 } else if (chan >= 149 && chan <= 165) {
8514 maxpwr20 = QDB(17);
8515 maxpwr40 = QDB(16);
8517 } else if (li_mimo == &locale_19n_2) {
8518 if (chan >= 36 && chan <= 48) {
8519 maxpwr20 = QDB(14);
8520 maxpwr40 = QDB(13);
8521 } else if (chan >= 52 && chan <= 140) {
8522 maxpwr20 = QDB(16);
8523 maxpwr40 = QDB(16);
8524 } else if (chan >= 149 && chan <= 165) {
8525 maxpwr20 = QDB(18);
8526 maxpwr40 = QDB(18);
8528 } else if (li_mimo == &locale_3jn_4) {
8529 maxpwr20 = 0;
8530 maxpwr40 = 0;
8532 if (chan >= 36 && chan <= 48) {
8533 maxpwr20 = QDB(15);
8534 maxpwr40 = QDB(13);
8535 } else if (chan >= 52 && chan <= 64) {
8536 maxpwr20 = QDB(10);
8537 maxpwr40 = QDB(10);
8538 } else if (chan >= 100 && chan <= 140) {
8539 maxpwr20 = QDB(16);
8540 maxpwr40 = QDB(16);
8542 } else if (li_mimo == &locale_3rn_3) {
8543 maxpwr20 = 0;
8544 maxpwr40 = 0;
8546 if ((chan >= 36 && chan <= 64) ||
8547 (chan >= 100 && chan <= 116) ||
8548 (chan >= 132 && chan <= 140)) {
8549 maxpwr20 = QDB(16);
8550 maxpwr40 = QDB(16);
8552 } else if (li_mimo == &locale_2n) {
8553 maxpwr20 = QDB(16);
8554 maxpwr40 = QDB(16);
8555 } else if (li_mimo == &locale_5ln_2) {
8556 maxpwr20 = 0;
8557 maxpwr40 = 0;
8559 if (chan >= 36 && chan <= 64) {
8560 maxpwr20 = QDB(15);
8561 maxpwr40 = QDB(16);
8562 } else if (chan >= 149 && chan <= 165) {
8563 maxpwr20 = QDB(16);
8564 maxpwr40 = QDB(16);
8566 } else if (li_mimo == &locale_6an_1) {
8567 maxpwr20 = 0;
8568 maxpwr40 = 0;
8570 if (chan >= 36 && chan <= 38) {
8571 maxpwr20 = QDB(15);
8572 maxpwr40 = QDB(14);
8573 } else if ((chan >= 40 && chan <= 48) ||
8574 (chan >= 52 && chan <= 64)) {
8575 maxpwr20 = QDB(15);
8576 maxpwr40 = QDB(17);
8577 } else if (chan >= 149 && chan <= 165) {
8578 maxpwr20 = QDB(17);
8579 maxpwr40 = QDB(17);
8581 } else if (li_mimo == &locale_7cn_1) {
8582 maxpwr20 = 0;
8583 maxpwr40 = 0;
8585 if (chan >= 149 && chan <= 165) {
8586 maxpwr20 = QDB(16);
8587 maxpwr40 = QDB(16);
8589 } else if (li_mimo == &locale_8an_1) {
8590 maxpwr20 = 0;
8591 maxpwr40 = 0;
8593 if (chan >= 56 && chan <= 64) {
8594 maxpwr20 = QDB(15);
8595 maxpwr40 = QDB(17);
8596 } else if (chan >= 100 && chan <= 102) {
8597 maxpwr20 = QDB(17);
8598 maxpwr40 = QDB(16);
8599 } else if ((chan >= 104 && chan <= 140) ||
8600 (chan >= 149 && chan <= 165)) {
8601 maxpwr20 = QDB(17);
8602 maxpwr40 = QDB(17);
8604 } else if (li_mimo == &locale_13n_2) {
8605 maxpwr20 = 0;
8606 maxpwr40 = 0;
8608 if (chan >= 36 && chan <= 64) {
8609 maxpwr20 = QDB(16);
8610 maxpwr40 = QDB(16);
8612 } else if (li_mimo == &locale_25hn) {
8613 maxpwr20 = 0;
8614 maxpwr40 = 0;
8616 if (chan >= 36 && chan <= 48) {
8617 maxpwr20 = QDB(15);
8618 maxpwr40 = QDB(16);
8619 } else if (chan >= 52 && chan <= 64) {
8620 maxpwr20 = QDB(16);
8621 maxpwr40 = QDB(16);
8622 } else if ((chan >= 100 && chan <= 124) ||
8623 (chan >= 149 && chan <= 161)) {
8624 maxpwr20 = QDB(16);
8625 maxpwr40 = QDB(16);
8627 } else if (li_mimo == &locale_29dn_2) {
8628 maxpwr20 = 0;
8629 maxpwr40 = 0;
8631 if (chan >= 36 && chan <= 38) {
8632 maxpwr20 = QDB(15);
8633 maxpwr40 = QDB(14);
8634 } else if (chan >= 40 && chan <= 48) {
8635 maxpwr20 = QDB(15);
8636 maxpwr40 = QDB(17);
8637 } else if (chan >= 100 && chan <= 108) {
8638 maxpwr20 = QDB(17);
8639 maxpwr40 = QDB(16);
8640 } else if ((chan >= 52 && chan <= 64) ||
8641 (chan >= 110 && chan <= 116) ||
8642 (chan >= 132 && chan <= 140) ||
8643 (chan >= 149 && chan <= 165)) {
8644 maxpwr20 = QDB(17);
8645 maxpwr40 = QDB(17);
8647 } else if (li_mimo == &locale_3en) {
8648 if (chan >= 36 && chan <= 140) {
8649 maxpwr20 = QDB(21);
8650 maxpwr40 = QDB(20);
8654 if (li_mimo == &locale_bn7) {
8655 maxpwr20 = QDB(19);
8656 maxpwr40 = 0;
8657 if (chan >= 3 && chan <= 11) {
8658 maxpwr40 = QDB(16);
8662 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8663 txpwr->u20.n.siso[i] = (uint8)maxpwr20;
8664 txpwr->u40.n.siso[i] = (uint8)maxpwr40;
8668 if (li_mimo == &locale_19n_3) {
8669 maxpwr20 = 0;
8670 maxpwr40 = 0;
8672 /* Fixup SISO */
8673 if (chan >= 36 && chan <= 38) {
8674 maxpwr20 = QDB(13);
8675 maxpwr40 = QDB(11);
8676 } else if (chan >= 40 && chan <= 48) {
8677 maxpwr20 = 62; /* 15.5 dBm */
8678 maxpwr40 = 58; /* 14.5 dBm */
8679 } else if (chan >= 52 && chan <= 60) {
8680 maxpwr20 = 62; /* 15.5 dBm */
8681 maxpwr40 = 58; /* 14.5 dBm */
8682 } else if (chan >= 62 && chan <= 64) {
8683 maxpwr20 = QDB(13);
8684 maxpwr40 = 46; /* 11.5 dBm */
8685 } else if (chan >= 100 && chan <= 102) {
8686 maxpwr20 = 62; /* 15.5 dBm */
8687 maxpwr40 = 58; /* 14.5 dBm */
8688 } else if (chan >= 104 && chan <= 140) {
8689 maxpwr20 = 58; /* 14.5 dBm */
8690 maxpwr40 = 54; /* 13.5 dBm */
8691 } else if (chan >= 149 && chan <= 165) {
8692 maxpwr20 = 58; /* 14.5 dBm */
8693 maxpwr40 = 54; /* 13.5 dBm */
8695 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8696 txpwr->u20.n.siso[i] = (uint8)maxpwr20;
8697 txpwr->u40.n.siso[i] = (uint8)maxpwr40;
8702 if (li_mimo == &locale_19bn ||
8703 li_mimo == &locale_19hn ||
8704 li_mimo == &locale_19ln ||
8705 li_mimo == &locale_19rn ||
8706 li_mimo == &locale_19ln_1 ||
8707 li_mimo == &locale_19ln_2 ||
8708 li_mimo == &locale_19ln_4) {
8709 /* Fixup SISO */
8710 maxpwr20 = 0;
8711 maxpwr40 = 0;
8713 if (chan >= 36 && chan <= 44) {
8714 maxpwr20 = QDB(14);
8715 maxpwr40 = QDB(13);
8716 if (li_mimo == &locale_19ln_1)
8717 maxpwr40 = 58; /* 14.5 dBm */
8719 if (li_mimo == &locale_19ln_2)
8720 maxpwr20 = QDB(13);
8722 if (li_mimo == &locale_19ln_4) {
8723 maxpwr20 = QDB(13);
8724 maxpwr40 = QDB(16);
8727 } else if (chan >= 46 && chan <= 48) {
8728 if ((li_mimo == &locale_19ln_2) || (li_mimo == &locale_19ln_4)) {
8729 maxpwr20 = QDB(13);
8730 maxpwr40 = QDB(16);
8731 } else {
8732 maxpwr20 = QDB(14);
8733 maxpwr40 = 66; /* 16.5 dBm */
8735 } else if (chan >= 52 && chan <= 60) {
8736 maxpwr20 = 70; /* 17.5 dBm */
8737 maxpwr40 = QDB(17);
8738 } else if (chan >= 62 && chan <= 64) {
8739 if ((li_mimo == &locale_19ln_2) || (li_mimo == &locale_19ln_4)) {
8740 maxpwr20 = 58; /* 14.5 dBm */
8741 maxpwr40 = QDB(11);
8742 } else {
8743 maxpwr20 = 58; /* 14.5 dBm */
8744 maxpwr40 = QDB(13);
8746 } else if (chan >= 100 && chan <= 108) {
8747 if (li_mimo == &locale_19ln_2)
8748 maxpwr20 = 58; /* 14.5 dBm */
8749 else
8750 maxpwr20 = QDB(17);
8751 maxpwr40 = 62; /* 15.5 dBm */
8752 if (li_mimo == &locale_19ln_4) {
8753 maxpwr20 = 58; /* 14.5 dBm */
8754 maxpwr40 = 54; /* 13.5 dBm */
8756 } else if (chan >= 110 && chan <= 140) {
8757 maxpwr20 = QDB(17);
8758 maxpwr40 = QDB(18);
8759 if (chan >= 134 && chan <= 136) {
8760 if (li_mimo == &locale_19ln_1)
8761 maxpwr40 = QDB(17);
8762 else if ((li_mimo == &locale_19ln_2) || (li_mimo == &locale_19ln_4))
8763 maxpwr40 = QDB(15);
8765 if (chan == 140 &&
8766 (li_mimo == &locale_19ln_2 || (li_mimo == &locale_19ln_1) ||
8767 (li_mimo == &locale_19ln_4))) {
8768 maxpwr20 = QDB(15);
8769 maxpwr40 = 0;
8771 } else if (chan >= 149 && chan <= 165) {
8772 maxpwr20 = 70; /* 17.5 dBm */
8773 maxpwr40 = 74; /* 18.5 dBm */
8776 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8777 txpwr->u20.n.siso[i] = (uint8)maxpwr20;
8778 txpwr->u40.n.siso[i] = (uint8)maxpwr40;
8782 if (li_mimo == &locale_19hn_1) {
8783 /* Fixup SISO */
8784 maxpwr20 = 0;
8785 maxpwr40 = 0;
8787 if (chan >= 36 && chan <= 48) {
8788 maxpwr20 = QDB(14);
8789 maxpwr40 = 62 /* 15.5 */;
8790 } else if (chan >= 52 && chan <= 60) {
8791 maxpwr20 = 70 /* 17.5 */;
8792 maxpwr40 = 70;
8793 } else if (chan >= 62 && chan <= 64) {
8794 maxpwr20 = 62;
8795 maxpwr40 = 62;
8796 } else if (chan >= 100 && chan <= 102) {
8797 maxpwr20 = 66 /* 16.5 */;
8798 maxpwr40 = 62;
8799 } else if (chan >= 104 && chan <= 132) {
8800 maxpwr20 = 66 /* 16.5 */;
8801 maxpwr40 = 66;
8802 } else if (chan >= 134 && chan <= 136) {
8803 maxpwr20 = 66 /* 16.5 */;
8804 maxpwr40 = 70;
8805 } else if (chan == 140) {
8806 maxpwr20 = 58 /* 14.5 */;
8807 } else if (chan >= 149 && chan <= 165) {
8808 maxpwr20 = 74 /* 18.5 */;
8809 maxpwr40 = 70;
8812 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8813 txpwr->u20.n.siso[i] = (uint8)maxpwr20;
8814 txpwr->u40.n.siso[i] = (uint8)maxpwr40;
8817 /* CLM 4.2.3 fixup chan 100-140 CDD power */
8818 if ((li_mimo == &locale_19ln_4) || (li_mimo == &locale_11ln_4)) {
8819 if (chan >= 100 && chan <= 108) {
8820 maxpwr20 = QDB(13);
8821 maxpwr40 = QDB(12);
8822 } else if (chan >= 110 && chan <= 132) {
8823 maxpwr20 = 58; /* 14.5 dBm */
8824 maxpwr40 = QDB(17);
8825 } else if (chan >= 134 && chan <= 136) {
8826 maxpwr20 = 58; /* 14.5 dBm */
8827 maxpwr40 = 62; /* 15.5 dBm */
8828 } else if (chan == 140) {
8829 maxpwr20 = QDB(17);
8830 maxpwr40 = QDB(18);
8832 if ((chan >= 100) && (chan <= 140)) {
8833 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8834 txpwr->u20.n.cdd[i] = (uint8)maxpwr20;
8835 txpwr->u40.n.cdd[i] = (uint8)maxpwr40;
8840 if (li_mimo == &locale_29n || li_mimo == &locale_29an) {
8841 /* Fixup SISO */
8842 maxpwr20 = 0;
8843 maxpwr40 = 0;
8845 if (chan >= 36 && chan <= 48) {
8846 maxpwr20 = QDB(14);
8847 maxpwr40 = QDB(14);
8848 } else if ((chan >= 52 && chan <= 64) ||
8849 (chan >= 100 && chan <= 140) ||
8850 (chan >= 149 && chan <= 165)) {
8851 maxpwr20 = QDB(16);
8852 maxpwr40 = QDB(16);
8855 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8856 txpwr->u20.n.siso[i] = (uint8)maxpwr20;
8857 txpwr->u40.n.siso[i] = (uint8)maxpwr40;
8861 /* Copy the 40 MHz MCS0-7 CDD value to the 40 MHz OFDM CDD value if it wasn't
8862 * provided explicitly. When doing so, the constellation and coding rates of
8863 * the corresponding Legacy OFDM and MCS rates should be matched in the same way
8864 * as done in wlc_phy_mcs_to_ofdm_powers_nphy(). Specifically, the power of 9 Mbps
8865 * Legacy OFDM is set to the power of MCS-0 (same as 6 Mbps power) since no equivalent
8866 * of 9 Mbps exists in the 11n standard in terms of constellation and coding rate.
8868 for (i = 0, j = 0; i < WL_NUM_RATES_OFDM; i++, j++) {
8869 if (txpwr->ofdm_40_cdd[i] == 0)
8870 txpwr->ofdm_40_cdd[i] = txpwr->u40.n.cdd[j];
8871 if (i == 0) {
8872 i = i + 1;
8873 if (txpwr->ofdm_40_cdd[i] == 0)
8874 txpwr->ofdm_40_cdd[i] = txpwr->u40.n.cdd[j];
8878 /* Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO value if it wasn't
8879 * provided explicitly. Note the CDD value might be zero if 40 MHZ operations are
8880 * not allowed.
8883 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8884 if (txpwr->u40.n.siso[i] == 0)
8885 txpwr->u40.n.siso[i] = txpwr->u40.n.cdd[i];
8888 /* Copy the 40 MHz MCS0-7 SISO value to the 40 MHz OFDM SISO value if it wasn't
8889 * provided explicitly. When doing so, the constellation and coding rates of
8890 * the corresponding Legacy OFDM and MCS rates should be matched in the same way
8891 * as done in wlc_phy_mcs_to_ofdm_powers_nphy(). Specifically, the power of 9 Mbps
8892 * Legacy OFDM is set to the power of MCS-0 (same as 6 Mbps power) since no equivalent
8893 * of 9 Mbps exists in the 11n standard in terms of constellation and coding rate.
8895 for (i = 0, j = 0; i < WL_NUM_RATES_OFDM; i++, j++) {
8896 if (txpwr->ofdm_40[i] == 0)
8897 txpwr->ofdm_40[i] = txpwr->u40.n.siso[j];
8898 if (i == 0) {
8899 i = i + 1;
8900 if (txpwr->ofdm_40[i] == 0)
8901 txpwr->ofdm_40[i] = txpwr->u40.n.siso[j];
8905 /* Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding STBC values if they weren't
8906 * provided explicitly.
8908 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
8909 if (txpwr->u20.n.stbc[i] == 0)
8910 txpwr->u20.n.stbc[i] = txpwr->u20.n.cdd[i];
8912 if (txpwr->u40.n.stbc[i] == 0)
8913 txpwr->u40.n.stbc[i] = txpwr->u40.n.cdd[i];
8916 #if HTCONF
8917 if (WLCISHTPHY(wlc->band)) {
8918 n2x2_t u20pl, u40pl, u20npl, u40npl;
8920 li_mimo = NULL;
8921 if (IS_CCODE_REV(wlc_cm, "Q2", 4)) {
8922 li_mimo = BAND_5G(band->bandtype) ?
8923 wlc_get_mimo_5g(LOCALE_MIMO_IDX_27en_3n) :
8924 wlc_get_mimo_2g(LOCALE_MIMO_IDX_an6_4_3n);
8925 } else if (IS_CCODE_REV(wlc_cm, "EU", 9)) {
8926 li_mimo = BAND_5G(band->bandtype) ?
8927 wlc_get_mimo_5g(LOCALE_MIMO_IDX_18n_1_3n) :
8928 wlc_get_mimo_2g(LOCALE_MIMO_IDX_bn_10_3n);
8929 } else if (IS_CCODE_REV(wlc_cm, "US", 61) ||
8930 (IS_CCODE_REV(wlc_cm, "US", 53))) {
8931 li_mimo = BAND_5G(band->bandtype) ?
8932 wlc_get_mimo_5g(LOCALE_MIMO_IDX_19_3n) :
8933 wlc_get_mimo_2g(LOCALE_MIMO_IDX_a_3n);
8934 } else if (IS_CCODE_REV(wlc_cm, "US", 72)) {
8935 li_mimo = BAND_5G(band->bandtype) ?
8936 wlc_get_mimo_5g(LOCALE_MIMO_IDX_19_3n) :
8937 wlc_get_mimo_2g(LOCALE_MIMO_IDX_an6_4_3n);
8938 } else if (IS_CCODE_REV(wlc_cm, "US", 73)) {
8939 li_mimo = BAND_5G(band->bandtype) ?
8940 wlc_get_mimo_5g(LOCALE_MIMO_IDX_29_3n) :
8941 wlc_get_mimo_2g(LOCALE_MIMO_IDX_a1_3n);
8942 } else if (IS_CCODE_REV(wlc_cm, "GB", 6)) {
8943 li_mimo = BAND_5G(band->bandtype) ?
8944 wlc_get_mimo_5g(LOCALE_MIMO_IDX_3_3n) :
8945 wlc_get_mimo_2g(LOCALE_MIMO_IDX_b2_3n);
8949 /* Copy the 20 in 40MHz CCK, OFDM, MCS0-7 values to the
8950 * corresponding values if they weren't provided explicitly.
8952 for (i = 0; i < WL_NUM_RATES_CCK; i++) {
8953 if (li_mimo == &locale_a_3n) {
8954 /* Using CCK CDD 1x3 power limits for 1x2 as well
8955 * As they are not defined in CLM.
8957 if ((chan == 1) || (chan == 11)) {
8958 txpwr->cck_cdd.s1x2[i] = QDB(16);
8959 txpwr->cck_cdd.s1x3[i] = QDB(16);
8960 txpwr->cck_20ul_cdd.s1x2[i] = QDB(16);
8961 txpwr->cck_20ul_cdd.s1x3[i] = QDB(16);
8962 } else if ((chan >= 2) && (chan <= 10)) {
8963 txpwr->cck_cdd.s1x2[i] = QDB(18);
8964 txpwr->cck_cdd.s1x3[i] = QDB(18);
8965 txpwr->cck_20ul_cdd.s1x2[i] = QDB(18);
8966 txpwr->cck_20ul_cdd.s1x3[i] = QDB(18);
8970 if (li_mimo == &locale_a1_3n) {
8971 /* Using CCK CDD 1x3 power limits for 1x2 as well
8972 * As they are not defined in CLM.
8974 if (chan == 1) {
8975 txpwr->cck_cdd.s1x2[i] = QDB(22);
8976 txpwr->cck_cdd.s1x3[i] = QDB(21);
8977 txpwr->cck_20ul_cdd.s1x2[i] = QDB(22);
8978 txpwr->cck_20ul_cdd.s1x3[i] = QDB(21);
8979 } else if ((chan >= 2) && (chan <= 10)) {
8980 txpwr->cck_cdd.s1x2[i] = 94; /* 23.5 dBm */
8981 txpwr->cck_cdd.s1x3[i] = QDB(18);
8982 txpwr->cck_20ul_cdd.s1x2[i] = 94; /* 23.5 dBm */
8983 txpwr->cck_20ul_cdd.s1x3[i] = QDB(18);
8984 } else if (chan == 11) {
8985 txpwr->cck_cdd.s1x2[i] = QDB(22); /* 21.5 dBm */
8986 txpwr->cck_cdd.s1x3[i] = 86;
8987 txpwr->cck_20ul_cdd.s1x2[i] = QDB(22);
8988 txpwr->cck_20ul_cdd.s1x3[i] = 86;
8992 if (li_mimo == &locale_an6_7) {
8993 /* Using CCK CDD 1x2 power limits for 1x3 as well
8994 * As they are not defined in CLM.
8996 if (chan == 1) {
8997 txpwr->cck_cdd.s1x2[i] = QDB(22);
8998 txpwr->cck_cdd.s1x3[i] = QDB(21);
8999 txpwr->cck_20ul_cdd.s1x2[i] = QDB(22);
9000 txpwr->cck_20ul_cdd.s1x3[i] = QDB(21);
9001 } else if ((chan >= 2) && (chan <= 10)) {
9002 txpwr->cck_cdd.s1x2[i] = 94; /* 23.5 dBm */
9003 txpwr->cck_cdd.s1x3[i] = QDB(22);
9004 txpwr->cck_20ul_cdd.s1x2[i] = 94;
9005 txpwr->cck_20ul_cdd.s1x3[i] = QDB(22);
9006 } else if (chan == 11) {
9007 txpwr->cck_cdd.s1x2[i] = QDB(22);
9008 txpwr->cck_cdd.s1x3[i] = 86; /* 21.5 dBm */
9009 txpwr->cck_20ul_cdd.s1x2[i] = QDB(22);
9010 txpwr->cck_20ul_cdd.s1x3[i] = 86;
9014 if (txpwr->cck_20ul[i] == 0)
9015 txpwr->cck_20ul[i] = txpwr->cck[i];
9016 if (txpwr->cck_cdd.s1x2[i] == 0)
9017 txpwr->cck_cdd.s1x2[i] = txpwr->cck[i];
9018 if (txpwr->cck_cdd.s1x3[i] == 0)
9019 txpwr->cck_cdd.s1x3[i] = txpwr->cck[i];
9020 if (txpwr->cck_20ul_cdd.s1x2[i] == 0)
9021 txpwr->cck_20ul_cdd.s1x2[i] = txpwr->cck_20ul[i];
9022 if (txpwr->cck_20ul_cdd.s1x3[i] == 0)
9023 txpwr->cck_20ul_cdd.s1x3[i] = txpwr->cck_20ul[i];
9027 for (i = 0; i < WL_NUM_RATES_OFDM; i++) {
9028 if (txpwr->ofdm_20ul[i] == 0)
9029 txpwr->ofdm_20ul[i] = txpwr->ofdm[i];
9030 if (txpwr->ofdm_20ul_cdd[i] == 0)
9031 txpwr->ofdm_20ul_cdd[i] = txpwr->ofdm_cdd[i];
9035 if (li_mimo) {
9036 maxpwr20 = li_mimo->maxpwr20[maxpwr_idx];
9037 maxpwr40 = li_mimo->maxpwr40[maxpwr_idx];
9039 if (li_mimo == &locale_19_3n) {
9040 if ((chan >= 100) && (chan <= 108)) {
9041 maxpwr20 = QDB(13);
9042 maxpwr40 = QDB(12);
9043 } else if ((chan >= 134) && (chan <= 136)) {
9044 maxpwr20 = 58; /* 14.5dbm */
9045 maxpwr40 = 62; /* 15.5dbm */
9046 } else if (chan == 140) {
9047 maxpwr20 = 54; /* 13.5dbm */
9048 maxpwr40 = QDB(18);
9052 if (li_mimo == &locale_29_3n) {
9053 if ((chan >= 100) && (chan <= 102)) {
9054 maxpwr20 = QDB(15);
9055 maxpwr40 = 42; /* 10.5 dBm */
9056 } else if ((chan >= 104) && (chan <= 140)) {
9057 maxpwr20 = 62; /* 15.5dbm */
9058 maxpwr40 = QDB(18);
9059 } else if ((chan >= 161) && (chan <= 165)) {
9060 maxpwr40 = 0;
9065 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
9066 if (li_mimo) {
9067 u20pl.sdm[i] = (uint8)maxpwr20;
9068 u20pl.cdd[i] = (uint8)maxpwr20;
9069 u40pl.sdm[i] = (uint8)maxpwr40;
9070 u40pl.cdd[i] = (uint8)maxpwr40;
9071 } else {
9072 u20pl.sdm[i] = txpwr->u20.n.sdm[i];
9073 u20pl.cdd[i] = txpwr->u20.n.cdd[i];
9074 u40pl.sdm[i] = txpwr->u40.n.sdm[i];
9075 u40pl.cdd[i] = txpwr->u40.n.cdd[i];
9079 /* txpwr->u20/40 declared is union of n/ht powerlimits,
9080 * so save the powerlimits for n, for using them later to fill ht.
9082 bcopy(&txpwr->u20, &u20npl, sizeof(n2x2_t));
9083 bcopy(&txpwr->u40, &u40npl, sizeof(n2x2_t));
9085 for (i = 0; i < WL_NUM_RATES_MCS_1STREAM; i++) {
9086 txpwr->u20.ht.s2x2[i] = u20npl.sdm[i];
9087 txpwr->u20.ht.s3x3[i] = u20pl.sdm[i];
9088 txpwr->ht.u20s1x3[i] = u20pl.cdd[i];
9089 txpwr->ht.u20s2x3[i] = u20pl.sdm[i];
9091 txpwr->u40.ht.s2x2[i] = u40npl.sdm[i];
9092 txpwr->u40.ht.s3x3[i] = u40pl.sdm[i];
9093 txpwr->ht.u40s1x3[i] = u40pl.cdd[i];
9094 txpwr->ht.u40s2x3[i] = u40pl.sdm[i];
9096 txpwr->ht20ul.s1x1[i] = u20npl.siso[i];
9097 txpwr->ht20ul.s1x2[i] = u20npl.cdd[i];
9098 txpwr->ht20ul.s2x2[i] = u20npl.sdm[i];
9099 txpwr->ht20ul.s3x3[i] = u20pl.sdm[i];
9100 txpwr->ht.ul20s1x3[i] = u20pl.cdd[i];
9101 txpwr->ht.ul20s2x3[i] = u20pl.sdm[i];
9102 #ifdef NOT_YET
9103 txpwr->stbc.s2x2[i] = txpwr->u20.ht.s2x2[i];
9104 txpwr->stbc.s2x3[i] = txpwr->ht.u20s2x3[i];
9105 txpwr->stbc.u40_s2x2[i] = txpwr->u40.ht.s2x2[i];
9106 txpwr->stbc.u40_s2x3[i] = txpwr->ht.u40s2x3[i];
9107 txpwr->stbc.ul20_s2x2[i] = txpwr->ht20ul.s2x2[i];
9108 txpwr->stbc.ul20_s2x3[i] = txpwr->ht.ul20s2x3[i];
9109 #endif
9110 if (li_mimo == &locale_19_3n) {
9111 if ((chan >= 36) && (chan <= 48)) {
9112 /* MCS 0-7 has seperate CDD limits defined,
9113 * set them here
9115 txpwr->ht.u20s1x3[i] = 14; /* 3.5 dbm */
9116 txpwr->ht.u40s1x3[i] = QDB(7);
9117 txpwr->ht.ul20s1x3[i] = 14; /* 3.5 dbm */
9119 /* MCS 0-7 has seperate STBC limits defined,
9120 * set them here
9122 #ifdef NOT_YET
9123 txpwr->stbc.s2x3[i] = QDB(7);
9124 txpwr->stbc.u40_s2x3[i] = QDB(9);
9125 txpwr->stbc.ul20_s2x3[i] = QDB(7);
9126 #endif
9128 if (i <= 3) {
9129 txpwr->ht.u20s2x3[i] = QDB(8);
9130 txpwr->ht.u40s2x3[i] = QDB(10);
9131 } else {
9132 txpwr->ht.u20s2x3[i] = QDB(9);
9133 txpwr->ht.u40s2x3[i] = QDB(12);
9135 if (i <= 2) {
9136 txpwr->u20.ht.s3x3[i] = QDB(8);
9137 txpwr->u40.ht.s3x3[i] = QDB(10);
9138 } else if (i <= 5) {
9139 txpwr->u20.ht.s3x3[i] = QDB(9);
9140 txpwr->u40.ht.s3x3[i] = QDB(12);
9141 } else {
9142 txpwr->u20.ht.s3x3[i] = QDB(10);
9143 txpwr->u40.ht.s3x3[i] = QDB(13);
9148 if (li_mimo == &locale_29_3n) {
9149 if ((chan >= 36) && (chan <= 48)) {
9150 /* MCS 0-7 has seperate CDD limits defined,
9151 * set them here
9153 txpwr->ht.ul20s1x3[i] = 0;
9154 txpwr->ht.u20s1x3[i] = 0; /* disabled */
9155 txpwr->ht.u40s1x3[i] = 0;
9158 /* MCS 0-7 has seperate STBC limits defined,
9159 * set them here
9161 #ifdef NOT_YET
9162 txpwr->stbc.s2x3[i] = QDB(10);
9163 txpwr->stbc.u40_s2x3[i] = QDB(13);
9164 txpwr->stbc.ul20_s2x3[i] = QDB(10);
9165 #endif
9167 /* SDM (MCS8-15) */
9168 txpwr->ht.u20s2x3[i] = 41; /* 10.25 dBm */
9169 txpwr->ht.u40s2x3[i] = QDB(13);
9170 txpwr->ht.ul20s2x3[i] = 41;
9173 if ((chan >= 52) && (chan <= 60)) {
9174 /* MCS 0-7 has seperate CDD limits defined,
9175 * set them here
9177 txpwr->ht.ul20s1x3[i] = 46 /* 11.5 */;
9178 txpwr->ht.u40s1x3[i] = 54; /* 13.5 */
9179 txpwr->ht.u20s1x3[i] = 46;
9181 /* MCS 0-7 has seperate STBC limits defined,
9182 * set them here
9184 #ifdef NOT_YET
9185 txpwr->stbc.s2x3[i] = 62; /* 15.5 */
9186 txpwr->stbc.u40_s2x3[i] = QDB(18);
9187 txpwr->stbc.ul20_s2x3[i] = 62;
9188 #endif
9191 if ((chan >= 62) && (chan <= 64)) {
9192 /* MCS 0-7 has seperate CDD limits defined,
9193 * set them here
9195 txpwr->ht.ul20s1x3[i] = 46 /* 11.5 */;
9196 txpwr->ht.u40s1x3[i] = 46;
9197 txpwr->ht.u20s1x3[i] = 46;
9199 /* MCS 0-7 has seperate STBC limits defined,
9200 * set them here
9202 #ifdef NOT_YET
9203 txpwr->stbc.s2x3[i] = QDB(15);
9204 txpwr->stbc.u40_s2x3[i] = 50; /* 12.5 dBm */
9205 txpwr->stbc.ul20_s2x3[i] = QDB(15);
9206 #endif
9209 if ((chan >= 100) && (chan <= 102)) {
9210 /* MCS 0-7 has seperate CDD limits defined,
9211 * set them here
9213 txpwr->ht.ul20s1x3[i] = 54 /* 13.5 */;
9214 txpwr->ht.u40s1x3[i] = 38; /* 9.5 */
9215 txpwr->ht.u20s1x3[i] = 54;
9217 /* MCS 0-7 has seperate STBC limits defined,
9218 * set them here
9220 #ifdef NOT_YET
9221 txpwr->stbc.s2x3[i] = QDB(15);
9222 txpwr->stbc.u40_s2x3[i] = 42; /* 10.5 dBm */
9223 txpwr->stbc.ul20_s2x3[i] = QDB(15);
9224 #endif
9227 if ((chan >= 104) && (chan <= 140)) {
9228 /* MCS 0-7 has seperate CDD limits defined,
9229 * set them here
9231 txpwr->ht.ul20s1x3[i] = 54 /* 13.5 */;
9232 txpwr->ht.u40s1x3[i] = 53; /* 13.25 */
9233 txpwr->ht.u20s1x3[i] = 54;
9235 /* MCS 0-7 has seperate STBC limits defined,
9236 * set them here
9238 #ifdef NOT_YET
9239 txpwr->stbc.s2x3[i] = 62; /* 15.5 dBm */
9240 txpwr->stbc.u40_s2x3[i] = QDB(18);
9241 txpwr->stbc.ul20_s2x3[i] = 62;
9242 #endif
9248 #endif /* HTCONF */
9249 #endif /* WL11N */
9251 WL_NONE(("Channel(chanspec) %d (0x%4.4x)\n", CHSPEC_CHANNEL(chanspec), chanspec));
9252 #ifdef WLC_LOW
9253 /* Convoluted WL debug conditional execution of function to avoid warnings. */
9254 WL_NONE(("%s", (wlc_phy_txpower_limits_dump(txpwr, WLCISHTPHY(wlc->band)), "")));
9255 #endif /* WLC_LOW */
9257 return;
9260 /* Returns TRUE if currently set country is Japan or variant */
9261 bool
9262 wlc_japan(struct wlc_info *wlc)
9264 return wlc_japan_ccode(wlc->cmi->country_abbrev);
9267 /* JP, J1 - J10 are Japan ccodes */
9268 static bool
9269 wlc_japan_ccode(const char *ccode)
9271 return (ccode[0] == 'J' &&
9272 (ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9')));
9275 /* Q2 is an alternate USA ccode */
9276 static bool
9277 wlc_us_ccode(const char *ccode)
9279 return (!strncmp("US", ccode, 3) || !strncmp("Q2", ccode, 3));
9282 void
9283 wlc_rcinfo_init(wlc_cm_info_t *wlc_cm)
9285 if (wlc_us_ccode(wlc_cm->country_abbrev)) {
9286 #ifdef BAND5G
9287 wlc_cm->rcinfo_list[WLC_RCLIST_20] = &rcinfo_us_20;
9288 #endif
9289 #ifdef WL11N
9290 if (N_ENAB(wlc_cm->wlc->pub)) {
9291 wlc_cm->rcinfo_list[WLC_RCLIST_40L] = &rcinfo_us_40lower;
9292 wlc_cm->rcinfo_list[WLC_RCLIST_40U] = &rcinfo_us_40upper;
9294 #endif
9295 } else if (wlc_japan_ccode(wlc_cm->country_abbrev)) {
9296 #ifdef BAND5G
9297 wlc_cm->rcinfo_list[WLC_RCLIST_20] = &rcinfo_jp_20;
9298 #endif
9299 #ifdef WL11N
9300 if (N_ENAB(wlc_cm->wlc->pub)) {
9301 wlc_cm->rcinfo_list[WLC_RCLIST_40L] = &rcinfo_jp_40;
9302 wlc_cm->rcinfo_list[WLC_RCLIST_40U] = &rcinfo_jp_40;
9304 #endif
9305 } else {
9306 #ifdef BAND5G
9307 wlc_cm->rcinfo_list[WLC_RCLIST_20] = &rcinfo_eu_20;
9308 #endif
9309 #ifdef WL11N
9310 if (N_ENAB(wlc_cm->wlc->pub)) {
9311 wlc_cm->rcinfo_list[WLC_RCLIST_40L] = &rcinfo_eu_40lower;
9312 wlc_cm->rcinfo_list[WLC_RCLIST_40U] = &rcinfo_eu_40upper;
9314 #endif
9318 static void
9319 wlc_regclass_vec_init(wlc_cm_info_t *wlc_cm)
9321 uint8 i, idx;
9322 chanspec_t chanspec;
9323 #ifdef WL11N
9324 wlc_info_t *wlc = wlc_cm->wlc;
9325 bool saved_cap_40, saved_db_cap_40 = TRUE;
9326 #endif
9327 rcvec_t *rcvec = &wlc_cm->valid_rcvec;
9329 #ifdef WL11N
9330 /* save 40 MHz cap */
9331 saved_cap_40 = wlc->band->mimo_cap_40;
9332 wlc->band->mimo_cap_40 = TRUE;
9333 if (NBANDS(wlc) > 1) {
9334 saved_db_cap_40 = wlc->bandstate[OTHERBANDUNIT(wlc)]->mimo_cap_40;
9335 wlc->bandstate[OTHERBANDUNIT(wlc)]->mimo_cap_40 = TRUE;
9337 #endif
9339 bzero(rcvec, MAXRCVEC);
9340 for (i = 0; i < MAXCHANNEL; i++) {
9341 chanspec = CH20MHZ_CHSPEC(i);
9342 if (wlc_valid_chanspec_db(wlc_cm, chanspec)) {
9343 if ((idx = wlc_get_regclass(wlc_cm, chanspec)))
9344 setbit(rcvec, idx);
9346 #if defined(WL11N) && !defined(WL11N_20MHZONLY)
9347 if (N_ENAB(wlc->pub)) {
9348 chanspec = CH40MHZ_CHSPEC(i, WL_CHANSPEC_CTL_SB_LOWER);
9349 if (wlc_valid_chanspec_db(wlc_cm, chanspec)) {
9350 if ((idx = wlc_get_regclass(wlc_cm, chanspec)))
9351 setbit(rcvec, idx);
9353 chanspec = CH40MHZ_CHSPEC(i, WL_CHANSPEC_CTL_SB_UPPER);
9354 if (wlc_valid_chanspec_db(wlc_cm, chanspec)) {
9355 if ((idx = wlc_get_regclass(wlc_cm, chanspec)))
9356 setbit(rcvec, idx);
9359 #endif /* defined(WL11N) && !defined(WL11N_20MHZONLY) */
9361 #ifdef WL11N
9362 /* restore 40 MHz cap */
9363 wlc->band->mimo_cap_40 = saved_cap_40;
9364 if (NBANDS(wlc) > 1)
9365 wlc->bandstate[OTHERBANDUNIT(wlc)]->mimo_cap_40 = saved_db_cap_40;
9366 #endif
9369 #ifdef WL11N
9370 uint8
9371 wlc_rclass_extch_get(wlc_cm_info_t *wlc_cm, uint8 rclass)
9373 const rcinfo_t *rcinfo;
9374 uint8 i, extch = DOT11_EXT_CH_NONE;
9376 if (!isset(wlc_cm->valid_rcvec.vec, rclass)) {
9377 WL_ERROR(("wl%d: %s %d regulatory class not supported\n",
9378 wlc_cm->wlc->pub->unit, wlc_cm->country_abbrev, rclass));
9379 return extch;
9382 /* rcinfo consist of control channel at lower sb */
9383 rcinfo = wlc_cm->rcinfo_list[WLC_RCLIST_40L];
9384 for (i = 0; rcinfo && i < rcinfo->len; i++) {
9385 if (rclass == rcinfo->rctbl[i].rclass) {
9386 /* ext channel is opposite of control channel */
9387 extch = DOT11_EXT_CH_UPPER;
9388 goto exit;
9392 /* rcinfo consist of control channel at upper sb */
9393 rcinfo = wlc_cm->rcinfo_list[WLC_RCLIST_40U];
9394 for (i = 0; rcinfo && i < rcinfo->len; i++) {
9395 if (rclass == rcinfo->rctbl[i].rclass) {
9396 /* ext channel is opposite of control channel */
9397 extch = DOT11_EXT_CH_LOWER;
9398 break;
9401 exit:
9402 WL_INFORM(("wl%d: %s regulatory class %d has ctl chan %s\n",
9403 wlc_cm->wlc->pub->unit, wlc_cm->country_abbrev, rclass,
9404 ((!extch) ? "NONE" : (((extch == DOT11_EXT_CH_LOWER) ? "LOWER" : "UPPER")))));
9406 return extch;
9409 /* get the ordered list of supported reg class, with current reg class
9410 * as first element
9412 uint8
9413 wlc_get_regclass_list(wlc_cm_info_t *wlc_cm, uint8 *rclist, uint lsize,
9414 chanspec_t chspec, bool ie_order)
9416 uint8 i, cur_rc = 0, idx = 0;
9418 ASSERT(rclist != NULL);
9419 ASSERT(lsize > 1);
9421 if (ie_order) {
9422 cur_rc = wlc_get_regclass(wlc_cm, chspec);
9423 if (!cur_rc) {
9424 WL_ERROR(("wl%d: current regulatory class is not found\n",
9425 wlc_cm->wlc->pub->unit));
9426 return 0;
9428 rclist[idx++] = cur_rc; /* first element is current reg class */
9431 for (i = 0; i < MAXREGCLASS && idx < lsize; i++) {
9432 if (i != cur_rc && isset(wlc_cm->valid_rcvec.vec, i))
9433 rclist[idx++] = i;
9436 if (i < MAXREGCLASS && idx == lsize) {
9437 WL_ERROR(("wl%d: regulatory class list full %d\n", wlc_cm->wlc->pub->unit, idx));
9438 ASSERT(0);
9441 return idx;
9443 #endif /* WL11N */
9445 static uint8
9446 wlc_get_2g_regclass(wlc_cm_info_t *wlc_cm, uint8 chan)
9448 if (wlc_us_ccode(wlc_cm->country_abbrev))
9449 return WLC_REGCLASS_USA_2G_20MHZ;
9450 else if (wlc_japan_ccode(wlc_cm->country_abbrev)) {
9451 if (chan < 14)
9452 return WLC_REGCLASS_JPN_2G_20MHZ;
9453 else
9454 return WLC_REGCLASS_JPN_2G_20MHZ_CH14;
9455 } else
9456 return WLC_REGCLASS_EUR_2G_20MHZ;
9459 uint8
9460 wlc_get_regclass(wlc_cm_info_t *wlc_cm, chanspec_t chanspec)
9462 const rcinfo_t *rcinfo = NULL;
9463 uint8 i;
9464 uint8 chan;
9466 #ifdef WL11N
9467 if (CHSPEC_IS40(chanspec)) {
9468 chan = wf_chspec_ctlchan(chanspec);
9469 if (CHSPEC_SB_UPPER(chanspec))
9470 rcinfo = wlc_cm->rcinfo_list[WLC_RCLIST_40U];
9471 else
9472 rcinfo = wlc_cm->rcinfo_list[WLC_RCLIST_40L];
9473 } else
9474 #endif /* WL11N */
9476 chan = CHSPEC_CHANNEL(chanspec);
9477 if (CHSPEC_IS2G(chanspec))
9478 return (wlc_get_2g_regclass(wlc_cm, chan));
9479 rcinfo = wlc_cm->rcinfo_list[WLC_RCLIST_20];
9482 for (i = 0; rcinfo != NULL && i < rcinfo->len; i++) {
9483 if (chan == rcinfo->rctbl[i].chan)
9484 return (rcinfo->rctbl[i].rclass);
9487 WL_INFORM(("wl%d: No regulatory class assigned for %s channel %d\n",
9488 wlc_cm->wlc->pub->unit, wlc_cm->country_abbrev, chan));
9490 return 0;
9493 #if defined(BCMDBG) || defined(BCMDBG_DUMP)
9495 wlc_dump_rclist(const char *name, uint8 *rclist, uint8 rclen, struct bcmstrbuf *b)
9497 uint i;
9499 if (!rclen)
9500 return 0;
9502 bcm_bprintf(b, "%s [ ", name ? name : "");
9503 for (i = 0; i < rclen; i++) {
9504 bcm_bprintf(b, "%d ", rclist[i]);
9506 bcm_bprintf(b, "]");
9507 bcm_bprintf(b, "\n");
9509 return 0;
9512 /* format a qdB value as integer and decimal fraction in a bcmstrbuf */
9513 static void
9514 wlc_channel_dump_qdb(struct bcmstrbuf *b, uint qdb)
9516 const char fraction[4][4] = {" ", ".25", ".5 ", ".75"};
9518 bcm_bprintf(b, "%2d%s",
9519 qdb / WLC_TXPWR_DB_FACTOR,
9520 fraction[qdb % WLC_TXPWR_DB_FACTOR]);
9523 /* helper function for wlc_channel_dump_txppr() to print one set of power targets with label */
9524 static void
9525 wlc_channel_dump_pwr_range(struct bcmstrbuf *b, const char *label, uint8 *ptr, uint count)
9527 uint i;
9529 bcm_bprintf(b, "%s ", label);
9530 for (i = 0; i < count; i++) {
9531 wlc_channel_dump_qdb(b, ptr[i]);
9532 bcm_bprintf(b, " ");
9534 bcm_bprintf(b, "\n");
9537 /* helper function to print a target range line with the typical 8 targets */
9538 static void
9539 wlc_channel_dump_pwr_range8(struct bcmstrbuf *b, const char *label, uint8 *ptr)
9541 wlc_channel_dump_pwr_range(b, label, ptr, 8);
9544 /* format the contents of a txppr_t struction for a bcmstrbuf */
9545 static void
9546 wlc_channel_dump_txppr(struct bcmstrbuf *b, txppr_t *txppr, int is_ht_format)
9548 bcm_bprintf(b, "20MHz:\n");
9549 wlc_channel_dump_pwr_range(b, "CCK ", txppr->cck, 4);
9550 wlc_channel_dump_pwr_range8(b, "OFDM ", txppr->ofdm);
9551 wlc_channel_dump_pwr_range8(b, "OFDM-CDD ", txppr->ofdm_cdd);
9553 if (!is_ht_format) {
9554 wlc_channel_dump_pwr_range8(b, "MCS-SISO ", txppr->u20.n.siso);
9555 wlc_channel_dump_pwr_range8(b, "MCS-CDD ", txppr->u20.n.cdd);
9556 wlc_channel_dump_pwr_range8(b, "MCS STBC ", txppr->u20.n.stbc);
9557 wlc_channel_dump_pwr_range8(b, "MCS 8~15 ", txppr->u20.n.sdm);
9558 } else {
9559 wlc_channel_dump_pwr_range8(b, "1 Nsts 1 Tx ", txppr->u20.ht.s1x1);
9560 wlc_channel_dump_pwr_range8(b, "1 Nsts 2 Tx ", txppr->u20.ht.s1x2);
9561 wlc_channel_dump_pwr_range8(b, "1 Nsts 3 Tx ", txppr->ht.u20s1x3);
9562 wlc_channel_dump_pwr_range8(b, "2 Nsts 2 Tx ", txppr->u20.ht.s2x2);
9563 wlc_channel_dump_pwr_range8(b, "2 Nsts 3 Tx ", txppr->ht.u20s2x3);
9564 wlc_channel_dump_pwr_range8(b, "3 Nsts 3 Tx ", txppr->u20.ht.s3x3);
9567 bcm_bprintf(b, "\n40MHz:\n");
9568 wlc_channel_dump_pwr_range8(b, "OFDM ", txppr->ofdm_40);
9569 wlc_channel_dump_pwr_range8(b, "OFDM-CDD ", txppr->ofdm_40_cdd);
9571 if (!is_ht_format) {
9572 wlc_channel_dump_pwr_range8(b, "MCS-SISO ", txppr->u40.n.siso);
9573 wlc_channel_dump_pwr_range8(b, "MCS-CDD ", txppr->u40.n.cdd);
9574 wlc_channel_dump_pwr_range8(b, "MCS STBC ", txppr->u40.n.stbc);
9575 wlc_channel_dump_pwr_range8(b, "MCS 8~15 ", txppr->u40.n.sdm);
9576 } else {
9577 wlc_channel_dump_pwr_range8(b, "1 Nsts 1 Tx ", txppr->u40.ht.s1x1);
9578 wlc_channel_dump_pwr_range8(b, "1 Nsts 2 Tx ", txppr->u40.ht.s1x2);
9579 wlc_channel_dump_pwr_range8(b, "1 Nsts 3 Tx ", txppr->ht.u40s1x3);
9580 wlc_channel_dump_pwr_range8(b, "2 Nsts 2 Tx ", txppr->u40.ht.s2x2);
9581 wlc_channel_dump_pwr_range8(b, "2 Nsts 3 Tx ", txppr->ht.u40s2x3);
9582 wlc_channel_dump_pwr_range8(b, "3 Nsts 3 Tx ", txppr->u40.ht.s3x3);
9585 bcm_bprintf(b, "MCS32 %2d\n", txppr->mcs32);
9587 bcm_bprintf(b, "\n20 in 40MHz:\n");
9588 wlc_channel_dump_pwr_range(b, "CCK ", txppr->cck_20ul, 4);
9589 wlc_channel_dump_pwr_range8(b, "OFDM ", txppr->ofdm_20ul);
9590 wlc_channel_dump_pwr_range8(b, "OFDM-CDD ", txppr->ofdm_20ul_cdd);
9592 wlc_channel_dump_pwr_range8(b, "1 Nsts 1 Tx ", txppr->ht20ul.s1x1);
9593 wlc_channel_dump_pwr_range8(b, "1 Nsts 2 Tx ", txppr->ht20ul.s1x2);
9594 wlc_channel_dump_pwr_range8(b, "1 Nsts 3 Tx ", txppr->ht.ul20s1x3);
9595 wlc_channel_dump_pwr_range8(b, "2 Nsts 2 Tx ", txppr->ht20ul.s2x2);
9596 wlc_channel_dump_pwr_range8(b, "2 Nsts 3 Tx ", txppr->ht.ul20s2x3);
9597 wlc_channel_dump_pwr_range8(b, "3 Nsts 3 Tx ", txppr->ht20ul.s3x3);
9599 bcm_bprintf(b, "\n");
9601 #endif /* BCMDBG || BCMDBG_DUMP */
9604 * if (wlc->country_list_extended) all country listable.
9605 * else J1 - J10 is excluded.
9607 static bool
9608 wlc_country_listable(struct wlc_info *wlc, const char *countrystr)
9610 bool listable = TRUE;
9612 if (wlc->country_list_extended == FALSE) {
9613 if (countrystr[0] == 'J' &&
9614 (countrystr[1] >= '1' && countrystr[1] <= '9'))
9615 listable = FALSE;
9618 return listable;
9621 static bool
9622 wlc_buffalo_map_locale(struct wlc_info *wlc, const char* abbrev)
9624 if ((wlc->pub->sih->boardvendor == VENDOR_BUFFALO) &&
9625 D11REV_GT(wlc->pub->corerev, 5) && !strcmp("JP", abbrev))
9626 return TRUE;
9627 else
9628 return FALSE;
9632 wlc_get_channels_in_country(struct wlc_info *wlc, void *arg)
9634 chanvec_t channels;
9635 wl_channels_in_country_t *cic = (wl_channels_in_country_t *)arg;
9636 chanvec_t sup_chan;
9637 uint count, need, i;
9639 if ((cic->band != WLC_BAND_5G) && (cic->band != WLC_BAND_2G)) {
9640 WL_ERROR(("Invalid band %d\n", cic->band));
9641 return BCME_BADBAND;
9644 if ((NBANDS(wlc) == 1) && (cic->band != (uint)wlc->band->bandtype)) {
9645 WL_ERROR(("Invalid band %d for card\n", cic->band));
9646 return BCME_BADBAND;
9649 if (wlc_channel_get_chanvec(wlc, cic->country_abbrev, cic->band, &channels) == FALSE) {
9650 WL_ERROR(("Invalid country %s\n", cic->country_abbrev));
9651 return BCME_NOTFOUND;
9654 wlc_phy_chanspec_band_validch(wlc->band->pi, cic->band, &sup_chan);
9655 for (i = 0; i < sizeof(chanvec_t); i++)
9656 sup_chan.vec[i] &= channels.vec[i];
9658 /* find all valid channels */
9659 for (count = 0, i = 0; i < sizeof(sup_chan.vec)*NBBY; i++) {
9660 if (isset(sup_chan.vec, i))
9661 count++;
9664 need = sizeof(wl_channels_in_country_t) + count*sizeof(cic->channel[0]);
9666 if (need > cic->buflen) {
9667 /* too short, need this much */
9668 WL_ERROR(("WLC_GET_COUNTRY_LIST: Buffer size: Need %d Received %d\n",
9669 need, cic->buflen));
9670 cic->buflen = need;
9671 return BCME_BUFTOOSHORT;
9674 for (count = 0, i = 0; i < sizeof(sup_chan.vec)*NBBY; i++) {
9675 if (isset(sup_chan.vec, i))
9676 cic->channel[count++] = i;
9679 cic->count = count;
9680 return 0;
9684 wlc_get_country_list(struct wlc_info *wlc, void *arg)
9686 chanvec_t channels;
9687 wl_country_list_t *cl = (wl_country_list_t *)arg;
9688 const locale_info_t *locale = NULL;
9689 chanvec_t sup_chan;
9690 uint count, need, i, j;
9691 uint cntry_locales_size = ARRAYSIZE(cntry_locales);
9693 if (cl->band_set == FALSE) {
9694 /* get for current band */
9695 cl->band = wlc->band->bandtype;
9698 if ((cl->band != WLC_BAND_5G) && (cl->band != WLC_BAND_2G)) {
9699 WL_ERROR(("Invalid band %d\n", cl->band));
9700 return BCME_BADBAND;
9703 if ((NBANDS(wlc) == 1) && (cl->band != (uint)wlc->band->bandtype)) {
9704 WL_INFORM(("Invalid band %d for card\n", cl->band));
9705 cl->count = 0;
9706 return 0;
9709 wlc_phy_chanspec_band_validch(wlc->band->pi, cl->band, &sup_chan);
9711 for (count = 0, i = 0; i < cntry_locales_size; i++) {
9712 locale = (cl->band == WLC_BAND_5G) ?
9713 wlc_get_locale_5g(cntry_locales[i].country.locale_5G) :
9714 wlc_get_locale_2g(cntry_locales[i].country.locale_2G);
9716 wlc_locale_get_channels(locale, &channels);
9718 for (j = 0; j < sizeof(sup_chan.vec); j++) {
9719 if (sup_chan.vec[j] & channels.vec[j]) {
9720 count++;
9721 break;
9726 need = sizeof(wl_country_list_t) + count*WLC_CNTRY_BUF_SZ;
9728 if (need > cl->buflen) {
9729 /* too short, need this much */
9730 WL_ERROR(("WLC_GET_COUNTRY_LIST: Buffer size: Need %d Received %d\n",
9731 need, cl->buflen));
9732 cl->buflen = need;
9733 return BCME_BUFTOOSHORT;
9736 for (count = 0, i = 0; i < cntry_locales_size; i++) {
9737 locale = (cl->band == WLC_BAND_5G) ?
9738 wlc_get_locale_5g(cntry_locales[i].country.locale_5G) :
9739 wlc_get_locale_2g(cntry_locales[i].country.locale_2G);
9741 wlc_locale_get_channels(locale, &channels);
9743 for (j = 0; j < sizeof(sup_chan.vec); j++) {
9744 if (sup_chan.vec[j] & channels.vec[j]) {
9745 if ((wlc_country_listable(wlc, cntry_locales[i].abbrev) ==
9746 TRUE)) {
9747 strncpy(&cl->country_abbrev[count*WLC_CNTRY_BUF_SZ],
9748 cntry_locales[i].abbrev, WLC_CNTRY_BUF_SZ);
9749 count++;
9751 break;
9756 cl->count = count;
9757 return 0;
9760 /* Get regulatory max power for a given channel in a given locale.
9761 * for external FALSE, it returns limit for brcm hw
9762 * ---- for 2.4GHz channel, it returns cck limit, not ofdm limit.
9763 * for external TRUE, it returns 802.11d Country Information Element -
9764 * Maximum Transmit Power Level.
9766 int8
9767 wlc_get_reg_max_power_for_channel(wlc_cm_info_t *wlc_cm, int chan, bool external)
9769 int8 maxpwr;
9770 int indx;
9771 const locale_info_t *li;
9773 if (chan <= CH_MAX_2G_CHANNEL) {
9774 indx = CHANNEL_POWER_IDX_2G_CCK(chan); /* 2.4 GHz cck index */
9775 li = wlc_get_locale_2g(wlc_cm->country->locale_2G);
9776 } else {
9777 indx = CHANNEL_POWER_IDX_5G(chan); /* 5 GHz channel */
9778 li = wlc_get_locale_5g(wlc_cm->country->locale_5G);
9781 maxpwr = external ? li->pub_maxpwr[indx] : li->maxpwr[indx];
9783 return (maxpwr);
9787 * Validate the chanspec for this locale, for 40MHZ we need to also check that the sidebands
9788 * are valid 20MZH channels in this locale and they are also a legal HT combination
9790 static bool
9791 wlc_valid_chanspec_ext(wlc_cm_info_t *wlc_cm, chanspec_t chspec, bool dualband)
9793 wlc_info_t *wlc = wlc_cm->wlc;
9794 uint8 channel = CHSPEC_CHANNEL(chspec);
9796 /* check the chanspec */
9797 if (wf_chspec_malformed(chspec)) {
9798 WL_ERROR(("wl%d: malformed chanspec 0x%x\n", wlc->pub->unit, chspec));
9799 ASSERT(0);
9800 return FALSE;
9803 if (CHANNEL_BANDUNIT(wlc_cm->wlc, channel) != CHSPEC_WLCBANDUNIT(chspec))
9804 return FALSE;
9806 /* Check a 20Mhz channel */
9807 if (CHSPEC_IS20(chspec)) {
9808 if (dualband)
9809 return (VALID_CHANNEL20_DB(wlc_cm->wlc, channel));
9810 else
9811 return (VALID_CHANNEL20(wlc_cm->wlc, channel));
9814 /* We know we are now checking a 40MHZ channel, so we should only be here
9815 * for NPHYS
9817 if (WLCISNPHY(wlc->band) || WLCISHTPHY(wlc->band) ||
9818 (WLCISSSLPNPHY(wlc->band) && SSLPNREV_GT(wlc->band->phyrev, 2))) {
9819 uint8 upper_sideband = 0, idx;
9820 uint8 num_ch20_entries = sizeof(chan20_info)/sizeof(struct chan20_info);
9822 if (!VALID_40CHANSPEC_IN_BAND(wlc, CHSPEC_WLCBANDUNIT(chspec)))
9823 return FALSE;
9825 if (dualband) {
9826 if (!VALID_CHANNEL20_DB(wlc, LOWER_20_SB(channel)) ||
9827 !VALID_CHANNEL20_DB(wlc, UPPER_20_SB(channel)))
9828 return FALSE;
9829 } else {
9830 if (!VALID_CHANNEL20(wlc, LOWER_20_SB(channel)) ||
9831 !VALID_CHANNEL20(wlc, UPPER_20_SB(channel)))
9832 return FALSE;
9835 /* find the lower sideband info in the sideband array */
9836 for (idx = 0; idx < num_ch20_entries; idx++) {
9837 if (chan20_info[idx].sb == LOWER_20_SB(channel))
9838 upper_sideband = chan20_info[idx].adj_sbs;
9840 /* check that the lower sideband allows an upper sideband */
9841 if ((upper_sideband & (CH_UPPER_SB | CH_EWA_VALID)) == (CH_UPPER_SB | CH_EWA_VALID))
9842 return TRUE;
9843 return FALSE;
9846 return FALSE;
9849 bool
9850 wlc_valid_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec)
9852 return wlc_valid_chanspec_ext(wlc_cm, chspec, FALSE);
9855 bool
9856 wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec)
9858 return wlc_valid_chanspec_ext(wlc_cm, chspec, TRUE);
9862 * Fill in 'list' with validated chanspecs, looping through channels using the chanspec_mask.
9864 static void
9865 wlc_chanspec_list(wlc_info_t *wlc, wl_uint32_list_t *list, chanspec_t chanspec_mask)
9867 uint8 channel;
9868 chanspec_t chanspec;
9870 for (channel = 0; channel < MAXCHANNEL; channel++) {
9871 chanspec = (chanspec_mask | channel);
9872 if (!wf_chspec_malformed(chanspec) &&
9873 ((NBANDS(wlc) > 1) ? wlc_valid_chanspec_db(wlc->cmi, chanspec) :
9874 wlc_valid_chanspec(wlc->cmi, chanspec))) {
9875 list->element[list->count] = chanspec;
9876 list->count++;
9882 * Returns a list of valid chanspecs meeting the provided settings
9884 void
9885 wlc_get_valid_chanspecs(wlc_cm_info_t *wlc_cm, wl_uint32_list_t *list, bool bw20, bool band2G,
9886 const char *abbrev)
9888 wlc_info_t *wlc = wlc_cm->wlc;
9889 chanspec_t chanspec;
9890 const country_info_t* country;
9891 const locale_info_t *locale = NULL;
9892 chanvec_t saved_valid_channels, saved_db_valid_channels;
9893 #ifdef WL11N
9894 uint8 saved_locale_flags = 0, saved_db_locale_flags = 0;
9895 const locale_mimo_info_t *li_mimo = NULL;
9896 bool saved_cap_40 = TRUE, saved_db_cap_40 = TRUE;
9897 #endif /* WL11N */
9899 /* Check if this is a valid band for this card */
9900 if ((NBANDS(wlc) == 1) &&
9901 (BAND_5G(wlc->band->bandtype) == band2G))
9902 return;
9904 /* see if we need to look up country. Else, current locale */
9905 if (strcmp(abbrev, "")) {
9906 country = wlc_country_lookup(wlc, abbrev);
9908 if (country == NULL) {
9909 WL_ERROR(("Invalid country \"%s\"\n", abbrev));
9910 return;
9913 locale = band2G ?
9914 wlc_get_locale_2g(country->locale_2G) :
9915 wlc_get_locale_5g(country->locale_5G);
9917 #ifdef WL11N
9918 li_mimo = band2G ?
9919 wlc_get_mimo_2g(country->locale_mimo_2G) :
9920 wlc_get_mimo_5g(country->locale_mimo_5G);
9921 #endif /* WL11N */
9924 /* Save current locales */
9925 if (locale != NULL) {
9926 bcopy(&wlc->cmi->bandstate[wlc->band->bandunit].valid_channels,
9927 &saved_valid_channels, sizeof(chanvec_t));
9928 wlc_locale_get_channels(locale,
9929 &wlc->cmi->bandstate[wlc->band->bandunit].valid_channels);
9930 if (NBANDS(wlc) > 1) {
9931 bcopy(&wlc->cmi->bandstate[OTHERBANDUNIT(wlc)].valid_channels,
9932 &saved_db_valid_channels, sizeof(chanvec_t));
9933 wlc_locale_get_channels(locale,
9934 &wlc->cmi->bandstate[OTHERBANDUNIT(wlc)].valid_channels);
9938 #ifdef WL11N
9939 if (li_mimo != NULL) {
9940 saved_locale_flags = wlc_cm->bandstate[wlc->band->bandunit].locale_flags;
9941 wlc_cm->bandstate[wlc->band->bandunit].locale_flags = li_mimo->flags;
9942 if (NBANDS(wlc) > 1) {
9943 saved_db_locale_flags = wlc_cm->bandstate[OTHERBANDUNIT(wlc)].locale_flags;
9944 wlc_cm->bandstate[OTHERBANDUNIT(wlc)].locale_flags = li_mimo->flags;
9948 /* save 40 MHz cap */
9949 saved_cap_40 = wlc->band->mimo_cap_40;
9950 wlc->band->mimo_cap_40 = TRUE;
9951 if (NBANDS(wlc) > 1) {
9952 saved_db_cap_40 = wlc->bandstate[OTHERBANDUNIT(wlc)]->mimo_cap_40;
9953 wlc->bandstate[OTHERBANDUNIT(wlc)]->mimo_cap_40 = TRUE;
9956 #endif /* WL11N */
9958 /* Go through 2G 20MHZ chanspecs */
9959 if (band2G && bw20) {
9960 chanspec = WL_CHANSPEC_BAND_2G | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE;
9961 wlc_chanspec_list(wlc, list, chanspec);
9964 /* Go through 5G 20 MHZ chanspecs */
9965 if (!band2G && bw20) {
9966 chanspec = WL_CHANSPEC_BAND_5G | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE;
9967 wlc_chanspec_list(wlc, list, chanspec);
9970 /* Go through 2G 40MHZ chanspecs only if N mode and 40MHZ are both enabled */
9971 if (band2G && !bw20 &&
9972 N_ENAB(wlc->pub) && wlc->bandstate[BAND_2G_INDEX]->mimo_cap_40) {
9973 chanspec = WL_CHANSPEC_BAND_2G | WL_CHANSPEC_BW_40 | WL_CHANSPEC_CTL_SB_UPPER;
9974 wlc_chanspec_list(wlc, list, chanspec);
9975 chanspec = WL_CHANSPEC_BAND_2G | WL_CHANSPEC_BW_40 | WL_CHANSPEC_CTL_SB_LOWER;
9976 wlc_chanspec_list(wlc, list, chanspec);
9979 /* Go through 5G 40MHZ chanspecs only if N mode and 40MHZ are both enabled */
9980 if (!band2G && !bw20 &&
9981 N_ENAB(wlc->pub) && ((NBANDS(wlc) > 1) || IS_SINGLEBAND_5G(wlc->deviceid)) &&
9982 wlc->bandstate[BAND_5G_INDEX]->mimo_cap_40) {
9983 chanspec = WL_CHANSPEC_BAND_5G | WL_CHANSPEC_BW_40 | WL_CHANSPEC_CTL_SB_UPPER;
9984 wlc_chanspec_list(wlc, list, chanspec);
9985 chanspec = WL_CHANSPEC_BAND_5G | WL_CHANSPEC_BW_40 | WL_CHANSPEC_CTL_SB_LOWER;
9986 wlc_chanspec_list(wlc, list, chanspec);
9989 #ifdef WL11N
9990 /* restore 40 MHz cap */
9991 wlc->band->mimo_cap_40 = saved_cap_40;
9992 if (NBANDS(wlc) > 1)
9993 wlc->bandstate[OTHERBANDUNIT(wlc)]->mimo_cap_40 = saved_db_cap_40;
9995 if (li_mimo != NULL) {
9996 wlc_cm->bandstate[wlc->band->bandunit].locale_flags = saved_locale_flags;
9997 if ((NBANDS(wlc) > 1))
9998 wlc_cm->bandstate[OTHERBANDUNIT(wlc)].locale_flags = saved_db_locale_flags;
10000 #endif /* WL11N */
10002 /* Restore the locales if switched */
10003 if (locale != NULL) {
10004 bcopy(&saved_valid_channels,
10005 &wlc->cmi->bandstate[wlc->band->bandunit].valid_channels,
10006 sizeof(chanvec_t));
10007 if ((NBANDS(wlc) > 1))
10008 bcopy(&saved_db_valid_channels,
10009 &wlc->cmi->bandstate[OTHERBANDUNIT(wlc)].valid_channels,
10010 sizeof(chanvec_t));
10014 /* query the channel list given a country and a regulatory class */
10015 uint8
10016 wlc_rclass_get_channel_list(wlc_cm_info_t *cmi, char *abbrev, uint8 rclass,
10017 bool bw20, wl_uint32_list_t *list)
10019 const rcinfo_t *rcinfo = NULL;
10020 uint8 ch2g_start = 0, ch2g_end = 0;
10021 int i;
10023 if (wlc_us_ccode(abbrev)) {
10024 if (rclass == WLC_REGCLASS_USA_2G_20MHZ) {
10025 ch2g_start = 1;
10026 ch2g_end = 11;
10028 #ifdef BAND5G
10029 else
10030 rcinfo = &rcinfo_us_20;
10031 #endif
10032 } else if (wlc_japan_ccode(abbrev)) {
10033 if (rclass == WLC_REGCLASS_JPN_2G_20MHZ) {
10034 ch2g_start = 1;
10035 ch2g_end = 13;
10037 else if (rclass == WLC_REGCLASS_JPN_2G_20MHZ_CH14) {
10038 ch2g_start = 14;
10039 ch2g_end = 14;
10041 #ifdef BAND5G
10042 else
10043 rcinfo = &rcinfo_jp_20;
10044 #endif
10045 } else {
10046 if (rclass == WLC_REGCLASS_EUR_2G_20MHZ) {
10047 ch2g_start = 1;
10048 ch2g_end = 11;
10050 #ifdef BAND5G
10051 else
10052 rcinfo = &rcinfo_eu_20;
10053 #endif
10056 list->count = 0;
10057 if (rcinfo == NULL) {
10058 for (i = ch2g_start; i <= ch2g_end; i ++)
10059 list->element[list->count ++] = i;
10061 else {
10062 for (i = 0; i < rcinfo->len; i ++) {
10063 if (rclass == rcinfo->rctbl[i].rclass)
10064 list->element[list->count ++] = rcinfo->rctbl[i].chan;
10068 return (uint8)list->count;
10071 /* Return true if the channel is a valid channel that is radar sensitive
10072 * in the current country/locale
10074 bool
10075 wlc_radar_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec)
10077 #ifdef BAND5G /* RADAR */
10078 uint channel = CHSPEC_CHANNEL(chspec);
10079 const chanvec_t *radar_channels;
10081 /* The radar_channels chanvec may be a superset of valid channels,
10082 * so be sure to check for a valid channel first.
10085 if (!chspec || !wlc_valid_chanspec_db(wlc_cm, chspec)) {
10086 return FALSE;
10089 if (CHSPEC_IS5G(chspec)) {
10090 radar_channels = wlc_cm->bandstate[BAND_5G_INDEX].radar_channels;
10092 if (CHSPEC_IS40(chspec)) {
10093 if (isset(radar_channels->vec, LOWER_20_SB(channel)) ||
10094 isset(radar_channels->vec, UPPER_20_SB(channel)))
10095 return TRUE;
10096 } else if (isset(radar_channels->vec, channel)) {
10097 return TRUE;
10100 #endif /* BAND5G */
10101 return FALSE;
10104 /* Return true if the channel is a valid channel that is radar sensitive
10105 * in the current country/locale
10107 bool
10108 wlc_restricted_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec)
10110 uint channel = CHSPEC_CHANNEL(chspec);
10111 chanvec_t *restricted_channels;
10113 /* The restriced_channels chanvec may be a superset of valid channels,
10114 * so be sure to check for a valid channel first.
10117 if (!chspec || !wlc_valid_chanspec_db(wlc_cm, chspec)) {
10118 return FALSE;
10121 restricted_channels = &wlc_cm->restricted_channels;
10123 if (CHSPEC_IS40(chspec)) {
10124 if (isset(restricted_channels->vec, LOWER_20_SB(channel)) ||
10125 isset(restricted_channels->vec, UPPER_20_SB(channel)))
10126 return TRUE;
10127 } else if (isset(restricted_channels->vec, channel)) {
10128 return TRUE;
10131 return FALSE;
10134 void
10135 wlc_clr_restricted_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec)
10137 if (CHSPEC_IS40_UNCOND(chspec)) {
10138 clrbit(wlc_cm->restricted_channels.vec, LOWER_20_SB(CHSPEC_CHANNEL(chspec)));
10139 clrbit(wlc_cm->restricted_channels.vec, UPPER_20_SB(CHSPEC_CHANNEL(chspec)));
10140 } else
10141 clrbit(wlc_cm->restricted_channels.vec, CHSPEC_CHANNEL(chspec));
10143 wlc_upd_restricted_chanspec_flag(wlc_cm);
10146 static void
10147 wlc_upd_restricted_chanspec_flag(wlc_cm_info_t *wlc_cm)
10149 uint j;
10151 for (j = 0; j < (int)sizeof(chanvec_t); j++)
10152 if (wlc_cm->restricted_channels.vec[j]) {
10153 wlc_cm->has_restricted_ch = TRUE;
10154 return;
10157 wlc_cm->has_restricted_ch = FALSE;
10160 bool
10161 wlc_has_restricted_chanspec(wlc_cm_info_t *wlc_cm)
10163 return wlc_cm->has_restricted_ch;
10166 #if defined(BCMDBG) || defined(BCMDBG_DUMP)
10167 #define QDB_FRAC(x) (x) / WLC_TXPWR_DB_FACTOR, fraction[(x) % WLC_TXPWR_DB_FACTOR]
10169 wlc_channel_dump_locale(void *handle, struct bcmstrbuf *b)
10171 wlc_info_t *wlc = (wlc_info_t*)handle;
10172 txppr_t txpwr;
10173 char max_cck_str[32];
10174 int chan, i;
10175 int restricted;
10176 int radar = 0;
10177 int max_cck, max_ofdm;
10178 int max_ht20 = 0, max_ht40 = 0;
10179 char fraction[4][4] = {" ", ".25", ".5", ".75"};
10180 char flagstr[64];
10181 const bcm_bit_desc_t fc_flags[] = {
10182 {WLC_EIRP, "EIRP"},
10183 {WLC_DFS_TPC, "DFS/TPC"},
10184 {WLC_NO_OFDM, "No OFDM"},
10185 {WLC_NO_40MHZ, "No 40MHz"},
10186 {WLC_NO_MIMO, "No MIMO"},
10187 {WLC_RADAR_TYPE_EU, "EU_RADAR"},
10188 {0, NULL}
10190 uint8 rclist[MAXRCLISTSIZE], rclen;
10191 chanspec_t chanspec;
10192 int quiet;
10194 bcm_bprintf(b, "srom_ccode \"%s\" srom_regrev %u\n",
10195 wlc->cmi->srom_ccode, wlc->cmi->srom_regrev);
10197 if (NBANDS(wlc) > 1) {
10198 bcm_format_flags(fc_flags, wlc->cmi->bandstate[BAND_2G_INDEX].locale_flags,
10199 flagstr, 64);
10200 bcm_bprintf(b, "2G Flags: %s\n", flagstr);
10201 bcm_format_flags(fc_flags, wlc->cmi->bandstate[BAND_5G_INDEX].locale_flags,
10202 flagstr, 64);
10203 bcm_bprintf(b, "5G Flags: %s\n", flagstr);
10204 } else {
10205 bcm_format_flags(fc_flags, wlc->cmi->bandstate[wlc->band->bandunit].locale_flags,
10206 flagstr, 64);
10207 bcm_bprintf(b, "%dG Flags: %s\n", BAND_2G(wlc->band->bandtype)?2:5, flagstr);
10210 if (N_ENAB(wlc->pub))
10211 bcm_bprintf(b, " Ch Rdr/reS max HT 20/40\n");
10212 else
10213 bcm_bprintf(b, " Ch Rdr/reS max\n");
10215 for (chan = 0; chan < MAXCHANNEL; chan++) {
10216 chanspec = CH20MHZ_CHSPEC(chan);
10217 if (!wlc_valid_chanspec_db(wlc->cmi, chanspec)) {
10218 chanspec = CH40MHZ_CHSPEC(chan, WL_CHANSPEC_CTL_SB_LOWER);
10219 if (!wlc_valid_chanspec_db(wlc->cmi, chanspec))
10220 continue;
10223 radar = wlc_radar_chanspec(wlc->cmi, chanspec);
10224 restricted = wlc_restricted_chanspec(wlc->cmi, chanspec);
10225 quiet = wlc_quiet_chanspec(wlc->cmi, chanspec);
10227 wlc_channel_reg_limits(wlc->cmi, chanspec, &txpwr);
10229 max_cck = txpwr.cck[0];
10230 max_ofdm = txpwr.ofdm[0];
10231 #ifdef WL11N
10232 max_ht20 = txpwr.u20.n.cdd[0];
10233 max_ht40 = txpwr.u40.n.cdd[0];
10234 #endif /* WL11N */
10236 if (CHSPEC_IS2G(chanspec))
10237 snprintf(max_cck_str, sizeof(max_cck_str),
10238 "%2d%s/", QDB_FRAC(max_cck));
10239 else
10240 strncpy(max_cck_str, " ", sizeof(max_cck_str));
10242 if (N_ENAB(wlc->pub))
10243 bcm_bprintf(b, "%s%3d %s%s%s %s%2d%s %2d%s/%2d%s\n",
10244 (CHSPEC_IS40(chanspec)?">":" "), chan,
10245 (radar ? "R" : " "), (restricted ? "S" : " "),
10246 (quiet ? "Q" : " "),
10247 max_cck_str, QDB_FRAC(max_ofdm),
10248 QDB_FRAC(max_ht20), QDB_FRAC(max_ht40));
10249 else
10250 bcm_bprintf(b, "%s%3d %s%s%s %s%2d%s\n",
10251 (CHSPEC_IS40(chanspec)?">":" "), chan,
10252 (radar ? "R" : " "), (restricted ? "S" : " "),
10253 (quiet ? "Q" : " "),
10254 max_cck_str, QDB_FRAC(max_ofdm));
10257 bzero(rclist, MAXRCLISTSIZE);
10258 chanspec = wlc->pub->associated ?
10259 wlc->home_chanspec : WLC_BAND_PI_RADIO_CHANSPEC;
10260 rclen = wlc_get_regclass_list(wlc->cmi, rclist, MAXRCLISTSIZE, chanspec, FALSE);
10261 if (rclen) {
10262 bcm_bprintf(b, "supported regulatory class:\n");
10263 for (i = 0; i < rclen; i++)
10264 bcm_bprintf(b, "%d ", rclist[i]);
10265 bcm_bprintf(b, "\n");
10268 bcm_bprintf(b, "has_restricted_ch %s\n", wlc->cmi->has_restricted_ch ? "TRUE" : "FALSE");
10270 #if HTCONF
10272 struct wlc_channel_txchain_limits *lim;
10274 lim = &wlc->cmi->bandstate[BAND_2G_INDEX].chain_limits;
10275 bcm_bprintf(b, "chain limits 2g:");
10276 for (i = 0; i < WLC_CHAN_NUM_TXCHAIN; i++)
10277 bcm_bprintf(b, " %2d%s", QDB_FRAC(lim->chain_limit[i]));
10278 bcm_bprintf(b, "\n");
10280 lim = &wlc->cmi->bandstate[BAND_5G_INDEX].chain_limits;
10281 bcm_bprintf(b, "chain limits 5g:");
10282 for (i = 0; i < WLC_CHAN_NUM_TXCHAIN; i++)
10283 bcm_bprintf(b, " %2d%s", QDB_FRAC(lim->chain_limit[i]));
10284 bcm_bprintf(b, "\n");
10286 #endif /* HTCONF */
10288 return 0;
10291 #endif /* BCMDBG || BCMDBG_DUMP */
10293 #ifndef INT8_MIN
10294 #define INT8_MIN 0x80
10295 #endif
10296 #ifndef INT8_MAX
10297 #define INT8_MAX 0x7F
10298 #endif
10300 /* Perform an element by element min of txppr structs a and b, and
10301 * store the result in a.
10303 static void
10304 wlc_channel_txpwr_vec_combine_min(txppr_t *a, txppr_t *b)
10306 uint i;
10308 for (i = 0; i < sizeof(txppr_t); i++)
10309 ((uint8*)a)[i] = MIN(((uint8*)a)[i], ((uint8*)b)[i]);
10312 static void
10313 wlc_channel_margin_summary_mapfn(void *context, uint8 *a, uint8 *b)
10315 uint8 margin;
10316 uint8 *pmin = (uint8*)context;
10318 if (*a > *b)
10319 margin = *a - *b;
10320 else
10321 margin = 0;
10323 *pmin = MIN(*pmin, margin);
10326 static void
10327 wlc_channel_max_summary_mapfn(void *context, uint8 *a, uint8 *ignore)
10329 uint8 *pmax = (uint8*)context;
10331 *pmax = MAX(*pmax, *a);
10334 /* Map the given function with its context value over the two
10335 * uint8 vectors
10337 static void
10338 wlc_channel_map_uint8_vec_binary(wlc_channel_mapfn_t fn, void* context, uint len,
10339 uint8 *vec_a, uint8 *vec_b)
10341 uint i;
10343 for (i = 0; i < len; i++)
10344 (fn)(context, vec_a + i, vec_b + i);
10347 /* Map the given function with its context value over the power targets
10348 * appropriate for the given band and bandwidth in two txppr structs.
10349 * If the band is 2G, DSSS/CCK rates will be included.
10350 * If the bandwidth is 20MHz, only 20MHz targets are included.
10351 * If the bandwidth is 40MHz, both 40MHz and 20in40 targets are included.
10353 static void
10354 wlc_channel_map_txppr_binary(wlc_channel_mapfn_t fn, void* context, uint bandtype, uint bw,
10355 txppr_t *a, txppr_t *b)
10358 /* macro for the typical 8 rates in a group (OFDM, MCS0-7, 8-15, 16-23) */
10359 #define MAP_GROUP(member) \
10360 wlc_channel_map_uint8_vec_binary(fn, context, 8, a->member, b->member)
10362 if (bw == WL_CHANSPEC_BW_20) {
10363 if (bandtype == WL_CHANSPEC_BAND_2G) {
10364 wlc_channel_map_uint8_vec_binary(fn, context, WL_NUM_RATES_CCK,
10365 a->cck, b->cck);
10368 MAP_GROUP(ofdm);
10371 #ifdef WL11N
10372 /* map over 20MHz rates for 20MHz channels */
10373 if (bw == WL_CHANSPEC_BW_20) {
10374 if (bandtype == WL_CHANSPEC_BAND_2G) {
10375 wlc_channel_map_uint8_vec_binary(fn, context, WL_NUM_RATES_CCK,
10376 a->cck_cdd.s1x2, b->cck_cdd.s1x2);
10377 wlc_channel_map_uint8_vec_binary(fn, context, WL_NUM_RATES_CCK,
10378 a->cck_cdd.s1x3, b->cck_cdd.s1x3);
10381 MAP_GROUP(ofdm_cdd);
10383 MAP_GROUP(u20.ht.s1x1);
10384 MAP_GROUP(u20.ht.s1x2);
10385 MAP_GROUP(ht.u20s1x3);
10387 MAP_GROUP(u20.ht.s2x2);
10388 MAP_GROUP(ht.u20s2x3);
10390 MAP_GROUP(u20.ht.s3x3);
10392 } else
10393 /* map over 40MHz and 20in40 rates for 40MHz channels */
10395 MAP_GROUP(ofdm_40);
10396 MAP_GROUP(ofdm_40_cdd);
10398 MAP_GROUP(u40.ht.s1x1);
10399 MAP_GROUP(u40.ht.s1x2);
10400 MAP_GROUP(ht.u40s1x3);
10402 MAP_GROUP(u40.ht.s2x2);
10403 MAP_GROUP(ht.u40s2x3);
10405 MAP_GROUP(u40.ht.s3x3);
10407 /* 20in40 legacy */
10408 if (bandtype == WL_CHANSPEC_BAND_2G) {
10409 wlc_channel_map_uint8_vec_binary(fn, context, WL_NUM_RATES_CCK,
10410 a->cck_20ul, b->cck_20ul);
10411 wlc_channel_map_uint8_vec_binary(fn, context, WL_NUM_RATES_CCK,
10412 a->cck_20ul_cdd.s1x2,
10413 b->cck_20ul_cdd.s1x2);
10414 wlc_channel_map_uint8_vec_binary(fn, context, WL_NUM_RATES_CCK,
10415 a->cck_20ul_cdd.s1x3,
10416 b->cck_20ul_cdd.s1x3);
10418 MAP_GROUP(ofdm_20ul);
10419 MAP_GROUP(ofdm_20ul_cdd);
10421 /* 20in40 HT */
10422 MAP_GROUP(ht20ul.s1x1);
10423 MAP_GROUP(ht20ul.s1x2);
10424 MAP_GROUP(ht20ul.s2x2);
10425 MAP_GROUP(ht20ul.s3x3);
10426 MAP_GROUP(ht.ul20s1x3);
10427 MAP_GROUP(ht.ul20s2x3);
10429 /* MCS 32 oddball */
10430 wlc_channel_map_uint8_vec_binary(fn, context, 1,
10431 &a->mcs32, &b->mcs32);
10433 #endif /* WL11N */
10436 /* calculate the offset from each per-rate power target in txpwr to the supplied
10437 * limit (or zero if txpwr[x] is less than limit[x]), and return the smallest
10438 * offset of relevant rates for bandtype/bw.
10440 static uint8
10441 wlc_channel_txpwr_margin(txppr_t *txpwr, txppr_t *limit, uint bandtype, uint bw)
10443 uint8 margin = 0xff;
10445 wlc_channel_map_txppr_binary(wlc_channel_margin_summary_mapfn, &margin,
10446 bandtype, bw, txpwr, limit);
10448 return margin;
10451 /* calculate the max power target of relevant rates for bandtype/bw */
10452 static uint8
10453 wlc_channel_txpwr_max(txppr_t *txpwr, uint bandtype, uint bw)
10455 uint8 pwr_max = 0;
10457 wlc_channel_map_txppr_binary(wlc_channel_max_summary_mapfn, &pwr_max,
10458 bandtype, bw, txpwr, NULL);
10460 return pwr_max;
10463 struct txp_range {
10464 int start;
10465 int end;
10468 static const struct txp_range txp_ranges_2g_20[] = {
10469 {0, 51},
10470 {153, 168},
10471 {201, 208},
10472 {-1, -1}
10475 static const struct txp_range txp_ranges_2g_40[] = {
10476 {52, 152},
10477 {169, 200},
10478 {209, 216},
10479 {-1, -1}
10482 static const struct txp_range txp_ranges_5g_20[] = {
10483 {4, 51},
10484 {153, 168},
10485 {-1, -1}
10488 static const struct txp_range txp_ranges_5g_40[] = {
10489 {52, 100},
10490 {105, 152},
10491 {169, 200},
10492 {-1, -1}
10495 /* return a txppr_t struct with the phy srom limits for the given channel */
10496 static void
10497 wlc_channel_srom_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec,
10498 txppr_t *srommin, txppr_t *srommax)
10500 wlc_info_t *wlc = wlc_cm->wlc;
10501 wlc_phy_t *pi = wlc->band->pi;
10502 const struct txp_range *txp_ranges;
10503 int range_idx, start, end, txp_rate_idx;
10504 uint8 min_srom, max_srom;
10505 uint channel = wf_chspec_ctlchan(chanspec);
10507 if (srommin != NULL)
10508 memset(srommin, 0, sizeof(txppr_t));
10509 if (srommax != NULL)
10510 memset(srommax, 0, sizeof(txppr_t));
10512 if (!WLCISHTPHY(wlc_cm->wlc->band))
10513 return;
10515 if (CHSPEC_IS2G(chanspec)) {
10516 if (CHSPEC_IS20(chanspec))
10517 txp_ranges = txp_ranges_2g_20;
10518 else
10519 txp_ranges = txp_ranges_2g_40;
10520 } else {
10521 if (CHSPEC_IS20(chanspec))
10522 txp_ranges = txp_ranges_5g_20;
10523 else
10524 txp_ranges = txp_ranges_5g_40;
10527 for (range_idx = 0; txp_ranges[range_idx].start != -1; range_idx++) {
10528 start = txp_ranges[range_idx].start;
10529 end = txp_ranges[range_idx].end;
10531 for (txp_rate_idx = start; txp_rate_idx <= end; txp_rate_idx++) {
10532 wlc_phy_txpower_sromlimit(pi, channel, &min_srom, &max_srom, txp_rate_idx);
10534 if (srommin != NULL)
10535 ((uint8*)srommin)[txp_rate_idx] = min_srom;
10536 if (srommax != NULL)
10537 ((uint8*)srommax)[txp_rate_idx] = max_srom;
10542 /* Set a per-chain power limit for the given band
10543 * Per-chain offsets will be used to make sure the max target power does not exceed
10544 * the per-chain power limit
10547 wlc_channel_band_chain_limit(wlc_cm_info_t *wlc_cm, uint bandtype,
10548 struct wlc_channel_txchain_limits *lim)
10550 wlc_info_t *wlc = wlc_cm->wlc;
10551 txppr_t txpwr;
10552 int bandunit = (bandtype == WLC_BAND_2G) ? BAND_2G_INDEX : BAND_5G_INDEX;
10554 if (!WLCISHTPHY(wlc_cm->wlc->band))
10555 return BCME_UNSUPPORTED;
10557 wlc_cm->bandstate[bandunit].chain_limits = *lim;
10559 if (CHSPEC_WLCBANDUNIT(wlc->chanspec) != bandunit)
10560 return 0;
10562 /* update the current tx chain offset if we just updated this band's limits */
10563 wlc_channel_txpower_limits(wlc_cm, &txpwr);
10564 wlc_channel_update_txchain_offsets(wlc_cm, &txpwr);
10566 return 0;
10569 /* update the per-chain tx power offset given the current power targets to implement
10570 * the correct per-chain tx power limit
10572 static int
10573 wlc_channel_update_txchain_offsets(wlc_cm_info_t *wlc_cm, txppr_t *txpwr)
10575 wlc_info_t *wlc = wlc_cm->wlc;
10576 struct wlc_channel_txchain_limits *lim;
10577 wl_txchain_pwr_offsets_t offsets;
10578 chanspec_t chanspec;
10579 txppr_t srompwr;
10580 int i, err;
10581 int max_pwr;
10582 int band, bw;
10583 int limits_present = FALSE;
10584 uint8 delta, margin, err_margin;
10585 #ifdef BCMDBG
10586 char chanbuf[CHANSPEC_STR_LEN];
10587 #endif
10589 if (!WLCISHTPHY(wlc->band))
10590 return BCME_UNSUPPORTED;
10592 chanspec = wlc->chanspec;
10593 band = CHSPEC_BAND(chanspec);
10594 bw = CHSPEC_BW(chanspec);
10596 /* initialze the offsets to a default of no offset */
10597 memset(&offsets, 0, sizeof(wl_txchain_pwr_offsets_t));
10599 lim = &wlc_cm->bandstate[CHSPEC_WLCBANDUNIT(chanspec)].chain_limits;
10601 /* see if there are any chain limits specified */
10602 for (i = 0; i < WLC_CHAN_NUM_TXCHAIN; i++) {
10603 if (lim->chain_limit[i] < WLC_TXPWR_MAX) {
10604 limits_present = TRUE;
10605 break;
10609 /* if there are no limits, we do not need to do any calculations */
10610 if (limits_present) {
10612 /* find the max power target for this channel and impose
10613 * a txpwr delta per chain to meet the specified chain limits
10614 * Bound the delta by the tx power margin
10617 /* get the srom min powers */
10618 wlc_channel_srom_limits(wlc_cm, wlc->chanspec, &srompwr, NULL);
10620 /* find the dB margin we can use to adjust tx power */
10621 margin = wlc_channel_txpwr_margin(txpwr, &srompwr, band, bw);
10623 /* reduce the margin by the error margin 1.5dB backoff */
10624 err_margin = 6; /* 1.5 dB in qdBm */
10625 margin = (margin >= err_margin) ? margin - err_margin : 0;
10627 /* get the srom max powers */
10628 wlc_channel_srom_limits(wlc_cm, wlc->chanspec, NULL, &srompwr);
10630 /* combine the srom limits with the given regulatory limits
10631 * to find the actual channel max
10633 wlc_channel_txpwr_vec_combine_min(&srompwr, txpwr);
10635 max_pwr = (int)wlc_channel_txpwr_max(&srompwr, band, bw);
10637 WL_NONE(("wl%d: %s: channel %s max_pwr %d margin %d\n",
10638 wlc->pub->unit, __FUNCTION__,
10639 wf_chspec_ntoa(wlc->chanspec, chanbuf), max_pwr, margin));
10641 /* for each chain, calculate an offset that keeps the max tx power target
10642 * no greater than the chain limit
10644 for (i = 0; i < WLC_CHAN_NUM_TXCHAIN; i++) {
10645 WL_NONE(("wl%d: %s: chain_limit[%d] %d",
10646 wlc->pub->unit, __FUNCTION__,
10647 i, lim->chain_limit[i]));
10648 if (lim->chain_limit[i] < max_pwr) {
10649 delta = max_pwr - lim->chain_limit[i];
10651 WL_NONE((" desired delta -%u lim delta -%u",
10652 delta, MIN(delta, margin)));
10654 /* limit to the margin allowed for our adjustmets */
10655 delta = MIN(delta, margin);
10657 offsets.offset[i] = -delta;
10659 WL_NONE(("\n"));
10661 } else {
10662 WL_NONE(("wl%d: %s skipping limit calculation since limits are MAX\n",
10663 wlc->pub->unit, __FUNCTION__));
10666 err = wlc_iovar_op(wlc, "txchain_pwr_offset", NULL, 0,
10667 &offsets, sizeof(wl_txchain_pwr_offsets_t), IOV_SET, NULL);
10668 if (err) {
10669 WL_ERROR(("wl%d: txchain_pwr_offset failed: error %d\n",
10670 wlc->pub->unit, err));
10673 return err;
10676 #if defined(BCMDBG) || defined(BCMDBG_DUMP)
10677 static int
10678 wlc_channel_dump_reg_ppr(void *handle, struct bcmstrbuf *b)
10680 wlc_cm_info_t *wlc_cm = (wlc_cm_info_t*)handle;
10681 wlc_info_t *wlc = wlc_cm->wlc;
10682 txppr_t txpwr;
10683 char chanbuf[CHANSPEC_STR_LEN];
10685 wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr);
10687 bcm_bprintf(b, "Regulatory Limits for channel %s\n",
10688 wf_chspec_ntoa(wlc->chanspec, chanbuf));
10689 wlc_channel_dump_txppr(b, &txpwr, WLCISHTPHY(wlc->band));
10691 return 0;
10694 /* dump of regulatory power with local constraint factored in for the current channel */
10695 static int
10696 wlc_channel_dump_reg_local_ppr(void *handle, struct bcmstrbuf *b)
10698 wlc_cm_info_t *wlc_cm = (wlc_cm_info_t*)handle;
10699 wlc_info_t *wlc = wlc_cm->wlc;
10700 txppr_t txpwr;
10701 char chanbuf[CHANSPEC_STR_LEN];
10703 wlc_channel_txpower_limits(wlc_cm, &txpwr);
10705 bcm_bprintf(b, "Regulatory Limits with constraint for channel %s\n",
10706 wf_chspec_ntoa(wlc->chanspec, chanbuf));
10707 wlc_channel_dump_txppr(b, &txpwr, WLCISHTPHY(wlc->band));
10709 return 0;
10712 /* dump of srom per-rate max/min values for the current channel */
10713 static int
10714 wlc_channel_dump_srom_ppr(void *handle, struct bcmstrbuf *b)
10716 wlc_cm_info_t *wlc_cm = (wlc_cm_info_t*)handle;
10717 wlc_info_t *wlc = wlc_cm->wlc;
10718 txppr_t srompwr;
10719 char chanbuf[CHANSPEC_STR_LEN];
10721 wlc_channel_srom_limits(wlc_cm, wlc->chanspec, NULL, &srompwr);
10723 bcm_bprintf(b, "PHY/SROM Max Limits for channel %s\n",
10724 wf_chspec_ntoa(wlc->chanspec, chanbuf));
10725 wlc_channel_dump_txppr(b, &srompwr, WLCISHTPHY(wlc->band));
10727 wlc_channel_srom_limits(wlc_cm, wlc->chanspec, &srompwr, NULL);
10729 bcm_bprintf(b, "PHY/SROM Min Limits for channel %s\n",
10730 wf_chspec_ntoa(wlc->chanspec, chanbuf));
10731 wlc_channel_dump_txppr(b, &srompwr, WLCISHTPHY(wlc->band));
10733 return 0;
10736 static void
10737 wlc_channel_margin_calc_mapfn(void *ignore, uint8 *a, uint8 *b)
10739 if (*a > *b)
10740 *a = *a - *b;
10741 else
10742 *a = 0;
10745 /* dumps dB margin between a rate an the lowest allowable power target, and
10746 * summarize the min of the margins for the current channel
10748 static int
10749 wlc_channel_dump_margin(void *handle, struct bcmstrbuf *b)
10751 wlc_cm_info_t *wlc_cm = (wlc_cm_info_t*)handle;
10752 wlc_info_t *wlc = wlc_cm->wlc;
10753 txppr_t txpwr, srommin;
10754 chanspec_t chanspec;
10755 int band, bw;
10756 uint8 margin;
10757 char chanbuf[CHANSPEC_STR_LEN];
10759 chanspec = wlc->chanspec;
10760 band = CHSPEC_BAND(chanspec);
10761 bw = CHSPEC_BW(chanspec);
10763 memset(&txpwr, 0, sizeof(txppr_t));
10764 memset(&srommin, 0, sizeof(txppr_t));
10766 wlc_channel_txpower_limits(wlc_cm, &txpwr);
10768 /* get the srom min powers */
10769 wlc_channel_srom_limits(wlc_cm, wlc->chanspec, &srommin, NULL);
10771 /* find the dB margin we can use to adjust tx power */
10772 margin = wlc_channel_txpwr_margin(&txpwr, &srommin, band, bw);
10774 /* calulate the per-rate margins */
10775 wlc_channel_map_txppr_binary(wlc_channel_margin_calc_mapfn, NULL,
10776 band, bw, &txpwr, &srommin);
10778 bcm_bprintf(b, "Power margin for channel %s, min = %u\n",
10779 wf_chspec_ntoa(wlc->chanspec, chanbuf), margin);
10780 wlc_channel_dump_txppr(b, &txpwr, WLCISHTPHY(wlc->band));
10782 return 0;
10784 #endif /* BCMDBG || BCMDBG_DUMP */