|
|
@@ -0,0 +1,118 @@
|
|
|
+From: Felix Fietkau <[email protected]>
|
|
|
+Date: Wed, 22 Oct 2014 18:18:04 +0200
|
|
|
+Subject: [PATCH] ath9k: add support for reporting tx power to mac80211
|
|
|
+
|
|
|
+Track it per channel context instead of in the softc
|
|
|
+
|
|
|
+Signed-off-by: Felix Fietkau <[email protected]>
|
|
|
+---
|
|
|
+
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
|
|
+@@ -347,6 +347,7 @@ struct ath_chanctx {
|
|
|
+
|
|
|
+ int flush_timeout;
|
|
|
+ u16 txpower;
|
|
|
++ u16 cur_txpower;
|
|
|
+ bool offchannel;
|
|
|
+ bool stopped;
|
|
|
+ bool active;
|
|
|
+@@ -987,7 +988,6 @@ struct ath_softc {
|
|
|
+ u8 gtt_cnt;
|
|
|
+ u32 intrstatus;
|
|
|
+ u16 ps_flags; /* PS_* */
|
|
|
+- u16 curtxpow;
|
|
|
+ bool ps_enabled;
|
|
|
+ bool ps_idle;
|
|
|
+ short nbcnvifs;
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/init.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/init.c
|
|
|
+@@ -172,17 +172,20 @@ static void ath9k_reg_notifier(struct wi
|
|
|
+ ath_reg_notifier_apply(wiphy, request, reg);
|
|
|
+
|
|
|
+ /* Set tx power */
|
|
|
+- if (ah->curchan) {
|
|
|
+- sc->cur_chan->txpower = 2 * ah->curchan->chan->max_power;
|
|
|
+- ath9k_ps_wakeup(sc);
|
|
|
+- ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false);
|
|
|
+- sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
|
|
|
+- /* synchronize DFS detector if regulatory domain changed */
|
|
|
+- if (sc->dfs_detector != NULL)
|
|
|
+- sc->dfs_detector->set_dfs_domain(sc->dfs_detector,
|
|
|
+- request->dfs_region);
|
|
|
+- ath9k_ps_restore(sc);
|
|
|
+- }
|
|
|
++ 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);
|
|
|
++ /* synchronize DFS detector if regulatory domain changed */
|
|
|
++ if (sc->dfs_detector != NULL)
|
|
|
++ sc->dfs_detector->set_dfs_domain(sc->dfs_detector,
|
|
|
++ request->dfs_region);
|
|
|
++ ath9k_ps_restore(sc);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/main.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/main.c
|
|
|
+@@ -233,8 +233,9 @@ static bool ath_complete_reset(struct at
|
|
|
+
|
|
|
+ ath9k_calculate_summary_state(sc, sc->cur_chan);
|
|
|
+ ath_startrecv(sc);
|
|
|
+- ath9k_cmn_update_txpow(ah, sc->curtxpow,
|
|
|
+- sc->cur_chan->txpower, &sc->curtxpow);
|
|
|
++ ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower,
|
|
|
++ sc->cur_chan->txpower,
|
|
|
++ &sc->cur_chan->cur_txpower);
|
|
|
+ clear_bit(ATH_OP_HW_RESET, &common->op_flags);
|
|
|
+
|
|
|
+ if (!sc->cur_chan->offchannel && start) {
|
|
|
+@@ -1471,8 +1472,9 @@ static int ath9k_config(struct ieee80211
|
|
|
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
|
|
|
+ ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level);
|
|
|
+ sc->cur_chan->txpower = 2 * conf->power_level;
|
|
|
+- ath9k_cmn_update_txpow(ah, sc->curtxpow,
|
|
|
+- sc->cur_chan->txpower, &sc->curtxpow);
|
|
|
++ ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower,
|
|
|
++ sc->cur_chan->txpower,
|
|
|
++ &sc->cur_chan->cur_txpower);
|
|
|
+ }
|
|
|
+
|
|
|
+ mutex_unlock(&sc->mutex);
|
|
|
+@@ -2594,6 +2596,24 @@ void ath9k_fill_chanctx_ops(void)
|
|
|
+
|
|
|
+ #endif
|
|
|
+
|
|
|
++static int ath9k_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
|
++ int *dbm)
|
|
|
++{
|
|
|
++ struct ath_softc *sc = hw->priv;
|
|
|
++ struct ath_vif *avp = (void *)vif->drv_priv;
|
|
|
++
|
|
|
++ mutex_lock(&sc->mutex);
|
|
|
++ if (avp->chanctx)
|
|
|
++ *dbm = avp->chanctx->cur_txpower;
|
|
|
++ else
|
|
|
++ *dbm = sc->cur_chan->cur_txpower;
|
|
|
++ mutex_unlock(&sc->mutex);
|
|
|
++
|
|
|
++ *dbm /= 2;
|
|
|
++
|
|
|
++ return 0;
|
|
|
++}
|
|
|
++
|
|
|
+ struct ieee80211_ops ath9k_ops = {
|
|
|
+ .tx = ath9k_tx,
|
|
|
+ .start = ath9k_start,
|
|
|
+@@ -2640,4 +2660,5 @@ struct ieee80211_ops ath9k_ops = {
|
|
|
+ #endif
|
|
|
+ .sw_scan_start = ath9k_sw_scan_start,
|
|
|
+ .sw_scan_complete = ath9k_sw_scan_complete,
|
|
|
++ .get_txpower = ath9k_get_txpower,
|
|
|
+ };
|