Changeset 41673


Ignore:
Timestamp:
2014-07-16T20:26:21+02:00 (4 years ago)
Author:
nbd
Message:

ath9k: add a fix for tx pending frame accounting, fixes some tx hang issues

Signed-off-by: Felix Fietkau <nbd@…>

Location:
trunk/package/kernel/mac80211/patches
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/package/kernel/mac80211/patches/300-pending_work.patch

    r41298 r41673  
     1commit c0ee7fa4c0da824ccccc172bf175fb1f86540921 
     2Author: Felix Fietkau <nbd@openwrt.org> 
     3Date:   Wed Jul 16 18:00:31 2014 +0200 
     4 
     5    ath9k: fix pending tx frames accounting 
     6     
     7    Packets originally buffered for the regular hardware tx queues can end 
     8    up being transmitted through the U-APSD queue (via PS-Poll or U-APSD). 
     9    When packets are dropped due to retransmit failures, the pending frames 
     10    counter is not always updated properly. 
     11    Fix this by keeping track of the queue that a frame was accounted for in 
     12    the ath_frame_info struct, and using that on completion to decide 
     13    whether the counter should be updated. 
     14    This fixes some spurious transmit queue hangs. 
     15     
     16    Cc: stable@vger.kernel.org 
     17    Signed-off-by: Felix Fietkau <nbd@openwrt.org> 
     18 
    119commit edcdf0989410a05a6a4b8438df4010447eaa7d9a 
    220Author: Felix Fietkau <nbd@openwrt.org> 
     
    29212939                bw_flags |= IEEE80211_CHAN_NO_80MHZ; 
    29222940        if (max_bandwidth_khz < MHZ_TO_KHZ(160)) 
     2941--- a/drivers/net/wireless/ath/ath9k/ath9k.h 
     2942+++ b/drivers/net/wireless/ath/ath9k/ath9k.h 
     2943@@ -185,7 +185,8 @@ struct ath_atx_ac { 
     2944  
     2945 struct ath_frame_info { 
     2946        struct ath_buf *bf; 
     2947-       int framelen; 
     2948+       u16 framelen; 
     2949+       s8 txq; 
     2950        enum ath9k_key_type keytype; 
     2951        u8 keyix; 
     2952        u8 rtscts_rate; 
     2953--- a/drivers/net/wireless/ath/ath9k/xmit.c 
     2954+++ b/drivers/net/wireless/ath/ath9k/xmit.c 
     2955@@ -147,15 +147,13 @@ static void ath_set_rates(struct ieee802 
     2956 static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, 
     2957                             struct sk_buff *skb) 
     2958 { 
     2959-       int q; 
     2960- 
     2961-       q = skb_get_queue_mapping(skb); 
     2962-       if (txq == sc->tx.uapsdq) 
     2963-               txq = sc->tx.txq_map[q]; 
     2964+       struct ath_frame_info *fi = get_frame_info(skb); 
     2965+       int q = fi->txq; 
     2966  
     2967-       if (txq != sc->tx.txq_map[q]) 
     2968+       if (q < 0) 
     2969                return; 
     2970  
     2971+       txq = sc->tx.txq_map[q]; 
     2972        if (WARN_ON(--txq->pending_frames < 0)) 
     2973                txq->pending_frames = 0; 
     2974  
     2975@@ -1999,6 +1997,7 @@ static void setup_frame_info(struct ieee 
     2976                an = (struct ath_node *) sta->drv_priv; 
     2977  
     2978        memset(fi, 0, sizeof(*fi)); 
     2979+       fi->txq = -1; 
     2980        if (hw_key) 
     2981                fi->keyix = hw_key->hw_key_idx; 
     2982        else if (an && ieee80211_is_data(hdr->frame_control) && an->ps_key > 0) 
     2983@@ -2150,6 +2149,7 @@ int ath_tx_start(struct ieee80211_hw *hw 
     2984        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 
     2985        struct ieee80211_sta *sta = txctl->sta; 
     2986        struct ieee80211_vif *vif = info->control.vif; 
     2987+       struct ath_frame_info *fi = get_frame_info(skb); 
     2988        struct ath_softc *sc = hw->priv; 
     2989        struct ath_txq *txq = txctl->txq; 
     2990        struct ath_atx_tid *tid = NULL; 
     2991@@ -2170,11 +2170,13 @@ int ath_tx_start(struct ieee80211_hw *hw 
     2992        q = skb_get_queue_mapping(skb); 
     2993  
     2994        ath_txq_lock(sc, txq); 
     2995-       if (txq == sc->tx.txq_map[q] && 
     2996-           ++txq->pending_frames > sc->tx.txq_max_pending[q] && 
     2997-           !txq->stopped) { 
     2998-               ieee80211_stop_queue(sc->hw, q); 
     2999-               txq->stopped = true; 
     3000+       if (txq == sc->tx.txq_map[q]) { 
     3001+               fi->txq = q; 
     3002+               if (++txq->pending_frames > sc->tx.txq_max_pending[q] && 
     3003+                   !txq->stopped) { 
     3004+                       ieee80211_stop_queue(sc->hw, q); 
     3005+                       txq->stopped = true; 
     3006+               } 
     3007        } 
     3008  
     3009        if (txctl->an && ieee80211_is_data_present(hdr->frame_control)) 
  • trunk/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch

    r40834 r41673  
    11--- a/drivers/net/wireless/ath/ath9k/ath9k.h 
    22+++ b/drivers/net/wireless/ath/ath9k/ath9k.h 
    3 @@ -564,6 +564,9 @@ static inline int ath9k_dump_btcoex(stru 
     3@@ -565,6 +565,9 @@ static inline int ath9k_dump_btcoex(stru 
    44 void ath_init_leds(struct ath_softc *sc); 
    55 void ath_deinit_leds(struct ath_softc *sc); 
     
    1111 static inline void ath_init_leds(struct ath_softc *sc) 
    1212 { 
    13 @@ -702,6 +705,13 @@ void ath_ant_comb_scan(struct ath_softc  
     13@@ -703,6 +706,13 @@ void ath_ant_comb_scan(struct ath_softc  
    1414 #define PS_BEACON_SYNC            BIT(4) 
    1515 #define PS_WAIT_FOR_ANI           BIT(5) 
     
    2525        struct ieee80211_hw *hw; 
    2626        struct device *dev; 
    27 @@ -744,9 +754,8 @@ struct ath_softc { 
     27@@ -745,9 +755,8 @@ struct ath_softc { 
    2828        struct ath_beacon beacon; 
    2929  
Note: See TracChangeset for help on using the changeset viewer.