svn commit: r288318 - head/sys/net80211

Adrian Chadd adrian at FreeBSD.org
Mon Sep 28 00:59:09 UTC 2015


Author: adrian
Date: Mon Sep 28 00:59:07 2015
New Revision: 288318
URL: https://svnweb.freebsd.org/changeset/base/288318

Log:
  Migrate the fast-frames transmit support away from using the txa_private
  field and into a separate fast-frames staging pointer in ieee80211_node.
  
  The A-MPDU TX path allows txa_private to be used by drivers.  So it will
  clash with any attempt to use fast-frames.  Now, fast-frames is not really
  anything special - it's just a custom ethernet frame type that contains
  two MSDUs into one MPDU.  So all the NIC has to support doing is transmitting
  up to a 4KiB frame with an arbitrary ethertype and bam! Fast-frames.
  However, using txa_private means we can /either/ do fast-frames or A-MPDU TX,
  so fast frames has been turned off in the Atheros HAL for 11n chipsets.
  This is a bit silly - it actually means that 802.11 performance to/from
  11abg Atheros chips is actually better than between an 11abg atheros device
  and an 11n Atheros device.
  
  So:
  
  * create a new mbuf staging queue for fast frames.  It only queues a single
    frame in the staging queue (and there's a top-level ic staging queue
    used for expiry/tracking) so it's just an mbuf pointer per TID.
  
  * Still use the ampdu TX packet counter to determine whether to do
    aggregation or not.  It'll double count if we start doing both A-MPDU TX
    and fast frames, but that's not all that important right now.
  
  * Initialise the pps tracker so ticks isn't zero.  This ensures that
    fast-frames actually gets used - without it, the ticks math overflows
    and the pps math always sets txa_pps=0.  This is the same bug that
    plagued A-MPDU TX starting logic.
  
  This actually allows fast-frames transmit to occur between the AR9331
  (in 11n HT/20 mode) and AR9170 (if_otus) in 11bg mode.
  
  Now, this is a great big no-op on atheros 11n hardware, so don't worry.
  It may mean you start seeing more reliable fast-frames transmission on
  11abg hardware which may expose some more amusing bugs.
  
  TODO:
  
  * further testing and debugging of all of this before flipping on
    fast-frames in if_ath (for 11n) and if_otus.

Modified:
  head/sys/net80211/ieee80211_node.h
  head/sys/net80211/ieee80211_superg.c

