17 #include <linux/types.h>
31 #define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR)
33 #define LOCALE_MIMO_IDX_bn 0
34 #define LOCALE_MIMO_IDX_11n 0
37 #define BRCMS_MAXPWR_MIMO_TBL_SIZE 14
46 #define BAND_5G_PWR_LVLS 5
48 #define LC(id) LOCALE_MIMO_IDX_ ## id
50 #define LOCALES(mimo2, mimo5) \
51 {LC(mimo2), LC(mimo5)}
54 #define CHANNEL_POWER_IDX_5G(c) (((c) < 52) ? 0 : \
57 (((c) < 149) ? 3 : 4))))
59 #define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0)
60 #define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \
61 NL80211_RRF_PASSIVE_SCAN | \
64 #define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \
65 NL80211_RRF_PASSIVE_SCAN | \
67 #define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \
68 NL80211_RRF_PASSIVE_SCAN | \
71 #define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \
72 NL80211_RRF_PASSIVE_SCAN | \
75 #define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \
76 NL80211_RRF_PASSIVE_SCAN | \
140 { 50, 50, 50,
QDB(15),
QDB(15)},
148 static const struct brcms_regd cntry_locales[] = {
152 .regdomain = &brcms_regdom_x2,
158 if (locale_idx >=
ARRAY_SIZE(g_mimo_2g_table))
161 return g_mimo_2g_table[locale_idx];
166 if (locale_idx >=
ARRAY_SIZE(g_mimo_5g_table))
169 return g_mimo_5g_table[locale_idx];
178 static bool brcms_c_country_valid(
const char *ccode)
184 if (!((0x80 & ccode[0]) == 0 && ccode[0] >= 0x41 && ccode[0] <= 0x5A &&
185 (0x80 & ccode[1]) == 0 && ccode[1] >= 0x41 && ccode[1] <= 0x5A &&
193 if (!
strcmp(
"AA", ccode) ||
197 (ccode[1] >=
'M' && ccode[1] <=
'Z')))
206 static const struct brcms_regd *brcms_world_regd(
const char *regdom,
int len)
211 for (i = 0; i <
ARRAY_SIZE(cntry_locales); i++) {
213 regd = &cntry_locales[
i];
221 static const struct brcms_regd *brcms_default_world_regd(
void)
223 return &cntry_locales[0];
227 static bool brcms_c_japan_ccode(
const char *ccode)
229 return (ccode[0] ==
'J' &&
230 (ccode[1] ==
'P' || (ccode[1] >=
'1' && ccode[1] <=
'9')));
234 brcms_c_channel_min_txpower_limits_with_local_constraint(
236 u8 local_constraint_qdbm)
242 txpwr->
cck[j] =
min(txpwr->
cck[j], local_constraint_qdbm);
246 txpwr->
ofdm[j] =
min(txpwr->
ofdm[j], local_constraint_qdbm);
335 struct ssb_sprom *sprom = &wlc->
hw->d11core->bus->sprom;
336 const char *ccode = sprom->
alpha2;
337 int ccode_len =
sizeof(sprom->
alpha2);
349 wlc_cm->
world_regd = brcms_world_regd(ccode, ccode_len);
350 if (brcms_c_country_valid(ccode))
351 strncpy(wlc->
pub->srom_ccode, ccode, ccode_len);
358 wlc_cm->
world_regd = brcms_default_world_regd();
359 ccode = wlc_cm->
world_regd->regdomain->alpha2;
369 brcms_c_set_country(wlc_cm, wlc_cm->
world_regd);
381 u8 local_constraint_qdbm)
389 brcms_c_channel_min_txpower_limits_with_local_constraint(
390 wlc_cm, &txpwr, local_constraint_qdbm
430 band = wlc->
bandstate[chspec_bandunit(chanspec)];
438 conducted_max =
QDB(22);
441 maxpwr =
max(maxpwr, 0);
442 maxpwr =
min(maxpwr, conducted_max);
447 txpwr->
cck[i] = (
u8) maxpwr;
472 maxpwr_idx = (chan - 1);
476 maxpwr20 = li_mimo->
maxpwr20[maxpwr_idx];
477 maxpwr40 = li_mimo->
maxpwr40[maxpwr_idx];
479 maxpwr20 = maxpwr20 -
delta;
480 maxpwr20 =
max(maxpwr20, 0);
481 maxpwr40 = maxpwr40 -
delta;
482 maxpwr40 =
max(maxpwr40, 0);
505 if (li_mimo == &locale_bn) {
506 if (li_mimo == &locale_bn) {
510 if (chan >= 3 && chan <= 11)
585 static bool brcms_c_chspec_malformed(
u16 chanspec)
617 if (brcms_c_chspec_malformed(chspec)) {
619 wlc->
pub->unit, chspec);
624 chspec_bandunit(chspec))
632 return brcms_c_valid_chanspec_ext(wlc_cm, chspec);
635 static bool brcms_is_radar_freq(
u16 center_freq)
637 return center_freq >= 5260 && center_freq <= 5700;
640 static void brcms_reg_apply_radar_flags(
struct wiphy *
wiphy)
668 brcms_reg_apply_beaconing_flags(
struct wiphy *wiphy,
677 sband = wiphy->
bands[band];
707 static int brcms_reg_notifier(
struct wiphy *wiphy,
716 bool ch_found =
false;
718 brcms_reg_apply_radar_flags(wiphy);
721 brcms_reg_apply_beaconing_flags(wiphy, request->
initiator);
729 for (i = 0; !ch_found && i < sband->
n_channels; i++) {
742 wlc->
pub->unit, __func__, request->
alpha2);
747 brcms_c_japan_ccode(request->
alpha2));
754 struct wiphy *wiphy = wlc->
wiphy;
763 for (band_idx = 0; band_idx < wlc->
pub->_nbands; band_idx++) {
781 wlc->
wiphy->reg_notifier = brcms_reg_notifier;