aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenzo Bianconi <lorenzo.bianconi83@gmail.com>2014-12-30 17:10:19 -0500
committerKalle Valo <kvalo@codeaurora.org>2015-01-15 07:47:16 -0500
commit9ddad58bee51663001ff118d65cc9166bafcd122 (patch)
treec375ab0c939e24a4c5d627126d299429bac8ca5b
parentc08267dc9a3641c78846bfac92abfc54984c6694 (diff)
ath9k: add TPC to TX path for AR9002 based chips
Add TPC capability to TX descriptor path for AR9002 based chips. Scale per-packet TX power according to eeprom power bias, power adjustments for HT40 mode and open loop CCK rates. Cap per-packet TX power according to TX power per-rate tables Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c68
1 files changed, 56 insertions, 12 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 52d63de4a93d..9c332f9c3fc5 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1097,24 +1097,65 @@ void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop)
1097} 1097}
1098 1098
1099static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf, 1099static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf,
1100 u8 rateidx) 1100 u8 rateidx, bool is_40, bool is_cck)
1101{ 1101{
1102 u8 max_power; 1102 u8 max_power;
1103 struct sk_buff *skb;
1104 struct ath_frame_info *fi;
1105 struct ieee80211_tx_info *info;
1103 struct ath_hw *ah = sc->sc_ah; 1106 struct ath_hw *ah = sc->sc_ah;
1104 1107
1105 if (sc->tx99_state) 1108 if (sc->tx99_state || !ah->tpc_enabled)
1106 return MAX_RATE_POWER; 1109 return MAX_RATE_POWER;
1107 1110
1111 skb = bf->bf_mpdu;
1112 fi = get_frame_info(skb);
1113 info = IEEE80211_SKB_CB(skb);
1114
1108 if (!AR_SREV_9300_20_OR_LATER(ah)) { 1115 if (!AR_SREV_9300_20_OR_LATER(ah)) {
1109 /* ar9002 does not support TPC for the moment */ 1116 int txpower = fi->tx_power;
1110 return MAX_RATE_POWER;
1111 }
1112 1117
1113 if (!bf->bf_state.bfs_paprd) { 1118 if (is_40) {
1114 struct sk_buff *skb = bf->bf_mpdu; 1119 u8 power_ht40delta;
1115 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1120 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
1116 struct ath_frame_info *fi = get_frame_info(skb);
1117 1121
1122 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) {
1123 bool is_2ghz;
1124 struct modal_eep_header *pmodal;
1125
1126 is_2ghz = info->band == IEEE80211_BAND_2GHZ;
1127 pmodal = &eep->modalHeader[is_2ghz];
1128 power_ht40delta = pmodal->ht40PowerIncForPdadc;
1129 } else {
1130 power_ht40delta = 2;
1131 }
1132 txpower += power_ht40delta;
1133 }
1134
1135 if (AR_SREV_9287(ah) || AR_SREV_9285(ah) ||
1136 AR_SREV_9271(ah)) {
1137 txpower -= 2 * AR9287_PWR_TABLE_OFFSET_DB;
1138 } else if (AR_SREV_9280_20_OR_LATER(ah)) {
1139 s8 power_offset;
1140
1141 power_offset = ah->eep_ops->get_eeprom(ah,
1142 EEP_PWR_TABLE_OFFSET);
1143 txpower -= 2 * power_offset;
1144 }
1145
1146 if (OLC_FOR_AR9280_20_LATER && is_cck)
1147 txpower -= 2;
1148
1149 txpower = max(txpower, 0);
1150 max_power = min_t(u8, ah->tx_power[rateidx], txpower);
1151
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;
1158 } else if (!bf->bf_state.bfs_paprd) {
1118 if (rateidx < 8 && (info->flags & IEEE80211_TX_CTL_STBC)) 1159 if (rateidx < 8 && (info->flags & IEEE80211_TX_CTL_STBC))
1119 max_power = min(ah->tx_power_stbc[rateidx], 1160 max_power = min(ah->tx_power_stbc[rateidx],
1120 fi->tx_power); 1161 fi->tx_power);
@@ -1152,7 +1193,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
1152 info->rtscts_rate = fi->rtscts_rate; 1193 info->rtscts_rate = fi->rtscts_rate;
1153 1194
1154 for (i = 0; i < ARRAY_SIZE(bf->rates); i++) { 1195 for (i = 0; i < ARRAY_SIZE(bf->rates); i++) {
1155 bool is_40, is_sgi, is_sp; 1196 bool is_40, is_sgi, is_sp, is_cck;
1156 int phy; 1197 int phy;
1157 1198
1158 if (!rates[i].count || (rates[i].idx < 0)) 1199 if (!rates[i].count || (rates[i].idx < 0))
@@ -1198,7 +1239,8 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
1198 if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) 1239 if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC))
1199 info->rates[i].RateFlags |= ATH9K_RATESERIES_STBC; 1240 info->rates[i].RateFlags |= ATH9K_RATESERIES_STBC;
1200 1241
1201 info->txpower[i] = ath_get_rate_txpower(sc, bf, rix); 1242 info->txpower[i] = ath_get_rate_txpower(sc, bf, rix,
1243 is_40, false);
1202 continue; 1244 continue;
1203 } 1245 }
1204 1246
@@ -1227,7 +1269,9 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
1227 info->rates[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah, 1269 info->rates[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah,
1228 phy, rate->bitrate * 100, len, rix, is_sp); 1270 phy, rate->bitrate * 100, len, rix, is_sp);
1229 1271
1230 info->txpower[i] = ath_get_rate_txpower(sc, bf, rix); 1272 is_cck = IS_CCK_RATE(info->rates[i].Rate);
1273 info->txpower[i] = ath_get_rate_txpower(sc, bf, rix, false,
1274 is_cck);
1231 } 1275 }
1232 1276
1233 /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ 1277 /* For AR5416 - RTS cannot be followed by a frame larger than 8K */