Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 11 Jun 2011 07:42:18 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r222978 - user/adrian/if_ath_tx/sys/dev/ath
Message-ID:  <201106110742.p5B7gI7H064031@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Sat Jun 11 07:42:18 2011
New Revision: 222978
URL: http://svn.freebsd.org/changeset/base/222978

Log:
  Flesh out some more software TX queue operators.
  
  There's still a few more operators (queue software packet to hardware,
  requeue packet (from hardware) back onto the software queue, free
  software queue packets that aren't on the hardware, and mark queued packets
  as having no parent queue) to implement.
  
  It's unclear yet whether packets which are queued but whose parent node
  is going away should cause the TXCB callback to occur if needed.

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

Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath.c
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/ath/if_ath.c	Sat Jun 11 06:56:26 2011	(r222977)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_ath.c	Sat Jun 11 07:42:18 2011	(r222978)
@@ -3112,6 +3112,7 @@ ath_node_alloc(struct ieee80211vap *vap,
 	ath_rate_node_init(sc, an);
 
 	/* XXX setup ath_tid */
+	ath_tx_tid_init(sc, an);
 
 	DPRINTF(sc, ATH_DEBUG_NODE, "%s: an %p\n", __func__, an);
 	return &an->an_node;
@@ -3125,8 +3126,8 @@ ath_node_free(struct ieee80211_node *ni)
 
 	DPRINTF(sc, ATH_DEBUG_NODE, "%s: ni %p\n", __func__, ni);
 
-	/* XXX ensure it's not scheduled on the TXQ; remove if needed */
-	/* XXX cleanup ath_tid */
+	/* Cleanup ath_tid, free unused bufs, unlink bufs in TXQ */
+	ath_tx_tid_cleanup(sc, ATH_NODE(ni));
 
 	ath_rate_node_cleanup(sc, ATH_NODE(ni));
 	sc->sc_node_free(ni);

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	Sat Jun 11 06:56:26 2011	(r222977)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c	Sat Jun 11 07:42:18 2011	(r222978)
@@ -1215,6 +1215,8 @@ bad:
  *
  * This is done to make it easy for the software scheduler to 
  * find which nodes/TIDs have data to send.
+ *
+ * This must be called with the TX/ATH lock held.
  */
 static void
 ath_tx_node_sched(struct ath_softc *sc, struct ath_node *an, int tid)
@@ -1232,6 +1234,22 @@ ath_tx_node_sched(struct ath_softc *sc, 
 }
 
 /*
+ * Mark the current node/TID as no longer needing to be polled for
+ * TX packets.
+ *
+ * This must be called with the TX/ATH lock held.
+ */
+static void
+ath_tx_node_unsched(struct ath_softc *sc, struct ath_node *an, int tid)
+{
+	if (an->sched == 0)
+		return;
+
+	STAILQ_REMOVE(&sc->sc_txnodeq, an, ath_node, an_list);
+	an->sched = 0;
+}
+
+/*
  * Queue the given packet on the relevant software queue.
  *
  * This however doesn't queue the packet to the hardware!
@@ -1269,3 +1287,80 @@ ath_tx_swq(struct ath_softc *sc, struct 
  * Note that this may cause the mbuf to be reallocated, so
  * m0 may not be valid.
  */
+
+
+/*
+ * Configure the per-TID node state.
+ *
+ * This likely belongs in if_ath_node.c but I can't think of anywhere
+ * else to put it just yet.
+ *
+ * This sets up the SLISTs and the mutex as appropriate.
+ */
+void
+ath_tx_tid_init(struct ath_softc *sc, struct ath_node *an)
+{
+	int i;
+	struct ath_tid *atid;
+	struct ieee80211_node *ni = &an->an_node;
+
+	for (i = 0; i < IEEE80211_TID_SIZE; i++) {
+		atid = &an->an_tid[i];
+		STAILQ_INIT(&atid->axq_q);
+		snprintf(atid->axq_name, sizeof(atid->axq_name),
+		    "%s_a%d_t%d\n", device_get_nameunit(sc->sc_dev),
+		    ni->ni_associd,
+		    i);
+		mtx_init(&atid->axq_lock, atid->axq_name, NULL, MTX_DEF);
+	}
+}
+
+/*
+ * Mark packets currently in the hardware TXQ from this TID
+ * as now having no parent software TXQ.
+ *
+ * This is done when an ath_node goes away so any pending
+ * packets going out to the device are simply freed, rather
+ * than referencing some now-nonexisting ath_node.
+ *
+ * XXX make sure that access to the hardware TXQ is correctly locked!
+ */
+static void
+ath_tx_tid_txq_unmark(struct ath_softc *sc, struct ath_node *an,
+    int tid)
+{
+	/* XXX TODO */
+}
+
+/*
+ * Free the per-TID node state.
+ *
+ * This frees any packets currently in the software queue and frees
+ * any other TID state.
+ *
+ * Since node destruction currenty doesn't wait for the last
+ * packets to be xmited, there needs to be a good place to
+ * mark packets currently in the hardware TX queue as
+ * now having no parent node!
+ */
+void
+ath_tx_tid_cleanup(struct ath_softc *sc, struct ath_node *an)
+{
+	int i;
+	struct ath_tid *atid;
+
+	for (i = 0; i < IEEE80211_TID_SIZE; i++) {
+		atid = &an->an_tid[i];
+
+		/* Free packets in sw queue */
+
+		/* Mark hw-queued packets as having no parent now */
+		ath_tx_tid_txq_unmark(sc, an, i);
+
+		/* Remove any pending hardware TXQ scheduling */
+		ath_tx_node_unsched(sc, an, i);
+
+		/* Free mutex */
+		mtx_destroy(&atid->axq_lock);
+	}
+}

Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.h
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.h	Sat Jun 11 06:56:26 2011	(r222977)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.h	Sat Jun 11 07:42:18 2011	(r222978)
@@ -44,5 +44,8 @@ extern int ath_raw_xmit(struct ieee80211
 /* software queue stuff */
 extern void ath_tx_swq(struct ath_softc *sc, struct ieee80211_node *ni,
     struct ath_buf *bf, struct mbuf *m0);
+extern void ath_tx_tid_init(struct ath_softc *sc, struct ath_node *an);
+extern void ath_tx_tid_cleanup(struct ath_softc *sc, struct ath_node *an);
+
 
 #endif

Modified: user/adrian/if_ath_tx/sys/dev/ath/if_athvar.h
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/ath/if_athvar.h	Sat Jun 11 06:56:26 2011	(r222977)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_athvar.h	Sat Jun 11 07:42:18 2011	(r222978)
@@ -93,6 +93,8 @@ struct ath_buf;
 struct ath_tid {
 	STAILQ_HEAD(,ath_buf) axq_q;		/* pending buffers        */
 	u_int			axq_depth;	/* queue depth (stat only) */
+	struct mtx		axq_lock;	/* lock on queue, tx_buf */
+	char			axq_name[24];	/* e.g. "ath0_a1_t5" */
 	struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];	/* active tx buffers, beginning at current BAW */
 };
 



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