This source file includes following definitions.
- ieee80211_rssadapt_choose
- ieee80211_rssadapt_updatestats
- ieee80211_rssadapt_input
- ieee80211_rssadapt_lower_rate
- ieee80211_rssadapt_raise_rate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #include <sys/param.h>
35 #include <sys/kernel.h>
36 #include <sys/socket.h>
37 #include <sys/sysctl.h>
38
39 #include <net/if.h>
40 #include <net/if_media.h>
41
42 #ifdef INET
43 #include <netinet/in.h>
44 #include <netinet/if_ether.h>
45 #endif
46
47 #include <net80211/ieee80211_var.h>
48 #include <net80211/ieee80211_rssadapt.h>
49
50 #ifdef interpolate
51 #undef interpolate
52 #endif
53 #define interpolate(parm, old, new) \
54 ((parm##_old * (old) + \
55 (parm##_denom - parm##_old) * (new)) / parm##_denom)
56
57 #ifdef IEEE80211_DEBUG
58 static struct timeval lastrateadapt;
59 static int currssadaptps = 0;
60 static int ieee80211_adaptrate = 4;
61
62 #define RSSADAPT_DO_PRINT() \
63 ((ieee80211_rssadapt_debug > 0) && \
64 ppsratecheck(&lastrateadapt, &currssadaptps, ieee80211_adaptrate))
65 #define RSSADAPT_PRINTF(X) \
66 if (RSSADAPT_DO_PRINT()) \
67 printf X
68
69 int ieee80211_rssadapt_debug = 0;
70
71 #else
72 #define RSSADAPT_DO_PRINT() (0)
73 #define RSSADAPT_PRINTF(X)
74 #endif
75
76 static struct ieee80211_rssadapt_expavgctl master_expavgctl = {
77 rc_decay_denom : 16,
78 rc_decay_old : 15,
79 rc_thresh_denom : 8,
80 rc_thresh_old : 4,
81 rc_avgrssi_denom : 8,
82 rc_avgrssi_old : 4
83 };
84
85 int
86 ieee80211_rssadapt_choose(struct ieee80211_rssadapt *ra,
87 const struct ieee80211_rateset *rs, const struct ieee80211_frame *wh,
88 u_int len, int fixed_rate, const char *dvname, int do_not_adapt)
89 {
90 u_int16_t (*thrs)[IEEE80211_RATE_SIZE];
91 int flags = 0, i, rateidx = 0, thridx, top;
92
93 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
94 flags |= IEEE80211_RATE_BASIC;
95
96 for (i = 0, top = IEEE80211_RSSADAPT_BKT0;
97 i < IEEE80211_RSSADAPT_BKTS;
98 i++, top <<= IEEE80211_RSSADAPT_BKTPOWER) {
99 thridx = i;
100 if (len <= top)
101 break;
102 }
103
104 thrs = &ra->ra_rate_thresh[thridx];
105
106 if (fixed_rate != -1) {
107 if ((rs->rs_rates[fixed_rate] & flags) == flags) {
108 rateidx = fixed_rate;
109 goto out;
110 }
111 flags |= IEEE80211_RATE_BASIC;
112 i = fixed_rate;
113 } else
114 i = rs->rs_nrates;
115
116 while (--i >= 0) {
117 rateidx = i;
118 if ((rs->rs_rates[i] & flags) != flags)
119 continue;
120 if (do_not_adapt)
121 break;
122 if ((*thrs)[i] < ra->ra_avg_rssi)
123 break;
124 }
125
126 out:
127 #ifdef IEEE80211_DEBUG
128 if (ieee80211_rssadapt_debug && dvname != NULL) {
129 printf("%s: dst %s threshold[%d, %d.%d] %d < %d\n",
130 dvname, ether_sprintf((u_int8_t *)wh->i_addr1), len,
131 (rs->rs_rates[rateidx] & IEEE80211_RATE_VAL) / 2,
132 (rs->rs_rates[rateidx] & IEEE80211_RATE_VAL) * 5 % 10,
133 (*thrs)[rateidx], ra->ra_avg_rssi);
134 }
135 #endif
136 return rateidx;
137 }
138
139 void
140 ieee80211_rssadapt_updatestats(struct ieee80211_rssadapt *ra)
141 {
142 long interval;
143
144 ra->ra_pktrate =
145 (ra->ra_pktrate + 10 * (ra->ra_nfail + ra->ra_nok)) / 2;
146 ra->ra_nfail = ra->ra_nok = 0;
147
148
149
150
151 interval = MAX(100000, 10000000 / MAX(1, 10 * ra->ra_pktrate));
152 ra->ra_raise_interval.tv_sec = interval / (1000 * 1000);
153 ra->ra_raise_interval.tv_usec = interval % (1000 * 1000);
154 }
155
156 void
157 ieee80211_rssadapt_input(struct ieee80211com *ic,
158 const struct ieee80211_node *ni, struct ieee80211_rssadapt *ra, int rssi)
159 {
160 #ifdef IEEE80211_DEBUG
161 int last_avg_rssi = ra->ra_avg_rssi;
162 #endif
163
164 ra->ra_avg_rssi = interpolate(master_expavgctl.rc_avgrssi,
165 ra->ra_avg_rssi, (rssi << 8));
166
167 RSSADAPT_PRINTF(("%s: src %s rssi %d avg %d -> %d\n",
168 ic->ic_if.if_xname, ether_sprintf((u_int8_t *)ni->ni_macaddr),
169 rssi, last_avg_rssi, ra->ra_avg_rssi));
170 }
171
172
173
174
175
176
177
178 void
179 ieee80211_rssadapt_lower_rate(struct ieee80211com *ic,
180 const struct ieee80211_node *ni, struct ieee80211_rssadapt *ra,
181 const struct ieee80211_rssdesc *id)
182 {
183 const struct ieee80211_rateset *rs = &ni->ni_rates;
184 u_int16_t last_thr;
185 u_int i, thridx, top;
186
187 ra->ra_nfail++;
188
189 if (id->id_rateidx >= rs->rs_nrates) {
190 RSSADAPT_PRINTF(("ieee80211_rssadapt_lower_rate: "
191 "%s rate #%d > #%d out of bounds\n",
192 ether_sprintf((u_int8_t *)ni->ni_macaddr), id->id_rateidx,
193 rs->rs_nrates - 1));
194 return;
195 }
196
197 for (i = 0, top = IEEE80211_RSSADAPT_BKT0;
198 i < IEEE80211_RSSADAPT_BKTS;
199 i++, top <<= IEEE80211_RSSADAPT_BKTPOWER) {
200 thridx = i;
201 if (id->id_len <= top)
202 break;
203 }
204
205 last_thr = ra->ra_rate_thresh[thridx][id->id_rateidx];
206 ra->ra_rate_thresh[thridx][id->id_rateidx] =
207 interpolate(master_expavgctl.rc_thresh, last_thr,
208 (id->id_rssi << 8));
209
210 RSSADAPT_PRINTF(("%s: dst %s rssi %d threshold[%d, %d.%d] %d -> %d\n",
211 ic->ic_if.if_xname, ether_sprintf((u_int8_t *)ni->ni_macaddr),
212 id->id_rssi, id->id_len,
213 (rs->rs_rates[id->id_rateidx] & IEEE80211_RATE_VAL) / 2,
214 (rs->rs_rates[id->id_rateidx] & IEEE80211_RATE_VAL) * 5 % 10,
215 last_thr, ra->ra_rate_thresh[thridx][id->id_rateidx]));
216 }
217
218 void
219 ieee80211_rssadapt_raise_rate(struct ieee80211com *ic,
220 struct ieee80211_rssadapt *ra, const struct ieee80211_rssdesc *id)
221 {
222 u_int16_t (*thrs)[IEEE80211_RATE_SIZE], newthr, oldthr;
223 const struct ieee80211_node *ni = id->id_node;
224 const struct ieee80211_rateset *rs = &ni->ni_rates;
225 int i, rate, top;
226 #ifdef IEEE80211_DEBUG
227 int j;
228 #endif
229
230 ra->ra_nok++;
231
232 if (!ratecheck(&ra->ra_last_raise, &ra->ra_raise_interval))
233 return;
234
235 for (i = 0, top = IEEE80211_RSSADAPT_BKT0;
236 i < IEEE80211_RSSADAPT_BKTS;
237 i++, top <<= IEEE80211_RSSADAPT_BKTPOWER) {
238 thrs = &ra->ra_rate_thresh[i];
239 if (id->id_len <= top)
240 break;
241 }
242
243 if (id->id_rateidx + 1 < rs->rs_nrates &&
244 (*thrs)[id->id_rateidx + 1] > (*thrs)[id->id_rateidx]) {
245 rate = (rs->rs_rates[id->id_rateidx + 1] & IEEE80211_RATE_VAL);
246
247 RSSADAPT_PRINTF(("%s: threshold[%d, %d.%d] decay %d ",
248 ic->ic_if.if_xname,
249 IEEE80211_RSSADAPT_BKT0 << (IEEE80211_RSSADAPT_BKTPOWER* i),
250 rate / 2, rate * 5 % 10, (*thrs)[id->id_rateidx + 1]));
251 oldthr = (*thrs)[id->id_rateidx + 1];
252 if ((*thrs)[id->id_rateidx] == 0)
253 newthr = ra->ra_avg_rssi;
254 else
255 newthr = (*thrs)[id->id_rateidx];
256 (*thrs)[id->id_rateidx + 1] =
257 interpolate(master_expavgctl.rc_decay, oldthr, newthr);
258
259 RSSADAPT_PRINTF(("-> %d\n", (*thrs)[id->id_rateidx + 1]));
260 }
261
262 #ifdef IEEE80211_DEBUG
263 if (RSSADAPT_DO_PRINT()) {
264 printf("%s: dst %s thresholds\n", ic->ic_if.if_xname,
265 ether_sprintf((u_int8_t *)ni->ni_macaddr));
266 for (i = 0; i < IEEE80211_RSSADAPT_BKTS; i++) {
267 printf("%d-byte", IEEE80211_RSSADAPT_BKT0 <<
268 (IEEE80211_RSSADAPT_BKTPOWER * i));
269 for (j = 0; j < rs->rs_nrates; j++) {
270 rate = (rs->rs_rates[j] & IEEE80211_RATE_VAL);
271 printf(", T[%d.%d] = %d", rate / 2,
272 rate * 5 % 10, ra->ra_rate_thresh[i][j]);
273 }
274 printf("\n");
275 }
276 }
277 #endif
278 }