[ath] [ar9300] ensure the software scheduler is called to form more aggregates for EDMA chips

When investigating performance on UDP TX on the AR9380 I found that the
following sequence was occuring:

* INTR
* EINPROGRESS - nothing yet
* INTR
* TXSTATUS - process a TX completion for an aggregate
* INTR, INTR
* TXSTATUS - process a TX completion for an aggregate
* TXD, TXD ... populate frames from the hardware queue and submit

What should be happening is a completed TXSTATUS fires off more packets
that are queued on active TIDs.

What /was/ happening was after that first TXSTATUS the TX queue hardware queue
was still empty, so it didn't push anything into the FIFO.  Only after the
second TXSTATUS did any progress get made.

This is one of two commits - it ensures that the software TX queue scheduler
is called /after/ TX completion, otherwise no frames from the software staging
queues will be processed into the hardware queues.

The second commit will fix it so it populates aggregate frames correctly
when the above occurs - right now ath_txq_sched() is called, but it doesn't
populate anything because its pre-check conditions are wrong.

Whilst here, add/tweak debugging.

Tested:

* AR9380 STA (testing device) -> AR9580 hostap
This commit is contained in:
Adrian Chadd 2017-01-23 04:20:37 +00:00
parent 8d2f50dba6
commit 6eb9f206a6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=312660

View File

@ -178,6 +178,13 @@ ath_tx_edma_push_staging_list(struct ath_softc *sc, struct ath_txq *txq,
ATH_TXQ_LOCK_ASSERT(txq);
DPRINTF(sc, ATH_DEBUG_XMIT | ATH_DEBUG_TX_PROC,
"%s: called; TXQ=%d, fifo.depth=%d, axq_q empty=%d\n",
__func__,
txq->axq_qnum,
txq->axq_fifo_depth,
!! (TAILQ_EMPTY(&txq->axq_q)));
/*
* Don't bother doing any work if it's full.
*/
@ -802,6 +809,8 @@ ath_edma_tx_processq(struct ath_softc *sc, int dosched)
uint32_t txstatus[32];
#endif
DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: called\n", __func__);
for (idx = 0; ; idx++) {
bzero(&ts, sizeof(ts));
@ -812,8 +821,12 @@ ath_edma_tx_processq(struct ath_softc *sc, int dosched)
status = ath_hal_txprocdesc(ah, NULL, (void *) &ts);
ATH_TXSTATUS_UNLOCK(sc);
if (status == HAL_EINPROGRESS)
if (status == HAL_EINPROGRESS) {
DPRINTF(sc, ATH_DEBUG_TX_PROC,
"%s: (%d): EINPROGRESS\n",
__func__, idx);
break;
}
#ifdef ATH_DEBUG
if (sc->sc_debug & ATH_DEBUG_TX_PROC)
@ -1016,6 +1029,10 @@ ath_edma_tx_processq(struct ath_softc *sc, int dosched)
/* Attempt to schedule more hardware frames to the TX FIFO */
for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, i)) {
ATH_TX_LOCK(sc);
ath_txq_sched(sc, &sc->sc_txq[i]);
ATH_TX_UNLOCK(sc);
ATH_TXQ_LOCK(&sc->sc_txq[i]);
ath_edma_tx_fifo_fill(sc, &sc->sc_txq[i]);
ATH_TXQ_UNLOCK(&sc->sc_txq[i]);
@ -1024,6 +1041,8 @@ ath_edma_tx_processq(struct ath_softc *sc, int dosched)
/* Kick software scheduler */
ath_tx_swq_kick(sc);
}
DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: end\n", __func__);
}
static void