summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/xmit.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/xmit.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index eaaeb937fa1..8785ec3b1cb 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1968,6 +1968,8 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_hw *hw = bf->aphy->hw;
+ struct ath_softc *sc = bf->aphy->sc;
+ struct ath_hw *ah = sc->sc_ah;
u8 i, tx_rateindex;
if (txok)
@@ -1989,11 +1991,24 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 &&
(bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
- if (ieee80211_is_data(hdr->frame_control)) {
- if (ts->ts_flags &
- (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN))
- tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN;
- }
+ /*
+ * If an underrun error is seen assume it as an excessive
+ * retry only if max frame trigger level has been reached
+ * (2 KB for single stream, and 4 KB for dual stream).
+ * Adjust the long retry as if the frame was tried
+ * hw->max_rate_tries times to affect how rate control updates
+ * PER for the failed rate.
+ * In case of congestion on the bus penalizing this type of
+ * underruns should help hardware actually transmit new frames
+ * successfully by eventually preferring slower rates.
+ * This itself should also alleviate congestion on the bus.
+ */
+ if (ieee80211_is_data(hdr->frame_control) &&
+ (ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN |
+ ATH9K_TX_DELIM_UNDERRUN)) &&
+ ah->tx_trig_level >= sc->sc_ah->caps.tx_triglevel_max)
+ tx_info->status.rates[tx_rateindex].count =
+ hw->max_rate_tries;
}
for (i = tx_rateindex + 1; i < hw->max_rates; i++) {