Modified: head/sys/net80211/ieee80211_node.h
==============================================================================
--- head/sys/net80211/ieee80211_node.h	Mon Sep 28 00:51:24 2015	(r288317)
+++ head/sys/net80211/ieee80211_node.h	Mon Sep 28 00:59:07 2015	(r288318)
@@ -219,6 +219,9 @@ struct ieee80211_node {
 	struct ieee80211_tx_ampdu ni_tx_ampdu[WME_NUM_TID];
 	struct ieee80211_rx_ampdu ni_rx_ampdu[WME_NUM_TID];
 
+	/* fast-frames state */
+	struct mbuf *		ni_tx_superg[WME_NUM_TID];
+
 	/* others */
 	short			ni_inact;	/* inactivity mark count */
 	short			ni_inact_reload;/* inactivity reload value */

Modified: head/sys/net80211/ieee80211_superg.c
==============================================================================
--- head/sys/net80211/ieee80211_superg.c	Mon Sep 28 00:51:24 2015	(r288317)
+++ head/sys/net80211/ieee80211_superg.c	Mon Sep 28 00:59:07 2015	(r288318)
@@ -530,7 +530,6 @@ ieee80211_ff_age(struct ieee80211com *ic
 {
 	struct mbuf *m, *head;
 	struct ieee80211_node *ni;
-	struct ieee80211_tx_ampdu *tap;
 
 #if 0
 	KASSERT(sq->head != NULL, ("stageq empty"));
@@ -541,11 +540,10 @@ ieee80211_ff_age(struct ieee80211com *ic
 	while ((m = sq->head) != NULL && M_AGE_GET(m) < quanta) {
 		int tid = WME_AC_TO_TID(M_WME_GETAC(m));
 
-		/* clear tap ref to frame */
+		/* clear staging ref to frame */
 		ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
-		tap = &ni->ni_tx_ampdu[tid];
-		KASSERT(tap->txa_private == m, ("staging queue empty"));
-		tap->txa_private = NULL;
+		KASSERT(ni->ni_tx_superg[tid] == m, ("staging queue empty"));
+		ni->ni_tx_superg[tid] = NULL;
 
 		sq->head = m->m_nextpkt;
 		sq->depth--;
@@ -658,7 +656,12 @@ ieee80211_ff_check(struct ieee80211_node
 	 */
 	IEEE80211_LOCK(ic);
 	tap = &ni->ni_tx_ampdu[WME_AC_TO_TID(pri)];
-	mstaged = tap->txa_private;		/* NB: we reuse AMPDU state */
+	mstaged = ni->ni_tx_superg[WME_AC_TO_TID(pri)];
+	/* XXX NOTE: reusing packet counter state from A-MPDU */
+	/*
+	 * XXX NOTE: this means we're double-counting; it should just
+	 * be done in ieee80211_output.c once for both superg and A-MPDU.
+	 */
 	ieee80211_txampdu_count_packet(tap);
 
 	/*
@@ -676,6 +679,8 @@ ieee80211_ff_check(struct ieee80211_node
 	 * If there is no frame to combine with and the pps is
 	 * too low; then do not attempt to aggregate this frame.
 	 */
+	IEEE80211_DPRINTF(vap, IEEE80211_MSG_SUPERG,
+	    "%s: staged: %p; pps: %d\n", __func__, mstaged, ieee80211_txampdu_getpps(tap));
 	if (mstaged == NULL &&
 	    ieee80211_txampdu_getpps(tap) < ieee80211_ffppsmin) {
 		IEEE80211_UNLOCK(ic);
@@ -698,7 +703,7 @@ ieee80211_ff_check(struct ieee80211_node
 		    "%s: txtime %u exceeds txop limit %u\n",
 		    __func__, txtime, limit);
 
-		tap->txa_private = NULL;
+		ni->ni_tx_superg[WME_AC_TO_TID(pri)] = NULL;
 		if (mstaged != NULL)
 			stageq_remove(ic, sq, mstaged);
 		IEEE80211_UNLOCK(ic);
@@ -721,7 +726,7 @@ ieee80211_ff_check(struct ieee80211_node
 	 * hold their node reference.
 	 */
 	if (mstaged != NULL) {
-		tap->txa_private = NULL;
+		ni->ni_tx_superg[WME_AC_TO_TID(pri)] = NULL;
 		stageq_remove(ic, sq, mstaged);
 		IEEE80211_UNLOCK(ic);
 
@@ -739,9 +744,10 @@ ieee80211_ff_check(struct ieee80211_node
 		mstaged->m_nextpkt = m;
 		mstaged->m_flags |= M_FF; /* NB: mark for encap work */
 	} else {
-		KASSERT(tap->txa_private == NULL,
-		    ("txa_private %p", tap->txa_private));
-		tap->txa_private = m;
+		KASSERT(ni->ni_tx_superg[WME_AC_TO_TID(pri)]== NULL,
+		    ("ni_tx_superg[]: %p",
+		    ni->ni_tx_superg[WME_AC_TO_TID(pri)]));
+		ni->ni_tx_superg[WME_AC_TO_TID(pri)] = m;
 
 		stageq_add(ic, sq, m);
 		IEEE80211_UNLOCK(ic);
@@ -769,7 +775,6 @@ ieee80211_ff_node_cleanup(struct ieee802
 {
 	struct ieee80211com *ic = ni->ni_ic;
 	struct ieee80211_superg *sg = ic->ic_superg;
-	struct ieee80211_tx_ampdu *tap;
 	struct mbuf *m, *next_m, *head;
 	int tid;
 
@@ -777,11 +782,16 @@ ieee80211_ff_node_cleanup(struct ieee802
 	head = NULL;
 	for (tid = 0; tid < WME_NUM_TID; tid++) {
 		int ac = TID_TO_WME_AC(tid);
-
-		tap = &ni->ni_tx_ampdu[tid];
-		m = tap->txa_private;
+		/*
+		 * XXX Initialise the packet counter.
+		 *
+		 * This may be double-work for 11n stations;
+		 * but without it we never setup things.
+		 */
+		ieee80211_txampdu_init_pps(&ni->ni_tx_ampdu[tid]);
+		m = ni->ni_tx_superg[tid];
 		if (m != NULL) {
-			tap->txa_private = NULL;
+			ni->ni_tx_superg[tid] = NULL;
 			stageq_remove(ic, &sg->ff_stageq[ac], m);
 			m->m_nextpkt = head;
 			head = m;


More information about the svn-src-head mailing list