aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2010-11-14 09:20:13 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-11-17 16:19:29 -0500
commit2d42efc44e38d3a8b2bf30e34559036bb6541672 (patch)
tree42bd46218aa2f0caa35f418768387164c50e8338
parent04caf863750bc7e042d1e8d57e5ce9d6326ab435 (diff)
ath9k: store frame information used by aggregation inside the skb tx info
Since the pointers after the rates in the tx info cannot be used anymore after frames have been queued, this area can be used to store information that was previously stored in the ath_buf. With these changes, we can delay the ath_buf assignment in the aggregation code until aggregates are formed. That will not only make it possible to simplify DMA descriptor setup to do less rewriting of uncached memory, but will also make it easier to move aggregation out of the core of the ath9k tx path. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h15
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c203
2 files changed, 109 insertions, 109 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index d12123a6576b..be9c8d3b3337 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -89,20 +89,16 @@ struct ath_config {
89 * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX) 89 * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX)
90 * @BUF_AGGR: Indicates whether the buffer can be aggregated 90 * @BUF_AGGR: Indicates whether the buffer can be aggregated
91 * (used in aggregation scheduling) 91 * (used in aggregation scheduling)
92 * @BUF_RETRY: Indicates whether the buffer is retried
93 * @BUF_XRETRY: To denote excessive retries of the buffer 92 * @BUF_XRETRY: To denote excessive retries of the buffer
94 */ 93 */
95enum buffer_type { 94enum buffer_type {
96 BUF_AMPDU = BIT(2), 95 BUF_AMPDU = BIT(2),
97 BUF_AGGR = BIT(3), 96 BUF_AGGR = BIT(3),
98 BUF_RETRY = BIT(4),
99 BUF_XRETRY = BIT(5), 97 BUF_XRETRY = BIT(5),
100}; 98};
101 99
102#define bf_retries bf_state.bfs_retries
103#define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU) 100#define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU)
104#define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR) 101#define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR)
105#define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY)
106#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY) 102#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY)
107 103
108#define ATH_TXSTATUS_RING_SIZE 64 104#define ATH_TXSTATUS_RING_SIZE 64
@@ -207,8 +203,15 @@ struct ath_atx_ac {
207 struct list_head tid_q; 203 struct list_head tid_q;
208}; 204};
209 205
206struct ath_frame_info {
207 int framelen;
208 u32 keyix;
209 enum ath9k_key_type keytype;
210 u8 retries;
211 u16 seqno;
212};
213
210struct ath_buf_state { 214struct ath_buf_state {
211 int bfs_retries;
212 u8 bf_type; 215 u8 bf_type;
213 u8 bfs_paprd; 216 u8 bfs_paprd;
214 enum ath9k_internal_frame_type bfs_ftype; 217 enum ath9k_internal_frame_type bfs_ftype;
@@ -260,9 +263,9 @@ struct ath_node {
260 263
261struct ath_tx_control { 264struct ath_tx_control {
262 struct ath_txq *txq; 265 struct ath_txq *txq;
266 struct ath_node *an;
263 int if_id; 267 int if_id;
264 enum ath9k_internal_frame_type frame_type; 268 enum ath9k_internal_frame_type frame_type;
265 int frmlen;
266 u8 paprd; 269 u8 paprd;
267}; 270};
268 271
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 5eeffaea551e..c63e283ff97f 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -50,7 +50,7 @@ static u16 bits_per_symbol[][2] = {
50 50
51static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, 51static 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, int frmlen); 53 struct list_head *bf_head);
54static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, 54static 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);
@@ -138,30 +138,12 @@ unlock:
138 spin_unlock_bh(&txq->axq_lock); 138 spin_unlock_bh(&txq->axq_lock);
139} 139}
140 140
141static u16 ath_frame_seqno(struct sk_buff *skb) 141static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
142{
143 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
144 return le16_to_cpu(hdr->seq_ctrl) >> IEEE80211_SEQ_SEQ_SHIFT;
145}
146
147static int ath_frame_len(struct sk_buff *skb)
148{ 142{
149 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 143 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
150 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 144 BUILD_BUG_ON(sizeof(struct ath_frame_info) >
151 int frmlen = skb->len + FCS_LEN; 145 sizeof(tx_info->rate_driver_data));
152 int padpos, padsize; 146 return (struct ath_frame_info *) &tx_info->rate_driver_data[0];
153
154 /* Remove the padding size, if any */
155 padpos = ath9k_cmn_padpos(hdr->frame_control);
156 padsize = padpos & 3;
157
158 if (padsize && skb->len > padpos + padsize)
159 frmlen -= padsize;
160
161 if (tx_info->control.hw_key)
162 frmlen += tx_info->control.hw_key->icv_len;
163
164 return frmlen;
165} 147}
166 148
167static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) 149static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
@@ -170,6 +152,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
170 struct ath_buf *bf; 152 struct ath_buf *bf;
171 struct list_head bf_head; 153 struct list_head bf_head;
172 struct ath_tx_status ts; 154 struct ath_tx_status ts;
155 struct ath_frame_info *fi;
173 156
174 INIT_LIST_HEAD(&bf_head); 157 INIT_LIST_HEAD(&bf_head);
175 158
@@ -180,12 +163,12 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
180 bf = list_first_entry(&tid->buf_q, struct ath_buf, list); 163 bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
181 list_move_tail(&bf->list, &bf_head); 164 list_move_tail(&bf->list, &bf_head);
182 165
183 if (bf_isretried(bf)) { 166 fi = get_frame_info(bf->bf_mpdu);
184 ath_tx_update_baw(sc, tid, ath_frame_seqno(bf->bf_mpdu)); 167 if (fi->retries) {
168 ath_tx_update_baw(sc, tid, fi->seqno);
185 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); 169 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
186 } else { 170 } else {
187 ath_tx_send_normal(sc, txq, tid, &bf_head, 171 ath_tx_send_normal(sc, txq, tid, &bf_head);
188 ath_frame_len(bf->bf_mpdu));
189 } 172 }
190 } 173 }
191 174
@@ -237,7 +220,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
237 struct ath_buf *bf; 220 struct ath_buf *bf;
238 struct list_head bf_head; 221 struct list_head bf_head;
239 struct ath_tx_status ts; 222 struct ath_tx_status ts;
240 u16 bf_seqno; 223 struct ath_frame_info *fi;
241 224
242 memset(&ts, 0, sizeof(ts)); 225 memset(&ts, 0, sizeof(ts));
243 INIT_LIST_HEAD(&bf_head); 226 INIT_LIST_HEAD(&bf_head);
@@ -249,9 +232,9 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
249 bf = list_first_entry(&tid->buf_q, struct ath_buf, list); 232 bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
250 list_move_tail(&bf->list, &bf_head); 233 list_move_tail(&bf->list, &bf_head);
251 234
252 bf_seqno = ath_frame_seqno(bf->bf_mpdu); 235 fi = get_frame_info(bf->bf_mpdu);
253 if (bf_isretried(bf)) 236 if (fi->retries)
254 ath_tx_update_baw(sc, tid, bf_seqno); 237 ath_tx_update_baw(sc, tid, fi->seqno);
255 238
256 spin_unlock(&txq->axq_lock); 239 spin_unlock(&txq->axq_lock);
257 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); 240 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
@@ -263,16 +246,15 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
263} 246}
264 247
265static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq, 248static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
266 struct ath_buf *bf) 249 struct sk_buff *skb)
267{ 250{
268 struct sk_buff *skb; 251 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
269 struct ieee80211_hdr *hdr; 252 struct ieee80211_hdr *hdr;
270 253
271 bf->bf_state.bf_type |= BUF_RETRY;
272 bf->bf_retries++;
273 TX_STAT_INC(txq->axq_qnum, a_retries); 254 TX_STAT_INC(txq->axq_qnum, a_retries);
255 if (tx_info->control.rates[4].count++ > 0)
256 return;
274 257
275 skb = bf->bf_mpdu;
276 hdr = (struct ieee80211_hdr *)skb->data; 258 hdr = (struct ieee80211_hdr *)skb->data;
277 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY); 259 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
278} 260}
@@ -326,6 +308,7 @@ static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf,
326 struct ath_tx_status *ts, int txok, 308 struct ath_tx_status *ts, int txok,
327 int *nframes, int *nbad) 309 int *nframes, int *nbad)
328{ 310{
311 struct ath_frame_info *fi;
329 u16 seq_st = 0; 312 u16 seq_st = 0;
330 u32 ba[WME_BA_BMP_SIZE >> 5]; 313 u32 ba[WME_BA_BMP_SIZE >> 5];
331 int ba_index; 314 int ba_index;
@@ -341,7 +324,8 @@ static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf,
341 } 324 }
342 325
343 while (bf) { 326 while (bf) {
344 ba_index = ATH_BA_INDEX(seq_st, ath_frame_seqno(bf->bf_mpdu)); 327 fi = get_frame_info(bf->bf_mpdu);
328 ba_index = ATH_BA_INDEX(seq_st, fi->seqno);
345 329
346 (*nframes)++; 330 (*nframes)++;
347 if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index))) 331 if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
@@ -370,7 +354,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
370 int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; 354 int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
371 bool rc_update = true; 355 bool rc_update = true;
372 struct ieee80211_tx_rate rates[4]; 356 struct ieee80211_tx_rate rates[4];
373 u16 bf_seqno; 357 struct ath_frame_info *fi;
374 int nframes; 358 int nframes;
375 u8 tidno; 359 u8 tidno;
376 360
@@ -448,9 +432,9 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
448 432
449 skb = bf->bf_mpdu; 433 skb = bf->bf_mpdu;
450 tx_info = IEEE80211_SKB_CB(skb); 434 tx_info = IEEE80211_SKB_CB(skb);
451 bf_seqno = ath_frame_seqno(skb); 435 fi = get_frame_info(skb);
452 436
453 if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf_seqno))) { 437 if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, fi->seqno))) {
454 /* transmit completion, subframe is 438 /* transmit completion, subframe is
455 * acked by block ack */ 439 * acked by block ack */
456 acked_cnt++; 440 acked_cnt++;
@@ -459,8 +443,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
459 acked_cnt++; 443 acked_cnt++;
460 } else { 444 } else {
461 if (!(tid->state & AGGR_CLEANUP) && retry) { 445 if (!(tid->state & AGGR_CLEANUP) && retry) {
462 if (bf->bf_retries < ATH_MAX_SW_RETRIES) { 446 if (fi->retries < ATH_MAX_SW_RETRIES) {
463 ath_tx_set_retry(sc, txq, bf); 447 ath_tx_set_retry(sc, txq, bf->bf_mpdu);
464 txpending = 1; 448 txpending = 1;
465 } else { 449 } else {
466 bf->bf_state.bf_type |= BUF_XRETRY; 450 bf->bf_state.bf_type |= BUF_XRETRY;
@@ -498,7 +482,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
498 * block-ack window 482 * block-ack window
499 */ 483 */
500 spin_lock_bh(&txq->axq_lock); 484 spin_lock_bh(&txq->axq_lock);
501 ath_tx_update_baw(sc, tid, bf_seqno); 485 ath_tx_update_baw(sc, tid, fi->seqno);
502 spin_unlock_bh(&txq->axq_lock); 486 spin_unlock_bh(&txq->axq_lock);
503 487
504 if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { 488 if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
@@ -525,8 +509,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
525 */ 509 */
526 if (!tbf) { 510 if (!tbf) {
527 spin_lock_bh(&txq->axq_lock); 511 spin_lock_bh(&txq->axq_lock);
528 ath_tx_update_baw(sc, tid, 512 ath_tx_update_baw(sc, tid, fi->seqno);
529 bf_seqno);
530 spin_unlock_bh(&txq->axq_lock); 513 spin_unlock_bh(&txq->axq_lock);
531 514
532 bf->bf_state.bf_type |= 515 bf->bf_state.bf_type |=
@@ -666,6 +649,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
666 u16 minlen; 649 u16 minlen;
667 u8 flags, rix; 650 u8 flags, rix;
668 int width, streams, half_gi, ndelim, mindelim; 651 int width, streams, half_gi, ndelim, mindelim;
652 struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
669 653
670 /* Select standard number of delimiters based on frame length alone */ 654 /* Select standard number of delimiters based on frame length alone */
671 ndelim = ATH_AGGR_GET_NDELIM(frmlen); 655 ndelim = ATH_AGGR_GET_NDELIM(frmlen);
@@ -676,7 +660,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
676 * TODO - this could be improved to be dependent on the rate. 660 * TODO - this could be improved to be dependent on the rate.
677 * The hardware can keep up at lower rates, but not higher rates 661 * The hardware can keep up at lower rates, but not higher rates
678 */ 662 */
679 if (tx_info->control.hw_key) 663 if (fi->keyix != ATH9K_TXKEYIX_INVALID)
680 ndelim += ATH_AGGR_ENCRYPTDELIM; 664 ndelim += ATH_AGGR_ENCRYPTDELIM;
681 665
682 /* 666 /*
@@ -730,17 +714,16 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
730 al_delta, h_baw = tid->baw_size / 2; 714 al_delta, h_baw = tid->baw_size / 2;
731 enum ATH_AGGR_STATUS status = ATH_AGGR_DONE; 715 enum ATH_AGGR_STATUS status = ATH_AGGR_DONE;
732 struct ieee80211_tx_info *tx_info; 716 struct ieee80211_tx_info *tx_info;
733 int frmlen; 717 struct ath_frame_info *fi;
734 u16 bf_seqno;
735 718
736 bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list); 719 bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list);
737 720
738 do { 721 do {
739 bf = list_first_entry(&tid->buf_q, struct ath_buf, list); 722 bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
740 bf_seqno = ath_frame_seqno(bf->bf_mpdu); 723 fi = get_frame_info(bf->bf_mpdu);
741 724
742 /* do not step over block-ack window */ 725 /* do not step over block-ack window */
743 if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf_seqno)) { 726 if (!BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno)) {
744 status = ATH_AGGR_BAW_CLOSED; 727 status = ATH_AGGR_BAW_CLOSED;
745 break; 728 break;
746 } 729 }
@@ -751,8 +734,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
751 } 734 }
752 735
753 /* do not exceed aggregation limit */ 736 /* do not exceed aggregation limit */
754 frmlen = ath_frame_len(bf->bf_mpdu); 737 al_delta = ATH_AGGR_DELIM_SZ + fi->framelen;
755 al_delta = ATH_AGGR_DELIM_SZ + frmlen;
756 738
757 if (nframes && 739 if (nframes &&
758 (aggr_limit < (al + bpad + al_delta + prev_al))) { 740 (aggr_limit < (al + bpad + al_delta + prev_al))) {
@@ -779,15 +761,15 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
779 * Get the delimiters needed to meet the MPDU 761 * Get the delimiters needed to meet the MPDU
780 * density for this node. 762 * density for this node.
781 */ 763 */
782 ndelim = ath_compute_num_delims(sc, tid, bf_first, frmlen); 764 ndelim = ath_compute_num_delims(sc, tid, bf_first, fi->framelen);
783 bpad = PADBYTES(al_delta) + (ndelim << 2); 765 bpad = PADBYTES(al_delta) + (ndelim << 2);
784 766
785 bf->bf_next = NULL; 767 bf->bf_next = NULL;
786 ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0); 768 ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0);
787 769
788 /* link buffers of this frame to the aggregate */ 770 /* link buffers of this frame to the aggregate */
789 if (!bf_isretried(bf)) 771 if (!fi->retries)
790 ath_tx_addto_baw(sc, tid, bf_seqno); 772 ath_tx_addto_baw(sc, tid, fi->seqno);
791 ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim); 773 ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
792 list_move_tail(&bf->list, bf_q); 774 list_move_tail(&bf->list, bf_q);
793 if (bf_prev) { 775 if (bf_prev) {
@@ -810,6 +792,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
810{ 792{
811 struct ath_buf *bf; 793 struct ath_buf *bf;
812 enum ATH_AGGR_STATUS status; 794 enum ATH_AGGR_STATUS status;
795 struct ath_frame_info *fi;
813 struct list_head bf_q; 796 struct list_head bf_q;
814 int aggr_len; 797 int aggr_len;
815 798
@@ -833,9 +816,11 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
833 816
834 /* if only one frame, send as non-aggregate */ 817 /* if only one frame, send as non-aggregate */
835 if (bf == bf->bf_lastbf) { 818 if (bf == bf->bf_lastbf) {
819 fi = get_frame_info(bf->bf_mpdu);
820
836 bf->bf_state.bf_type &= ~BUF_AGGR; 821 bf->bf_state.bf_type &= ~BUF_AGGR;
837 ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); 822 ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc);
838 ath_buf_set_rate(sc, bf, ath_frame_len(bf->bf_mpdu)); 823 ath_buf_set_rate(sc, bf, fi->framelen);
839 ath_tx_txqaddbuf(sc, txq, &bf_q); 824 ath_tx_txqaddbuf(sc, txq, &bf_q);
840 continue; 825 continue;
841 } 826 }
@@ -1346,12 +1331,11 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
1346static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, 1331static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
1347 struct ath_buf *bf, struct ath_tx_control *txctl) 1332 struct ath_buf *bf, struct ath_tx_control *txctl)
1348{ 1333{
1334 struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
1349 struct list_head bf_head; 1335 struct list_head bf_head;
1350 u16 bf_seqno;
1351 1336
1352 bf->bf_state.bf_type |= BUF_AMPDU; 1337 bf->bf_state.bf_type |= BUF_AMPDU;
1353 TX_STAT_INC(txctl->txq->axq_qnum, a_queued); 1338 TX_STAT_INC(txctl->txq->axq_qnum, a_queued);
1354 bf_seqno = ath_frame_seqno(bf->bf_mpdu);
1355 1339
1356 /* 1340 /*
1357 * Do not queue to h/w when any of the following conditions is true: 1341 * Do not queue to h/w when any of the following conditions is true:
@@ -1361,7 +1345,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
1361 * - h/w queue depth exceeds low water mark 1345 * - h/w queue depth exceeds low water mark
1362 */ 1346 */
1363 if (!list_empty(&tid->buf_q) || tid->paused || 1347 if (!list_empty(&tid->buf_q) || tid->paused ||
1364 !BAW_WITHIN(tid->seq_start, tid->baw_size, bf_seqno) || 1348 !BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno) ||
1365 txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) { 1349 txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
1366 /* 1350 /*
1367 * Add this frame to software queue for scheduling later 1351 * Add this frame to software queue for scheduling later
@@ -1376,19 +1360,20 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
1376 list_add(&bf->list, &bf_head); 1360 list_add(&bf->list, &bf_head);
1377 1361
1378 /* Add sub-frame to BAW */ 1362 /* Add sub-frame to BAW */
1379 if (!bf_isretried(bf)) 1363 if (!fi->retries)
1380 ath_tx_addto_baw(sc, tid, bf_seqno); 1364 ath_tx_addto_baw(sc, tid, fi->seqno);
1381 1365
1382 /* Queue to h/w without aggregation */ 1366 /* Queue to h/w without aggregation */
1383 bf->bf_lastbf = bf; 1367 bf->bf_lastbf = bf;
1384 ath_buf_set_rate(sc, bf, txctl->frmlen); 1368 ath_buf_set_rate(sc, bf, fi->framelen);
1385 ath_tx_txqaddbuf(sc, txctl->txq, &bf_head); 1369 ath_tx_txqaddbuf(sc, txctl->txq, &bf_head);
1386} 1370}
1387 1371
1388static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, 1372static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
1389 struct ath_atx_tid *tid, 1373 struct ath_atx_tid *tid,
1390 struct list_head *bf_head, int frmlen) 1374 struct list_head *bf_head)
1391{ 1375{
1376 struct ath_frame_info *fi;
1392 struct ath_buf *bf; 1377 struct ath_buf *bf;
1393 1378
1394 bf = list_first_entry(bf_head, struct ath_buf, list); 1379 bf = list_first_entry(bf_head, struct ath_buf, list);
@@ -1399,7 +1384,8 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
1399 INCR(tid->seq_start, IEEE80211_SEQ_MAX); 1384 INCR(tid->seq_start, IEEE80211_SEQ_MAX);
1400 1385
1401 bf->bf_lastbf = bf; 1386 bf->bf_lastbf = bf;
1402 ath_buf_set_rate(sc, bf, frmlen); 1387 fi = get_frame_info(bf->bf_mpdu);
1388 ath_buf_set_rate(sc, bf, fi->framelen);
1403 ath_tx_txqaddbuf(sc, txq, bf_head); 1389 ath_tx_txqaddbuf(sc, txq, bf_head);
1404 TX_STAT_INC(txq->axq_qnum, queued); 1390 TX_STAT_INC(txq->axq_qnum, queued);
1405} 1391}
@@ -1427,30 +1413,49 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
1427 return htype; 1413 return htype;
1428} 1414}
1429 1415
1430static void assign_aggr_tid_seqno(struct sk_buff *skb) 1416static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb,
1417 int framelen)
1431{ 1418{
1419 struct ath_wiphy *aphy = hw->priv;
1420 struct ath_softc *sc = aphy->sc;
1432 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1421 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1422 struct ieee80211_sta *sta = tx_info->control.sta;
1423 struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
1433 struct ieee80211_hdr *hdr; 1424 struct ieee80211_hdr *hdr;
1425 struct ath_frame_info *fi = get_frame_info(skb);
1434 struct ath_node *an; 1426 struct ath_node *an;
1435 struct ath_atx_tid *tid; 1427 struct ath_atx_tid *tid;
1436 __le16 fc; 1428 enum ath9k_key_type keytype;
1429 u16 seqno = 0;
1437 u8 tidno; 1430 u8 tidno;
1438 1431
1439 if (!tx_info->control.sta) 1432 keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
1440 return;
1441 1433
1442 an = (struct ath_node *)tx_info->control.sta->drv_priv;
1443 hdr = (struct ieee80211_hdr *)skb->data; 1434 hdr = (struct ieee80211_hdr *)skb->data;
1444 fc = hdr->frame_control; 1435 if (sta && ieee80211_is_data_qos(hdr->frame_control) &&
1445 tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; 1436 conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) {
1446 1437
1447 /* 1438 an = (struct ath_node *) sta->drv_priv;
1448 * Override seqno set by upper layer with the one 1439 tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
1449 * in tx aggregation state. 1440
1450 */ 1441 /*
1451 tid = ATH_AN_2_TID(an, tidno); 1442 * Override seqno set by upper layer with the one
1452 hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); 1443 * in tx aggregation state.
1453 INCR(tid->seq_next, IEEE80211_SEQ_MAX); 1444 */
1445 tid = ATH_AN_2_TID(an, tidno);
1446 seqno = tid->seq_next;
1447 hdr->seq_ctrl = cpu_to_le16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
1448 INCR(tid->seq_next, IEEE80211_SEQ_MAX);
1449 }
1450
1451 memset(fi, 0, sizeof(*fi));
1452 if (hw_key)
1453 fi->keyix = hw_key->hw_key_idx;
1454 else
1455 fi->keyix = ATH9K_TXKEYIX_INVALID;
1456 fi->keytype = keytype;
1457 fi->framelen = framelen;
1458 fi->seqno = seqno;
1454} 1459}
1455 1460
1456static int setup_tx_flags(struct sk_buff *skb) 1461static int setup_tx_flags(struct sk_buff *skb)
@@ -1609,18 +1614,15 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
1609 1614
1610static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, 1615static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw,
1611 struct ath_txq *txq, 1616 struct ath_txq *txq,
1612 struct sk_buff *skb, int frmlen) 1617 struct sk_buff *skb)
1613{ 1618{
1614 struct ath_wiphy *aphy = hw->priv; 1619 struct ath_wiphy *aphy = hw->priv;
1615 struct ath_softc *sc = aphy->sc; 1620 struct ath_softc *sc = aphy->sc;
1616 struct ath_hw *ah = sc->sc_ah; 1621 struct ath_hw *ah = sc->sc_ah;
1617 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1622 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1618 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1623 struct ath_frame_info *fi = get_frame_info(skb);
1619 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb;
1620 struct ath_buf *bf; 1624 struct ath_buf *bf;
1621 struct ath_desc *ds; 1625 struct ath_desc *ds;
1622 enum ath9k_key_type keytype;
1623 u32 keyix;
1624 int frm_type; 1626 int frm_type;
1625 1627
1626 bf = ath_tx_get_buffer(sc); 1628 bf = ath_tx_get_buffer(sc);
@@ -1631,10 +1633,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw,
1631 1633
1632 ATH_TXBUF_RESET(bf); 1634 ATH_TXBUF_RESET(bf);
1633 1635
1634 if (ieee80211_is_data_qos(hdr->frame_control) &&
1635 conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR))
1636 assign_aggr_tid_seqno(skb);
1637
1638 bf->aphy = aphy; 1636 bf->aphy = aphy;
1639 bf->bf_flags = setup_tx_flags(skb); 1637 bf->bf_flags = setup_tx_flags(skb);
1640 bf->bf_mpdu = skb; 1638 bf->bf_mpdu = skb;
@@ -1655,14 +1653,8 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw,
1655 ds = bf->bf_desc; 1653 ds = bf->bf_desc;
1656 ath9k_hw_set_desc_link(ah, ds, 0); 1654 ath9k_hw_set_desc_link(ah, ds, 0);
1657 1655
1658 keytype = ath9k_cmn_get_hw_crypto_keytype(skb); 1656 ath9k_hw_set11n_txdesc(ah, ds, fi->framelen, frm_type, MAX_RATE_POWER,
1659 if (tx_info->control.hw_key) 1657 fi->keyix, fi->keytype, bf->bf_flags);
1660 keyix = tx_info->control.hw_key->hw_key_idx;
1661 else
1662 keyix = ATH9K_TXKEYIX_INVALID;
1663
1664 ath9k_hw_set11n_txdesc(ah, ds, frmlen, frm_type, MAX_RATE_POWER,
1665 keyix, keytype, bf->bf_flags);
1666 1658
1667 ath9k_hw_filltxdesc(ah, ds, 1659 ath9k_hw_filltxdesc(ah, ds,
1668 skb->len, /* segment length */ 1660 skb->len, /* segment length */
@@ -1683,18 +1675,16 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
1683 struct sk_buff *skb = bf->bf_mpdu; 1675 struct sk_buff *skb = bf->bf_mpdu;
1684 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1676 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1685 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 1677 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1686 struct ath_node *an = NULL;
1687 struct list_head bf_head; 1678 struct list_head bf_head;
1688 struct ath_atx_tid *tid; 1679 struct ath_atx_tid *tid;
1689 u8 tidno; 1680 u8 tidno;
1690 1681
1691 spin_lock_bh(&txctl->txq->axq_lock); 1682 spin_lock_bh(&txctl->txq->axq_lock);
1692 1683
1693 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tx_info->control.sta) { 1684 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && txctl->an) {
1694 an = (struct ath_node *)tx_info->control.sta->drv_priv;
1695 tidno = ieee80211_get_qos_ctl(hdr)[0] & 1685 tidno = ieee80211_get_qos_ctl(hdr)[0] &
1696 IEEE80211_QOS_CTL_TID_MASK; 1686 IEEE80211_QOS_CTL_TID_MASK;
1697 tid = ATH_AN_2_TID(an, tidno); 1687 tid = ATH_AN_2_TID(txctl->an, tidno);
1698 1688
1699 WARN_ON(tid->ac->txq != txctl->txq); 1689 WARN_ON(tid->ac->txq != txctl->txq);
1700 /* 1690 /*
@@ -1713,7 +1703,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
1713 ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc, 1703 ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc,
1714 bf->bf_state.bfs_paprd); 1704 bf->bf_state.bfs_paprd);
1715 1705
1716 ath_tx_send_normal(sc, txctl->txq, NULL, &bf_head, txctl->frmlen); 1706 ath_tx_send_normal(sc, txctl->txq, NULL, &bf_head);
1717 } 1707 }
1718 1708
1719 spin_unlock_bh(&txctl->txq->axq_lock); 1709 spin_unlock_bh(&txctl->txq->axq_lock);
@@ -1725,6 +1715,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1725{ 1715{
1726 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 1716 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1727 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1717 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1718 struct ieee80211_sta *sta = info->control.sta;
1728 struct ath_wiphy *aphy = hw->priv; 1719 struct ath_wiphy *aphy = hw->priv;
1729 struct ath_softc *sc = aphy->sc; 1720 struct ath_softc *sc = aphy->sc;
1730 struct ath_txq *txq = txctl->txq; 1721 struct ath_txq *txq = txctl->txq;
@@ -1733,11 +1724,10 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1733 int frmlen = skb->len + FCS_LEN; 1724 int frmlen = skb->len + FCS_LEN;
1734 int q; 1725 int q;
1735 1726
1727 txctl->an = (struct ath_node *)sta->drv_priv;
1736 if (info->control.hw_key) 1728 if (info->control.hw_key)
1737 frmlen += info->control.hw_key->icv_len; 1729 frmlen += info->control.hw_key->icv_len;
1738 1730
1739 txctl->frmlen = frmlen;
1740
1741 /* 1731 /*
1742 * As a temporary workaround, assign seq# here; this will likely need 1732 * As a temporary workaround, assign seq# here; this will likely need
1743 * to be cleaned up to work better with Beacon transmission and virtual 1733 * to be cleaned up to work better with Beacon transmission and virtual
@@ -1761,7 +1751,14 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1761 memmove(skb->data, skb->data + padsize, padpos); 1751 memmove(skb->data, skb->data + padsize, padpos);
1762 } 1752 }
1763 1753
1764 bf = ath_tx_setup_buffer(hw, txctl->txq, skb, frmlen); 1754 setup_frame_info(hw, skb, frmlen);
1755
1756 /*
1757 * At this point, the vif, hw_key and sta pointers in the tx control
1758 * info are no longer valid (overwritten by the ath_frame_info data.
1759 */
1760
1761 bf = ath_tx_setup_buffer(hw, txctl->txq, skb);
1765 if (unlikely(!bf)) 1762 if (unlikely(!bf))
1766 return -ENOMEM; 1763 return -ENOMEM;
1767 1764