Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 043a0405 authored by Sujith's avatar Sujith Committed by John W. Linville
Browse files

ath9k: Merge queue draining functions



The TX queue draining routines have confusing names,
rename them approprately and merge ath_drain_txdataq()
with ath_drain_all_txq().

Signed-off-by: default avatarSujith <Sujith.Manoharan@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 55f5e4a9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -220,7 +220,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
		 * acquires txq lock inside.
		 */
		if (sc->sc_nvaps > 1) {
			ath_tx_draintxq(sc, cabq, false);
			ath_draintxq(sc, cabq, false);
			DPRINTF(sc, ATH_DBG_BEACON,
				"flush previous cabq traffic\n");
		}
+2 −2
Original line number Diff line number Diff line
@@ -485,8 +485,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush);
struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
int ath_tx_setup(struct ath_softc *sc, int haltype);
void ath_draintxq(struct ath_softc *sc, bool retry_tx);
void ath_tx_draintxq(struct ath_softc *sc,
void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
void ath_draintxq(struct ath_softc *sc,
		     struct ath_txq *txq, bool retry_tx);
void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
+4 −4
Original line number Diff line number Diff line
@@ -247,7 +247,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
	 * the relevant bits of the h/w.
	 */
	ath9k_hw_set_interrupts(ah, 0);
	ath_draintxq(sc, false);
	ath_drain_all_txq(sc, false);
	stopped = ath_stoprecv(sc);

	/* XXX: do not flush receive queue here. We don't want
@@ -1092,7 +1092,7 @@ static void ath_radio_disable(struct ath_softc *sc)
	/* Disable interrupts */
	ath9k_hw_set_interrupts(ah, 0);

	ath_draintxq(sc, false);	/* clear pending tx frames */
	ath_drain_all_txq(sc, false);	/* clear pending tx frames */
	ath_stoprecv(sc);		/* turn off frame recv */
	ath_flushrecv(sc);		/* flush recv queue */

@@ -1592,7 +1592,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
	int r;

	ath9k_hw_set_interrupts(ah, 0);
	ath_draintxq(sc, retry_tx);
	ath_drain_all_txq(sc, retry_tx);
	ath_stoprecv(sc);
	ath_flushrecv(sc);

@@ -1988,7 +1988,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
	ath9k_hw_set_interrupts(sc->sc_ah, 0);

	if (!(sc->sc_flags & SC_OP_INVALID)) {
		ath_draintxq(sc, false);
		ath_drain_all_txq(sc, false);
		ath_stoprecv(sc);
		ath9k_hw_phy_disable(sc->sc_ah);
	} else
+48 −50
Original line number Diff line number Diff line
@@ -890,43 +890,6 @@ static void ath_get_beaconconfig(struct ath_softc *sc, int if_id,
	conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval;
}

static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
{
	struct ath_hal *ah = sc->sc_ah;
	struct ath_txq *txq;
	int i, npend = 0;

	if (sc->sc_flags & SC_OP_INVALID)
		return;

	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
		if (ATH_TXQ_SETUP(sc, i)) {
			txq = &sc->tx.txq[i];
			ath9k_hw_stoptxdma(ah, txq->axq_qnum);
			npend += ath9k_hw_numtxpending(ah, txq->axq_qnum);
		}
	}

	if (npend) {
		int r;

		DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");

		spin_lock_bh(&sc->sc_resetlock);
		r = ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, true);
		if (r)
			DPRINTF(sc, ATH_DBG_FATAL,
				"Unable to reset hardware; reset status %u\n",
				r);
		spin_unlock_bh(&sc->sc_resetlock);
	}

	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
		if (ATH_TXQ_SETUP(sc, i))
			ath_tx_draintxq(sc, &sc->tx.txq[i], retry_tx);
	}
}

static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
					  struct ath_txq *txq)
{
@@ -1120,17 +1083,19 @@ int ath_cabq_update(struct ath_softc *sc)
	return 0;
}

void ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
/*
 * Drain a given TX queue (could be Beacon or Data)
 *
 * This assumes output has been stopped and
 * we do not need to block ath_tx_tasklet.
 */
void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
{
	struct ath_buf *bf, *lastbf;
	struct list_head bf_head;

	INIT_LIST_HEAD(&bf_head);

	/*
	 * NB: this assumes output has been stopped and
	 *     we do not need to block ath_tx_tasklet
	 */
	for (;;) {
		spin_lock_bh(&txq->axq_lock);

@@ -1180,18 +1145,51 @@ void ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
	}
}

void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
{
	ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
	sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
	struct ath_hal *ah = sc->sc_ah;
	struct ath_txq *txq;
	int i, npend = 0;

	if (sc->sc_flags & SC_OP_INVALID)
		return;

	/* Stop beacon queue */
	ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);

	/* Stop data queues */
	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
		if (ATH_TXQ_SETUP(sc, i)) {
			txq = &sc->tx.txq[i];
			ath9k_hw_stoptxdma(ah, txq->axq_qnum);
			npend += ath9k_hw_numtxpending(ah, txq->axq_qnum);
		}
	}

void ath_draintxq(struct ath_softc *sc, bool retry_tx)
{
	if (!(sc->sc_flags & SC_OP_INVALID))
		(void) ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
	if (npend) {
		int r;

	ath_drain_txdataq(sc, retry_tx);
		DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");

		spin_lock_bh(&sc->sc_resetlock);
		r = ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, true);
		if (r)
			DPRINTF(sc, ATH_DBG_FATAL,
				"Unable to reset hardware; reset status %u\n",
				r);
		spin_unlock_bh(&sc->sc_resetlock);
	}

	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
		if (ATH_TXQ_SETUP(sc, i))
			ath_draintxq(sc, &sc->tx.txq[i], retry_tx);
	}
}

void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
{
	ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
	sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
}

void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)