diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/xmit.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index d4927c9a6bae..704fcbcbe20b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -157,15 +157,14 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, | |||
157 | struct sk_buff *skb) | 157 | struct sk_buff *skb) |
158 | { | 158 | { |
159 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 159 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
160 | int q, hw_queue; | 160 | struct ath_frame_info *fi = get_frame_info(skb); |
161 | 161 | int hw_queue; | |
162 | q = skb_get_queue_mapping(skb); | 162 | int q = fi->txq; |
163 | if (txq == sc->tx.uapsdq) | ||
164 | txq = sc->tx.txq_map[q]; | ||
165 | 163 | ||
166 | if (txq != sc->tx.txq_map[q]) | 164 | if (q < 0) |
167 | return; | 165 | return; |
168 | 166 | ||
167 | txq = sc->tx.txq_map[q]; | ||
169 | if (WARN_ON(--txq->pending_frames < 0)) | 168 | if (WARN_ON(--txq->pending_frames < 0)) |
170 | txq->pending_frames = 0; | 169 | txq->pending_frames = 0; |
171 | 170 | ||
@@ -898,6 +897,15 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, | |||
898 | 897 | ||
899 | tx_info = IEEE80211_SKB_CB(skb); | 898 | tx_info = IEEE80211_SKB_CB(skb); |
900 | tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT; | 899 | tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT; |
900 | |||
901 | /* | ||
902 | * No aggregation session is running, but there may be frames | ||
903 | * from a previous session or a failed attempt in the queue. | ||
904 | * Send them out as normal data frames | ||
905 | */ | ||
906 | if (!tid->active) | ||
907 | tx_info->flags &= ~IEEE80211_TX_CTL_AMPDU; | ||
908 | |||
901 | if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) { | 909 | if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) { |
902 | bf->bf_state.bf_type = 0; | 910 | bf->bf_state.bf_type = 0; |
903 | return bf; | 911 | return bf; |
@@ -2036,6 +2044,7 @@ static void setup_frame_info(struct ieee80211_hw *hw, | |||
2036 | an = (struct ath_node *) sta->drv_priv; | 2044 | an = (struct ath_node *) sta->drv_priv; |
2037 | 2045 | ||
2038 | memset(fi, 0, sizeof(*fi)); | 2046 | memset(fi, 0, sizeof(*fi)); |
2047 | fi->txq = -1; | ||
2039 | if (hw_key) | 2048 | if (hw_key) |
2040 | fi->keyix = hw_key->hw_key_idx; | 2049 | fi->keyix = hw_key->hw_key_idx; |
2041 | else if (an && ieee80211_is_data(hdr->frame_control) && an->ps_key > 0) | 2050 | else if (an && ieee80211_is_data(hdr->frame_control) && an->ps_key > 0) |
@@ -2187,6 +2196,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2187 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 2196 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
2188 | struct ieee80211_sta *sta = txctl->sta; | 2197 | struct ieee80211_sta *sta = txctl->sta; |
2189 | struct ieee80211_vif *vif = info->control.vif; | 2198 | struct ieee80211_vif *vif = info->control.vif; |
2199 | struct ath_frame_info *fi = get_frame_info(skb); | ||
2190 | struct ath_vif *avp = NULL; | 2200 | struct ath_vif *avp = NULL; |
2191 | struct ath_softc *sc = hw->priv; | 2201 | struct ath_softc *sc = hw->priv; |
2192 | struct ath_txq *txq = txctl->txq; | 2202 | struct ath_txq *txq = txctl->txq; |
@@ -2216,11 +2226,13 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2216 | hw_queue = (info->hw_queue >= sc->hw->queues - 2) ? q : info->hw_queue; | 2226 | hw_queue = (info->hw_queue >= sc->hw->queues - 2) ? q : info->hw_queue; |
2217 | 2227 | ||
2218 | ath_txq_lock(sc, txq); | 2228 | ath_txq_lock(sc, txq); |
2219 | if (txq == sc->tx.txq_map[q] && | 2229 | if (txq == sc->tx.txq_map[q]) { |
2220 | ++txq->pending_frames > sc->tx.txq_max_pending[q] && | 2230 | fi->txq = q; |
2221 | !txq->stopped) { | 2231 | if (++txq->pending_frames > sc->tx.txq_max_pending[q] && |
2222 | ieee80211_stop_queue(sc->hw, hw_queue); | 2232 | !txq->stopped) { |
2223 | txq->stopped = true; | 2233 | ieee80211_stop_queue(sc->hw, hw_queue); |
2234 | txq->stopped = true; | ||
2235 | } | ||
2224 | } | 2236 | } |
2225 | 2237 | ||
2226 | queue = ieee80211_is_data_present(hdr->frame_control); | 2238 | queue = ieee80211_is_data_present(hdr->frame_control); |