Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 8 Jan 2004 14:54:13 -0800 (PST)
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 44985 for review
Message-ID:  <200401082254.i08MsDEL039763@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=44985

Change 44985 by sam@sam_ebb on 2004/01/08 14:53:27

	Overhaul multi-rate retry code in preparation for commit to HEAD:
	
	o use a hal trick to deduce if a card supports multi-rate retry
	o add ATH_TXMAXTRY to define the max # of xmits we request
	o handle cards w/o multi-rate retry correctly
	o track hal change to eliminate short preamble parameter
	  from ath_hal_setuptxdesc (eliminates if in xmit path)
	o consolidate logic to set the starting xmit rate
	o change multi-rate retry setup to add the lowest xmit
	  rate as a last-chance rate
	o set 11a/g starting xmit rate to the sweet spot (24/36 Mb)
	  rather than the max negotiated rate
	o retard rate raising; must be seeing good statistics for 5
	  seconds instead of 2 (need to do this differently but it's
	  an interim compromise)
	o purge some unused cruft from if_athvar.h

Affected files ...

.. //depot/projects/netperf+sockets/sys/dev/ath/if_ath.c#9 edit
.. //depot/projects/netperf+sockets/sys/dev/ath/if_athvar.h#4 edit

Differences ...

==== //depot/projects/netperf+sockets/sys/dev/ath/if_ath.c#9 (text+ko) ====

@@ -137,6 +137,7 @@
 static void	ath_setcurmode(struct ath_softc *, enum ieee80211_phymode);
 static void	ath_rate_update(struct ath_softc *, struct ieee80211_node *,
 			int rate);
+static void	ath_rate_ctl_start(struct ath_softc *, struct ieee80211_node *);
 static void	ath_rate_ctl_reset(struct ath_softc *, enum ieee80211_state);
 static void	ath_rate_ctl(void *, struct ieee80211_node *);
 
@@ -241,6 +242,15 @@
 	sc->sc_invalid = 0;	/* ready to go, enable interrupt handling */
 
 	/*
+	 * Check if the MAC has multi-rate retry support.
+	 * We do this by trying to setup a fake extended
+	 * descriptor.  MAC's that don't have support will
+	 * return false w/o doing anything.  MAC's that do
+	 * support it will return true w/o doing anything.
+	 */
+	sc->sc_mrretry = ath_hal_setupxtxdesc(ah, NULL, 0,0, 0,0, 0,0);
+
+	/*
 	 * Collect the channel list using the default country
 	 * code and including outdoor channels.  The 802.11 layer
 	 * is resposible for filtering this list based on settings
@@ -1840,7 +1850,7 @@
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ath_hal *ah = sc->sc_ah;
 	struct ifnet *ifp = &sc->sc_ic.ic_if;
-	int i, error, iswep, hdrlen, pktlen;
+	int i, error, iswep, hdrlen, pktlen, try0;
 	u_int8_t rix, cix, txrate, ctsrate;
 	struct ath_desc *ds;
 	struct mbuf *m;
@@ -1996,6 +2006,7 @@
 		else if (subtype == IEEE80211_FC0_SUBTYPE_ATIM)
 			atype = HAL_PKT_TYPE_ATIM;
 		rix = 0;			/* XXX lowest rate */
+		try0 = ATH_TXMAXTRY;
 		if (shortPreamble)
 			txrate = an->an_tx_mgtrate;
 		else
@@ -2006,6 +2017,7 @@
 		if (subtype == IEEE80211_FC0_SUBTYPE_PS_POLL)
 			atype = HAL_PKT_TYPE_PSPOLL;
 		rix = 0;			/* XXX lowest rate */
+		try0 = ATH_TXMAXTRY;
 		if (shortPreamble)
 			txrate = an->an_tx_mgtrate;
 		else
@@ -2013,6 +2025,7 @@
 		break;
 	default:
 		rix = an->an_tx_rix0;
