File: | net80211/ieee80211_rssadapt.c |
Warning: | line 240, column 3 Value stored to 'rate' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: ieee80211_rssadapt.c,v 1.11 2014/12/23 03:24:08 tedu Exp $ */ |
2 | /* $NetBSD: ieee80211_rssadapt.c,v 1.7 2004/05/25 04:33:59 dyoung Exp $ */ |
3 | |
4 | /*- |
5 | * Copyright (c) 2003, 2004 David Young. All rights reserved. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or |
8 | * without modification, are permitted provided that the following |
9 | * conditions are met: |
10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above |
13 | * copyright notice, this list of conditions and the following |
14 | * disclaimer in the documentation and/or other materials provided |
15 | * with the distribution. |
16 | * |
17 | * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY |
18 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
19 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
20 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David |
21 | * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED |
23 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
26 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
28 | * OF SUCH DAMAGE. |
29 | */ |
30 | |
31 | #include <sys/param.h> |
32 | #include <sys/systm.h> |
33 | #include <sys/kernel.h> |
34 | #include <sys/socket.h> |
35 | |
36 | #include <net/if.h> |
37 | #include <net/if_media.h> |
38 | |
39 | #include <netinet/in.h> |
40 | #include <netinet/if_ether.h> |
41 | |
42 | #include <net80211/ieee80211_var.h> |
43 | #include <net80211/ieee80211_rssadapt.h> |
44 | |
45 | #ifdef interpolate |
46 | #undef interpolate |
47 | #endif |
48 | #define interpolate(parm, old, new)((parm_old * (old) + (parm_denom - parm_old) * (new)) / parm_denom ) \ |
49 | ((parm##_old * (old) + \ |
50 | (parm##_denom - parm##_old) * (new)) / parm##_denom) |
51 | |
52 | #ifdef IEEE80211_DEBUG |
53 | static struct timeval lastrateadapt; /* time of last rate adaptation msg */ |
54 | static int currssadaptps = 0; /* rate-adaptation msgs this second */ |
55 | static int ieee80211_adaptrate = 4; /* rate-adaptation max msgs/sec */ |
56 | |
57 | #define RSSADAPT_DO_PRINT()(0) \ |
58 | ((ieee80211_rssadapt_debug > 0) && \ |
59 | ppsratecheck(&lastrateadapt, &currssadaptps, ieee80211_adaptrate)) |
60 | #define RSSADAPT_PRINTF(X) \ |
61 | if (RSSADAPT_DO_PRINT()(0)) \ |
62 | printf X |
63 | |
64 | int ieee80211_rssadapt_debug = 0; |
65 | |
66 | #else |
67 | #define RSSADAPT_DO_PRINT()(0) (0) |
68 | #define RSSADAPT_PRINTF(X) |
69 | #endif |
70 | |
71 | static const struct ieee80211_rssadapt_expavgctl master_expavgctl = { |
72 | .rc_decay_denom = 16, |
73 | .rc_decay_old = 15, |
74 | .rc_thresh_denom = 8, |
75 | .rc_thresh_old = 4, |
76 | .rc_avgrssi_denom = 8, |
77 | .rc_avgrssi_old = 4 |
78 | }; |
79 | |
80 | int |
81 | ieee80211_rssadapt_choose(struct ieee80211_rssadapt *ra, |
82 | const struct ieee80211_rateset *rs, const struct ieee80211_frame *wh, |
83 | u_int len, int fixed_rate, const char *dvname, int do_not_adapt) |
84 | { |
85 | u_int16_t (*thrs)[IEEE80211_RATE_SIZE8]; |
86 | int flags = 0, i, rateidx = 0, thridx, top; |
87 | |
88 | if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK0x0c) == IEEE80211_FC0_TYPE_CTL0x04) |
89 | flags |= IEEE80211_RATE_BASIC0x80; |
90 | |
91 | for (i = 0, top = IEEE80211_RSSADAPT_BKT0128; |
92 | i < IEEE80211_RSSADAPT_BKTS3; |
93 | i++, top <<= IEEE80211_RSSADAPT_BKTPOWER3) { |
94 | thridx = i; |
95 | if (len <= top) |
96 | break; |
97 | } |
98 | |
99 | thrs = &ra->ra_rate_thresh[thridx]; |
100 | |
101 | if (fixed_rate != -1) { |
102 | if ((rs->rs_rates[fixed_rate] & flags) == flags) { |
103 | rateidx = fixed_rate; |
104 | goto out; |
105 | } |
106 | flags |= IEEE80211_RATE_BASIC0x80; |
107 | i = fixed_rate; |
108 | } else |
109 | i = rs->rs_nrates; |
110 | |
111 | while (--i >= 0) { |
112 | rateidx = i; |
113 | if ((rs->rs_rates[i] & flags) != flags) |
114 | continue; |
115 | if (do_not_adapt) |
116 | break; |
117 | if ((*thrs)[i] < ra->ra_avg_rssi) |
118 | break; |
119 | } |
120 | |
121 | out: |
122 | #ifdef IEEE80211_DEBUG |
123 | if (ieee80211_rssadapt_debug && dvname != NULL((void *)0)) { |
124 | printf("%s: dst %s threshold[%d, %d.%d] %d < %d\n", |
125 | dvname, ether_sprintf((u_int8_t *)wh->i_addr1), len, |
126 | (rs->rs_rates[rateidx] & IEEE80211_RATE_VAL0x7f) / 2, |
127 | (rs->rs_rates[rateidx] & IEEE80211_RATE_VAL0x7f) * 5 % 10, |
128 | (*thrs)[rateidx], ra->ra_avg_rssi); |
129 | } |
130 | #endif /* IEEE80211_DEBUG */ |
131 | return rateidx; |
132 | } |
133 | |
134 | void |
135 | ieee80211_rssadapt_updatestats(struct ieee80211_rssadapt *ra) |
136 | { |
137 | long interval; |
138 | |
139 | ra->ra_pktrate = |
140 | (ra->ra_pktrate + 10 * (ra->ra_nfail + ra->ra_nok)) / 2; |
141 | ra->ra_nfail = ra->ra_nok = 0; |
142 | |
143 | /* a node is eligible for its rate to be raised every 1/10 to 10 |
144 | * seconds, more eligible in proportion to recent packet rates. |
145 | */ |
146 | interval = MAX(100000, 10000000 / MAX(1, 10 * ra->ra_pktrate))(((100000)>(10000000 / (((1)>(10 * ra->ra_pktrate))? (1):(10 * ra->ra_pktrate))))?(100000):(10000000 / (((1)> (10 * ra->ra_pktrate))?(1):(10 * ra->ra_pktrate)))); |
147 | ra->ra_raise_interval.tv_sec = interval / (1000 * 1000); |
148 | ra->ra_raise_interval.tv_usec = interval % (1000 * 1000); |
149 | } |
150 | |
151 | void |
152 | ieee80211_rssadapt_input(struct ieee80211com *ic, |
153 | const struct ieee80211_node *ni, struct ieee80211_rssadapt *ra, int rssi) |
154 | { |
155 | #ifdef IEEE80211_DEBUG |
156 | int last_avg_rssi = ra->ra_avg_rssi; |
157 | #endif |
158 | |
159 | ra->ra_avg_rssi = interpolate(master_expavgctl.rc_avgrssi,((master_expavgctl.rc_avgrssi_old * (ra->ra_avg_rssi) + (master_expavgctl .rc_avgrssi_denom - master_expavgctl.rc_avgrssi_old) * ((rssi << 8))) / master_expavgctl.rc_avgrssi_denom) |
160 | ra->ra_avg_rssi, (rssi << 8))((master_expavgctl.rc_avgrssi_old * (ra->ra_avg_rssi) + (master_expavgctl .rc_avgrssi_denom - master_expavgctl.rc_avgrssi_old) * ((rssi << 8))) / master_expavgctl.rc_avgrssi_denom); |
161 | |
162 | RSSADAPT_PRINTF(("%s: src %s rssi %d avg %d -> %d\n", |
163 | ic->ic_if.if_xname, ether_sprintf((u_int8_t *)ni->ni_macaddr), |
164 | rssi, last_avg_rssi, ra->ra_avg_rssi)); |
165 | } |
166 | |
167 | /* |
168 | * Adapt the data rate to suit the conditions. When a transmitted |
169 | * packet is dropped after IEEE80211_RSSADAPT_RETRY_LIMIT retransmissions, |
170 | * raise the RSS threshold for transmitting packets of similar length at |
171 | * the same data rate. |
172 | */ |
173 | void |
174 | ieee80211_rssadapt_lower_rate(struct ieee80211com *ic, |
175 | const struct ieee80211_node *ni, struct ieee80211_rssadapt *ra, |
176 | const struct ieee80211_rssdesc *id) |
177 | { |
178 | const struct ieee80211_rateset *rs = &ni->ni_rates; |
179 | u_int16_t last_thr; |
180 | u_int i, thridx, top; |
181 | |
182 | ra->ra_nfail++; |
183 | |
184 | if (id->id_rateidx >= rs->rs_nrates) { |
185 | RSSADAPT_PRINTF(("ieee80211_rssadapt_lower_rate: " |
186 | "%s rate #%d > #%d out of bounds\n", |
187 | ether_sprintf((u_int8_t *)ni->ni_macaddr), id->id_rateidx, |
188 | rs->rs_nrates - 1)); |
189 | return; |
190 | } |
191 | |
192 | for (i = 0, top = IEEE80211_RSSADAPT_BKT0128; |
193 | i < IEEE80211_RSSADAPT_BKTS3; |
194 | i++, top <<= IEEE80211_RSSADAPT_BKTPOWER3) { |
195 | thridx = i; |
196 | if (id->id_len <= top) |
197 | break; |
198 | } |
199 | |
200 | last_thr = ra->ra_rate_thresh[thridx][id->id_rateidx]; |
201 | ra->ra_rate_thresh[thridx][id->id_rateidx] = |
202 | interpolate(master_expavgctl.rc_thresh, last_thr,((master_expavgctl.rc_thresh_old * (last_thr) + (master_expavgctl .rc_thresh_denom - master_expavgctl.rc_thresh_old) * ((id-> id_rssi << 8))) / master_expavgctl.rc_thresh_denom) |
203 | (id->id_rssi << 8))((master_expavgctl.rc_thresh_old * (last_thr) + (master_expavgctl .rc_thresh_denom - master_expavgctl.rc_thresh_old) * ((id-> id_rssi << 8))) / master_expavgctl.rc_thresh_denom); |
204 | |
205 | RSSADAPT_PRINTF(("%s: dst %s rssi %d threshold[%d, %d.%d] %d -> %d\n", |
206 | ic->ic_if.if_xname, ether_sprintf((u_int8_t *)ni->ni_macaddr), |
207 | id->id_rssi, id->id_len, |
208 | (rs->rs_rates[id->id_rateidx] & IEEE80211_RATE_VAL) / 2, |
209 | (rs->rs_rates[id->id_rateidx] & IEEE80211_RATE_VAL) * 5 % 10, |
210 | last_thr, ra->ra_rate_thresh[thridx][id->id_rateidx])); |
211 | } |
212 | |
213 | void |
214 | ieee80211_rssadapt_raise_rate(struct ieee80211com *ic, |
215 | struct ieee80211_rssadapt *ra, const struct ieee80211_rssdesc *id) |
216 | { |
217 | u_int16_t (*thrs)[IEEE80211_RATE_SIZE8], newthr, oldthr; |
218 | const struct ieee80211_node *ni = id->id_node; |
219 | const struct ieee80211_rateset *rs = &ni->ni_rates; |
220 | int i, rate, top; |
221 | #ifdef IEEE80211_DEBUG |
222 | int j; |
223 | #endif |
224 | |
225 | ra->ra_nok++; |
226 | |
227 | if (!ratecheck(&ra->ra_last_raise, &ra->ra_raise_interval)) |
228 | return; |
229 | |
230 | for (i = 0, top = IEEE80211_RSSADAPT_BKT0128; |
231 | i < IEEE80211_RSSADAPT_BKTS3; |
232 | i++, top <<= IEEE80211_RSSADAPT_BKTPOWER3) { |
233 | thrs = &ra->ra_rate_thresh[i]; |
234 | if (id->id_len <= top) |
235 | break; |
236 | } |
237 | |
238 | if (id->id_rateidx + 1 < rs->rs_nrates && |
239 | (*thrs)[id->id_rateidx + 1] > (*thrs)[id->id_rateidx]) { |
240 | rate = (rs->rs_rates[id->id_rateidx + 1] & IEEE80211_RATE_VAL0x7f); |
Value stored to 'rate' is never read | |
241 | |
242 | RSSADAPT_PRINTF(("%s: threshold[%d, %d.%d] decay %d ", |
243 | ic->ic_if.if_xname, IEEE80211_RSSADAPT_BKT0 << |
244 | (IEEE80211_RSSADAPT_BKTPOWER * i), |
245 | rate / 2, rate * 5 % 10, (*thrs)[id->id_rateidx + 1])); |
246 | oldthr = (*thrs)[id->id_rateidx + 1]; |
247 | if ((*thrs)[id->id_rateidx] == 0) |
248 | newthr = ra->ra_avg_rssi; |
249 | else |
250 | newthr = (*thrs)[id->id_rateidx]; |
251 | (*thrs)[id->id_rateidx + 1] = |
252 | interpolate(master_expavgctl.rc_decay, oldthr, newthr)((master_expavgctl.rc_decay_old * (oldthr) + (master_expavgctl .rc_decay_denom - master_expavgctl.rc_decay_old) * (newthr)) / master_expavgctl.rc_decay_denom); |
253 | |
254 | RSSADAPT_PRINTF(("-> %d\n", (*thrs)[id->id_rateidx + 1])); |
255 | } |
256 | |
257 | #ifdef IEEE80211_DEBUG |
258 | if (RSSADAPT_DO_PRINT()(0)) { |
259 | printf("%s: dst %s thresholds\n", ic->ic_ific_ac.ac_if.if_xname, |
260 | ether_sprintf((u_int8_t *)ni->ni_macaddr)); |
261 | for (i = 0; i < IEEE80211_RSSADAPT_BKTS3; i++) { |
262 | printf("%d-byte", IEEE80211_RSSADAPT_BKT0128 << |
263 | (IEEE80211_RSSADAPT_BKTPOWER3 * i)); |
264 | for (j = 0; j < rs->rs_nrates; j++) { |
265 | rate = (rs->rs_rates[j] & IEEE80211_RATE_VAL0x7f); |
266 | printf(", T[%d.%d] = %d", rate / 2, |
267 | rate * 5 % 10, ra->ra_rate_thresh[i][j]); |
268 | } |
269 | printf("\n"); |
270 | } |
271 | } |
272 | #endif /* IEEE80211_DEBUG */ |
273 | } |