示例#1
0
/* 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);
	}
}
示例#2
0
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;
}
示例#3
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;
}