Preparation for correct 802.11n tx/rx handling.
* Change ath_rx_proc() to ath_rx_tasklet(); make that the taskqueue function. This way (eventually) ath_rx_proc() can be called from elsewhere in the packet reset/processing queue so frames aren't just "flushed" during interface resets/reconfigure. This breaks 802.11n RX aggregation tracking. * Extend ath_tx_proc() to take a 'resched' flag, which marks whether to reschedule further RX PCU reads or not. * Change ath_tx_processq() to take a "dosched" flag, which will eventually be used to indicate whether to reschedule the software TX scheduler. Sponsored by: Hobnob, Inc.
This commit is contained in:
parent
0f0c074eaa
commit
96ff485dc3
@ -170,7 +170,8 @@ static int ath_rxbuf_init(struct ath_softc *, struct ath_buf *);
|
||||
static void ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
|
||||
int subtype, int rssi, int nf);
|
||||
static void ath_setdefantenna(struct ath_softc *, u_int);
|
||||
static void ath_rx_proc(void *, int);
|
||||
static void ath_rx_proc(struct ath_softc *sc, int);
|
||||
static void ath_rx_tasklet(void *, int);
|
||||
static void ath_txq_init(struct ath_softc *sc, struct ath_txq *, int);
|
||||
static struct ath_txq *ath_txq_setup(struct ath_softc*, int qtype, int subtype);
|
||||
static int ath_tx_setup(struct ath_softc *, int, int);
|
||||
@ -382,7 +383,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
|
||||
taskqueue_start_threads(&sc->sc_tq, 1, PI_NET,
|
||||
"%s taskq", ifp->if_xname);
|
||||
|
||||
TASK_INIT(&sc->sc_rxtask, 0, ath_rx_proc, sc);
|
||||
TASK_INIT(&sc->sc_rxtask, 0, ath_rx_tasklet, sc);
|
||||
TASK_INIT(&sc->sc_bmisstask, 0, ath_bmiss_proc, sc);
|
||||
TASK_INIT(&sc->sc_bstucktask,0, ath_bstuck_proc, sc);
|
||||
|
||||
@ -3505,13 +3506,27 @@ ath_handle_micerror(struct ieee80211com *ic,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Only run the RX proc if it's not already running.
|
||||
* Since this may get run as part of the reset/flush path,
|
||||
* the task can't clash with an existing, running tasklet.
|
||||
*/
|
||||
static void
|
||||
ath_rx_proc(void *arg, int npending)
|
||||
ath_rx_tasklet(void *arg, int npending)
|
||||
{
|
||||
struct ath_softc *sc = arg;
|
||||
|
||||
CTR1(ATH_KTR_INTR, "ath_rx_proc: pending=%d", npending);
|
||||
DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending);
|
||||
ath_rx_proc(sc, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
ath_rx_proc(struct ath_softc *sc, int resched)
|
||||
{
|
||||
#define PA2DESC(_sc, _pa) \
|
||||
((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \
|
||||
((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))
|
||||
struct ath_softc *sc = arg;
|
||||
struct ath_buf *bf;
|
||||
struct ifnet *ifp = sc->sc_ifp;
|
||||
struct ieee80211com *ic = ifp->if_l2com;
|
||||
@ -3526,7 +3541,7 @@ ath_rx_proc(void *arg, int npending)
|
||||
u_int64_t tsf;
|
||||
int npkts = 0;
|
||||
|
||||
DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending);
|
||||
DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: called\n", __func__);
|
||||
ngood = 0;
|
||||
nf = ath_hal_getchannoise(ah, sc->sc_curchan);
|
||||
sc->sc_stats.ast_rx_noise = nf;
|
||||
@ -3862,7 +3877,7 @@ ath_rx_proc(void *arg, int npending)
|
||||
sc->sc_lastrx = tsf;
|
||||
|
||||
/* Queue DFS tasklet if needed */
|
||||
if (ath_dfs_tasklet_needed(sc, sc->sc_curchan))
|
||||
if (resched && ath_dfs_tasklet_needed(sc, sc->sc_curchan))
|
||||
taskqueue_enqueue(sc->sc_tq, &sc->sc_dfstask);
|
||||
|
||||
/*
|
||||
@ -3870,7 +3885,7 @@ ath_rx_proc(void *arg, int npending)
|
||||
* need to be handled, kick the PCU if there's
|
||||
* been an RXEOL condition.
|
||||
*/
|
||||
if (sc->sc_kickpcu) {
|
||||
if (resched && sc->sc_kickpcu) {
|
||||
device_printf(sc->sc_dev, "%s: kickpcu; handled %d packets\n",
|
||||
__func__, npkts);
|
||||
|
||||
@ -3887,7 +3902,7 @@ ath_rx_proc(void *arg, int npending)
|
||||
ATH_UNLOCK(sc);
|
||||
}
|
||||
|
||||
if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
|
||||
if (resched && (ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
|
||||
#ifdef IEEE80211_SUPPORT_SUPERG
|
||||
ieee80211_ff_age_all(ic, 100);
|
||||
#endif
|
||||
@ -4121,7 +4136,7 @@ ath_tx_findrix(const struct ath_softc *sc, uint8_t rate)
|
||||
* Process completed xmit descriptors from the specified queue.
|
||||
*/
|
||||
static int
|
||||
ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
||||
ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq, int dosched)
|
||||
{
|
||||
struct ath_hal *ah = sc->sc_ah;
|
||||
struct ifnet *ifp = sc->sc_ifp;
|
||||
@ -4287,11 +4302,11 @@ ath_tx_proc_q0(void *arg, int npending)
|
||||
sc->sc_txq_active &= ~txqs;
|
||||
ATH_UNLOCK(sc);
|
||||
|
||||
if (TXQACTIVE(txqs, 0) && ath_tx_processq(sc, &sc->sc_txq[0]))
|
||||
if (TXQACTIVE(txqs, 0) && ath_tx_processq(sc, &sc->sc_txq[0], 1))
|
||||
/* XXX why is lastrx updated in tx code? */
|
||||
sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah);
|
||||
if (TXQACTIVE(txqs, sc->sc_cabq->axq_qnum))
|
||||
ath_tx_processq(sc, sc->sc_cabq);
|
||||
ath_tx_processq(sc, sc->sc_cabq, 1);
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
sc->sc_wd_timer = 0;
|
||||
|
||||
@ -4323,15 +4338,15 @@ ath_tx_proc_q0123(void *arg, int npending)
|
||||
*/
|
||||
nacked = 0;
|
||||
if (TXQACTIVE(txqs, 0))
|
||||
nacked += ath_tx_processq(sc, &sc->sc_txq[0]);
|
||||
nacked += ath_tx_processq(sc, &sc->sc_txq[0], 1);
|
||||
if (TXQACTIVE(txqs, 1))
|
||||
nacked += ath_tx_processq(sc, &sc->sc_txq[1]);
|
||||
nacked += ath_tx_processq(sc, &sc->sc_txq[1], 1);
|
||||
if (TXQACTIVE(txqs, 2))
|
||||
nacked += ath_tx_processq(sc, &sc->sc_txq[2]);
|
||||
nacked += ath_tx_processq(sc, &sc->sc_txq[2], 1);
|
||||
if (TXQACTIVE(txqs, 3))
|
||||
nacked += ath_tx_processq(sc, &sc->sc_txq[3]);
|
||||
nacked += ath_tx_processq(sc, &sc->sc_txq[3], 1);
|
||||
if (TXQACTIVE(txqs, sc->sc_cabq->axq_qnum))
|
||||
ath_tx_processq(sc, sc->sc_cabq);
|
||||
ath_tx_processq(sc, sc->sc_cabq, 1);
|
||||
if (nacked)
|
||||
sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah);
|
||||
|
||||
@ -4366,7 +4381,7 @@ ath_tx_proc(void *arg, int npending)
|
||||
nacked = 0;
|
||||
for (i = 0; i < HAL_NUM_TX_QUEUES; i++)
|
||||
if (ATH_TXQ_SETUP(sc, i) && TXQACTIVE(txqs, i))
|
||||
nacked += ath_tx_processq(sc, &sc->sc_txq[i]);
|
||||
nacked += ath_tx_processq(sc, &sc->sc_txq[i], 1);
|
||||
if (nacked)
|
||||
sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user