+		try0 = an->an_tx_try0;
 		if (rix == 0xff) {
 			if_printf(ifp, "bogus xmit rate 0x%x\n",
 				ni->ni_rates.rs_rates[ni->ni_txrate]);
@@ -2124,30 +2137,26 @@
 		, hdrlen		/* header length */
 		, atype			/* Atheros packet type */
 		, 60			/* txpower XXX */
-		, txrate, 1+3		/* series 0 rate/tries */
+		, txrate, try0		/* series 0 rate/tries */
 		, iswep ? sc->sc_ic.ic_wep_txkey : HAL_TXKEYIX_INVALID
 		, antenna		/* antenna mode */
 		, flags			/* flags */
 		, ctsrate		/* rts/cts rate */
 		, ctsduration		/* rts/cts duration */
 	);
-	if (rix != 0) {
-		if (shortPreamble) {
-			ath_hal_setupxtxdesc(ah, ds
-				, AH_TRUE		/* short preamble */
-				, an->an_tx_rate1sp, 2	/* series 1 */
-				, an->an_tx_rate2sp, 2	/* series 2 */
-				, an->an_tx_rate3sp, 2	/* series 3 */
-			);
-		} else {
-			ath_hal_setupxtxdesc(ah, ds
-				, AH_FALSE		/* no short preamble */
-				, an->an_tx_rate1, 2	/* series 1 */
-				, an->an_tx_rate2, 2	/* series 2 */
-				, an->an_tx_rate3, 2	/* series 3 */
-			);
-		}
-	}
+	/*
+	 * 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 (try0 != ATH_TXMAXTRY)
+		ath_hal_setupxtxdesc(ah, ds
+			, an->an_tx_rate1sp, 2	/* series 1 */
+			, an->an_tx_rate2sp, 2	/* series 2 */
+			, an->an_tx_rate3sp, 2	/* series 3 */
+		);
 
 	/*
 	 * Fillin the remainder of the descriptor info.
@@ -2648,17 +2657,8 @@
 static void
 ath_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
 {
-	if (isnew) {
-		/* start with highest negotiated rate */
-		/*
-		 * XXX should do otherwise but only when
-		 * the rate control algorithm is better.
-		 */
-		KASSERT(ni->ni_rates.rs_nrates > 0,
-			("new association w/ no rates!"));
-		ath_rate_update((struct ath_softc *)ic, ni,
-			ni->ni_rates.rs_nrates - 1);
-	}
+	if (isnew)
+		ath_rate_ctl_start((struct ath_softc *)ic, ni);
 }
 
 static int
@@ -2793,43 +2793,78 @@
 	/* XXX management/control frames always go at the lowest speed */
 	an->an_tx_mgtrate = rt->info[0].rateCode;
 	an->an_tx_mgtratesp = an->an_tx_mgtrate | rt->info[0].shortPreamble;
