diff options
-rw-r--r-- | drivers/net/wireless/ath/ath9k/common.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/rc.c | 71 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/rc.h | 18 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/virtual.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 70 |
6 files changed, 83 insertions, 97 deletions
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index 292e3d860c0e..4e1176029356 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h | |||
@@ -81,6 +81,7 @@ struct ath_buf { | |||
81 | u16 bf_flags; | 81 | u16 bf_flags; |
82 | struct ath_buf_state bf_state; | 82 | struct ath_buf_state bf_state; |
83 | dma_addr_t bf_dmacontext; | 83 | dma_addr_t bf_dmacontext; |
84 | struct ath_wiphy *aphy; | ||
84 | }; | 85 | }; |
85 | 86 | ||
86 | struct ath_atx_tid { | 87 | struct ath_atx_tid { |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 84f44269de47..06f1fcfb03e9 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -257,14 +257,17 @@ static const struct file_operations fops_interrupt = { | |||
257 | 257 | ||
258 | void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb) | 258 | void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb) |
259 | { | 259 | { |
260 | struct ath_tx_info_priv *tx_info_priv = NULL; | ||
261 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 260 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
262 | struct ieee80211_tx_rate *rates = tx_info->status.rates; | 261 | struct ieee80211_tx_rate *rates = tx_info->status.rates; |
263 | int final_ts_idx, idx; | 262 | int final_ts_idx = 0, idx, i; |
264 | struct ath_rc_stats *stats; | 263 | struct ath_rc_stats *stats; |
265 | 264 | ||
266 | tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | 265 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
267 | final_ts_idx = tx_info_priv->tx.ts_rateindex; | 266 | if (!rates[i].count) |
267 | break; | ||
268 | |||
269 | final_ts_idx = i; | ||
270 | } | ||
268 | idx = rates[final_ts_idx].idx; | 271 | idx = rates[final_ts_idx].idx; |
269 | stats = &sc->debug.stats.rcstats[idx]; | 272 | stats = &sc->debug.stats.rcstats[idx]; |
270 | stats->success++; | 273 | stats->success++; |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index bb72b46567f9..ea4b9081b4d0 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -859,12 +859,12 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
859 | static bool ath_rc_update_per(struct ath_softc *sc, | 859 | static bool ath_rc_update_per(struct ath_softc *sc, |
860 | const struct ath_rate_table *rate_table, | 860 | const struct ath_rate_table *rate_table, |
861 | struct ath_rate_priv *ath_rc_priv, | 861 | struct ath_rate_priv *ath_rc_priv, |
862 | struct ath_tx_info_priv *tx_info_priv, | 862 | struct ieee80211_tx_info *tx_info, |
863 | int tx_rate, int xretries, int retries, | 863 | int tx_rate, int xretries, int retries, |
864 | u32 now_msec) | 864 | u32 now_msec) |
865 | { | 865 | { |
866 | bool state_change = false; | 866 | bool state_change = false; |
867 | int count; | 867 | int count, n_bad_frames; |
868 | u8 last_per; | 868 | u8 last_per; |
869 | static u32 nretry_to_per_lookup[10] = { | 869 | static u32 nretry_to_per_lookup[10] = { |
870 | 100 * 0 / 1, | 870 | 100 * 0 / 1, |
@@ -880,6 +880,7 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
880 | }; | 880 | }; |
881 | 881 | ||
882 | last_per = ath_rc_priv->per[tx_rate]; | 882 | last_per = ath_rc_priv->per[tx_rate]; |
883 | n_bad_frames = tx_info->status.ampdu_len - tx_info->status.ampdu_ack_len; | ||
883 | 884 | ||
884 | if (xretries) { | 885 | if (xretries) { |
885 | if (xretries == 1) { | 886 | if (xretries == 1) { |
@@ -907,7 +908,7 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
907 | if (retries >= count) | 908 | if (retries >= count) |
908 | retries = count - 1; | 909 | retries = count - 1; |
909 | 910 | ||
910 | if (tx_info_priv->n_bad_frames) { | 911 | if (n_bad_frames) { |
911 | /* new_PER = 7/8*old_PER + 1/8*(currentPER) | 912 | /* new_PER = 7/8*old_PER + 1/8*(currentPER) |
912 | * Assuming that n_frames is not 0. The current PER | 913 | * Assuming that n_frames is not 0. The current PER |
913 | * from the retries is 100 * retries / (retries+1), | 914 | * from the retries is 100 * retries / (retries+1), |
@@ -920,14 +921,14 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
920 | * the above PER. The expression below is a | 921 | * the above PER. The expression below is a |
921 | * simplified version of the sum of these two terms. | 922 | * simplified version of the sum of these two terms. |
922 | */ | 923 | */ |
923 | if (tx_info_priv->n_frames > 0) { | 924 | if (tx_info->status.ampdu_len > 0) { |
924 | int n_frames, n_bad_frames; | 925 | int n_frames, n_bad_tries; |
925 | u8 cur_per, new_per; | 926 | u8 cur_per, new_per; |
926 | 927 | ||
927 | n_bad_frames = retries * tx_info_priv->n_frames + | 928 | n_bad_tries = retries * tx_info->status.ampdu_len + |
928 | tx_info_priv->n_bad_frames; | 929 | n_bad_frames; |
929 | n_frames = tx_info_priv->n_frames * (retries + 1); | 930 | n_frames = tx_info->status.ampdu_len * (retries + 1); |
930 | cur_per = (100 * n_bad_frames / n_frames) >> 3; | 931 | cur_per = (100 * n_bad_tries / n_frames) >> 3; |
931 | new_per = (u8)(last_per - (last_per >> 3) + cur_per); | 932 | new_per = (u8)(last_per - (last_per >> 3) + cur_per); |
932 | ath_rc_priv->per[tx_rate] = new_per; | 933 | ath_rc_priv->per[tx_rate] = new_per; |
933 | } | 934 | } |
@@ -943,8 +944,7 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
943 | * this was a probe. Otherwise, ignore the probe. | 944 | * this was a probe. Otherwise, ignore the probe. |
944 | */ | 945 | */ |
945 | if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) { | 946 | if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) { |
946 | if (retries > 0 || 2 * tx_info_priv->n_bad_frames > | 947 | if (retries > 0 || 2 * n_bad_frames > tx_info->status.ampdu_len) { |
947 | tx_info_priv->n_frames) { | ||
948 | /* | 948 | /* |
949 | * Since we probed with just a single attempt, | 949 | * Since we probed with just a single attempt, |
950 | * any retries means the probe failed. Also, | 950 | * any retries means the probe failed. Also, |
@@ -1003,7 +1003,7 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
1003 | 1003 | ||
1004 | static void ath_rc_update_ht(struct ath_softc *sc, | 1004 | static void ath_rc_update_ht(struct ath_softc *sc, |
1005 | struct ath_rate_priv *ath_rc_priv, | 1005 | struct ath_rate_priv *ath_rc_priv, |
1006 | struct ath_tx_info_priv *tx_info_priv, | 1006 | struct ieee80211_tx_info *tx_info, |
1007 | int tx_rate, int xretries, int retries) | 1007 | int tx_rate, int xretries, int retries) |
1008 | { | 1008 | { |
1009 | u32 now_msec = jiffies_to_msecs(jiffies); | 1009 | u32 now_msec = jiffies_to_msecs(jiffies); |
@@ -1020,7 +1020,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, | |||
1020 | 1020 | ||
1021 | /* Update PER first */ | 1021 | /* Update PER first */ |
1022 | state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv, | 1022 | state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv, |
1023 | tx_info_priv, tx_rate, xretries, | 1023 | tx_info, tx_rate, xretries, |
1024 | retries, now_msec); | 1024 | retries, now_msec); |
1025 | 1025 | ||
1026 | /* | 1026 | /* |
@@ -1098,7 +1098,6 @@ static void ath_rc_tx_status(struct ath_softc *sc, | |||
1098 | struct ieee80211_tx_info *tx_info, | 1098 | struct ieee80211_tx_info *tx_info, |
1099 | int final_ts_idx, int xretries, int long_retry) | 1099 | int final_ts_idx, int xretries, int long_retry) |
1100 | { | 1100 | { |
1101 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
1102 | const struct ath_rate_table *rate_table; | 1101 | const struct ath_rate_table *rate_table; |
1103 | struct ieee80211_tx_rate *rates = tx_info->status.rates; | 1102 | struct ieee80211_tx_rate *rates = tx_info->status.rates; |
1104 | u8 flags; | 1103 | u8 flags; |
@@ -1124,9 +1123,8 @@ static void ath_rc_tx_status(struct ath_softc *sc, | |||
1124 | return; | 1123 | return; |
1125 | 1124 | ||
1126 | rix = ath_rc_get_rateindex(rate_table, &rates[i]); | 1125 | rix = ath_rc_get_rateindex(rate_table, &rates[i]); |
1127 | ath_rc_update_ht(sc, ath_rc_priv, | 1126 | ath_rc_update_ht(sc, ath_rc_priv, tx_info, |
1128 | tx_info_priv, rix, | 1127 | rix, xretries ? 1 : 2, |
1129 | xretries ? 1 : 2, | ||
1130 | rates[i].count); | 1128 | rates[i].count); |
1131 | } | 1129 | } |
1132 | } | 1130 | } |
@@ -1149,8 +1147,7 @@ static void ath_rc_tx_status(struct ath_softc *sc, | |||
1149 | return; | 1147 | return; |
1150 | 1148 | ||
1151 | rix = ath_rc_get_rateindex(rate_table, &rates[i]); | 1149 | rix = ath_rc_get_rateindex(rate_table, &rates[i]); |
1152 | ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix, | 1150 | ath_rc_update_ht(sc, ath_rc_priv, tx_info, rix, xretries, long_retry); |
1153 | xretries, long_retry); | ||
1154 | } | 1151 | } |
1155 | 1152 | ||
1156 | static const | 1153 | static const |
@@ -1301,23 +1298,30 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1301 | { | 1298 | { |
1302 | struct ath_softc *sc = priv; | 1299 | struct ath_softc *sc = priv; |
1303 | struct ath_rate_priv *ath_rc_priv = priv_sta; | 1300 | struct ath_rate_priv *ath_rc_priv = priv_sta; |
1304 | struct ath_tx_info_priv *tx_info_priv = NULL; | ||
1305 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1301 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1306 | struct ieee80211_hdr *hdr; | 1302 | struct ieee80211_hdr *hdr; |
1307 | int final_ts_idx, tx_status = 0, is_underrun = 0; | 1303 | int final_ts_idx = 0, tx_status = 0, is_underrun = 0; |
1304 | int long_retry = 0; | ||
1308 | __le16 fc; | 1305 | __le16 fc; |
1306 | int i; | ||
1309 | 1307 | ||
1310 | hdr = (struct ieee80211_hdr *)skb->data; | 1308 | hdr = (struct ieee80211_hdr *)skb->data; |
1311 | fc = hdr->frame_control; | 1309 | fc = hdr->frame_control; |
1312 | tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | 1310 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
1313 | final_ts_idx = tx_info_priv->tx.ts_rateindex; | 1311 | struct ieee80211_tx_rate *rate = &tx_info->status.rates[i]; |
1312 | if (!rate->count) | ||
1313 | break; | ||
1314 | |||
1315 | final_ts_idx = i; | ||
1316 | long_retry = rate->count - 1; | ||
1317 | } | ||
1314 | 1318 | ||
1315 | if (!priv_sta || !ieee80211_is_data(fc) || | 1319 | if (!priv_sta || !ieee80211_is_data(fc) || |
1316 | !tx_info_priv->update_rc) | 1320 | !(tx_info->pad[0] & ATH_TX_INFO_UPDATE_RC)) |
1317 | goto exit; | 1321 | return; |
1318 | 1322 | ||
1319 | if (tx_info_priv->tx.ts_status & ATH9K_TXERR_FILT) | 1323 | if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) |
1320 | goto exit; | 1324 | return; |
1321 | 1325 | ||
1322 | /* | 1326 | /* |
1323 | * If underrun error is seen assume it as an excessive retry only | 1327 | * If underrun error is seen assume it as an excessive retry only |
@@ -1325,20 +1329,17 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1325 | * Adjust the long retry as if the frame was tried hw->max_rate_tries | 1329 | * Adjust the long retry as if the frame was tried hw->max_rate_tries |
1326 | * times. This affects how ratectrl updates PER for the failed rate. | 1330 | * times. This affects how ratectrl updates PER for the failed rate. |
1327 | */ | 1331 | */ |
1328 | if (tx_info_priv->tx.ts_flags & | 1332 | if ((tx_info->pad[0] & ATH_TX_INFO_UNDERRUN) && |
1329 | (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) && | 1333 | (sc->sc_ah->tx_trig_level >= ath_rc_priv->tx_triglevel_max)) { |
1330 | ((sc->sc_ah->tx_trig_level) >= ath_rc_priv->tx_triglevel_max)) { | ||
1331 | tx_status = 1; | 1334 | tx_status = 1; |
1332 | is_underrun = 1; | 1335 | is_underrun = 1; |
1333 | } | 1336 | } |
1334 | 1337 | ||
1335 | if ((tx_info_priv->tx.ts_status & ATH9K_TXERR_XRETRY) || | 1338 | if (tx_info->pad[0] & ATH_TX_INFO_XRETRY) |
1336 | (tx_info_priv->tx.ts_status & ATH9K_TXERR_FIFO)) | ||
1337 | tx_status = 1; | 1339 | tx_status = 1; |
1338 | 1340 | ||
1339 | ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status, | 1341 | ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status, |
1340 | (is_underrun) ? sc->hw->max_rate_tries : | 1342 | (is_underrun) ? sc->hw->max_rate_tries : long_retry); |
1341 | tx_info_priv->tx.ts_longretry); | ||
1342 | 1343 | ||
1343 | /* Check if aggregation has to be enabled for this tid */ | 1344 | /* Check if aggregation has to be enabled for this tid */ |
1344 | if (conf_is_ht(&sc->hw->conf) && | 1345 | if (conf_is_ht(&sc->hw->conf) && |
@@ -1357,8 +1358,6 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1357 | } | 1358 | } |
1358 | 1359 | ||
1359 | ath_debug_stat_rc(sc, skb); | 1360 | ath_debug_stat_rc(sc, skb); |
1360 | exit: | ||
1361 | kfree(tx_info_priv); | ||
1362 | } | 1361 | } |
1363 | 1362 | ||
1364 | static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, | 1363 | static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, |
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index 94cb9f8d2446..51f85ecbe88d 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h | |||
@@ -167,24 +167,18 @@ struct ath_rate_priv { | |||
167 | struct ath_rate_softc *asc; | 167 | struct ath_rate_softc *asc; |
168 | }; | 168 | }; |
169 | 169 | ||
170 | #define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0) | ||
171 | #define ATH_TX_INFO_FRAME_TYPE_PAUSE (1 << 1) | ||
172 | #define ATH_TX_INFO_UPDATE_RC (1 << 2) | ||
173 | #define ATH_TX_INFO_XRETRY (1 << 3) | ||
174 | #define ATH_TX_INFO_UNDERRUN (1 << 4) | ||
175 | |||
170 | enum ath9k_internal_frame_type { | 176 | enum ath9k_internal_frame_type { |
171 | ATH9K_NOT_INTERNAL, | 177 | ATH9K_NOT_INTERNAL, |
172 | ATH9K_INT_PAUSE, | 178 | ATH9K_INT_PAUSE, |
173 | ATH9K_INT_UNPAUSE | 179 | ATH9K_INT_UNPAUSE |
174 | }; | 180 | }; |
175 | 181 | ||
176 | struct ath_tx_info_priv { | ||
177 | struct ath_wiphy *aphy; | ||
178 | struct ath_tx_status tx; | ||
179 | int n_frames; | ||
180 | int n_bad_frames; | ||
181 | bool update_rc; | ||
182 | enum ath9k_internal_frame_type frame_type; | ||
183 | }; | ||
184 | |||
185 | #define ATH_TX_INFO_PRIV(tx_info) \ | ||
186 | ((struct ath_tx_info_priv *)((tx_info)->rate_driver_data[0])) | ||
187 | |||
188 | void ath_rate_attach(struct ath_softc *sc); | 182 | void ath_rate_attach(struct ath_softc *sc); |
189 | u8 ath_rate_findrateix(struct ath_softc *sc, u8 dot11_rate); | 183 | u8 ath_rate_findrateix(struct ath_softc *sc, u8 dot11_rate); |
190 | int ath_rate_control_register(void); | 184 | int ath_rate_control_register(void); |
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index 0a36b572294c..cd26caaf44e7 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c | |||
@@ -338,13 +338,11 @@ void ath9k_wiphy_chan_work(struct work_struct *work) | |||
338 | void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | 338 | void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) |
339 | { | 339 | { |
340 | struct ath_wiphy *aphy = hw->priv; | 340 | struct ath_wiphy *aphy = hw->priv; |
341 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
342 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 341 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
343 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
344 | 342 | ||
345 | if (tx_info_priv && tx_info_priv->frame_type == ATH9K_INT_PAUSE && | 343 | if ((tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_PAUSE) && |
346 | aphy->state == ATH_WIPHY_PAUSING) { | 344 | aphy->state == ATH_WIPHY_PAUSING) { |
347 | if (!(info->flags & IEEE80211_TX_STAT_ACK)) { | 345 | if (!(tx_info->flags & IEEE80211_TX_STAT_ACK)) { |
348 | printk(KERN_DEBUG "ath9k: %s: no ACK for pause " | 346 | printk(KERN_DEBUG "ath9k: %s: no ACK for pause " |
349 | "frame\n", wiphy_name(hw->wiphy)); | 347 | "frame\n", wiphy_name(hw->wiphy)); |
350 | /* | 348 | /* |
@@ -363,9 +361,6 @@ void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
363 | } | 361 | } |
364 | } | 362 | } |
365 | 363 | ||
366 | kfree(tx_info_priv); | ||
367 | tx_info->rate_driver_data[0] = NULL; | ||
368 | |||
369 | dev_kfree_skb(skb); | 364 | dev_kfree_skb(skb); |
370 | } | 365 | } |
371 | 366 | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 86b54ddd01cb..2db0fa878c26 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -251,6 +251,7 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) | |||
251 | 251 | ||
252 | ATH_TXBUF_RESET(tbf); | 252 | ATH_TXBUF_RESET(tbf); |
253 | 253 | ||
254 | tbf->aphy = bf->aphy; | ||
254 | tbf->bf_mpdu = bf->bf_mpdu; | 255 | tbf->bf_mpdu = bf->bf_mpdu; |
255 | tbf->bf_buf_addr = bf->bf_buf_addr; | 256 | tbf->bf_buf_addr = bf->bf_buf_addr; |
256 | *(tbf->bf_desc) = *(bf->bf_desc); | 257 | *(tbf->bf_desc) = *(bf->bf_desc); |
@@ -270,7 +271,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
270 | struct ieee80211_hw *hw; | 271 | struct ieee80211_hw *hw; |
271 | struct ieee80211_hdr *hdr; | 272 | struct ieee80211_hdr *hdr; |
272 | struct ieee80211_tx_info *tx_info; | 273 | struct ieee80211_tx_info *tx_info; |
273 | struct ath_tx_info_priv *tx_info_priv; | ||
274 | struct ath_atx_tid *tid = NULL; | 274 | struct ath_atx_tid *tid = NULL; |
275 | struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; | 275 | struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; |
276 | struct ath_desc *ds = bf_last->bf_desc; | 276 | struct ath_desc *ds = bf_last->bf_desc; |
@@ -284,8 +284,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
284 | hdr = (struct ieee80211_hdr *)skb->data; | 284 | hdr = (struct ieee80211_hdr *)skb->data; |
285 | 285 | ||
286 | tx_info = IEEE80211_SKB_CB(skb); | 286 | tx_info = IEEE80211_SKB_CB(skb); |
287 | tx_info_priv = (struct ath_tx_info_priv *) tx_info->rate_driver_data[0]; | 287 | hw = bf->aphy->hw; |
288 | hw = tx_info_priv->aphy->hw; | ||
289 | 288 | ||
290 | rcu_read_lock(); | 289 | rcu_read_lock(); |
291 | 290 | ||
@@ -464,7 +463,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
464 | struct sk_buff *skb; | 463 | struct sk_buff *skb; |
465 | struct ieee80211_tx_info *tx_info; | 464 | struct ieee80211_tx_info *tx_info; |
466 | struct ieee80211_tx_rate *rates; | 465 | struct ieee80211_tx_rate *rates; |
467 | struct ath_tx_info_priv *tx_info_priv; | ||
468 | u32 max_4ms_framelen, frmlen; | 466 | u32 max_4ms_framelen, frmlen; |
469 | u16 aggr_limit, legacy = 0; | 467 | u16 aggr_limit, legacy = 0; |
470 | int i; | 468 | int i; |
@@ -472,7 +470,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
472 | skb = bf->bf_mpdu; | 470 | skb = bf->bf_mpdu; |
473 | tx_info = IEEE80211_SKB_CB(skb); | 471 | tx_info = IEEE80211_SKB_CB(skb); |
474 | rates = tx_info->control.rates; | 472 | rates = tx_info->control.rates; |
475 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->rate_driver_data[0]; | ||
476 | 473 | ||
477 | /* | 474 | /* |
478 | * Find the lowest frame length among the rate series that will have a | 475 | * Find the lowest frame length among the rate series that will have a |
@@ -1560,21 +1557,26 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
1560 | struct ath_softc *sc = aphy->sc; | 1557 | struct ath_softc *sc = aphy->sc; |
1561 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1558 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1562 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1559 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1563 | struct ath_tx_info_priv *tx_info_priv; | ||
1564 | int hdrlen; | 1560 | int hdrlen; |
1565 | __le16 fc; | 1561 | __le16 fc; |
1566 | 1562 | ||
1567 | tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC); | 1563 | tx_info->pad[0] = 0; |
1568 | if (unlikely(!tx_info_priv)) | 1564 | switch (txctl->frame_type) { |
1569 | return -ENOMEM; | 1565 | case ATH9K_NOT_INTERNAL: |
1570 | tx_info->rate_driver_data[0] = tx_info_priv; | 1566 | break; |
1571 | tx_info_priv->aphy = aphy; | 1567 | case ATH9K_INT_PAUSE: |
1572 | tx_info_priv->frame_type = txctl->frame_type; | 1568 | tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_PAUSE; |
1569 | /* fall through */ | ||
1570 | case ATH9K_INT_UNPAUSE: | ||
1571 | tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_INTERNAL; | ||
1572 | break; | ||
1573 | } | ||
1573 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1574 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
1574 | fc = hdr->frame_control; | 1575 | fc = hdr->frame_control; |
1575 | 1576 | ||
1576 | ATH_TXBUF_RESET(bf); | 1577 | ATH_TXBUF_RESET(bf); |
1577 | 1578 | ||
1579 | bf->aphy = aphy; | ||
1578 | bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3); | 1580 | bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3); |
1579 | 1581 | ||
1580 | if (conf_is_ht(&hw->conf) && !is_pae(skb)) | 1582 | if (conf_is_ht(&hw->conf) && !is_pae(skb)) |
@@ -1599,8 +1601,6 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
1599 | skb->len, DMA_TO_DEVICE); | 1601 | skb->len, DMA_TO_DEVICE); |
1600 | if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) { | 1602 | if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) { |
1601 | bf->bf_mpdu = NULL; | 1603 | bf->bf_mpdu = NULL; |
1602 | kfree(tx_info_priv); | ||
1603 | tx_info->rate_driver_data[0] = NULL; | ||
1604 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | 1604 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, |
1605 | "dma_mapping_error() on TX\n"); | 1605 | "dma_mapping_error() on TX\n"); |
1606 | return -ENOMEM; | 1606 | return -ENOMEM; |
@@ -1781,27 +1781,17 @@ exit: | |||
1781 | /*****************/ | 1781 | /*****************/ |
1782 | 1782 | ||
1783 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | 1783 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, |
1784 | int tx_flags) | 1784 | struct ath_wiphy *aphy, int tx_flags) |
1785 | { | 1785 | { |
1786 | struct ieee80211_hw *hw = sc->hw; | 1786 | struct ieee80211_hw *hw = sc->hw; |
1787 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1787 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1788 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
1789 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1788 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1790 | int hdrlen, padsize; | 1789 | int hdrlen, padsize; |
1791 | int frame_type = ATH9K_NOT_INTERNAL; | ||
1792 | 1790 | ||
1793 | ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); | 1791 | ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); |
1794 | 1792 | ||
1795 | if (tx_info_priv) { | 1793 | if (aphy) |
1796 | hw = tx_info_priv->aphy->hw; | 1794 | hw = aphy->hw; |
1797 | frame_type = tx_info_priv->frame_type; | ||
1798 | } | ||
1799 | |||
1800 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK || | ||
1801 | tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) { | ||
1802 | kfree(tx_info_priv); | ||
1803 | tx_info->rate_driver_data[0] = NULL; | ||
1804 | } | ||
1805 | 1795 | ||
1806 | if (tx_flags & ATH_TX_BAR) | 1796 | if (tx_flags & ATH_TX_BAR) |
1807 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; | 1797 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; |
@@ -1833,10 +1823,10 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1833 | SC_OP_WAIT_FOR_TX_ACK)); | 1823 | SC_OP_WAIT_FOR_TX_ACK)); |
1834 | } | 1824 | } |
1835 | 1825 | ||
1836 | if (frame_type == ATH9K_NOT_INTERNAL) | 1826 | if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) |
1837 | ieee80211_tx_status(hw, skb); | ||
1838 | else | ||
1839 | ath9k_tx_status(hw, skb); | 1827 | ath9k_tx_status(hw, skb); |
1828 | else | ||
1829 | ieee80211_tx_status(hw, skb); | ||
1840 | } | 1830 | } |
1841 | 1831 | ||
1842 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 1832 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, |
@@ -1859,7 +1849,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | |||
1859 | } | 1849 | } |
1860 | 1850 | ||
1861 | dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); | 1851 | dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); |
1862 | ath_tx_complete(sc, skb, tx_flags); | 1852 | ath_tx_complete(sc, skb, bf->aphy, tx_flags); |
1863 | ath_debug_stat_tx(sc, txq, bf); | 1853 | ath_debug_stat_tx(sc, txq, bf); |
1864 | 1854 | ||
1865 | /* | 1855 | /* |
@@ -1907,8 +1897,7 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, | |||
1907 | struct sk_buff *skb = bf->bf_mpdu; | 1897 | struct sk_buff *skb = bf->bf_mpdu; |
1908 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1898 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1909 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1899 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1910 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | 1900 | struct ieee80211_hw *hw = bf->aphy->hw; |
1911 | struct ieee80211_hw *hw = tx_info_priv->aphy->hw; | ||
1912 | u8 i, tx_rateindex; | 1901 | u8 i, tx_rateindex; |
1913 | 1902 | ||
1914 | if (txok) | 1903 | if (txok) |
@@ -1917,17 +1906,22 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, | |||
1917 | tx_rateindex = ds->ds_txstat.ts_rateindex; | 1906 | tx_rateindex = ds->ds_txstat.ts_rateindex; |
1918 | WARN_ON(tx_rateindex >= hw->max_rates); | 1907 | WARN_ON(tx_rateindex >= hw->max_rates); |
1919 | 1908 | ||
1920 | tx_info_priv->update_rc = update_rc; | 1909 | if (update_rc) |
1910 | tx_info->pad[0] |= ATH_TX_INFO_UPDATE_RC; | ||
1921 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) | 1911 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) |
1922 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | 1912 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; |
1923 | 1913 | ||
1924 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && | 1914 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && |
1925 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { | 1915 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { |
1926 | if (ieee80211_is_data(hdr->frame_control)) { | 1916 | if (ieee80211_is_data(hdr->frame_control)) { |
1927 | memcpy(&tx_info_priv->tx, &ds->ds_txstat, | 1917 | if (ds->ds_txstat.ts_flags & |
1928 | sizeof(tx_info_priv->tx)); | 1918 | (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN)) |
1929 | tx_info_priv->n_frames = bf->bf_nframes; | 1919 | tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN; |
1930 | tx_info_priv->n_bad_frames = nbad; | 1920 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) || |
1921 | (ds->ds_txstat.ts_status & ATH9K_TXERR_FIFO)) | ||
1922 | tx_info->pad[0] |= ATH_TX_INFO_XRETRY; | ||
1923 | tx_info->status.ampdu_len = bf->bf_nframes; | ||
1924 | tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; | ||
1931 | } | 1925 | } |
1932 | } | 1926 | } |
1933 | 1927 | ||