Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 3 Aug 2011 08:55:51 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r224628 - user/adrian/if_ath_tx/sys/dev/ath
Message-ID:  <201108030855.p738tpJ8094094@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Wed Aug  3 08:55:50 2011
New Revision: 224628
URL: http://svn.freebsd.org/changeset/base/224628

Log:
  Implement TID TX queue pause and unpause.
  
  This is needed for a clean implementation of ADDBA packet buffering.

Modified:
  user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c
  user/adrian/if_ath_tx/sys/dev/ath/if_athvar.h

Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c	Wed Aug  3 07:44:15 2011	(r224627)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c	Wed Aug  3 08:55:50 2011	(r224628)
@@ -1542,6 +1542,38 @@ ath_tx_tid_init(struct ath_softc *sc, st
 }
 
 /*
+ * Pause the current TID. This stops packets from being transmitted
+ * on it.
+ */
+static void
+ath_tx_tid_pause(struct ath_softc *sc, struct ath_tid *tid)
+{
+	int ac = TID_TO_WME_AC(tid->tid);
+	struct ath_txq *txq = sc->sc_ac2q[ac];
+
+	ATH_TXQ_LOCK_ASSERT(txq);
+	tid->paused++;
+}
+
+static void
+ath_tx_tid_resume(struct ath_softc *sc, struct ath_tid *tid)
+{
+	int ac = TID_TO_WME_AC(tid->tid);
+	struct ath_txq *txq = sc->sc_ac2q[ac];
+
+	ATH_TXQ_LOCK_ASSERT(txq);
+	tid->paused--;
+
+	if (tid->paused)
+		return;
+	if (tid->axq_depth == 0)
+		return;
+
+	ath_tx_node_sched(sc, tid->an, tid->tid);
+	ath_txq_sched(sc, txq);
+}
+
+/*
  * Mark packets currently in the hardware TXQ from this TID
  * as now having no parent software TXQ.
  *
@@ -1763,8 +1795,12 @@ ath_txq_sched(struct ath_softc *sc, stru
 	 * packets at the hardware.
 	 */
 	STAILQ_FOREACH_SAFE(atid, &txq->axq_tidq, axq_qelem, next) {
-		if (ath_tx_ampdu_pending(sc, atid->an, atid->tid)) {
-			/* XXX TODO should remove it from the list */
+		/*
+		 * Suspend paused queues here; they'll be resumed
+		 * once the addba completes or times out.
+		 */
+		if (atid->paused) {
+			ath_tx_node_unsched(sc, atid->an, atid->tid);
 			continue;
 		}
 		if (ath_tx_ampdu_running(sc, atid->an, atid->tid))
@@ -1850,6 +1886,14 @@ ath_addba_request(struct ieee80211_node 
     int dialogtoken, int baparamset, int batimeout)
 {
 	struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+	int tid = WME_AC_TO_TID(tap->txa_ac);
+	struct ath_node *an = ATH_NODE(ni);
+	struct ath_tid *atid = &an->an_tid[tid];
+
+	ATH_TXQ_LOCK(sc->sc_ac2q[tap->txa_ac]);
+	ath_tx_tid_pause(sc, atid);
+	ATH_TXQ_UNLOCK(sc->sc_ac2q[tap->txa_ac]);
+
 	return sc->sc_addba_request(ni, tap, dialogtoken, baparamset,
 	    batimeout);
 }
@@ -1867,11 +1911,13 @@ ath_addba_response(struct ieee80211_node
     int dialogtoken, int code, int batimeout)
 {
 	struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+	int tid = WME_AC_TO_TID(tap->txa_ac);
+	struct ath_node *an = ATH_NODE(ni);
+	struct ath_tid *atid = &an->an_tid[tid];
 
-	/*
-	 * XXX todo: resume the ath_node/TID now, rather than
-	 * XXX waiting for the next packet to trigger a TX.
-	 */
+	ATH_TXQ_LOCK(sc->sc_ac2q[tap->txa_ac]);
+	ath_tx_tid_resume(sc, atid);
+	ATH_TXQ_UNLOCK(sc->sc_ac2q[tap->txa_ac]);
 	return sc->sc_addba_response(ni, tap, dialogtoken, code, batimeout);
 }
 
@@ -1887,5 +1933,11 @@ void
 ath_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
 {
 	struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+#if 0
+	int tid = WME_AC_TO_TID(tap->txa_ac);
+	struct ath_node *an = ATH_NODE(ni);
+	struct ath_tid *atid = an->an_tid[tid];
+#endif
+
 	sc->sc_addba_stop(ni, tap);
 }

Modified: user/adrian/if_ath_tx/sys/dev/ath/if_athvar.h
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/ath/if_athvar.h	Wed Aug  3 07:44:15 2011	(r224627)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_athvar.h	Wed Aug  3 08:55:50 2011	(r224628)
@@ -102,6 +102,7 @@ struct ath_tid {
 	 */
 	STAILQ_ENTRY(ath_tid)	axq_qelem;
 	int			sched;
+	int			paused;	/* >0 if the TID has been paused */
 
 	/*
 	 * The following implements a ring representing



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201108030855.p738tpJ8094094>