Beispiel #1
0
static void ath9k_reg_notifier(struct wiphy *wiphy,
			       struct regulatory_request *request)
{
	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
	struct ath_softc *sc = hw->priv;
	struct ath_hw *ah = sc->sc_ah;
	struct ath_regulatory *reg = ath9k_hw_regulatory(ah);

	ath_reg_notifier_apply(wiphy, request, reg);

	/* synchronize DFS detector if regulatory domain changed */
	if (sc->dfs_detector != NULL)
		sc->dfs_detector->set_dfs_domain(sc->dfs_detector,
						 request->dfs_region);

	/* Set tx power */
	if (!ah->curchan)
		return;

	sc->cur_chan->txpower = 2 * ah->curchan->chan->max_power;
	ath9k_ps_wakeup(sc);
	ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false);
	ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower,
			       sc->cur_chan->txpower,
			       &sc->cur_chan->cur_txpower);
	ath9k_ps_restore(sc);
}
Beispiel #2
0
static void ath9k_reg_notifier(struct wiphy *wiphy,
			       struct regulatory_request *request)
{
	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
	struct ath9k_htc_priv *priv = hw->priv;

	ath_reg_notifier_apply(wiphy, request,
			       ath9k_hw_regulatory(priv->ah));
}
static int ath9k_reg_notifier(struct wiphy *wiphy,
			      struct regulatory_request *request)
{
	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
	struct ath_softc *sc = hw->priv;
	struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah);

	return ath_reg_notifier_apply(wiphy, request, reg);
}
Beispiel #4
0
void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
			    u16 new_txpow, u16 *txpower)
{
	if (cur_txpow != new_txpow) {
		ath9k_hw_set_txpowerlimit(ah, new_txpow, 0);
		/* read back in case value is clamped */
		*txpower = ath9k_hw_regulatory(ah)->power_limit;
	}
}
Beispiel #5
0
void ath_update_txpow(struct ath9k_htc_priv *priv)
{
	struct ath_hw *ah = priv->ah;

	if (priv->curtxpow != priv->txpowlimit) {
		ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit, false);
		/* read back in case value is clamped */
		priv->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
	}
}
Beispiel #6
0
void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
			    u16 new_txpow, u16 *txpower)
{
	struct ath_regulatory *reg = ath9k_hw_regulatory(ah);

	if (reg->power_limit != new_txpow) {
		ath9k_hw_set_txpowerlimit(ah, new_txpow, false);
		/* read back in case value is clamped */
		*txpower = reg->max_power_level;
	}
}
Beispiel #7
0
static int ath9k_reg_notifier(struct wiphy *wiphy,
			      struct regulatory_request *request)
{
	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
	struct ath_softc *sc = hw->priv;
	struct ath_hw *ah = sc->sc_ah;
	struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
	int ret;

	ret = ath_reg_notifier_apply(wiphy, request, reg);

	/* Set tx power */
	if (ah->curchan) {
		sc->config.txpowlimit = 2 * ah->curchan->chan->max_power;
		ath9k_ps_wakeup(sc);
		ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false);
		sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
		ath9k_ps_restore(sc);
	}

	return ret;
}
Beispiel #8
0
static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
{
	struct net80211_channel *chan;
	struct ath_hw *ah = sc->sc_ah;
	struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
	int i;

	for (i = 0; i < sc->hwinfo->nr_channels; i++) {
		chan = &sc->hwinfo->channels[i];
		if(chan->band != band)
			continue;
		ah->curchan = &ah->channels[chan->hw_value];
		ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, 1);
		chan->maxpower = reg->max_power_level / 2;
	}
}
static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
{
	struct ieee80211_supported_band *sband;
	struct ieee80211_channel *chan;
	struct ath_hw *ah = sc->sc_ah;
	struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
	int i;

	sband = &sc->sbands[band];
	for (i = 0; i < sband->n_channels; i++) {
		chan = &sband->channels[i];
		ah->curchan = &ah->channels[chan->hw_value];
		ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20);
		ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
		chan->max_power = reg->max_power_level / 2;
	}
}
Beispiel #10
0
void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah)
{
	struct ath_common *common = ath9k_hw_common(ah);
	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);

	switch (ar5416_get_ntxchains(ah->txchainmask)) {
	case 1:
		break;
	case 2:
		regulatory->max_power_level += POWER_CORRECTION_FOR_TWO_CHAIN;
		break;
	case 3:
		regulatory->max_power_level += POWER_CORRECTION_FOR_THREE_CHAIN;
		break;
	default:
		ath_dbg(common, EEPROM, "Invalid chainmask configuration\n");
		break;
	}
}
Beispiel #11
0
void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah)
{
	struct ath_common *common = ath9k_hw_common(ah);
	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);

	switch (ar5416_get_ntxchains(ah->txchainmask)) {
	case 1:
		break;
	case 2:
		regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
		break;
	case 3:
		regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
		break;
	default:
		ath_print(common, ATH_DBG_EEPROM,
			  "Invalid chainmask configuration\n");
		break;
	}
}
Beispiel #12
0
static int ar9003_hw_process_ini(struct ath_hw *ah,
				 struct ath9k_channel *chan)
{
	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
	unsigned int regWrites = 0, i;
	struct ieee80211_channel *channel = chan->chan;
	u32 modesIndex, freqIndex;

	switch (chan->chanmode) {
	case CHANNEL_A:
	case CHANNEL_A_HT20:
		modesIndex = 1;
		freqIndex = 1;
		break;
	case CHANNEL_A_HT40PLUS:
	case CHANNEL_A_HT40MINUS:
		modesIndex = 2;
		freqIndex = 1;
		break;
	case CHANNEL_G:
	case CHANNEL_G_HT20:
	case CHANNEL_B:
		modesIndex = 4;
		freqIndex = 2;
		break;
	case CHANNEL_G_HT40PLUS:
	case CHANNEL_G_HT40MINUS:
		modesIndex = 3;
		freqIndex = 2;
		break;

	default:
		return -EINVAL;
	}

	for (i = 0; i < ATH_INI_NUM_SPLIT; i++) {
		ar9003_hw_prog_ini(ah, &ah->iniSOC[i], modesIndex);
		ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex);
		ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex);
		ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex);
	}

	REG_WRITE_ARRAY(&ah->iniModesRxGain, 1, regWrites);
	REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);

	/*
	 * For 5GHz channels requiring Fast Clock, apply
	 * different modal values.
	 */
	if (IS_CHAN_A_FAST_CLOCK(ah, chan))
		REG_WRITE_ARRAY(&ah->iniModesAdditional,
				modesIndex, regWrites);

	ar9003_hw_override_ini(ah);
	ar9003_hw_set_channel_regs(ah, chan);
	ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);

	/* Set TX power */
	ah->eep_ops->set_txpower(ah, chan,
				 ath9k_regd_get_ctl(regulatory, chan),
				 channel->max_antenna_gain * 2,
				 channel->max_power * 2,
				 min((u32) MAX_RATE_POWER,
				 (u32) regulatory->power_limit));

	return 0;
}