aboutsummaryrefslogtreecommitdiffstats
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.c34
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);