From owner-p4-projects@FreeBSD.ORG Mon Mar 17 21:43:09 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id D44BB1065680; Mon, 17 Mar 2008 21:43:08 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 909F11065673 for ; Mon, 17 Mar 2008 21:43:08 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 7929C8FC13 for ; Mon, 17 Mar 2008 21:43:08 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m2HLh8Mm008331 for ; Mon, 17 Mar 2008 21:43:08 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m2HLh8vL008329 for perforce@freebsd.org; Mon, 17 Mar 2008 21:43:08 GMT (envelope-from sam@freebsd.org) Date: Mon, 17 Mar 2008 21:43:08 GMT Message-Id: <200803172143.m2HLh8vL008329@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Cc: Subject: PERFORCE change 137953 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 17 Mar 2008 21:43:09 -0000 http://perforce.freebsd.org/chv.cgi?CH=137953 Change 137953 by sam@sam_ebb on 2008/03/17 21:42:55 wack some sense into this code before we throw it away Affected files ... .. //depot/projects/vap/sys/net80211/ieee80211_rssadapt.c#4 edit .. //depot/projects/vap/sys/net80211/ieee80211_rssadapt.h#2 edit Differences ... ==== //depot/projects/vap/sys/net80211/ieee80211_rssadapt.c#4 (text+ko) ==== @@ -71,93 +71,80 @@ (parm##_denom - parm##_old) * (new)) / \ parm##_denom) +static void rssadapt_sysctlattach(struct ieee80211_rssadapt *rs, + struct sysctl_ctx_list *ctx, struct sysctl_oid *tree); + /* number of references from net80211 layer */ static int nrefs = 0; void -ieee80211_rssadapt_init(struct ieee80211_rssadapt *rs, struct ieee80211vap *vap) +ieee80211_rssadapt_setinterval(struct ieee80211_rssadapt *rs, int msecs) { + int t; + + if (msecs < 100) + msecs = 100; + t = msecs_to_ticks(msecs); + rs->interval = (t < 1) ? 1 : t; } void -ieee80211_rssadapt_node_init(struct ieee80211_rssadapt *rs, - struct ieee80211_rssadapt_node *ra, struct ieee80211_node *ni) +ieee80211_rssadapt_init(struct ieee80211_rssadapt *rs, struct ieee80211vap *vap, int interval) { - ra->ra_ni = ni; + rs->vap = vap; + ieee80211_rssadapt_setinterval(rs, interval); + + rssadapt_sysctlattach(rs, vap->iv_sysctl, vap->iv_oid); } -int -ieee80211_rssadapt_choose(struct ieee80211_rssadapt_node *ra, - const struct ieee80211_rateset *rs, u_int len) +void +ieee80211_rssadapt_cleanup(struct ieee80211_rssadapt *rs) { - u_int16_t (*thrs)[IEEE80211_RATE_SIZE]; - int i, rateidx = 0, thridx, top, rssi; - - for (i = 0, top = IEEE80211_RSSADAPT_BKT0; - i < IEEE80211_RSSADAPT_BKTS; - i++, top <<= IEEE80211_RSSADAPT_BKTPOWER) { - thridx = i; - if (len <= top) - break; - } - thrs = &ra->ra_rate_thresh[thridx]; - - rssi = ra->ra_ni->ni_ic->ic_node_getrssi(ra->ra_ni); - i = rs->rs_nrates; - while (--i >= 0) { - rateidx = i; - if ((*thrs)[i] < (rssi << 8)) - break; - } - return rateidx; } -void -ieee80211_rssadapt_updatestats(struct ieee80211_rssadapt_node *ra) +static void +rssadapt_updatestats(struct ieee80211_rssadapt_node *ra) { long interval; - ra->ra_pktrate = - (ra->ra_pktrate + 10 * (ra->ra_nfail + ra->ra_nok)) / 2; + ra->ra_pktrate = (ra->ra_pktrate + 10*(ra->ra_nfail + ra->ra_nok))/2; ra->ra_nfail = ra->ra_nok = 0; - /* a node is eligible for its rate to be raised every 1/10 to 10 + /* + * A node is eligible for its rate to be raised every 1/10 to 10 * seconds, more eligible in proportion to recent packet rates. */ - interval = MAX(100000, 10000000 / MAX(1, 10 * ra->ra_pktrate)); - ra->ra_raise_interval.tv_sec = interval / (1000 * 1000); - ra->ra_raise_interval.tv_usec = interval % (1000 * 1000); + interval = MAX(10*1000, 10*1000 / MAX(1, 10 * ra->ra_pktrate)); + ra->ra_raise_interval = msecs_to_ticks(interval); } -#if 0 void -ral_rssadapt_input(struct ieee80211_node *ni, - struct ral_rssadapt *ra, int rssi) +ieee80211_rssadapt_node_init(struct ieee80211_rssadapt *rsa, + struct ieee80211_rssadapt_node *ra, struct ieee80211_node *ni) { - ra->ra_avg_rssi = interpolate(master_expavgctl.rc_avgrssi, - ra->ra_avg_rssi, (rssi << 8)); + const struct ieee80211_rateset *rs = &ni->ni_rates; + + ra->ra_rs = rsa; + ra->ra_rates = *rs; + rssadapt_updatestats(ra); + + /* pick initial rate */ + for (ra->ra_rix = rs->rs_nrates - 1; + ra->ra_rix > 0 && (rs->rs_rates[ra->ra_rix] & IEEE80211_RATE_VAL) > 72; + ra->ra_rix--) + ; + ni->ni_txrate = rs->rs_rates[ra->ra_rix] & IEEE80211_RATE_VAL; + ra->ra_ticks = ticks; + + IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, + "RSSADAPT initial rate %d", ni->ni_txrate); } -#endif -/* - * Adapt the data rate to suit the conditions. When a transmitted - * packet is dropped after RAL_RSSADAPT_RETRY_LIMIT retransmissions, - * raise the RSS threshold for transmitting packets of similar length at - * the same data rate. - */ -static __inline__ void -rssadapt_lower_rate(struct ieee80211_rssadapt_node *ra, - int pktlen, int rix, int rssi) +static __inline int +bucket(int pktlen) { - const struct ieee80211_rateset *rs = &ra->ra_ni->ni_rates; - u_int16_t last_thr; - u_int i, thridx, top; - - ra->ra_nfail++; + int i, top, thridx; - if (rix >= rs->rs_nrates) - return; - for (i = 0, top = IEEE80211_RSSADAPT_BKT0; i < IEEE80211_RSSADAPT_BKTS; i++, top <<= IEEE80211_RSSADAPT_BKTPOWER) { @@ -165,65 +152,119 @@ if (pktlen <= top) break; } + return thridx; +} + +int +ieee80211_rssadapt_choose(struct ieee80211_node *ni, + struct ieee80211_rssadapt_node *ra, u_int pktlen) +{ + const struct ieee80211_rateset *rs = &ra->ra_rates; + uint16_t (*thrs)[IEEE80211_RATE_SIZE]; + int rix, rssi; + + if ((ticks - ra->ra_ticks) > ra->ra_rs->interval) { + rssadapt_updatestats(ra); + ra->ra_ticks = ticks; + } - last_thr = ra->ra_rate_thresh[thridx][rix]; - ra->ra_rate_thresh[thridx][rix] = - interpolate(master_expavgctl.rc_thresh, last_thr, (rssi << 8)); + thrs = &ra->ra_rate_thresh[bucket(pktlen)]; + + /* XXX this is average rssi, should be using last value */ + rssi = ni->ni_ic->ic_node_getrssi(ni); + for (rix = rs->rs_nrates-1; rix >= 0; rix--) + if ((*thrs)[rix] < (rssi << 8)) + break; + if (rix != ra->ra_rix) { + /* update public rate */ + ni->ni_txrate = ni->ni_rates.rs_rates[rix] & IEEE80211_RATE_VAL; + ra->ra_rix = rix; - IEEE80211_DPRINTF(ra->ra_ni->ni_vap, IEEE80211_MSG_RATECTL, - "RSSADAPT lower threshold for rix %d (last_thr=%d new thr=%d rssi=%d)\n", - rix, last_thr, ra->ra_rate_thresh[thridx][rix], rssi); + IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, + "RSSADAPT new rate %d (pktlen %d rssi %d)", + ni->ni_txrate, pktlen, rssi); + } + return rix; } -static __inline__ void -rssadapt_raise_rate(struct ieee80211_rssadapt_node *ra, - int pktlen, int rix, int rssi) +/* + * Adapt the data rate to suit the conditions. When a transmitted + * packet is dropped after RAL_RSSADAPT_RETRY_LIMIT retransmissions, + * raise the RSS threshold for transmitting packets of similar length at + * the same data rate. + */ +void +ieee80211_rssadapt_lower_rate(struct ieee80211_rssadapt_node *ra, + int pktlen, int rssi) { - u_int16_t (*thrs)[IEEE80211_RATE_SIZE], newthr, oldthr; - const struct ieee80211_rateset *rs = &ra->ra_ni->ni_rates; - int i, rate, top; + uint16_t last_thr; + uint16_t (*thrs)[IEEE80211_RATE_SIZE]; + u_int rix; + + thrs = &ra->ra_rate_thresh[bucket(pktlen)]; - ra->ra_nok++; + rix = ra->ra_rix; + last_thr = (*thrs)[rix]; + (*thrs)[rix] = interpolate(master_expavgctl.rc_thresh, + last_thr, (rssi << 8)); - if (!ratecheck(&ra->ra_last_raise, &ra->ra_raise_interval)) - return; + IEEE80211_DPRINTF(ra->ra_rs->vap, IEEE80211_MSG_RATECTL, + "RSSADAPT lower threshold for rate %d (last_thr %d new thr %d rssi %d)\n", + ra->ra_rates.rs_rates[rix + 1] & IEEE80211_RATE_VAL, + last_thr, (*thrs)[rix], rssi); +} - for (i = 0, top = IEEE80211_RSSADAPT_BKT0; - i < IEEE80211_RSSADAPT_BKTS; - i++, top <<= IEEE80211_RSSADAPT_BKTPOWER) { - thrs = &ra->ra_rate_thresh[i]; - if (pktlen <= top) - break; - } +void +ieee80211_rssadapt_raise_rate(struct ieee80211_rssadapt_node *ra, + int pktlen, int rssi) +{ + uint16_t (*thrs)[IEEE80211_RATE_SIZE]; + uint16_t newthr, oldthr; + int rix; - if (rix + 1 < rs->rs_nrates && - (*thrs)[rix + 1] > (*thrs)[rix]) { - rate = rs->rs_rates[rix + 1] & IEEE80211_RATE_VAL; + thrs = &ra->ra_rate_thresh[bucket(pktlen)]; + rix = ra->ra_rix; + if ((*thrs)[rix + 1] > (*thrs)[rix]) { oldthr = (*thrs)[rix + 1]; if ((*thrs)[rix] == 0) newthr = (rssi << 8); else newthr = (*thrs)[rix]; - (*thrs)[rix + 1] = - interpolate(master_expavgctl.rc_decay, oldthr, newthr); + (*thrs)[rix + 1] = interpolate(master_expavgctl.rc_decay, + oldthr, newthr); + + IEEE80211_DPRINTF(ra->ra_rs->vap, IEEE80211_MSG_RATECTL, + "RSSADAPT raise threshold for rate %d (oldthr %d newthr %d rssi %d)\n", + ra->ra_rates.rs_rates[rix + 1] & IEEE80211_RATE_VAL, + oldthr, newthr, rssi); - IEEE80211_DPRINTF(ra->ra_ni->ni_vap, IEEE80211_MSG_RATECTL, - "RSSADAPT raise threshold for rix %d (oldthr=%d newthr=%d rssi=%d)\n", - rix+1, oldthr, newthr, rssi); + ra->ra_last_raise = ticks; } } -void -ieee80211_rssadapt_tx_complete(struct ieee80211_rssadapt_node *ra, - int success, int pktlen, int rate, int rssi) +static int +rssadapt_sysctl_interval(SYSCTL_HANDLER_ARGS) +{ + struct ieee80211_rssadapt *rs = arg1; + int msecs = ticks_to_msecs(rs->interval); + int error; + + error = sysctl_handle_int(oidp, &msecs, 0, req); + if (error || !req->newptr) + return error; + ieee80211_rssadapt_setinterval(rs, msecs); + return 0; +} + +static void +rssadapt_sysctlattach(struct ieee80211_rssadapt *rs, + struct sysctl_ctx_list *ctx, struct sysctl_oid *tree) { - if (ra->ra_ni != NULL) { /* setup when associated */ - if (success) - rssadapt_raise_rate(ra, pktlen, rate, rssi); - else - rssadapt_lower_rate(ra, pktlen, rate, rssi); - } + + SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "rssadapt_rate_interval", CTLTYPE_INT | CTLFLAG_RW, rs, + 0, rssadapt_sysctl_interval, "I", "rssadapt operation interval (ms)"); } /* ==== //depot/projects/vap/sys/net80211/ieee80211_rssadapt.h#2 (text+ko) ==== @@ -43,33 +43,59 @@ #define IEEE80211_RSSADAPT_BKTPOWER 3 /* 2**_BKTPOWER */ struct ieee80211_rssadapt { - /* nothing right now */ + struct ieee80211vap *vap; + int interval; /* update interval (ticks) */ }; struct ieee80211_rssadapt_node { - struct ieee80211_node *ra_ni; /* backpointer */ + struct ieee80211_rssadapt *ra_rs; /* backpointer */ + struct ieee80211_rateset ra_rates; /* negotiated rates */ + int ra_rix; /* current rate index */ + int ra_ticks; /* time of last update */ + int ra_last_raise; /* time of last rate raise */ + int ra_raise_interval; /* rate raise time threshold */ /* Tx failures in this update interval */ - u_int32_t ra_nfail; + uint32_t ra_nfail; /* Tx successes in this update interval */ - u_int32_t ra_nok; + uint32_t ra_nok; /* exponential average packets/second */ - u_int32_t ra_pktrate; + uint32_t ra_pktrate; /* RSSI threshold for each Tx rate */ - u_int16_t ra_rate_thresh[IEEE80211_RSSADAPT_BKTS] + uint16_t ra_rate_thresh[IEEE80211_RSSADAPT_BKTS] [IEEE80211_RATE_SIZE]; - struct timeval ra_last_raise; - struct timeval ra_raise_interval; }; void ieee80211_rssadapt_init(struct ieee80211_rssadapt *, - struct ieee80211vap *); + struct ieee80211vap *, int); +void ieee80211_rssadapt_cleanup(struct ieee80211_rssadapt *); +void ieee80211_rssadapt_setinterval(struct ieee80211_rssadapt *, int); void ieee80211_rssadapt_node_init(struct ieee80211_rssadapt *, struct ieee80211_rssadapt_node *, struct ieee80211_node *); -int ieee80211_rssadapt_choose(struct ieee80211_rssadapt_node *, - const struct ieee80211_rateset *, u_int); -void ieee80211_rssadapt_tx_complete(struct ieee80211_rssadapt_node *, - int success, int pktlen, int rate, int rssi); -/* XXX periodic stat updater; should be done in tx_complete callback */ -void ieee80211_rssadapt_updatestats(struct ieee80211_rssadapt_node *); +int ieee80211_rssadapt_choose(struct ieee80211_node *, + struct ieee80211_rssadapt_node *, u_int); + +/* NB: these are public only for the inline below */ +void ieee80211_rssadapt_raise_rate(struct ieee80211_rssadapt_node *, + int pktlen, int rssi); +void ieee80211_rssadapt_lower_rate(struct ieee80211_rssadapt_node *, + int pktlen, int rssi); + +#define IEEE80211_RSSADAPT_SUCCESS 1 +#define IEEE80211_RSSADAPT_FAILURE 0 + +static __inline void +ieee80211_rssadapt_tx_complete(struct ieee80211_rssadapt_node *ra, + int success, int pktlen, int rssi) +{ + if (success) { + ra->ra_nok++; + if ((ra->ra_rix + 1) < ra->ra_rates.rs_nrates && + (ticks - ra->ra_last_raise) >= ra->ra_raise_interval) + ieee80211_rssadapt_raise_rate(ra, pktlen, rssi); + } else { + ra->ra_nfail++; + ieee80211_rssadapt_lower_rate(ra, pktlen, rssi); + } +} #endif /* _NET80211_IEEE80211_RSSADAPT_H_ */