382{ 383 struct sample_node *sn = ATH_NODE_SAMPLE(an); 384 int rateCode = -1; 385 int frame_size, size_bin, best_ndx, ndx; 386 387 frame_size = ds->ds_ctl0 & 0x0fff; /* low-order 12 bits of ds_ctl0 */ 388 KASSERT(frame_size != 0, ("no frame size")); 389 size_bin = size_to_bin(frame_size); 390 best_ndx = best_rate_ndx(sn, size_bin, 0); 391 392 if (best_ndx == -1 || !sn->stats[size_bin][best_ndx].packets_acked) { 393 /* 394 * no packet has succeeded, so also try at the 395 * lowest bitate. 396 */ 397 ndx = 0; 398 } else { 399 /* 400 * we're trying a different bit-rate, and it could be lossy, 401 * so if it fails try at the best bit-rate. 402 */ 403 ndx = best_ndx; 404 } 405 KASSERT(0 <= ndx && ndx < IEEE80211_RATE_MAXSIZE, 406 ("invalid ndx %d", ndx)); 407 if (shortPreamble) { 408 rateCode = sn->rates[ndx].shortPreambleRateCode; 409 } else { 410 rateCode = sn->rates[ndx].rateCode; 411 } 412 ath_hal_setupxtxdesc(sc->sc_ah, ds 413 , rateCode, 3 /* series 1 */ 414 , sn->rates[0].rateCode, 3 /* series 2 */ 415 , 0, 0 /* series 3 */ 416 ); 417} 418 419static void 420update_stats(struct ath_softc *sc, struct ath_node *an, 421 int frame_size, 422 int ndx0, int tries0, 423 int ndx1, int tries1, 424 int ndx2, int tries2, 425 int ndx3, int tries3, 426 int short_tries, int tries, int status) 427{ 428 struct sample_node *sn = ATH_NODE_SAMPLE(an); 429 struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc); 430 int tt = 0; 431 int tries_so_far = 0; 432 int size_bin = 0; 433 int size = 0; 434 int rate = 0; 435 436 size_bin = size_to_bin(frame_size); 437 size = bin_to_size(size_bin); 438 rate = sn->rates[ndx0].rate; 439 440 tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx0].rix, 441 short_tries-1, 442 MIN(tries0, tries) - 1); 443 tries_so_far += tries0; 444 if (tries1 && tries0 < tries) { 445 tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx1].rix, 446 short_tries-1, 447 MIN(tries1 + tries_so_far, tries) - tries_so_far - 1); 448 } 449 tries_so_far += tries1; 450 451 if (tries2 && tries0 + tries1 < tries) { 452 tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx2].rix, 453 short_tries-1, 454 MIN(tries2 + tries_so_far, tries) - tries_so_far - 1); 455 } 456 457 tries_so_far += tries2; 458 459 if (tries3 && tries0 + tries1 + tries2 < tries) { 460 tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx3].rix, 461 short_tries-1, 462 MIN(tries3 + tries_so_far, tries) - tries_so_far - 1); 463 } 464#ifdef SAMPLE_DEBUG 465 if (short_tries + tries > 3 || status) { 466 DPRINTF(sc, "%s: %s size %d rate %d ndx %d tries (%d/%d) tries0 %d tt %d avg_tt %d perfect_tt %d status %d\n", 467 __func__, ether_sprintf(an->an_node.ni_macaddr), 468 size, 469 rate, ndx0, short_tries, tries, tries0, tt, 470 sn->stats[size_bin][ndx0].average_tx_time, 471 sn->stats[size_bin][ndx0].perfect_tx_time, 472 status); 473 } 474#endif /* SAMPLE_DEBUG */ 475 if (sn->stats[size_bin][ndx0].total_packets < (100 / (100 - ssc->ath_smoothing_rate))) { 476 /* just average the first few packets */ 477 int avg_tx = sn->stats[size_bin][ndx0].average_tx_time; 478 int packets = sn->stats[size_bin][ndx0].total_packets; 479 sn->stats[size_bin][ndx0].average_tx_time = (tt+(avg_tx*packets))/(packets+1); 480 } else { 481 /* use a ewma */ 482 sn->stats[size_bin][ndx0].average_tx_time = 483 ((sn->stats[size_bin][ndx0].average_tx_time * ssc->ath_smoothing_rate) + 484 (tt * (100 - ssc->ath_smoothing_rate))) / 100; 485 } 486 487 if (status) { 488 /* 489 * this packet failed - count this as a failure 490 * for larger packets also, since we assume 491 * if a small packet fails at a lower bit-rate 492 * then a larger one will also. 493 */ 494 int y; 495 for (y = size_bin; y < NUM_PACKET_SIZE_BINS; y++) { 496 sn->stats[y][ndx0].successive_failures++; 497 sn->stats[y][ndx0].last_tx = ticks; 498 } 499 } else { 500 sn->stats[size_bin][ndx0].packets_acked++; 501 sn->stats[size_bin][ndx0].successive_failures = 0; 502 } 503 sn->stats[size_bin][ndx0].tries += tries; 504 sn->stats[size_bin][ndx0].last_tx = ticks; 505 sn->stats[size_bin][ndx0].total_packets++; 506 507 508 if (ndx0 == sn->current_sample_ndx[size_bin]) { 509 DPRINTF(sc, "%s: %s size %d sample rate %d tries (%d/%d) tt %d avg_tt (%d/%d) status %d\n", 510 __func__, ether_sprintf(an->an_node.ni_macaddr), 511 size, rate, short_tries, tries, tt, 512 sn->stats[size_bin][ndx0].average_tx_time, 513 sn->stats[size_bin][ndx0].perfect_tx_time, 514 status); 515 sn->sample_tt[size_bin] = tt; 516 sn->current_sample_ndx[size_bin] = -1; 517 } 518} 519 520void 521ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an, 522 const struct ath_desc *ds, const struct ath_desc *ds0) 523{ 524 struct sample_node *sn = ATH_NODE_SAMPLE(an); 525 const struct ar5212_desc *ads = (const struct ar5212_desc *)&ds->ds_ctl0; 526 int final_rate, short_tries, long_tries, frame_size; 527 int ndx = -1; 528 529 final_rate = sc->sc_hwmap[ds->ds_txstat.ts_rate &~ HAL_TXSTAT_ALTRATE].ieeerate; 530 short_tries = ds->ds_txstat.ts_shortretry + 1; 531 long_tries = ds->ds_txstat.ts_longretry + 1; 532 frame_size = ds0->ds_ctl0 & 0x0fff; /* low-order 12 bits of ds_ctl0 */ 533 if (frame_size == 0) /* NB: should not happen */ 534 frame_size = 1500; 535 536 if (sn->num_rates <= 0) { 537 DPRINTF(sc, "%s: %s size %d status %d rate/try %d/%d " 538 "no rates yet\n", 539 __func__, ether_sprintf(an->an_node.ni_macaddr), 540 bin_to_size(size_to_bin(frame_size)), 541 ds->ds_txstat.ts_status, 542 short_tries, long_tries); 543 return; 544 } 545 546 if (sc->sc_mrretry && ds->ds_txstat.ts_status) { 547 /* this packet failed */ 548 DPRINTF(sc, "%s: %s size %d rate/try %d/%d %d/%d %d/%d %d/%d status %s retries (%d/%d)\n", 549 __func__, 550 ether_sprintf(an->an_node.ni_macaddr), 551 bin_to_size(size_to_bin(frame_size)), 552 sc->sc_hwmap[ads->xmit_rate0].ieeerate, 553 ads->xmit_tries0, 554 sc->sc_hwmap[ads->xmit_rate1].ieeerate, 555 ads->xmit_tries1, 556 sc->sc_hwmap[ads->xmit_rate2].ieeerate, 557 ads->xmit_tries2, 558 sc->sc_hwmap[ads->xmit_rate3].ieeerate, 559 ads->xmit_tries3, 560 ds->ds_txstat.ts_status ? "FAIL" : "OK", 561 short_tries, 562 long_tries); 563 } 564 565 if (!(ds->ds_txstat.ts_rate & HAL_TXSTAT_ALTRATE)) { 566 /* only one rate was used */ 567 ndx = rate_to_ndx(sn, final_rate); 568 DPRINTF(sc, "%s: %s size %d status %d rate/try %d/%d/%d\n", 569 __func__, ether_sprintf(an->an_node.ni_macaddr), 570 bin_to_size(size_to_bin(frame_size)), 571 ds->ds_txstat.ts_status, 572 ndx, short_tries, long_tries); 573 if (ndx >= 0 && ndx < sn->num_rates) { 574 update_stats(sc, an, frame_size, 575 ndx, long_tries, 576 0, 0, 577 0, 0, 578 0, 0, 579 short_tries, long_tries, ds->ds_txstat.ts_status); 580 } 581 } else { 582 int rate0, tries0, ndx0; 583 int rate1, tries1, ndx1; 584 int rate2, tries2, ndx2; 585 int rate3, tries3, ndx3; 586 int finalTSIdx = ads->final_ts_index; 587 588 /* 589 * Process intermediate rates that failed. 590 */ 591 592 rate0 = sc->sc_hwmap[ads->xmit_rate0].ieeerate; 593 tries0 = ads->xmit_tries0; 594 ndx0 = rate_to_ndx(sn, rate0); 595 596 rate1 = sc->sc_hwmap[ads->xmit_rate1].ieeerate; 597 tries1 = ads->xmit_tries1; 598 ndx1 = rate_to_ndx(sn, rate1); 599 600 rate2 = sc->sc_hwmap[ads->xmit_rate2].ieeerate; 601 tries2 = ads->xmit_tries2; 602 ndx2 = rate_to_ndx(sn, rate2); 603 604 rate3 = sc->sc_hwmap[ads->xmit_rate3].ieeerate; 605 tries3 = ads->xmit_tries3; 606 ndx3 = rate_to_ndx(sn, rate3); 607 608#if 1 609 DPRINTF(sc, "%s: %s size %d finaltsidx %d tries %d status %d rate/try %d/%d %d/%d %d/%d %d/%d\n", 610 __func__, ether_sprintf(an->an_node.ni_macaddr), 611 bin_to_size(size_to_bin(frame_size)), 612 finalTSIdx, 613 long_tries, 614 ds->ds_txstat.ts_status, 615 rate0, tries0, 616 rate1, tries1, 617 rate2, tries2, 618 rate3, tries3); 619#endif 620 621 if (tries0) { 622 update_stats(sc, an, frame_size, 623 ndx0, tries0, 624 ndx1, tries1, 625 ndx2, tries2, 626 ndx3, tries3, 627 short_tries, ds->ds_txstat.ts_longretry + 1, 628 ds->ds_txstat.ts_status); 629 } 630 631 if (tries1 && finalTSIdx > 0) { 632 update_stats(sc, an, frame_size, 633 ndx1, tries1, 634 ndx2, tries2, 635 ndx3, tries3, 636 0, 0, 637 short_tries, ds->ds_txstat.ts_longretry + 1 - tries0, 638 ds->ds_txstat.ts_status); 639 } 640 641 if (tries2 && finalTSIdx > 1) { 642 update_stats(sc, an, frame_size, 643 ndx2, tries2, 644 ndx3, tries3, 645 0, 0, 646 0, 0, 647 short_tries, ds->ds_txstat.ts_longretry + 1 - tries0 - tries1, 648 ds->ds_txstat.ts_status); 649 } 650 651 if (tries3 && finalTSIdx > 2) { 652 update_stats(sc, an, frame_size, 653 ndx3, tries3, 654 0, 0, 655 0, 0, 656 0, 0, 657 short_tries, ds->ds_txstat.ts_longretry + 1 - tries0 - tries1 - tries2, 658 ds->ds_txstat.ts_status); 659 } 660 } 661} 662 663void 664ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew) 665{ 666 DPRINTF(sc, "%s: %s isnew %d\n", __func__, 667 ether_sprintf(an->an_node.ni_macaddr), isnew); 668 if (isnew) 669 ath_rate_ctl_reset(sc, &an->an_node); 670} 671 672/* 673 * Initialize the tables for a node. 674 */ 675static void 676ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni) 677{ 678#define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL) 679 struct ieee80211com *ic = &sc->sc_ic; 680 struct ath_node *an = ATH_NODE(ni); 681 struct sample_node *sn = ATH_NODE_SAMPLE(an); 682 const HAL_RATE_TABLE *rt = sc->sc_currates; 683 int x, y, srate; 684 685 KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); 686 sn->static_rate_ndx = -1; 687 if (ic->ic_fixed_rate != -1) { 688 /* 689 * A fixed rate is to be used; ic_fixed_rate is an 690 * index into the supported rate set. Convert this 691 * to the index into the negotiated rate set for 692 * the node. We know the rate is there because the 693 * rate set is checked when the station associates. 694 */ 695 const struct ieee80211_rateset *rs = 696 &ic->ic_sup_rates[ic->ic_curmode]; 697 int r = rs->rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; 698 /* NB: the rate set is assumed sorted */ 699 srate = ni->ni_rates.rs_nrates - 1; 700 for (; srate >= 0 && RATE(srate) != r; srate--) 701 ; 702 KASSERT(srate >= 0, 703 ("fixed rate %d not in rate set", ic->ic_fixed_rate)); 704 sn->static_rate_ndx = srate; 705 } 706 707 DPRINTF(sc, "%s: %s size 1600 rate/tt", __func__, ether_sprintf(ni->ni_macaddr)); 708 709 sn->num_rates = ni->ni_rates.rs_nrates; 710 for (x = 0; x < ni->ni_rates.rs_nrates; x++) { 711 sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL; 712 sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate]; 713 sn->rates[x].rateCode = rt->info[sn->rates[x].rix].rateCode; 714 sn->rates[x].shortPreambleRateCode = 715 rt->info[sn->rates[x].rix].rateCode | 716 rt->info[sn->rates[x].rix].shortPreamble; 717 718 DPRINTF(sc, " %d/%d", sn->rates[x].rate, 719 calc_usecs_unicast_packet(sc, 1600, sn->rates[x].rix, 720 0,0)); 721 } 722 DPRINTF(sc, "%s\n", ""); 723 724 /* set the visible bit-rate to the lowest one available */ 725 ni->ni_txrate = 0; 726 sn->num_rates = ni->ni_rates.rs_nrates; 727 728 for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) { 729 int size = bin_to_size(y); 730 sn->packets_sent[y] = 0; 731 sn->current_sample_ndx[y] = -1; 732 sn->last_sample_ndx[y] = 0; 733 734 for (x = 0; x < ni->ni_rates.rs_nrates; x++) { 735 sn->stats[y][x].successive_failures = 0; 736 sn->stats[y][x].tries = 0; 737 sn->stats[y][x].total_packets = 0; 738 sn->stats[y][x].packets_acked = 0; 739 sn->stats[y][x].last_tx = 0; 740 741 sn->stats[y][x].perfect_tx_time = 742 calc_usecs_unicast_packet(sc, size, 743 sn->rates[x].rix, 744 0, 0); 745 sn->stats[y][x].average_tx_time = sn->stats[y][x].perfect_tx_time; 746 } 747 } 748#undef RATE 749} 750 751static void 752rate_cb(void *arg, struct ieee80211_node *ni) 753{ 754 struct ath_softc *sc = arg; 755 756 ath_rate_newassoc(sc, ATH_NODE(ni), 1); 757} 758 759/* 760 * Reset the rate control state for each 802.11 state transition. 761 */ 762void 763ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state) 764{ 765 struct ieee80211com *ic = &sc->sc_ic; 766 767 if (state == IEEE80211_S_RUN) { 768 if (ic->ic_opmode != IEEE80211_M_STA) { 769 /* 770 * Sync rates for associated stations and neighbors. 771 */ 772 ieee80211_iterate_nodes(&ic->ic_sta, rate_cb, sc); 773 } 774 ath_rate_newassoc(sc, ATH_NODE(ic->ic_bss), 1); 775 } 776} 777 778static void 779ath_rate_sysctlattach(struct ath_softc *sc, struct sample_softc *osc) 780{ 781 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev); 782 struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev); 783 784 /* XXX bounds check [0..100] */ 785 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 786 "smoothing_rate", CTLFLAG_RW, &osc->ath_smoothing_rate, 0, 787 "rate control: retry threshold to credit rate raise (%%)"); 788 /* XXX bounds check [2..100] */ 789 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 790 "sample_rate", CTLFLAG_RW, &osc->ath_sample_rate,0, 791 "rate control: # good periods before raising rate"); 792} 793 794struct ath_ratectrl * 795ath_rate_attach(struct ath_softc *sc) 796{ 797 struct sample_softc *osc; 798 799 DPRINTF(sc, "%s:\n", __func__); 800 osc = malloc(sizeof(struct sample_softc), M_DEVBUF, M_NOWAIT|M_ZERO); 801 if (osc == NULL) 802 return NULL; 803 osc->arc.arc_space = sizeof(struct sample_node); 804 osc->ath_smoothing_rate = 95; /* ewma percentage (out of 100) */ 805 osc->ath_sample_rate = 10; /* send a different bit-rate 1/X packets */ 806 ath_rate_sysctlattach(sc, osc); 807 return &osc->arc; 808} 809 810void 811ath_rate_detach(struct ath_ratectrl *arc) 812{ 813 struct sample_softc *osc = (struct sample_softc *) arc; 814 815 free(osc, M_DEVBUF); 816} 817 818/* 819 * Module glue. 820 */ 821static int 822sample_modevent(module_t mod, int type, void *unused) 823{ 824 switch (type) { 825 case MOD_LOAD: 826 if (bootverbose) 827 printf("ath_rate: version 1.2 <SampleRate bit-rate selection algorithm>\n"); 828 return 0; 829 case MOD_UNLOAD: 830 return 0; 831 } 832 return EINVAL; 833} 834 835static moduledata_t sample_mod = { 836 "ath_rate", 837 sample_modevent, 838 0 839}; 840DECLARE_MODULE(ath_rate, sample_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); 841MODULE_VERSION(ath_rate, 1); 842MODULE_DEPEND(ath_rate, ath_hal, 1, 1, 1); /* Atheros HAL */ 843MODULE_DEPEND(ath_rate, wlan, 1, 1, 1);
|