/* Update the radio state (enable/disable) and tx power targets * based on a new set of channel/regulatory information */ static void wlc_channels_commit(wlc_cm_info_t *wlc_cm) { struct wlc_info *wlc = wlc_cm->wlc; uint chan; struct txpwr_limits txpwr; /* search for the existence of any valid channel */ for (chan = 0; chan < MAXCHANNEL; chan++) { if (VALID_CHANNEL20_DB(wlc, chan)) { break; } } if (chan == MAXCHANNEL) chan = INVCHANNEL; /* based on the channel search above, set or clear WL_RADIO_COUNTRY_DISABLE */ if (chan == INVCHANNEL) { /* country/locale with no valid channels, set the radio disable bit */ mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); WL_ERROR("wl%d: %s: no valid channel for \"%s\" nbands %d bandlocked %d\n", wlc->pub->unit, __func__, wlc_cm->country_abbrev, NBANDS(wlc), wlc->bandlocked); } else if (mboolisset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE)) { /* country/locale with valid channel, clear the radio disable bit */ mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); } /* Now that the country abbreviation is set, if the radio supports 2G, then * set channel 14 restrictions based on the new locale. */ if (NBANDS(wlc) > 1 || BAND_2G(wlc->band->bandtype)) { wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, wlc_japan(wlc) ? true : false); } if (wlc->pub->up && chan != INVCHANNEL) { wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr); wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr, WLC_TXPWR_MAX); wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec); } }
static int wlc_channels_init(wlc_cm_info_t *wlc_cm, const country_info_t *country) { struct wlc_info *wlc = wlc_cm->wlc; uint i, j; struct wlcband *band; const locale_info_t *li; chanvec_t sup_chan; const locale_mimo_info_t *li_mimo; band = wlc->band; for (i = 0; i < NBANDS(wlc); i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { li = BAND_5G(band->bandtype) ? wlc_get_locale_5g(country->locale_5G) : wlc_get_locale_2g(country->locale_2G); ASSERT(li); wlc_cm->bandstate[band->bandunit].locale_flags = li->flags; li_mimo = BAND_5G(band->bandtype) ? wlc_get_mimo_5g(country->locale_mimo_5G) : wlc_get_mimo_2g(country->locale_mimo_2G); ASSERT(li_mimo); /* merge the mimo non-mimo locale flags */ wlc_cm->bandstate[band->bandunit].locale_flags |= li_mimo->flags; wlc_cm->bandstate[band->bandunit].restricted_channels = g_table_restricted_chan[li->restricted_channels]; wlc_cm->bandstate[band->bandunit].radar_channels = g_table_radar_set[li->radar_channels]; /* set the channel availability, * masking out the channels that may not be supported on this phy */ wlc_phy_chanspec_band_validch(band->pi, band->bandtype, &sup_chan); wlc_locale_get_channels(li, &wlc_cm->bandstate[band->bandunit]. valid_channels); for (j = 0; j < sizeof(chanvec_t); j++) wlc_cm->bandstate[band->bandunit].valid_channels. vec[j] &= sup_chan.vec[j]; } wlc_quiet_channels_reset(wlc_cm); wlc_channels_commit(wlc_cm); return 0; }
/* reset the quiet channels vector to the union of the restricted and radar channel sets */ void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm) { struct wlc_info *wlc = wlc_cm->wlc; uint i, j; struct wlcband *band; const chanvec_t *chanvec; memset(&wlc_cm->quiet_channels, 0, sizeof(chanvec_t)); band = wlc->band; for (i = 0; i < NBANDS(wlc); i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { /* initialize quiet channels for restricted channels */ chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels; for (j = 0; j < sizeof(chanvec_t); j++) wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j]; } }
int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force) { u8 txchain = (u8) int_val; u8 txstreams; uint i; if (wlc->stf->txchain == txchain) return BCME_OK; if ((txchain & ~wlc->stf->hw_txchain) || !(txchain & wlc->stf->hw_txchain)) return BCME_RANGE; /* if nrate override is configured to be non-SISO STF mode, reject reducing txchain to 1 */ txstreams = (u8) WLC_BITSCNT(txchain); if (txstreams > MAX_STREAMS_SUPPORTED) return BCME_RANGE; if (txstreams == 1) { for (i = 0; i < NBANDS(wlc); i++) if ((RSPEC_STF(wlc->bandstate[i]->rspec_override) != PHY_TXC1_MODE_SISO) || (RSPEC_STF(wlc->bandstate[i]->mrspec_override) != PHY_TXC1_MODE_SISO)) { if (!force) return BCME_ERROR; /* over-write the override rspec */ if (RSPEC_STF(wlc->bandstate[i]->rspec_override) != PHY_TXC1_MODE_SISO) { wlc->bandstate[i]->rspec_override = 0; WL_ERROR("%s(): temp sense override non-SISO rspec_override\n", __func__); } if (RSPEC_STF (wlc->bandstate[i]->mrspec_override) != PHY_TXC1_MODE_SISO) { wlc->bandstate[i]->mrspec_override = 0; WL_ERROR("%s(): temp sense override non-SISO mrspec_override\n", __func__); } } } wlc->stf->txchain = txchain; wlc->stf->txstreams = txstreams; wlc_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx); wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); wlc->stf->txant = (wlc->stf->txstreams == 1) ? ANT_TX_FORCE_0 : ANT_TX_DEF; _wlc_stf_phy_txant_upd(wlc); wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, wlc->stf->rxchain); for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) wlc_stf_txcore_set(wlc, (u8) i, txcore_default[i]); return BCME_OK; }