mac80211: update to wireless-testing 2010-04-09, add work-in-progress ar9300 patches
[openwrt/staging/florian.git] / package / mac80211 / patches / 560-ath9k_tx_buf_return_cleanup.patch
1 --- a/drivers/net/wireless/ath/ath9k/xmit.c
2 +++ b/drivers/net/wireless/ath/ath9k/xmit.c
3 @@ -260,19 +260,40 @@ static void ath_tx_set_retry(struct ath_
4 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
5 }
6
7 -static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
8 +static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
9 {
10 - struct ath_buf *tbf;
11 + struct ath_buf *bf = NULL;
12
13 spin_lock_bh(&sc->tx.txbuflock);
14 - if (WARN_ON(list_empty(&sc->tx.txbuf))) {
15 +
16 + if (unlikely(list_empty(&sc->tx.txbuf))) {
17 spin_unlock_bh(&sc->tx.txbuflock);
18 return NULL;
19 }
20 - tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
21 - list_del(&tbf->list);
22 +
23 + bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
24 + list_del(&bf->list);
25 +
26 spin_unlock_bh(&sc->tx.txbuflock);
27
28 + return bf;
29 +}
30 +
31 +static void ath_tx_return_buffer(struct ath_softc *sc, struct ath_buf *bf)
32 +{
33 + spin_lock_bh(&sc->tx.txbuflock);
34 + list_add_tail(&bf->list, &sc->tx.txbuf);
35 + spin_unlock_bh(&sc->tx.txbuflock);
36 +}
37 +
38 +static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
39 +{
40 + struct ath_buf *tbf;
41 +
42 + tbf = ath_tx_get_buffer(sc);
43 + if (WARN_ON(!tbf))
44 + return NULL;
45 +
46 ATH_TXBUF_RESET(tbf);
47
48 tbf->aphy = bf->aphy;
49 @@ -1083,9 +1104,7 @@ void ath_draintxq(struct ath_softc *sc,
50 list_del(&bf->list);
51 spin_unlock_bh(&txq->axq_lock);
52
53 - spin_lock_bh(&sc->tx.txbuflock);
54 - list_add_tail(&bf->list, &sc->tx.txbuf);
55 - spin_unlock_bh(&sc->tx.txbuflock);
56 + ath_tx_return_buffer(sc, bf);
57 continue;
58 }
59 }
60 @@ -1305,25 +1324,6 @@ static void ath_tx_txqaddbuf(struct ath_
61 txq->axq_depth++;
62 }
63
64 -static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
65 -{
66 - struct ath_buf *bf = NULL;
67 -
68 - spin_lock_bh(&sc->tx.txbuflock);
69 -
70 - if (unlikely(list_empty(&sc->tx.txbuf))) {
71 - spin_unlock_bh(&sc->tx.txbuflock);
72 - return NULL;
73 - }
74 -
75 - bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
76 - list_del(&bf->list);
77 -
78 - spin_unlock_bh(&sc->tx.txbuflock);
79 -
80 - return bf;
81 -}
82 -
83 static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
84 struct list_head *bf_head,
85 struct ath_tx_control *txctl)
86 @@ -1805,9 +1805,7 @@ int ath_tx_start(struct ieee80211_hw *hw
87 }
88 spin_unlock_bh(&txq->axq_lock);
89
90 - spin_lock_bh(&sc->tx.txbuflock);
91 - list_add_tail(&bf->list, &sc->tx.txbuf);
92 - spin_unlock_bh(&sc->tx.txbuflock);
93 + ath_tx_return_buffer(sc, bf);
94
95 return r;
96 }
97 @@ -2123,11 +2121,8 @@ static void ath_tx_processq(struct ath_s
98 txq->axq_tx_inprogress = false;
99 spin_unlock_bh(&txq->axq_lock);
100
101 - if (bf_held) {
102 - spin_lock_bh(&sc->tx.txbuflock);
103 - list_move_tail(&bf_held->list, &sc->tx.txbuf);
104 - spin_unlock_bh(&sc->tx.txbuflock);
105 - }
106 + if (bf_held)
107 + ath_tx_return_buffer(sc, bf_held);
108
109 if (!bf_isampdu(bf)) {
110 /*