-	/*
-	 * Setup two step-down retry rates.
-	 */
-	if (--rate >= 0) {
-		rix = sc->sc_rixmap[
-			ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL];
-		an->an_tx_rate1 = rt->info[rix].rateCode;
-		an->an_tx_rate1sp = an->an_tx_rate1 |
-			rt->info[rix].shortPreamble;
-	} else
-		an->an_tx_rate1 = 0;
-	if (--rate >= 0) {
-		rix = sc->sc_rixmap[
-			ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL];
-		an->an_tx_rate2 = rt->info[rix].rateCode;
-		an->an_tx_rate2sp = an->an_tx_rate2 |
-			rt->info[rix].shortPreamble;
-	} else
-		an->an_tx_rate2 = 0;
-#if 0
-	if (--rate >= 0) {
-		rix = sc->sc_rixmap[
-			ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL];
-		an->an_tx_rate3 = rt->info[rix].rateCode;
-		an->an_tx_rate3sp = an->an_tx_rate3 |
-			rt->info[rix].shortPreamble;
-	} else
-		an->an_tx_rate3 = 0;
-	an->an_tx_rate2 = an->an_tx_mgtrate;
-	an->an_tx_rate2sp = an->an_tx_mgtratesp;
-#else
-	an->an_tx_rate3 = an->an_tx_rate3sp = 0;
-#endif
+	if (sc->sc_mrretry) {
+		/*
+		 * Hardware supports multi-rate retry; setup two
+		 * step-down retry rates and make the lowest rate
+		 * be the ``last chance''.  We use 4, 2, 2, 2 tries
+		 * respectively (4 is set here, the rest are fixed
+		 * in the xmit routine).
+		 */
+		an->an_tx_try0 = 1 + 3;		/* 4 tries at rate 0 */
+		if (--rate >= 0) {
+			rix = sc->sc_rixmap[
+				ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL];
+			an->an_tx_rate1 = rt->info[rix].rateCode;
+			an->an_tx_rate1sp = an->an_tx_rate1 |
+				rt->info[rix].shortPreamble;
+		} else {
+			an->an_tx_rate1 = an->an_tx_rate1sp = 0;
+		}
+		if (--rate >= 0) {
+			rix = sc->sc_rixmap[
+				ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL];
+			an->an_tx_rate2 = rt->info[rix].rateCode;
+			an->an_tx_rate2sp = an->an_tx_rate2 |
+				rt->info[rix].shortPreamble;
+		} else {
+			an->an_tx_rate2 = an->an_tx_rate2sp = 0;
+		}
+		if (rate > 0) {
+			/* NB: only do this if we didn't already do it above */
+			an->an_tx_rate3 = rt->info[0].rateCode;
+			an->an_tx_rate3sp =
+				an->an_tx_mgtrate | rt->info[0].shortPreamble;
+		} else {
+			an->an_tx_rate3 = an->an_tx_rate3sp = 0;
+		}
+	} else {
+		an->an_tx_try0 = ATH_TXMAXTRY;	/* max tries at rate 0 */
+		an->an_tx_rate1 = an->an_tx_rate1sp = 0;
+		an->an_tx_rate2 = an->an_tx_rate2sp = 0;
+		an->an_tx_rate3 = an->an_tx_rate3sp = 0;
+	}
 	an->an_tx_ok = an->an_tx_err = an->an_tx_retr = an->an_tx_upper = 0;
 }
 
 /*
+ * Set the starting transmit rate for a node.
+ */
+static void
+ath_rate_ctl_start(struct ath_softc *sc, struct ieee80211_node *ni)
+{
+#define	RATE(_ix)	(ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL)
+	int srate;
+
+	KASSERT(ni->ni_rates.rs_nrates > 0, ("no rates"));
+	/* start with highest negotiated rate */
+	srate = ni->ni_rates.rs_nrates - 1;
+	if (sc->sc_curmode != IEEE80211_MODE_11B) {
+		/*
+		 * 11a and 11g work better if you start at 24Mb
+		 * or 36Mb and raise the rate.  Scan the negotiated
+		 * rate set to find the closest rate.
+		 */
+		/* NB: rate set assumed sorted */
+		for (; srate >= 0 && RATE(srate) > 72; srate--)
+			;
+		KASSERT(srate >= 0, ("bogus rate set"));
+	}
+	ath_rate_update(sc, ni, srate);
+#undef RATE
+}
+
+/*
  * Reset the rate control state for each 802.11 state transition.
  */
 static void
@@ -2845,10 +2880,7 @@
 		 */
 		ni = ic->ic_bss;
 		if (state == IEEE80211_S_RUN) {
-			/* start with highest negotiated rate */
-			KASSERT(ni->ni_rates.rs_nrates > 0,
-				("transition to RUN state w/ no rates!"));
-			ath_rate_update(sc, ni, ni->ni_rates.rs_nrates - 1);
+			ath_rate_ctl_start(sc, ni);
 		} else {
 			ath_rate_update(sc, ni, 0);
 		}
@@ -2878,7 +2910,7 @@
 
 	/*
 	 * Rate control
-	 * XXX: very primitive version.
+	 * XXX: very primitive version; need to at least consider rssi
 	 */
 	sc->sc_stats.ast_rate_calls++;
 
