1 /* $NetBSD: athrate-onoe.c,v 1.13 2008/12/11 05:45:29 alc Exp $ */
4 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer,
12 * without modification.
13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
15 * redistribution must be conditioned upon including a substantially
16 * similar Disclaimer requirement for further binary redistribution.
17 * 3. Neither the names of the above-listed copyright holders nor the names
18 * of any contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * Alternatively, this software may be distributed under the terms of the
22 * GNU General Public License ("GPL") version 2 as published by the Free
23 * Software Foundation.
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
29 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
30 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
31 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
34 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
36 * THE POSSIBILITY OF SUCH DAMAGES.
39 #include <sys/cdefs.h>
41 __FBSDID("$FreeBSD: src/sys/dev/ath/ath_rate/onoe/onoe.c,v 1.10 2005/08/09 10:19:43 rwatson Exp $");
44 __KERNEL_RCSID(0, "$NetBSD: athrate-onoe.c,v 1.13 2008/12/11 05:45:29 alc Exp $");
48 * Atsushi Onoe's rate control algorithm.
52 #include <sys/param.h>
53 #include <sys/systm.h>
54 #include <sys/sysctl.h>
55 #include <sys/kernel.h>
56 #include <sys/errno.h>
57 #include <sys/device.h>
59 #include <sys/socket.h>
62 #include <net/if_media.h>
63 #include <net/if_arp.h>
64 #include <net/if_ether.h> /* XXX for ether_sprintf */
66 #include <net80211/ieee80211_var.h>
71 #include <netinet/in.h>
75 #include <dev/ic/ath_netbsd.h>
76 #include <dev/ic/athvar.h>
77 #include <dev/ic/athrate-onoe.h>
79 #include <external/isc/atheros_hal/dist/ah.h>
87 ATH_DEBUG_RATE
= 0x00000010, /* rate control */
89 #define DPRINTF(sc, _fmt, ...) do { \
90 if (sc->sc_debug & ATH_DEBUG_RATE) \
91 printf(_fmt, __VA_ARGS__); \
94 #define DPRINTF(sc, _fmt, ...)
98 * Default parameters for the rate control algorithm. These are
99 * all tunable with sysctls. The rate controller runs periodically
100 * (each ath_rateinterval ms) analyzing transmit statistics for each
101 * neighbor/station (when operating in station mode this is only the AP).
102 * If transmits look to be working well over a sampling period then
103 * it gives a "raise rate credit". If transmits look to not be working
104 * well than it deducts a credit. If the credits cross a threshold then
105 * the transmit rate is raised. Various error conditions force the
106 * the transmit rate to be dropped.
108 * The decision to issue/deduct a credit is based on the errors and
109 * retries accumulated over the sampling period. ath_rate_raise defines
110 * the percent of retransmits for which a credit is issued/deducted.
111 * ath_rate_raise_threshold defines the threshold on credits at which
112 * the transmit rate is increased.
114 * XXX this algorithm is flawed.
116 static int ath_rateinterval
= 1000; /* rate ctl interval (ms) */
117 static int ath_rate_raise
= 10; /* add credit threshold */
118 static int ath_rate_raise_threshold
= 10; /* rate ctl raise threshold */
120 static void ath_ratectl(void *);
121 static void ath_rate_update(struct ath_softc
*, struct ieee80211_node
*,
123 static void ath_rate_ctl_start(struct ath_softc
*, struct ieee80211_node
*);
124 static void ath_rate_ctl(void *, struct ieee80211_node
*);
127 ath_rate_node_init(struct ath_softc
*sc
, struct ath_node
*an
)
129 /* NB: assumed to be zero'd by caller */
130 ath_rate_update(sc
, &an
->an_node
, 0);
134 ath_rate_node_cleanup(struct ath_softc
*sc
, struct ath_node
*an
)
139 ath_rate_findrate(struct ath_softc
*sc
, struct ath_node
*an
,
140 int shortPreamble
, size_t frameLen
,
141 u_int8_t
*rix
, int *try0
, u_int8_t
*txrate
)
143 struct onoe_node
*on
= ATH_NODE_ONOE(an
);
145 *rix
= on
->on_tx_rix0
;
146 *try0
= on
->on_tx_try0
;
148 *txrate
= on
->on_tx_rate0sp
;
150 *txrate
= on
->on_tx_rate0
;
154 ath_rate_setupxtxdesc(struct ath_softc
*sc
, struct ath_node
*an
,
155 struct ath_desc
*ds
, int shortPreamble
, u_int8_t rix
)
157 struct onoe_node
*on
= ATH_NODE_ONOE(an
);
159 ath_hal_setupxtxdesc(sc
->sc_ah
, ds
160 , on
->on_tx_rate1sp
, 2 /* series 1 */
161 , on
->on_tx_rate2sp
, 2 /* series 2 */
162 , on
->on_tx_rate3sp
, 2 /* series 3 */
167 ath_rate_tx_complete(struct ath_softc
*sc
, struct ath_node
*an
,
168 const struct ath_desc
*ds
, const struct ath_desc
*ds0
)
170 struct onoe_node
*on
= ATH_NODE_ONOE(an
);
172 if (ds
->ds_txstat
.ts_status
== 0)
176 on
->on_tx_retr
+= ds
->ds_txstat
.ts_shortretry
177 + ds
->ds_txstat
.ts_longretry
;
181 ath_rate_newassoc(struct ath_softc
*sc
, struct ath_node
*an
, int isnew
)
184 ath_rate_ctl_start(sc
, &an
->an_node
);
188 ath_rate_update(struct ath_softc
*sc
, struct ieee80211_node
*ni
, int rate
)
190 struct ath_node
*an
= ATH_NODE(ni
);
191 struct onoe_node
*on
= ATH_NODE_ONOE(an
);
192 const HAL_RATE_TABLE
*rt
= sc
->sc_currates
;
195 KASSERT(rt
!= NULL
, ("no rate table, mode %u", sc
->sc_curmode
));
197 DPRINTF(sc
, "%s: set xmit rate for %s to %dM\n",
198 __func__
, ether_sprintf(ni
->ni_macaddr
),
199 ni
->ni_rates
.rs_nrates
> 0 ?
200 (ni
->ni_rates
.rs_rates
[rate
] & IEEE80211_RATE_VAL
) / 2 : 0);
202 ni
->ni_txrate
= rate
;
204 * Before associating a node has no rate set setup
205 * so we can't calculate any transmit codes to use.
206 * This is ok since we should never be sending anything
207 * but management frames and those always go at the
208 * lowest hardware rate.
210 if (ni
->ni_rates
.rs_nrates
== 0)
212 on
->on_tx_rix0
= sc
->sc_rixmap
[
213 ni
->ni_rates
.rs_rates
[rate
] & IEEE80211_RATE_VAL
];
214 on
->on_tx_rate0
= rt
->info
[on
->on_tx_rix0
].rateCode
;
216 on
->on_tx_rate0sp
= on
->on_tx_rate0
|
217 rt
->info
[on
->on_tx_rix0
].shortPreamble
;
218 if (sc
->sc_mrretry
) {
220 * Hardware supports multi-rate retry; setup two
221 * step-down retry rates and make the lowest rate
222 * be the ``last chance''. We use 4, 2, 2, 2 tries
223 * respectively (4 is set here, the rest are fixed
224 * in the xmit routine).
226 on
->on_tx_try0
= 1 + 3; /* 4 tries at rate 0 */
229 ni
->ni_rates
.rs_rates
[rate
]&IEEE80211_RATE_VAL
];
230 on
->on_tx_rate1
= rt
->info
[rix
].rateCode
;
231 on
->on_tx_rate1sp
= on
->on_tx_rate1
|
232 rt
->info
[rix
].shortPreamble
;
234 on
->on_tx_rate1
= on
->on_tx_rate1sp
= 0;
238 ni
->ni_rates
.rs_rates
[rate
]&IEEE80211_RATE_VAL
];
239 on
->on_tx_rate2
= rt
->info
[rix
].rateCode
;
240 on
->on_tx_rate2sp
= on
->on_tx_rate2
|
241 rt
->info
[rix
].shortPreamble
;
243 on
->on_tx_rate2
= on
->on_tx_rate2sp
= 0;
246 /* NB: only do this if we didn't already do it above */
247 on
->on_tx_rate3
= rt
->info
[0].rateCode
;
249 on
->on_tx_rate3
| rt
->info
[0].shortPreamble
;
251 on
->on_tx_rate3
= on
->on_tx_rate3sp
= 0;
254 on
->on_tx_try0
= ATH_TXMAXTRY
; /* max tries at rate 0 */
255 on
->on_tx_rate1
= on
->on_tx_rate1sp
= 0;
256 on
->on_tx_rate2
= on
->on_tx_rate2sp
= 0;
257 on
->on_tx_rate3
= on
->on_tx_rate3sp
= 0;
260 on
->on_tx_ok
= on
->on_tx_err
= on
->on_tx_retr
= on
->on_tx_upper
= 0;
264 * Set the starting transmit rate for a node.
267 ath_rate_ctl_start(struct ath_softc
*sc
, struct ieee80211_node
*ni
)
269 #define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL)
270 struct ieee80211com
*ic
= &sc
->sc_ic
;
273 KASSERT(ni
->ni_rates
.rs_nrates
> 0, ("no rates"));
274 if (ic
->ic_fixed_rate
== IEEE80211_FIXED_RATE_NONE
) {
276 * No fixed rate is requested. For 11b start with
277 * the highest negotiated rate; otherwise, for 11g
278 * and 11a, we start "in the middle" at 24Mb or 36Mb.
280 srate
= ni
->ni_rates
.rs_nrates
- 1;
281 if (sc
->sc_curmode
!= IEEE80211_MODE_11B
) {
283 * Scan the negotiated rate set to find the
286 /* NB: the rate set is assumed sorted */
287 for (; srate
>= 0 && RATE(srate
) > 72; srate
--)
289 KASSERT(srate
>= 0, ("bogus rate set"));
293 * A fixed rate is to be used; ic_fixed_rate is an
294 * index into the supported rate set. Convert this
295 * to the index into the negotiated rate set for
296 * the node. We know the rate is there because the
297 * rate set is checked when the station associates.
299 const struct ieee80211_rateset
*rs
=
300 &ic
->ic_sup_rates
[ic
->ic_curmode
];
301 int r
= rs
->rs_rates
[ic
->ic_fixed_rate
] & IEEE80211_RATE_VAL
;
302 /* NB: the rate set is assumed sorted */
303 srate
= ni
->ni_rates
.rs_nrates
- 1;
304 for (; srate
>= 0 && RATE(srate
) != r
; srate
--)
307 ("fixed rate %d not in rate set", ic
->ic_fixed_rate
));
309 ath_rate_update(sc
, ni
, srate
);
314 ath_rate_cb(void *arg
, struct ieee80211_node
*ni
)
316 struct ath_softc
*sc
= arg
;
318 ath_rate_update(sc
, ni
, 0);
322 * Reset the rate control state for each 802.11 state transition.
325 ath_rate_newstate(struct ath_softc
*sc
, enum ieee80211_state state
)
327 struct onoe_softc
*osc
= (struct onoe_softc
*) sc
->sc_rc
;
328 struct ieee80211com
*ic
= &sc
->sc_ic
;
329 struct ieee80211_node
*ni
;
331 if (state
== IEEE80211_S_INIT
) {
332 callout_stop(&osc
->timer
);
335 if (ic
->ic_opmode
== IEEE80211_M_STA
) {
337 * Reset local xmit state; this is really only
338 * meaningful when operating in station mode.
341 if (state
== IEEE80211_S_RUN
) {
342 ath_rate_ctl_start(sc
, ni
);
344 ath_rate_update(sc
, ni
, 0);
348 * When operating as a station the node table holds
349 * the AP's that were discovered during scanning.
350 * For any other operating mode we want to reset the
351 * tx rate state of each node.
353 ieee80211_iterate_nodes(&ic
->ic_sta
, ath_rate_cb
, sc
);
354 ath_rate_update(sc
, ic
->ic_bss
, 0);
356 if (ic
->ic_fixed_rate
== IEEE80211_FIXED_RATE_NONE
&&
357 state
== IEEE80211_S_RUN
) {
360 * Start the background rate control thread if we
361 * are not configured to use a fixed xmit rate.
363 interval
= ath_rateinterval
;
364 if (ic
->ic_opmode
== IEEE80211_M_STA
)
366 callout_reset(&osc
->timer
, (interval
* hz
) / 1000,
367 ath_ratectl
, &sc
->sc_if
);
372 * Examine and potentially adjust the transmit rate.
375 ath_rate_ctl(void *arg
, struct ieee80211_node
*ni
)
377 struct ath_softc
*sc
= arg
;
378 struct onoe_node
*on
= ATH_NODE_ONOE(ATH_NODE(ni
));
379 struct ieee80211_rateset
*rs
= &ni
->ni_rates
;
380 int dir
= 0, nrate
, enough
;
384 * XXX: very primitive version.
386 enough
= (on
->on_tx_ok
+ on
->on_tx_err
>= 10);
388 /* no packet reached -> down */
389 if (on
->on_tx_err
> 0 && on
->on_tx_ok
== 0)
392 /* all packets needs retry in average -> down */
393 if (enough
&& on
->on_tx_ok
< on
->on_tx_retr
)
396 /* no error and less than rate_raise% of packets need retry -> up */
397 if (enough
&& on
->on_tx_err
== 0 &&
398 on
->on_tx_retr
< (on
->on_tx_ok
* ath_rate_raise
) / 100)
401 DPRINTF(sc
, "%s: ok %d err %d retr %d upper %d dir %d\n",
402 ether_sprintf(ni
->ni_macaddr
),
403 on
->on_tx_ok
, on
->on_tx_err
, on
->on_tx_retr
,
404 on
->on_tx_upper
, dir
);
406 nrate
= ni
->ni_txrate
;
409 if (enough
&& on
->on_tx_upper
> 0)
415 sc
->sc_stats
.ast_rate_drop
++;
420 /* raise rate if we hit rate_raise_threshold */
421 if (++on
->on_tx_upper
< ath_rate_raise_threshold
)
424 if (nrate
+ 1 < rs
->rs_nrates
) {
426 sc
->sc_stats
.ast_rate_raise
++;
431 if (nrate
!= ni
->ni_txrate
) {
432 DPRINTF(sc
, "%s: %dM -> %dM (%d ok, %d err, %d retr)\n",
434 (rs
->rs_rates
[ni
->ni_txrate
] & IEEE80211_RATE_VAL
) / 2,
435 (rs
->rs_rates
[nrate
] & IEEE80211_RATE_VAL
) / 2,
436 on
->on_tx_ok
, on
->on_tx_err
, on
->on_tx_retr
);
437 ath_rate_update(sc
, ni
, nrate
);
439 on
->on_tx_ok
= on
->on_tx_err
= on
->on_tx_retr
= 0;
443 ath_ratectl(void *arg
)
445 struct ifnet
*ifp
= arg
;
446 struct ath_softc
*sc
= ifp
->if_softc
;
447 struct onoe_softc
*osc
= (struct onoe_softc
*) sc
->sc_rc
;
448 struct ieee80211com
*ic
= &sc
->sc_ic
;
451 if (ifp
->if_flags
& IFF_RUNNING
) {
452 sc
->sc_stats
.ast_rate_calls
++;
454 if (ic
->ic_opmode
== IEEE80211_M_STA
)
455 ath_rate_ctl(sc
, ic
->ic_bss
); /* NB: no reference */
457 ieee80211_iterate_nodes(&ic
->ic_sta
, ath_rate_ctl
, sc
);
459 interval
= ath_rateinterval
;
460 if (ic
->ic_opmode
== IEEE80211_M_STA
)
462 callout_reset(&osc
->timer
, (interval
* hz
) / 1000,
463 ath_ratectl
, &sc
->sc_if
);
467 ath_rate_sysctlattach(struct ath_softc
*sc
)
469 struct sysctllog
**clog
= &sc
->sc_sysctllog
;
470 const struct sysctlnode
*cnode
, *rnode
;
472 if ((rnode
= ath_sysctl_treetop(NULL
)) == NULL
)
475 SYSCTL_GLOBAL_INT(CTLFLAG_READWRITE
, "rate_interval",
476 "rate control: operation interval (ms)", rateinterval
);
477 /* XXX bounds check values */
478 SYSCTL_GLOBAL_INT(CTLFLAG_READWRITE
, "rate_raise",
479 "rate control: retry threshold to credit rate raise (%%)",
481 SYSCTL_GLOBAL_INT(CTLFLAG_READWRITE
, "rate_raise_threshold",
482 "rate control: # good periods before raising rate",
483 rate_raise_threshold
);
486 struct ath_ratectrl
*
487 ath_rate_attach(struct ath_softc
*sc
)
489 struct onoe_softc
*osc
;
491 osc
= malloc(sizeof(struct onoe_softc
), M_DEVBUF
, M_NOWAIT
|M_ZERO
);
494 osc
->arc
.arc_space
= sizeof(struct onoe_node
);
495 callout_init(&osc
->timer
, 0);
496 ath_rate_sysctlattach(sc
);
502 ath_rate_detach(struct ath_ratectrl
*arc
)
504 struct onoe_softc
*osc
= (struct onoe_softc
*) arc
;
506 callout_stop(&osc
->timer
);