diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/xmit.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 631 |
1 files changed, 285 insertions, 346 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 6380bbd82d4..495432ec85a 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -48,19 +48,17 @@ static u16 bits_per_symbol[][2] = { | |||
48 | 48 | ||
49 | #define IS_HT_RATE(_rate) ((_rate) & 0x80) | 49 | #define IS_HT_RATE(_rate) ((_rate) & 0x80) |
50 | 50 | ||
51 | static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq, | 51 | static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, |
52 | struct ath_atx_tid *tid, | 52 | struct ath_atx_tid *tid, |
53 | struct list_head *bf_head); | 53 | struct list_head *bf_head); |
54 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 54 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, |
55 | struct ath_txq *txq, struct list_head *bf_q, | 55 | struct ath_txq *txq, struct list_head *bf_q, |
56 | struct ath_tx_status *ts, int txok, int sendbar); | 56 | struct ath_tx_status *ts, int txok, int sendbar); |
57 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | 57 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, |
58 | struct list_head *head); | 58 | struct list_head *head); |
59 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf); | 59 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len); |
60 | static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, | ||
61 | struct ath_tx_status *ts, int txok); | ||
62 | static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, | 60 | static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, |
63 | int nbad, int txok, bool update_rc); | 61 | int nframes, int nbad, int txok, bool update_rc); |
64 | static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, | 62 | static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, |
65 | int seqno); | 63 | int seqno); |
66 | 64 | ||
@@ -140,12 +138,21 @@ unlock: | |||
140 | spin_unlock_bh(&txq->axq_lock); | 138 | spin_unlock_bh(&txq->axq_lock); |
141 | } | 139 | } |
142 | 140 | ||
141 | static struct ath_frame_info *get_frame_info(struct sk_buff *skb) | ||
142 | { | ||
143 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
144 | BUILD_BUG_ON(sizeof(struct ath_frame_info) > | ||
145 | sizeof(tx_info->rate_driver_data)); | ||
146 | return (struct ath_frame_info *) &tx_info->rate_driver_data[0]; | ||
147 | } | ||
148 | |||
143 | static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | 149 | static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) |
144 | { | 150 | { |
145 | struct ath_txq *txq = tid->ac->txq; | 151 | struct ath_txq *txq = tid->ac->txq; |
146 | struct ath_buf *bf; | 152 | struct ath_buf *bf; |
147 | struct list_head bf_head; | 153 | struct list_head bf_head; |
148 | struct ath_tx_status ts; | 154 | struct ath_tx_status ts; |
155 | struct ath_frame_info *fi; | ||
149 | 156 | ||
150 | INIT_LIST_HEAD(&bf_head); | 157 | INIT_LIST_HEAD(&bf_head); |
151 | 158 | ||
@@ -156,12 +163,15 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | |||
156 | bf = list_first_entry(&tid->buf_q, struct ath_buf, list); | 163 | bf = list_first_entry(&tid->buf_q, struct ath_buf, list); |
157 | list_move_tail(&bf->list, &bf_head); | 164 | list_move_tail(&bf->list, &bf_head); |
158 | 165 | ||
159 | if (bf_isretried(bf)) { | 166 | spin_unlock_bh(&txq->axq_lock); |
160 | ath_tx_update_baw(sc, tid, bf->bf_seqno); | 167 | fi = get_frame_info(bf->bf_mpdu); |
168 | if (fi->retries) { | ||
169 | ath_tx_update_baw(sc, tid, fi->seqno); | ||
161 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); | 170 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); |
162 | } else { | 171 | } else { |
163 | ath_tx_send_ht_normal(sc, txq, tid, &bf_head); | 172 | ath_tx_send_normal(sc, txq, tid, &bf_head); |
164 | } | 173 | } |
174 | spin_lock_bh(&txq->axq_lock); | ||
165 | } | 175 | } |
166 | 176 | ||
167 | spin_unlock_bh(&txq->axq_lock); | 177 | spin_unlock_bh(&txq->axq_lock); |
@@ -184,14 +194,11 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
184 | } | 194 | } |
185 | 195 | ||
186 | static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid, | 196 | static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid, |
187 | struct ath_buf *bf) | 197 | u16 seqno) |
188 | { | 198 | { |
189 | int index, cindex; | 199 | int index, cindex; |
190 | 200 | ||
191 | if (bf_isretried(bf)) | 201 | index = ATH_BA_INDEX(tid->seq_start, seqno); |
192 | return; | ||
193 | |||
194 | index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno); | ||
195 | cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); | 202 | cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); |
196 | __set_bit(cindex, tid->tx_buf); | 203 | __set_bit(cindex, tid->tx_buf); |
197 | 204 | ||
@@ -215,6 +222,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq, | |||
215 | struct ath_buf *bf; | 222 | struct ath_buf *bf; |
216 | struct list_head bf_head; | 223 | struct list_head bf_head; |
217 | struct ath_tx_status ts; | 224 | struct ath_tx_status ts; |
225 | struct ath_frame_info *fi; | ||
218 | 226 | ||
219 | memset(&ts, 0, sizeof(ts)); | 227 | memset(&ts, 0, sizeof(ts)); |
220 | INIT_LIST_HEAD(&bf_head); | 228 | INIT_LIST_HEAD(&bf_head); |
@@ -226,8 +234,9 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq, | |||
226 | bf = list_first_entry(&tid->buf_q, struct ath_buf, list); | 234 | bf = list_first_entry(&tid->buf_q, struct ath_buf, list); |
227 | list_move_tail(&bf->list, &bf_head); | 235 | list_move_tail(&bf->list, &bf_head); |
228 | 236 | ||
229 | if (bf_isretried(bf)) | 237 | fi = get_frame_info(bf->bf_mpdu); |
230 | ath_tx_update_baw(sc, tid, bf->bf_seqno); | 238 | if (fi->retries) |
239 | ath_tx_update_baw(sc, tid, fi->seqno); | ||
231 | 240 | ||
232 | spin_unlock(&txq->axq_lock); | 241 | spin_unlock(&txq->axq_lock); |
233 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); | 242 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); |
@@ -239,16 +248,15 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq, | |||
239 | } | 248 | } |
240 | 249 | ||
241 | static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq, | 250 | static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq, |
242 | struct ath_buf *bf) | 251 | struct sk_buff *skb) |
243 | { | 252 | { |
244 | struct sk_buff *skb; | 253 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
245 | struct ieee80211_hdr *hdr; | 254 | struct ieee80211_hdr *hdr; |
246 | 255 | ||
247 | bf->bf_state.bf_type |= BUF_RETRY; | ||
248 | bf->bf_retries++; | ||
249 | TX_STAT_INC(txq->axq_qnum, a_retries); | 256 | TX_STAT_INC(txq->axq_qnum, a_retries); |
257 | if (tx_info->control.rates[4].count++ > 0) | ||
258 | return; | ||
250 | 259 | ||
251 | skb = bf->bf_mpdu; | ||
252 | hdr = (struct ieee80211_hdr *)skb->data; | 260 | hdr = (struct ieee80211_hdr *)skb->data; |
253 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY); | 261 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY); |
254 | } | 262 | } |
@@ -298,9 +306,41 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) | |||
298 | return tbf; | 306 | return tbf; |
299 | } | 307 | } |
300 | 308 | ||
309 | static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf, | ||
310 | struct ath_tx_status *ts, int txok, | ||
311 | int *nframes, int *nbad) | ||
312 | { | ||
313 | struct ath_frame_info *fi; | ||
314 | u16 seq_st = 0; | ||
315 | u32 ba[WME_BA_BMP_SIZE >> 5]; | ||
316 | int ba_index; | ||
317 | int isaggr = 0; | ||
318 | |||
319 | *nbad = 0; | ||
320 | *nframes = 0; | ||
321 | |||
322 | isaggr = bf_isaggr(bf); | ||
323 | if (isaggr) { | ||
324 | seq_st = ts->ts_seqnum; | ||
325 | memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3); | ||
326 | } | ||
327 | |||
328 | while (bf) { | ||
329 | fi = get_frame_info(bf->bf_mpdu); | ||
330 | ba_index = ATH_BA_INDEX(seq_st, fi->seqno); | ||
331 | |||
332 | (*nframes)++; | ||
333 | if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index))) | ||
334 | (*nbad)++; | ||
335 | |||
336 | bf = bf->bf_next; | ||
337 | } | ||
338 | } | ||
339 | |||
340 | |||
301 | static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | 341 | static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, |
302 | struct ath_buf *bf, struct list_head *bf_q, | 342 | struct ath_buf *bf, struct list_head *bf_q, |
303 | struct ath_tx_status *ts, int txok) | 343 | struct ath_tx_status *ts, int txok, bool retry) |
304 | { | 344 | { |
305 | struct ath_node *an = NULL; | 345 | struct ath_node *an = NULL; |
306 | struct sk_buff *skb; | 346 | struct sk_buff *skb; |
@@ -316,7 +356,9 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
316 | int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; | 356 | int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; |
317 | bool rc_update = true; | 357 | bool rc_update = true; |
318 | struct ieee80211_tx_rate rates[4]; | 358 | struct ieee80211_tx_rate rates[4]; |
359 | struct ath_frame_info *fi; | ||
319 | int nframes; | 360 | int nframes; |
361 | u8 tidno; | ||
320 | 362 | ||
321 | skb = bf->bf_mpdu; | 363 | skb = bf->bf_mpdu; |
322 | hdr = (struct ieee80211_hdr *)skb->data; | 364 | hdr = (struct ieee80211_hdr *)skb->data; |
@@ -325,7 +367,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
325 | hw = bf->aphy->hw; | 367 | hw = bf->aphy->hw; |
326 | 368 | ||
327 | memcpy(rates, tx_info->control.rates, sizeof(rates)); | 369 | memcpy(rates, tx_info->control.rates, sizeof(rates)); |
328 | nframes = bf->bf_nframes; | ||
329 | 370 | ||
330 | rcu_read_lock(); | 371 | rcu_read_lock(); |
331 | 372 | ||
@@ -342,7 +383,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
342 | !bf->bf_stale || bf_next != NULL) | 383 | !bf->bf_stale || bf_next != NULL) |
343 | list_move_tail(&bf->list, &bf_head); | 384 | list_move_tail(&bf->list, &bf_head); |
344 | 385 | ||
345 | ath_tx_rc_status(bf, ts, 1, 0, false); | 386 | ath_tx_rc_status(bf, ts, 1, 1, 0, false); |
346 | ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, | 387 | ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, |
347 | 0, 0); | 388 | 0, 0); |
348 | 389 | ||
@@ -352,14 +393,15 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
352 | } | 393 | } |
353 | 394 | ||
354 | an = (struct ath_node *)sta->drv_priv; | 395 | an = (struct ath_node *)sta->drv_priv; |
355 | tid = ATH_AN_2_TID(an, bf->bf_tidno); | 396 | tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; |
397 | tid = ATH_AN_2_TID(an, tidno); | ||
356 | 398 | ||
357 | /* | 399 | /* |
358 | * The hardware occasionally sends a tx status for the wrong TID. | 400 | * The hardware occasionally sends a tx status for the wrong TID. |
359 | * In this case, the BA status cannot be considered valid and all | 401 | * In this case, the BA status cannot be considered valid and all |
360 | * subframes need to be retransmitted | 402 | * subframes need to be retransmitted |
361 | */ | 403 | */ |
362 | if (bf->bf_tidno != ts->tid) | 404 | if (tidno != ts->tid) |
363 | txok = false; | 405 | txok = false; |
364 | 406 | ||
365 | isaggr = bf_isaggr(bf); | 407 | isaggr = bf_isaggr(bf); |
@@ -385,15 +427,16 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
385 | INIT_LIST_HEAD(&bf_pending); | 427 | INIT_LIST_HEAD(&bf_pending); |
386 | INIT_LIST_HEAD(&bf_head); | 428 | INIT_LIST_HEAD(&bf_head); |
387 | 429 | ||
388 | nbad = ath_tx_num_badfrms(sc, bf, ts, txok); | 430 | ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad); |
389 | while (bf) { | 431 | while (bf) { |
390 | txfail = txpending = 0; | 432 | txfail = txpending = 0; |
391 | bf_next = bf->bf_next; | 433 | bf_next = bf->bf_next; |
392 | 434 | ||
393 | skb = bf->bf_mpdu; | 435 | skb = bf->bf_mpdu; |
394 | tx_info = IEEE80211_SKB_CB(skb); | 436 | tx_info = IEEE80211_SKB_CB(skb); |
437 | fi = get_frame_info(skb); | ||
395 | 438 | ||
396 | if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) { | 439 | if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, fi->seqno))) { |
397 | /* transmit completion, subframe is | 440 | /* transmit completion, subframe is |
398 | * acked by block ack */ | 441 | * acked by block ack */ |
399 | acked_cnt++; | 442 | acked_cnt++; |
@@ -401,10 +444,9 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
401 | /* transmit completion */ | 444 | /* transmit completion */ |
402 | acked_cnt++; | 445 | acked_cnt++; |
403 | } else { | 446 | } else { |
404 | if (!(tid->state & AGGR_CLEANUP) && | 447 | if (!(tid->state & AGGR_CLEANUP) && retry) { |
405 | !bf_last->bf_tx_aborted) { | 448 | if (fi->retries < ATH_MAX_SW_RETRIES) { |
406 | if (bf->bf_retries < ATH_MAX_SW_RETRIES) { | 449 | ath_tx_set_retry(sc, txq, bf->bf_mpdu); |
407 | ath_tx_set_retry(sc, txq, bf); | ||
408 | txpending = 1; | 450 | txpending = 1; |
409 | } else { | 451 | } else { |
410 | bf->bf_state.bf_type |= BUF_XRETRY; | 452 | bf->bf_state.bf_type |= BUF_XRETRY; |
@@ -442,16 +484,15 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
442 | * block-ack window | 484 | * block-ack window |
443 | */ | 485 | */ |
444 | spin_lock_bh(&txq->axq_lock); | 486 | spin_lock_bh(&txq->axq_lock); |
445 | ath_tx_update_baw(sc, tid, bf->bf_seqno); | 487 | ath_tx_update_baw(sc, tid, fi->seqno); |
446 | spin_unlock_bh(&txq->axq_lock); | 488 | spin_unlock_bh(&txq->axq_lock); |
447 | 489 | ||
448 | if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { | 490 | if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { |
449 | memcpy(tx_info->control.rates, rates, sizeof(rates)); | 491 | memcpy(tx_info->control.rates, rates, sizeof(rates)); |
450 | bf->bf_nframes = nframes; | 492 | ath_tx_rc_status(bf, ts, nframes, nbad, txok, true); |
451 | ath_tx_rc_status(bf, ts, nbad, txok, true); | ||
452 | rc_update = false; | 493 | rc_update = false; |
453 | } else { | 494 | } else { |
454 | ath_tx_rc_status(bf, ts, nbad, txok, false); | 495 | ath_tx_rc_status(bf, ts, nframes, nbad, txok, false); |
455 | } | 496 | } |
456 | 497 | ||
457 | ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, | 498 | ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, |
@@ -470,14 +511,13 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
470 | */ | 511 | */ |
471 | if (!tbf) { | 512 | if (!tbf) { |
472 | spin_lock_bh(&txq->axq_lock); | 513 | spin_lock_bh(&txq->axq_lock); |
473 | ath_tx_update_baw(sc, tid, | 514 | ath_tx_update_baw(sc, tid, fi->seqno); |
474 | bf->bf_seqno); | ||
475 | spin_unlock_bh(&txq->axq_lock); | 515 | spin_unlock_bh(&txq->axq_lock); |
476 | 516 | ||
477 | bf->bf_state.bf_type |= | 517 | bf->bf_state.bf_type |= |
478 | BUF_XRETRY; | 518 | BUF_XRETRY; |
479 | ath_tx_rc_status(bf, ts, nbad, | 519 | ath_tx_rc_status(bf, ts, nframes, |
480 | 0, false); | 520 | nbad, 0, false); |
481 | ath_tx_complete_buf(sc, bf, txq, | 521 | ath_tx_complete_buf(sc, bf, txq, |
482 | &bf_head, | 522 | &bf_head, |
483 | ts, 0, 0); | 523 | ts, 0, 0); |
@@ -611,6 +651,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
611 | u16 minlen; | 651 | u16 minlen; |
612 | u8 flags, rix; | 652 | u8 flags, rix; |
613 | int width, streams, half_gi, ndelim, mindelim; | 653 | int width, streams, half_gi, ndelim, mindelim; |
654 | struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu); | ||
614 | 655 | ||
615 | /* Select standard number of delimiters based on frame length alone */ | 656 | /* Select standard number of delimiters based on frame length alone */ |
616 | ndelim = ATH_AGGR_GET_NDELIM(frmlen); | 657 | ndelim = ATH_AGGR_GET_NDELIM(frmlen); |
@@ -621,7 +662,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
621 | * TODO - this could be improved to be dependent on the rate. | 662 | * TODO - this could be improved to be dependent on the rate. |
622 | * The hardware can keep up at lower rates, but not higher rates | 663 | * The hardware can keep up at lower rates, but not higher rates |
623 | */ | 664 | */ |
624 | if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) | 665 | if (fi->keyix != ATH9K_TXKEYIX_INVALID) |
625 | ndelim += ATH_AGGR_ENCRYPTDELIM; | 666 | ndelim += ATH_AGGR_ENCRYPTDELIM; |
626 | 667 | ||
627 | /* | 668 | /* |
@@ -665,7 +706,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
665 | static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | 706 | static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, |
666 | struct ath_txq *txq, | 707 | struct ath_txq *txq, |
667 | struct ath_atx_tid *tid, | 708 | struct ath_atx_tid *tid, |
668 | struct list_head *bf_q) | 709 | struct list_head *bf_q, |
710 | int *aggr_len) | ||
669 | { | 711 | { |
670 | #define PADBYTES(_len) ((4 - ((_len) % 4)) % 4) | 712 | #define PADBYTES(_len) ((4 - ((_len) % 4)) % 4) |
671 | struct ath_buf *bf, *bf_first, *bf_prev = NULL; | 713 | struct ath_buf *bf, *bf_first, *bf_prev = NULL; |
@@ -674,14 +716,16 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
674 | al_delta, h_baw = tid->baw_size / 2; | 716 | al_delta, h_baw = tid->baw_size / 2; |
675 | enum ATH_AGGR_STATUS status = ATH_AGGR_DONE; | 717 | enum ATH_AGGR_STATUS status = ATH_AGGR_DONE; |
676 | struct ieee80211_tx_info *tx_info; | 718 | struct ieee80211_tx_info *tx_info; |
719 | struct ath_frame_info *fi; | ||
677 | 720 | ||
678 | bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list); | 721 | bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list); |
679 | 722 | ||
680 | do { | 723 | do { |
681 | bf = list_first_entry(&tid->buf_q, struct ath_buf, list); | 724 | bf = list_first_entry(&tid->buf_q, struct ath_buf, list); |
725 | fi = get_frame_info(bf->bf_mpdu); | ||
682 | 726 | ||
683 | /* do not step over block-ack window */ | 727 | /* do not step over block-ack window */ |
684 | if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno)) { | 728 | if (!BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno)) { |
685 | status = ATH_AGGR_BAW_CLOSED; | 729 | status = ATH_AGGR_BAW_CLOSED; |
686 | break; | 730 | break; |
687 | } | 731 | } |
@@ -692,7 +736,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
692 | } | 736 | } |
693 | 737 | ||
694 | /* do not exceed aggregation limit */ | 738 | /* do not exceed aggregation limit */ |
695 | al_delta = ATH_AGGR_DELIM_SZ + bf->bf_frmlen; | 739 | al_delta = ATH_AGGR_DELIM_SZ + fi->framelen; |
696 | 740 | ||
697 | if (nframes && | 741 | if (nframes && |
698 | (aggr_limit < (al + bpad + al_delta + prev_al))) { | 742 | (aggr_limit < (al + bpad + al_delta + prev_al))) { |
@@ -719,14 +763,15 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
719 | * Get the delimiters needed to meet the MPDU | 763 | * Get the delimiters needed to meet the MPDU |
720 | * density for this node. | 764 | * density for this node. |
721 | */ | 765 | */ |
722 | ndelim = ath_compute_num_delims(sc, tid, bf_first, bf->bf_frmlen); | 766 | ndelim = ath_compute_num_delims(sc, tid, bf_first, fi->framelen); |
723 | bpad = PADBYTES(al_delta) + (ndelim << 2); | 767 | bpad = PADBYTES(al_delta) + (ndelim << 2); |
724 | 768 | ||
725 | bf->bf_next = NULL; | 769 | bf->bf_next = NULL; |
726 | ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0); | 770 | ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0); |
727 | 771 | ||
728 | /* link buffers of this frame to the aggregate */ | 772 | /* link buffers of this frame to the aggregate */ |
729 | ath_tx_addto_baw(sc, tid, bf); | 773 | if (!fi->retries) |
774 | ath_tx_addto_baw(sc, tid, fi->seqno); | ||
730 | ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim); | 775 | ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim); |
731 | list_move_tail(&bf->list, bf_q); | 776 | list_move_tail(&bf->list, bf_q); |
732 | if (bf_prev) { | 777 | if (bf_prev) { |
@@ -738,8 +783,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
738 | 783 | ||
739 | } while (!list_empty(&tid->buf_q)); | 784 | } while (!list_empty(&tid->buf_q)); |
740 | 785 | ||
741 | bf_first->bf_al = al; | 786 | *aggr_len = al; |
742 | bf_first->bf_nframes = nframes; | ||
743 | 787 | ||
744 | return status; | 788 | return status; |
745 | #undef PADBYTES | 789 | #undef PADBYTES |
@@ -750,7 +794,9 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
750 | { | 794 | { |
751 | struct ath_buf *bf; | 795 | struct ath_buf *bf; |
752 | enum ATH_AGGR_STATUS status; | 796 | enum ATH_AGGR_STATUS status; |
797 | struct ath_frame_info *fi; | ||
753 | struct list_head bf_q; | 798 | struct list_head bf_q; |
799 | int aggr_len; | ||
754 | 800 | ||
755 | do { | 801 | do { |
756 | if (list_empty(&tid->buf_q)) | 802 | if (list_empty(&tid->buf_q)) |
@@ -758,7 +804,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
758 | 804 | ||
759 | INIT_LIST_HEAD(&bf_q); | 805 | INIT_LIST_HEAD(&bf_q); |
760 | 806 | ||
761 | status = ath_tx_form_aggr(sc, txq, tid, &bf_q); | 807 | status = ath_tx_form_aggr(sc, txq, tid, &bf_q, &aggr_len); |
762 | 808 | ||
763 | /* | 809 | /* |
764 | * no frames picked up to be aggregated; | 810 | * no frames picked up to be aggregated; |
@@ -771,18 +817,20 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
771 | bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list); | 817 | bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list); |
772 | 818 | ||
773 | /* if only one frame, send as non-aggregate */ | 819 | /* if only one frame, send as non-aggregate */ |
774 | if (bf->bf_nframes == 1) { | 820 | if (bf == bf->bf_lastbf) { |
821 | fi = get_frame_info(bf->bf_mpdu); | ||
822 | |||
775 | bf->bf_state.bf_type &= ~BUF_AGGR; | 823 | bf->bf_state.bf_type &= ~BUF_AGGR; |
776 | ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); | 824 | ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); |
777 | ath_buf_set_rate(sc, bf); | 825 | ath_buf_set_rate(sc, bf, fi->framelen); |
778 | ath_tx_txqaddbuf(sc, txq, &bf_q); | 826 | ath_tx_txqaddbuf(sc, txq, &bf_q); |
779 | continue; | 827 | continue; |
780 | } | 828 | } |
781 | 829 | ||
782 | /* setup first desc of aggregate */ | 830 | /* setup first desc of aggregate */ |
783 | bf->bf_state.bf_type |= BUF_AGGR; | 831 | bf->bf_state.bf_type |= BUF_AGGR; |
784 | ath_buf_set_rate(sc, bf); | 832 | ath_buf_set_rate(sc, bf, aggr_len); |
785 | ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al); | 833 | ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, aggr_len); |
786 | 834 | ||
787 | /* anchor last desc of aggregate */ | 835 | /* anchor last desc of aggregate */ |
788 | ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc); | 836 | ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc); |
@@ -1067,8 +1115,6 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
1067 | } | 1115 | } |
1068 | 1116 | ||
1069 | lastbf = bf->bf_lastbf; | 1117 | lastbf = bf->bf_lastbf; |
1070 | if (!retry_tx) | ||
1071 | lastbf->bf_tx_aborted = true; | ||
1072 | 1118 | ||
1073 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 1119 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
1074 | list_cut_position(&bf_head, | 1120 | list_cut_position(&bf_head, |
@@ -1085,7 +1131,8 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
1085 | spin_unlock_bh(&txq->axq_lock); | 1131 | spin_unlock_bh(&txq->axq_lock); |
1086 | 1132 | ||
1087 | if (bf_isampdu(bf)) | 1133 | if (bf_isampdu(bf)) |
1088 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0); | 1134 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0, |
1135 | retry_tx); | ||
1089 | else | 1136 | else |
1090 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); | 1137 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); |
1091 | } | 1138 | } |
@@ -1106,7 +1153,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
1106 | 1153 | ||
1107 | if (bf_isampdu(bf)) | 1154 | if (bf_isampdu(bf)) |
1108 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, | 1155 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, |
1109 | &ts, 0); | 1156 | &ts, 0, retry_tx); |
1110 | else | 1157 | else |
1111 | ath_tx_complete_buf(sc, bf, txq, &bf_head, | 1158 | ath_tx_complete_buf(sc, bf, txq, &bf_head, |
1112 | &ts, 0, 0); | 1159 | &ts, 0, 0); |
@@ -1284,12 +1331,11 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | |||
1284 | } | 1331 | } |
1285 | 1332 | ||
1286 | static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, | 1333 | static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, |
1287 | struct list_head *bf_head, | 1334 | struct ath_buf *bf, struct ath_tx_control *txctl) |
1288 | struct ath_tx_control *txctl) | ||
1289 | { | 1335 | { |
1290 | struct ath_buf *bf; | 1336 | struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu); |
1337 | struct list_head bf_head; | ||
1291 | 1338 | ||
1292 | bf = list_first_entry(bf_head, struct ath_buf, list); | ||
1293 | bf->bf_state.bf_type |= BUF_AMPDU; | 1339 | bf->bf_state.bf_type |= BUF_AMPDU; |
1294 | TX_STAT_INC(txctl->txq->axq_qnum, a_queued); | 1340 | TX_STAT_INC(txctl->txq->axq_qnum, a_queued); |
1295 | 1341 | ||
@@ -1301,56 +1347,47 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
1301 | * - h/w queue depth exceeds low water mark | 1347 | * - h/w queue depth exceeds low water mark |
1302 | */ | 1348 | */ |
1303 | if (!list_empty(&tid->buf_q) || tid->paused || | 1349 | if (!list_empty(&tid->buf_q) || tid->paused || |
1304 | !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) || | 1350 | !BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno) || |
1305 | txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) { | 1351 | txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) { |
1306 | /* | 1352 | /* |
1307 | * Add this frame to software queue for scheduling later | 1353 | * Add this frame to software queue for scheduling later |
1308 | * for aggregation. | 1354 | * for aggregation. |
1309 | */ | 1355 | */ |
1310 | list_move_tail(&bf->list, &tid->buf_q); | 1356 | list_add_tail(&bf->list, &tid->buf_q); |
1311 | ath_tx_queue_tid(txctl->txq, tid); | 1357 | ath_tx_queue_tid(txctl->txq, tid); |
1312 | return; | 1358 | return; |
1313 | } | 1359 | } |
1314 | 1360 | ||
1361 | INIT_LIST_HEAD(&bf_head); | ||
1362 | list_add(&bf->list, &bf_head); | ||
1363 | |||
1315 | /* Add sub-frame to BAW */ | 1364 | /* Add sub-frame to BAW */ |
1316 | ath_tx_addto_baw(sc, tid, bf); | 1365 | if (!fi->retries) |
1366 | ath_tx_addto_baw(sc, tid, fi->seqno); | ||
1317 | 1367 | ||
1318 | /* Queue to h/w without aggregation */ | 1368 | /* Queue to h/w without aggregation */ |
1319 | bf->bf_nframes = 1; | ||
1320 | bf->bf_lastbf = bf; | 1369 | bf->bf_lastbf = bf; |
1321 | ath_buf_set_rate(sc, bf); | 1370 | ath_buf_set_rate(sc, bf, fi->framelen); |
1322 | ath_tx_txqaddbuf(sc, txctl->txq, bf_head); | 1371 | ath_tx_txqaddbuf(sc, txctl->txq, &bf_head); |
1323 | } | 1372 | } |
1324 | 1373 | ||
1325 | static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq, | 1374 | static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, |
1326 | struct ath_atx_tid *tid, | 1375 | struct ath_atx_tid *tid, |
1327 | struct list_head *bf_head) | 1376 | struct list_head *bf_head) |
1328 | { | 1377 | { |
1378 | struct ath_frame_info *fi; | ||
1329 | struct ath_buf *bf; | 1379 | struct ath_buf *bf; |
1330 | 1380 | ||
1331 | bf = list_first_entry(bf_head, struct ath_buf, list); | 1381 | bf = list_first_entry(bf_head, struct ath_buf, list); |
1332 | bf->bf_state.bf_type &= ~BUF_AMPDU; | 1382 | bf->bf_state.bf_type &= ~BUF_AMPDU; |
1333 | 1383 | ||
1334 | /* update starting sequence number for subsequent ADDBA request */ | 1384 | /* update starting sequence number for subsequent ADDBA request */ |
1335 | INCR(tid->seq_start, IEEE80211_SEQ_MAX); | 1385 | if (tid) |
1336 | 1386 | INCR(tid->seq_start, IEEE80211_SEQ_MAX); | |
1337 | bf->bf_nframes = 1; | ||
1338 | bf->bf_lastbf = bf; | ||
1339 | ath_buf_set_rate(sc, bf); | ||
1340 | ath_tx_txqaddbuf(sc, txq, bf_head); | ||
1341 | TX_STAT_INC(txq->axq_qnum, queued); | ||
1342 | } | ||
1343 | |||
1344 | static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, | ||
1345 | struct list_head *bf_head) | ||
1346 | { | ||
1347 | struct ath_buf *bf; | ||
1348 | |||
1349 | bf = list_first_entry(bf_head, struct ath_buf, list); | ||
1350 | 1387 | ||
1351 | bf->bf_lastbf = bf; | 1388 | bf->bf_lastbf = bf; |
1352 | bf->bf_nframes = 1; | 1389 | fi = get_frame_info(bf->bf_mpdu); |
1353 | ath_buf_set_rate(sc, bf); | 1390 | ath_buf_set_rate(sc, bf, fi->framelen); |
1354 | ath_tx_txqaddbuf(sc, txq, bf_head); | 1391 | ath_tx_txqaddbuf(sc, txq, bf_head); |
1355 | TX_STAT_INC(txq->axq_qnum, queued); | 1392 | TX_STAT_INC(txq->axq_qnum, queued); |
1356 | } | 1393 | } |
@@ -1378,40 +1415,52 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) | |||
1378 | return htype; | 1415 | return htype; |
1379 | } | 1416 | } |
1380 | 1417 | ||
1381 | static void assign_aggr_tid_seqno(struct sk_buff *skb, | 1418 | static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, |
1382 | struct ath_buf *bf) | 1419 | int framelen) |
1383 | { | 1420 | { |
1421 | struct ath_wiphy *aphy = hw->priv; | ||
1422 | struct ath_softc *sc = aphy->sc; | ||
1384 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1423 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1424 | struct ieee80211_sta *sta = tx_info->control.sta; | ||
1425 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; | ||
1385 | struct ieee80211_hdr *hdr; | 1426 | struct ieee80211_hdr *hdr; |
1427 | struct ath_frame_info *fi = get_frame_info(skb); | ||
1386 | struct ath_node *an; | 1428 | struct ath_node *an; |
1387 | struct ath_atx_tid *tid; | 1429 | struct ath_atx_tid *tid; |
1388 | __le16 fc; | 1430 | enum ath9k_key_type keytype; |
1389 | u8 *qc; | 1431 | u16 seqno = 0; |
1432 | u8 tidno; | ||
1390 | 1433 | ||
1391 | if (!tx_info->control.sta) | 1434 | keytype = ath9k_cmn_get_hw_crypto_keytype(skb); |
1392 | return; | ||
1393 | 1435 | ||
1394 | an = (struct ath_node *)tx_info->control.sta->drv_priv; | ||
1395 | hdr = (struct ieee80211_hdr *)skb->data; | 1436 | hdr = (struct ieee80211_hdr *)skb->data; |
1396 | fc = hdr->frame_control; | 1437 | if (sta && ieee80211_is_data_qos(hdr->frame_control) && |
1438 | conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) { | ||
1397 | 1439 | ||
1398 | if (ieee80211_is_data_qos(fc)) { | 1440 | an = (struct ath_node *) sta->drv_priv; |
1399 | qc = ieee80211_get_qos_ctl(hdr); | 1441 | tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; |
1400 | bf->bf_tidno = qc[0] & 0xf; | 1442 | |
1443 | /* | ||
1444 | * Override seqno set by upper layer with the one | ||
1445 | * in tx aggregation state. | ||
1446 | */ | ||
1447 | tid = ATH_AN_2_TID(an, tidno); | ||
1448 | seqno = tid->seq_next; | ||
1449 | hdr->seq_ctrl = cpu_to_le16(seqno << IEEE80211_SEQ_SEQ_SHIFT); | ||
1450 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); | ||
1401 | } | 1451 | } |
1402 | 1452 | ||
1403 | /* | 1453 | memset(fi, 0, sizeof(*fi)); |
1404 | * For HT capable stations, we save tidno for later use. | 1454 | if (hw_key) |
1405 | * We also override seqno set by upper layer with the one | 1455 | fi->keyix = hw_key->hw_key_idx; |
1406 | * in tx aggregation state. | 1456 | else |
1407 | */ | 1457 | fi->keyix = ATH9K_TXKEYIX_INVALID; |
1408 | tid = ATH_AN_2_TID(an, bf->bf_tidno); | 1458 | fi->keytype = keytype; |
1409 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); | 1459 | fi->framelen = framelen; |
1410 | bf->bf_seqno = tid->seq_next; | 1460 | fi->seqno = seqno; |
1411 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); | ||
1412 | } | 1461 | } |
1413 | 1462 | ||
1414 | static int setup_tx_flags(struct sk_buff *skb, bool use_ldpc) | 1463 | static int setup_tx_flags(struct sk_buff *skb) |
1415 | { | 1464 | { |
1416 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1465 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1417 | int flags = 0; | 1466 | int flags = 0; |
@@ -1422,7 +1471,7 @@ static int setup_tx_flags(struct sk_buff *skb, bool use_ldpc) | |||
1422 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) | 1471 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) |
1423 | flags |= ATH9K_TXDESC_NOACK; | 1472 | flags |= ATH9K_TXDESC_NOACK; |
1424 | 1473 | ||
1425 | if (use_ldpc) | 1474 | if (tx_info->flags & IEEE80211_TX_CTL_LDPC) |
1426 | flags |= ATH9K_TXDESC_LDPC; | 1475 | flags |= ATH9K_TXDESC_LDPC; |
1427 | 1476 | ||
1428 | return flags; | 1477 | return flags; |
@@ -1434,13 +1483,11 @@ static int setup_tx_flags(struct sk_buff *skb, bool use_ldpc) | |||
1434 | * width - 0 for 20 MHz, 1 for 40 MHz | 1483 | * width - 0 for 20 MHz, 1 for 40 MHz |
1435 | * half_gi - to use 4us v/s 3.6 us for symbol time | 1484 | * half_gi - to use 4us v/s 3.6 us for symbol time |
1436 | */ | 1485 | */ |
1437 | static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, | 1486 | static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen, |
1438 | int width, int half_gi, bool shortPreamble) | 1487 | int width, int half_gi, bool shortPreamble) |
1439 | { | 1488 | { |
1440 | u32 nbits, nsymbits, duration, nsymbols; | 1489 | u32 nbits, nsymbits, duration, nsymbols; |
1441 | int streams, pktlen; | 1490 | int streams; |
1442 | |||
1443 | pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen; | ||
1444 | 1491 | ||
1445 | /* find number of symbols: PLCP + data */ | 1492 | /* find number of symbols: PLCP + data */ |
1446 | streams = HT_RC_2_STREAMS(rix); | 1493 | streams = HT_RC_2_STREAMS(rix); |
@@ -1459,7 +1506,7 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, | |||
1459 | return duration; | 1506 | return duration; |
1460 | } | 1507 | } |
1461 | 1508 | ||
1462 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) | 1509 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) |
1463 | { | 1510 | { |
1464 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1511 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1465 | struct ath9k_11n_rate_series series[4]; | 1512 | struct ath9k_11n_rate_series series[4]; |
@@ -1522,7 +1569,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) | |||
1522 | if (rates[i].flags & IEEE80211_TX_RC_MCS) { | 1569 | if (rates[i].flags & IEEE80211_TX_RC_MCS) { |
1523 | /* MCS rates */ | 1570 | /* MCS rates */ |
1524 | series[i].Rate = rix | 0x80; | 1571 | series[i].Rate = rix | 0x80; |
1525 | series[i].PktDuration = ath_pkt_duration(sc, rix, bf, | 1572 | series[i].PktDuration = ath_pkt_duration(sc, rix, len, |
1526 | is_40, is_sgi, is_sp); | 1573 | is_40, is_sgi, is_sp); |
1527 | if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) | 1574 | if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) |
1528 | series[i].RateFlags |= ATH9K_RATESERIES_STBC; | 1575 | series[i].RateFlags |= ATH9K_RATESERIES_STBC; |
@@ -1546,11 +1593,11 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) | |||
1546 | } | 1593 | } |
1547 | 1594 | ||
1548 | series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah, | 1595 | series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah, |
1549 | phy, rate->bitrate * 100, bf->bf_frmlen, rix, is_sp); | 1596 | phy, rate->bitrate * 100, len, rix, is_sp); |
1550 | } | 1597 | } |
1551 | 1598 | ||
1552 | /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ | 1599 | /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ |
1553 | if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit)) | 1600 | if (bf_isaggr(bf) && (len > sc->sc_ah->caps.rts_aggr_limit)) |
1554 | flags &= ~ATH9K_TXDESC_RTSENA; | 1601 | flags &= ~ATH9K_TXDESC_RTSENA; |
1555 | 1602 | ||
1556 | /* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */ | 1603 | /* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */ |
@@ -1567,67 +1614,29 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) | |||
1567 | ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192); | 1614 | ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192); |
1568 | } | 1615 | } |
1569 | 1616 | ||
1570 | static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | 1617 | static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, |
1571 | struct sk_buff *skb, | 1618 | struct ath_txq *txq, |
1572 | struct ath_tx_control *txctl) | 1619 | struct sk_buff *skb) |
1573 | { | 1620 | { |
1574 | struct ath_wiphy *aphy = hw->priv; | 1621 | struct ath_wiphy *aphy = hw->priv; |
1575 | struct ath_softc *sc = aphy->sc; | 1622 | struct ath_softc *sc = aphy->sc; |
1576 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1623 | struct ath_hw *ah = sc->sc_ah; |
1577 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1624 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1578 | int hdrlen; | 1625 | struct ath_frame_info *fi = get_frame_info(skb); |
1579 | __le16 fc; | 1626 | struct ath_buf *bf; |
1580 | int padpos, padsize; | 1627 | struct ath_desc *ds; |
1581 | bool use_ldpc = false; | 1628 | int frm_type; |
1582 | 1629 | ||
1583 | tx_info->pad[0] = 0; | 1630 | bf = ath_tx_get_buffer(sc); |
1584 | switch (txctl->frame_type) { | 1631 | if (!bf) { |
1585 | case ATH9K_IFT_NOT_INTERNAL: | 1632 | ath_print(common, ATH_DBG_XMIT, "TX buffers are full\n"); |
1586 | break; | 1633 | return NULL; |
1587 | case ATH9K_IFT_PAUSE: | ||
1588 | tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_PAUSE; | ||
1589 | /* fall through */ | ||
1590 | case ATH9K_IFT_UNPAUSE: | ||
1591 | tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_INTERNAL; | ||
1592 | break; | ||
1593 | } | 1634 | } |
1594 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
1595 | fc = hdr->frame_control; | ||
1596 | 1635 | ||
1597 | ATH_TXBUF_RESET(bf); | 1636 | ATH_TXBUF_RESET(bf); |
1598 | 1637 | ||
1599 | bf->aphy = aphy; | 1638 | bf->aphy = aphy; |
1600 | bf->bf_frmlen = skb->len + FCS_LEN; | 1639 | bf->bf_flags = setup_tx_flags(skb); |
1601 | /* Remove the padding size from bf_frmlen, if any */ | ||
1602 | padpos = ath9k_cmn_padpos(hdr->frame_control); | ||
1603 | padsize = padpos & 3; | ||
1604 | if (padsize && skb->len>padpos+padsize) { | ||
1605 | bf->bf_frmlen -= padsize; | ||
1606 | } | ||
1607 | |||
1608 | if (!txctl->paprd && conf_is_ht(&hw->conf)) { | ||
1609 | bf->bf_state.bf_type |= BUF_HT; | ||
1610 | if (tx_info->flags & IEEE80211_TX_CTL_LDPC) | ||
1611 | use_ldpc = true; | ||
1612 | } | ||
1613 | |||
1614 | bf->bf_state.bfs_paprd = txctl->paprd; | ||
1615 | if (txctl->paprd) | ||
1616 | bf->bf_state.bfs_paprd_timestamp = jiffies; | ||
1617 | bf->bf_flags = setup_tx_flags(skb, use_ldpc); | ||
1618 | |||
1619 | bf->bf_keytype = ath9k_cmn_get_hw_crypto_keytype(skb); | ||
1620 | if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) { | ||
1621 | bf->bf_frmlen += tx_info->control.hw_key->icv_len; | ||
1622 | bf->bf_keyix = tx_info->control.hw_key->hw_key_idx; | ||
1623 | } else { | ||
1624 | bf->bf_keyix = ATH9K_TXKEYIX_INVALID; | ||
1625 | } | ||
1626 | |||
1627 | if (ieee80211_is_data_qos(fc) && bf_isht(bf) && | ||
1628 | (sc->sc_flags & SC_OP_TXAGGR)) | ||
1629 | assign_aggr_tid_seqno(skb, bf); | ||
1630 | |||
1631 | bf->bf_mpdu = skb; | 1640 | bf->bf_mpdu = skb; |
1632 | 1641 | ||
1633 | bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, | 1642 | bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, |
@@ -1637,40 +1646,17 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
1637 | bf->bf_buf_addr = 0; | 1646 | bf->bf_buf_addr = 0; |
1638 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | 1647 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, |
1639 | "dma_mapping_error() on TX\n"); | 1648 | "dma_mapping_error() on TX\n"); |
1640 | return -ENOMEM; | 1649 | ath_tx_return_buffer(sc, bf); |
1650 | return NULL; | ||
1641 | } | 1651 | } |
1642 | 1652 | ||
1643 | bf->bf_tx_aborted = false; | ||
1644 | |||
1645 | return 0; | ||
1646 | } | ||
1647 | |||
1648 | /* FIXME: tx power */ | ||
1649 | static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | ||
1650 | struct ath_tx_control *txctl) | ||
1651 | { | ||
1652 | struct sk_buff *skb = bf->bf_mpdu; | ||
1653 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1654 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
1655 | struct ath_node *an = NULL; | ||
1656 | struct list_head bf_head; | ||
1657 | struct ath_desc *ds; | ||
1658 | struct ath_atx_tid *tid; | ||
1659 | struct ath_hw *ah = sc->sc_ah; | ||
1660 | int frm_type; | ||
1661 | __le16 fc; | ||
1662 | |||
1663 | frm_type = get_hw_packet_type(skb); | 1653 | frm_type = get_hw_packet_type(skb); |
1664 | fc = hdr->frame_control; | ||
1665 | |||
1666 | INIT_LIST_HEAD(&bf_head); | ||
1667 | list_add_tail(&bf->list, &bf_head); | ||
1668 | 1654 | ||
1669 | ds = bf->bf_desc; | 1655 | ds = bf->bf_desc; |
1670 | ath9k_hw_set_desc_link(ah, ds, 0); | 1656 | ath9k_hw_set_desc_link(ah, ds, 0); |
1671 | 1657 | ||
1672 | ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER, | 1658 | ath9k_hw_set11n_txdesc(ah, ds, fi->framelen, frm_type, MAX_RATE_POWER, |
1673 | bf->bf_keyix, bf->bf_keytype, bf->bf_flags); | 1659 | fi->keyix, fi->keytype, bf->bf_flags); |
1674 | 1660 | ||
1675 | ath9k_hw_filltxdesc(ah, ds, | 1661 | ath9k_hw_filltxdesc(ah, ds, |
1676 | skb->len, /* segment length */ | 1662 | skb->len, /* segment length */ |
@@ -1678,43 +1664,50 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | |||
1678 | true, /* last segment */ | 1664 | true, /* last segment */ |
1679 | ds, /* first descriptor */ | 1665 | ds, /* first descriptor */ |
1680 | bf->bf_buf_addr, | 1666 | bf->bf_buf_addr, |
1681 | txctl->txq->axq_qnum); | 1667 | txq->axq_qnum); |
1682 | 1668 | ||
1683 | if (bf->bf_state.bfs_paprd) | ||
1684 | ar9003_hw_set_paprd_txdesc(ah, ds, bf->bf_state.bfs_paprd); | ||
1685 | 1669 | ||
1686 | spin_lock_bh(&txctl->txq->axq_lock); | 1670 | return bf; |
1671 | } | ||
1687 | 1672 | ||
1688 | if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) && | 1673 | /* FIXME: tx power */ |
1689 | tx_info->control.sta) { | 1674 | static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, |
1690 | an = (struct ath_node *)tx_info->control.sta->drv_priv; | 1675 | struct ath_tx_control *txctl) |
1691 | tid = ATH_AN_2_TID(an, bf->bf_tidno); | 1676 | { |
1677 | struct sk_buff *skb = bf->bf_mpdu; | ||
1678 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1679 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
1680 | struct list_head bf_head; | ||
1681 | struct ath_atx_tid *tid; | ||
1682 | u8 tidno; | ||
1692 | 1683 | ||
1693 | if (!ieee80211_is_data_qos(fc)) { | 1684 | spin_lock_bh(&txctl->txq->axq_lock); |
1694 | ath_tx_send_normal(sc, txctl->txq, &bf_head); | 1685 | |
1695 | goto tx_done; | 1686 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && txctl->an) { |
1696 | } | 1687 | tidno = ieee80211_get_qos_ctl(hdr)[0] & |
1688 | IEEE80211_QOS_CTL_TID_MASK; | ||
1689 | tid = ATH_AN_2_TID(txctl->an, tidno); | ||
1697 | 1690 | ||
1698 | WARN_ON(tid->ac->txq != txctl->txq); | 1691 | WARN_ON(tid->ac->txq != txctl->txq); |
1699 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | 1692 | /* |
1700 | /* | 1693 | * Try aggregation if it's a unicast data frame |
1701 | * Try aggregation if it's a unicast data frame | 1694 | * and the destination is HT capable. |
1702 | * and the destination is HT capable. | 1695 | */ |
1703 | */ | 1696 | ath_tx_send_ampdu(sc, tid, bf, txctl); |
1704 | ath_tx_send_ampdu(sc, tid, &bf_head, txctl); | ||
1705 | } else { | ||
1706 | /* | ||
1707 | * Send this frame as regular when ADDBA | ||
1708 | * exchange is neither complete nor pending. | ||
1709 | */ | ||
1710 | ath_tx_send_ht_normal(sc, txctl->txq, | ||
1711 | tid, &bf_head); | ||
1712 | } | ||
1713 | } else { | 1697 | } else { |
1714 | ath_tx_send_normal(sc, txctl->txq, &bf_head); | 1698 | INIT_LIST_HEAD(&bf_head); |
1699 | list_add_tail(&bf->list, &bf_head); | ||
1700 | |||
1701 | bf->bf_state.bfs_ftype = txctl->frame_type; | ||
1702 | bf->bf_state.bfs_paprd = txctl->paprd; | ||
1703 | |||
1704 | if (bf->bf_state.bfs_paprd) | ||
1705 | ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc, | ||
1706 | bf->bf_state.bfs_paprd); | ||
1707 | |||
1708 | ath_tx_send_normal(sc, txctl->txq, NULL, &bf_head); | ||
1715 | } | 1709 | } |
1716 | 1710 | ||
1717 | tx_done: | ||
1718 | spin_unlock_bh(&txctl->txq->axq_lock); | 1711 | spin_unlock_bh(&txctl->txq->axq_lock); |
1719 | } | 1712 | } |
1720 | 1713 | ||
@@ -1722,65 +1715,20 @@ tx_done: | |||
1722 | int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | 1715 | int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, |
1723 | struct ath_tx_control *txctl) | 1716 | struct ath_tx_control *txctl) |
1724 | { | 1717 | { |
1718 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
1719 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1720 | struct ieee80211_sta *sta = info->control.sta; | ||
1725 | struct ath_wiphy *aphy = hw->priv; | 1721 | struct ath_wiphy *aphy = hw->priv; |
1726 | struct ath_softc *sc = aphy->sc; | 1722 | struct ath_softc *sc = aphy->sc; |
1727 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1728 | struct ath_txq *txq = txctl->txq; | 1723 | struct ath_txq *txq = txctl->txq; |
1729 | struct ath_buf *bf; | 1724 | struct ath_buf *bf; |
1730 | int q, r; | ||
1731 | |||
1732 | bf = ath_tx_get_buffer(sc); | ||
1733 | if (!bf) { | ||
1734 | ath_print(common, ATH_DBG_XMIT, "TX buffers are full\n"); | ||
1735 | return -1; | ||
1736 | } | ||
1737 | |||
1738 | q = skb_get_queue_mapping(skb); | ||
1739 | r = ath_tx_setup_buffer(hw, bf, skb, txctl); | ||
1740 | if (unlikely(r)) { | ||
1741 | ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n"); | ||
1742 | |||
1743 | /* upon ath_tx_processq() this TX queue will be resumed, we | ||
1744 | * guarantee this will happen by knowing beforehand that | ||
1745 | * we will at least have to run TX completionon one buffer | ||
1746 | * on the queue */ | ||
1747 | spin_lock_bh(&txq->axq_lock); | ||
1748 | if (txq == sc->tx.txq_map[q] && !txq->stopped && | ||
1749 | txq->axq_depth > 1) { | ||
1750 | ath_mac80211_stop_queue(sc, q); | ||
1751 | txq->stopped = 1; | ||
1752 | } | ||
1753 | spin_unlock_bh(&txq->axq_lock); | ||
1754 | |||
1755 | ath_tx_return_buffer(sc, bf); | ||
1756 | |||
1757 | return r; | ||
1758 | } | ||
1759 | |||
1760 | spin_lock_bh(&txq->axq_lock); | ||
1761 | if (txq == sc->tx.txq_map[q] && | ||
1762 | ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { | ||
1763 | ath_mac80211_stop_queue(sc, q); | ||
1764 | txq->stopped = 1; | ||
1765 | } | ||
1766 | spin_unlock_bh(&txq->axq_lock); | ||
1767 | |||
1768 | ath_tx_start_dma(sc, bf, txctl); | ||
1769 | |||
1770 | return 0; | ||
1771 | } | ||
1772 | |||
1773 | void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
1774 | { | ||
1775 | struct ath_wiphy *aphy = hw->priv; | ||
1776 | struct ath_softc *sc = aphy->sc; | ||
1777 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1778 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
1779 | int padpos, padsize; | 1725 | int padpos, padsize; |
1780 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1726 | int frmlen = skb->len + FCS_LEN; |
1781 | struct ath_tx_control txctl; | 1727 | int q; |
1782 | 1728 | ||
1783 | memset(&txctl, 0, sizeof(struct ath_tx_control)); | 1729 | txctl->an = (struct ath_node *)sta->drv_priv; |
1730 | if (info->control.hw_key) | ||
1731 | frmlen += info->control.hw_key->icv_len; | ||
1784 | 1732 | ||
1785 | /* | 1733 | /* |
1786 | * As a temporary workaround, assign seq# here; this will likely need | 1734 | * As a temporary workaround, assign seq# here; this will likely need |
@@ -1797,30 +1745,37 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1797 | /* Add the padding after the header if this is not already done */ | 1745 | /* Add the padding after the header if this is not already done */ |
1798 | padpos = ath9k_cmn_padpos(hdr->frame_control); | 1746 | padpos = ath9k_cmn_padpos(hdr->frame_control); |
1799 | padsize = padpos & 3; | 1747 | padsize = padpos & 3; |
1800 | if (padsize && skb->len>padpos) { | 1748 | if (padsize && skb->len > padpos) { |
1801 | if (skb_headroom(skb) < padsize) { | 1749 | if (skb_headroom(skb) < padsize) |
1802 | ath_print(common, ATH_DBG_XMIT, | 1750 | return -ENOMEM; |
1803 | "TX CABQ padding failed\n"); | 1751 | |
1804 | dev_kfree_skb_any(skb); | ||
1805 | return; | ||
1806 | } | ||
1807 | skb_push(skb, padsize); | 1752 | skb_push(skb, padsize); |
1808 | memmove(skb->data, skb->data + padsize, padpos); | 1753 | memmove(skb->data, skb->data + padsize, padpos); |
1809 | } | 1754 | } |
1810 | 1755 | ||
1811 | txctl.txq = sc->beacon.cabq; | 1756 | setup_frame_info(hw, skb, frmlen); |
1812 | 1757 | ||
1813 | ath_print(common, ATH_DBG_XMIT, | 1758 | /* |
1814 | "transmitting CABQ packet, skb: %p\n", skb); | 1759 | * At this point, the vif, hw_key and sta pointers in the tx control |
1760 | * info are no longer valid (overwritten by the ath_frame_info data. | ||
1761 | */ | ||
1815 | 1762 | ||
1816 | if (ath_tx_start(hw, skb, &txctl) != 0) { | 1763 | bf = ath_tx_setup_buffer(hw, txctl->txq, skb); |
1817 | ath_print(common, ATH_DBG_XMIT, "CABQ TX failed\n"); | 1764 | if (unlikely(!bf)) |
1818 | goto exit; | 1765 | return -ENOMEM; |
1766 | |||
1767 | q = skb_get_queue_mapping(skb); | ||
1768 | spin_lock_bh(&txq->axq_lock); | ||
1769 | if (txq == sc->tx.txq_map[q] && | ||
1770 | ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { | ||
1771 | ath_mac80211_stop_queue(sc, q); | ||
1772 | txq->stopped = 1; | ||
1819 | } | 1773 | } |
1774 | spin_unlock_bh(&txq->axq_lock); | ||
1820 | 1775 | ||
1821 | return; | 1776 | ath_tx_start_dma(sc, bf, txctl); |
1822 | exit: | 1777 | |
1823 | dev_kfree_skb_any(skb); | 1778 | return 0; |
1824 | } | 1779 | } |
1825 | 1780 | ||
1826 | /*****************/ | 1781 | /*****************/ |
@@ -1828,7 +1783,7 @@ exit: | |||
1828 | /*****************/ | 1783 | /*****************/ |
1829 | 1784 | ||
1830 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | 1785 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, |
1831 | struct ath_wiphy *aphy, int tx_flags, | 1786 | struct ath_wiphy *aphy, int tx_flags, int ftype, |
1832 | struct ath_txq *txq) | 1787 | struct ath_txq *txq) |
1833 | { | 1788 | { |
1834 | struct ieee80211_hw *hw = sc->hw; | 1789 | struct ieee80211_hw *hw = sc->hw; |
@@ -1872,8 +1827,8 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1872 | PS_WAIT_FOR_TX_ACK)); | 1827 | PS_WAIT_FOR_TX_ACK)); |
1873 | } | 1828 | } |
1874 | 1829 | ||
1875 | if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) | 1830 | if (unlikely(ftype)) |
1876 | ath9k_tx_status(hw, skb); | 1831 | ath9k_tx_status(hw, skb, ftype); |
1877 | else { | 1832 | else { |
1878 | q = skb_get_queue_mapping(skb); | 1833 | q = skb_get_queue_mapping(skb); |
1879 | if (txq == sc->tx.txq_map[q]) { | 1834 | if (txq == sc->tx.txq_map[q]) { |
@@ -1909,15 +1864,14 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | |||
1909 | bf->bf_buf_addr = 0; | 1864 | bf->bf_buf_addr = 0; |
1910 | 1865 | ||
1911 | if (bf->bf_state.bfs_paprd) { | 1866 | if (bf->bf_state.bfs_paprd) { |
1912 | if (time_after(jiffies, | 1867 | if (!sc->paprd_pending) |
1913 | bf->bf_state.bfs_paprd_timestamp + | ||
1914 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT))) | ||
1915 | dev_kfree_skb_any(skb); | 1868 | dev_kfree_skb_any(skb); |
1916 | else | 1869 | else |
1917 | complete(&sc->paprd_complete); | 1870 | complete(&sc->paprd_complete); |
1918 | } else { | 1871 | } else { |
1919 | ath_debug_stat_tx(sc, bf, ts); | 1872 | ath_debug_stat_tx(sc, bf, ts); |
1920 | ath_tx_complete(sc, skb, bf->aphy, tx_flags, txq); | 1873 | ath_tx_complete(sc, skb, bf->aphy, tx_flags, |
1874 | bf->bf_state.bfs_ftype, txq); | ||
1921 | } | 1875 | } |
1922 | /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't | 1876 | /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't |
1923 | * accidentally reference it later. | 1877 | * accidentally reference it later. |
@@ -1932,42 +1886,15 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | |||
1932 | spin_unlock_irqrestore(&sc->tx.txbuflock, flags); | 1886 | spin_unlock_irqrestore(&sc->tx.txbuflock, flags); |
1933 | } | 1887 | } |
1934 | 1888 | ||
1935 | static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, | ||
1936 | struct ath_tx_status *ts, int txok) | ||
1937 | { | ||
1938 | u16 seq_st = 0; | ||
1939 | u32 ba[WME_BA_BMP_SIZE >> 5]; | ||
1940 | int ba_index; | ||
1941 | int nbad = 0; | ||
1942 | int isaggr = 0; | ||
1943 | |||
1944 | if (bf->bf_lastbf->bf_tx_aborted) | ||
1945 | return 0; | ||
1946 | |||
1947 | isaggr = bf_isaggr(bf); | ||
1948 | if (isaggr) { | ||
1949 | seq_st = ts->ts_seqnum; | ||
1950 | memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3); | ||
1951 | } | ||
1952 | |||
1953 | while (bf) { | ||
1954 | ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno); | ||
1955 | if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index))) | ||
1956 | nbad++; | ||
1957 | |||
1958 | bf = bf->bf_next; | ||
1959 | } | ||
1960 | |||
1961 | return nbad; | ||
1962 | } | ||
1963 | |||
1964 | static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, | 1889 | static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, |
1965 | int nbad, int txok, bool update_rc) | 1890 | int nframes, int nbad, int txok, bool update_rc) |
1966 | { | 1891 | { |
1967 | struct sk_buff *skb = bf->bf_mpdu; | 1892 | struct sk_buff *skb = bf->bf_mpdu; |
1968 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1893 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1969 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1894 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1970 | struct ieee80211_hw *hw = bf->aphy->hw; | 1895 | struct ieee80211_hw *hw = bf->aphy->hw; |
1896 | struct ath_softc *sc = bf->aphy->sc; | ||
1897 | struct ath_hw *ah = sc->sc_ah; | ||
1971 | u8 i, tx_rateindex; | 1898 | u8 i, tx_rateindex; |
1972 | 1899 | ||
1973 | if (txok) | 1900 | if (txok) |
@@ -1981,22 +1908,32 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, | |||
1981 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) { | 1908 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) { |
1982 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU; | 1909 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU; |
1983 | 1910 | ||
1984 | BUG_ON(nbad > bf->bf_nframes); | 1911 | BUG_ON(nbad > nframes); |
1985 | 1912 | ||
1986 | tx_info->status.ampdu_len = bf->bf_nframes; | 1913 | tx_info->status.ampdu_len = nframes; |
1987 | tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; | 1914 | tx_info->status.ampdu_ack_len = nframes - nbad; |
1988 | } | 1915 | } |
1989 | 1916 | ||
1990 | if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && | 1917 | if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && |
1991 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { | 1918 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { |
1992 | if (ieee80211_is_data(hdr->frame_control)) { | 1919 | /* |
1993 | if (ts->ts_flags & | 1920 | * If an underrun error is seen assume it as an excessive |
1994 | (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN)) | 1921 | * retry only if max frame trigger level has been reached |
1995 | tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN; | 1922 | * (2 KB for single stream, and 4 KB for dual stream). |
1996 | if ((ts->ts_status & ATH9K_TXERR_XRETRY) || | 1923 | * Adjust the long retry as if the frame was tried |
1997 | (ts->ts_status & ATH9K_TXERR_FIFO)) | 1924 | * hw->max_rate_tries times to affect how rate control updates |
1998 | tx_info->pad[0] |= ATH_TX_INFO_XRETRY; | 1925 | * PER for the failed rate. |
1999 | } | 1926 | * In case of congestion on the bus penalizing this type of |
1927 | * underruns should help hardware actually transmit new frames | ||
1928 | * successfully by eventually preferring slower rates. | ||
1929 | * This itself should also alleviate congestion on the bus. | ||
1930 | */ | ||
1931 | if (ieee80211_is_data(hdr->frame_control) && | ||
1932 | (ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN | | ||
1933 | ATH9K_TX_DELIM_UNDERRUN)) && | ||
1934 | ah->tx_trig_level >= sc->sc_ah->caps.tx_triglevel_max) | ||
1935 | tx_info->status.rates[tx_rateindex].count = | ||
1936 | hw->max_rate_tries; | ||
2000 | } | 1937 | } |
2001 | 1938 | ||
2002 | for (i = tx_rateindex + 1; i < hw->max_rates; i++) { | 1939 | for (i = tx_rateindex + 1; i < hw->max_rates; i++) { |
@@ -2103,13 +2040,14 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2103 | */ | 2040 | */ |
2104 | if (ts.ts_status & ATH9K_TXERR_XRETRY) | 2041 | if (ts.ts_status & ATH9K_TXERR_XRETRY) |
2105 | bf->bf_state.bf_type |= BUF_XRETRY; | 2042 | bf->bf_state.bf_type |= BUF_XRETRY; |
2106 | ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true); | 2043 | ath_tx_rc_status(bf, &ts, 1, txok ? 0 : 1, txok, true); |
2107 | } | 2044 | } |
2108 | 2045 | ||
2109 | qnum = skb_get_queue_mapping(bf->bf_mpdu); | 2046 | qnum = skb_get_queue_mapping(bf->bf_mpdu); |
2110 | 2047 | ||
2111 | if (bf_isampdu(bf)) | 2048 | if (bf_isampdu(bf)) |
2112 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok); | 2049 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok, |
2050 | true); | ||
2113 | else | 2051 | else |
2114 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0); | 2052 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0); |
2115 | 2053 | ||
@@ -2225,13 +2163,14 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2225 | if (!bf_isampdu(bf)) { | 2163 | if (!bf_isampdu(bf)) { |
2226 | if (txs.ts_status & ATH9K_TXERR_XRETRY) | 2164 | if (txs.ts_status & ATH9K_TXERR_XRETRY) |
2227 | bf->bf_state.bf_type |= BUF_XRETRY; | 2165 | bf->bf_state.bf_type |= BUF_XRETRY; |
2228 | ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true); | 2166 | ath_tx_rc_status(bf, &txs, 1, txok ? 0 : 1, txok, true); |
2229 | } | 2167 | } |
2230 | 2168 | ||
2231 | qnum = skb_get_queue_mapping(bf->bf_mpdu); | 2169 | qnum = skb_get_queue_mapping(bf->bf_mpdu); |
2232 | 2170 | ||
2233 | if (bf_isampdu(bf)) | 2171 | if (bf_isampdu(bf)) |
2234 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok); | 2172 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, |
2173 | txok, true); | ||
2235 | else | 2174 | else |
2236 | ath_tx_complete_buf(sc, bf, txq, &bf_head, | 2175 | ath_tx_complete_buf(sc, bf, txq, &bf_head, |
2237 | &txs, txok, 0); | 2176 | &txs, txok, 0); |