diff options
author | Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> | 2015-04-08 14:51:57 -0400 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2015-05-03 16:54:38 -0400 |
commit | f673821864899153142365aca888435815ac93f0 (patch) | |
tree | 57b82b9ca75f7b6a2a9d541d038acd6dc099aa36 /drivers/net/wireless/ath/ath9k | |
parent | 0581276deb9c2578a17d9f4463e7b5172da99eb9 (diff) |
ath9k: fix per-packet tx power configuration
Do not use ieee80211_vif pointer in ath_get_rate_txpower() since it has been
overwritten by setup_frame_info() and it will result in a corrupted tx power
configuration. Set per-packet tx power in setup_frame_info() according to
current vif tx power.
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 52 |
1 files changed, 25 insertions, 27 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 0acd079ba96b..3ad79bb4f2c2 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1103,28 +1103,14 @@ static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf, | |||
1103 | struct sk_buff *skb; | 1103 | struct sk_buff *skb; |
1104 | struct ath_frame_info *fi; | 1104 | struct ath_frame_info *fi; |
1105 | struct ieee80211_tx_info *info; | 1105 | struct ieee80211_tx_info *info; |
1106 | struct ieee80211_vif *vif; | ||
1107 | struct ath_hw *ah = sc->sc_ah; | 1106 | struct ath_hw *ah = sc->sc_ah; |
1108 | 1107 | ||
1109 | if (sc->tx99_state || !ah->tpc_enabled) | 1108 | if (sc->tx99_state || !ah->tpc_enabled) |
1110 | return MAX_RATE_POWER; | 1109 | return MAX_RATE_POWER; |
1111 | 1110 | ||
1112 | skb = bf->bf_mpdu; | 1111 | skb = bf->bf_mpdu; |
1113 | info = IEEE80211_SKB_CB(skb); | ||
1114 | vif = info->control.vif; | ||
1115 | |||
1116 | if (!vif) { | ||
1117 | max_power = sc->cur_chan->cur_txpower; | ||
1118 | goto out; | ||
1119 | } | ||
1120 | |||
1121 | if (vif->bss_conf.txpower_type != NL80211_TX_POWER_LIMITED) { | ||
1122 | max_power = min_t(u8, sc->cur_chan->cur_txpower, | ||
1123 | 2 * vif->bss_conf.txpower); | ||
1124 | goto out; | ||
1125 | } | ||
1126 | |||
1127 | fi = get_frame_info(skb); | 1112 | fi = get_frame_info(skb); |
1113 | info = IEEE80211_SKB_CB(skb); | ||
1128 | 1114 | ||
1129 | if (!AR_SREV_9300_20_OR_LATER(ah)) { | 1115 | if (!AR_SREV_9300_20_OR_LATER(ah)) { |
1130 | int txpower = fi->tx_power; | 1116 | int txpower = fi->tx_power; |
@@ -1161,25 +1147,26 @@ static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf, | |||
1161 | txpower -= 2; | 1147 | txpower -= 2; |
1162 | 1148 | ||
1163 | txpower = max(txpower, 0); | 1149 | txpower = max(txpower, 0); |
1164 | max_power = min_t(u8, ah->tx_power[rateidx], | 1150 | max_power = min_t(u8, ah->tx_power[rateidx], txpower); |
1165 | 2 * vif->bss_conf.txpower); | 1151 | |
1166 | max_power = min_t(u8, max_power, txpower); | 1152 | /* XXX: clamp minimum TX power at 1 for AR9160 since if |
1153 | * max_power is set to 0, frames are transmitted at max | ||
1154 | * TX power | ||
1155 | */ | ||
1156 | if (!max_power && !AR_SREV_9280_20_OR_LATER(ah)) | ||
1157 | max_power = 1; | ||
1167 | } else if (!bf->bf_state.bfs_paprd) { | 1158 | } else if (!bf->bf_state.bfs_paprd) { |
1168 | if (rateidx < 8 && (info->flags & IEEE80211_TX_CTL_STBC)) | 1159 | if (rateidx < 8 && (info->flags & IEEE80211_TX_CTL_STBC)) |
1169 | max_power = min_t(u8, ah->tx_power_stbc[rateidx], | 1160 | max_power = min_t(u8, ah->tx_power_stbc[rateidx], |
1170 | 2 * vif->bss_conf.txpower); | 1161 | fi->tx_power); |
1171 | else | 1162 | else |
1172 | max_power = min_t(u8, ah->tx_power[rateidx], | 1163 | max_power = min_t(u8, ah->tx_power[rateidx], |
1173 | 2 * vif->bss_conf.txpower); | 1164 | fi->tx_power); |
1174 | max_power = min(max_power, fi->tx_power); | ||
1175 | } else { | 1165 | } else { |
1176 | max_power = ah->paprd_training_power; | 1166 | max_power = ah->paprd_training_power; |
1177 | } | 1167 | } |
1178 | out: | 1168 | |
1179 | /* XXX: clamp minimum TX power at 1 for AR9160 since if max_power | 1169 | return max_power; |
1180 | * is set to 0, frames are transmitted at max TX power | ||
1181 | */ | ||
1182 | return (!max_power && !AR_SREV_9280_20_OR_LATER(ah)) ? 1 : max_power; | ||
1183 | } | 1170 | } |
1184 | 1171 | ||
1185 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, | 1172 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, |
@@ -2129,6 +2116,7 @@ static void setup_frame_info(struct ieee80211_hw *hw, | |||
2129 | struct ath_node *an = NULL; | 2116 | struct ath_node *an = NULL; |
2130 | enum ath9k_key_type keytype; | 2117 | enum ath9k_key_type keytype; |
2131 | bool short_preamble = false; | 2118 | bool short_preamble = false; |
2119 | u8 txpower; | ||
2132 | 2120 | ||
2133 | /* | 2121 | /* |
2134 | * We check if Short Preamble is needed for the CTS rate by | 2122 | * We check if Short Preamble is needed for the CTS rate by |
@@ -2145,6 +2133,16 @@ static void setup_frame_info(struct ieee80211_hw *hw, | |||
2145 | if (sta) | 2133 | if (sta) |
2146 | an = (struct ath_node *) sta->drv_priv; | 2134 | an = (struct ath_node *) sta->drv_priv; |
2147 | 2135 | ||
2136 | if (tx_info->control.vif) { | ||
2137 | struct ieee80211_vif *vif = tx_info->control.vif; | ||
2138 | |||
2139 | txpower = 2 * vif->bss_conf.txpower; | ||
2140 | } else { | ||
2141 | struct ath_softc *sc = hw->priv; | ||
2142 | |||
2143 | txpower = sc->cur_chan->cur_txpower; | ||
2144 | } | ||
2145 | |||
2148 | memset(fi, 0, sizeof(*fi)); | 2146 | memset(fi, 0, sizeof(*fi)); |
2149 | fi->txq = -1; | 2147 | fi->txq = -1; |
2150 | if (hw_key) | 2148 | if (hw_key) |
@@ -2155,7 +2153,7 @@ static void setup_frame_info(struct ieee80211_hw *hw, | |||
2155 | fi->keyix = ATH9K_TXKEYIX_INVALID; | 2153 | fi->keyix = ATH9K_TXKEYIX_INVALID; |
2156 | fi->keytype = keytype; | 2154 | fi->keytype = keytype; |
2157 | fi->framelen = framelen; | 2155 | fi->framelen = framelen; |
2158 | fi->tx_power = MAX_RATE_POWER; | 2156 | fi->tx_power = txpower; |
2159 | 2157 | ||
2160 | if (!rate) | 2158 | if (!rate) |
2161 | return; | 2159 | return; |