mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-31 05:54:26 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			119 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From: Felix Fietkau <nbd@openwrt.org>
 | |
| 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 <nbd@openwrt.org>
 | |
| ---
 | |
| 
 | |
| --- 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,
 | |
|  };
 |