OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 * Copyright (c) 2008-2009 Atheros Communications Inc. |
3 * | 3 * |
4 * Permission to use, copy, modify, and/or distribute this software for any | 4 * Permission to use, copy, modify, and/or distribute this software for any |
5 * purpose with or without fee is hereby granted, provided that the above | 5 * purpose with or without fee is hereby granted, provided that the above |
6 * copyright notice and this permission notice appear in all copies. | 6 * copyright notice and this permission notice appear in all copies. |
7 * | 7 * |
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 * not a holding desc. | 432 * not a holding desc. |
433 */ | 433 */ |
434 if (!bf_last->bf_stale) | 434 if (!bf_last->bf_stale) |
435 list_move_tail(&bf->list, &bf_head); | 435 list_move_tail(&bf->list, &bf_head); |
436 else | 436 else |
437 INIT_LIST_HEAD(&bf_head); | 437 INIT_LIST_HEAD(&bf_head); |
438 } else { | 438 } else { |
439 BUG_ON(list_empty(bf_q)); | 439 BUG_ON(list_empty(bf_q)); |
440 list_move_tail(&bf->list, &bf_head); | 440 list_move_tail(&bf->list, &bf_head); |
441 } | 441 } |
| 442 |
| 443 ath9k_pktlog_txcomplete(sc, &bf_head, bf, bf_last); |
442 | 444 |
443 if (!txpending || (tid->state & AGGR_CLEANUP)) { | 445 if (!txpending || (tid->state & AGGR_CLEANUP)) { |
444 /* | 446 /* |
445 * complete the acked-ones/xretried ones; update | 447 * complete the acked-ones/xretried ones; update |
446 * block-ack window | 448 * block-ack window |
447 */ | 449 */ |
448 spin_lock_bh(&txq->axq_lock); | 450 spin_lock_bh(&txq->axq_lock); |
449 ath_tx_update_baw(sc, tid, bf->bf_seqno); | 451 ath_tx_update_baw(sc, tid, bf->bf_seqno); |
450 spin_unlock_bh(&txq->axq_lock); | 452 spin_unlock_bh(&txq->axq_lock); |
451 | 453 |
(...skipping 1630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2082 } else { | 2084 } else { |
2083 bf = list_entry(bf_held->list.next, | 2085 bf = list_entry(bf_held->list.next, |
2084 struct ath_buf, list); | 2086 struct ath_buf, list); |
2085 } | 2087 } |
2086 } | 2088 } |
2087 | 2089 |
2088 lastbf = bf->bf_lastbf; | 2090 lastbf = bf->bf_lastbf; |
2089 ds = lastbf->bf_desc; | 2091 ds = lastbf->bf_desc; |
2090 | 2092 |
2091 memset(&ts, 0, sizeof(ts)); | 2093 memset(&ts, 0, sizeof(ts)); |
2092 » » status = ath9k_hw_txprocdesc(ah, ds, &ts); | 2094 » » status = ath9k_hw_txprocdesc(ah, ds, &ts, NULL); |
2093 if (status == -EINPROGRESS) { | 2095 if (status == -EINPROGRESS) { |
2094 spin_unlock_bh(&txq->axq_lock); | 2096 spin_unlock_bh(&txq->axq_lock); |
2095 break; | 2097 break; |
2096 } | 2098 } |
2097 | 2099 |
2098 /* | 2100 /* |
2099 * We now know the nullfunc frame has been ACKed so we | 2101 * We now know the nullfunc frame has been ACKed so we |
2100 * can disable RX. | 2102 * can disable RX. |
2101 */ | 2103 */ |
2102 if (bf->bf_isnullfunc && | 2104 if (bf->bf_isnullfunc && |
(...skipping 30 matching lines...) Expand all Loading... |
2133 * This frame is sent out as a single frame. | 2135 * This frame is sent out as a single frame. |
2134 * Use hardware retry status for this frame. | 2136 * Use hardware retry status for this frame. |
2135 */ | 2137 */ |
2136 if (ts.ts_status & ATH9K_TXERR_XRETRY) | 2138 if (ts.ts_status & ATH9K_TXERR_XRETRY) |
2137 bf->bf_state.bf_type |= BUF_XRETRY; | 2139 bf->bf_state.bf_type |= BUF_XRETRY; |
2138 ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true); | 2140 ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true); |
2139 } | 2141 } |
2140 | 2142 |
2141 qnum = skb_get_queue_mapping(bf->bf_mpdu); | 2143 qnum = skb_get_queue_mapping(bf->bf_mpdu); |
2142 | 2144 |
2143 » » if (bf_isampdu(bf)) | 2145 » » if (bf_isampdu(bf)) { |
2144 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok); | 2146 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok); |
2145 » » else | 2147 » » } else { |
| 2148 » » » ath9k_pktlog_txctrl(sc, &bf_head, lastbf); |
2146 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0)
; | 2149 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0)
; |
| 2150 } |
| 2151 |
| 2152 ath_pktlog_txstatus(sc, lastbf->bf_desc); |
2147 | 2153 |
2148 if (txq == sc->tx.txq_map[qnum]) | 2154 if (txq == sc->tx.txq_map[qnum]) |
2149 ath_wake_mac80211_queue(sc, qnum); | 2155 ath_wake_mac80211_queue(sc, qnum); |
2150 | 2156 |
2151 spin_lock_bh(&txq->axq_lock); | 2157 spin_lock_bh(&txq->axq_lock); |
2152 if (sc->sc_flags & SC_OP_TXAGGR) | 2158 if (sc->sc_flags & SC_OP_TXAGGR) |
2153 ath_txq_schedule(sc, txq); | 2159 ath_txq_schedule(sc, txq); |
2154 spin_unlock_bh(&txq->axq_lock); | 2160 spin_unlock_bh(&txq->axq_lock); |
2155 } | 2161 } |
2156 } | 2162 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2210 { | 2216 { |
2211 struct ath_tx_status txs; | 2217 struct ath_tx_status txs; |
2212 struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 2218 struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
2213 struct ath_hw *ah = sc->sc_ah; | 2219 struct ath_hw *ah = sc->sc_ah; |
2214 struct ath_txq *txq; | 2220 struct ath_txq *txq; |
2215 struct ath_buf *bf, *lastbf; | 2221 struct ath_buf *bf, *lastbf; |
2216 struct list_head bf_head; | 2222 struct list_head bf_head; |
2217 int status; | 2223 int status; |
2218 int txok; | 2224 int txok; |
2219 int qnum; | 2225 int qnum; |
| 2226 u32 txs_desc[9]; |
2220 | 2227 |
2221 for (;;) { | 2228 for (;;) { |
2222 » » status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs); | 2229 » » status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs, |
| 2230 » » » » » (void *) txs_desc); |
2223 if (status == -EINPROGRESS) | 2231 if (status == -EINPROGRESS) |
2224 break; | 2232 break; |
2225 if (status == -EIO) { | 2233 if (status == -EIO) { |
2226 ath_print(common, ATH_DBG_XMIT, | 2234 ath_print(common, ATH_DBG_XMIT, |
2227 "Error processing tx status\n"); | 2235 "Error processing tx status\n"); |
2228 break; | 2236 break; |
2229 } | 2237 } |
2230 | 2238 |
2231 /* Skip beacon completions */ | 2239 /* Skip beacon completions */ |
2232 if (txs.qid == sc->beacon.beaconq) | 2240 if (txs.qid == sc->beacon.beaconq) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2266 } | 2274 } |
2267 | 2275 |
2268 if (!bf_isampdu(bf)) { | 2276 if (!bf_isampdu(bf)) { |
2269 if (txs.ts_status & ATH9K_TXERR_XRETRY) | 2277 if (txs.ts_status & ATH9K_TXERR_XRETRY) |
2270 bf->bf_state.bf_type |= BUF_XRETRY; | 2278 bf->bf_state.bf_type |= BUF_XRETRY; |
2271 ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true); | 2279 ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true); |
2272 } | 2280 } |
2273 | 2281 |
2274 qnum = skb_get_queue_mapping(bf->bf_mpdu); | 2282 qnum = skb_get_queue_mapping(bf->bf_mpdu); |
2275 | 2283 |
2276 » » if (bf_isampdu(bf)) | 2284 » » if (bf_isampdu(bf)) { |
2277 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok); | 2285 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok); |
2278 » » else | 2286 » » } else { |
| 2287 » » » ath9k_pktlog_txctrl(sc, &bf_head, lastbf); |
2279 ath_tx_complete_buf(sc, bf, txq, &bf_head, | 2288 ath_tx_complete_buf(sc, bf, txq, &bf_head, |
2280 &txs, txok, 0); | 2289 &txs, txok, 0); |
| 2290 } |
2281 | 2291 |
2282 if (txq == sc->tx.txq_map[qnum]) | 2292 if (txq == sc->tx.txq_map[qnum]) |
2283 ath_wake_mac80211_queue(sc, qnum); | 2293 ath_wake_mac80211_queue(sc, qnum); |
2284 | 2294 |
| 2295 ath_pktlog_txstatus(sc, txs_desc); |
| 2296 |
2285 spin_lock_bh(&txq->axq_lock); | 2297 spin_lock_bh(&txq->axq_lock); |
2286 if (!list_empty(&txq->txq_fifo_pending)) { | 2298 if (!list_empty(&txq->txq_fifo_pending)) { |
2287 INIT_LIST_HEAD(&bf_head); | 2299 INIT_LIST_HEAD(&bf_head); |
2288 bf = list_first_entry(&txq->txq_fifo_pending, | 2300 bf = list_first_entry(&txq->txq_fifo_pending, |
2289 struct ath_buf, list); | 2301 struct ath_buf, list); |
2290 list_cut_position(&bf_head, &txq->txq_fifo_pending, | 2302 list_cut_position(&bf_head, &txq->txq_fifo_pending, |
2291 &bf->bf_lastbf->list); | 2303 &bf->bf_lastbf->list); |
2292 ath_tx_txqaddbuf(sc, txq, &bf_head); | 2304 ath_tx_txqaddbuf(sc, txq, &bf_head); |
2293 } else if (sc->sc_flags & SC_OP_TXAGGR) | 2305 } else if (sc->sc_flags & SC_OP_TXAGGR) |
2294 ath_txq_schedule(sc, txq); | 2306 ath_txq_schedule(sc, txq); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2442 tid->ac->sched = false; | 2454 tid->ac->sched = false; |
2443 } | 2455 } |
2444 | 2456 |
2445 ath_tid_drain(sc, txq, tid); | 2457 ath_tid_drain(sc, txq, tid); |
2446 tid->state &= ~AGGR_ADDBA_COMPLETE; | 2458 tid->state &= ~AGGR_ADDBA_COMPLETE; |
2447 tid->state &= ~AGGR_CLEANUP; | 2459 tid->state &= ~AGGR_CLEANUP; |
2448 | 2460 |
2449 spin_unlock_bh(&txq->axq_lock); | 2461 spin_unlock_bh(&txq->axq_lock); |
2450 } | 2462 } |
2451 } | 2463 } |
OLD | NEW |