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>