ath9k: fix a potential buffer leak
[openwrt/openwrt.git] / package / mac80211 / patches / 560-ath9k_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 }