359cf5d035ac7eade8eace1a915bc2e7d3618aa3
[openwrt.git] / package / mac80211 / patches / 572-ath9k_xmit_queue_cleanup.patch
1 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
2 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
3 @@ -195,7 +195,6 @@ enum ATH_AGGR_STATUS {
4  
5  #define ATH_TXFIFO_DEPTH 8
6  struct ath_txq {
7 -       int axq_class;
8         u32 axq_qnum;
9         u32 *axq_link;
10         struct list_head axq_q;
11 @@ -208,11 +207,12 @@ struct ath_txq {
12         struct list_head txq_fifo_pending;
13         u8 txq_headidx;
14         u8 txq_tailidx;
15 +       int pending_frames;
16  };
17  
18  struct ath_atx_ac {
19 +       struct ath_txq *txq;
20         int sched;
21 -       int qnum;
22         struct list_head list;
23         struct list_head tid_q;
24  };
25 @@ -290,12 +290,11 @@ struct ath_tx_control {
26  struct ath_tx {
27         u16 seq_no;
28         u32 txqsetup;
29 -       int hwq_map[WME_NUM_AC];
30         spinlock_t txbuflock;
31         struct list_head txbuf;
32         struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
33         struct ath_descdma txdma;
34 -       int pending_frames[WME_NUM_AC];
35 +       struct ath_txq *txq_map[WME_NUM_AC];
36  };
37  
38  struct ath_rx_edma {
39 @@ -325,7 +324,6 @@ void ath_rx_cleanup(struct ath_softc *sc
40  int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);
41  struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
42  void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
43 -int ath_tx_setup(struct ath_softc *sc, int haltype);
44  void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
45  void ath_draintxq(struct ath_softc *sc,
46                      struct ath_txq *txq, bool retry_tx);
47 @@ -665,7 +663,6 @@ struct ath_wiphy {
48  
49  void ath9k_tasklet(unsigned long data);
50  int ath_reset(struct ath_softc *sc, bool retry_tx);
51 -int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
52  int ath_cabq_update(struct ath_softc *);
53  
54  static inline void ath_read_cachesize(struct ath_common *common, int *csz)
55 --- a/drivers/net/wireless/ath/ath9k/beacon.c
56 +++ b/drivers/net/wireless/ath/ath9k/beacon.c
57 @@ -28,7 +28,7 @@ int ath_beaconq_config(struct ath_softc 
58         struct ath_hw *ah = sc->sc_ah;
59         struct ath_common *common = ath9k_hw_common(ah);
60         struct ath9k_tx_queue_info qi, qi_be;
61 -       int qnum;
62 +       struct ath_txq *txq;
63  
64         ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
65         if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
66 @@ -38,8 +38,8 @@ int ath_beaconq_config(struct ath_softc 
67                 qi.tqi_cwmax = 0;
68         } else {
69                 /* Adhoc mode; important thing is to use 2x cwmin. */
70 -               qnum = sc->tx.hwq_map[WME_AC_BE];
71 -               ath9k_hw_get_txq_props(ah, qnum, &qi_be);
72 +               txq = sc->tx.txq_map[WME_AC_BE];
73 +               ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be);
74                 qi.tqi_aifs = qi_be.tqi_aifs;
75                 qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
76                 qi.tqi_cwmax = qi_be.tqi_cwmax;
77 --- a/drivers/net/wireless/ath/ath9k/common.h
78 +++ b/drivers/net/wireless/ath/ath9k/common.h
79 @@ -31,10 +31,11 @@
80  #define WME_MAX_BA              WME_BA_BMP_SIZE
81  #define ATH_TID_MAX_BUFS        (2 * WME_MAX_BA)
82  
83 -#define WME_AC_BE   0
84 -#define WME_AC_BK   1
85 -#define WME_AC_VI   2
86 -#define WME_AC_VO   3
87 +/* These must match mac80211 skb queue mapping numbers */
88 +#define WME_AC_VO   0
89 +#define WME_AC_VI   1
90 +#define WME_AC_BE   2
91 +#define WME_AC_BK   3
92  #define WME_NUM_AC  4
93  
94  #define ATH_RSSI_DUMMY_MARKER   0x127
95 --- a/drivers/net/wireless/ath/ath9k/main.c
96 +++ b/drivers/net/wireless/ath/ath9k/main.c
97 @@ -331,7 +331,7 @@ void ath_paprd_calibrate(struct work_str
98         struct ath_tx_control txctl;
99         struct ath9k_hw_cal_data *caldata = ah->caldata;
100         struct ath_common *common = ath9k_hw_common(ah);
101 -       int qnum, ftype;
102 +       int ftype;
103         int chain_ok = 0;
104         int chain;
105         int len = 1800;
106 @@ -358,8 +358,7 @@ void ath_paprd_calibrate(struct work_str
107         memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
108  
109         memset(&txctl, 0, sizeof(txctl));
110 -       qnum = sc->tx.hwq_map[WME_AC_BE];
111 -       txctl.txq = &sc->tx.txq[qnum];
112 +       txctl.txq = sc->tx.txq_map[WME_AC_BE];
113  
114         ath9k_ps_wakeup(sc);
115         ar9003_paprd_init_table(ah);
116 @@ -1025,56 +1024,6 @@ int ath_reset(struct ath_softc *sc, bool
117         return r;
118  }
119  
120 -static int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
121 -{
122 -       int qnum;
123 -
124 -       switch (queue) {
125 -       case 0:
126 -               qnum = sc->tx.hwq_map[WME_AC_VO];
127 -               break;
128 -       case 1:
129 -               qnum = sc->tx.hwq_map[WME_AC_VI];
130 -               break;
131 -       case 2:
132 -               qnum = sc->tx.hwq_map[WME_AC_BE];
133 -               break;
134 -       case 3:
135 -               qnum = sc->tx.hwq_map[WME_AC_BK];
136 -               break;
137 -       default:
138 -               qnum = sc->tx.hwq_map[WME_AC_BE];
139 -               break;
140 -       }
141 -
142 -       return qnum;
143 -}
144 -
145 -int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc)
146 -{
147 -       int qnum;
148 -
149 -       switch (queue) {
150 -       case WME_AC_VO:
151 -               qnum = 0;
152 -               break;
153 -       case WME_AC_VI:
154 -               qnum = 1;
155 -               break;
156 -       case WME_AC_BE:
157 -               qnum = 2;
158 -               break;
159 -       case WME_AC_BK:
160 -               qnum = 3;
161 -               break;
162 -       default:
163 -               qnum = -1;
164 -               break;
165 -       }
166 -
167 -       return qnum;
168 -}
169 -
170  /* XXX: Remove me once we don't depend on ath9k_channel for all
171   * this redundant data */
172  void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
173 @@ -1244,7 +1193,6 @@ static int ath9k_tx(struct ieee80211_hw 
174         struct ath_tx_control txctl;
175         int padpos, padsize;
176         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
177 -       int qnum;
178  
179         if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
180                 ath_print(common, ATH_DBG_XMIT,
181 @@ -1317,8 +1265,7 @@ static int ath9k_tx(struct ieee80211_hw 
182                 memmove(skb->data, skb->data + padsize, padpos);
183         }
184  
185 -       qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
186 -       txctl.txq = &sc->tx.txq[qnum];
187 +       txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)];
188  
189         ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
190  
191 @@ -1802,12 +1749,15 @@ static int ath9k_conf_tx(struct ieee8021
192         struct ath_wiphy *aphy = hw->priv;
193         struct ath_softc *sc = aphy->sc;
194         struct ath_common *common = ath9k_hw_common(sc->sc_ah);
195 +       struct ath_txq *txq;
196         struct ath9k_tx_queue_info qi;
197 -       int ret = 0, qnum;
198 +       int ret = 0;
199  
200         if (queue >= WME_NUM_AC)
201                 return 0;
202  
203 +       txq = sc->tx.txq_map[queue];
204 +
205         mutex_lock(&sc->mutex);
206  
207         memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
208 @@ -1816,20 +1766,19 @@ static int ath9k_conf_tx(struct ieee8021
209         qi.tqi_cwmin = params->cw_min;
210         qi.tqi_cwmax = params->cw_max;
211         qi.tqi_burstTime = params->txop;
212 -       qnum = ath_get_hal_qnum(queue, sc);
213  
214         ath_print(common, ATH_DBG_CONFIG,
215                   "Configure tx [queue/halq] [%d/%d],  "
216                   "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
217 -                 queue, qnum, params->aifs, params->cw_min,
218 +                 queue, txq->axq_qnum, params->aifs, params->cw_min,
219                   params->cw_max, params->txop);
220  
221 -       ret = ath_txq_update(sc, qnum, &qi);
222 +       ret = ath_txq_update(sc, txq->axq_qnum, &qi);
223         if (ret)
224                 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
225  
226         if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)
227 -               if ((qnum == sc->tx.hwq_map[WME_AC_BE]) && !ret)
228 +               if (queue == WME_AC_BE && !ret)
229                         ath_beaconq_config(sc);
230  
231         mutex_unlock(&sc->mutex);
232 --- a/drivers/net/wireless/ath/ath9k/xmit.c
233 +++ b/drivers/net/wireless/ath/ath9k/xmit.c
234 @@ -124,7 +124,7 @@ static void ath_tx_queue_tid(struct ath_
235  
236  static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
237  {
238 -       struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
239 +       struct ath_txq *txq = tid->ac->txq;
240  
241         WARN_ON(!tid->paused);
242  
243 @@ -142,7 +142,7 @@ unlock:
244  
245  static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
246  {
247 -       struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
248 +       struct ath_txq *txq = tid->ac->txq;
249         struct ath_buf *bf;
250         struct list_head bf_head;
251         struct ath_tx_status ts;
252 @@ -817,7 +817,7 @@ void ath_tx_aggr_stop(struct ath_softc *
253  {
254         struct ath_node *an = (struct ath_node *)sta->drv_priv;
255         struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
256 -       struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
257 +       struct ath_txq *txq = txtid->ac->txq;
258  
259         if (txtid->state & AGGR_CLEANUP)
260                 return;
261 @@ -888,10 +888,16 @@ struct ath_txq *ath_txq_setup(struct ath
262         struct ath_hw *ah = sc->sc_ah;
263         struct ath_common *common = ath9k_hw_common(ah);
264         struct ath9k_tx_queue_info qi;
265 +       static const int subtype_txq_to_hwq[] = {
266 +               [WME_AC_BE] = ATH_TXQ_AC_BE,
267 +               [WME_AC_BK] = ATH_TXQ_AC_BK,
268 +               [WME_AC_VI] = ATH_TXQ_AC_VI,
269 +               [WME_AC_VO] = ATH_TXQ_AC_VO,
270 +       };
271         int qnum, i;
272  
273         memset(&qi, 0, sizeof(qi));
274 -       qi.tqi_subtype = subtype;
275 +       qi.tqi_subtype = subtype_txq_to_hwq[subtype];
276         qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
277         qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
278         qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;
279 @@ -940,7 +946,6 @@ struct ath_txq *ath_txq_setup(struct ath
280         if (!ATH_TXQ_SETUP(sc, qnum)) {
281                 struct ath_txq *txq = &sc->tx.txq[qnum];
282  
283 -               txq->axq_class = subtype;
284                 txq->axq_qnum = qnum;
285                 txq->axq_link = NULL;
286                 INIT_LIST_HEAD(&txq->axq_q);
287 @@ -1210,24 +1215,6 @@ void ath_txq_schedule(struct ath_softc *
288         }
289  }
290  
291 -int ath_tx_setup(struct ath_softc *sc, int haltype)
292 -{
293 -       struct ath_txq *txq;
294 -
295 -       if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
296 -               ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
297 -                         "HAL AC %u out of range, max %zu!\n",
298 -                        haltype, ARRAY_SIZE(sc->tx.hwq_map));
299 -               return 0;
300 -       }
301 -       txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
302 -       if (txq != NULL) {
303 -               sc->tx.hwq_map[haltype] = txq->axq_qnum;
304 -               return 1;
305 -       } else
306 -               return 0;
307 -}
308 -
309  /***********/
310  /* TX, DMA */
311  /***********/
312 @@ -1708,6 +1695,7 @@ static void ath_tx_start_dma(struct ath_
313                         goto tx_done;
314                 }
315  
316 +               WARN_ON(tid->ac->txq != txctl->txq);
317                 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
318                         /*
319                          * Try aggregation if it's a unicast data frame
320 @@ -1747,6 +1735,7 @@ int ath_tx_start(struct ieee80211_hw *hw
321                 return -1;
322         }
323  
324 +       q = skb_get_queue_mapping(skb);
325         r = ath_tx_setup_buffer(hw, bf, skb, txctl);
326         if (unlikely(r)) {
327                 ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n");
328 @@ -1756,8 +1745,9 @@ int ath_tx_start(struct ieee80211_hw *hw
329                  * we will at least have to run TX completionon one buffer
330                  * on the queue */
331                 spin_lock_bh(&txq->axq_lock);
332 -               if (!txq->stopped && txq->axq_depth > 1) {
333 -                       ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
334 +               if (txq == sc->tx.txq_map[q] && !txq->stopped &&
335 +                   txq->axq_depth > 1) {
336 +                       ath_mac80211_stop_queue(sc, q);
337                         txq->stopped = 1;
338                 }
339                 spin_unlock_bh(&txq->axq_lock);
340 @@ -1767,13 +1757,10 @@ int ath_tx_start(struct ieee80211_hw *hw
341                 return r;
342         }
343  
344 -       q = skb_get_queue_mapping(skb);
345 -       if (q >= 4)
346 -               q = 0;
347 -
348         spin_lock_bh(&txq->axq_lock);
349 -       if (++sc->tx.pending_frames[q] > ATH_MAX_QDEPTH && !txq->stopped) {
350 -               ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
351 +       if (txq == sc->tx.txq_map[q] &&
352 +           ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) {
353 +               ath_mac80211_stop_queue(sc, q);
354                 txq->stopped = 1;
355         }
356         spin_unlock_bh(&txq->axq_lock);
357 @@ -1841,7 +1828,8 @@ exit:
358  /*****************/
359  
360  static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
361 -                           struct ath_wiphy *aphy, int tx_flags)
362 +                           struct ath_wiphy *aphy, int tx_flags,
363 +                           struct ath_txq *txq)
364  {
365         struct ieee80211_hw *hw = sc->hw;
366         struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
367 @@ -1888,11 +1876,12 @@ static void ath_tx_complete(struct ath_s
368                 ath9k_tx_status(hw, skb);
369         else {
370                 q = skb_get_queue_mapping(skb);
371 -               if (q >= 4)
372 -                       q = 0;
373 -
374 -               if (--sc->tx.pending_frames[q] < 0)
375 -                       sc->tx.pending_frames[q] = 0;
376 +               if (txq == sc->tx.txq_map[q]) {
377 +                       spin_lock_bh(&txq->axq_lock);
378 +                       if (WARN_ON(--txq->pending_frames < 0))
379 +                               txq->pending_frames = 0;
380 +                       spin_unlock_bh(&txq->axq_lock);
381 +               }
382  
383                 ieee80211_tx_status(hw, skb);
384         }
385 @@ -1927,8 +1916,8 @@ static void ath_tx_complete_buf(struct a
386                 else
387                         complete(&sc->paprd_complete);
388         } else {
389 -               ath_debug_stat_tx(sc, txq, bf, ts);
390 -               ath_tx_complete(sc, skb, bf->aphy, tx_flags);
391 +               ath_debug_stat_tx(sc, bf, ts);
392 +               ath_tx_complete(sc, skb, bf->aphy, tx_flags, txq);
393         }
394         /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't
395          * accidentally reference it later.
396 @@ -2018,16 +2007,13 @@ static void ath_tx_rc_status(struct ath_
397         tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1;
398  }
399  
400 -static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
401 +static void ath_wake_mac80211_queue(struct ath_softc *sc, int qnum)
402  {
403 -       int qnum;
404 -
405 -       qnum = ath_get_mac80211_qnum(txq->axq_class, sc);
406 -       if (qnum == -1)
407 -               return;
408 +       struct ath_txq *txq;
409  
410 +       txq = sc->tx.txq_map[qnum];
411         spin_lock_bh(&txq->axq_lock);
412 -       if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) {
413 +       if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) {
414                 if (ath_mac80211_start_queue(sc, qnum))
415                         txq->stopped = 0;
416         }
417 @@ -2044,6 +2030,7 @@ static void ath_tx_processq(struct ath_s
418         struct ath_tx_status ts;
419         int txok;
420         int status;
421 +       int qnum;
422  
423         ath_print(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
424                   txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
425 @@ -2119,12 +2106,15 @@ static void ath_tx_processq(struct ath_s
426                         ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true);
427                 }
428  
429 +               qnum = skb_get_queue_mapping(bf->bf_mpdu);
430 +
431                 if (bf_isampdu(bf))
432                         ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok);
433                 else
434                         ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0);
435  
436 -               ath_wake_mac80211_queue(sc, txq);
437 +               if (txq == sc->tx.txq_map[qnum])
438 +                       ath_wake_mac80211_queue(sc, qnum);
439  
440                 spin_lock_bh(&txq->axq_lock);
441                 if (sc->sc_flags & SC_OP_TXAGGR)
442 @@ -2194,6 +2184,7 @@ void ath_tx_edma_tasklet(struct ath_soft
443         struct list_head bf_head;
444         int status;
445         int txok;
446 +       int qnum;
447  
448         for (;;) {
449                 status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs);
450 @@ -2237,13 +2228,16 @@ void ath_tx_edma_tasklet(struct ath_soft
451                         ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true);
452                 }
453  
454 +               qnum = skb_get_queue_mapping(bf->bf_mpdu);
455 +
456                 if (bf_isampdu(bf))
457                         ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok);
458                 else
459                         ath_tx_complete_buf(sc, bf, txq, &bf_head,
460                                             &txs, txok, 0);
461  
462 -               ath_wake_mac80211_queue(sc, txq);
463 +               if (txq == sc->tx.txq_map[qnum])
464 +                       ath_wake_mac80211_queue(sc, qnum);
465  
466                 spin_lock_bh(&txq->axq_lock);
467                 if (!list_empty(&txq->txq_fifo_pending)) {
468 @@ -2375,7 +2369,7 @@ void ath_tx_node_init(struct ath_softc *
469         for (acno = 0, ac = &an->ac[acno];
470              acno < WME_NUM_AC; acno++, ac++) {
471                 ac->sched    = false;
472 -               ac->qnum = sc->tx.hwq_map[acno];
473 +               ac->txq = sc->tx.txq_map[acno];
474                 INIT_LIST_HEAD(&ac->tid_q);
475         }
476  }
477 @@ -2385,17 +2379,13 @@ void ath_tx_node_cleanup(struct ath_soft
478         struct ath_atx_ac *ac;
479         struct ath_atx_tid *tid;
480         struct ath_txq *txq;
481 -       int i, tidno;
482 +       int tidno;
483  
484         for (tidno = 0, tid = &an->tid[tidno];
485              tidno < WME_NUM_TID; tidno++, tid++) {
486 -               i = tid->ac->qnum;
487 -
488 -               if (!ATH_TXQ_SETUP(sc, i))
489 -                       continue;
490  
491 -               txq = &sc->tx.txq[i];
492                 ac = tid->ac;
493 +               txq = ac->txq;
494  
495                 spin_lock_bh(&txq->axq_lock);
496  
497 --- a/drivers/net/wireless/ath/ath9k/hw.h
498 +++ b/drivers/net/wireless/ath/ath9k/hw.h
499 @@ -157,6 +157,13 @@
500  #define PAPRD_GAIN_TABLE_ENTRIES    32
501  #define PAPRD_TABLE_SZ              24
502  
503 +enum ath_hw_txq_subtype {
504 +       ATH_TXQ_AC_BE = 0,
505 +       ATH_TXQ_AC_BK = 1,
506 +       ATH_TXQ_AC_VI = 2,
507 +       ATH_TXQ_AC_VO = 3,
508 +};
509 +
510  enum ath_ini_subsys {
511         ATH_INI_PRE = 0,
512         ATH_INI_CORE,
513 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
514 +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
515 @@ -20,8 +20,15 @@
516  /* TX */
517  /******/
518  
519 +static const int subtype_txq_to_hwq[] = {
520 +       [WME_AC_BE] = ATH_TXQ_AC_BE,
521 +       [WME_AC_BK] = ATH_TXQ_AC_BK,
522 +       [WME_AC_VI] = ATH_TXQ_AC_VI,
523 +       [WME_AC_VO] = ATH_TXQ_AC_VO,
524 +};
525 +
526  #define ATH9K_HTC_INIT_TXQ(subtype) do {                       \
527 -               qi.tqi_subtype = subtype;                       \
528 +               qi.tqi_subtype = subtype_txq_to_hwq[subtype];   \
529                 qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;             \
530                 qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;            \
531                 qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;            \
532 --- a/drivers/net/wireless/ath/ath9k/init.c
533 +++ b/drivers/net/wireless/ath/ath9k/init.c
534 @@ -396,7 +396,8 @@ static void ath9k_init_crypto(struct ath
535  
536  static int ath9k_init_btcoex(struct ath_softc *sc)
537  {
538 -       int r, qnum;
539 +       struct ath_txq *txq;
540 +       int r;
541  
542         switch (sc->sc_ah->btcoex_hw.scheme) {
543         case ATH_BTCOEX_CFG_NONE:
544 @@ -409,8 +410,8 @@ static int ath9k_init_btcoex(struct ath_
545                 r = ath_init_btcoex_timer(sc);
546                 if (r)
547                         return -1;
548 -               qnum = sc->tx.hwq_map[WME_AC_BE];
549 -               ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum);
550 +               txq = sc->tx.txq_map[WME_AC_BE];
551 +               ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
552                 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
553                 break;
554         default:
555 @@ -423,59 +424,18 @@ static int ath9k_init_btcoex(struct ath_
556  
557  static int ath9k_init_queues(struct ath_softc *sc)
558  {
559 -       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
560         int i = 0;
561  
562 -       for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
563 -               sc->tx.hwq_map[i] = -1;
564 -
565         sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
566 -       if (sc->beacon.beaconq == -1) {
567 -               ath_print(common, ATH_DBG_FATAL,
568 -                         "Unable to setup a beacon xmit queue\n");
569 -               goto err;
570 -       }
571 -
572         sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
573 -       if (sc->beacon.cabq == NULL) {
574 -               ath_print(common, ATH_DBG_FATAL,
575 -                         "Unable to setup CAB xmit queue\n");
576 -               goto err;
577 -       }
578  
579         sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
580         ath_cabq_update(sc);
581  
582 -       if (!ath_tx_setup(sc, WME_AC_BK)) {
583 -               ath_print(common, ATH_DBG_FATAL,
584 -                         "Unable to setup xmit queue for BK traffic\n");
585 -               goto err;
586 -       }
587 -
588 -       if (!ath_tx_setup(sc, WME_AC_BE)) {
589 -               ath_print(common, ATH_DBG_FATAL,
590 -                         "Unable to setup xmit queue for BE traffic\n");
591 -               goto err;
592 -       }
593 -       if (!ath_tx_setup(sc, WME_AC_VI)) {
594 -               ath_print(common, ATH_DBG_FATAL,
595 -                         "Unable to setup xmit queue for VI traffic\n");
596 -               goto err;
597 -       }
598 -       if (!ath_tx_setup(sc, WME_AC_VO)) {
599 -               ath_print(common, ATH_DBG_FATAL,
600 -                         "Unable to setup xmit queue for VO traffic\n");
601 -               goto err;
602 -       }
603 +       for (i = 0; i < WME_NUM_AC; i++)
604 +               sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
605  
606         return 0;
607 -
608 -err:
609 -       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
610 -               if (ATH_TXQ_SETUP(sc, i))
611 -                       ath_tx_cleanupq(sc, &sc->tx.txq[i]);
612 -
613 -       return -EIO;
614  }
615  
616  static int ath9k_init_channels_rates(struct ath_softc *sc)
617 --- a/drivers/net/wireless/ath/ath9k/virtual.c
618 +++ b/drivers/net/wireless/ath/ath9k/virtual.c
619 @@ -187,7 +187,7 @@ static int ath9k_send_nullfunc(struct at
620         info->control.rates[1].idx = -1;
621  
622         memset(&txctl, 0, sizeof(struct ath_tx_control));
623 -       txctl.txq = &sc->tx.txq[sc->tx.hwq_map[WME_AC_VO]];
624 +       txctl.txq = sc->tx.txq_map[WME_AC_VO];
625         txctl.frame_type = ps ? ATH9K_IFT_PAUSE : ATH9K_IFT_UNPAUSE;
626  
627         if (ath_tx_start(aphy->hw, skb, &txctl) != 0)
628 --- a/drivers/net/wireless/ath/ath9k/debug.c
629 +++ b/drivers/net/wireless/ath/ath9k/debug.c
630 @@ -579,10 +579,10 @@ static const struct file_operations fops
631         do {                                                            \
632                 len += snprintf(buf + len, size - len,                  \
633                                 "%s%13u%11u%10u%10u\n", str,            \
634 -               sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BE]].elem, \
635 -               sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BK]].elem, \
636 -               sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VI]].elem, \
637 -               sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VO]].elem); \
638 +               sc->debug.stats.txstats[WME_AC_BE].elem, \
639 +               sc->debug.stats.txstats[WME_AC_BK].elem, \
640 +               sc->debug.stats.txstats[WME_AC_VI].elem, \
641 +               sc->debug.stats.txstats[WME_AC_VO].elem); \
642  } while(0)
643  
644  static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
645 @@ -624,33 +624,35 @@ static ssize_t read_file_xmit(struct fil
646         return retval;
647  }
648  
649 -void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
650 -                      struct ath_buf *bf, struct ath_tx_status *ts)
651 +void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
652 +                      struct ath_tx_status *ts)
653  {
654 -       TX_STAT_INC(txq->axq_qnum, tx_pkts_all);
655 -       sc->debug.stats.txstats[txq->axq_qnum].tx_bytes_all += bf->bf_mpdu->len;
656 +       int qnum = skb_get_queue_mapping(bf->bf_mpdu);
657 +
658 +       TX_STAT_INC(qnum, tx_pkts_all);
659 +       sc->debug.stats.txstats[qnum].tx_bytes_all += bf->bf_mpdu->len;
660  
661         if (bf_isampdu(bf)) {
662                 if (bf_isxretried(bf))
663 -                       TX_STAT_INC(txq->axq_qnum, a_xretries);
664 +                       TX_STAT_INC(qnum, a_xretries);
665                 else
666 -                       TX_STAT_INC(txq->axq_qnum, a_completed);
667 +                       TX_STAT_INC(qnum, a_completed);
668         } else {
669 -               TX_STAT_INC(txq->axq_qnum, completed);
670 +               TX_STAT_INC(qnum, completed);
671         }
672  
673         if (ts->ts_status & ATH9K_TXERR_FIFO)
674 -               TX_STAT_INC(txq->axq_qnum, fifo_underrun);
675 +               TX_STAT_INC(qnum, fifo_underrun);
676         if (ts->ts_status & ATH9K_TXERR_XTXOP)
677 -               TX_STAT_INC(txq->axq_qnum, xtxop);
678 +               TX_STAT_INC(qnum, xtxop);
679         if (ts->ts_status & ATH9K_TXERR_TIMER_EXPIRED)
680 -               TX_STAT_INC(txq->axq_qnum, timer_exp);
681 +               TX_STAT_INC(qnum, timer_exp);
682         if (ts->ts_flags & ATH9K_TX_DESC_CFG_ERR)
683 -               TX_STAT_INC(txq->axq_qnum, desc_cfg_err);
684 +               TX_STAT_INC(qnum, desc_cfg_err);
685         if (ts->ts_flags & ATH9K_TX_DATA_UNDERRUN)
686 -               TX_STAT_INC(txq->axq_qnum, data_underrun);
687 +               TX_STAT_INC(qnum, data_underrun);
688         if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN)
689 -               TX_STAT_INC(txq->axq_qnum, delim_underrun);
690 +               TX_STAT_INC(qnum, delim_underrun);
691  }
692  
693  static const struct file_operations fops_xmit = {
694 --- a/drivers/net/wireless/ath/ath9k/debug.h
695 +++ b/drivers/net/wireless/ath/ath9k/debug.h
696 @@ -169,8 +169,8 @@ void ath9k_exit_debug(struct ath_hw *ah)
697  int ath9k_debug_create_root(void);
698  void ath9k_debug_remove_root(void);
699  void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
700 -void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
701 -                      struct ath_buf *bf, struct ath_tx_status *ts);
702 +void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
703 +                      struct ath_tx_status *ts);
704  void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
705  
706  #else