onoe.c revision 171613
150472Speter/*-
233975Sjdp * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting
333975Sjdp * All rights reserved.
433975Sjdp *
544360Simp * Redistribution and use in source and binary forms, with or without
633975Sjdp * modification, are permitted provided that the following conditions
784902Sobrien * are met:
8130746Smarcel * 1. Redistributions of source code must retain the above copyright
989876Sobrien *    notice, this list of conditions and the following disclaimer,
1089876Sobrien *    without modification.
1189876Sobrien * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12130575Sobrien *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13126228Sjohan *    redistribution must be conditioned upon including a substantially
14203434Simp *    similar Disclaimer requirement for further binary redistribution.
15126197Sjohan *
1692257Sobrien * NO WARRANTY
17130575Sobrien * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1884902Sobrien * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19136910Sru * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20130575Sobrien * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
2133975Sjdp * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
2235711Sjb * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23114050Sobrien * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24114050Sobrien * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25114050Sobrien * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2684902Sobrien * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2758953Ssteve * THE POSSIBILITY OF SUCH DAMAGES.
2835711Sjb */
2935711Sjb
3084902Sobrien#include <sys/cdefs.h>
3135711Sjb__FBSDID("$FreeBSD: head/sys/dev/ath/ath_rate/onoe/onoe.c 171613 2007-07-27 11:59:57Z rwatson $");
3284902Sobrien
3335711Sjb/*
3435711Sjb * Atsushi Onoe's rate control algorithm.
3558953Ssteve */
3684902Sobrien#include "opt_inet.h"
3735711Sjb
3835711Sjb#include <sys/param.h>
3935711Sjb#include <sys/systm.h>
40107506Sobrien#include <sys/sysctl.h>
4135711Sjb#include <sys/module.h>
4284902Sobrien#include <sys/kernel.h>
4335711Sjb#include <sys/lock.h>
4484902Sobrien#include <sys/mutex.h>
4535711Sjb#include <sys/errno.h>
4635711Sjb
4784902Sobrien#include <machine/bus.h>
48131832Sobrien#include <machine/resource.h>
4935711Sjb#include <sys/bus.h>
50130575Sobrien
51130575Sobrien#include <sys/socket.h>
52130740Smarcel
53130740Smarcel#include <net/if.h>
54130575Sobrien#include <net/if_media.h>
55130575Sobrien#include <net/if_arp.h>
5633975Sjdp#include <net/ethernet.h>		/* XXX for ether_sprintf */
5733975Sjdp
58130740Smarcel#include <net80211/ieee80211_var.h>
5984905Sobrien
60103780Sobrien#include <net/bpf.h>
6184905Sobrien
6284905Sobrien#ifdef INET
6384905Sobrien#include <netinet/in.h>
6484905Sobrien#include <netinet/if_ether.h>
6533975Sjdp#endif
66131832Sobrien
67130743Smarcel#include <dev/ath/if_athvar.h>
68130743Smarcel#include <dev/ath/ath_rate/onoe/onoe.h>
69130743Smarcel#include <contrib/dev/ath/ah_desc.h>
70130743Smarcel
71130743Smarcel#define	ONOE_DEBUG
72130743Smarcel#ifdef ONOE_DEBUG
7333975Sjdpenum {
74	ATH_DEBUG_RATE		= 0x00000010,	/* rate control */
75};
76#define	DPRINTF(sc, _fmt, ...) do {				\
77	if (sc->sc_debug & ATH_DEBUG_RATE)			\
78		printf(_fmt, __VA_ARGS__);			\
79} while (0)
80#else
81#define	DPRINTF(sc, _fmt, ...)
82#endif
83
84/*
85 * Default parameters for the rate control algorithm.  These are
86 * all tunable with sysctls.  The rate controller runs periodically
87 * (each ath_rateinterval ms) analyzing transmit statistics for each
88 * neighbor/station (when operating in station mode this is only the AP).
89 * If transmits look to be working well over a sampling period then
90 * it gives a "raise rate credit".  If transmits look to not be working
91 * well than it deducts a credit.  If the credits cross a threshold then
92 * the transmit rate is raised.  Various error conditions force the
93 * the transmit rate to be dropped.
94 *
95 * The decision to issue/deduct a credit is based on the errors and
96 * retries accumulated over the sampling period.  ath_rate_raise defines
97 * the percent of retransmits for which a credit is issued/deducted.
98 * ath_rate_raise_threshold defines the threshold on credits at which
99 * the transmit rate is increased.
100 *
101 * XXX this algorithm is flawed.
102 */
103static	int ath_rateinterval = 1000;		/* rate ctl interval (ms)  */
104static	int ath_rate_raise = 10;		/* add credit threshold */
105static	int ath_rate_raise_threshold = 10;	/* rate ctl raise threshold */
106
107static void	ath_ratectl(void *);
108static void	ath_rate_update(struct ath_softc *, struct ieee80211_node *,
109			int rate);
110static void	ath_rate_ctl_start(struct ath_softc *, struct ieee80211_node *);
111static void	ath_rate_ctl(void *, struct ieee80211_node *);
112
113void
114ath_rate_node_init(struct ath_softc *sc, struct ath_node *an)
115{
116	/* NB: assumed to be zero'd by caller */
117	ath_rate_update(sc, &an->an_node, 0);
118}
119
120void
121ath_rate_node_cleanup(struct ath_softc *sc, struct ath_node *an)
122{
123}
124
125void
126ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
127	int shortPreamble, size_t frameLen,
128	u_int8_t *rix, int *try0, u_int8_t *txrate)
129{
130	struct onoe_node *on = ATH_NODE_ONOE(an);
131
132	*rix = on->on_tx_rix0;
133	*try0 = on->on_tx_try0;
134	if (shortPreamble)
135		*txrate = on->on_tx_rate0sp;
136	else
137		*txrate = on->on_tx_rate0;
138}
139
140void
141ath_rate_setupxtxdesc(struct ath_softc *sc, struct ath_node *an,
142	struct ath_desc *ds, int shortPreamble, u_int8_t rix)
143{
144	struct onoe_node *on = ATH_NODE_ONOE(an);
145
146	ath_hal_setupxtxdesc(sc->sc_ah, ds
147		, on->on_tx_rate1sp, 2	/* series 1 */
148		, on->on_tx_rate2sp, 2	/* series 2 */
149		, on->on_tx_rate3sp, 2	/* series 3 */
150	);
151}
152
153void
154ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
155	const struct ath_buf *bf)
156{
157	struct onoe_node *on = ATH_NODE_ONOE(an);
158	const struct ath_tx_status *ts = &bf->bf_status.ds_txstat;
159
160	if (ts->ts_status == 0)
161		on->on_tx_ok++;
162	else
163		on->on_tx_err++;
164	on->on_tx_retr += ts->ts_shortretry
165			+ ts->ts_longretry;
166}
167
168void
169ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew)
170{
171	if (isnew)
172		ath_rate_ctl_start(sc, &an->an_node);
173}
174
175static void
176ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate)
177{
178	struct ath_node *an = ATH_NODE(ni);
179	struct onoe_node *on = ATH_NODE_ONOE(an);
180	const HAL_RATE_TABLE *rt = sc->sc_currates;
181	u_int8_t rix;
182
183	KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
184
185	DPRINTF(sc, "%s: set xmit rate for %s to %dM\n",
186	    __func__, ether_sprintf(ni->ni_macaddr),
187	    ni->ni_rates.rs_nrates > 0 ?
188		(ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL) / 2 : 0);
189
190	ni->ni_txrate = rate;
191	/*
192	 * Before associating a node has no rate set setup
193	 * so we can't calculate any transmit codes to use.
194	 * This is ok since we should never be sending anything
195	 * but management frames and those always go at the
196	 * lowest hardware rate.
197	 */
198	if (ni->ni_rates.rs_nrates == 0)
199		goto done;
200	on->on_tx_rix0 = sc->sc_rixmap[
201		ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL];
202	on->on_tx_rate0 = rt->info[on->on_tx_rix0].rateCode;
203
204	on->on_tx_rate0sp = on->on_tx_rate0 |
205		rt->info[on->on_tx_rix0].shortPreamble;
206	if (sc->sc_mrretry) {
207		/*
208		 * Hardware supports multi-rate retry; setup two
209		 * step-down retry rates and make the lowest rate
210		 * be the ``last chance''.  We use 4, 2, 2, 2 tries
211		 * respectively (4 is set here, the rest are fixed
212		 * in the xmit routine).
213		 */
214		on->on_tx_try0 = 1 + 3;		/* 4 tries at rate 0 */
215		if (--rate >= 0) {
216			rix = sc->sc_rixmap[
217				ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL];
218			on->on_tx_rate1 = rt->info[rix].rateCode;
219			on->on_tx_rate1sp = on->on_tx_rate1 |
220				rt->info[rix].shortPreamble;
221		} else {
222			on->on_tx_rate1 = on->on_tx_rate1sp = 0;
223		}
224		if (--rate >= 0) {
225			rix = sc->sc_rixmap[
226				ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL];
227			on->on_tx_rate2 = rt->info[rix].rateCode;
228			on->on_tx_rate2sp = on->on_tx_rate2 |
229				rt->info[rix].shortPreamble;
230		} else {
231			on->on_tx_rate2 = on->on_tx_rate2sp = 0;
232		}
233		if (rate > 0) {
234			/* NB: only do this if we didn't already do it above */
235			on->on_tx_rate3 = rt->info[0].rateCode;
236			on->on_tx_rate3sp =
237				on->on_tx_rate3 | rt->info[0].shortPreamble;
238		} else {
239			on->on_tx_rate3 = on->on_tx_rate3sp = 0;
240		}
241	} else {
242		on->on_tx_try0 = ATH_TXMAXTRY;	/* max tries at rate 0 */
243		on->on_tx_rate1 = on->on_tx_rate1sp = 0;
244		on->on_tx_rate2 = on->on_tx_rate2sp = 0;
245		on->on_tx_rate3 = on->on_tx_rate3sp = 0;
246	}
247done:
248	on->on_tx_ok = on->on_tx_err = on->on_tx_retr = on->on_tx_upper = 0;
249}
250
251/*
252 * Set the starting transmit rate for a node.
253 */
254static void
255ath_rate_ctl_start(struct ath_softc *sc, struct ieee80211_node *ni)
256{
257#define	RATE(_ix)	(ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL)
258	struct ieee80211com *ic = &sc->sc_ic;
259	int srate;
260
261	KASSERT(ni->ni_rates.rs_nrates > 0, ("no rates"));
262	if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) {
263		/*
264		 * No fixed rate is requested. For 11b start with
265		 * the highest negotiated rate; otherwise, for 11g
266		 * and 11a, we start "in the middle" at 24Mb or 36Mb.
267		 */
268		srate = ni->ni_rates.rs_nrates - 1;
269		if (sc->sc_curmode != IEEE80211_MODE_11B) {
270			/*
271			 * Scan the negotiated rate set to find the
272			 * closest rate.
273			 */
274			/* NB: the rate set is assumed sorted */
275			for (; srate >= 0 && RATE(srate) > 72; srate--)
276				;
277		}
278	} else {
279		/*
280		 * A fixed rate is to be used; ic_fixed_rate is the
281		 * IEEE code for this rate (sans basic bit).  Convert this
282		 * to the index into the negotiated rate set for
283		 * the node.  We know the rate is there because the
284		 * rate set is checked when the station associates.
285		 */
286		/* NB: the rate set is assumed sorted */
287		srate = ni->ni_rates.rs_nrates - 1;
288		for (; srate >= 0 && RATE(srate) != ic->ic_fixed_rate; srate--)
289			;
290	}
291	/*
292	 * The selected rate may not be available due to races
293	 * and mode settings.  Also orphaned nodes created in
294	 * adhoc mode may not have any rate set so this lookup
295	 * can fail.  This is not fatal.
296	 */
297	ath_rate_update(sc, ni, srate < 0 ? 0 : srate);
298#undef RATE
299}
300
301static void
302ath_rate_cb(void *arg, struct ieee80211_node *ni)
303{
304	struct ath_softc *sc = arg;
305
306	ath_rate_update(sc, ni, 0);
307}
308
309/*
310 * Reset the rate control state for each 802.11 state transition.
311 */
312void
313ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state)
314{
315	struct onoe_softc *osc = (struct onoe_softc *) sc->sc_rc;
316	struct ieee80211com *ic = &sc->sc_ic;
317	struct ieee80211_node *ni;
318
319	if (state == IEEE80211_S_INIT) {
320		callout_stop(&osc->timer);
321		return;
322	}
323	if (ic->ic_opmode == IEEE80211_M_STA) {
324		/*
325		 * Reset local xmit state; this is really only
326		 * meaningful when operating in station mode.
327		 */
328		ni = ic->ic_bss;
329		if (state == IEEE80211_S_RUN) {
330			ath_rate_ctl_start(sc, ni);
331		} else {
332			ath_rate_update(sc, ni, 0);
333		}
334	} else {
335		/*
336		 * When operating as a station the node table holds
337		 * the AP's that were discovered during scanning.
338		 * For any other operating mode we want to reset the
339		 * tx rate state of each node.
340		 */
341		ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_cb, sc);
342		ath_rate_update(sc, ic->ic_bss, 0);
343	}
344	if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE &&
345	    state == IEEE80211_S_RUN) {
346		int interval;
347		/*
348		 * Start the background rate control thread if we
349		 * are not configured to use a fixed xmit rate.
350		 */
351		interval = ath_rateinterval;
352		if (ic->ic_opmode == IEEE80211_M_STA)
353			interval /= 2;
354		callout_reset(&osc->timer, (interval * hz) / 1000,
355			ath_ratectl, sc->sc_ifp);
356	}
357}
358
359/*
360 * Examine and potentially adjust the transmit rate.
361 */
362static void
363ath_rate_ctl(void *arg, struct ieee80211_node *ni)
364{
365	struct ath_softc *sc = arg;
366	struct onoe_node *on = ATH_NODE_ONOE(ATH_NODE(ni));
367	struct ieee80211_rateset *rs = &ni->ni_rates;
368	int dir = 0, nrate, enough;
369
370	/*
371	 * Rate control
372	 * XXX: very primitive version.
373	 */
374	enough = (on->on_tx_ok + on->on_tx_err >= 10);
375
376	/* no packet reached -> down */
377	if (on->on_tx_err > 0 && on->on_tx_ok == 0)
378		dir = -1;
379
380	/* all packets needs retry in average -> down */
381	if (enough && on->on_tx_ok < on->on_tx_retr)
382		dir = -1;
383
384	/* no error and less than rate_raise% of packets need retry -> up */
385	if (enough && on->on_tx_err == 0 &&
386	    on->on_tx_retr < (on->on_tx_ok * ath_rate_raise) / 100)
387		dir = 1;
388
389	DPRINTF(sc, "%s: ok %d err %d retr %d upper %d dir %d\n",
390		ether_sprintf(ni->ni_macaddr),
391		on->on_tx_ok, on->on_tx_err, on->on_tx_retr,
392		on->on_tx_upper, dir);
393
394	nrate = ni->ni_txrate;
395	switch (dir) {
396	case 0:
397		if (enough && on->on_tx_upper > 0)
398			on->on_tx_upper--;
399		break;
400	case -1:
401		if (nrate > 0) {
402			nrate--;
403			sc->sc_stats.ast_rate_drop++;
404		}
405		on->on_tx_upper = 0;
406		break;
407	case 1:
408		/* raise rate if we hit rate_raise_threshold */
409		if (++on->on_tx_upper < ath_rate_raise_threshold)
410			break;
411		on->on_tx_upper = 0;
412		if (nrate + 1 < rs->rs_nrates) {
413			nrate++;
414			sc->sc_stats.ast_rate_raise++;
415		}
416		break;
417	}
418
419	if (nrate != ni->ni_txrate) {
420		DPRINTF(sc, "%s: %dM -> %dM (%d ok, %d err, %d retr)\n",
421		    __func__,
422		    (rs->rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL) / 2,
423		    (rs->rs_rates[nrate] & IEEE80211_RATE_VAL) / 2,
424		    on->on_tx_ok, on->on_tx_err, on->on_tx_retr);
425		ath_rate_update(sc, ni, nrate);
426	} else if (enough)
427		on->on_tx_ok = on->on_tx_err = on->on_tx_retr = 0;
428}
429
430static void
431ath_ratectl(void *arg)
432{
433	struct ifnet *ifp = arg;
434	struct ath_softc *sc = ifp->if_softc;
435	struct onoe_softc *osc = (struct onoe_softc *) sc->sc_rc;
436	struct ieee80211com *ic = &sc->sc_ic;
437	int interval;
438
439	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
440		sc->sc_stats.ast_rate_calls++;
441
442		if (ic->ic_opmode == IEEE80211_M_STA)
443			ath_rate_ctl(sc, ic->ic_bss);	/* NB: no reference */
444		else
445			ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_ctl, sc);
446	}
447	interval = ath_rateinterval;
448	if (ic->ic_opmode == IEEE80211_M_STA)
449		interval /= 2;
450	callout_reset(&osc->timer, (interval * hz) / 1000,
451		ath_ratectl, sc->sc_ifp);
452}
453
454static void
455ath_rate_sysctlattach(struct ath_softc *sc)
456{
457	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
458	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
459
460	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
461		"rate_interval", CTLFLAG_RW, &ath_rateinterval, 0,
462		"rate control: operation interval (ms)");
463	/* XXX bounds check values */
464	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
465		"rate_raise", CTLFLAG_RW, &ath_rate_raise, 0,
466		"rate control: retry threshold to credit rate raise (%%)");
467	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
468		"rate_raise_threshold", CTLFLAG_RW, &ath_rate_raise_threshold,0,
469		"rate control: # good periods before raising rate");
470}
471
472struct ath_ratectrl *
473ath_rate_attach(struct ath_softc *sc)
474{
475	struct onoe_softc *osc;
476
477	osc = malloc(sizeof(struct onoe_softc), M_DEVBUF, M_NOWAIT|M_ZERO);
478	if (osc == NULL)
479		return NULL;
480	osc->arc.arc_space = sizeof(struct onoe_node);
481	callout_init(&osc->timer, CALLOUT_MPSAFE);
482	ath_rate_sysctlattach(sc);
483
484	return &osc->arc;
485}
486
487void
488ath_rate_detach(struct ath_ratectrl *arc)
489{
490	struct onoe_softc *osc = (struct onoe_softc *) arc;
491
492	callout_drain(&osc->timer);
493	free(osc, M_DEVBUF);
494}
495
496/*
497 * Module glue.
498 */
499static int
500onoe_modevent(module_t mod, int type, void *unused)
501{
502	switch (type) {
503	case MOD_LOAD:
504		if (bootverbose)
505			printf("ath_rate: <Atsushi Onoe's rate control algorithm>\n");
506		return 0;
507	case MOD_UNLOAD:
508		return 0;
509	}
510	return EINVAL;
511}
512
513static moduledata_t onoe_mod = {
514	"ath_rate",
515	onoe_modevent,
516	0
517};
518DECLARE_MODULE(ath_rate, onoe_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
519MODULE_VERSION(ath_rate, 1);
520MODULE_DEPEND(ath_rate, wlan, 1, 1, 1);
521