2 * Common interface to channel definitions.
3 * Copyright (C) 2010, Broadcom Corporation
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 $
20 #include <bcmendian.h>
21 #include <proto/802.11.h>
22 #include <proto/wpa.h>
29 #include <proto/eapol.h>
31 #endif /* BCMSUP_PSK */
36 #include <wlc_bsscfg.h>
39 #include <wlc_phy_hal.h>
41 #include <wl_export.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 */
50 const chanvec_t
*radar_channels
; /* List of radar sensitive channels */
52 struct wlc_channel_txchain_limits chain_limits
; /* per chain power limit */
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 */
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
);
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
);
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
);
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 */
117 #define QDB(n) ((n) * WLC_TXPWR_DB_FACTOR)
119 /* Regulatory Matrix Spreadsheet (CLM) MIMO v3.8.6.4
122 * + CLM v4.3.1 (Item-1 only EU/9 and Q2/4)
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
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
181 #define radar_set_none chanvec_none
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}
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}
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
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}
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}
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}
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}
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}
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}
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}
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
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
[] =
424 static const chanvec_t
* g_table_restricted_chan
[] =
426 &chanvec_none
, /* restricted_set_none */
427 &restricted_set_2g_short
,
428 &restricted_chan_165
,
430 &restricted_set_japan_legacy
,
431 &chanvec_all_2G
, /* restricted_set_11d_2G */
432 &chanvec_all_5G
, /* restricted_set_11d_5G */
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
[] =
552 &locale_5g_52_140_ALL
,
555 void wlc_locale_add_channels(chanvec_t
*target
, const chanvec_t
*channels
)
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
)
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
581 static const locale_info_t locale_a
= { /* locale a. channel 1 - 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},
589 {QDB(19), QDB(19), QDB(19),
590 QDB(19), QDB(19), /* 16.5 dBm */ 66},
596 static const locale_info_t locale_a_1
= { /* locale a. channel 1 - 11 */
598 LOCALE_RADAR_SET_NONE
,
599 LOCALE_RESTRICTED_NONE
,
600 {QDB(19), QDB(19), QDB(19),
601 QDB(15), QDB(17), QDB(16)},
606 static const locale_info_t locale_a_2
= { /* locale a. channel 1 - 11 */
608 LOCALE_RADAR_SET_NONE
,
609 LOCALE_RESTRICTED_NONE
,
610 {QDB(19), QDB(19), QDB(19),
611 QDB(18), QDB(18), QDB(18)},
616 static const locale_info_t locale_a_3
= { /* locale a_3. channel 1 - 11 */
618 LOCALE_RADAR_SET_NONE
,
619 LOCALE_RESTRICTED_NONE
,
620 {QDB(15), QDB(17), QDB(15),
621 QDB(13), QDB(17), QDB(13)},
626 static const locale_info_t locale_a_5
= { /* locale a_5. channel 1 - 11 */
628 LOCALE_RADAR_SET_NONE
,
629 LOCALE_RESTRICTED_NONE
,
630 { /* 16.5 */ 66, 66, 66,
631 /* 12.5 */ 50, /* 16.5 */ 66, 66},
636 static const locale_info_t locale_a_6
= { /* locale a_6. channel 1 - 11 */
638 LOCALE_RADAR_SET_NONE
,
639 LOCALE_RESTRICTED_NONE
,
640 {QDB(20), QDB(20), QDB(20),
641 QDB(17), QDB(17), QDB(16)},
646 static const locale_info_t locale_a1
= { /* locale a. channel 1 - 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},
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 */
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)},
671 static const locale_info_t locale_a3
= { /* locale a3. channel 1 - 11 */
673 LOCALE_RADAR_SET_NONE
,
674 LOCALE_RESTRICTED_NONE
,
675 {QDB(18), QDB(19), QDB(18),
676 QDB(17), QDB(19), QDB(16)},
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 */
686 LOCALE_RADAR_SET_NONE
,
687 LOCALE_RESTRICTED_NONE
,
688 {QDB(18), QDB(19), QDB(18),
689 QDB(14), QDB(17), QDB(12)},
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 */
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},
707 static const locale_info_t locale_a4_2
= { /* locale a4_2. channel 1 - 11 */
709 LOCALE_RADAR_SET_NONE
,
710 LOCALE_RESTRICTED_NONE
,
711 { QDB(21), QDB(23), QDB(21),
712 QDB(18), QDB(23), QDB(18)},
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 */
722 LOCALE_RADAR_SET_NONE
,
723 LOCALE_RESTRICTED_NONE
,
724 { QDB(19), QDB(23), QDB(19),
725 QDB(16), QDB(23), QDB(16)},
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 */
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 },
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 */
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)},
757 static const locale_info_t locale_a5_1
= { /* locale a5_1. channel 1 - 11 */
759 LOCALE_RADAR_SET_NONE
,
760 LOCALE_RESTRICTED_NONE
,
761 { QDB(18), QDB(18), QDB(18),
762 QDB(14), QDB(18), QDB(14)},
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 */
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},
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 */
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)},
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 */
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)},
806 static const locale_info_t locale_a6_3
= { /* locale a6_3. channel 1 - 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},
816 static const locale_info_t locale_a6_8
= { /* locale a6_8. channel 1 - 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)},
826 static const locale_info_t locale_a7
= { /* locale a7 channel 1 - 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},
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 */
841 LOCALE_RADAR_SET_NONE
,
842 LOCALE_RESTRICTED_NONE
,
843 {QDB(19), QDB(19), QDB(18),
844 QDB(13), QDB(18), QDB(13)},
849 static const locale_info_t locale_a10
= { /* locale a9 channel 1 - 11 */
851 LOCALE_RADAR_SET_NONE
,
852 LOCALE_RESTRICTED_NONE
,
853 {QDB(17), QDB(17), QDB(17),
854 QDB(17), QDB(17), QDB(17)},
859 static const locale_info_t locale_a10_1
= {
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},
869 static const locale_info_t locale_a10_2
= {
871 LOCALE_RADAR_SET_NONE
,
872 LOCALE_RESTRICTED_NONE
,
873 { /* 16.5 dBm */ 66, 66, 66,
874 QDB(14), /* 14.5 */ 58, 58},
879 static const locale_info_t locale_a10_3
= {
881 LOCALE_RADAR_SET_NONE
,
882 LOCALE_RESTRICTED_NONE
,
883 { QDB(18), QDB(18), QDB(18),
884 /* 15.5 */ 62, QDB(16), QDB(16)},
889 static const locale_info_t locale_a11
= {
891 LOCALE_RADAR_SET_NONE
,
892 LOCALE_RESTRICTED_NONE
,
893 { /* 16.5 */ 66, 66, 66,
894 QDB(13), 66, /* 12.75 */ 51},
899 static const locale_info_t locale_a12
= { /* locale a12 channel 1 - 11 */
901 LOCALE_RADAR_SET_NONE
,
902 LOCALE_RESTRICTED_NONE
,
903 {QDB(17), QDB(17), QDB(14),
904 QDB(10), QDB(10), QDB(10)},
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 */
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)},
920 static const locale_info_t locale_a20
= { /* locale a20. channel 1 - 11 */
922 LOCALE_RADAR_SET_NONE
,
923 LOCALE_RESTRICTED_NONE
,
924 {QDB(19), QDB(19), QDB(19),
925 QDB(14), QDB(19), QDB(14)},
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)},
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)},
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)},
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,
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},
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)},
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},
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)},
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)},
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)},
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)},
1040 static const locale_info_t locale_b2
= { /* locale b. channel 1 - 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)},
1050 static const locale_info_t locale_b2_1
= { /* locale b. channel 1 - 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)},
1060 static const locale_info_t locale_b2_2
= { /* locale b. channel 1 - 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)},
1070 static const locale_info_t locale_b2_3
= { /* locale b. channel 1 - 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)},
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},
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)},
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)},
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)},
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)},
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),
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)},
1157 static const locale_info_t locale_b5
= { /* locale b5. channel 1 - 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},
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 */
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},
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 */
1185 LOCALE_RADAR_SET_NONE
,
1186 LOCALE_RESTRICTED_12_13_14
,
1187 { /* 16.5 */ 66, 66, 66,
1193 static const locale_info_t locale_b5_4
= { /* locale b5-4. channel 1 - 14 */
1195 LOCALE_RADAR_SET_NONE
,
1196 LOCALE_RESTRICTED_12_13_14
,
1197 { /* 16.5 */ 66, 66, 66,
1203 static const locale_info_t locale_c
= { /* locale c. channel 1 - 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:
1212 * 10dBm + 10*log10(20)
1220 static const locale_info_t locale_c_1
= { /* locale c-1. channel 1 - 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:
1229 * 10dBm + 10*log10(20)
1237 static const locale_info_t locale_c_2
= { /* locale c-2. channel 1 - 14 */
1239 LOCALE_RADAR_SET_NONE
,
1240 LOCALE_RESTRICTED_NONE
,
1241 { /* 16.5 */ 66, 66, 66,
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},
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)},
1267 static const locale_info_t locale_f
= { /* locale f. no channel */
1269 LOCALE_RADAR_SET_NONE
,
1270 LOCALE_RESTRICTED_NONE
,
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)},
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)},
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)},
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)},
1317 static const locale_info_t locale_j
= { /* locale j. channel 1 - 11 */
1319 LOCALE_RADAR_SET_NONE
,
1320 LOCALE_RESTRICTED_NONE
,
1321 {QDB(19), QDB(19), QDB(19),
1322 QDB(19), QDB(19), QDB(19)},
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)},
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,
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)},
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,
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:
1380 * 10dBm + 10*log10(20)
1388 static const locale_info_t locale_2G_band_all
= { /* locale testing. channel 1 - 14 */
1390 LOCALE_RADAR_SET_NONE
,
1391 LOCALE_RESTRICTED_NONE
,
1392 {QDB(30), QDB(30), QDB(30),
1393 QDB(30), QDB(30), QDB(30)},
1400 * Locale Definitions - 5 GHz
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
,
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
,
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
,
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
,
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
,
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
,
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
1460 static const locale_info_t locale_3_1
= {
1461 LOCALE_CHAN_36_64
| LOCALE_CHAN_100_140
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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},
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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)},
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)},
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)},
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)},
1733 LOCALE_SET_5G_LOW3
| LOCALE_CHAN_149_165
,
1735 LOCALE_RESTRICTED_NONE
,
1736 {0, QDB(17), QDB(17), 0, QDB(17)},
1738 WLC_PEAK_CONDUCTED
| WLC_DFS_FCC
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
,
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
,
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
,
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)},
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)},
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)},
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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)},
1881 static const locale_info_t locale_13
= { /* locale 13. channel 36 - 48, 52 - 64 */
1884 LOCALE_RESTRICTED_NONE
,
1885 {QDB(21), QDB(21), QDB(21), 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 */
1893 LOCALE_RESTRICTED_NONE
,
1894 { /* 13.5 */ 54, 54, 54, 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 */
1902 LOCALE_RESTRICTED_NONE
,
1903 {QDB(16), QDB(16), QDB(16), 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 */
1911 LOCALE_RESTRICTED_NONE
,
1912 { /* 15.5 */ 62, 62, 62, 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
,
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
,
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
,
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
,
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
,
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
,
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
,
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 */
1982 LOCALE_RADAR_SET_NONE
,
1983 LOCALE_RESTRICTED_NONE
,
1984 {QDB(21), 0, 0, 0, 0},
1989 static const locale_info_t locale_18_2
= { /* locale 18_2. channel 36 - 48 */
1991 LOCALE_RADAR_SET_NONE
,
1992 LOCALE_RESTRICTED_NONE
,
1993 {QDB(15), 0, 0, 0, 0},
1998 static const locale_info_t locale_18l
= { /* locale 18l channel 36 - 48 */
2000 LOCALE_RADAR_SET_NONE
,
2001 LOCALE_RESTRICTED_NONE
,
2002 {QDB(14), 0, 0, 0, 0},
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
2142 LOCALE_RESTRICTED_NONE
,
2143 {0, 0, 0, QDB(21), 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
,
2151 LOCALE_RESTRICTED_NONE
,
2152 {0, QDB(15), QDB(15), 0, QDB(17)},
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
,
2161 LOCALE_RESTRICTED_JAPAN_LEGACY
,
2162 {QDB(21), 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
,
2171 LOCALE_RESTRICTED_JAPAN_LEGACY
,
2172 {QDB(21), QDB(21), QDB(21), 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
,
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
,
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
,
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
,
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)},
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)},
2233 {QDB(14), 0, 0, 0, QDB(23)},
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)},
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},
2257 static const locale_info_t locale_28
= { /* locale 28. channel 36 - 48 */
2259 LOCALE_RADAR_SET_NONE
,
2260 LOCALE_RESTRICTED_NONE
,
2261 {QDB(14), 0, 0, 0, 0},
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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)},
2372 static const locale_info_t locale_5G_radar_only
= { /* Channels 52 - 140 with US power */
2373 LOCALE_CHAN_52_140_ALL
,
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
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},
2398 /* 802.11d locale with all regulatory supported 2.4 GHz channels valid but marked as restricted
2401 static const locale_info_t locale_11d_2G
= {
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 */
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
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
,
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
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
[]=
2525 &locale_2G_band_all
,
2531 #if defined(BAND2G) && defined(WL11D)
2535 #endif /* WL11D && BAND2G */
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 */
2697 static const locale_info_t
* g_locale_5g_table
[]=
2738 &locale_5G_band_all
,
2749 &locale_5G_radar_only
,
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
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),
2833 {0, 0, QDB(13), QDB(14), QDB(14),
2834 QDB(14), QDB(14), QDB(12), QDB(12), 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},
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},
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},
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,
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,
2972 {QDB(15), /* 16.5 dBm = 66 qdBm */ 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,
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,
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),
2996 {0, 0, QDB(10), QDB(10), QDB(10),
2997 QDB(10), QDB(10), QDB(10), /* 9.5 */ 38, 0,
3002 static const locale_mimo_info_t locale_an2_3
= {
3003 {QDB(15), /* 15.5 */ 62, 62, 62, 62,
3006 {0, 0, /* 11.5 */ 46, 46, 46,
3007 46, 46, 46, QDB(11), 0,
3012 static const locale_mimo_info_t locale_an2_4
= {
3013 {QDB(13), /* 15.5 */ 62, 62, 62, 62,
3016 {0, 0, QDB(12), QDB(14), QDB(14),
3017 QDB(14), QDB(14), QDB(14), QDB(12), 0,
3022 static const locale_mimo_info_t locale_an2_5
= {
3023 {QDB(11), /* 16.5 */ 66, 66, 66, 66,
3026 {0, 0, /* 9.5 */ 38, /* 15.5 */ 62, 62,
3027 62, 62, 62, /* 12.5 */ 50, 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),
3036 {0, 0, /* 14.5 dBm */ 58, 58, 58,
3037 58, 58, QDB(13), QDB(13), 0,
3042 static const locale_mimo_info_t locale_an4
= {
3043 { /* 16.5 dBm */ 66, /* 18.5 dBm */ 74, 74, 74, 74,
3046 {0, 0, QDB(15), /* 15.5 dBm */ 62, 62,
3047 62, 62, QDB(15), QDB(15), 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,
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,
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,
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,
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,
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),
3109 {0, 0, QDB(14), QDB(17), QDB(19),
3110 QDB(19), QDB(19), QDB(17), QDB(13), 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),
3119 {0, 0, QDB(13), QDB(15), QDB(16),
3120 QDB(16), QDB(16), QDB(15), QDB(13), 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,
3129 {0, 0, /* 14.5 */ 58, 58, 58,
3135 static const locale_mimo_info_t locale_an7_8
= {
3136 { QDB(15), /* 21.5 dBm */ 86, 86, 86, 86,
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),
3148 {0, 0, QDB(13), QDB(14), QDB(14),
3149 QDB(14), QDB(14), QDB(14), /* 10.5 dBm */ 42, 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,
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),
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),
3179 {0, 0, QDB(14), QDB(16), QDB(16),
3180 QDB(16), QDB(16), QDB(15), QDB(14), 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),
3189 {0, 0, QDB(11), QDB(14), QDB(14),
3190 QDB(14), QDB(14), QDB(14), QDB(12), 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},
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),
3209 {0, 0, QDB(16), QDB(19), /* 22.5 dBm */ 90,
3210 90, 90, QDB(19), QDB(16), 0,
3215 static const locale_mimo_info_t locale_b2_3n
= {
3216 {57 /* 14.25 dBm */, 57, 57, 57, 57,
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),
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),
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),
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),
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),
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),
3288 static const locale_mimo_info_t locale_bn_10
= {
3289 { /* 11.5 dBm */ 46, 46, 46, 46, 46,
3292 {0, 0, /* 13.5 */ 54, 54, 54,
3298 static const locale_mimo_info_t locale_bn_10_3n
= {
3299 { /* 9.75 dBm */ 39, 39, 39, 39, 39,
3302 {0, 0, /* 11.75 dBm */ 47, 47, 47,
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,
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),
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,
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,
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,
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,
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),
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),
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},
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),
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),
3444 static const locale_mimo_info_t locale_cn_2
= {
3445 { /* 13.5 */ 54, 54, 54, 54,
3448 {0, 0, /* 10.5 */ 42, 42, 42,
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,
3461 {0, 0, /* 14.5 */ 58, 58, 58,
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},
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},
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},
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},
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},
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),
3527 {0, 0, QDB(13), QDB(13), QDB(13),
3528 QDB(13), QDB(13), QDB(13), QDB(13), 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,
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),
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),
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),
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,
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
[]=
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},
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},
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},
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},
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},
3904 static const locale_mimo_info_t locale_4n
= {
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)},
3975 {0, 0, 0, 0, QDB(13)},
3976 {0, 0, 0, 0, QDB(13)},
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)},
3992 {0, QDB(16), QDB(16), 0, QDB(15)},
3993 {0, /* 16.5 dBm */ 66, 66, 0, QDB(15)},
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)},
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
= {
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},
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},
4171 { /* 12.5 dBm */ 50, 0, 0, 0, 0},
4172 {QDB(14), 0, 0, 0, 0},
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},
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},
4355 static const locale_mimo_info_t locale_23n
= {
4356 { /* 12.5 dBm */ 50, 50, 50, 0, 0},
4361 static const locale_mimo_info_t locale_24n
= {
4362 { /* 12.5 dBm */ 50, 50, 50, /* 15.5 dBm */ 62, 0},
4367 static const locale_mimo_info_t locale_25n
= {
4368 { QDB(9), QDB(13), QDB(13), QDB(13), QDB(13)},
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},
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},
4408 {QDB(10), 0, 0, 0, QDB(20)},
4409 {QDB(12), 0, 0, 0, /* 23.5 dBm */ 94},
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},
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
[]=
4745 &locale_3n_1
, /* CLM v4.6.6 */
4755 #define LC(id) LOCALE_MIMO_IDX_ ## id
4760 #define LC_2G(id) LOCALE_2G_IDX_ ## id
4765 #define LC_5G(id) LOCALE_5G_IDX_ ## id
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)}
4775 #error "Don't know how to define LOCALES() for WL11N"
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)}
4785 #error "Don't know how to define LOCALES()"
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
)},
5054 {"RDR", LOCALES(f
, 5G_radar_only
, mimo_2g_all
, mimo_5g_all
)},
5057 {"B2", LOCALES(11d_2G
, 11d_5G
, fn
, 15n
)}
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
] = {
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 */
5366 "SJ", /* Svalbard and Jan Mayen */
5367 "TL", /* Timor-leste (East Timor) */
5368 /* Tinian Island (Z1 duplicate) */
5370 "TA", /* Tristan Da Cunha */
5371 /* Wake Island (Z1 duplicate) */
5372 "YU", /* Yugoslavia */
5375 /* Regulatory Revision mapping support for aggregate country definitions */
5377 char cc
[WLC_CNTRY_BUF_SZ
];
5378 char mapped_cc
[WLC_CNTRY_BUF_SZ
];
5382 struct wlc_aggregate_cc_map_lookup
{
5383 char cc
[WLC_CNTRY_BUF_SZ
];
5385 const struct wlc_cc_map
*map
;
5388 static const struct wlc_cc_map cc_map_ww1
[] = {
5402 static const struct wlc_cc_map cc_map_ww1_1
[] = {
5418 static const struct wlc_cc_map cc_map_ww2
[] = {
5433 static const struct wlc_cc_map cc_map_DE1
[] = {
5439 static const struct wlc_cc_map cc_map_DE2
[] = {
5453 static const struct wlc_cc_map cc_map_XA1
[] = {
5464 static const struct wlc_cc_map cc_map_X_1
[] = {
5475 static const struct wlc_cc_map cc_map_X_2
[] = {
5488 static const struct wlc_cc_map cc_map_X_3
[] = {
5501 static const struct wlc_cc_map cc_map_X_4
[] = {
5514 static const struct wlc_cc_map cc_map_X_5
[] = {
5561 static const struct wlc_cc_map cc_map_X_6
[] = {
5608 static const struct wlc_cc_map cc_map_X_7
[] = {
5681 static const struct wlc_cc_map cc_map_US12
[] = {
5687 static const struct wlc_cc_map cc_map_US16
[] = {
5733 static const struct wlc_cc_map cc_map_US25
[] = {
5782 static const struct wlc_cc_map cc_map_ww4
[] = {
5833 static struct wlc_cc_map cc_map_US33
[] = {
5838 static const struct wlc_cc_map cc_map_ww3
[] = {
5886 static const struct wlc_cc_map cc_map_DE3
[] = {
5933 static const struct wlc_cc_map cc_map_US17
[] = {
5981 static const struct wlc_cc_map cc_map_XZ_2
[] = {
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
},
6087 /* 20MHz channel info for 40MHz pairing support */
6089 struct chan20_info
{
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
[] = {
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
)},
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
)},
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
)},
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 */
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
] = {
6191 const locale_info_t
* wlc_get_locale_2g(uint8 locale_idx
)
6194 if (locale_idx
>= ARRAYSIZE(g_locale_2g_table
)) {
6195 WL_ERROR(("wl%d: locale 2g index size out of range\n", locale_idx
));
6198 return g_locale_2g_table
[locale_idx
];
6204 const locale_info_t
* wlc_get_locale_5g(uint8 locale_idx
)
6207 if (locale_idx
>= ARRAYSIZE(g_locale_5g_table
)) {
6208 WL_ERROR(("wl%d: locale 5g index size out of range\n", locale_idx
));
6211 return g_locale_5g_table
[locale_idx
];
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
));
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
));
6233 return g_mimo_5g_table
[locale_idx
];
6235 #endif /* #ifdef WL11N */
6238 wlc_autocountry_lookup(char *cc
)
6242 for (i
= 0; i
< ARRAYSIZE(def_autocountry
); i
++)
6243 if (!strcmp(def_autocountry
[i
], cc
))
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
;
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
)));
6267 bzero((char *)wlc_cm
, sizeof(wlc_cm_info_t
));
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");
6284 strncpy(country_abbrev
, ccode
, WLC_CNTRY_BUF_SZ
- 1);
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);
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__
,
6354 wlc_channel_mgr_detach(wlc_cm
);
6357 if ((pub
->sih
->boardvendor
== VENDOR_HP
) && (!bcmp(country_abbrev
, "US", 2) ||
6358 !bcmp(country_abbrev
, "JP", 2) || !bcmp(country_abbrev
, "IL", 2)))
6361 /* use RoW locale if set */
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 */
6395 BCMATTACHFN(wlc_channel_mgr_detach
)(wlc_cm_info_t
*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.
6433 wlc_default_chanspec(wlc_cm_info_t
*wlc_cm
, bool hw_fallback
)
6435 wlc_info_t
*wlc
= wlc_cm
->wlc
;
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 */
6443 chspec
= wlc_phy_chanspec_band_firstch(wlc_cm
->wlc
->band
->pi
,
6444 wlc
->band
->bandtype
);
6450 * Return the next channel's chanspec.
6453 wlc_next_chanspec(wlc_cm_info_t
*wlc_cm
, chanspec_t cur_chanspec
, int type
, bool any_band
)
6456 uint8 cur_chan
= CHSPEC_CHANNEL(cur_chanspec
);
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 */
6466 for (; ch
<= MAXCHANNEL
; ch
++) {
6467 if (ch
== MAXCHANNEL
)
6471 /* create the next channel spec */
6472 chspec
= cur_chanspec
& ~WL_CHANSPEC_CHAN_MASK
;
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
)))
6483 return ((chanspec_t
)INVCHANSPEC
);
6485 /* Couldn't find any in current band, try other band */
6487 for (; ch
<= MAXCHANNEL
; ch
++) {
6488 if (ch
== MAXCHANNEL
)
6493 /* create the next channel spec */
6494 chspec
= cur_chanspec
& ~(WL_CHANSPEC_CHAN_MASK
| WL_CHANSPEC_BAND_MASK
);
6496 if (CHANNEL_BANDUNIT(wlc
, ch
) == BAND_2G_INDEX
)
6497 chspec
|= WL_CHANSPEC_BAND_2G
;
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
)))
6508 return ((chanspec_t
)INVCHANSPEC
);
6511 /* return chanvec for a given country code and band */
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
)
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
);
6530 wlc_locale_get_channels(locale
, channels
);
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);
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
)
6563 wlc_info_t
*wlc
= wlc_cm
->wlc
;
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
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
);
6580 WL_NONE(("wl%d: %s: mapped to \"%s\"/%u\n",
6581 wlc
->pub
->unit
, __FUNCTION__
, ccode
, mapped_regrev
));
6583 WL_NONE(("wl%d: %s: failed lookup\n",
6584 wlc
->pub
->unit
, __FUNCTION__
));
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
)
6596 /* set the driver state for the country */
6597 wlc_set_country_common(wlc_cm
, country_abbrev
, mapped_ccode
, mapped_regrev
, country
);
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.
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
)
6611 const locale_mimo_info_t
* li_mimo
;
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
;
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
;
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
]);
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
);
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 */
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);
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
];
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
);
6694 WL_NONE(("wl%d: %s: mapped to \"%s\"/%u\n",
6695 wlc
->pub
->unit
, __FUNCTION__
, mapped_ccode
, mapped_regrev
));
6697 WL_NONE(("wl%d: %s: failed lookup\n",
6698 wlc
->pub
->unit
, __FUNCTION__
));
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
;
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
));
6720 /* default mapping is the given ccode and regrev 0 */
6721 strncpy(mapped_ccode
, ccode
, WLC_CNTRY_BUF_SZ
);
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
);
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
;
6742 mapped
= wlc_country_aggregate_map(wlc_cm
, ccode
, mapped_ccode
, mapped_regrev
);
6744 WL_NONE(("wl%d: %s: found aggregate mapping \"%s\"/%u\n",
6745 wlc
->pub
->unit
, __FUNCTION__
, mapped_ccode
, *mapped_regrev
));
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))) {
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) {
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__
));
6789 wlc_country_aggregate_map(wlc_cm_info_t
*wlc_cm
, const char *ccode
,
6790 char *mapped_ccode
, uint
*mapped_regrev
)
6793 wlc_info_t
*wlc
= wlc_cm
->wlc
;
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')
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
));
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
;
6817 WL_NONE(("wl%d: %s: no map for \"%s\"/%u\n",
6818 wlc
->pub
->unit
, __FUNCTION__
, srom_ccode
, srom_regrev
));
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
;
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
)
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 */
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
;
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')))
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')))
6916 if (!strcmp("NA", country_str_lookup
))
6920 return wlc_country_lookup(wlc
, country_str_lookup
);
6922 #endif /* STA && WL11D */
6925 wlc_channels_init(wlc_cm_info_t
*wlc_cm
, const country_info_t
*country
)
6927 wlc_info_t
*wlc
= wlc_cm
->wlc
;
6930 const locale_info_t
* li
;
6933 const locale_mimo_info_t
*li_mimo
;
6937 bzero(wlc
->ap
->chan_blocked
, sizeof(wlc
->ap
->chan_blocked
));
6940 bzero(&wlc_cm
->restricted_channels
, sizeof(chanvec_t
));
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
;
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
;
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
];
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
] &=
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
);
6988 /* Update the radio state (enable/disable) and tx power targets
6989 * based on a new set of channel/regulatory information
6992 wlc_channels_commit(wlc_cm_info_t
*wlc_cm
)
6994 wlc_info_t
*wlc
= wlc_cm
->wlc
;
6998 /* search for the existence of any valid channel */
6999 for (chan
= 0; chan
< MAXCHANNEL
; chan
++) {
7000 if (VALID_CHANNEL20_DB(wlc
, chan
)) {
7004 if (chan
== MAXCHANNEL
)
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 */
7042 wlc_quiet_channels_reset(wlc_cm_info_t
*wlc_cm
)
7044 wlc_info_t
*wlc
= wlc_cm
->wlc
;
7048 /* initialize quiet channels for restricted channels */
7049 bcopy(&wlc_cm
->restricted_channels
, &wlc_cm
->quiet_channels
, sizeof(chanvec_t
));
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
)) {
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
];
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
)));
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
)));
7082 setbit(wlc_cm
->quiet_channels
.vec
, CHSPEC_CHANNEL(chspec
));
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
)));
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)
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? */
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? */
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? */
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.
7142 wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t
*wlc_cm
,
7143 txppr_t
*txpwr
, uint8 local_constraint_qdbm
)
7147 bool ishtphy
= WLCISHTPHY(wlc_cm
->wlc
->band
);
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
);
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 */
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 */
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
);
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
);
7283 txpwr
->mcs32
= MIN(txpwr
->mcs32
, local_constraint_qdbm
);
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
);
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
;
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),
7318 wlc_channel_set_txpower_limit(wlc_cm_info_t
*wlc_cm
, uint8 local_constraint_qdbm
)
7320 wlc_info_t
*wlc
= wlc_cm
->wlc
;
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
);
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
;
7342 const country_info_t
*country
;
7344 const locale_info_t
* li
;
7346 int conducted_ofdm_max
;
7348 const locale_mimo_info_t
*li_mimo
;
7349 int maxpwr20
, maxpwr40
;
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
)))
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
)
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
);
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
);
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
7398 if (li
->flags
& WLC_EIRP
) {
7399 delta
= band
->antgain
;
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))
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);
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
) {
7438 else if (chan
== 14)
7440 } else if (li
== &locale_b2
) {
7442 maxpwr
= 54; /* 13.5 dBm */
7443 } else if (li
== &locale_b2_1
|| li
== &locale_b2_2
) {
7444 if (chan
== 11 || chan
== 14)
7446 } else if (li
== &locale_b2_6
) {
7449 } else if (li
== &locale_b5
) {
7451 maxpwr
= 42; /* 10.5 dBm */
7452 } else if (li
== &locale_a4
||
7453 li
== &locale_a4_2
||
7454 li
== &locale_a4_3
) {
7457 else if (chan
== 10)
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
) {
7465 } else if (li
== &locale_b5_2
) {
7468 } else if (li
== &locale_b5_3
|| li
== &locale_c_2
) {
7471 } else if (li
== &locale_a12
) {
7472 if (chan
== 7 || chan
== 8)
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
) {
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
) {
7503 maxpwr
= 66; /* 16.5 dBm */
7504 } else if (li
== &locale_b2
) {
7506 maxpwr
= 70; /* 17.5 dBm */
7507 } else if (li
== &locale_b2_1
|| li
== &locale_b2_2
) {
7510 } else if (li
== &locale_b2_3
|| li
== &locale_b2_5
) {
7512 maxpwr
= 46 /* 11.5 dBm */;
7513 } else if (li
== &locale_b2_6
) {
7516 } else if (li
== &locale_k
) {
7519 } else if (li
== &locale_b5
) {
7521 maxpwr
= 62; /* 15.5 dBm */
7522 } else if (li
== &locale_a4
|| li
== &locale_a4_2
) {
7523 if (chan
== 2 || chan
== 10)
7525 } else if (li
== &locale_a4_3
) {
7526 if (chan
== 2 || chan
== 10)
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)
7534 } else if (li
== &locale_a5_1
) {
7535 if (chan
== 2 || chan
== 10)
7537 } else if (li
== &locale_a6_2
) {
7538 if (chan
== 2 || chan
== 10)
7540 } else if (li
== &locale_a6
|| li
== &locale_a6_1
) {
7541 if (chan
== 2 || chan
== 10)
7543 } else if (li
== &locale_a9
) {
7544 if (chan
== 2 || chan
== 10)
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)
7551 } else if (li
== &locale_b5_3
) {
7553 maxpwr
= 51; /* 12.75 */
7554 } else if (li
== &locale_i_1
) {
7559 } else if (li
== &locale_a3_1
) {
7562 else if (chan
== 10)
7564 } else if (li
== &locale_a12
) {
7567 else if (chan
== 3 || chan
== 8)
7569 else if (chan
== 4 || chan
== 7)
7571 else if (chan
== 5 || chan
== 6)
7577 maxpwr
= li
->maxpwr
[CHANNEL_POWER_IDX_5G(chan
)];
7580 /* special cases for 5G OFDM */
7581 if (li
== &locale_8b
) {
7583 maxpwr
= 58; /* 14.5 dBm */
7584 } else if (chan
>= 104 && chan
<= 136) {
7586 } else if (chan
== 140) {
7589 } else if (li
== &locale_29b
) {
7591 maxpwr
= 62; /* 15.5 dBm */
7592 } else if (chan
>= 132 && chan
<= 140) {
7595 } else if ((li
== &locale_29b_1
) || (li
== &locale_29b_3
)) {
7597 maxpwr
= 74; /* 18.5 dBm */
7598 } else if (chan
== 140) {
7601 } else if (li
== &locale_29d
) {
7602 if (chan
>= 132 && chan
<= 140)
7603 maxpwr
= 78 /* 19.5 */;
7604 } else if (li
== &locale_11_2
) {
7608 } else if (li
== &locale_19_1
) {
7609 if (chan
>= 104 && chan
<= 136) {
7611 } else if (chan
== 140) {
7612 maxpwr
= 50; /* 12.5 dBm */
7614 } else if (li
== &locale_19_2
) {
7615 if (chan
== 100 || chan
== 140) {
7617 } else if (chan
== 149 || chan
== 165) {
7618 maxpwr
= 78 /* 19.5 */;
7620 } else if (li
== &locale_19h_1
) {
7622 maxpwr
= 58 /* 14.5 */;
7624 } else if (li
== &locale_19_3
) {
7628 } else if (li
== &locale_19_4
) {
7633 maxpwr
= 62 /* 15.5 dBm */;
7635 } else if (li
== &locale_19a_1
) {
7639 } else if (li
== &locale_19l_1
) {
7643 } else if (li
== &locale_19l_2
) {
7645 maxpwr
= /* 14.5 dBm */ 58;
7646 } else if (chan
== 140) {
7649 } else if (li
== &locale_3l
) {
7650 if (chan
>= 132 && chan
<= 140) {
7651 maxpwr
= 54; /* 13.5 dBm */
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
;
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;
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
7699 if (li_mimo
->flags
& WLC_EIRP
) {
7700 delta
= band
->antgain
;
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);
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
) {
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) {
7739 } else if (chan
>= 110 && chan
<= 132) {
7740 maxpwr20
= 58; /* 14.5 dBm */
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 */
7765 if (li_mimo
== &locale_19an
||
7766 li_mimo
== &locale_19ln
)
7769 maxpwr40
= 74; /* 18.5 dBm */
7773 if (li_mimo
== &locale_19hn_2
) {
7774 if (chan
>= 100 && chan
<= 102) {
7775 maxpwr20
= 82; /* 20.5 */
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) {
7787 } else if (chan
== 140) {
7788 maxpwr20
= 54; /* 13.5 dBm */
7793 if (li_mimo
== &locale_19n_2
) {
7794 if (chan
>= 100 && chan
<= 102) {
7797 } else if (chan
>= 128 && chan
<= 136) {
7800 } else if (chan
>= 159 && chan
<= 161) {
7801 maxpwr20
= 82 /* 20.5 */;
7803 } else if (chan
== 140) {
7806 } else if (chan
== 165) {
7807 maxpwr20
= 78 /* 19.5 */;
7809 } else if (chan
== 149) {
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
) {
7829 } else if (chan
>= 104 && chan
<= 116) {
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
) {
7844 maxpwr20
= 58 /* 14.5 */;
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
) {
7859 } else if (chan
== 140) {
7860 maxpwr20
= 66 /* 16.5 */;
7862 } else if (chan
>= 132 && chan
<= 136) {
7863 maxpwr40
= 74; /* 18.5 dBm */
7867 if (li_mimo
== &locale_29bn_3
) {
7871 } else if (chan
== 140) {
7872 maxpwr20
= 66 /* 16.5 */;
7874 } else if (chan
>= 132 && chan
<= 136) {
7879 if (li_mimo
== &locale_19ln_1
) {
7880 if (chan
>= 100 && chan
<= 108) {
7884 if (chan
>= 110 && chan
<= 132) {
7885 maxpwr40
= 70; /* 18.5 dBm */
7887 if (chan
>= 134 && chan
<= 136) {
7888 maxpwr40
= 62; /* 15.5 dBm */
7891 maxpwr20
= 54; /* 13.5 dBm */
7894 if (chan
>= 149 && chan
< 165) {
7899 if (li_mimo
== &locale_19ln_2
) {
7900 if (chan
>= 110 && chan
<= 132) {
7901 maxpwr20
= /* 14.5 dBm */ 58;
7904 if (chan
>= 134 && chan
<= 136) {
7905 maxpwr20
= /* 14.5 dBm */ 58;
7906 maxpwr40
= 62; /* 15.5 dBm */
7909 maxpwr20
= 54; /* 13.5 dBm */
7914 if (li_mimo
== &locale_19ln_3
) {
7915 if (chan
>= 100 && chan
<= 102) {
7921 if (li_mimo
== &locale_3ln
||
7922 li_mimo
== &locale_11ln
) {
7923 if (chan
>= 132 && chan
<= 140) {
7928 if (li_mimo
== &locale_6an_1
) {
7929 if (chan
>= 36 && chan
<= 38) {
7931 } else if (chan
>= 52 && chan
<= 54) {
7936 if (li_mimo
== &locale_8an_1
) {
7937 if (chan
>= 100 && chan
<= 102) {
7943 if (li_mimo
== &locale_29dn_2
) {
7944 if (chan
>= 52 && chan
<= 54) {
7947 } else if (chan
>= 100 && chan
<= 108) {
7953 if (li_mimo
== &locale_25hn
) {
7954 if ((chan
>= 100 && chan
<= 124)||
7955 (chan
>= 149 && chan
<= 161)) {
7962 if (li_mimo
== &locale_3n_1
) {
7963 if (chan
>= 100 && chan
<= 102) {
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
) {
8028 } else if (chan
>= 4 && chan
<= 8) {
8030 } else if (chan
== 9) {
8032 } else if (chan
== 12 || chan
== 13) {
8037 if (li_mimo
== &locale_bn2_8
) {
8042 maxpwr40
= 54; /* 13.5 QDB */
8043 } else if (chan
>= 4 && chan
<= 8) {
8045 } else if (chan
== 9) {
8047 } else if (chan
== 12 || chan
== 13) {
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
) {
8066 maxpwr20
= 50; /* 12.5 dBm */
8069 maxpwr20
= 66; /* 16.5 dBm */
8075 maxpwr40
= 58; /* 14.5 dBm */
8080 if (li_mimo
== &locale_bn
|| li_mimo
== &locale_cn
) {
8084 if (chan
>= 3 && chan
<= 11) {
8089 if (li_mimo
== &locale_cn_3
) {
8090 maxpwr20
= 70; /* 17.5 dBm */
8093 if (chan
>= 3 && chan
<= 11) {
8094 maxpwr40
= 70; /* 17.5 dBm */
8098 if (li_mimo
== &locale_an6_6
) {
8104 if (chan
== 3 || chan
== 9)
8106 else if (chan
>= 4 && chan
<= 8)
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
;
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 */
8150 if (li_mimo
== &locale_an1_t1
) {
8153 } else if (chan
== 2) {
8155 } else if (chan
== 3) {
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) {
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) {
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) {
8172 } else if (chan
== 11) {
8175 } else if (li_mimo
== &locale_an1_t2
) {
8178 } else if (chan
== 2) {
8179 maxpwr20
= 62; /* 15.5 dBm */
8180 } else if (chan
== 3) {
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) {
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
) {
8203 } else if (chan
== 2) {
8205 } else if (chan
>= 3 && chan
<= 8) {
8207 } else if (chan
== 9) {
8208 maxpwr20
= 66; /* 16.5 dBm */
8209 } else if (chan
== 10) {
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
8223 txpwr
->u40
.n
.cdd
[i
] = (uint8
)max_low_mcs
;
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
8235 txpwr
->u40
.n
.sdm
[i
] = (uint8
)max_mid_mcs
;
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
;
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
) {
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
) {
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
8313 txpwr
->u40
.n
.cdd
[i
] = (uint8
)max_low_mcs
;
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
8323 txpwr
->u40
.n
.sdm
[i
] = (uint8
)max_mid_mcs
;
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
;
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
8351 txpwr
->u20
.n
.cdd
[i
] = (uint8
)max_low_mcs
;
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
8361 txpwr
->u20
.n
.sdm
[i
] = (uint8
)max_mid_mcs_sdm
;
8363 txpwr
->u20
.n
.sdm
[i
] = (uint8
)max_high_mcs
;
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
8380 txpwr
->u40
.n
.cdd
[i
] = (uint8
)max_low_mcs
;
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
8390 txpwr
->u40
.n
.sdm
[i
] = (uint8
)max_mid_mcs_sdm
;
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
;
8414 max_mid_mcs_sdm
= 0;
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
8435 txpwr
->u40
.n
.cdd
[i
] = (uint8
)max_low_mcs
;
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
8445 txpwr
->u40
.n
.sdm
[i
] = (uint8
)max_mid_mcs
;
8447 txpwr
->u40
.n
.sdm
[i
] = (uint8
)max_high_mcs
;
8451 if (li_mimo
== &locale_11ln_2
) {
8456 if (chan
>= 36 && chan
<= 48) {
8459 } else if (chan
>= 52 && chan
<= 64) {
8460 maxpwr20
= 58; /* 14.5 dBm */
8462 } else if (chan
>= 100 && chan
<= 140) {
8465 } else if (chan
>= 149 && chan
<= 165) {
8466 maxpwr20
= 70; /* 17.5 dBm */
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
) {
8491 if (li_mimo
== &locale_19n_1
) {
8495 if (chan
>= 36 && chan
<= 44) {
8498 } else if (chan
>= 46 && chan
<= 48) {
8501 } else if (chan
>= 52 && chan
<= 60) {
8504 } else if (chan
>= 62 && chan
<= 64) {
8507 } else if (chan
>= 100 && chan
<= 108) {
8510 } else if (chan
>= 110 && chan
<= 140) {
8511 maxpwr20
= 50; /* 12.5 dBm */
8513 } else if (chan
>= 149 && chan
<= 165) {
8517 } else if (li_mimo
== &locale_19n_2
) {
8518 if (chan
>= 36 && chan
<= 48) {
8521 } else if (chan
>= 52 && chan
<= 140) {
8524 } else if (chan
>= 149 && chan
<= 165) {
8528 } else if (li_mimo
== &locale_3jn_4
) {
8532 if (chan
>= 36 && chan
<= 48) {
8535 } else if (chan
>= 52 && chan
<= 64) {
8538 } else if (chan
>= 100 && chan
<= 140) {
8542 } else if (li_mimo
== &locale_3rn_3
) {
8546 if ((chan
>= 36 && chan
<= 64) ||
8547 (chan
>= 100 && chan
<= 116) ||
8548 (chan
>= 132 && chan
<= 140)) {
8552 } else if (li_mimo
== &locale_2n
) {
8555 } else if (li_mimo
== &locale_5ln_2
) {
8559 if (chan
>= 36 && chan
<= 64) {
8562 } else if (chan
>= 149 && chan
<= 165) {
8566 } else if (li_mimo
== &locale_6an_1
) {
8570 if (chan
>= 36 && chan
<= 38) {
8573 } else if ((chan
>= 40 && chan
<= 48) ||
8574 (chan
>= 52 && chan
<= 64)) {
8577 } else if (chan
>= 149 && chan
<= 165) {
8581 } else if (li_mimo
== &locale_7cn_1
) {
8585 if (chan
>= 149 && chan
<= 165) {
8589 } else if (li_mimo
== &locale_8an_1
) {
8593 if (chan
>= 56 && chan
<= 64) {
8596 } else if (chan
>= 100 && chan
<= 102) {
8599 } else if ((chan
>= 104 && chan
<= 140) ||
8600 (chan
>= 149 && chan
<= 165)) {
8604 } else if (li_mimo
== &locale_13n_2
) {
8608 if (chan
>= 36 && chan
<= 64) {
8612 } else if (li_mimo
== &locale_25hn
) {
8616 if (chan
>= 36 && chan
<= 48) {
8619 } else if (chan
>= 52 && chan
<= 64) {
8622 } else if ((chan
>= 100 && chan
<= 124) ||
8623 (chan
>= 149 && chan
<= 161)) {
8627 } else if (li_mimo
== &locale_29dn_2
) {
8631 if (chan
>= 36 && chan
<= 38) {
8634 } else if (chan
>= 40 && chan
<= 48) {
8637 } else if (chan
>= 100 && chan
<= 108) {
8640 } else if ((chan
>= 52 && chan
<= 64) ||
8641 (chan
>= 110 && chan
<= 116) ||
8642 (chan
>= 132 && chan
<= 140) ||
8643 (chan
>= 149 && chan
<= 165)) {
8647 } else if (li_mimo
== &locale_3en
) {
8648 if (chan
>= 36 && chan
<= 140) {
8654 if (li_mimo
== &locale_bn7
) {
8657 if (chan
>= 3 && chan
<= 11) {
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
) {
8673 if (chan
>= 36 && chan
<= 38) {
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) {
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
) {
8713 if (chan
>= 36 && chan
<= 44) {
8716 if (li_mimo
== &locale_19ln_1
)
8717 maxpwr40
= 58; /* 14.5 dBm */
8719 if (li_mimo
== &locale_19ln_2
)
8722 if (li_mimo
== &locale_19ln_4
) {
8727 } else if (chan
>= 46 && chan
<= 48) {
8728 if ((li_mimo
== &locale_19ln_2
) || (li_mimo
== &locale_19ln_4
)) {
8733 maxpwr40
= 66; /* 16.5 dBm */
8735 } else if (chan
>= 52 && chan
<= 60) {
8736 maxpwr20
= 70; /* 17.5 dBm */
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 */
8743 maxpwr20
= 58; /* 14.5 dBm */
8746 } else if (chan
>= 100 && chan
<= 108) {
8747 if (li_mimo
== &locale_19ln_2
)
8748 maxpwr20
= 58; /* 14.5 dBm */
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) {
8759 if (chan
>= 134 && chan
<= 136) {
8760 if (li_mimo
== &locale_19ln_1
)
8762 else if ((li_mimo
== &locale_19ln_2
) || (li_mimo
== &locale_19ln_4
))
8766 (li_mimo
== &locale_19ln_2
|| (li_mimo
== &locale_19ln_1
) ||
8767 (li_mimo
== &locale_19ln_4
))) {
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
) {
8787 if (chan
>= 36 && chan
<= 48) {
8789 maxpwr40
= 62 /* 15.5 */;
8790 } else if (chan
>= 52 && chan
<= 60) {
8791 maxpwr20
= 70 /* 17.5 */;
8793 } else if (chan
>= 62 && chan
<= 64) {
8796 } else if (chan
>= 100 && chan
<= 102) {
8797 maxpwr20
= 66 /* 16.5 */;
8799 } else if (chan
>= 104 && chan
<= 132) {
8800 maxpwr20
= 66 /* 16.5 */;
8802 } else if (chan
>= 134 && chan
<= 136) {
8803 maxpwr20
= 66 /* 16.5 */;
8805 } else if (chan
== 140) {
8806 maxpwr20
= 58 /* 14.5 */;
8807 } else if (chan
>= 149 && chan
<= 165) {
8808 maxpwr20
= 74 /* 18.5 */;
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) {
8822 } else if (chan
>= 110 && chan
<= 132) {
8823 maxpwr20
= 58; /* 14.5 dBm */
8825 } else if (chan
>= 134 && chan
<= 136) {
8826 maxpwr20
= 58; /* 14.5 dBm */
8827 maxpwr40
= 62; /* 15.5 dBm */
8828 } else if (chan
== 140) {
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
) {
8845 if (chan
>= 36 && chan
<= 48) {
8848 } else if ((chan
>= 52 && chan
<= 64) ||
8849 (chan
>= 100 && chan
<= 140) ||
8850 (chan
>= 149 && chan
<= 165)) {
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
];
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
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
];
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
];
8917 if (WLCISHTPHY(wlc
->band
)) {
8918 n2x2_t u20pl
, u40pl
, u20npl
, u40npl
;
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.
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.
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
];
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)) {
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 */
9052 if (li_mimo
== &locale_29_3n
) {
9053 if ((chan
>= 100) && (chan
<= 102)) {
9055 maxpwr40
= 42; /* 10.5 dBm */
9056 } else if ((chan
>= 104) && (chan
<= 140)) {
9057 maxpwr20
= 62; /* 15.5dbm */
9059 } else if ((chan
>= 161) && (chan
<= 165)) {
9065 for (i
= 0; i
< WL_NUM_RATES_MCS_1STREAM
; i
++) {
9067 u20pl
.sdm
[i
] = (uint8
)maxpwr20
;
9068 u20pl
.cdd
[i
] = (uint8
)maxpwr20
;
9069 u40pl
.sdm
[i
] = (uint8
)maxpwr40
;
9070 u40pl
.cdd
[i
] = (uint8
)maxpwr40
;
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
];
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
];
9110 if (li_mimo
== &locale_19_3n
) {
9111 if ((chan
>= 36) && (chan
<= 48)) {
9112 /* MCS 0-7 has seperate CDD limits defined,
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,
9123 txpwr
->stbc
.s2x3
[i
] = QDB(7);
9124 txpwr
->stbc
.u40_s2x3
[i
] = QDB(9);
9125 txpwr
->stbc
.ul20_s2x3
[i
] = QDB(7);
9129 txpwr
->ht
.u20s2x3
[i
] = QDB(8);
9130 txpwr
->ht
.u40s2x3
[i
] = QDB(10);
9132 txpwr
->ht
.u20s2x3
[i
] = QDB(9);
9133 txpwr
->ht
.u40s2x3
[i
] = QDB(12);
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);
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,
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,
9162 txpwr
->stbc
.s2x3
[i
] = QDB(10);
9163 txpwr
->stbc
.u40_s2x3
[i
] = QDB(13);
9164 txpwr
->stbc
.ul20_s2x3
[i
] = QDB(10);
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,
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,
9185 txpwr
->stbc
.s2x3
[i
] = 62; /* 15.5 */
9186 txpwr
->stbc
.u40_s2x3
[i
] = QDB(18);
9187 txpwr
->stbc
.ul20_s2x3
[i
] = 62;
9191 if ((chan
>= 62) && (chan
<= 64)) {
9192 /* MCS 0-7 has seperate CDD limits defined,
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,
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);
9209 if ((chan
>= 100) && (chan
<= 102)) {
9210 /* MCS 0-7 has seperate CDD limits defined,
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,
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);
9227 if ((chan
>= 104) && (chan
<= 140)) {
9228 /* MCS 0-7 has seperate CDD limits defined,
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,
9239 txpwr
->stbc
.s2x3
[i
] = 62; /* 15.5 dBm */
9240 txpwr
->stbc
.u40_s2x3
[i
] = QDB(18);
9241 txpwr
->stbc
.ul20_s2x3
[i
] = 62;
9251 WL_NONE(("Channel(chanspec) %d (0x%4.4x)\n", CHSPEC_CHANNEL(chanspec
), chanspec
));
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 */
9260 /* Returns TRUE if currently set country is Japan or variant */
9262 wlc_japan(struct wlc_info
*wlc
)
9264 return wlc_japan_ccode(wlc
->cmi
->country_abbrev
);
9267 /* JP, J1 - J10 are Japan ccodes */
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 */
9277 wlc_us_ccode(const char *ccode
)
9279 return (!strncmp("US", ccode
, 3) || !strncmp("Q2", ccode
, 3));
9283 wlc_rcinfo_init(wlc_cm_info_t
*wlc_cm
)
9285 if (wlc_us_ccode(wlc_cm
->country_abbrev
)) {
9287 wlc_cm
->rcinfo_list
[WLC_RCLIST_20
] = &rcinfo_us_20
;
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
;
9295 } else if (wlc_japan_ccode(wlc_cm
->country_abbrev
)) {
9297 wlc_cm
->rcinfo_list
[WLC_RCLIST_20
] = &rcinfo_jp_20
;
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
;
9307 wlc_cm
->rcinfo_list
[WLC_RCLIST_20
] = &rcinfo_eu_20
;
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
;
9319 wlc_regclass_vec_init(wlc_cm_info_t
*wlc_cm
)
9322 chanspec_t chanspec
;
9324 wlc_info_t
*wlc
= wlc_cm
->wlc
;
9325 bool saved_cap_40
, saved_db_cap_40
= TRUE
;
9327 rcvec_t
*rcvec
= &wlc_cm
->valid_rcvec
;
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
;
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
)))
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
)))
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
)))
9359 #endif /* defined(WL11N) && !defined(WL11N_20MHZONLY) */
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
;
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
));
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
;
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
;
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")))));
9409 /* get the ordered list of supported reg class, with current reg class
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
);
9422 cur_rc
= wlc_get_regclass(wlc_cm
, chspec
);
9424 WL_ERROR(("wl%d: current regulatory class is not found\n",
9425 wlc_cm
->wlc
->pub
->unit
));
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
))
9436 if (i
< MAXREGCLASS
&& idx
== lsize
) {
9437 WL_ERROR(("wl%d: regulatory class list full %d\n", wlc_cm
->wlc
->pub
->unit
, idx
));
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
)) {
9452 return WLC_REGCLASS_JPN_2G_20MHZ
;
9454 return WLC_REGCLASS_JPN_2G_20MHZ_CH14
;
9456 return WLC_REGCLASS_EUR_2G_20MHZ
;
9460 wlc_get_regclass(wlc_cm_info_t
*wlc_cm
, chanspec_t chanspec
)
9462 const rcinfo_t
*rcinfo
= NULL
;
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
];
9472 rcinfo
= wlc_cm
->rcinfo_list
[WLC_RCLIST_40L
];
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
));
9493 #if defined(BCMDBG) || defined(BCMDBG_DUMP)
9495 wlc_dump_rclist(const char *name
, uint8
*rclist
, uint8 rclen
, struct bcmstrbuf
*b
)
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");
9512 /* format a qdB value as integer and decimal fraction in a bcmstrbuf */
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 */
9525 wlc_channel_dump_pwr_range(struct bcmstrbuf
*b
, const char *label
, uint8
*ptr
, uint count
)
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 */
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 */
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
);
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
);
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.
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'))
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
))
9632 wlc_get_channels_in_country(struct wlc_info
*wlc
, void *arg
)
9635 wl_channels_in_country_t
*cic
= (wl_channels_in_country_t
*)arg
;
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
))
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
));
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
;
9684 wlc_get_country_list(struct wlc_info
*wlc
, void *arg
)
9687 wl_country_list_t
*cl
= (wl_country_list_t
*)arg
;
9688 const locale_info_t
*locale
= NULL
;
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
));
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
]) {
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",
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
) ==
9747 strncpy(&cl
->country_abbrev
[count
*WLC_CNTRY_BUF_SZ
],
9748 cntry_locales
[i
].abbrev
, WLC_CNTRY_BUF_SZ
);
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.
9767 wlc_get_reg_max_power_for_channel(wlc_cm_info_t
*wlc_cm
, int chan
, bool external
)
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
);
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
];
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
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
));
9803 if (CHANNEL_BANDUNIT(wlc_cm
->wlc
, channel
) != CHSPEC_WLCBANDUNIT(chspec
))
9806 /* Check a 20Mhz channel */
9807 if (CHSPEC_IS20(chspec
)) {
9809 return (VALID_CHANNEL20_DB(wlc_cm
->wlc
, channel
));
9811 return (VALID_CHANNEL20(wlc_cm
->wlc
, channel
));
9814 /* We know we are now checking a 40MHZ channel, so we should only be here
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
)))
9826 if (!VALID_CHANNEL20_DB(wlc
, LOWER_20_SB(channel
)) ||
9827 !VALID_CHANNEL20_DB(wlc
, UPPER_20_SB(channel
)))
9830 if (!VALID_CHANNEL20(wlc
, LOWER_20_SB(channel
)) ||
9831 !VALID_CHANNEL20(wlc
, UPPER_20_SB(channel
)))
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
))
9850 wlc_valid_chanspec(wlc_cm_info_t
*wlc_cm
, chanspec_t chspec
)
9852 return wlc_valid_chanspec_ext(wlc_cm
, chspec
, FALSE
);
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.
9865 wlc_chanspec_list(wlc_info_t
*wlc
, wl_uint32_list_t
*list
, chanspec_t chanspec_mask
)
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
;
9882 * Returns a list of valid chanspecs meeting the provided settings
9885 wlc_get_valid_chanspecs(wlc_cm_info_t
*wlc_cm
, wl_uint32_list_t
*list
, bool bw20
, bool band2G
,
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
;
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
;
9899 /* Check if this is a valid band for this card */
9900 if ((NBANDS(wlc
) == 1) &&
9901 (BAND_5G(wlc
->band
->bandtype
) == band2G
))
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
));
9914 wlc_get_locale_2g(country
->locale_2G
) :
9915 wlc_get_locale_5g(country
->locale_5G
);
9919 wlc_get_mimo_2g(country
->locale_mimo_2G
) :
9920 wlc_get_mimo_5g(country
->locale_mimo_5G
);
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
);
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
;
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
);
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
;
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 */
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;
10023 if (wlc_us_ccode(abbrev
)) {
10024 if (rclass
== WLC_REGCLASS_USA_2G_20MHZ
) {
10030 rcinfo
= &rcinfo_us_20
;
10032 } else if (wlc_japan_ccode(abbrev
)) {
10033 if (rclass
== WLC_REGCLASS_JPN_2G_20MHZ
) {
10037 else if (rclass
== WLC_REGCLASS_JPN_2G_20MHZ_CH14
) {
10043 rcinfo
= &rcinfo_jp_20
;
10046 if (rclass
== WLC_REGCLASS_EUR_2G_20MHZ
) {
10052 rcinfo
= &rcinfo_eu_20
;
10057 if (rcinfo
== NULL
) {
10058 for (i
= ch2g_start
; i
<= ch2g_end
; i
++)
10059 list
->element
[list
->count
++] = i
;
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
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
)) {
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
)))
10096 } else if (isset(radar_channels
->vec
, channel
)) {
10100 #endif /* BAND5G */
10104 /* Return true if the channel is a valid channel that is radar sensitive
10105 * in the current country/locale
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
)) {
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
)))
10127 } else if (isset(restricted_channels
->vec
, channel
)) {
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
)));
10141 clrbit(wlc_cm
->restricted_channels
.vec
, CHSPEC_CHANNEL(chspec
));
10143 wlc_upd_restricted_chanspec_flag(wlc_cm
);
10147 wlc_upd_restricted_chanspec_flag(wlc_cm_info_t
*wlc_cm
)
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
;
10157 wlc_cm
->has_restricted_ch
= FALSE
;
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
;
10173 char max_cck_str
[32];
10177 int max_cck
, max_ofdm
;
10178 int max_ht20
= 0, max_ht40
= 0;
10179 char fraction
[4][4] = {" ", ".25", ".5", ".75"};
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"},
10190 uint8 rclist
[MAXRCLISTSIZE
], rclen
;
10191 chanspec_t chanspec
;
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
,
10200 bcm_bprintf(b
, "2G Flags: %s\n", flagstr
);
10201 bcm_format_flags(fc_flags
, wlc
->cmi
->bandstate
[BAND_5G_INDEX
].locale_flags
,
10203 bcm_bprintf(b
, "5G Flags: %s\n", flagstr
);
10205 bcm_format_flags(fc_flags
, wlc
->cmi
->bandstate
[wlc
->band
->bandunit
].locale_flags
,
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");
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
))
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];
10232 max_ht20
= txpwr
.u20
.n
.cdd
[0];
10233 max_ht40
= txpwr
.u40
.n
.cdd
[0];
10236 if (CHSPEC_IS2G(chanspec
))
10237 snprintf(max_cck_str
, sizeof(max_cck_str
),
10238 "%2d%s/", QDB_FRAC(max_cck
));
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
));
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
);
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");
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 */
10291 #endif /* BCMDBG || BCMDBG_DUMP */
10294 #define INT8_MIN 0x80
10297 #define INT8_MAX 0x7F
10300 /* Perform an element by element min of txppr structs a and b, and
10301 * store the result in a.
10304 wlc_channel_txpwr_vec_combine_min(txppr_t
*a
, txppr_t
*b
)
10308 for (i
= 0; i
< sizeof(txppr_t
); i
++)
10309 ((uint8
*)a
)[i
] = MIN(((uint8
*)a
)[i
], ((uint8
*)b
)[i
]);
10313 wlc_channel_margin_summary_mapfn(void *context
, uint8
*a
, uint8
*b
)
10316 uint8
*pmin
= (uint8
*)context
;
10323 *pmin
= MIN(*pmin
, margin
);
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
10338 wlc_channel_map_uint8_vec_binary(wlc_channel_mapfn_t fn
, void* context
, uint len
,
10339 uint8
*vec_a
, uint8
*vec_b
)
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.
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
,
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
);
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
);
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
);
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.
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
);
10451 /* calculate the max power target of relevant rates for bandtype/bw */
10453 wlc_channel_txpwr_max(txppr_t
*txpwr
, uint bandtype
, uint bw
)
10457 wlc_channel_map_txppr_binary(wlc_channel_max_summary_mapfn
, &pwr_max
,
10458 bandtype
, bw
, txpwr
, NULL
);
10468 static const struct txp_range txp_ranges_2g_20
[] = {
10475 static const struct txp_range txp_ranges_2g_40
[] = {
10482 static const struct txp_range txp_ranges_5g_20
[] = {
10488 static const struct txp_range txp_ranges_5g_40
[] = {
10495 /* return a txppr_t struct with the phy srom limits for the given channel */
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
))
10515 if (CHSPEC_IS2G(chanspec
)) {
10516 if (CHSPEC_IS20(chanspec
))
10517 txp_ranges
= txp_ranges_2g_20
;
10519 txp_ranges
= txp_ranges_2g_40
;
10521 if (CHSPEC_IS20(chanspec
))
10522 txp_ranges
= txp_ranges_5g_20
;
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
;
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
)
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
);
10569 /* update the per-chain tx power offset given the current power targets to implement
10570 * the correct per-chain tx power limit
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
;
10583 int limits_present
= FALSE
;
10584 uint8 delta
, margin
, err_margin
;
10586 char chanbuf
[CHANSPEC_STR_LEN
];
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
;
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
;
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
);
10669 WL_ERROR(("wl%d: txchain_pwr_offset failed: error %d\n",
10670 wlc
->pub
->unit
, err
));
10676 #if defined(BCMDBG) || defined(BCMDBG_DUMP)
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
;
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
));
10694 /* dump of regulatory power with local constraint factored in for the current channel */
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
;
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
));
10712 /* dump of srom per-rate max/min values for the current channel */
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
;
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
));
10737 wlc_channel_margin_calc_mapfn(void *ignore
, uint8
*a
, uint8
*b
)
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
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
;
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
));
10784 #endif /* BCMDBG || BCMDBG_DUMP */