diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/xmit.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 20221b8c04fd..c3681a1dc941 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -328,6 +328,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
328 | u32 ba[WME_BA_BMP_SIZE >> 5]; | 328 | u32 ba[WME_BA_BMP_SIZE >> 5]; |
329 | int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; | 329 | int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; |
330 | bool rc_update = true; | 330 | bool rc_update = true; |
331 | struct ieee80211_tx_rate rates[4]; | ||
331 | 332 | ||
332 | skb = bf->bf_mpdu; | 333 | skb = bf->bf_mpdu; |
333 | hdr = (struct ieee80211_hdr *)skb->data; | 334 | hdr = (struct ieee80211_hdr *)skb->data; |
@@ -335,6 +336,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
335 | tx_info = IEEE80211_SKB_CB(skb); | 336 | tx_info = IEEE80211_SKB_CB(skb); |
336 | hw = bf->aphy->hw; | 337 | hw = bf->aphy->hw; |
337 | 338 | ||
339 | memcpy(rates, tx_info->control.rates, sizeof(rates)); | ||
340 | |||
338 | rcu_read_lock(); | 341 | rcu_read_lock(); |
339 | 342 | ||
340 | /* XXX: use ieee80211_find_sta! */ | 343 | /* XXX: use ieee80211_find_sta! */ |
@@ -375,6 +378,9 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
375 | txfail = txpending = 0; | 378 | txfail = txpending = 0; |
376 | bf_next = bf->bf_next; | 379 | bf_next = bf->bf_next; |
377 | 380 | ||
381 | skb = bf->bf_mpdu; | ||
382 | tx_info = IEEE80211_SKB_CB(skb); | ||
383 | |||
378 | if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) { | 384 | if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) { |
379 | /* transmit completion, subframe is | 385 | /* transmit completion, subframe is |
380 | * acked by block ack */ | 386 | * acked by block ack */ |
@@ -428,6 +434,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
428 | spin_unlock_bh(&txq->axq_lock); | 434 | spin_unlock_bh(&txq->axq_lock); |
429 | 435 | ||
430 | if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { | 436 | if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { |
437 | memcpy(tx_info->control.rates, rates, sizeof(rates)); | ||
431 | ath_tx_rc_status(bf, ts, nbad, txok, true); | 438 | ath_tx_rc_status(bf, ts, nbad, txok, true); |
432 | rc_update = false; | 439 | rc_update = false; |
433 | } else { | 440 | } else { |
@@ -1644,6 +1651,8 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
1644 | } | 1651 | } |
1645 | 1652 | ||
1646 | bf->bf_state.bfs_paprd = txctl->paprd; | 1653 | bf->bf_state.bfs_paprd = txctl->paprd; |
1654 | if (txctl->paprd) | ||
1655 | bf->bf_state.bfs_paprd_timestamp = jiffies; | ||
1647 | bf->bf_flags = setup_tx_flags(skb, use_ldpc); | 1656 | bf->bf_flags = setup_tx_flags(skb, use_ldpc); |
1648 | 1657 | ||
1649 | bf->bf_keytype = get_hw_crypto_keytype(skb); | 1658 | bf->bf_keytype = get_hw_crypto_keytype(skb); |
@@ -1944,8 +1953,12 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | |||
1944 | dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); | 1953 | dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); |
1945 | 1954 | ||
1946 | if (bf->bf_state.bfs_paprd) { | 1955 | if (bf->bf_state.bfs_paprd) { |
1947 | sc->paprd_txok = txok; | 1956 | if (time_after(jiffies, |
1948 | complete(&sc->paprd_complete); | 1957 | bf->bf_state.bfs_paprd_timestamp + |
1958 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT))) | ||
1959 | dev_kfree_skb_any(skb); | ||
1960 | else | ||
1961 | complete(&sc->paprd_complete); | ||
1949 | } else { | 1962 | } else { |
1950 | ath_tx_complete(sc, skb, bf->aphy, tx_flags); | 1963 | ath_tx_complete(sc, skb, bf->aphy, tx_flags); |
1951 | ath_debug_stat_tx(sc, txq, bf, ts); | 1964 | ath_debug_stat_tx(sc, txq, bf, ts); |
@@ -2027,7 +2040,7 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, | |||
2027 | tx_info->status.rates[i].idx = -1; | 2040 | tx_info->status.rates[i].idx = -1; |
2028 | } | 2041 | } |
2029 | 2042 | ||
2030 | tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1; | 2043 | tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; |
2031 | } | 2044 | } |
2032 | 2045 | ||
2033 | static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) | 2046 | static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) |
@@ -2138,7 +2151,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2138 | * This frame is sent out as a single frame. | 2151 | * This frame is sent out as a single frame. |
2139 | * Use hardware retry status for this frame. | 2152 | * Use hardware retry status for this frame. |
2140 | */ | 2153 | */ |
2141 | bf->bf_retries = ts.ts_longretry; | ||
2142 | if (ts.ts_status & ATH9K_TXERR_XRETRY) | 2154 | if (ts.ts_status & ATH9K_TXERR_XRETRY) |
2143 | bf->bf_state.bf_type |= BUF_XRETRY; | 2155 | bf->bf_state.bf_type |= BUF_XRETRY; |
2144 | ath_tx_rc_status(bf, &ts, 0, txok, true); | 2156 | ath_tx_rc_status(bf, &ts, 0, txok, true); |
@@ -2268,7 +2280,6 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2268 | } | 2280 | } |
2269 | 2281 | ||
2270 | if (!bf_isampdu(bf)) { | 2282 | if (!bf_isampdu(bf)) { |
2271 | bf->bf_retries = txs.ts_longretry; | ||
2272 | if (txs.ts_status & ATH9K_TXERR_XRETRY) | 2283 | if (txs.ts_status & ATH9K_TXERR_XRETRY) |
2273 | bf->bf_state.bf_type |= BUF_XRETRY; | 2284 | bf->bf_state.bf_type |= BUF_XRETRY; |
2274 | ath_tx_rc_status(bf, &txs, 0, txok, true); | 2285 | ath_tx_rc_status(bf, &txs, 0, txok, true); |