mac80211: update to wireless-testing 2010-04-13, add some more fixes for the ar9300...
[openwrt.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 @@ -1084,9 +1105,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 @@ -1306,25 +1325,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 @@ -1806,9 +1806,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 @@ -2122,13 +2120,12 @@ static void ath_tx_processq(struct ath_s
98                 txq->axq_depth--;
99                 txok = !(ts.ts_status & ATH9K_TXERR_MASK);
100                 txq->axq_tx_inprogress = false;
101 +               if (bf_held)
102 +                       list_del(&bf_held->list);
103                 spin_unlock_bh(&txq->axq_lock);
104  
105 -               if (bf_held) {
106 -                       spin_lock_bh(&sc->tx.txbuflock);
107 -                       list_move_tail(&bf_held->list, &sc->tx.txbuf);
108 -                       spin_unlock_bh(&sc->tx.txbuflock);
109 -               }
110 +               if (bf_held)
111 +                       ath_tx_return_buffer(sc, bf_held);
112  
113                 if (!bf_isampdu(bf)) {
114                         /*