From 5d4dedadb67381a9837f8205aa1c77c060a11b83 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Tue, 16 Apr 2013 20:21:02 +0000 Subject: [PATCH] Use a per-RX-queue deferred list, rather than a single deferred list for both queues. Since ath_rx_pkt() does multi-mbuf frame recombining based on the RX queue, this needs to occur. Tested: * AR9380 (XB112), hostap mode --- sys/dev/ath/if_ath.c | 3 ++- sys/dev/ath/if_ath_rx_edma.c | 13 ++++++++++--- sys/dev/ath/if_athvar.h | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index c0d002d248b..85e2b4e86ab 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -842,7 +842,8 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) /* * Initialise the deferred completed RX buffer list. */ - TAILQ_INIT(&sc->sc_rx_rxlist); + TAILQ_INIT(&sc->sc_rx_rxlist[HAL_RX_QUEUE_HP]); + TAILQ_INIT(&sc->sc_rx_rxlist[HAL_RX_QUEUE_LP]); /* * Indicate we need the 802.11 header padded to a diff --git a/sys/dev/ath/if_ath_rx_edma.c b/sys/dev/ath/if_ath_rx_edma.c index 76ce0f3aebc..abfb57deed8 100644 --- a/sys/dev/ath/if_ath_rx_edma.c +++ b/sys/dev/ath/if_ath_rx_edma.c @@ -398,7 +398,7 @@ ath_edma_recv_proc_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype, * queue. */ re->m_fifo[re->m_fifo_head] = NULL; - TAILQ_INSERT_TAIL(&sc->sc_rx_rxlist, bf, bf_list); + TAILQ_INSERT_TAIL(&sc->sc_rx_rxlist[qtype], bf, bf_list); /* Bump the descriptor FIFO stats */ INCR(re->m_fifo_head, re->m_fifolen); @@ -451,8 +451,15 @@ ath_edma_flush_deferred_queue(struct ath_softc *sc) struct ath_buf *bf, *next; ATH_RX_LOCK_ASSERT(sc); + /* Free in one set, inside the lock */ - TAILQ_FOREACH_SAFE(bf, &sc->sc_rx_rxlist, bf_list, next) { + TAILQ_FOREACH_SAFE(bf, + &sc->sc_rx_rxlist[HAL_RX_QUEUE_LP], bf_list, next) { + /* Free the buffer/mbuf */ + ath_edma_rxbuf_free(sc, bf); + } + TAILQ_FOREACH_SAFE(bf, + &sc->sc_rx_rxlist[HAL_RX_QUEUE_HP], bf_list, next) { /* Free the buffer/mbuf */ ath_edma_rxbuf_free(sc, bf); } @@ -482,7 +489,7 @@ ath_edma_recv_proc_deferred_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype, /* Copy the list over */ ATH_RX_LOCK(sc); - TAILQ_CONCAT(&rxlist, &sc->sc_rx_rxlist, bf_list); + TAILQ_CONCAT(&rxlist, &sc->sc_rx_rxlist[qtype], bf_list); ATH_RX_UNLOCK(sc); /* Handle the completed descriptors */ diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h index 78580ace9a0..703bb53bb41 100644 --- a/sys/dev/ath/if_athvar.h +++ b/sys/dev/ath/if_athvar.h @@ -542,6 +542,7 @@ struct ath_softc { struct ath_rx_methods sc_rx; struct ath_rx_edma sc_rxedma[HAL_NUM_RX_QUEUES]; /* HP/LP queues */ + ath_bufhead sc_rx_rxlist[HAL_NUM_RX_QUEUES]; /* deferred RX completion */ struct ath_tx_methods sc_tx; struct ath_tx_edma_fifo sc_txedma[HAL_NUM_TX_QUEUES]; @@ -700,7 +701,6 @@ struct ath_softc { struct ath_descdma sc_rxdma; /* RX descriptors */ ath_bufhead sc_rxbuf; /* receive buffer */ - ath_bufhead sc_rx_rxlist; /* deferred RX completion */ u_int32_t *sc_rxlink; /* link ptr in last RX desc */ struct task sc_rxtask; /* rx int processing */ u_int8_t sc_defant; /* current default antenna */