diff options
author | Felix Fietkau <nbd@openwrt.org> | 2010-03-29 23:07:11 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-03-31 14:46:41 -0400 |
commit | db1a052b73f7c97f9e8b21f3f19a92313ed2acb1 (patch) | |
tree | 47bb94db727c4ec11d6eb9cfdba5a89f5833eb68 | |
parent | e65054b64ff6b89380a7f546c9eebf862e679646 (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.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.c | 16 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/mac.c | 75 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/mac.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 107 |
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 | ||
558 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, | 558 | void 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); | |||
167 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); | 167 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); |
168 | void ath_debug_stat_rc(struct ath_softc *sc, int final_rate); | 168 | void ath_debug_stat_rc(struct ath_softc *sc, int final_rate); |
169 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, | 169 | void 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); |
171 | void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf); | 171 | void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf); |
172 | void ath_debug_stat_retries(struct ath_softc *sc, int rix, | 172 | void 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 | } |
247 | EXPORT_SYMBOL(ath9k_hw_cleartxdesc); | 247 | EXPORT_SYMBOL(ath9k_hw_cleartxdesc); |
248 | 248 | ||
249 | int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds) | 249 | int 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); |
704 | void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds); | 703 | void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds); |
705 | int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds); | 704 | int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds, |
705 | struct ath_tx_status *ts); | ||
706 | void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds, | 706 | void 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); |
61 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 61 | static 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); | ||
65 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | 64 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, |
66 | struct list_head *head); | 65 | struct list_head *head); |
67 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf); | 66 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf); |
68 | static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, | 67 | static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, |
69 | int txok); | 68 | struct ath_tx_status *ts, int txok); |
70 | static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, | 69 | static 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 | ||
73 | enum { | 72 | enum { |
@@ -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 | ||
287 | static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | 289 | static 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 | ||
1873 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 1879 | static 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 | ||
1904 | static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, | 1909 | static 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 | ||
1935 | static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, | 1938 | static 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 | ||