| 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 | } |