aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2010-03-29 23:07:11 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-03-31 14:46:41 -0400
commitdb1a052b73f7c97f9e8b21f3f19a92313ed2acb1 (patch)
tree47bb94db727c4ec11d6eb9cfdba5a89f5833eb68
parente65054b64ff6b89380a7f546c9eebf862e679646 (diff)
ath9k: split out access to tx status information
This patch passes in a pointer to the ath_tx_status data structure for functions that need it, instead of letting them grab it directly from the ath_desc struct. This is useful for making it possible to allocate the intermediate tx status data separately. 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.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c16
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c75
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c107
6 files changed, 104 insertions, 103 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 83c7ea4c007f..a581c365da6f 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -178,9 +178,6 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
178#define BAW_WITHIN(_start, _bawsz, _seqno) \ 178#define BAW_WITHIN(_start, _bawsz, _seqno) \
179 ((((_seqno) - (_start)) & 4095) < (_bawsz)) 179 ((((_seqno) - (_start)) & 4095) < (_bawsz))
180 180
181#define ATH_DS_BA_SEQ(_ds) ((_ds)->ds_us.tx.ts_seqnum)
182#define ATH_DS_BA_BITMAP(_ds) (&(_ds)->ds_us.tx.ba_low)
183#define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
184#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)]) 181#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)])
185 182
186#define ATH_TX_COMPLETE_POLL_INT 1000 183#define ATH_TX_COMPLETE_POLL_INT 1000
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 42d2a506845a..6a4ef9bcff33 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -556,10 +556,8 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
556} 556}
557 557
558void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, 558void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
559 struct ath_buf *bf) 559 struct ath_buf *bf, struct ath_tx_status *ts)
560{ 560{
561 struct ath_desc *ds = bf->bf_desc;
562
563 if (bf_isampdu(bf)) { 561 if (bf_isampdu(bf)) {
564 if (bf_isxretried(bf)) 562 if (bf_isxretried(bf))
565 TX_STAT_INC(txq->axq_qnum, a_xretries); 563 TX_STAT_INC(txq->axq_qnum, a_xretries);
@@ -569,17 +567,17 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
569 TX_STAT_INC(txq->axq_qnum, completed); 567 TX_STAT_INC(txq->axq_qnum, completed);
570 } 568 }
571 569
572 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FIFO) 570 if (ts->ts_status & ATH9K_TXERR_FIFO)
573 TX_STAT_INC(txq->axq_qnum, fifo_underrun); 571 TX_STAT_INC(txq->axq_qnum, fifo_underrun);
574 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XTXOP) 572 if (ts->ts_status & ATH9K_TXERR_XTXOP)
575 TX_STAT_INC(txq->axq_qnum, xtxop); 573 TX_STAT_INC(txq->axq_qnum, xtxop);
576 if (ds->ds_txstat.ts_status & ATH9K_TXERR_TIMER_EXPIRED) 574 if (ts->ts_status & ATH9K_TXERR_TIMER_EXPIRED)
577 TX_STAT_INC(txq->axq_qnum, timer_exp); 575 TX_STAT_INC(txq->axq_qnum, timer_exp);
578 if (ds->ds_txstat.ts_flags & ATH9K_TX_DESC_CFG_ERR) 576 if (ts->ts_flags & ATH9K_TX_DESC_CFG_ERR)
579 TX_STAT_INC(txq->axq_qnum, desc_cfg_err); 577 TX_STAT_INC(txq->axq_qnum, desc_cfg_err);
580 if (ds->ds_txstat.ts_flags & ATH9K_TX_DATA_UNDERRUN) 578 if (ts->ts_flags & ATH9K_TX_DATA_UNDERRUN)
581 TX_STAT_INC(txq->axq_qnum, data_underrun); 579 TX_STAT_INC(txq->axq_qnum, data_underrun);
582 if (ds->ds_txstat.ts_flags & ATH9K_TX_DELIM_UNDERRUN) 580 if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN)
583 TX_STAT_INC(txq->axq_qnum, delim_underrun); 581 TX_STAT_INC(txq->axq_qnum, delim_underrun);
584} 582}
585 583
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 86780e68b31e..789c67791092 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -167,7 +167,7 @@ void ath9k_debug_remove_root(void);
167void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); 167void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
168void ath_debug_stat_rc(struct ath_softc *sc, int final_rate); 168void ath_debug_stat_rc(struct ath_softc *sc, int final_rate);
169void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, 169void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
170 struct ath_buf *bf); 170 struct ath_buf *bf, struct ath_tx_status *ts);
171void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf); 171void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf);
172void ath_debug_stat_retries(struct ath_softc *sc, int rix, 172void ath_debug_stat_retries(struct ath_softc *sc, int rix,
173 int xretries, int retries, u8 per); 173 int xretries, int retries, u8 per);
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 7af823a1527d..08ad6dfa976d 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -246,79 +246,80 @@ void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
246} 246}
247EXPORT_SYMBOL(ath9k_hw_cleartxdesc); 247EXPORT_SYMBOL(ath9k_hw_cleartxdesc);
248 248
249int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds) 249int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds,
250 struct ath_tx_status *ts)
250{ 251{
251 struct ar5416_desc *ads = AR5416DESC(ds); 252 struct ar5416_desc *ads = AR5416DESC(ds);
252 253
253 if ((ads->ds_txstatus9 & AR_TxDone) == 0) 254 if ((ads->ds_txstatus9 & AR_TxDone) == 0)
254 return -EINPROGRESS; 255 return -EINPROGRESS;
255 256
256 ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum); 257 ts->ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
257 ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp; 258 ts->ts_tstamp = ads->AR_SendTimestamp;
258 ds->ds_txstat.ts_status = 0; 259 ts->ts_status = 0;
259 ds->ds_txstat.ts_flags = 0; 260 ts->ts_flags = 0;
260 261
261 if (ads->ds_txstatus1 & AR_FrmXmitOK) 262 if (ads->ds_txstatus1 & AR_FrmXmitOK)
262 ds->ds_txstat.ts_status |= ATH9K_TX_ACKED; 263 ts->ts_status |= ATH9K_TX_ACKED;
263 if (ads->ds_txstatus1 & AR_ExcessiveRetries) 264 if (ads->ds_txstatus1 & AR_ExcessiveRetries)
264 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY; 265 ts->ts_status |= ATH9K_TXERR_XRETRY;
265 if (ads->ds_txstatus1 & AR_Filtered) 266 if (ads->ds_txstatus1 & AR_Filtered)
266 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT; 267 ts->ts_status |= ATH9K_TXERR_FILT;
267 if (ads->ds_txstatus1 & AR_FIFOUnderrun) { 268 if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
268 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO; 269 ts->ts_status |= ATH9K_TXERR_FIFO;
269 ath9k_hw_updatetxtriglevel(ah, true); 270 ath9k_hw_updatetxtriglevel(ah, true);
270 } 271 }
271 if (ads->ds_txstatus9 & AR_TxOpExceeded) 272 if (ads->ds_txstatus9 & AR_TxOpExceeded)
272 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP; 273 ts->ts_status |= ATH9K_TXERR_XTXOP;
273 if (ads->ds_txstatus1 & AR_TxTimerExpired) 274 if (ads->ds_txstatus1 & AR_TxTimerExpired)
274 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED; 275 ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
275 276
276 if (ads->ds_txstatus1 & AR_DescCfgErr) 277 if (ads->ds_txstatus1 & AR_DescCfgErr)
277 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR; 278 ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
278 if (ads->ds_txstatus1 & AR_TxDataUnderrun) { 279 if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
279 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN; 280 ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
280 ath9k_hw_updatetxtriglevel(ah, true); 281 ath9k_hw_updatetxtriglevel(ah, true);
281 } 282 }
282 if (ads->ds_txstatus1 & AR_TxDelimUnderrun) { 283 if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
283 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN; 284 ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
284 ath9k_hw_updatetxtriglevel(ah, true); 285 ath9k_hw_updatetxtriglevel(ah, true);
285 } 286 }
286 if (ads->ds_txstatus0 & AR_TxBaStatus) { 287 if (ads->ds_txstatus0 & AR_TxBaStatus) {
287 ds->ds_txstat.ts_flags |= ATH9K_TX_BA; 288 ts->ts_flags |= ATH9K_TX_BA;
288 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow; 289 ts->ba_low = ads->AR_BaBitmapLow;
289 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh; 290 ts->ba_high = ads->AR_BaBitmapHigh;
290 } 291 }
291 292
292 ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx); 293 ts->ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
293 switch (ds->ds_txstat.ts_rateindex) { 294 switch (ts->ts_rateindex) {
294 case 0: 295 case 0:
295 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0); 296 ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
296 break; 297 break;
297 case 1: 298 case 1:
298 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1); 299 ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
299 break; 300 break;
300 case 2: 301 case 2:
301 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2); 302 ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
302 break; 303 break;
303 case 3: 304 case 3:
304 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3); 305 ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
305 break; 306 break;
306 } 307 }
307 308
308 ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined); 309 ts->ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
309 ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00); 310 ts->ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
310 ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01); 311 ts->ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
311 ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02); 312 ts->ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
312 ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10); 313 ts->ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
313 ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11); 314 ts->ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
314 ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12); 315 ts->ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
315 ds->ds_txstat.evm0 = ads->AR_TxEVM0; 316 ts->evm0 = ads->AR_TxEVM0;
316 ds->ds_txstat.evm1 = ads->AR_TxEVM1; 317 ts->evm1 = ads->AR_TxEVM1;
317 ds->ds_txstat.evm2 = ads->AR_TxEVM2; 318 ts->evm2 = ads->AR_TxEVM2;
318 ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt); 319 ts->ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
319 ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt); 320 ts->ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
320 ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt); 321 ts->ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
321 ds->ds_txstat.ts_antenna = 0; 322 ts->ts_antenna = 0;
322 323
323 return 0; 324 return 0;
324} 325}
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index a5e543bd2271..27529204d91e 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -241,7 +241,6 @@ struct ath_desc {
241 void *ds_vdata; 241 void *ds_vdata;
242} __packed; 242} __packed;
243 243
244#define ds_txstat ds_us.tx
245#define ds_rxstat ds_us.rx 244#define ds_rxstat ds_us.rx
246#define ds_stat ds_us.stats 245#define ds_stat ds_us.stats
247 246
@@ -702,7 +701,8 @@ void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
702 u32 segLen, bool firstSeg, 701 u32 segLen, bool firstSeg,
703 bool lastSeg, const struct ath_desc *ds0); 702 bool lastSeg, const struct ath_desc *ds0);
704void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds); 703void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds);
705int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds); 704int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds,
705 struct ath_tx_status *ts);
706void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds, 706void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
707 u32 pktLen, enum ath9k_pkt_type type, u32 txPower, 707 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
708 u32 keyIx, enum ath9k_key_type keyType, u32 flags); 708 u32 keyIx, enum ath9k_key_type keyType, u32 flags);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 8359362fc51c..9d5d102b23bd 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -59,15 +59,14 @@ static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
59 struct ath_atx_tid *tid, 59 struct ath_atx_tid *tid,
60 struct list_head *bf_head); 60 struct list_head *bf_head);
61static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, 61static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
62 struct ath_txq *txq, 62 struct ath_txq *txq, struct list_head *bf_q,
63 struct list_head *bf_q, 63 struct ath_tx_status *ts, int txok, int sendbar);
64 int txok, int sendbar);
65static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, 64static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
66 struct list_head *head); 65 struct list_head *head);
67static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf); 66static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf);
68static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, 67static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
69 int txok); 68 struct ath_tx_status *ts, int txok);
70static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, 69static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
71 int nbad, int txok, bool update_rc); 70 int nbad, int txok, bool update_rc);
72 71
73enum { 72enum {
@@ -223,6 +222,9 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
223{ 222{
224 struct ath_buf *bf; 223 struct ath_buf *bf;
225 struct list_head bf_head; 224 struct list_head bf_head;
225 struct ath_tx_status ts;
226
227 memset(&ts, 0, sizeof(ts));
226 INIT_LIST_HEAD(&bf_head); 228 INIT_LIST_HEAD(&bf_head);
227 229
228 for (;;) { 230 for (;;) {
@@ -236,7 +238,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
236 ath_tx_update_baw(sc, tid, bf->bf_seqno); 238 ath_tx_update_baw(sc, tid, bf->bf_seqno);
237 239
238 spin_unlock(&txq->axq_lock); 240 spin_unlock(&txq->axq_lock);
239 ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0); 241 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
240 spin_lock(&txq->axq_lock); 242 spin_lock(&txq->axq_lock);
241 } 243 }
242 244
@@ -286,7 +288,7 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
286 288
287static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, 289static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
288 struct ath_buf *bf, struct list_head *bf_q, 290 struct ath_buf *bf, struct list_head *bf_q,
289 int txok) 291 struct ath_tx_status *ts, int txok)
290{ 292{
291 struct ath_node *an = NULL; 293 struct ath_node *an = NULL;
292 struct sk_buff *skb; 294 struct sk_buff *skb;
@@ -296,7 +298,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
296 struct ieee80211_tx_info *tx_info; 298 struct ieee80211_tx_info *tx_info;
297 struct ath_atx_tid *tid = NULL; 299 struct ath_atx_tid *tid = NULL;
298 struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; 300 struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
299 struct ath_desc *ds = bf_last->bf_desc;
300 struct list_head bf_head, bf_pending; 301 struct list_head bf_head, bf_pending;
301 u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0; 302 u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0;
302 u32 ba[WME_BA_BMP_SIZE >> 5]; 303 u32 ba[WME_BA_BMP_SIZE >> 5];
@@ -325,10 +326,9 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
325 memset(ba, 0, WME_BA_BMP_SIZE >> 3); 326 memset(ba, 0, WME_BA_BMP_SIZE >> 3);
326 327
327 if (isaggr && txok) { 328 if (isaggr && txok) {
328 if (ATH_DS_TX_BA(ds)) { 329 if (ts->ts_flags & ATH9K_TX_BA) {
329 seq_st = ATH_DS_BA_SEQ(ds); 330 seq_st = ts->ts_seqnum;
330 memcpy(ba, ATH_DS_BA_BITMAP(ds), 331 memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3);
331 WME_BA_BMP_SIZE >> 3);
332 } else { 332 } else {
333 /* 333 /*
334 * AR5416 can become deaf/mute when BA 334 * AR5416 can become deaf/mute when BA
@@ -345,7 +345,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
345 INIT_LIST_HEAD(&bf_pending); 345 INIT_LIST_HEAD(&bf_pending);
346 INIT_LIST_HEAD(&bf_head); 346 INIT_LIST_HEAD(&bf_head);
347 347
348 nbad = ath_tx_num_badfrms(sc, bf, txok); 348 nbad = ath_tx_num_badfrms(sc, bf, ts, txok);
349 while (bf) { 349 while (bf) {
350 txfail = txpending = 0; 350 txfail = txpending = 0;
351 bf_next = bf->bf_next; 351 bf_next = bf->bf_next;
@@ -359,7 +359,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
359 acked_cnt++; 359 acked_cnt++;
360 } else { 360 } else {
361 if (!(tid->state & AGGR_CLEANUP) && 361 if (!(tid->state & AGGR_CLEANUP) &&
362 ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) { 362 ts->ts_flags != ATH9K_TX_SW_ABORTED) {
363 if (bf->bf_retries < ATH_MAX_SW_RETRIES) { 363 if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
364 ath_tx_set_retry(sc, txq, bf); 364 ath_tx_set_retry(sc, txq, bf);
365 txpending = 1; 365 txpending = 1;
@@ -402,13 +402,14 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
402 spin_unlock_bh(&txq->axq_lock); 402 spin_unlock_bh(&txq->axq_lock);
403 403
404 if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { 404 if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
405 ath_tx_rc_status(bf, ds, nbad, txok, true); 405 ath_tx_rc_status(bf, ts, nbad, txok, true);
406 rc_update = false; 406 rc_update = false;
407 } else { 407 } else {
408 ath_tx_rc_status(bf, ds, nbad, txok, false); 408 ath_tx_rc_status(bf, ts, nbad, txok, false);
409 } 409 }
410 410
411 ath_tx_complete_buf(sc, bf, txq, &bf_head, !txfail, sendbar); 411 ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
412 !txfail, sendbar);
412 } else { 413 } else {
413 /* retry the un-acked ones */ 414 /* retry the un-acked ones */
414 if (bf->bf_next == NULL && bf_last->bf_stale) { 415 if (bf->bf_next == NULL && bf_last->bf_stale) {
@@ -426,10 +427,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
426 spin_unlock_bh(&txq->axq_lock); 427 spin_unlock_bh(&txq->axq_lock);
427 428
428 bf->bf_state.bf_type |= BUF_XRETRY; 429 bf->bf_state.bf_type |= BUF_XRETRY;
429 ath_tx_rc_status(bf, ds, nbad, 430 ath_tx_rc_status(bf, ts, nbad,
430 0, false); 431 0, false);
431 ath_tx_complete_buf(sc, bf, txq, 432 ath_tx_complete_buf(sc, bf, txq,
432 &bf_head, 0, 0); 433 &bf_head, ts, 0, 0);
433 break; 434 break;
434 } 435 }
435 436
@@ -752,8 +753,11 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
752 struct ath_node *an = (struct ath_node *)sta->drv_priv; 753 struct ath_node *an = (struct ath_node *)sta->drv_priv;
753 struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); 754 struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
754 struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum]; 755 struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
756 struct ath_tx_status ts;
755 struct ath_buf *bf; 757 struct ath_buf *bf;
756 struct list_head bf_head; 758 struct list_head bf_head;
759
760 memset(&ts, 0, sizeof(ts));
757 INIT_LIST_HEAD(&bf_head); 761 INIT_LIST_HEAD(&bf_head);
758 762
759 if (txtid->state & AGGR_CLEANUP) 763 if (txtid->state & AGGR_CLEANUP)
@@ -780,7 +784,7 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
780 } 784 }
781 list_move_tail(&bf->list, &bf_head); 785 list_move_tail(&bf->list, &bf_head);
782 ath_tx_update_baw(sc, txtid, bf->bf_seqno); 786 ath_tx_update_baw(sc, txtid, bf->bf_seqno);
783 ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0); 787 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
784 } 788 }
785 spin_unlock_bh(&txq->axq_lock); 789 spin_unlock_bh(&txq->axq_lock);
786 790
@@ -1028,6 +1032,11 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
1028{ 1032{
1029 struct ath_buf *bf, *lastbf; 1033 struct ath_buf *bf, *lastbf;
1030 struct list_head bf_head; 1034 struct list_head bf_head;
1035 struct ath_tx_status ts;
1036
1037 memset(&ts, 0, sizeof(ts));
1038 if (!retry_tx)
1039 ts.ts_flags = ATH9K_TX_SW_ABORTED;
1031 1040
1032 INIT_LIST_HEAD(&bf_head); 1041 INIT_LIST_HEAD(&bf_head);
1033 1042
@@ -1053,9 +1062,6 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
1053 } 1062 }
1054 1063
1055 lastbf = bf->bf_lastbf; 1064 lastbf = bf->bf_lastbf;
1056 if (!retry_tx)
1057 lastbf->bf_desc->ds_txstat.ts_flags =
1058 ATH9K_TX_SW_ABORTED;
1059 1065
1060 /* remove ath_buf's of the same mpdu from txq */ 1066 /* remove ath_buf's of the same mpdu from txq */
1061 list_cut_position(&bf_head, &txq->axq_q, &lastbf->list); 1067 list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
@@ -1064,9 +1070,9 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
1064 spin_unlock_bh(&txq->axq_lock); 1070 spin_unlock_bh(&txq->axq_lock);
1065 1071
1066 if (bf_isampdu(bf)) 1072 if (bf_isampdu(bf))
1067 ath_tx_complete_aggr(sc, txq, bf, &bf_head, 0); 1073 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0);
1068 else 1074 else
1069 ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0); 1075 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
1070 } 1076 }
1071 1077
1072 spin_lock_bh(&txq->axq_lock); 1078 spin_lock_bh(&txq->axq_lock);
@@ -1871,9 +1877,8 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1871} 1877}
1872 1878
1873static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, 1879static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1874 struct ath_txq *txq, 1880 struct ath_txq *txq, struct list_head *bf_q,
1875 struct list_head *bf_q, 1881 struct ath_tx_status *ts, int txok, int sendbar)
1876 int txok, int sendbar)
1877{ 1882{
1878 struct sk_buff *skb = bf->bf_mpdu; 1883 struct sk_buff *skb = bf->bf_mpdu;
1879 unsigned long flags; 1884 unsigned long flags;
@@ -1891,7 +1896,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1891 1896
1892 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); 1897 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
1893 ath_tx_complete(sc, skb, bf->aphy, tx_flags); 1898 ath_tx_complete(sc, skb, bf->aphy, tx_flags);
1894 ath_debug_stat_tx(sc, txq, bf); 1899 ath_debug_stat_tx(sc, txq, bf, ts);
1895 1900
1896 /* 1901 /*
1897 * Return the list of ath_buf of this mpdu to free queue 1902 * Return the list of ath_buf of this mpdu to free queue
@@ -1902,23 +1907,21 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1902} 1907}
1903 1908
1904static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, 1909static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
1905 int txok) 1910 struct ath_tx_status *ts, int txok)
1906{ 1911{
1907 struct ath_buf *bf_last = bf->bf_lastbf;
1908 struct ath_desc *ds = bf_last->bf_desc;
1909 u16 seq_st = 0; 1912 u16 seq_st = 0;
1910 u32 ba[WME_BA_BMP_SIZE >> 5]; 1913 u32 ba[WME_BA_BMP_SIZE >> 5];
1911 int ba_index; 1914 int ba_index;
1912 int nbad = 0; 1915 int nbad = 0;
1913 int isaggr = 0; 1916 int isaggr = 0;
1914 1917
1915 if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED) 1918 if (ts->ts_flags == ATH9K_TX_SW_ABORTED)
1916 return 0; 1919 return 0;
1917 1920
1918 isaggr = bf_isaggr(bf); 1921 isaggr = bf_isaggr(bf);
1919 if (isaggr) { 1922 if (isaggr) {
1920 seq_st = ATH_DS_BA_SEQ(ds); 1923 seq_st = ts->ts_seqnum;
1921 memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3); 1924 memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3);
1922 } 1925 }
1923 1926
1924 while (bf) { 1927 while (bf) {
@@ -1932,7 +1935,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
1932 return nbad; 1935 return nbad;
1933} 1936}
1934 1937
1935static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, 1938static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
1936 int nbad, int txok, bool update_rc) 1939 int nbad, int txok, bool update_rc)
1937{ 1940{
1938 struct sk_buff *skb = bf->bf_mpdu; 1941 struct sk_buff *skb = bf->bf_mpdu;
@@ -1942,24 +1945,24 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
1942 u8 i, tx_rateindex; 1945 u8 i, tx_rateindex;
1943 1946
1944 if (txok) 1947 if (txok)
1945 tx_info->status.ack_signal = ds->ds_txstat.ts_rssi; 1948 tx_info->status.ack_signal = ts->ts_rssi;
1946 1949
1947 tx_rateindex = ds->ds_txstat.ts_rateindex; 1950 tx_rateindex = ts->ts_rateindex;
1948 WARN_ON(tx_rateindex >= hw->max_rates); 1951 WARN_ON(tx_rateindex >= hw->max_rates);
1949 1952
1950 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) 1953 if (ts->ts_status & ATH9K_TXERR_FILT)
1951 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; 1954 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
1952 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) 1955 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc)
1953 tx_info->flags |= IEEE80211_TX_STAT_AMPDU; 1956 tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
1954 1957
1955 if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && 1958 if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 &&
1956 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { 1959 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
1957 if (ieee80211_is_data(hdr->frame_control)) { 1960 if (ieee80211_is_data(hdr->frame_control)) {
1958 if (ds->ds_txstat.ts_flags & 1961 if (ts->ts_flags &
1959 (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN)) 1962 (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN))
1960 tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN; 1963 tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN;
1961 if ((ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) || 1964 if ((ts->ts_status & ATH9K_TXERR_XRETRY) ||
1962 (ds->ds_txstat.ts_status & ATH9K_TXERR_FIFO)) 1965 (ts->ts_status & ATH9K_TXERR_FIFO))
1963 tx_info->pad[0] |= ATH_TX_INFO_XRETRY; 1966 tx_info->pad[0] |= ATH_TX_INFO_XRETRY;
1964 tx_info->status.ampdu_len = bf->bf_nframes; 1967 tx_info->status.ampdu_len = bf->bf_nframes;
1965 tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; 1968 tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad;
@@ -1997,6 +2000,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1997 struct ath_buf *bf, *lastbf, *bf_held = NULL; 2000 struct ath_buf *bf, *lastbf, *bf_held = NULL;
1998 struct list_head bf_head; 2001 struct list_head bf_head;
1999 struct ath_desc *ds; 2002 struct ath_desc *ds;
2003 struct ath_tx_status *ts;
2000 int txok; 2004 int txok;
2001 int status; 2005 int status;
2002 2006
@@ -2035,8 +2039,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2035 2039
2036 lastbf = bf->bf_lastbf; 2040 lastbf = bf->bf_lastbf;
2037 ds = lastbf->bf_desc; 2041 ds = lastbf->bf_desc;
2042 ts = &ds->ds_us.tx;
2038 2043
2039 status = ath9k_hw_txprocdesc(ah, ds); 2044 status = ath9k_hw_txprocdesc(ah, ds, ts);
2040 if (status == -EINPROGRESS) { 2045 if (status == -EINPROGRESS) {
2041 spin_unlock_bh(&txq->axq_lock); 2046 spin_unlock_bh(&txq->axq_lock);
2042 break; 2047 break;
@@ -2047,7 +2052,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2047 * can disable RX. 2052 * can disable RX.
2048 */ 2053 */
2049 if (bf->bf_isnullfunc && 2054 if (bf->bf_isnullfunc &&
2050 (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) { 2055 (ts->ts_status & ATH9K_TX_ACKED)) {
2051 if ((sc->ps_flags & PS_ENABLED)) 2056 if ((sc->ps_flags & PS_ENABLED))
2052 ath9k_enable_ps(sc); 2057 ath9k_enable_ps(sc);
2053 else 2058 else
@@ -2066,7 +2071,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2066 &txq->axq_q, lastbf->list.prev); 2071 &txq->axq_q, lastbf->list.prev);
2067 2072
2068 txq->axq_depth--; 2073 txq->axq_depth--;
2069 txok = !(ds->ds_txstat.ts_status & ATH9K_TXERR_MASK); 2074 txok = !(ts->ts_status & ATH9K_TXERR_MASK);
2070 txq->axq_tx_inprogress = false; 2075 txq->axq_tx_inprogress = false;
2071 spin_unlock_bh(&txq->axq_lock); 2076 spin_unlock_bh(&txq->axq_lock);
2072 2077
@@ -2081,16 +2086,16 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2081 * This frame is sent out as a single frame. 2086 * This frame is sent out as a single frame.
2082 * Use hardware retry status for this frame. 2087 * Use hardware retry status for this frame.
2083 */ 2088 */
2084 bf->bf_retries = ds->ds_txstat.ts_longretry; 2089 bf->bf_retries = ts->ts_longretry;
2085 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) 2090 if (ts->ts_status & ATH9K_TXERR_XRETRY)
2086 bf->bf_state.bf_type |= BUF_XRETRY; 2091 bf->bf_state.bf_type |= BUF_XRETRY;
2087 ath_tx_rc_status(bf, ds, 0, txok, true); 2092 ath_tx_rc_status(bf, ts, 0, txok, true);
2088 } 2093 }
2089 2094
2090 if (bf_isampdu(bf)) 2095 if (bf_isampdu(bf))
2091 ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok); 2096 ath_tx_complete_aggr(sc, txq, bf, &bf_head, ts, txok);
2092 else 2097 else
2093 ath_tx_complete_buf(sc, bf, txq, &bf_head, txok, 0); 2098 ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, txok, 0);
2094 2099
2095 ath_wake_mac80211_queue(sc, txq); 2100 ath_wake_mac80211_queue(sc, txq);
2096 2101