[package] nvram: handle nvram at varying offsets within the eraseblock (fixes Edimax...
[openwrt.git] / package / mac80211 / patches / 510-ath9k_aggr_buffer_leak.patch
1 --- a/drivers/net/wireless/ath/ath9k/xmit.c
2 +++ b/drivers/net/wireless/ath/ath9k/xmit.c
3 @@ -2430,37 +2430,37 @@ void ath_tx_node_init(struct ath_softc *
4  
5  void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
6  {
7 -       int i;
8 -       struct ath_atx_ac *ac, *ac_tmp;
9 -       struct ath_atx_tid *tid, *tid_tmp;
10 +       struct ath_atx_ac *ac;
11 +       struct ath_atx_tid *tid;
12         struct ath_txq *txq;
13 +       int i, tidno;
14  
15 -       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
16 -               if (ATH_TXQ_SETUP(sc, i)) {
17 -                       txq = &sc->tx.txq[i];
18 -
19 -                       spin_lock_bh(&txq->axq_lock);
20 -
21 -                       list_for_each_entry_safe(ac,
22 -                                       ac_tmp, &txq->axq_acq, list) {
23 -                               tid = list_first_entry(&ac->tid_q,
24 -                                               struct ath_atx_tid, list);
25 -                               if (tid && tid->an != an)
26 -                                       continue;
27 -                               list_del(&ac->list);
28 -                               ac->sched = false;
29 -
30 -                               list_for_each_entry_safe(tid,
31 -                                               tid_tmp, &ac->tid_q, list) {
32 -                                       list_del(&tid->list);
33 -                                       tid->sched = false;
34 -                                       ath_tid_drain(sc, txq, tid);
35 -                                       tid->state &= ~AGGR_ADDBA_COMPLETE;
36 -                                       tid->state &= ~AGGR_CLEANUP;
37 -                               }
38 -                       }
39 +       for (tidno = 0, tid = &an->tid[tidno];
40 +            tidno < WME_NUM_TID; tidno++, tid++) {
41 +               i = tid->ac->qnum;
42  
43 -                       spin_unlock_bh(&txq->axq_lock);
44 +               if (!ATH_TXQ_SETUP(sc, i))
45 +                       continue;
46 +
47 +               txq = &sc->tx.txq[i];
48 +               ac = tid->ac;
49 +
50 +               spin_lock_bh(&txq->axq_lock);
51 +
52 +               if (tid->sched) {
53 +                       list_del(&tid->list);
54 +                       tid->sched = false;
55                 }
56 +
57 +               if (ac->sched) {
58 +                       list_del(&ac->list);
59 +                       tid->ac->sched = false;
60 +               }
61 +
62 +               ath_tid_drain(sc, txq, tid);
63 +               tid->state &= ~AGGR_ADDBA_COMPLETE;
64 +               tid->state &= ~AGGR_CLEANUP;
65 +
66 +               spin_unlock_bh(&txq->axq_lock);
67         }
68  }