[backfire] backport r28376
[openwrt-10.03/.git] / package / mac80211 / patches / 544-ath9k_defer_buffer_setup.patch
1 --- a/drivers/net/wireless/ath/ath9k/xmit.c
2 +++ b/drivers/net/wireless/ath/ath9k/xmit.c
3 @@ -48,8 +48,9 @@ static u16 bits_per_symbol[][2] = {
4  #define IS_HT_RATE(_rate)     ((_rate) & 0x80)
5  
6  static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
7 -                              struct ath_atx_tid *tid,
8 -                              struct list_head *bf_head);
9 +                              struct ath_atx_tid *tid, struct sk_buff *skb);
10 +static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
11 +                           int tx_flags, struct ath_txq *txq);
12  static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
13                                 struct ath_txq *txq, struct list_head *bf_q,
14                                 struct ath_tx_status *ts, int txok, int sendbar);
15 @@ -61,6 +62,10 @@ static void ath_tx_rc_status(struct ath_
16                              int txok, bool update_rc);
17  static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
18                               int seqno);
19 +static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
20 +                                          struct ath_txq *txq,
21 +                                          struct ath_atx_tid *tid,
22 +                                          struct sk_buff *skb);
23  
24  enum {
25         MCS_HT20,
26 @@ -164,14 +169,13 @@ static void ath_tx_flush_tid(struct ath_
27                 fi = get_frame_info(skb);
28                 bf = fi->bf;
29  
30 -               list_add_tail(&bf->list, &bf_head);
31 -
32                 spin_unlock_bh(&txq->axq_lock);
33 -               if (fi->retries) {
34 +               if (bf && fi->retries) {
35 +                       list_add_tail(&bf->list, &bf_head);
36                         ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
37                         ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 1);
38                 } else {
39 -                       ath_tx_send_normal(sc, txq, NULL, &bf_head);
40 +                       ath_tx_send_normal(sc, txq, NULL, skb);
41                 }
42                 spin_lock_bh(&txq->axq_lock);
43         }
44 @@ -234,6 +238,13 @@ static void ath_tid_drain(struct ath_sof
45                 fi = get_frame_info(skb);
46                 bf = fi->bf;
47  
48 +               if (!bf) {
49 +                       spin_unlock(&txq->axq_lock);
50 +                       ath_tx_complete(sc, skb, ATH_TX_ERROR, txq);
51 +                       spin_lock(&txq->axq_lock);
52 +                       continue;
53 +               }
54 +
55                 list_add_tail(&bf->list, &bf_head);
56  
57                 if (fi->retries)
58 @@ -760,8 +771,14 @@ static enum ATH_AGGR_STATUS ath_tx_form_
59                 skb = skb_peek(&tid->buf_q);
60                 fi = get_frame_info(skb);
61                 bf = fi->bf;
62 -               seqno = bf->bf_state.seqno;
63 +               if (!fi->bf)
64 +                       bf = ath_tx_setup_buffer(sc, txq, tid, skb);
65  
66 +               if (!bf)
67 +                       continue;
68 +
69 +               bf->bf_state.bf_type |= BUF_AMPDU;
70 +               seqno = bf->bf_state.seqno;
71                 if (!bf_first)
72                         bf_first = bf;
73  
74 @@ -1434,13 +1451,11 @@ static void ath_tx_txqaddbuf(struct ath_
75  }
76  
77  static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
78 -                             struct ath_buf *bf, struct ath_tx_control *txctl)
79 +                             struct sk_buff *skb, struct ath_tx_control *txctl)
80  {
81 -       struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
82 +       struct ath_frame_info *fi = get_frame_info(skb);
83         struct list_head bf_head;
84 -       u16 seqno = bf->bf_state.seqno;
85 -
86 -       bf->bf_state.bf_type |= BUF_AMPDU;
87 +       struct ath_buf *bf;
88  
89         /*
90          * Do not queue to h/w when any of the following conditions is true:
91 @@ -1450,25 +1465,29 @@ static void ath_tx_send_ampdu(struct ath
92          * - h/w queue depth exceeds low water mark
93          */
94         if (!skb_queue_empty(&tid->buf_q) || tid->paused ||
95 -           !BAW_WITHIN(tid->seq_start, tid->baw_size, seqno) ||
96 +           !BAW_WITHIN(tid->seq_start, tid->baw_size, tid->seq_next) ||
97             txctl->txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) {
98                 /*
99                  * Add this frame to software queue for scheduling later
100                  * for aggregation.
101                  */
102                 TX_STAT_INC(txctl->txq->axq_qnum, a_queued_sw);
103 -               __skb_queue_tail(&tid->buf_q, bf->bf_mpdu);
104 +               __skb_queue_tail(&tid->buf_q, skb);
105                 if (!txctl->an || !txctl->an->sleeping)
106                         ath_tx_queue_tid(txctl->txq, tid);
107                 return;
108         }
109  
110 +       bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
111 +       if (!bf)
112 +               return;
113 +
114 +       bf->bf_state.bf_type |= BUF_AMPDU;
115         INIT_LIST_HEAD(&bf_head);
116         list_add(&bf->list, &bf_head);
117  
118         /* Add sub-frame to BAW */
119 -       if (!fi->retries)
120 -               ath_tx_addto_baw(sc, tid, seqno);
121 +       ath_tx_addto_baw(sc, tid, bf->bf_state.seqno);
122  
123         /* Queue to h/w without aggregation */
124         TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw);
125 @@ -1478,13 +1497,21 @@ static void ath_tx_send_ampdu(struct ath
126  }
127  
128  static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
129 -                              struct ath_atx_tid *tid,
130 -                              struct list_head *bf_head)
131 +                              struct ath_atx_tid *tid, struct sk_buff *skb)
132  {
133 -       struct ath_frame_info *fi;
134 +       struct ath_frame_info *fi = get_frame_info(skb);
135 +       struct list_head bf_head;
136         struct ath_buf *bf;
137  
138 -       bf = list_first_entry(bf_head, struct ath_buf, list);
139 +       bf = fi->bf;
140 +       if (!bf)
141 +               bf = ath_tx_setup_buffer(sc, txq, tid, skb);
142 +
143 +       if (!bf)
144 +               return;
145 +
146 +       INIT_LIST_HEAD(&bf_head);
147 +       list_add_tail(&bf->list, &bf_head);
148         bf->bf_state.bf_type &= ~BUF_AMPDU;
149  
150         /* update starting sequence number for subsequent ADDBA request */
151 @@ -1492,9 +1519,8 @@ static void ath_tx_send_normal(struct at
152                 INCR(tid->seq_start, IEEE80211_SEQ_MAX);
153  
154         bf->bf_lastbf = bf;
155 -       fi = get_frame_info(bf->bf_mpdu);
156         ath_buf_set_rate(sc, bf, fi->framelen);
157 -       ath_tx_txqaddbuf(sc, txq, bf_head, false);
158 +       ath_tx_txqaddbuf(sc, txq, &bf_head, false);
159         TX_STAT_INC(txq->axq_qnum, queued);
160  }
161  
162 @@ -1717,6 +1743,10 @@ static void ath_buf_set_rate(struct ath_
163  
164  }
165  
166 +/*
167 + * Assign a descriptor (and sequence number if necessary,
168 + * and map buffer for DMA. Frees skb on error
169 + */
170  static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
171                                            struct ath_txq *txq,
172                                            struct ath_atx_tid *tid,
173 @@ -1734,7 +1764,7 @@ static struct ath_buf *ath_tx_setup_buff
174         bf = ath_tx_get_buffer(sc);
175         if (!bf) {
176                 ath_dbg(common, ATH_DBG_XMIT, "TX buffers are full\n");
177 -               return NULL;
178 +               goto error;
179         }
180  
181         ATH_TXBUF_RESET(bf);
182 @@ -1757,7 +1787,7 @@ static struct ath_buf *ath_tx_setup_buff
183                 ath_err(ath9k_hw_common(sc->sc_ah),
184                         "dma_mapping_error() on TX\n");
185                 ath_tx_return_buffer(sc, bf);
186 -               return NULL;
187 +               goto error;
188         }
189  
190         frm_type = get_hw_packet_type(skb);
191 @@ -1779,18 +1809,20 @@ static struct ath_buf *ath_tx_setup_buff
192         fi->bf = bf;
193  
194         return bf;
195 +
196 +error:
197 +       dev_kfree_skb_any(skb);
198 +       return NULL;
199  }
200  
201  /* FIXME: tx power */
202 -static int ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
203 +static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
204                              struct ath_tx_control *txctl)
205  {
206         struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
207         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
208 -       struct list_head bf_head;
209         struct ath_atx_tid *tid = NULL;
210         struct ath_buf *bf;
211 -       int ret = 0;
212         u8 tidno;
213  
214         spin_lock_bh(&txctl->txq->axq_lock);
215 @@ -1803,21 +1835,16 @@ static int ath_tx_start_dma(struct ath_s
216                 WARN_ON(tid->ac->txq != txctl->txq);
217         }
218  
219 -       bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
220 -       if (unlikely(!bf)) {
221 -               ret = -ENOMEM;
222 -               goto out;
223 -       }
224 -
225         if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
226                 /*
227                  * Try aggregation if it's a unicast data frame
228                  * and the destination is HT capable.
229                  */
230 -               ath_tx_send_ampdu(sc, tid, bf, txctl);
231 +               ath_tx_send_ampdu(sc, tid, skb, txctl);
232         } else {
233 -               INIT_LIST_HEAD(&bf_head);
234 -               list_add_tail(&bf->list, &bf_head);
235 +               bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
236 +               if (!bf)
237 +                       goto out;
238  
239                 bf->bf_state.bfs_paprd = txctl->paprd;
240  
241 @@ -1831,12 +1858,11 @@ static int ath_tx_start_dma(struct ath_s
242                 if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
243                         ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true);
244  
245 -               ath_tx_send_normal(sc, txctl->txq, tid, &bf_head);
246 +               ath_tx_send_normal(sc, txctl->txq, tid, skb);
247         }
248  
249  out:
250         spin_unlock_bh(&txctl->txq->axq_lock);
251 -       return ret;
252  }
253  
254  /* Upon failure caller should free skb */
255 @@ -1904,7 +1930,8 @@ int ath_tx_start(struct ieee80211_hw *hw
256         }
257         spin_unlock_bh(&txq->axq_lock);
258  
259 -       return ath_tx_start_dma(sc, skb, txctl);
260 +       ath_tx_start_dma(sc, skb, txctl);
261 +       return 0;
262  }
263  
264  /*****************/