diff options
Diffstat (limited to 'sys/dev/ath/if_ath.c')
-rw-r--r-- | sys/dev/ath/if_ath.c | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index 18fffaa..2dee99b 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -1369,7 +1369,6 @@ ath_vap_delete(struct ieee80211vap *vap) * Reclaim any pending mcast frames for the vap. */ ath_tx_draintxq(sc, &avp->av_mcastq); - ATH_TXQ_LOCK_DESTROY(&avp->av_mcastq); } /* * Update bookkeeping. @@ -2271,16 +2270,16 @@ ath_reset(struct ifnet *ifp, ATH_RESET_TYPE reset_type) /* Restart TX/RX as needed */ ath_txrx_start(sc); - /* XXX Restart TX completion and pending TX */ + /* Restart TX completion and pending TX */ if (reset_type == ATH_RESET_NOLOSS) { + ATH_TX_LOCK(sc); for (i = 0; i < HAL_NUM_TX_QUEUES; i++) { if (ATH_TXQ_SETUP(sc, i)) { - ATH_TXQ_LOCK(&sc->sc_txq[i]); ath_txq_restart_dma(sc, &sc->sc_txq[i]); ath_txq_sched(sc, &sc->sc_txq[i]); - ATH_TXQ_UNLOCK(&sc->sc_txq[i]); } } + ATH_TX_UNLOCK(sc); } /* @@ -2513,7 +2512,9 @@ ath_start_task(void *arg, int npending) sc->sc_txstart_cnt++; ATH_PCU_UNLOCK(sc); + ATH_TX_LOCK(sc); ath_start(sc->sc_ifp); + ATH_TX_UNLOCK(sc); ATH_PCU_LOCK(sc); sc->sc_txstart_cnt--; @@ -2534,6 +2535,8 @@ ath_start(struct ifnet *ifp) if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) return; + ATH_TX_LOCK_ASSERT(sc); + ATH_KTR(sc, ATH_KTR_TX, 0, "ath_start: called"); for (;;) { @@ -2605,6 +2608,10 @@ ath_start(struct ifnet *ifp) ath_returnbuf_head(sc, bf); ath_txfrag_cleanup(sc, &frags, ni); ATH_TXBUF_UNLOCK(sc); + /* + * XXX todo, free the node outside of + * the TX lock context! + */ if (ni != NULL) ieee80211_free_node(ni); continue; @@ -2816,9 +2823,6 @@ void ath_txqmove(struct ath_txq *dst, struct ath_txq *src) { - ATH_TXQ_LOCK_ASSERT(dst); - ATH_TXQ_LOCK_ASSERT(src); - TAILQ_CONCAT(&dst->axq_q, &src->axq_q, bf_list); dst->axq_link = src->axq_link; src->axq_link = NULL; @@ -3298,7 +3302,6 @@ ath_txq_init(struct ath_softc *sc, struct ath_txq *txq, int qnum) txq->axq_softc = sc; TAILQ_INIT(&txq->axq_q); TAILQ_INIT(&txq->axq_tidq); - ATH_TXQ_LOCK_INIT(sc, txq); } /* @@ -3482,7 +3485,6 @@ ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq) { ath_hal_releasetxqueue(sc->sc_ah, txq->axq_qnum); - ATH_TXQ_LOCK_DESTROY(txq); sc->sc_txqsetup &= ~(1<<txq->axq_qnum); } @@ -3691,7 +3693,7 @@ ath_tx_process_buf_completion(struct ath_softc *sc, struct ath_txq *txq, struct ieee80211_node *ni = bf->bf_node; struct ath_node *an = NULL; - ATH_TXQ_UNLOCK_ASSERT(txq); + ATH_TX_UNLOCK_ASSERT(sc); /* If unicast frame, update general statistics */ if (ni != NULL) { @@ -3760,11 +3762,11 @@ ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq, int dosched) nacked = 0; for (;;) { - ATH_TXQ_LOCK(txq); + ATH_TX_LOCK(sc); txq->axq_intrcnt = 0; /* reset periodic desc intr count */ bf = TAILQ_FIRST(&txq->axq_q); if (bf == NULL) { - ATH_TXQ_UNLOCK(txq); + ATH_TX_UNLOCK(sc); break; } ds = bf->bf_lastds; /* XXX must be setup correctly! */ @@ -3792,7 +3794,7 @@ ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq, int dosched) ATH_KTR(sc, ATH_KTR_TXCOMP, 3, "ath_tx_processq: txq=%u, bf=%p ds=%p, HAL_EINPROGRESS", txq->axq_qnum, bf, ds); - ATH_TXQ_UNLOCK(txq); + ATH_TX_UNLOCK(sc); break; } ATH_TXQ_REMOVE(txq, bf, bf_list); @@ -3833,7 +3835,7 @@ ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq, int dosched) ATH_RSSI_LPF(sc->sc_halstats.ns_avgtxrssi, ts->ts_rssi); } - ATH_TXQ_UNLOCK(txq); + ATH_TX_UNLOCK(sc); /* * Update statistics and call completion @@ -3852,9 +3854,9 @@ ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq, int dosched) /* Kick the TXQ scheduler */ if (dosched) { - ATH_TXQ_LOCK(txq); + ATH_TX_LOCK(sc); ath_txq_sched(sc, txq); - ATH_TXQ_UNLOCK(txq); + ATH_TX_UNLOCK(sc); } ATH_KTR(sc, ATH_KTR_TXCOMP, 1, @@ -4027,13 +4029,13 @@ ath_txq_sched_tasklet(void *arg, int npending) sc->sc_txproc_cnt++; ATH_PCU_UNLOCK(sc); + ATH_TX_LOCK(sc); for (i = 0; i < HAL_NUM_TX_QUEUES; i++) { if (ATH_TXQ_SETUP(sc, i)) { - ATH_TXQ_LOCK(&sc->sc_txq[i]); ath_txq_sched(sc, &sc->sc_txq[i]); - ATH_TXQ_UNLOCK(&sc->sc_txq[i]); } } + ATH_TX_UNLOCK(sc); ATH_PCU_LOCK(sc); sc->sc_txproc_cnt--; @@ -4166,7 +4168,7 @@ ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq) ATH_TXBUF_UNLOCK(sc); for (ix = 0;; ix++) { - ATH_TXQ_LOCK(txq); + ATH_TX_LOCK(sc); bf = TAILQ_FIRST(&txq->axq_q); if (bf == NULL) { txq->axq_link = NULL; @@ -4181,7 +4183,7 @@ ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq) * very fruity very quickly. */ txq->axq_fifo_depth = 0; - ATH_TXQ_UNLOCK(txq); + ATH_TX_UNLOCK(sc); break; } ATH_TXQ_REMOVE(txq, bf, bf_list); @@ -4217,7 +4219,7 @@ ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq) * Clear ATH_BUF_BUSY; the completion handler * will free the buffer. */ - ATH_TXQ_UNLOCK(txq); + ATH_TX_UNLOCK(sc); bf->bf_flags &= ~ATH_BUF_BUSY; if (bf->bf_comp) bf->bf_comp(sc, bf, 1); |