diff options
Diffstat (limited to 'package/kernel')
-rw-r--r-- | package/kernel/mac80211/patches/336-ath9k-improve-powersave-filter-handling.patch | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/336-ath9k-improve-powersave-filter-handling.patch b/package/kernel/mac80211/patches/336-ath9k-improve-powersave-filter-handling.patch new file mode 100644 index 0000000000..67a6c631ee --- /dev/null +++ b/package/kernel/mac80211/patches/336-ath9k-improve-powersave-filter-handling.patch @@ -0,0 +1,70 @@ +From: Felix Fietkau <nbd@nbd.name> +Date: Tue, 2 Aug 2016 12:13:35 +0200 +Subject: [PATCH] ath9k: improve powersave filter handling + +For non-aggregated frames, ath9k was leaving handling of powersave +filtered packets to mac80211. This can be too slow if the intermediate +queue is already filled with packets and mac80211 does not immediately +send a new packet via drv_tx(). + +Improve response time with filtered frames by triggering clearing the +powersave filter internally. + +Signed-off-by: Felix Fietkau <nbd@nbd.name> +--- + +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -461,13 +461,13 @@ static void ath_tx_count_frames(struct a + static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, + struct ath_buf *bf, struct list_head *bf_q, + struct ieee80211_sta *sta, ++ struct ath_atx_tid *tid, + struct ath_tx_status *ts, int txok) + { + struct ath_node *an = NULL; + struct sk_buff *skb; + struct ieee80211_hdr *hdr; + struct ieee80211_tx_info *tx_info; +- struct ath_atx_tid *tid = NULL; + struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; + struct list_head bf_head; + struct sk_buff_head bf_pending; +@@ -509,7 +509,6 @@ static void ath_tx_complete_aggr(struct + } + + an = (struct ath_node *)sta->drv_priv; +- tid = ath_get_skb_tid(sc, an, skb); + seq_first = tid->seq_start; + isba = ts->ts_flags & ATH9K_TX_BA; + +@@ -695,6 +694,7 @@ static void ath_tx_process_buffer(struct + struct ieee80211_tx_info *info; + struct ieee80211_sta *sta; + struct ieee80211_hdr *hdr; ++ struct ath_atx_tid *tid = NULL; + bool txok, flush; + + txok = !(ts->ts_status & ATH9K_TXERR_MASK); +@@ -710,6 +710,12 @@ static void ath_tx_process_buffer(struct + + hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data; + sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2); ++ if (sta) { ++ struct ath_node *an = (struct ath_node *)sta->drv_priv; ++ tid = ath_get_skb_tid(sc, an, bf->bf_mpdu); ++ if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY)) ++ tid->clear_ps_filter = true; ++ } + + if (!bf_isampdu(bf)) { + if (!flush) { +@@ -721,7 +727,7 @@ static void ath_tx_process_buffer(struct + } + ath_tx_complete_buf(sc, bf, txq, bf_head, sta, ts, txok); + } else +- ath_tx_complete_aggr(sc, txq, bf, bf_head, sta, ts, txok); ++ ath_tx_complete_aggr(sc, txq, bf, bf_head, sta, tid, ts, txok); + + if (!flush) + ath_txq_schedule(sc, txq); |