PERFORCE change 44985 for review
Sam Leffler
sam at FreeBSD.org
Thu Jan 8 14:54:22 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=44985
Change 44985 by sam at 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)))
More information about the p4-projects
mailing list