1 /* $NetBSD: ieee80211_amrr.c,v 1.2 2007/12/11 12:40:10 lukem Exp $ */
2 /* $OpenBSD: ieee80211_amrr.c,v 1.1 2006/06/17 19:07:19 damien Exp $ */
5 * Copyright 2016 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
10 * Damien Bergamini <damien.bergamini@free.fr>
12 * Permission to use, copy, modify, and distribute this software for any
13 * purpose with or without fee is hereby granted, provided that the above
14 * copyright notice and this permission notice appear in all copies.
16 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
17 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
19 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
22 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 #include <sys/param.h>
26 #include <sys/socket.h>
31 #include <sys/net80211.h>
32 #include <sys/net80211_amrr.h>
33 #include "net80211_impl.h"
35 #define is_success(amn) \
36 ((amn)->amn_retrycnt < (amn)->amn_txcnt / 10)
37 #define is_failure(amn) \
38 ((amn)->amn_retrycnt > (amn)->amn_txcnt / 3)
39 #define is_enough(amn) \
40 ((amn)->amn_txcnt > 10)
41 #define is_min_rate(ni) \
42 ((ni)->in_txrate == 0)
43 #define is_max_rate(ni) \
44 ((ni)->in_txrate == (ni)->in_rates.ir_nrates - 1)
45 #define increase_rate(ni) \
47 #define decrease_rate(ni) \
49 #define reset_cnt(amn) \
50 do { (amn)->amn_txcnt = (amn)->amn_retrycnt = 0; \
51 _NOTE(CONSTCOND) } while (0)
54 ieee80211_amrr_node_init(struct ieee80211_amrr
*amrr
,
55 struct ieee80211_amrr_node
*amn
)
58 amn
->amn_recovery
= 0;
59 amn
->amn_txcnt
= amn
->amn_retrycnt
= 0;
60 amn
->amn_success_threshold
= amrr
->amrr_min_success_threshold
;
64 * Update ni->in_txrate.
67 ieee80211_amrr_choose(struct ieee80211_amrr
*amrr
, struct ieee80211_node
*ni
,
68 struct ieee80211_amrr_node
*amn
)
73 if (is_success(amn
) && is_enough(amn
)) {
75 if (amn
->amn_success
>= amn
->amn_success_threshold
&&
77 amn
->amn_recovery
= 1;
80 rate
= ni
->in_rates
.ir_rates
[ni
->in_txrate
] &
82 ieee80211_dbg(IEEE80211_MSG_XRATE
,
83 "AMRR increasing rate %d (txcnt=%d retrycnt=%d)",
84 rate
, amn
->amn_txcnt
, amn
->amn_retrycnt
);
85 DTRACE_PROBE4(amrr__increase__rate
,
86 struct ieee80211_node
*, ni
,
88 uint_t
, amn
->amn_txcnt
,
89 uint_t
, amn
->amn_retrycnt
);
92 amn
->amn_recovery
= 0;
94 } else if (is_failure(amn
)) {
96 if (!is_min_rate(ni
)) {
97 if (amn
->amn_recovery
) {
98 amn
->amn_success_threshold
*= 2;
99 if (amn
->amn_success_threshold
>
100 amrr
->amrr_max_success_threshold
)
101 amn
->amn_success_threshold
=
102 amrr
->amrr_max_success_threshold
;
104 amn
->amn_success_threshold
=
105 amrr
->amrr_min_success_threshold
;
108 rate
= ni
->in_rates
.ir_rates
[ni
->in_txrate
] &
110 ieee80211_dbg(IEEE80211_MSG_XRATE
,
111 "AMRR decreasing rate %d (txcnt=%d retrycnt=%d)",
112 rate
, amn
->amn_txcnt
, amn
->amn_retrycnt
);
113 DTRACE_PROBE4(amrr__decrease__rate
,
114 struct ieee80211_node
*, ni
,
116 uint_t
, amn
->amn_txcnt
,
117 uint_t
, amn
->amn_retrycnt
);
120 amn
->amn_recovery
= 0;
123 if (is_enough(amn
) || need_change
)