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