Lines Matching +full:edma +full:- +full:tx
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
44 * by the driver - eg, calls to ath_hal_gettsf32().
129 #define INCR(_l, _sz) (_l) ++; (_l) &= ((_sz) - 1)
130 #define DECR(_l, _sz) (_l) --; (_l) &= ((_sz) - 1)
153 if_ath_alq_post(&sc->sc_alq, ATH_ALQ_TX_FIFO_PUSH, in ath_tx_alq_edma_push()
161 * it may not meet the TXOP for say, DBA-gated traffic in TDMA mode.
163 * The TX completion code handles a TX FIFO slot having multiple frames,
184 txq->axq_qnum, in ath_tx_edma_push_staging_list()
185 txq->axq_fifo_depth, in ath_tx_edma_push_staging_list()
186 !! (TAILQ_EMPTY(&txq->axq_q))); in ath_tx_edma_push_staging_list()
191 if (txq->axq_fifo_depth >= HAL_TXFIFO_DEPTH) in ath_tx_edma_push_staging_list()
194 if (TAILQ_EMPTY(&txq->axq_q)) in ath_tx_edma_push_staging_list()
200 * First pass - walk sq, queue up to 'limit' entries, in ath_tx_edma_push_staging_list()
215 bf->bf_flags &= ~(ATH_BUF_FIFOPTR | ATH_BUF_FIFOEND); in ath_tx_edma_push_staging_list()
237 bf->bf_flags |= ATH_BUF_FIFOPTR; in ath_tx_edma_push_staging_list()
238 bf_last->bf_flags |= ATH_BUF_FIFOEND; in ath_tx_edma_push_staging_list()
246 ath_hal_settxdesclink(sc->sc_ah, bfp->bf_lastds, in ath_tx_edma_push_staging_list()
247 bfi->bf_daddr); in ath_tx_edma_push_staging_list()
255 if (sc->sc_debug & ATH_DEBUG_XMIT_DESC) in ath_tx_edma_push_staging_list()
256 ath_printtxbuf(sc, bfi, txq->axq_qnum, i, 0); in ath_tx_edma_push_staging_list()
259 if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_EDMA_TXDESC)) in ath_tx_edma_push_staging_list()
272 TAILQ_CONCAT(&txq->fifo.axq_q, &sq, bf_list); in ath_tx_edma_push_staging_list()
274 txq->fifo.axq_depth += sqdepth; in ath_tx_edma_push_staging_list()
277 txq->axq_fifo_depth++; in ath_tx_edma_push_staging_list()
280 __func__, sqdepth, txq->fifo.axq_depth, txq->axq_fifo_depth); in ath_tx_edma_push_staging_list()
283 ath_hal_puttxbuf(sc->sc_ah, txq->axq_qnum, bf->bf_daddr); in ath_tx_edma_push_staging_list()
286 ath_hal_txstart(sc->sc_ah, txq->axq_qnum); in ath_tx_edma_push_staging_list()
289 ath_tx_alq_edma_push(sc, txq->axq_qnum, sqdepth, in ath_tx_edma_push_staging_list()
290 txq->axq_fifo_depth, in ath_tx_edma_push_staging_list()
291 txq->fifo.axq_depth); in ath_tx_edma_push_staging_list()
298 * Push some frames into the TX FIFO if we have space.
309 txq->axq_qnum, in ath_edma_tx_fifo_fill()
310 txq->fifo.axq_depth, in ath_edma_tx_fifo_fill()
311 txq->axq_fifo_depth, in ath_edma_tx_fifo_fill()
312 txq->axq_depth, in ath_edma_tx_fifo_fill()
313 txq->axq_aggr_depth); in ath_edma_tx_fifo_fill()
316 * For now, push up to 32 frames per TX FIFO slot. in ath_edma_tx_fifo_fill()
319 * or complete a frame - so at most there'll be in ath_edma_tx_fifo_fill()
320 * 32 non-AMPDU frames per node/TID anyway. in ath_edma_tx_fifo_fill()
327 * the TX FIFO since we don't want to necessarily in ath_edma_tx_fifo_fill()
336 * So for TDMA we suffer a big performance penalty - in ath_edma_tx_fifo_fill()
337 * single TX FIFO entries mean the MAC only sends out in ath_edma_tx_fifo_fill()
339 * 6ms per TX frame. in ath_edma_tx_fifo_fill()
341 * So, for aggregates it's okay - it'll push two at a in ath_edma_tx_fifo_fill()
343 * For non-aggregates it'll do 4 at a time, up to the in ath_edma_tx_fifo_fill()
344 * non-aggr limit (non_aggr, which is 32.) They should in ath_edma_tx_fifo_fill()
362 if (txq->axq_depth >= TX_BATCH_SIZE / 2 && in ath_edma_tx_fifo_fill()
363 txq->fifo.axq_depth <= TX_BATCH_SIZE) { in ath_edma_tx_fifo_fill()
378 else if (txq->axq_aggr_depth > 0 && txq->axq_fifo_depth < 2) in ath_edma_tx_fifo_fill()
389 else if (txq->axq_fifo_depth == 0) { in ath_edma_tx_fifo_fill()
395 * Re-initialise the DMA FIFO with the current contents of
411 txq->axq_qnum); in ath_edma_dma_restart()
419 old_fifo_depth = txq->axq_fifo_depth; in ath_edma_dma_restart()
420 txq->axq_fifo_depth = 0; in ath_edma_dma_restart()
425 * we push the first frame we see into the FIFO and re-mark in ath_edma_dma_restart()
430 TAILQ_FOREACH(bf, &txq->fifo.axq_q, bf_list) { in ath_edma_dma_restart()
439 if (sc->sc_debug & ATH_DEBUG_XMIT_DESC) in ath_edma_dma_restart()
440 ath_printtxbuf(sc, bf, txq->axq_qnum, i, 0); in ath_edma_dma_restart()
443 if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_EDMA_TXDESC)) in ath_edma_dma_restart()
448 if (bf->bf_flags & ATH_BUF_FIFOEND) in ath_edma_dma_restart()
454 if (txq->axq_fifo_depth >= HAL_TXFIFO_DEPTH) { in ath_edma_dma_restart()
455 device_printf(sc->sc_dev, in ath_edma_dma_restart()
458 txq->axq_qnum, in ath_edma_dma_restart()
459 txq->axq_fifo_depth); in ath_edma_dma_restart()
466 txq->axq_qnum, in ath_edma_dma_restart()
467 txq->axq_fifo_depth, in ath_edma_dma_restart()
469 !! (bf->bf_flags & ATH_BUF_FIFOPTR), in ath_edma_dma_restart()
470 !! (bf->bf_flags & ATH_BUF_FIFOEND)); in ath_edma_dma_restart()
475 * list - even if it's also the last buffer in in ath_edma_dma_restart()
478 bf->bf_flags |= ATH_BUF_FIFOPTR; in ath_edma_dma_restart()
481 ath_hal_puttxbuf(sc->sc_ah, txq->axq_qnum, bf->bf_daddr); in ath_edma_dma_restart()
482 txq->axq_fifo_depth++; in ath_edma_dma_restart()
489 if (! (bf->bf_flags & ATH_BUF_FIFOEND)) in ath_edma_dma_restart()
496 ath_hal_txstart(sc->sc_ah, txq->axq_qnum); in ath_edma_dma_restart()
500 txq->axq_qnum, in ath_edma_dma_restart()
502 txq->axq_fifo_depth); in ath_edma_dma_restart()
505 if (txq->axq_fifo_depth != old_fifo_depth) { in ath_edma_dma_restart()
506 device_printf(sc->sc_dev, in ath_edma_dma_restart()
509 txq->axq_qnum, in ath_edma_dma_restart()
511 txq->axq_fifo_depth); in ath_edma_dma_restart()
518 * Things are a bit hairy in the EDMA world. The TX FIFO is only
520 * pushed into the FIFO and what's just sitting in the TX queue,
523 * So this is split into two halves - frames get appended to the
525 * actual TX FIFO.
534 KASSERT((bf->bf_flags & ATH_BUF_BUSY) == 0, in ath_edma_xmit_handoff_hw()
535 ("%s: busy status 0x%x", __func__, bf->bf_flags)); in ath_edma_xmit_handoff_hw()
538 * XXX TODO: write a hard-coded check to ensure that in ath_edma_xmit_handoff_hw()
539 * the queue id in the TX descriptor matches txq->axq_qnum. in ath_edma_xmit_handoff_hw()
543 if (bf->bf_state.bfs_aggr) in ath_edma_xmit_handoff_hw()
544 txq->axq_aggr_depth++; in ath_edma_xmit_handoff_hw()
560 * The EDMA TX CABQ will get a list of chained frames, chained
570 KASSERT((bf->bf_flags & ATH_BUF_BUSY) == 0, in ath_edma_xmit_handoff_mcast()
571 ("%s: busy status 0x%x", __func__, bf->bf_flags)); in ath_edma_xmit_handoff_mcast()
582 wh = mtod(bf_last->bf_m, struct ieee80211_frame *); in ath_edma_xmit_handoff_mcast()
583 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA; in ath_edma_xmit_handoff_mcast()
585 /* re-sync buffer to memory */ in ath_edma_xmit_handoff_mcast()
586 bus_dmamap_sync(sc->sc_dmat, bf_last->bf_dmamap, in ath_edma_xmit_handoff_mcast()
590 ath_hal_settxdesclink(sc->sc_ah, in ath_edma_xmit_handoff_mcast()
591 bf_last->bf_lastds, in ath_edma_xmit_handoff_mcast()
592 bf->bf_daddr); in ath_edma_xmit_handoff_mcast()
595 if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_EDMA_TXDESC)) in ath_edma_xmit_handoff_mcast()
612 * EDMA hardware has 8 FIFO slots per TXQ, this ensures that
615 * This does imply that a similar flush-hwq-to-fifoq method will
617 * per-node software scheduler is called.
629 txq->axq_qnum); in ath_edma_xmit_handoff()
631 if (txq->axq_qnum == ATH_TXQ_SWQ) in ath_edma_xmit_handoff()
640 struct ath_tx_edma_fifo *te = &sc->sc_txedma[qnum]; in ath_edma_setup_txfifo()
642 te->m_fifo = malloc(sizeof(struct ath_buf *) * HAL_TXFIFO_DEPTH, in ath_edma_setup_txfifo()
645 if (te->m_fifo == NULL) { in ath_edma_setup_txfifo()
646 device_printf(sc->sc_dev, "%s: malloc failed\n", in ath_edma_setup_txfifo()
648 return (-ENOMEM); in ath_edma_setup_txfifo()
654 te->m_fifo_head = te->m_fifo_tail = te->m_fifo_depth = 0; in ath_edma_setup_txfifo()
662 struct ath_tx_edma_fifo *te = &sc->sc_txedma[qnum]; in ath_edma_free_txfifo()
665 free(te->m_fifo, M_ATHDEV); in ath_edma_free_txfifo()
675 error = ath_descdma_alloc_desc(sc, &sc->sc_txsdma, in ath_edma_dma_txsetup()
676 NULL, "txcomp", sc->sc_tx_statuslen, ATH_TXSTATUS_RING_SIZE); in ath_edma_dma_txsetup()
680 ath_hal_setuptxstatusring(sc->sc_ah, in ath_edma_dma_txsetup()
681 (void *) sc->sc_txsdma.dd_desc, in ath_edma_dma_txsetup()
682 sc->sc_txsdma.dd_desc_paddr, in ath_edma_dma_txsetup()
701 ath_descdma_cleanup(sc, &sc->sc_txsdma, NULL); in ath_edma_dma_txteardown()
719 * If reset type is noloss, the TX FIFO needs to be serviced in ath_edma_tx_drain()
722 * Otherwise, just toss everything in each TX queue. in ath_edma_tx_drain()
728 ATH_TXQ_LOCK(&sc->sc_txq[i]); in ath_edma_tx_drain()
733 ath_txq_freeholdingbuf(sc, &sc->sc_txq[i]); in ath_edma_tx_drain()
738 sc->sc_txq[i].axq_link = NULL; in ath_edma_tx_drain()
739 ATH_TXQ_UNLOCK(&sc->sc_txq[i]); in ath_edma_tx_drain()
745 ath_tx_draintxq(sc, &sc->sc_txq[i]); in ath_edma_tx_drain()
749 /* XXX dump out the TX completion FIFO contents */ in ath_edma_tx_drain()
753 sc->sc_wd_timer = 0; in ath_edma_tx_drain()
757 * TX completion tasklet.
766 sc->sc_txproc_cnt++; in ath_edma_tx_proc()
780 sc->sc_txproc_cnt--; in ath_edma_tx_proc()
791 * Process the TX status queue.
796 struct ath_hal *ah = sc->sc_ah; in ath_edma_tx_processq()
831 if (sc->sc_debug & ATH_DEBUG_TX_PROC) in ath_edma_tx_processq()
832 if (ts.ts_queue_id != sc->sc_bhalq) in ath_edma_tx_processq()
844 device_printf(sc->sc_dev, "%s: invalid TX status?\n", in ath_edma_tx_processq()
850 if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_EDMA_TXSTATUS)) { in ath_edma_tx_processq()
851 if_ath_alq_post(&sc->sc_alq, ATH_ALQ_EDMA_TXSTATUS, in ath_edma_tx_processq()
852 sc->sc_tx_statuslen, in ath_edma_tx_processq()
863 * -head- of the given QID. Eventually we should verify in ath_edma_tx_processq()
873 if (ts.ts_queue_id == sc->sc_bhalq) in ath_edma_tx_processq()
876 txq = &sc->sc_txq[ts.ts_queue_id]; in ath_edma_tx_processq()
879 bf = ATH_TXQ_FIRST(&txq->fifo); in ath_edma_tx_processq()
887 device_printf(sc->sc_dev, "%s: Q%d: empty?\n", in ath_edma_tx_processq()
897 !! (bf->bf_flags & ATH_BUF_FIFOPTR), in ath_edma_tx_processq()
898 !! (bf->bf_flags & ATH_BUF_FIFOEND)); in ath_edma_tx_processq()
904 if (ts.ts_desc_id != bf->bf_descid) { in ath_edma_tx_processq()
905 device_printf(sc->sc_dev, in ath_edma_tx_processq()
911 bf->bf_descid); in ath_edma_tx_processq()
916 ATH_TXQ_REMOVE(&txq->fifo, bf, bf_list); in ath_edma_tx_processq()
917 if (bf->bf_state.bfs_aggr) in ath_edma_tx_processq()
918 txq->axq_aggr_depth--; in ath_edma_tx_processq()
923 if (bf->bf_flags & ATH_BUF_FIFOEND) in ath_edma_tx_processq()
924 txq->axq_fifo_depth--; in ath_edma_tx_processq()
930 if (! (bf->bf_flags & ATH_BUF_FIFOEND)) in ath_edma_tx_processq()
931 bf->bf_flags |= ATH_BUF_BUSY; in ath_edma_tx_processq()
935 txq->axq_qnum, in ath_edma_tx_processq()
936 txq->axq_fifo_depth, in ath_edma_tx_processq()
937 txq->fifo.axq_depth); in ath_edma_tx_processq()
943 * Outside of the TX lock - if the buffer is end in ath_edma_tx_processq()
947 if (bf->bf_flags & ATH_BUF_FIFOEND) { in ath_edma_tx_processq()
956 * Pre-EDMA chips pass the whole TX descriptor to in ath_edma_tx_processq()
958 * ts_rate based on the ts_finaltsi (final TX index) in ath_edma_tx_processq()
959 * in the TX descriptor. However the TX completion in ath_edma_tx_processq()
973 bf->bf_state.bfs_rc[ts.ts_finaltsi].ratecode; in ath_edma_tx_processq()
976 bf->bf_state.bfs_rc[2].tries; in ath_edma_tx_processq()
978 bf->bf_state.bfs_rc[1].tries; in ath_edma_tx_processq()
980 bf->bf_state.bfs_rc[0].tries; in ath_edma_tx_processq()
983 device_printf(sc->sc_dev, "%s: finaltsi=%d\n", in ath_edma_tx_processq()
986 ts.ts_rate = bf->bf_state.bfs_rc[0].ratecode; in ath_edma_tx_processq()
992 * Right now, some code uses the TX status that is in ath_edma_tx_processq()
994 * software TX path also use bf_status.ds_txstat. in ath_edma_tx_processq()
1000 memcpy(&bf->bf_status, &ts, sizeof(ts)); in ath_edma_tx_processq()
1002 ni = bf->bf_node; in ath_edma_tx_processq()
1007 ((bf->bf_state.bfs_txflags & HAL_TXDESC_NOACK) == 0)) { in ath_edma_tx_processq()
1009 sc->sc_stats.ast_tx_rssi = ts.ts_rssi; in ath_edma_tx_processq()
1010 ATH_RSSI_LPF(sc->sc_halstats.ns_avgtxrssi, in ath_edma_tx_processq()
1012 ATH_RSSI_LPF(ATH_NODE(ni)->an_node_stats.ns_avgtxrssi, in ath_edma_tx_processq()
1022 sc->sc_wd_timer = 0; in ath_edma_tx_processq()
1030 /* Attempt to schedule more hardware frames to the TX FIFO */ in ath_edma_tx_processq()
1034 ath_txq_sched(sc, &sc->sc_txq[i]); in ath_edma_tx_processq()
1037 ATH_TXQ_LOCK(&sc->sc_txq[i]); in ath_edma_tx_processq()
1038 ath_edma_tx_fifo_fill(sc, &sc->sc_txq[i]); in ath_edma_tx_processq()
1039 ATH_TXQ_UNLOCK(&sc->sc_txq[i]); in ath_edma_tx_processq()
1053 TASK_INIT(&sc->sc_txtask, 0, ath_edma_tx_proc, sc); in ath_edma_attach_comp_func()
1060 /* Fetch EDMA field and buffer sizes */ in ath_xmit_setup_edma()
1061 (void) ath_hal_gettxdesclen(sc->sc_ah, &sc->sc_tx_desclen); in ath_xmit_setup_edma()
1062 (void) ath_hal_gettxstatuslen(sc->sc_ah, &sc->sc_tx_statuslen); in ath_xmit_setup_edma()
1063 (void) ath_hal_getntxmaps(sc->sc_ah, &sc->sc_tx_nmaps); in ath_xmit_setup_edma()
1066 device_printf(sc->sc_dev, "TX descriptor length: %d\n", in ath_xmit_setup_edma()
1067 sc->sc_tx_desclen); in ath_xmit_setup_edma()
1068 device_printf(sc->sc_dev, "TX status length: %d\n", in ath_xmit_setup_edma()
1069 sc->sc_tx_statuslen); in ath_xmit_setup_edma()
1070 device_printf(sc->sc_dev, "TX buffers per descriptor: %d\n", in ath_xmit_setup_edma()
1071 sc->sc_tx_nmaps); in ath_xmit_setup_edma()
1074 sc->sc_tx.xmit_setup = ath_edma_dma_txsetup; in ath_xmit_setup_edma()
1075 sc->sc_tx.xmit_teardown = ath_edma_dma_txteardown; in ath_xmit_setup_edma()
1076 sc->sc_tx.xmit_attach_comp_func = ath_edma_attach_comp_func; in ath_xmit_setup_edma()
1078 sc->sc_tx.xmit_dma_restart = ath_edma_dma_restart; in ath_xmit_setup_edma()
1079 sc->sc_tx.xmit_handoff = ath_edma_xmit_handoff; in ath_xmit_setup_edma()
1080 sc->sc_tx.xmit_drain = ath_edma_tx_drain; in ath_xmit_setup_edma()