6757 want AMRR support in net80211
[unleashed.git] / usr / src / uts / common / io / net80211 / net80211_amrr.c
blob61d917bfbe91d4b8b61d20d9ef6cd294e73a280a
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 $ */
4 /*
5 * Copyright 2016 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
6 */
8 /*
9 * Copyright (c) 2006
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>
27 #include <sys/sdt.h>
29 #include <net/if.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) \
46 ((ni)->in_txrate++)
47 #define decrease_rate(ni) \
48 ((ni)->in_txrate--)
49 #define reset_cnt(amn) \
50 do { (amn)->amn_txcnt = (amn)->amn_retrycnt = 0; \
51 _NOTE(CONSTCOND) } while (0)
53 void
54 ieee80211_amrr_node_init(struct ieee80211_amrr *amrr,
55 struct ieee80211_amrr_node *amn)
57 amn->amn_success = 0;
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.
66 void
67 ieee80211_amrr_choose(struct ieee80211_amrr *amrr, struct ieee80211_node *ni,
68 struct ieee80211_amrr_node *amn)
70 int need_change = 0;
71 uint8_t rate;
73 if (is_success(amn) && is_enough(amn)) {
74 amn->amn_success++;
75 if (amn->amn_success >= amn->amn_success_threshold &&
76 !is_max_rate(ni)) {
77 amn->amn_recovery = 1;
78 amn->amn_success = 0;
79 increase_rate(ni);
80 rate = ni->in_rates.ir_rates[ni->in_txrate] &
81 IEEE80211_RATE_VAL;
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,
87 uint8_t, rate,
88 uint_t, amn->amn_txcnt,
89 uint_t, amn->amn_retrycnt);
90 need_change = 1;
91 } else {
92 amn->amn_recovery = 0;
94 } else if (is_failure(amn)) {
95 amn->amn_success = 0;
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;
103 } else {
104 amn->amn_success_threshold =
105 amrr->amrr_min_success_threshold;
107 decrease_rate(ni);
108 rate = ni->in_rates.ir_rates[ni->in_txrate] &
109 IEEE80211_RATE_VAL;
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,
115 uint8_t, rate,
116 uint_t, amn->amn_txcnt,
117 uint_t, amn->amn_retrycnt);
118 need_change = 1;
120 amn->amn_recovery = 0;
123 if (is_enough(amn) || need_change)
124 reset_cnt(amn);