1 /*- 2 * Copyright (c) 2005 John Bicket 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13 * redistribution must be conditioned upon including a substantially 14 * similar Disclaimer requirement for further binary redistribution. 15 * 3. Neither the names of the above-listed copyright holders nor the names 16 * of any contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * Alternatively, this software may be distributed under the terms of the 20 * GNU General Public License ("GPL") version 2 as published by the Free 21 * Software Foundation. 22 * 23 * NO WARRANTY 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 28 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 29 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 32 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 34 * THE POSSIBILITY OF SUCH DAMAGES. 35 */ 36 37 #include <sys/cdefs.h> 38 __FBSDID("$FreeBSD$"); 39 40 /* 41 * John Bicket's SampleRate control algorithm. 42 */ 43 #include "opt_inet.h" 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/sysctl.h> 48 #include <sys/module.h> 49 #include <sys/kernel.h> 50 #include <sys/lock.h> 51 #include <sys/mutex.h> 52 #include <sys/errno.h> 53 54 #include <machine/bus.h> 55 #include <machine/resource.h> 56 #include <sys/bus.h> 57 58 #include <sys/socket.h> 59 60 #include <net/if.h> 61 #include <net/if_media.h> 62 #include <net/if_arp.h> 63 #include <net/ethernet.h> /* XXX for ether_sprintf */ 64 65 #include <net80211/ieee80211_var.h> 66 67 #include <net/bpf.h> 68 69 #ifdef INET 70 #include <netinet/in.h> 71 #include <netinet/if_ether.h> 72 #endif 73 74 #include <dev/ath/if_athvar.h> 75 #include <dev/ath/ath_rate/sample/sample.h> 76 #include <contrib/dev/ath/ah_desc.h> 77 78 #define SAMPLE_DEBUG 79 #ifdef SAMPLE_DEBUG 80 enum { 81 ATH_DEBUG_RATE = 0x00000010 /* rate control */ 82 }; 83 #define DPRINTF(sc, _fmt, ...) do { \ 84 if (sc->sc_debug & ATH_DEBUG_RATE) \ 85 printf(_fmt, __VA_ARGS__); \ 86 } while (0) 87 #else 88 #define DPRINTF(sc, _fmt, ...) 89 #endif 90 91 /* 92 * This file is an implementation of the SampleRate algorithm 93 * in "Bit-rate Selection in Wireless Networks" 94 * (http://www.pdos.lcs.mit.edu/papers/jbicket-ms.ps) 95 * 96 * SampleRate chooses the bit-rate it predicts will provide the most 97 * throughput based on estimates of the expected per-packet 98 * transmission time for each bit-rate. SampleRate periodically sends 99 * packets at bit-rates other than the current one to estimate when 100 * another bit-rate will provide better performance. SampleRate 101 * switches to another bit-rate when its estimated per-packet 102 * transmission time becomes smaller than the current bit-rate's. 103 * SampleRate reduces the number of bit-rates it must sample by 104 * eliminating those that could not perform better than the one 105 * currently being used. SampleRate also stops probing at a bit-rate 106 * if it experiences several successive losses. 107 * 108 * The difference between the algorithm in the thesis and the one in this 109 * file is that the one in this file uses a ewma instead of a window. 110 * 111 * Also, this implementation tracks the average transmission time for 112 * a few different packet sizes independently for each link. 113 */ 114 115 #define STALE_FAILURE_TIMEOUT_MS 10000 116 #define MIN_SWITCH_MS 1000 117 118 static void ath_rate_ctl_reset(struct ath_softc *, struct ieee80211_node *); 119 120 static __inline int 121 size_to_bin(int size) 122 { 123 int x = 0; 124 for (x = 0; x < NUM_PACKET_SIZE_BINS; x++) { 125 if (size <= packet_size_bins[x]) { 126 return x; 127 } 128 } 129 return NUM_PACKET_SIZE_BINS-1; 130 } 131 static __inline int 132 bin_to_size(int index) { 133 return packet_size_bins[index]; 134 } 135 136 static __inline int 137 rate_to_ndx(struct sample_node *sn, int rate) { 138 int x = 0; 139 for (x = 0; x < sn->num_rates; x++) { 140 if (sn->rates[x].rate == rate) { 141 return x; 142 } 143 } 144 return -1; 145 } 146 147 void 148 ath_rate_node_init(struct ath_softc *sc, struct ath_node *an) 149 { 150 DPRINTF(sc, "%s:\n", __func__); 151 /* NB: assumed to be zero'd by caller */ 152 } 153 154 void 155 ath_rate_node_cleanup(struct ath_softc *sc, struct ath_node *an) 156 { 157 DPRINTF(sc, "%s:\n", __func__); 158 } 159 160 161 /* 162 * returns the ndx with the lowest average_tx_time, 163 * or -1 if all the average_tx_times are 0. 164 */ 165 static __inline int best_rate_ndx(struct sample_node *sn, int size_bin, 166 int require_acked_before) 167 { 168 int x = 0; 169 int best_rate_ndx = 0; 170 int best_rate_tt = 0; 171 for (x = 0; x < sn->num_rates; x++) { 172 int tt = sn->stats[size_bin][x].average_tx_time; 173 if (tt <= 0 || (require_acked_before && 174 !sn->stats[size_bin][x].packets_acked)) { 175 continue; 176 } 177 178 /* 9 megabits never works better than 12 */ 179 if (sn->rates[x].rate == 18) 180 continue; 181 182 /* don't use a bit-rate that has been failing */ 183 if (sn->stats[size_bin][x].successive_failures > 3) 184 continue; 185 186 if (!best_rate_tt || best_rate_tt > tt) { 187 best_rate_tt = tt; 188 best_rate_ndx = x; 189 } 190 } 191 return (best_rate_tt) ? best_rate_ndx : -1; 192 } 193 194 /* 195 * pick a good "random" bit-rate to sample other than the current one 196 */ 197 static __inline int 198 pick_sample_ndx(struct sample_node *sn, int size_bin) 199 { 200 int x = 0; 201 int current_ndx = 0; 202 unsigned current_tt = 0; 203 204 current_ndx = sn->current_rate[size_bin]; 205 if (current_ndx < 0) { 206 /* no successes yet, send at the lowest bit-rate */ 207 return 0; 208 } 209 210 current_tt = sn->stats[size_bin][current_ndx].average_tx_time; 211 212 for (x = 0; x < sn->num_rates; x++) { 213 int ndx = (sn->last_sample_ndx[size_bin]+1+x) % sn->num_rates; 214 215 /* don't sample the current bit-rate */ 216 if (ndx == current_ndx) 217 continue; 218 219 /* this bit-rate is always worse than the current one */ 220 if (sn->stats[size_bin][ndx].perfect_tx_time > current_tt) 221 continue; 222 223 /* rarely sample bit-rates that fail a lot */ 224 if (ticks - sn->stats[size_bin][ndx].last_tx < ((hz * STALE_FAILURE_TIMEOUT_MS)/1000) && 225 sn->stats[size_bin][ndx].successive_failures > 3) 226 continue; 227 228 /* don't sample more than 2 indexes higher 229 * for rates higher than 11 megabits 230 */ 231 if (sn->rates[ndx].rate > 22 && ndx > current_ndx + 2) 232 continue; 233 234 /* 9 megabits never works better than 12 */ 235 if (sn->rates[ndx].rate == 18) 236 continue; 237 238 /* if we're using 11 megabits, only sample up to 12 megabits 239 */ 240 if (sn->rates[current_ndx].rate == 22 && ndx > current_ndx + 1) 241 continue; 242 243 sn->last_sample_ndx[size_bin] = ndx; 244 return ndx; 245 } 246 return current_ndx; 247 } 248 249 void 250 ath_rate_findrate(struct ath_softc *sc, struct ath_node *an, 251 int shortPreamble, size_t frameLen, 252 u_int8_t *rix, int *try0, u_int8_t *txrate) 253 { 254 struct sample_node *sn = ATH_NODE_SAMPLE(an); 255 struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc); 256 struct ieee80211com *ic = &sc->sc_ic; 257 int ndx, size_bin, mrr, best_ndx, change_rates; 258 unsigned average_tx_time; 259 260 mrr = sc->sc_mrretry && !(ic->ic_flags & IEEE80211_F_USEPROT); 261 size_bin = size_to_bin(frameLen); 262 best_ndx = best_rate_ndx(sn, size_bin, !mrr); 263 264 if (best_ndx >= 0) { 265 average_tx_time = sn->stats[size_bin][best_ndx].average_tx_time; 266 } else { 267 average_tx_time = 0; 268 } 269 270 if (sn->static_rate_ndx != -1) { 271 ndx = sn->static_rate_ndx; 272 *try0 = ATH_TXMAXTRY; 273 } else { 274 *try0 = mrr ? 2 : ATH_TXMAXTRY; 275 276 if (sn->sample_tt[size_bin] < average_tx_time * (sn->packets_since_sample[size_bin]*ssc->ath_sample_rate/100)) { 277 /* 278 * we want to limit the time measuring the performance 279 * of other bit-rates to ath_sample_rate% of the 280 * total transmission time. 281 */ 282 ndx = pick_sample_ndx(sn, size_bin); 283 if (ndx != sn->current_rate[size_bin]) { 284 sn->current_sample_ndx[size_bin] = ndx; 285 } else { 286 sn->current_sample_ndx[size_bin] = -1; 287 } 288 sn->packets_since_sample[size_bin] = 0; 289 290 } else { 291 change_rates = 0; 292 if (!sn->packets_sent[size_bin] || best_ndx == -1) { 293 /* no packet has been sent successfully yet */ 294 for (ndx = sn->num_rates-1; ndx > 0; ndx--) { 295 /* 296 * pick the highest rate <= 36 Mbps 297 * that hasn't failed. 298 */ 299 if (sn->rates[ndx].rate <= 72 && 300 sn->stats[size_bin][ndx].successive_failures == 0) { 301 break; 302 } 303 } 304 change_rates = 1; 305 best_ndx = ndx; 306 } else if (sn->packets_sent[size_bin] < 20) { 307 /* let the bit-rate switch quickly during the first few packets */ 308 change_rates = 1; 309 } else if (ticks - ((hz*MIN_SWITCH_MS)/1000) > sn->ticks_since_switch[size_bin]) { 310 /* 2 seconds have gone by */ 311 change_rates = 1; 312 } else if (average_tx_time * 2 < sn->stats[size_bin][sn->current_rate[size_bin]].average_tx_time) { 313 /* the current bit-rate is twice as slow as the best one */ 314 change_rates = 1; 315 } 316 317 sn->packets_since_sample[size_bin]++; 318 319 if (change_rates) { 320 if (best_ndx != sn->current_rate[size_bin]) { 321 DPRINTF(sc, "%s: %s size %d switch rate %d (%d/%d) -> %d (%d/%d) after %d packets mrr %d\n", 322 __func__, 323 ether_sprintf(an->an_node.ni_macaddr), 324 packet_size_bins[size_bin], 325 sn->rates[sn->current_rate[size_bin]].rate, 326 sn->stats[size_bin][sn->current_rate[size_bin]].average_tx_time, 327 sn->stats[size_bin][sn->current_rate[size_bin]].perfect_tx_time, 328 sn->rates[best_ndx].rate, 329 sn->stats[size_bin][best_ndx].average_tx_time, 330 sn->stats[size_bin][best_ndx].perfect_tx_time, 331 sn->packets_since_switch[size_bin], 332 mrr); 333 } 334 sn->packets_since_switch[size_bin] = 0; 335 sn->current_rate[size_bin] = best_ndx; 336 sn->ticks_since_switch[size_bin] = ticks; 337 } 338 ndx = sn->current_rate[size_bin]; 339 sn->packets_since_switch[size_bin]++; 340 if (size_bin == 0) { 341 /* 342 * set the visible txrate for this node 343 * to the rate of small packets 344 */ 345 an->an_node.ni_txrate = ndx; 346 } 347 } 348 } 349 350 KASSERT(ndx >= 0 && ndx < sn->num_rates, ("ndx is %d", ndx)); 351 352 *rix = sn->rates[ndx].rix; 353 if (shortPreamble) { 354 *txrate = sn->rates[ndx].shortPreambleRateCode; 355 } else { 356 *txrate = sn->rates[ndx].rateCode; 357 } 358 sn->packets_sent[size_bin]++; 359 } 360 361 void 362 ath_rate_setupxtxdesc(struct ath_softc *sc, struct ath_node *an, 363 struct ath_desc *ds, int shortPreamble, u_int8_t rix) 364 { 365 struct sample_node *sn = ATH_NODE_SAMPLE(an); 366 int rateCode = -1; 367 int frame_size = 0; 368 int size_bin = 0; 369 int ndx = 0; 370 371 size_bin = size_to_bin(frame_size); // TODO: it's correct that frame_size alway 0 ? 372 ndx = sn->current_rate[size_bin]; /* retry at the current bit-rate */ 373 374 if (!sn->stats[size_bin][ndx].packets_acked) { 375 ndx = 0; /* use the lowest bit-rate */ 376 } 377 378 if (shortPreamble) { 379 rateCode = sn->rates[ndx].shortPreambleRateCode; 380 } else { 381 rateCode = sn->rates[ndx].rateCode; 382 } 383 ath_hal_setupxtxdesc(sc->sc_ah, ds 384 , rateCode, 3 /* series 1 */ 385 , sn->rates[0].rateCode, 3 /* series 2 */ 386 , 0, 0 /* series 3 */ 387 ); 388 } 389 390 static void 391 update_stats(struct ath_softc *sc, struct ath_node *an, 392 int frame_size, 393 int ndx0, int tries0, 394 int ndx1, int tries1, 395 int ndx2, int tries2, 396 int ndx3, int tries3, 397 int short_tries, int tries, int status) 398 { 399 struct sample_node *sn = ATH_NODE_SAMPLE(an); 400 struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc); 401 int tt = 0; 402 int tries_so_far = 0; 403 int size_bin = 0; 404 int size = 0; 405 int rate = 0; 406 407 size_bin = size_to_bin(frame_size); 408 size = bin_to_size(size_bin); 409 rate = sn->rates[ndx0].rate; 410 411 tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx0].rix, 412 short_tries-1, 413 MIN(tries0, tries) - 1); 414 tries_so_far += tries0; 415 if (tries1 && tries0 < tries) { 416 tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx1].rix, 417 short_tries-1, 418 MIN(tries1 + tries_so_far, tries) - tries_so_far - 1); 419 } 420 tries_so_far += tries1; 421 422 if (tries2 && tries0 + tries1 < tries) { 423 tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx2].rix, 424 short_tries-1, 425 MIN(tries2 + tries_so_far, tries) - tries_so_far - 1); 426 } 427 428 tries_so_far += tries2; 429 430 if (tries3 && tries0 + tries1 + tries2 < tries) { 431 tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx3].rix, 432 short_tries-1, 433 MIN(tries3 + tries_so_far, tries) - tries_so_far - 1); 434 } 435 if (sn->stats[size_bin][ndx0].total_packets < (100 / (100 - ssc->ath_smoothing_rate))) { 436 /* just average the first few packets */ 437 int avg_tx = sn->stats[size_bin][ndx0].average_tx_time; 438 int packets = sn->stats[size_bin][ndx0].total_packets; 439 sn->stats[size_bin][ndx0].average_tx_time = (tt+(avg_tx*packets))/(packets+1); 440 } else { 441 /* use a ewma */ 442 sn->stats[size_bin][ndx0].average_tx_time = 443 ((sn->stats[size_bin][ndx0].average_tx_time * ssc->ath_smoothing_rate) + 444 (tt * (100 - ssc->ath_smoothing_rate))) / 100; 445 } 446 447 if (status) { 448 int y; 449 sn->stats[size_bin][ndx0].successive_failures++; 450 for (y = size_bin+1; y < NUM_PACKET_SIZE_BINS; y++) { 451 /* also say larger packets failed since we 452 * assume if a small packet fails at a lower 453 * bit-rate then a larger one will also. 454 */ 455 sn->stats[y][ndx0].successive_failures++; 456 sn->stats[y][ndx0].last_tx = ticks; 457 sn->stats[y][ndx0].tries += tries; 458 sn->stats[y][ndx0].total_packets++; 459 } 460 } else { 461 sn->stats[size_bin][ndx0].packets_acked++; 462 sn->stats[size_bin][ndx0].successive_failures = 0; 463 } 464 sn->stats[size_bin][ndx0].tries += tries; 465 sn->stats[size_bin][ndx0].last_tx = ticks; 466 sn->stats[size_bin][ndx0].total_packets++; 467 468 469 if (ndx0 == sn->current_sample_ndx[size_bin]) { 470 DPRINTF(sc, "%s: %s size %d sample rate %d tries (%d/%d) tt %d avg_tt (%d/%d) status %d\n", 471 __func__, ether_sprintf(an->an_node.ni_macaddr), 472 size, rate, short_tries, tries, tt, 473 sn->stats[size_bin][ndx0].average_tx_time, 474 sn->stats[size_bin][ndx0].perfect_tx_time, 475 status); 476 sn->sample_tt[size_bin] = tt; 477 sn->current_sample_ndx[size_bin] = -1; 478 } 479 } 480 481 void 482 ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an, 483 const struct ath_desc *ds, const struct ath_desc *ds0) 484 { 485 struct ieee80211com *ic = &sc->sc_ic; 486 struct sample_node *sn = ATH_NODE_SAMPLE(an); 487 const struct ar5212_desc *ads = (const struct ar5212_desc *)&ds->ds_ctl0; 488 int final_rate, short_tries, long_tries, frame_size; 489 int ndx = -1; 490 int mrr; 491 492 final_rate = sc->sc_hwmap[ds->ds_txstat.ts_rate &~ HAL_TXSTAT_ALTRATE].ieeerate; 493 short_tries = ds->ds_txstat.ts_shortretry + 1; 494 long_tries = ds->ds_txstat.ts_longretry + 1; 495 frame_size = ds0->ds_ctl0 & 0x0fff; /* low-order 12 bits of ds_ctl0 */ 496 if (frame_size == 0) /* NB: should not happen */ 497 frame_size = 1500; 498 499 if (sn->num_rates <= 0) { 500 DPRINTF(sc, "%s: %s size %d status %d rate/try %d/%d " 501 "no rates yet\n", 502 __func__, ether_sprintf(an->an_node.ni_macaddr), 503 bin_to_size(size_to_bin(frame_size)), 504 ds->ds_txstat.ts_status, 505 short_tries, long_tries); 506 return; 507 } 508 509 mrr = sc->sc_mrretry && !(ic->ic_flags & IEEE80211_F_USEPROT); 510 511 if (sc->sc_mrretry && ds->ds_txstat.ts_status) { 512 /* this packet failed */ 513 DPRINTF(sc, "%s: %s size %d rate/try %d/%d %d/%d %d/%d %d/%d status %s retries (%d/%d)\n", 514 __func__, 515 ether_sprintf(an->an_node.ni_macaddr), 516 bin_to_size(size_to_bin(frame_size)), 517 sc->sc_hwmap[ads->xmit_rate0].ieeerate, 518 ads->xmit_tries0, 519 sc->sc_hwmap[ads->xmit_rate1].ieeerate, 520 ads->xmit_tries1, 521 sc->sc_hwmap[ads->xmit_rate2].ieeerate, 522 ads->xmit_tries2, 523 sc->sc_hwmap[ads->xmit_rate3].ieeerate, 524 ads->xmit_tries3, 525 ds->ds_txstat.ts_status ? "FAIL" : "OK", 526 short_tries, 527 long_tries); 528 } 529 530 if (!mrr || !(ds->ds_txstat.ts_rate & HAL_TXSTAT_ALTRATE)) { 531 /* only one rate was used */ 532 ndx = rate_to_ndx(sn, final_rate); 533 DPRINTF(sc, "%s: %s size %d status %d rate/try %d/%d/%d\n", 534 __func__, ether_sprintf(an->an_node.ni_macaddr), 535 bin_to_size(size_to_bin(frame_size)), 536 ds->ds_txstat.ts_status, 537 ndx, short_tries, long_tries); 538 if (ndx >= 0 && ndx < sn->num_rates) { 539 update_stats(sc, an, frame_size, 540 ndx, long_tries, 541 0, 0, 542 0, 0, 543 0, 0, 544 short_tries, long_tries, ds->ds_txstat.ts_status); 545 } 546 } else { 547 int rate0, tries0, ndx0; 548 int rate1, tries1, ndx1; 549 int rate2, tries2, ndx2; 550 int rate3, tries3, ndx3; 551 int finalTSIdx = ads->final_ts_index; 552 553 /* 554 * Process intermediate rates that failed. 555 */ 556 557 rate0 = sc->sc_hwmap[ads->xmit_rate0].ieeerate; 558 tries0 = ads->xmit_tries0; 559 ndx0 = rate_to_ndx(sn, rate0); 560 561 rate1 = sc->sc_hwmap[ads->xmit_rate1].ieeerate; 562 tries1 = ads->xmit_tries1; 563 ndx1 = rate_to_ndx(sn, rate1); 564 565 rate2 = sc->sc_hwmap[ads->xmit_rate2].ieeerate; 566 tries2 = ads->xmit_tries2; 567 ndx2 = rate_to_ndx(sn, rate2); 568 569 rate3 = sc->sc_hwmap[ads->xmit_rate3].ieeerate; 570 tries3 = ads->xmit_tries3; 571 ndx3 = rate_to_ndx(sn, rate3); 572 573 #if 1 574 DPRINTF(sc, "%s: %s size %d finaltsidx %d tries %d status %d rate/try %d/%d %d/%d %d/%d %d/%d\n", 575 __func__, ether_sprintf(an->an_node.ni_macaddr), 576 bin_to_size(size_to_bin(frame_size)), 577 finalTSIdx, 578 long_tries, 579 ds->ds_txstat.ts_status, 580 rate0, tries0, 581 rate1, tries1, 582 rate2, tries2, 583 rate3, tries3); 584 #endif 585 586 if (tries0) { 587 update_stats(sc, an, frame_size, 588 ndx0, tries0, 589 ndx1, tries1, 590 ndx2, tries2, 591 ndx3, tries3, 592 short_tries, ds->ds_txstat.ts_longretry + 1, 593 long_tries > tries0); 594 } 595 596 if (tries1 && finalTSIdx > 0) { 597 update_stats(sc, an, frame_size, 598 ndx1, tries1, 599 ndx2, tries2, 600 ndx3, tries3, 601 0, 0, 602 short_tries, ds->ds_txstat.ts_longretry + 1 - tries0, 603 ds->ds_txstat.ts_status); 604 } 605 606 if (tries2 && finalTSIdx > 1) { 607 update_stats(sc, an, frame_size, 608 ndx2, tries2, 609 ndx3, tries3, 610 0, 0, 611 0, 0, 612 short_tries, ds->ds_txstat.ts_longretry + 1 - tries0 - tries1, 613 ds->ds_txstat.ts_status); 614 } 615 616 if (tries3 && finalTSIdx > 2) { 617 update_stats(sc, an, frame_size, 618 ndx3, tries3, 619 0, 0, 620 0, 0, 621 0, 0, 622 short_tries, ds->ds_txstat.ts_longretry + 1 - tries0 - tries1 - tries2, 623 ds->ds_txstat.ts_status); 624 } 625 } 626 } 627 628 void 629 ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew) 630 { 631 DPRINTF(sc, "%s: %s isnew %d\n", __func__, 632 ether_sprintf(an->an_node.ni_macaddr), isnew); 633 if (isnew) 634 ath_rate_ctl_reset(sc, &an->an_node); 635 } 636 637 /* 638 * Initialize the tables for a node. 639 */ 640 static void 641 ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni) 642 { 643 #define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL) 644 struct ieee80211com *ic = &sc->sc_ic; 645 struct ath_node *an = ATH_NODE(ni); 646 struct sample_node *sn = ATH_NODE_SAMPLE(an); 647 const HAL_RATE_TABLE *rt = sc->sc_currates; 648 int x, y, srate; 649 650 KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); 651 sn->static_rate_ndx = -1; 652 if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) { 653 /* 654 * A fixed rate is to be used; ic_fixed_rate is an 655 * index into the supported rate set. Convert this 656 * to the index into the negotiated rate set for 657 * the node. 658 */ 659 const struct ieee80211_rateset *rs = 660 &ic->ic_sup_rates[ic->ic_curmode]; 661 int r = rs->rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; 662 /* NB: the rate set is assumed sorted */ 663 srate = ni->ni_rates.rs_nrates - 1; 664 for (; srate >= 0 && RATE(srate) != r; srate--) 665 ; 666 KASSERT(srate >= 0, 667 ("fixed rate %d not in rate set", ic->ic_fixed_rate)); 668 sn->static_rate_ndx = srate; 669 } 670 671 DPRINTF(sc, "%s: %s size 1600 rate/tt", __func__, ether_sprintf(ni->ni_macaddr)); 672 673 sn->num_rates = ni->ni_rates.rs_nrates; 674 for (x = 0; x < ni->ni_rates.rs_nrates; x++) { 675 sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL; 676 sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate]; 677 if (sn->rates[x].rix == 0xff) { 678 DPRINTF(sc, "%s: ignore bogus rix at %d\n", 679 __func__, x); 680 continue; 681 } 682 sn->rates[x].rateCode = rt->info[sn->rates[x].rix].rateCode; 683 sn->rates[x].shortPreambleRateCode = 684 rt->info[sn->rates[x].rix].rateCode | 685 rt->info[sn->rates[x].rix].shortPreamble; 686 687 DPRINTF(sc, " %d/%d", sn->rates[x].rate, 688 calc_usecs_unicast_packet(sc, 1600, sn->rates[x].rix, 689 0,0)); 690 } 691 DPRINTF(sc, "%s\n", ""); 692 693 /* set the visible bit-rate to the lowest one available */ 694 ni->ni_txrate = 0; 695 sn->num_rates = ni->ni_rates.rs_nrates; 696 697 for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) { 698 int size = bin_to_size(y); 699 int ndx = 0; 700 sn->packets_sent[y] = 0; 701 sn->current_sample_ndx[y] = -1; 702 sn->last_sample_ndx[y] = 0; 703 704 for (x = 0; x < ni->ni_rates.rs_nrates; x++) { 705 sn->stats[y][x].successive_failures = 0; 706 sn->stats[y][x].tries = 0; 707 sn->stats[y][x].total_packets = 0; 708 sn->stats[y][x].packets_acked = 0; 709 sn->stats[y][x].last_tx = 0; 710 711 sn->stats[y][x].perfect_tx_time = 712 calc_usecs_unicast_packet(sc, size, 713 sn->rates[x].rix, 714 0, 0); 715 sn->stats[y][x].average_tx_time = sn->stats[y][x].perfect_tx_time; 716 } 717 718 /* set the initial rate */ 719 for (ndx = sn->num_rates-1; ndx > 0; ndx--) { 720 if (sn->rates[ndx].rate <= 72) { 721 break; 722 } 723 } 724 sn->current_rate[y] = ndx; 725 } 726 727 DPRINTF(sc, "%s: %s %d rates %d%sMbps (%dus)- %d%sMbps (%dus)\n", 728 __func__, ether_sprintf(ni->ni_macaddr), 729 sn->num_rates, 730 sn->rates[0].rate/2, sn->rates[0].rate % 0x1 ? ".5" : "", 731 sn->stats[1][0].perfect_tx_time, 732 sn->rates[sn->num_rates-1].rate/2, 733 sn->rates[sn->num_rates-1].rate % 0x1 ? ".5" : "", 734 sn->stats[1][sn->num_rates-1].perfect_tx_time 735 ); 736 737 if (sn->static_rate_ndx != -1) 738 ni->ni_txrate = sn->static_rate_ndx; 739 else 740 ni->ni_txrate = sn->current_rate[0]; 741 #undef RATE 742 } 743 744 static void 745 rate_cb(void *arg, struct ieee80211_node *ni) 746 { 747 struct ath_softc *sc = arg; 748 749 ath_rate_newassoc(sc, ATH_NODE(ni), 1); 750 } 751 752 /* 753 * Reset the rate control state for each 802.11 state transition. 754 */ 755 void 756 ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state) 757 { 758 struct ieee80211com *ic = &sc->sc_ic; 759 760 if (state == IEEE80211_S_RUN) { 761 if (ic->ic_opmode != IEEE80211_M_STA) { 762 /* 763 * Sync rates for associated stations and neighbors. 764 */ 765 ieee80211_iterate_nodes(&ic->ic_sta, rate_cb, sc); 766 } 767 ath_rate_newassoc(sc, ATH_NODE(ic->ic_bss), 1); 768 } 769 } 770 771 static void 772 ath_rate_sysctlattach(struct ath_softc *sc, struct sample_softc *osc) 773 { 774 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev); 775 struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev); 776 777 /* XXX bounds check [0..100] */ 778 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 779 "smoothing_rate", CTLFLAG_RW, &osc->ath_smoothing_rate, 0, 780 "rate control: retry threshold to credit rate raise (%%)"); 781 /* XXX bounds check [2..100] */ 782 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 783 "sample_rate", CTLFLAG_RW, &osc->ath_sample_rate,0, 784 "rate control: # good periods before raising rate"); 785 } 786 787 struct ath_ratectrl * 788 ath_rate_attach(struct ath_softc *sc) 789 { 790 struct sample_softc *osc; 791 792 DPRINTF(sc, "%s:\n", __func__); 793 osc = malloc(sizeof(struct sample_softc), M_DEVBUF, M_NOWAIT|M_ZERO); 794 if (osc == NULL) 795 return NULL; 796 osc->arc.arc_space = sizeof(struct sample_node); 797 osc->ath_smoothing_rate = 95; /* ewma percentage (out of 100) */ 798 osc->ath_sample_rate = 10; /* send a different bit-rate 1/X packets */ 799 ath_rate_sysctlattach(sc, osc); 800 return &osc->arc; 801 } 802 803 void 804 ath_rate_detach(struct ath_ratectrl *arc) 805 { 806 struct sample_softc *osc = (struct sample_softc *) arc; 807 808 free(osc, M_DEVBUF); 809 } 810 811 /* 812 * Module glue. 813 */ 814 static int 815 sample_modevent(module_t mod, int type, void *unused) 816 { 817 switch (type) { 818 case MOD_LOAD: 819 if (bootverbose) 820 printf("ath_rate: version 1.2 <SampleRate bit-rate selection algorithm>\n"); 821 return 0; 822 case MOD_UNLOAD: 823 return 0; 824 } 825 return EINVAL; 826 } 827 828 static moduledata_t sample_mod = { 829 "ath_rate", 830 sample_modevent, 831 0 832 }; 833 DECLARE_MODULE(ath_rate, sample_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); 834 MODULE_VERSION(ath_rate, 1); 835 MODULE_DEPEND(ath_rate, ath_hal, 1, 1, 1); /* Atheros HAL */ 836 MODULE_DEPEND(ath_rate, wlan, 1, 1, 1); 837