svn commit: r225381 - user/adrian/if_ath_tx/sys/dev/ath

Adrian Chadd adrian at FreeBSD.org
Mon Sep 5 00:10:37 UTC 2011


Author: adrian
Date: Mon Sep  5 00:10:37 2011
New Revision: 225381
URL: http://svn.freebsd.org/changeset/base/225381

Log:
  Migrate the rate control selection out from the packet setup code and
  instead call it just before the packet is TXed.
  
  For non-aggregate packets, call it just before the frame is queued
  to hardware.
  
  For aggregate packets, call it on the first frame in the aggregate
  list so the aggregate code itself has a rate control selection to
  use when building the aggregate.
  
  This allows for some useful behaviour:
  
  * rate selection is now not done per-frame when doing aggregation.
    Aggregation only requires a rate lookup for the first frame.
    The rest are ignored.
  
  * The rate control module now gets a more "balanced" idea of how many
    times findrate is called versus completion. Beforehand, findrate
    would be called for each frame, but completion would be called for
    the entire aggregate.
  
  * software retransmission now allows for a new rate lookup - that way
    the retransmits aren't done using the same failing rates.
  
  This improves the aggregate throughput stability but it doesn't fix
  things entirely - primarily because ath_rate_sample is still making
  some very poor rate control decisions (eg dipping down to single-stream
  rates and trying MCS14/15 when it doesn't work.)

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	Sun Sep  4 22:06:32 2011	(r225380)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c	Mon Sep  5 00:10:37 2011	(r225381)
@@ -824,6 +824,43 @@ ath_tx_setds(struct ath_softc *sc, struc
 }
 
 /*
+ * Do a rate lookup.
+ *
+ * This performs a rate lookup for the given ath_buf only if it's required.
+ * Non-data frames and raw frames don't require it.
+ *
+ * This populates the primary and MRR entries; MRR values are
+ * then disabled later on if something requires it (eg RTS/CTS on
+ * pre-11n chipsets.
+ *
+ * This needs to be done before the RTS/CTS fields are calculated
+ * as they may depend upon the rate chosen.
+ */
+static void
+ath_tx_do_ratelookup(struct ath_softc *sc, struct ath_buf *bf)
+{
+	uint8_t rate, rix;
+	int try0;
+
+	if (! bf->bf_state.bfs_doratelookup)
+		return;
+
+	ATH_NODE_LOCK(ATH_NODE(bf->bf_node));
+	ath_rate_findrate(sc, ATH_NODE(bf->bf_node), bf->bf_state.bfs_shpream,
+	    bf->bf_state.bfs_pktlen, &rix, &try0, &rate);
+	/* XXX only do this if MRR is enabled for this frame? */
+	/* XXX and blank the rest if not? */
+	ath_rate_getxtxrates(sc, ATH_NODE(bf->bf_node), rix,
+	    bf->bf_state.bfs_rc);
+	ATH_NODE_UNLOCK(ATH_NODE(bf->bf_node));
+
+	sc->sc_txrix = rix;	/* for LED blinking */
+	sc->sc_lastdatarix = rix;	/* for fast frames */
+	bf->bf_state.bfs_try0 = try0;
+	bf->bf_state.bfs_txrate0 = rate;
+}
+
+/*
  * Set the rate control fields in the given descriptor based on
  * the bf_state fields and node state.
  *
@@ -886,6 +923,8 @@ ath_tx_xmit_normal(struct ath_softc *sc,
 	ATH_TXQ_LOCK_ASSERT(txq);
 
 	/* Setup the descriptor before handoff */
+	ath_tx_do_ratelookup(sc, bf);
+	ath_tx_rate_fill_rcflags(sc, bf);
 	ath_tx_set_rtscts(sc, bf);
 	ath_tx_setds(sc, bf);
 	ath_tx_set_ratectrl(sc, bf->bf_node, bf);
@@ -908,8 +947,8 @@ ath_tx_normal_setup(struct ath_softc *sc
 	struct ieee80211com *ic = ifp->if_l2com;
 	const struct chanAccParams *cap = &ic->ic_wme.wme_chanParams;
 	int error, iswep, ismcast, isfrag, ismrr;
-	int keyix, hdrlen, pktlen, try0;
-	u_int8_t rix, txrate;
+	int keyix, hdrlen, pktlen, try0 = 0;
+	u_int8_t rix = 0, txrate = 0;
 	struct ath_desc *ds;
 	struct ath_txq *txq;
 	struct ieee80211_frame *wh;
@@ -1029,14 +1068,12 @@ ath_tx_normal_setup(struct ath_softc *sc
 				txrate |= rt->info[rix].shortPreamble;
 			try0 = ATH_TXMAXTRY;	/* XXX?too many? */
 		} else {
-			ATH_NODE_LOCK(an);
-			ath_rate_findrate(sc, an, shortPreamble, pktlen,
-				&rix, &try0, &txrate);
-			ATH_NODE_UNLOCK(an);
-			sc->sc_txrix = rix;		/* for LED blinking */
-			sc->sc_lastdatarix = rix;	/* for fast frames */
-			if (try0 != ATH_TXMAXTRY)
-				ismrr = 1;
+			/*
+			 * Do rate lookup on each TX, rather than using
+			 * the hard-coded TX information decided here.
+			 */
+			ismrr = 1;
+			bf->bf_state.bfs_doratelookup = 1;
 		}
 		if (cap->cap_wmeParams[pri].wmep_noackPolicy)
 			flags |= HAL_TXDESC_NOACK;
@@ -1240,19 +1277,6 @@ ath_tx_normal_setup(struct ath_softc *sc
 	bf->bf_state.bfs_ctsduration = 0;
 	bf->bf_state.bfs_ismrr = ismrr;
 
-	/*
-	 * Setup the multi-rate retry state only when we're
-	 * going to use it.  This assumes ath_hal_setuptxdesc
-	 * initializes the descriptors (so we don't have to)
-	 * when the hardware supports multi-rate retry and
-	 * we don't use it.
-	 */
-        if (ismrr) {
-		ATH_NODE_LOCK(an);
-		ath_rate_getxtxrates(sc, an, rix, bf->bf_state.bfs_rc);
-		ATH_NODE_UNLOCK(an);
-        }
-
 	return 0;
 }
 
@@ -1362,12 +1386,6 @@ ath_tx_start(struct ath_softc *sc, struc
 	/* At this point m0 could have changed! */
 	m0 = bf->bf_m;
 
-	/*
-	 * ath_tx_normal_setup() has done the single and multi-rate
-	 * retry rate lookup for us. Fill in the rcflags based on
-	 * that.
-	 */
-	ath_tx_rate_fill_rcflags(sc, bf);
 #if 1
 	/*
 	 * If it's a multicast frame, do a direct-dispatch to the
@@ -2000,6 +2018,8 @@ ath_tx_xmit_aggr(struct ath_softc *sc, s
 	}
 
 	/* Direct dispatch to hardware */
+	ath_tx_do_ratelookup(sc, bf);
+	ath_tx_rate_fill_rcflags(sc, bf);
 	ath_tx_set_rtscts(sc, bf);
 	ath_tx_setds(sc, bf);
 	ath_tx_set_ratectrl(sc, bf->bf_node, bf);
@@ -3145,6 +3165,8 @@ ath_tx_tid_hw_queue_aggr(struct ath_soft
 			    __func__);
 			ATH_TXQ_REMOVE(tid, bf, bf_list);
 			bf->bf_state.bfs_aggr = 0;
+			ath_tx_do_ratelookup(sc, bf);
+			ath_tx_rate_fill_rcflags(sc, bf);
 			ath_tx_set_rtscts(sc, bf);
 			ath_tx_setds(sc, bf);
 			ath_tx_chaindesclist(sc, bf);
@@ -3157,8 +3179,19 @@ ath_tx_tid_hw_queue_aggr(struct ath_soft
 			goto queuepkt;
 		}
 
-		/* Don't lock the TID - ath_tx_form_aggr will lock as needed */
 		TAILQ_INIT(&bf_q);
+
+		/*
+		 * Do a rate control lookup on the first frame in the
+		 * list. The rate control code needs that to occur
+		 * before it can determine whether to TX.
+		 * It's inaccurate because the rate control code doesn't
+		 * really "do" aggregate lookups, so it only considers
+		 * the size of the first frame.
+		 */
+		ath_tx_do_ratelookup(sc, bf);
+		ath_tx_rate_fill_rcflags(sc, bf);
+
 		status = ath_tx_form_aggr(sc, an, tid, &bf_q);
 
 		DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
@@ -3204,6 +3237,13 @@ ath_tx_tid_hw_queue_aggr(struct ath_soft
 			sc->sc_aggr_stats.aggr_aggr_pkt++;
 
 			/*
+			 * Update the rate and rtscts information based on the
+			 * rate decision made by the rate control code;
+			 * the first frame in the aggregate needs it.
+			 */
+			ath_tx_set_rtscts(sc, bf);
+
+			/*
 			 * Setup the relevant descriptor fields
 			 * for aggregation. The first descriptor
 			 * already points to the rest in the chain.
@@ -3296,6 +3336,8 @@ ath_tx_tid_hw_queue_norm(struct ath_soft
 		bf->bf_comp = ath_tx_normal_comp;
 
 		/* Program descriptors + rate control */
+		ath_tx_do_ratelookup(sc, bf);
+		ath_tx_rate_fill_rcflags(sc, bf);
 		ath_tx_set_rtscts(sc, bf);
 		ath_tx_setds(sc, bf);
 		ath_tx_chaindesclist(sc, bf);

Modified: user/adrian/if_ath_tx/sys/dev/ath/if_athvar.h
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/ath/if_athvar.h	Sun Sep  4 22:06:32 2011	(r225380)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_athvar.h	Mon Sep  5 00:10:37 2011	(r225381)
@@ -214,6 +214,7 @@ struct ath_buf {
 		int bfs_istxfrag:1;	/* is fragmented */
 		int bfs_ismrr:1;	/* do multi-rate TX retry */
 		int bfs_doprot:1;	/* do RTS/CTS based protection */
+		int bfs_doratelookup:1;	/* do rate lookup before each TX */
 		int bfs_nfl;		/* next fragment length */
 
 		/*


More information about the svn-src-user mailing list