1 /* $NetBSD: ieee80211_amrr.c,v 1.1 2006/10/31 21:53:41 joerg Exp $ */
2 /* $OpenBSD: ieee80211_amrr.c,v 1.1 2006/06/17 19:07:19 damien Exp $ */
6 * Damien Bergamini <damien.bergamini@free.fr>
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 #include <sys/cdefs.h>
22 __KERNEL_RCSID(0, "$NetBSD$");
24 #include <sys/param.h>
25 #include <sys/kernel.h>
26 #include <sys/socket.h>
27 #include <sys/sysctl.h>
30 #include <net/if_media.h>
33 #include <netinet/in.h>
34 #include <netinet/if_ether.h>
37 #include <net80211/ieee80211.h>
38 #include <net80211/ieee80211_var.h>
39 #include <net80211/ieee80211_amrr.h>
41 #define is_success(amn) \
42 ((amn)->amn_retrycnt < (amn)->amn_txcnt / 10)
43 #define is_failure(amn) \
44 ((amn)->amn_retrycnt > (amn)->amn_txcnt / 3)
45 #define is_enough(amn) \
46 ((amn)->amn_txcnt > 10)
47 #define is_min_rate(ni) \
48 ((ni)->ni_txrate == 0)
49 #define is_max_rate(ni) \
50 ((ni)->ni_txrate == (ni)->ni_rates.rs_nrates - 1)
51 #define increase_rate(ni) \
53 #define decrease_rate(ni) \
55 #define reset_cnt(amn) \
56 do { (amn)->amn_txcnt = (amn)->amn_retrycnt = 0; } while (0)
59 ieee80211_amrr_node_init(struct ieee80211_amrr
*amrr
,
60 struct ieee80211_amrr_node
*amn
)
63 amn
->amn_recovery
= 0;
64 amn
->amn_txcnt
= amn
->amn_retrycnt
= 0;
65 amn
->amn_success_threshold
= amrr
->amrr_min_success_threshold
;
69 * Update ni->ni_txrate.
72 ieee80211_amrr_choose(struct ieee80211_amrr
*amrr
, struct ieee80211_node
*ni
,
73 struct ieee80211_amrr_node
*amn
)
77 if (is_success(amn
) && is_enough(amn
)) {
79 if (amn
->amn_success
>= amn
->amn_success_threshold
&&
81 amn
->amn_recovery
= 1;
84 IEEE80211_DPRINTF(ni
->ni_ic
, IEEE80211_MSG_DEBUG
,
85 "AMRR increasing rate %d (txcnt=%d retrycnt=%d)\n",
86 ni
->ni_rates
.rs_rates
[ni
->ni_txrate
] &
88 amn
->amn_txcnt
, amn
->amn_retrycnt
);
91 amn
->amn_recovery
= 0;
93 } else if (is_failure(amn
)) {
95 if (!is_min_rate(ni
)) {
96 if (amn
->amn_recovery
) {
97 amn
->amn_success_threshold
*= 2;
98 if (amn
->amn_success_threshold
>
99 amrr
->amrr_max_success_threshold
)
100 amn
->amn_success_threshold
=
101 amrr
->amrr_max_success_threshold
;
103 amn
->amn_success_threshold
=
104 amrr
->amrr_min_success_threshold
;
107 IEEE80211_DPRINTF(ni
->ni_ic
, IEEE80211_MSG_DEBUG
,
108 "AMRR decreasing rate %d (txcnt=%d retrycnt=%d)\n",
109 ni
->ni_rates
.rs_rates
[ni
->ni_txrate
] &
111 amn
->amn_txcnt
, amn
->amn_retrycnt
);
114 amn
->amn_recovery
= 0;
117 if (is_enough(amn
) || need_change
)