@@ -2910,7 +2942,7 @@
 		an->an_tx_upper = 0;
 		break;
 	case 1:
-		if (++an->an_tx_upper < 2)
+		if (++an->an_tx_upper < 5)
 			break;
 		an->an_tx_upper = 0;
 		if (nrate + 1 < rs->rs_nrates) {

==== //depot/projects/netperf+sockets/sys/dev/ath/if_athvar.h#4 (text+ko) ====

@@ -53,6 +53,7 @@
 #define	ATH_RXBUF	40		/* number of RX buffers */
 #define	ATH_TXBUF	60		/* number of TX buffers */
 #define	ATH_TXDESC	8		/* number of descriptors per buffer */
+#define	ATH_TXMAXTRY	11		/* max number of transmit attempts */
 
 struct ath_recv_hist {
 	int		arh_ticks;	/* sample time by system clock */
@@ -71,6 +72,7 @@
 	int		an_tx_upper;	/* tx upper rate req cnt */
 	u_int		an_tx_antenna;	/* antenna for last good frame */
 	u_int8_t	an_tx_rix0;	/* series 0 rate index */
+	u_int8_t	an_tx_try0;	/* series 0 try count */
 	u_int8_t	an_tx_mgtrate;	/* h/w rate for management/ctl frames */
 	u_int8_t	an_tx_mgtratesp;/* short preamble h/w rate for " " */
 	u_int8_t	an_tx_rate0;	/* series 0 h/w rate */
@@ -111,8 +113,7 @@
 	struct mtx		sc_mtx;		/* master lock (recursive) */
 	struct ath_hal		*sc_ah;		/* Atheros HAL */
 	unsigned int		sc_invalid  : 1,/* disable hardware accesses */
-				sc_doani    : 1,/* dynamic noise immunity */
-				sc_probing  : 1;/* probing AP on beacon miss */
+				sc_mrretry  : 1;/* multi-rate retry support */
 						/* rate tables */
 	const HAL_RATE_TABLE	*sc_rates[IEEE80211_MODE_MAX];
 	const HAL_RATE_TABLE	*sc_currates;	/* current rate table */
@@ -300,10 +301,6 @@
 #define	ath_hal_rxmonitor(_ah) \
 	((*(_ah)->ah_rxMonitor)((_ah)))
 
-#define	ath_hal_setupbeacondesc(_ah, _ds, _opmode, _flen, _hlen, \
-		_rate, _antmode) \
-	((*(_ah)->ah_setupBeaconDesc)((_ah), (_ds), (_opmode), \
-		(_flen), (_hlen), (_rate), (_antmode)))
 #define	ath_hal_setuprxdesc(_ah, _ds, _size, _intreq) \
 	((*(_ah)->ah_setupRxDesc)((_ah), (_ds), (_size), (_intreq)))
 #define	ath_hal_rxprocdesc(_ah, _ds, _dspa, _dsnext) \
@@ -314,9 +311,9 @@
 	((*(_ah)->ah_setupTxDesc)((_ah), (_ds), (_plen), (_hlen), (_atype), \
 		(_txpow), (_txr0), (_txtr0), (_keyix), (_ant), \
 		(_flags), (_rtsrate), (_rtsdura)))
-#define	ath_hal_setupxtxdesc(_ah, _ds, _short, \
+#define	ath_hal_setupxtxdesc(_ah, _ds, \
 		_txr1, _txtr1, _txr2, _txtr2, _txr3, _txtr3) \
-	((*(_ah)->ah_setupXTxDesc)((_ah), (_ds), (_short), \
+	((*(_ah)->ah_setupXTxDesc)((_ah), (_ds), \
 		(_txr1), (_txtr1), (_txr2), (_txtr2), (_txr3), (_txtr3)))
 #define	ath_hal_filltxdesc(_ah, _ds, _l, _first, _last) \
 	((*(_ah)->ah_fillTxDesc)((_ah), (_ds), (_l), (_first), (_last)))



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