1 /* $OpenBSD: ieee80211_ra.c,v 1.4 2021/10/11 09:01:06 stsp Exp $ */ 2 3 /* 4 * Copyright (c) 2021 Christian Ehrhardt <ehrhardt@genua.de> 5 * Copyright (c) 2016, 2021 Stefan Sperling <stsp@openbsd.org> 6 * Copyright (c) 2016 Theo Buehler <tb@openbsd.org> 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 #include <sys/param.h> 22 #include <sys/systm.h> 23 #include <sys/socket.h> 24 25 #include <net/if.h> 26 #include <net/if_media.h> 27 28 #include <netinet/in.h> 29 #include <netinet/if_ether.h> 30 31 #include <net80211/ieee80211_var.h> 32 #include <net80211/ieee80211_ra.h> 33 34 int ieee80211_ra_next_intra_rate(struct ieee80211_ra_node *, 35 struct ieee80211_node *); 36 const struct ieee80211_ht_rateset * ieee80211_ra_next_rateset( 37 struct ieee80211_ra_node *, struct ieee80211_node *); 38 int ieee80211_ra_best_mcs_in_rateset(struct ieee80211_ra_node *, 39 const struct ieee80211_ht_rateset *); 40 void ieee80211_ra_probe_next_rateset(struct ieee80211_ra_node *, 41 struct ieee80211_node *, const struct ieee80211_ht_rateset *); 42 int ieee80211_ra_next_mcs(struct ieee80211_ra_node *, 43 struct ieee80211_node *); 44 void ieee80211_ra_probe_done(struct ieee80211_ra_node *); 45 int ieee80211_ra_intra_mode_ra_finished( 46 struct ieee80211_ra_node *, struct ieee80211_node *); 47 void ieee80211_ra_trigger_next_rateset(struct ieee80211_ra_node *, 48 struct ieee80211_node *); 49 int ieee80211_ra_inter_mode_ra_finished( 50 struct ieee80211_ra_node *, struct ieee80211_node *); 51 int ieee80211_ra_best_rate(struct ieee80211_ra_node *, 52 struct ieee80211_node *); 53 void ieee80211_ra_probe_next_rate(struct ieee80211_ra_node *, 54 struct ieee80211_node *); 55 int ieee80211_ra_valid_tx_mcs(struct ieee80211com *, int); 56 uint32_t ieee80211_ra_valid_rates(struct ieee80211com *, 57 struct ieee80211_node *); 58 int ieee80211_ra_probe_valid(struct ieee80211_ra_goodput_stats *); 59 60 /* We use fixed point arithmetic with 64 bit integers. */ 61 #define RA_FP_SHIFT 21 62 #define RA_FP_INT(x) (x ## ULL << RA_FP_SHIFT) /* the integer x */ 63 #define RA_FP_1 RA_FP_INT(1) 64 65 /* Multiply two fixed point numbers. */ 66 #define RA_FP_MUL(a, b) \ 67 (((a) * (b)) >> RA_FP_SHIFT) 68 69 /* Divide two fixed point numbers. */ 70 #define RA_FP_DIV(a, b) \ 71 (b == 0 ? (uint64_t)-1 : (((a) << RA_FP_SHIFT) / (b))) 72 73 #define RA_DEBUG 74 #ifdef RA_DEBUG 75 #define DPRINTF(x) do { if (ra_debug > 0) printf x; } while (0) 76 #define DPRINTFN(n, x) do { if (ra_debug >= (n)) printf x; } while (0) 77 int ra_debug = 0; 78 #else 79 #define DPRINTF(x) do { ; } while (0) 80 #define DPRINTFN(n, x) do { ; } while (0) 81 #endif 82 83 #ifdef RA_DEBUG 84 void 85 ra_fixedp_split(uint32_t *i, uint32_t *f, uint64_t fp) 86 { 87 uint64_t tmp; 88 89 /* integer part */ 90 *i = (fp >> RA_FP_SHIFT); 91 92 /* fractional part */ 93 tmp = (fp & ((uint64_t)-1 >> (64 - RA_FP_SHIFT))); 94 tmp *= 100; 95 *f = (uint32_t)(tmp >> RA_FP_SHIFT); 96 } 97 98 char * 99 ra_fp_sprintf(uint64_t fp) 100 { 101 uint32_t i, f; 102 static char buf[64]; 103 int ret; 104 105 ra_fixedp_split(&i, &f, fp); 106 ret = snprintf(buf, sizeof(buf), "%u.%02u", i, f); 107 if (ret == -1 || ret >= sizeof(buf)) 108 return "ERR"; 109 110 return buf; 111 } 112 #endif /* RA_DEBUG */ 113 114 const struct ieee80211_ht_rateset * 115 ieee80211_ra_get_ht_rateset(int mcs, int chan40, int sgi) 116 { 117 const struct ieee80211_ht_rateset *rs; 118 int i; 119 120 for (i = 0; i < IEEE80211_HT_NUM_RATESETS; i++) { 121 rs = &ieee80211_std_ratesets_11n[i]; 122 if (chan40 == rs->chan40 && sgi == rs->sgi && 123 mcs >= rs->min_mcs && mcs <= rs->max_mcs) 124 return rs; 125 } 126 127 panic("MCS %d is not part of any rateset", mcs); 128 } 129 130 int 131 ieee80211_ra_use_ht_sgi(struct ieee80211_node *ni) 132 { 133 if ((ni->ni_chan->ic_flags & IEEE80211_CHAN_40MHZ) && 134 ieee80211_node_supports_ht_chan40(ni)) { 135 if (ni->ni_flags & IEEE80211_NODE_HT_SGI40) 136 return 1; 137 } else if (ni->ni_flags & IEEE80211_NODE_HT_SGI20) 138 return 1; 139 140 return 0; 141 } 142 143 /* 144 * Update goodput statistics. 145 */ 146 147 uint64_t 148 ieee80211_ra_get_txrate(int mcs, int chan40, int sgi) 149 { 150 const struct ieee80211_ht_rateset *rs; 151 uint64_t txrate; 152 153 rs = ieee80211_ra_get_ht_rateset(mcs, chan40, sgi); 154 txrate = rs->rates[mcs - rs->min_mcs]; 155 txrate <<= RA_FP_SHIFT; /* convert to fixed-point */ 156 txrate *= 500; /* convert to kbit/s */ 157 txrate /= 1000; /* convert to mbit/s */ 158 159 return txrate; 160 } 161 162 /* 163 * Rate selection. 164 */ 165 166 /* A rate's goodput has to be at least this much larger to be "better". */ 167 #define IEEE80211_RA_RATE_THRESHOLD (RA_FP_1 / 64) /* ~ 0.015 */ 168 169 int 170 ieee80211_ra_next_lower_intra_rate(struct ieee80211_ra_node *rn, 171 struct ieee80211_node *ni) 172 { 173 const struct ieee80211_ht_rateset *rs; 174 int i, next; 175 176 rs = ieee80211_ra_get_ht_rateset(ni->ni_txmcs, 177 ieee80211_node_supports_ht_chan40(ni), ieee80211_ra_use_ht_sgi(ni)); 178 if (ni->ni_txmcs == rs->min_mcs) 179 return rs->min_mcs; 180 181 next = ni->ni_txmcs; 182 for (i = rs->nrates - 1; i >= 0; i--) { 183 if ((rn->valid_rates & (1 << (i + rs->min_mcs))) == 0) 184 continue; 185 if (i + rs->min_mcs < ni->ni_txmcs) { 186 next = i + rs->min_mcs; 187 break; 188 } 189 } 190 191 return next; 192 } 193 194 int 195 ieee80211_ra_next_intra_rate(struct ieee80211_ra_node *rn, 196 struct ieee80211_node *ni) 197 { 198 const struct ieee80211_ht_rateset *rs; 199 int i, next; 200 201 rs = ieee80211_ra_get_ht_rateset(ni->ni_txmcs, 202 ieee80211_node_supports_ht_chan40(ni), ieee80211_ra_use_ht_sgi(ni)); 203 if (ni->ni_txmcs == rs->max_mcs) 204 return rs->max_mcs; 205 206 next = ni->ni_txmcs; 207 for (i = 0; i < rs->nrates; i++) { 208 if ((rn->valid_rates & (1 << (i + rs->min_mcs))) == 0) 209 continue; 210 if (i + rs->min_mcs > ni->ni_txmcs) { 211 next = i + rs->min_mcs; 212 break; 213 } 214 } 215 216 return next; 217 } 218 219 const struct ieee80211_ht_rateset * 220 ieee80211_ra_next_rateset(struct ieee80211_ra_node *rn, 221 struct ieee80211_node *ni) 222 { 223 const struct ieee80211_ht_rateset *rs, *rsnext; 224 int next; 225 int chan40 = ieee80211_node_supports_ht_chan40(ni); 226 int sgi = ieee80211_ra_use_ht_sgi(ni); 227 int mcs = ni->ni_txmcs; 228 229 rs = ieee80211_ra_get_ht_rateset(mcs, chan40, sgi); 230 if (rn->probing & IEEE80211_RA_PROBING_UP) { 231 if (rs->max_mcs == 7) { /* MCS 0-7 */ 232 if (chan40) 233 next = sgi ? IEEE80211_HT_RATESET_MIMO2_SGI40 : 234 IEEE80211_HT_RATESET_MIMO2_40; 235 else 236 next = sgi ? IEEE80211_HT_RATESET_MIMO2_SGI : 237 IEEE80211_HT_RATESET_MIMO2; 238 } else if (rs->max_mcs == 15) { /* MCS 8-15 */ 239 if (chan40) 240 next = sgi ? IEEE80211_HT_RATESET_MIMO3_SGI40 : 241 IEEE80211_HT_RATESET_MIMO3_40; 242 else 243 next = sgi ? IEEE80211_HT_RATESET_MIMO3_SGI : 244 IEEE80211_HT_RATESET_MIMO3; 245 } else if (rs->max_mcs == 23) { /* MCS 16-23 */ 246 if (chan40) 247 next = sgi ? IEEE80211_HT_RATESET_MIMO4_SGI40 : 248 IEEE80211_HT_RATESET_MIMO4_40; 249 else 250 next = sgi ? IEEE80211_HT_RATESET_MIMO4_SGI : 251 IEEE80211_HT_RATESET_MIMO4; 252 } else /* MCS 24-31 */ 253 return NULL; 254 } else if (rn->probing & IEEE80211_RA_PROBING_DOWN) { 255 if (rs->min_mcs == 24) { /* MCS 24-31 */ 256 if (chan40) 257 next = sgi ? IEEE80211_HT_RATESET_MIMO3_SGI40 : 258 IEEE80211_HT_RATESET_MIMO3_40; 259 else 260 next = sgi ? IEEE80211_HT_RATESET_MIMO3_SGI : 261 IEEE80211_HT_RATESET_MIMO3; 262 } else if (rs->min_mcs == 16) { /* MCS 16-23 */ 263 if (chan40) 264 next = sgi ? IEEE80211_HT_RATESET_MIMO2_SGI40 : 265 IEEE80211_HT_RATESET_MIMO2_40; 266 else 267 next = sgi ? IEEE80211_HT_RATESET_MIMO2_SGI : 268 IEEE80211_HT_RATESET_MIMO2; 269 } else if (rs->min_mcs == 8) { /* MCS 8-15 */ 270 if (chan40) 271 next = sgi ? IEEE80211_HT_RATESET_SISO_SGI40 : 272 IEEE80211_HT_RATESET_SISO_40; 273 else 274 next = sgi ? IEEE80211_HT_RATESET_SISO_SGI : 275 IEEE80211_HT_RATESET_SISO; 276 } else /* MCS 0-7 */ 277 return NULL; 278 } else 279 panic("%s: invalid probing mode %d", __func__, rn->probing); 280 281 rsnext = &ieee80211_std_ratesets_11n[next]; 282 if ((rsnext->mcs_mask & rn->valid_rates) == 0) 283 return NULL; 284 285 return rsnext; 286 } 287 288 int 289 ieee80211_ra_best_mcs_in_rateset(struct ieee80211_ra_node *rn, 290 const struct ieee80211_ht_rateset *rs) 291 { 292 uint64_t gmax = 0; 293 int i, best_mcs = rs->min_mcs; 294 295 for (i = 0; i < rs->nrates; i++) { 296 int mcs = rs->min_mcs + i; 297 struct ieee80211_ra_goodput_stats *g = &rn->g[mcs]; 298 if (((1 << mcs) & rn->valid_rates) == 0) 299 continue; 300 if (g->measured > gmax + IEEE80211_RA_RATE_THRESHOLD) { 301 gmax = g->measured; 302 best_mcs = mcs; 303 } 304 } 305 306 return best_mcs; 307 } 308 309 void 310 ieee80211_ra_probe_next_rateset(struct ieee80211_ra_node *rn, 311 struct ieee80211_node *ni, const struct ieee80211_ht_rateset *rsnext) 312 { 313 const struct ieee80211_ht_rateset *rs; 314 struct ieee80211_ra_goodput_stats *g; 315 int best_mcs, i; 316 317 /* Find most recently measured best MCS from the current rateset. */ 318 rs = ieee80211_ra_get_ht_rateset(ni->ni_txmcs, 319 ieee80211_node_supports_ht_chan40(ni), ieee80211_ra_use_ht_sgi(ni)); 320 best_mcs = ieee80211_ra_best_mcs_in_rateset(rn, rs); 321 322 /* Switch to the next rateset. */ 323 ni->ni_txmcs = rsnext->min_mcs; 324 if ((rn->valid_rates & (1 << rsnext->min_mcs)) == 0) 325 ni->ni_txmcs = ieee80211_ra_next_intra_rate(rn, ni); 326 327 /* Select the lowest rate from the next rateset with loss-free 328 * goodput close to the current best measurement. */ 329 g = &rn->g[best_mcs]; 330 for (i = 0; i < rsnext->nrates; i++) { 331 int mcs = rsnext->min_mcs + i; 332 uint64_t txrate = rsnext->rates[i]; 333 334 if ((rn->valid_rates & (1 << mcs)) == 0) 335 continue; 336 337 txrate = txrate * 500; /* convert to kbit/s */ 338 txrate <<= RA_FP_SHIFT; /* convert to fixed-point */ 339 txrate /= 1000; /* convert to mbit/s */ 340 341 if (txrate > g->measured + IEEE80211_RA_RATE_THRESHOLD) { 342 ni->ni_txmcs = mcs; 343 break; 344 } 345 } 346 /* If all rates are lower the maximum rate is the closest match. */ 347 if (i == rsnext->nrates) 348 ni->ni_txmcs = rsnext->max_mcs; 349 350 /* Add rates from the next rateset as candidates. */ 351 rn->candidate_rates |= (1 << ni->ni_txmcs); 352 if (rn->probing & IEEE80211_RA_PROBING_UP) { 353 rn->candidate_rates |= 354 (1 << ieee80211_ra_next_intra_rate(rn, ni)); 355 } else if (rn->probing & IEEE80211_RA_PROBING_DOWN) { 356 rn->candidate_rates |= 357 (1 << ieee80211_ra_next_lower_intra_rate(rn, ni)); 358 } else 359 panic("%s: invalid probing mode %d", __func__, rn->probing); 360 } 361 362 int 363 ieee80211_ra_next_mcs(struct ieee80211_ra_node *rn, 364 struct ieee80211_node *ni) 365 { 366 int next; 367 368 if (rn->probing & IEEE80211_RA_PROBING_DOWN) 369 next = ieee80211_ra_next_lower_intra_rate(rn, ni); 370 else if (rn->probing & IEEE80211_RA_PROBING_UP) 371 next = ieee80211_ra_next_intra_rate(rn, ni); 372 else 373 panic("%s: invalid probing mode %d", __func__, rn->probing); 374 375 return next; 376 } 377 378 void 379 ieee80211_ra_probe_clear(struct ieee80211_ra_node *rn, 380 struct ieee80211_node *ni) 381 { 382 struct ieee80211_ra_goodput_stats *g = &rn->g[ni->ni_txmcs]; 383 384 g->nprobe_pkts = 0; 385 g->nprobe_fail = 0; 386 } 387 388 void 389 ieee80211_ra_probe_done(struct ieee80211_ra_node *rn) 390 { 391 rn->probing = IEEE80211_RA_NOT_PROBING; 392 rn->probed_rates = 0; 393 rn->valid_probes = 0; 394 rn->candidate_rates = 0; 395 } 396 397 int 398 ieee80211_ra_intra_mode_ra_finished(struct ieee80211_ra_node *rn, 399 struct ieee80211_node *ni) 400 { 401 const struct ieee80211_ht_rateset *rs; 402 struct ieee80211_ra_goodput_stats *g = &rn->g[ni->ni_txmcs]; 403 int next_mcs, best_mcs; 404 uint64_t next_rate; 405 int chan40 = ieee80211_node_supports_ht_chan40(ni); 406 int sgi = ieee80211_ra_use_ht_sgi(ni); 407 408 rn->probed_rates = (rn->probed_rates | (1 << ni->ni_txmcs)); 409 410 /* Check if the min/max MCS in this rateset has been probed. */ 411 rs = ieee80211_ra_get_ht_rateset(ni->ni_txmcs, chan40, sgi); 412 if (rn->probing & IEEE80211_RA_PROBING_DOWN) { 413 if (ni->ni_txmcs == rs->min_mcs || 414 rn->probed_rates & (1 << rs->min_mcs)) { 415 ieee80211_ra_trigger_next_rateset(rn, ni); 416 return 1; 417 } 418 } else if (rn->probing & IEEE80211_RA_PROBING_UP) { 419 if (ni->ni_txmcs == rs->max_mcs || 420 rn->probed_rates & (1 << rs->max_mcs)) { 421 ieee80211_ra_trigger_next_rateset(rn, ni); 422 return 1; 423 } 424 } 425 426 /* 427 * Check if the measured goodput is loss-free and better than the 428 * loss-free goodput of the candidate rate. 429 */ 430 next_mcs = ieee80211_ra_next_mcs(rn, ni); 431 if (next_mcs == ni->ni_txmcs) { 432 ieee80211_ra_trigger_next_rateset(rn, ni); 433 return 1; 434 } 435 next_rate = ieee80211_ra_get_txrate(next_mcs, chan40, sgi); 436 if (g->loss == 0 && 437 g->measured >= next_rate + IEEE80211_RA_RATE_THRESHOLD) { 438 ieee80211_ra_trigger_next_rateset(rn, ni); 439 return 1; 440 } 441 442 /* Check if we had a better measurement at a previously probed MCS. */ 443 best_mcs = ieee80211_ra_best_mcs_in_rateset(rn, rs); 444 if (best_mcs != ni->ni_txmcs && (rn->probed_rates & (1 << best_mcs))) { 445 if ((rn->probing & IEEE80211_RA_PROBING_UP) && 446 best_mcs < ni->ni_txmcs) { 447 ieee80211_ra_trigger_next_rateset(rn, ni); 448 return 1; 449 } 450 if ((rn->probing & IEEE80211_RA_PROBING_DOWN) && 451 best_mcs > ni->ni_txmcs) { 452 ieee80211_ra_trigger_next_rateset(rn, ni); 453 return 1; 454 } 455 } 456 457 /* Check if all rates in the set of candidate rates have been probed. */ 458 if ((rn->candidate_rates & rn->probed_rates) == rn->candidate_rates) { 459 /* Remain in the current rateset until above checks trigger. */ 460 rn->probing &= ~IEEE80211_RA_PROBING_INTER; 461 return 1; 462 } 463 464 return 0; 465 } 466 467 void 468 ieee80211_ra_trigger_next_rateset(struct ieee80211_ra_node *rn, 469 struct ieee80211_node *ni) 470 { 471 const struct ieee80211_ht_rateset *rsnext; 472 473 rsnext = ieee80211_ra_next_rateset(rn, ni); 474 if (rsnext) { 475 ieee80211_ra_probe_next_rateset(rn, ni, rsnext); 476 rn->probing |= IEEE80211_RA_PROBING_INTER; 477 } else 478 rn->probing &= ~IEEE80211_RA_PROBING_INTER; 479 } 480 481 int 482 ieee80211_ra_inter_mode_ra_finished(struct ieee80211_ra_node *rn, 483 struct ieee80211_node *ni) 484 { 485 return ((rn->probing & IEEE80211_RA_PROBING_INTER) == 0); 486 } 487 488 int 489 ieee80211_ra_best_rate(struct ieee80211_ra_node *rn, 490 struct ieee80211_node *ni) 491 { 492 int i, best = rn->best_mcs; 493 uint64_t gmax = rn->g[rn->best_mcs].measured; 494 495 for (i = 0; i < nitems(rn->g); i++) { 496 struct ieee80211_ra_goodput_stats *g = &rn->g[i]; 497 if (((1 << i) & rn->valid_rates) == 0) 498 continue; 499 if (g->measured > gmax + IEEE80211_RA_RATE_THRESHOLD) { 500 gmax = g->measured; 501 best = i; 502 } 503 } 504 505 #ifdef RA_DEBUG 506 if (rn->best_mcs != best) { 507 DPRINTF(("MCS %d is best; MCS{cur|avg|loss}:", best)); 508 for (i = 0; i < IEEE80211_HT_RATESET_NUM_MCS; i++) { 509 struct ieee80211_ra_goodput_stats *g = &rn->g[i]; 510 if ((rn->valid_rates & (1 << i)) == 0) 511 continue; 512 DPRINTF((" %d{%s|", i, ra_fp_sprintf(g->measured))); 513 DPRINTF(("%s|", ra_fp_sprintf(g->average))); 514 DPRINTF(("%s%%}", ra_fp_sprintf(g->loss))); 515 } 516 DPRINTF(("\n")); 517 } 518 #endif 519 return best; 520 } 521 522 void 523 ieee80211_ra_probe_next_rate(struct ieee80211_ra_node *rn, 524 struct ieee80211_node *ni) 525 { 526 /* Select the next rate to probe. */ 527 rn->probed_rates |= (1 << ni->ni_txmcs); 528 ni->ni_txmcs = ieee80211_ra_next_mcs(rn, ni); 529 } 530 531 int 532 ieee80211_ra_valid_tx_mcs(struct ieee80211com *ic, int mcs) 533 { 534 uint32_t ntxstreams = 1; 535 static const int max_mcs[] = { 7, 15, 23, 31 }; 536 537 if ((ic->ic_tx_mcs_set & IEEE80211_TX_RX_MCS_NOT_EQUAL) == 0) 538 return isset(ic->ic_sup_mcs, mcs); 539 540 ntxstreams += ((ic->ic_tx_mcs_set & IEEE80211_TX_SPATIAL_STREAMS) >> 2); 541 if (ntxstreams < 1 || ntxstreams > 4) 542 panic("invalid number of Tx streams: %u", ntxstreams); 543 return (mcs <= max_mcs[ntxstreams - 1] && isset(ic->ic_sup_mcs, mcs)); 544 } 545 546 uint32_t 547 ieee80211_ra_valid_rates(struct ieee80211com *ic, struct ieee80211_node *ni) 548 { 549 uint32_t valid_mcs = 0; 550 int i; 551 552 for (i = 0; i < IEEE80211_HT_RATESET_NUM_MCS; i++) { 553 if (!isset(ni->ni_rxmcs, i)) 554 continue; 555 if (!ieee80211_ra_valid_tx_mcs(ic, i)) 556 continue; 557 valid_mcs |= (1 << i); 558 } 559 560 return valid_mcs; 561 } 562 563 int 564 ieee80211_ra_probe_valid(struct ieee80211_ra_goodput_stats *g) 565 { 566 /* 128 packets make up a valid probe in any case. */ 567 if (g->nprobe_pkts >= 128) 568 return 1; 569 570 /* 8 packets with > 75% loss make a valid probe, too. */ 571 if (g->nprobe_pkts >= 8 && 572 g->nprobe_pkts - g->nprobe_fail < g->nprobe_pkts / 4) 573 return 1; 574 575 return 0; 576 } 577 578 void 579 ieee80211_ra_add_stats_ht(struct ieee80211_ra_node *rn, 580 struct ieee80211com *ic, struct ieee80211_node *ni, 581 int mcs, uint32_t total, uint32_t fail) 582 { 583 static const uint64_t alpha = RA_FP_1 / 8; /* 1/8 = 0.125 */ 584 static const uint64_t beta = RA_FP_1 / 4; /* 1/4 = 0.25 */ 585 int s; 586 struct ieee80211_ra_goodput_stats *g; 587 uint64_t sfer, rate, delta; 588 589 /* 590 * Ignore invalid values. These values may come from hardware 591 * so asserting valid values via panic is not appropriate. 592 */ 593 if (mcs < 0 || mcs >= IEEE80211_HT_RATESET_NUM_MCS) 594 return; 595 if (total == 0) 596 return; 597 598 s = splnet(); 599 600 g = &rn->g[mcs]; 601 g->nprobe_pkts += total; 602 g->nprobe_fail += fail; 603 604 if (!ieee80211_ra_probe_valid(g)) { 605 splx(s); 606 return; 607 } 608 rn->valid_probes |= 1U << mcs; 609 610 if (g->nprobe_fail > g->nprobe_pkts) { 611 DPRINTF(("%s fail %u > pkts %u\n", 612 ether_sprintf(ni->ni_macaddr), 613 g->nprobe_fail, g->nprobe_pkts)); 614 g->nprobe_fail = g->nprobe_pkts; 615 } 616 617 sfer = g->nprobe_fail << RA_FP_SHIFT; 618 sfer /= g->nprobe_pkts; 619 g->nprobe_fail = 0; 620 g->nprobe_pkts = 0; 621 622 rate = ieee80211_ra_get_txrate(mcs, 623 ieee80211_node_supports_ht_chan40(ni), 624 ieee80211_ra_use_ht_sgi(ni)); 625 626 g->loss = sfer * 100; 627 g->measured = RA_FP_MUL(RA_FP_1 - sfer, rate); 628 g->average = RA_FP_MUL(RA_FP_1 - alpha, g->average); 629 g->average += RA_FP_MUL(alpha, g->measured); 630 631 g->stddeviation = RA_FP_MUL(RA_FP_1 - beta, g->stddeviation); 632 if (g->average > g->measured) 633 delta = g->average - g->measured; 634 else 635 delta = g->measured - g->average; 636 g->stddeviation += RA_FP_MUL(beta, delta); 637 638 splx(s); 639 } 640 641 void 642 ieee80211_ra_choose(struct ieee80211_ra_node *rn, struct ieee80211com *ic, 643 struct ieee80211_node *ni) 644 { 645 struct ieee80211_ra_goodput_stats *g = &rn->g[ni->ni_txmcs]; 646 int s; 647 int chan40 = ieee80211_node_supports_ht_chan40(ni); 648 int sgi = ieee80211_ra_use_ht_sgi(ni); 649 const struct ieee80211_ht_rateset *rs, *rsnext; 650 651 s = splnet(); 652 653 if (rn->valid_rates == 0) 654 rn->valid_rates = ieee80211_ra_valid_rates(ic, ni); 655 656 if (rn->probing) { 657 /* Probe another rate or settle at the best rate. */ 658 if (!(rn->valid_probes & (1UL << ni->ni_txmcs))) { 659 splx(s); 660 return; 661 } 662 ieee80211_ra_probe_clear(rn, ni); 663 if (!ieee80211_ra_intra_mode_ra_finished(rn, ni)) { 664 ieee80211_ra_probe_next_rate(rn, ni); 665 DPRINTFN(3, ("probing MCS %d\n", ni->ni_txmcs)); 666 } else if (ieee80211_ra_inter_mode_ra_finished(rn, ni)) { 667 rn->best_mcs = ieee80211_ra_best_rate(rn, ni); 668 ni->ni_txmcs = rn->best_mcs; 669 ieee80211_ra_probe_done(rn); 670 } 671 672 splx(s); 673 return; 674 } else { 675 rn->valid_probes = 0; 676 } 677 678 rs = ieee80211_ra_get_ht_rateset(ni->ni_txmcs, chan40, sgi); 679 if ((g->measured >> RA_FP_SHIFT) == 0LL || 680 (g->average >= 3 * g->stddeviation && 681 g->measured < g->average - 3 * g->stddeviation)) { 682 /* Channel becomes bad. Probe downwards. */ 683 rn->probing = IEEE80211_RA_PROBING_DOWN; 684 rn->probed_rates = 0; 685 if (ni->ni_txmcs == rs->min_mcs) { 686 rsnext = ieee80211_ra_next_rateset(rn, ni); 687 if (rsnext) { 688 ieee80211_ra_probe_next_rateset(rn, ni, 689 rsnext); 690 } else { 691 /* Cannot probe further down. */ 692 rn->probing = IEEE80211_RA_NOT_PROBING; 693 } 694 } else { 695 ni->ni_txmcs = ieee80211_ra_next_mcs(rn, ni); 696 rn->candidate_rates = (1 << ni->ni_txmcs); 697 } 698 } else if (g->loss < 2 * RA_FP_1 || 699 g->measured > g->average + 3 * g->stddeviation) { 700 /* Channel becomes good. */ 701 rn->probing = IEEE80211_RA_PROBING_UP; 702 rn->probed_rates = 0; 703 if (ni->ni_txmcs == rs->max_mcs) { 704 rsnext = ieee80211_ra_next_rateset(rn, ni); 705 if (rsnext) { 706 ieee80211_ra_probe_next_rateset(rn, ni, 707 rsnext); 708 } else { 709 /* Cannot probe further up. */ 710 rn->probing = IEEE80211_RA_NOT_PROBING; 711 } 712 } else { 713 ni->ni_txmcs = ieee80211_ra_next_mcs(rn, ni); 714 rn->candidate_rates = (1 << ni->ni_txmcs); 715 } 716 } else { 717 /* Remain at current rate. */ 718 rn->probing = IEEE80211_RA_NOT_PROBING; 719 rn->probed_rates = 0; 720 rn->candidate_rates = 0; 721 } 722 723 splx(s); 724 725 if (rn->probing) { 726 if (rn->probing & IEEE80211_RA_PROBING_UP) 727 DPRINTFN(2, ("channel becomes good; probe up\n")); 728 else 729 DPRINTFN(2, ("channel becomes bad; probe down\n")); 730 731 DPRINTFN(3, ("measured: %s Mbit/s\n", 732 ra_fp_sprintf(g->measured))); 733 DPRINTFN(3, ("average: %s Mbit/s\n", 734 ra_fp_sprintf(g->average))); 735 DPRINTFN(3, ("stddeviation: %s\n", 736 ra_fp_sprintf(g->stddeviation))); 737 DPRINTFN(3, ("loss: %s%%\n", ra_fp_sprintf(g->loss))); 738 } 739 } 740 741 void 742 ieee80211_ra_node_init(struct ieee80211_ra_node *rn) 743 { 744 memset(rn, 0, sizeof(*rn)); 745 } 746