| 549 | | ath_fill_sample_table(struct minstrel_node *sn) |
|---|
| 550 | | { |
|---|
| 551 | | unsigned int num_sample_rates = (sn->num_rates - 1); |
|---|
| 552 | | /* newIndex varies as 0 .. (num_rates - 2) |
|---|
| 553 | | * The highest index rate is the slowest and is ignored */ |
|---|
| 554 | | unsigned int i, column_index, newIndex; |
|---|
| 555 | | u_int8_t random_bytes[8]; |
|---|
| 556 | | |
|---|
| 557 | | /* This should be unnecessary if we are assuming storage is provided |
|---|
| 558 | | * as zeroed */ |
|---|
| 559 | | memset(sn->rs_sampleTable, 0, sizeof(sn->rs_sampleTable)); |
|---|
| 560 | | |
|---|
| 561 | | sn->rs_sampleColumn = 0; |
|---|
| 562 | | sn->rs_sampleIndex = 0; |
|---|
| 563 | | |
|---|
| 564 | | /* Seed value to random number generator, which determines when we |
|---|
| 565 | | * send a sample packet at some non-optimal rate |
|---|
| 566 | | * FIXME: randomise? */ |
|---|
| 567 | | sn->random_n = 1; |
|---|
| 568 | | sn->a = 1664525; |
|---|
| 569 | | sn->b = 1013904223; |
|---|
| 570 | | |
|---|
| 571 | | if (sn->num_rates > 1) { |
|---|
| 572 | | for (column_index = 0; column_index < MINSTREL_COLUMNS; column_index++) { |
|---|
| 573 | | for (i = 0; i < num_sample_rates; i++) { |
|---|
| 574 | | get_random_bytes(random_bytes, 8); |
|---|
| 575 | | newIndex = (i + random_bytes[i & 7]) % num_sample_rates; |
|---|
| 576 | | |
|---|
| 577 | | while (sn->rs_sampleTable[newIndex][column_index] != 0) |
|---|
| 578 | | newIndex = (newIndex + 1) % num_sample_rates; |
|---|
| 579 | | |
|---|
| 580 | | sn->rs_sampleTable[newIndex][column_index] = i + 1; |
|---|
| 581 | | } |
|---|
| | 564 | ath_fill_sample_table(struct ath_softc *sc, struct minstrel_node *sn) |
|---|
| | 565 | { |
|---|
| | 566 | unsigned int num_sample_rates = (sn->num_rates - 1); |
|---|
| | 567 | /* newIndex varies as 0 .. (num_rates - 2) |
|---|
| | 568 | * The highest index rate is the slowest and is ignored */ |
|---|
| | 569 | unsigned int i, column_index, newIndex; |
|---|
| | 570 | u_int8_t random_bytes[8]; |
|---|
| | 571 | |
|---|
| | 572 | /* This should be unnecessary if we are assuming storage is provided |
|---|
| | 573 | * as zeroed */ |
|---|
| | 574 | memset(sn->rs_sampleTable, 0, sizeof(sn->rs_sampleTable)); |
|---|
| | 575 | |
|---|
| | 576 | sn->rs_sampleColumn = 0; |
|---|
| | 577 | sn->rs_sampleIndex = 0; |
|---|
| | 578 | |
|---|
| | 579 | /* Seed value to random number generator, which determines when we |
|---|
| | 580 | * send a sample packet at some non-optimal rate |
|---|
| | 581 | * FIXME: randomise? */ |
|---|
| | 582 | sn->random_n = 1; |
|---|
| | 583 | sn->a = 1664525; |
|---|
| | 584 | sn->b = 1013904223; |
|---|
| | 585 | |
|---|
| | 586 | if (sn->num_rates > 1) { |
|---|
| | 587 | for (column_index = 0; column_index < MINSTREL_COLUMNS; column_index++) { |
|---|
| | 588 | for (i = 0; i < num_sample_rates; i++) { |
|---|
| | 589 | get_random_bytes(random_bytes, 8); |
|---|
| | 590 | newIndex = (i + random_bytes[i & 7]) % num_sample_rates; |
|---|
| | 591 | |
|---|
| | 592 | while (sn->rs_sampleTable[newIndex][column_index] != 0) |
|---|
| | 593 | newIndex = (newIndex + 1) % num_sample_rates; |
|---|
| | 594 | |
|---|
| | 595 | sn->rs_sampleTable[newIndex][column_index] = i + 1; |
|---|
| | 598 | } |
|---|
| | 599 | |
|---|
| | 600 | for (column_index = 0; column_index < MINSTREL_COLUMNS; column_index++) { |
|---|
| | 601 | for (i = 0; i < num_sample_rates && i < IEEE80211_RATE_MAXSIZE; i++) { |
|---|
| | 602 | DPRINTF(sc, "rs_sampleTable[%2u][%2u] = %2u\n", |
|---|
| | 603 | i, column_index, sn->rs_sampleTable[i][column_index]); |
|---|
| | 604 | } |
|---|
| | 605 | } |
|---|
| | 606 | } |
|---|
| | 607 | |
|---|
| | 608 | /* Initialize the tables for a node. */ |
|---|
| | 609 | static void |
|---|
| | 610 | ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni) |
|---|
| | 611 | { |
|---|
| | 612 | struct minstrel_node *sn = ATH_NODE_MINSTREL(ATH_NODE(ni)); |
|---|
| | 613 | struct ieee80211vap *vap = ni->ni_vap; |
|---|
| | 614 | const HAL_RATE_TABLE *rt = sc->sc_currates; |
|---|
| | 615 | unsigned int x; |
|---|
| | 616 | int retry_index, tx_time; |
|---|
| | 617 | int srate; |
|---|
| | 618 | int ndx = 0; |
|---|
| | 619 | |
|---|
| | 620 | sn->num_rates = 0; |
|---|
| | 621 | sn->max_tp_rate = 0; |
|---|
| | 622 | sn->max_tp_rate2 = 0; |
|---|
| | 623 | sn->max_prob_rate = 0; |
|---|
| | 624 | sn->packet_count = 0; |
|---|
| | 625 | sn->sample_count = 0; |
|---|
| | 626 | sn->is_sampling = 0; |
|---|
| | 627 | |
|---|
| | 628 | if (rt == NULL) { |
|---|
| | 629 | DPRINTF(sc, "no rates yet! mode %u\n", sc->sc_curmode); |
|---|
| | 630 | return; |
|---|
| | 631 | } |
|---|
| | 632 | sn->static_rate_ndx = -1; |
|---|
| | 633 | |
|---|
| | 634 | sn->num_rates = ni->ni_rates.rs_nrates; |
|---|
| | 635 | for (x = 0; x < ni->ni_rates.rs_nrates; x++) { |
|---|
| | 636 | sn->rs_rateattempts [x] = 0; |
|---|
| | 637 | sn->rs_thisprob [x] = 0; |
|---|
| | 638 | sn->rs_ratesuccess [x] = 0; |
|---|
| | 639 | sn->rs_lastrateattempts [x] = 0; |
|---|
| | 640 | sn->rs_lastratesuccess [x] = 0; |
|---|
| | 641 | sn->rs_probability [x] = 0; |
|---|
| | 642 | sn->rs_succ_hist [x] = 0; |
|---|
| | 643 | sn->rs_att_hist [x] = 0; |
|---|
| | 644 | sn->rs_this_tp [x] = 0; |
|---|
| | 645 | |
|---|
| | 646 | sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL; |
|---|
| | 647 | sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate]; |
|---|
| | 648 | if (sn->rates[x].rix == 0xff) { |
|---|
| | 649 | DPRINTF(sc, "%s: %s ignore bogus rix at %d\n", |
|---|
| | 650 | dev_info, __func__, x); |
|---|
| | 651 | continue; |
|---|
| | 652 | } |
|---|
| | 653 | sn->rates[x].rateCode = rt->info[sn->rates[x].rix].rateCode; |
|---|
| | 654 | sn->rates[x].shortPreambleRateCode = |
|---|
| | 655 | rt->info[sn->rates[x].rix].rateCode | |
|---|
| | 656 | rt->info[sn->rates[x].rix].shortPreamble; |
|---|
| | 657 | } |
|---|
| | 658 | |
|---|
| | 659 | ath_fill_sample_table(sc, sn); |
|---|
| | 660 | |
|---|
| | 661 | ni->ni_txrate = 0; |
|---|
| | 662 | |
|---|
| | 663 | if (sn->num_rates <= 0) { |
|---|
| | 664 | DPRINTF(sc, "%s: %s " MAC_FMT " no rates (fixed %d) \n", |
|---|
| | 665 | dev_info, __func__, MAC_ADDR(ni->ni_macaddr), |
|---|
| | 666 | vap->iv_fixed_rate); |
|---|
| | 667 | /* There are no rates yet; we're done */ |
|---|
| | 668 | return; |
|---|
| | 669 | } |
|---|
| | 670 | |
|---|
| | 671 | if (vap->iv_fixed_rate != IEEE80211_FIXED_RATE_NONE) { |
|---|
| | 672 | srate = sn->num_rates - 1; |
|---|
| | 673 | |
|---|
| | 674 | /* A fixed rate is to be used; ic_fixed_rate is an |
|---|
| | 675 | * index into the supported rate set. Convert this |
|---|
| | 676 | * to the index into the negotiated rate set for |
|---|
| | 677 | * the node. We know the rate is there because the |
|---|
| | 678 | * rate set is checked when the station associates. */ |
|---|
| | 679 | /* NB: the rate set is assumed to be sorted. */ |
|---|
| | 680 | for (; |
|---|
| | 681 | (srate >= 0) && |
|---|
| | 682 | (ni->ni_rates.rs_rates[srate] & |
|---|
| | 683 | IEEE80211_RATE_VAL) != vap->iv_fixed_rate; |
|---|
| | 684 | srate--); |
|---|
| | 685 | |
|---|
| | 686 | KASSERT(srate >= 0, |
|---|
| | 687 | ("fixed rate %d not in rate set", vap->iv_fixed_rate)); |
|---|
| | 688 | |
|---|
| | 689 | sn->static_rate_ndx = srate; |
|---|
| | 690 | ni->ni_txrate = srate; |
|---|
| | 691 | DPRINTF(sc, "%s: %s " MAC_FMT " fixed rate %d%sMbps\n", |
|---|
| | 692 | dev_info, __func__, MAC_ADDR(ni->ni_macaddr), |
|---|
| | 693 | sn->rates[srate].rate / 2, |
|---|
| | 694 | (sn->rates[srate].rate % 2) ? ".5 " : " "); |
|---|
| | 695 | return; |
|---|
| | 696 | } |
|---|
| | 697 | |
|---|
| | 698 | for (x = 0; x < ni->ni_rates.rs_nrates; x++) { |
|---|
| | 699 | if (sn->rates[x].rix == 0xff) { |
|---|
| | 700 | DPRINTF(sc, "%s: %s ignore bogus rix at %d\n", |
|---|
| | 701 | dev_info, __func__, x); |
|---|
| | 702 | continue; |
|---|
| | 703 | } |
|---|
| | 704 | |
|---|
| | 705 | sn->rs_rateattempts [x] = 0; |
|---|
| | 706 | sn->rs_thisprob [x] = 0; |
|---|
| | 707 | sn->rs_ratesuccess [x] = 0; |
|---|
| | 708 | sn->rs_probability [x] = 0; |
|---|
| | 709 | sn->rs_lastrateattempts [x] = 0; |
|---|
| | 710 | sn->rs_lastratesuccess [x] = 0; |
|---|
| | 711 | sn->rs_succ_hist [x] = 0; |
|---|
| | 712 | sn->rs_att_hist [x] = 0; |
|---|
| | 713 | sn->perfect_tx_time [x] = |
|---|
| | 714 | calc_usecs_unicast_packet(sc, 1200, |
|---|
| | 715 | sn->rates[x].rix, |
|---|
| | 716 | 0, 0); |
|---|
| | 717 | sn->retry_count [x] = 1; |
|---|
| | 718 | sn->retry_adjusted_count[x] = 1; |
|---|
| | 719 | |
|---|
| | 720 | for (retry_index = 2; retry_index < ATH_TXMAXTRY; retry_index++) { |
|---|
| | 721 | tx_time = calc_usecs_unicast_packet(sc, 1200, |
|---|
| | 722 | sn->rates[x].rix, 0, retry_index); |
|---|
| | 723 | if (tx_time > ath_segment_size) |
|---|
| | 724 | break; |
|---|
| | 725 | sn->retry_count[x] = retry_index; |
|---|
| | 726 | sn->retry_adjusted_count[x] = retry_index; |
|---|
| | 727 | } |
|---|
| | 728 | } |
|---|
| 595 | | } |
|---|
| 596 | | |
|---|
| 597 | | /* Initialize the tables for a node. */ |
|---|
| 598 | | static void |
|---|
| 599 | | ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni) |
|---|
| 600 | | { |
|---|
| 601 | | struct ath_node *an = ATH_NODE(ni); |
|---|
| 602 | | struct minstrel_node *sn = ATH_NODE_MINSTREL(an); |
|---|
| 603 | | struct ieee80211vap *vap = ni->ni_vap; |
|---|
| 604 | | const HAL_RATE_TABLE *rt = sc->sc_currates; |
|---|
| 605 | | unsigned int x; |
|---|
| 606 | | int retry_index, tx_time; |
|---|
| 607 | | int srate; |
|---|
| 608 | | int ndx = 0; |
|---|
| 609 | | |
|---|
| 610 | | sn->num_rates = 0; |
|---|
| 611 | | sn->max_tp_rate = 0; |
|---|
| 612 | | sn->max_tp_rate2 = 0; |
|---|
| 613 | | sn->max_prob_rate = 0; |
|---|
| 614 | | sn->packet_count = 0; |
|---|
| 615 | | sn->sample_count = 0; |
|---|
| 616 | | sn->is_sampling = 0; |
|---|
| 617 | | |
|---|
| 618 | | if (rt == NULL) { |
|---|
| 619 | | DPRINTF(sc, "no rates yet! mode %u\n", sc->sc_curmode); |
|---|
| 620 | | return; |
|---|
| 621 | | } |
|---|
| 622 | | sn->static_rate_ndx = -1; |
|---|
| 623 | | |
|---|
| 624 | | sn->num_rates = ni->ni_rates.rs_nrates; |
|---|
| 625 | | for (x = 0; x < ni->ni_rates.rs_nrates; x++) { |
|---|
| 626 | | sn->rs_rateattempts [x] = 0; |
|---|
| 627 | | sn->rs_thisprob [x] = 0; |
|---|
| 628 | | sn->rs_ratesuccess [x] = 0; |
|---|
| 629 | | sn->rs_lastrateattempts [x] = 0; |
|---|
| 630 | | sn->rs_lastratesuccess [x] = 0; |
|---|
| 631 | | sn->rs_probability [x] = 0; |
|---|
| 632 | | sn->rs_succ_hist [x] = 0; |
|---|
| 633 | | sn->rs_att_hist [x] = 0; |
|---|
| 634 | | sn->rs_this_tp [x] = 0; |
|---|
| 635 | | |
|---|
| 636 | | sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL; |
|---|
| 637 | | sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate]; |
|---|
| 638 | | if (sn->rates[x].rix == 0xff) { |
|---|
| 639 | | DPRINTF(sc, "%s: %s ignore bogus rix at %d\n", |
|---|
| 640 | | dev_info, __func__, x); |
|---|
| 641 | | continue; |
|---|
| 642 | | } |
|---|
| 643 | | sn->rates[x].rateCode = rt->info[sn->rates[x].rix].rateCode; |
|---|
| 644 | | sn->rates[x].shortPreambleRateCode = |
|---|
| 645 | | rt->info[sn->rates[x].rix].rateCode | |
|---|
| 646 | | rt->info[sn->rates[x].rix].shortPreamble; |
|---|
| 647 | | } |
|---|
| 648 | | |
|---|
| 649 | | ath_fill_sample_table(sn); |
|---|
| 650 | | |
|---|
| 651 | | ni->ni_txrate = 0; |
|---|
| 652 | | |
|---|
| 653 | | if (sn->num_rates <= 0) { |
|---|
| 654 | | DPRINTF(sc, "%s: %s " MAC_FMT " no rates (fixed %d) \n", |
|---|
| 655 | | dev_info, __func__, MAC_ADDR(ni->ni_macaddr), |
|---|
| 656 | | vap->iv_fixed_rate); |
|---|
| 657 | | /* There are no rates yet; we're done */ |
|---|
| 658 | | return; |
|---|
| 659 | | } |
|---|
| 660 | | |
|---|
| 661 | | if (vap->iv_fixed_rate != IEEE80211_FIXED_RATE_NONE) { |
|---|
| 662 | | srate = sn->num_rates - 1; |
|---|
| 663 | | |
|---|
| 664 | | /* A fixed rate is to be used; ic_fixed_rate is an |
|---|
| 665 | | * index into the supported rate set. Convert this |
|---|
| 666 | | * to the index into the negotiated rate set for |
|---|
| 667 | | * the node. We know the rate is there because the |
|---|
| 668 | | * rate set is checked when the station associates. */ |
|---|
| 669 | | /* NB: the rate set is assumed sorted */ |
|---|
| 670 | | for (; (srate >= 0) && (ni->ni_rates.rs_rates[srate] & IEEE80211_RATE_VAL) != vap->iv_fixed_rate; srate--); |
|---|
| 671 | | |
|---|
| 672 | | KASSERT(srate >= 0, |
|---|
| 673 | | ("fixed rate %d not in rate set", vap->iv_fixed_rate)); |
|---|
| 674 | | |
|---|
| 675 | | sn->static_rate_ndx = srate; |
|---|
| 676 | | ni->ni_txrate = srate; |
|---|
| 677 | | DPRINTF(sc, "%s: %s " MAC_FMT " fixed rate %d%sMbps\n", |
|---|
| 678 | | dev_info, __func__, MAC_ADDR(ni->ni_macaddr), |
|---|
| 679 | | sn->rates[srate].rate / 2, |
|---|
| 680 | | (sn->rates[srate].rate % 2) ? ".5 " : " "); |
|---|
| 681 | | return; |
|---|
| 682 | | } |
|---|
| 683 | | |
|---|
| 684 | | for (x = 0; x < ni->ni_rates.rs_nrates; x++) { |
|---|
| 685 | | if (sn->rates[x].rix == 0xff) { |
|---|
| 686 | | DPRINTF(sc, "%s: %s ignore bogus rix at %d\n", |
|---|
| 687 | | dev_info, __func__, x); |
|---|
| 688 | | continue; |
|---|
| 689 | | } |
|---|
| 690 | | |
|---|
| 691 | | sn->rs_rateattempts [x] = 0; |
|---|
| 692 | | sn->rs_thisprob [x] = 0; |
|---|
| 693 | | sn->rs_ratesuccess [x] = 0; |
|---|
| 694 | | sn->rs_probability [x] = 0; |
|---|
| 695 | | sn->rs_lastrateattempts [x] = 0; |
|---|
| 696 | | sn->rs_lastratesuccess [x] = 0; |
|---|
| 697 | | sn->rs_succ_hist [x] = 0; |
|---|
| 698 | | sn->rs_att_hist [x] = 0; |
|---|
| 699 | | sn->perfect_tx_time [x] = |
|---|
| 700 | | calc_usecs_unicast_packet(sc, 1200, |
|---|
| 701 | | sn->rates[x].rix, |
|---|
| 702 | | 0, 0); |
|---|
| 703 | | sn->retry_count [x] = 1; |
|---|
| 704 | | sn->retry_adjusted_count[x] = 1; |
|---|
| 705 | | |
|---|
| 706 | | for (retry_index = 2; retry_index < ATH_TXMAXTRY; retry_index++) { |
|---|
| 707 | | tx_time = calc_usecs_unicast_packet(sc, 1200, sn->rates[x].rix, 0, retry_index); |
|---|
| 708 | | if (tx_time > ath_segment_size) |
|---|
| 709 | | break; |
|---|
| 710 | | sn->retry_count[x] = retry_index; |
|---|
| 711 | | sn->retry_adjusted_count[x] = retry_index; |
|---|
| 712 | | } |
|---|
| 713 | | } |
|---|
| 714 | | |
|---|
| 715 | | #if 0 |
|---|
| 716 | | DPRINTF(sc, "%s: Retry table for this node\n", __func__); |
|---|
| 717 | | for (x = 0; x < ni->ni_rates.rs_nrates; x++) |
|---|
| 718 | | DPRINTF(sc, "%2d %2d %6d \n", x, sn->retry_count[x], sn->perfect_tx_time[x]); |
|---|
| 719 | | #endif |
|---|
| 720 | | |
|---|
| 721 | | /* Set the initial rate */ |
|---|
| 722 | | for (ndx = sn->num_rates - 1; ndx > 0; ndx--) |
|---|
| 723 | | if (sn->rates[ndx].rate <= 72) |
|---|
| 724 | | break; |
|---|
| 725 | | sn->current_rate = ndx; |
|---|
| 726 | | |
|---|
| 727 | | ni->ni_txrate = sn->current_rate; |
|---|
| | 736 | |
|---|
| | 737 | /* Set the initial rate */ |
|---|
| | 738 | for (ndx = sn->num_rates - 1; ndx > 0; ndx--) |
|---|
| | 739 | if (sn->rates[ndx].rate <= 72) |
|---|
| | 740 | break; |
|---|
| | 741 | sn->current_rate = ndx; |
|---|
| | 742 | |
|---|
| | 743 | ni->ni_txrate = sn->current_rate; |
|---|
| 754 | | struct minstrel_softc *ssc = (struct minstrel_softc *) data; |
|---|
| 755 | | struct ath_softc *sc = ssc->sc; |
|---|
| 756 | | struct ieee80211com *ic; |
|---|
| 757 | | struct net_device *dev = ssc->sc_dev; |
|---|
| 758 | | struct timer_list *timer; |
|---|
| 759 | | unsigned int interval = ath_timer_interval; |
|---|
| 760 | | |
|---|
| 761 | | if (dev == NULL) |
|---|
| 762 | | DPRINTF(sc, "%s: 'dev' is null in this timer \n", __func__); |
|---|
| 763 | | |
|---|
| 764 | | if (sc == NULL) |
|---|
| 765 | | DPRINTF(sc, "%s: 'sc' is null in this timer\n", __func__); |
|---|
| 766 | | |
|---|
| 767 | | ic = &sc->sc_ic; |
|---|
| 768 | | |
|---|
| 769 | | if (ssc->close_timer_now) |
|---|
| 770 | | return; |
|---|
| 771 | | |
|---|
| 772 | | if (dev->flags & IFF_RUNNING) { |
|---|
| 773 | | sc->sc_stats.ast_rate_calls++; |
|---|
| 774 | | |
|---|
| 775 | | if (ic->ic_opmode == IEEE80211_M_STA) { |
|---|
| 776 | | struct ieee80211vap *tmpvap; |
|---|
| 777 | | TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) { |
|---|
| 778 | | ath_rate_statistics(sc, tmpvap->iv_bss);/* NB: no reference */ |
|---|
| 779 | | } |
|---|
| 780 | | } else |
|---|
| 781 | | ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_statistics, sc); |
|---|
| 782 | | } |
|---|
| 783 | | |
|---|
| 784 | | if (ic->ic_opmode == IEEE80211_M_STA) |
|---|
| 785 | | interval = ath_timer_interval >> 1; |
|---|
| 786 | | |
|---|
| 787 | | timer = &(ssc->timer); |
|---|
| 788 | | if (timer == NULL) |
|---|
| 789 | | DPRINTF(sc, "%s: timer is null - leave it\n", __func__); |
|---|
| 790 | | |
|---|
| 791 | | timer->expires = jiffies + ((HZ * interval) / 1000); |
|---|
| 792 | | add_timer(timer); |
|---|
| | 773 | struct minstrel_softc *ssc = (struct minstrel_softc *) data; |
|---|
| | 774 | struct ath_softc *sc = ssc->sc; |
|---|
| | 775 | struct ieee80211com *ic; |
|---|
| | 776 | struct net_device *dev = ssc->sc_dev; |
|---|
| | 777 | struct timer_list *timer; |
|---|
| | 778 | unsigned int interval = ath_timer_interval; |
|---|
| | 779 | |
|---|
| | 780 | if (dev == NULL) |
|---|
| | 781 | DPRINTF(sc, "%s: 'dev' is null in this timer \n", __func__); |
|---|
| | 782 | |
|---|
| | 783 | if (sc == NULL) |
|---|
| | 784 | DPRINTF(sc, "%s: 'sc' is null in this timer\n", __func__); |
|---|
| | 785 | |
|---|
| | 786 | ic = &sc->sc_ic; |
|---|
| | 787 | |
|---|
| | 788 | if (ssc->close_timer_now) |
|---|
| | 789 | return; |
|---|
| | 790 | |
|---|
| | 791 | if (dev->flags & IFF_RUNNING) { |
|---|
| | 792 | sc->sc_stats.ast_rate_calls++; |
|---|
| | 793 | |
|---|
| | 794 | if (ic->ic_opmode == IEEE80211_M_STA) { |
|---|
| | 795 | struct ieee80211vap *tmpvap; |
|---|
| | 796 | TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) { |
|---|
| | 797 | /* NB: no reference */ |
|---|
| | 798 | ath_rate_statistics(sc, tmpvap->iv_bss); |
|---|
| | 799 | } |
|---|
| | 800 | } else |
|---|
| | 801 | ieee80211_iterate_nodes(&ic->ic_sta, |
|---|
| | 802 | ath_rate_statistics, sc); |
|---|
| | 803 | } |
|---|
| | 804 | |
|---|
| | 805 | if (ic->ic_opmode == IEEE80211_M_STA) |
|---|
| | 806 | interval = ath_timer_interval >> 1; |
|---|
| | 807 | |
|---|
| | 808 | timer = &(ssc->timer); |
|---|
| | 809 | if (timer == NULL) |
|---|
| | 810 | DPRINTF(sc, "%s: timer is null - leave it\n", __func__); |
|---|
| | 811 | |
|---|
| | 812 | timer->expires = jiffies + ((HZ * interval) / 1000); |
|---|
| | 813 | add_timer(timer); |
|---|
| 798 | | struct ath_node *an = (struct ath_node *) ni; |
|---|
| 799 | | struct ieee80211_rateset *rs = &ni->ni_rates; |
|---|
| 800 | | struct minstrel_node *rn = ATH_NODE_MINSTREL(an); |
|---|
| 801 | | unsigned int i; |
|---|
| 802 | | u_int32_t p; |
|---|
| 803 | | u_int32_t micro_secs; |
|---|
| 804 | | u_int32_t max_prob, index_max_prob; |
|---|
| 805 | | u_int32_t max_tp, index_max_tp, index_max_tp2; |
|---|
| 806 | | |
|---|
| 807 | | /* Calculate statistics for each date rate in the table */ |
|---|
| 808 | | /* 'micro_secs' is the time to transmit 1200 bytes, or 9600 bits. */ |
|---|
| 809 | | for (i = 0; i < rs->rs_nrates; i++) { |
|---|
| 810 | | micro_secs = rn->perfect_tx_time[i]; |
|---|
| 811 | | if (micro_secs == 0) |
|---|
| 812 | | micro_secs = ONE_SECOND; |
|---|
| 813 | | |
|---|
| 814 | | if (rn->rs_rateattempts[i] != 0) { |
|---|
| 815 | | p = (rn->rs_ratesuccess[i] * 18000) / rn->rs_rateattempts[i]; |
|---|
| 816 | | rn->rs_succ_hist[i] += rn->rs_ratesuccess[i]; |
|---|
| 817 | | rn->rs_att_hist[i] += rn->rs_rateattempts[i]; |
|---|
| 818 | | rn->rs_thisprob[i] = p; |
|---|
| 819 | | p = ((p * (100 - ath_ewma_level)) + (rn->rs_probability[i] * ath_ewma_level)) / 100; |
|---|
| 820 | | rn->rs_probability[i] = p; |
|---|
| 821 | | rn->rs_this_tp[i] = p * (ONE_SECOND / micro_secs); |
|---|
| 822 | | rn->rs_lastratesuccess[i] = rn->rs_ratesuccess[i]; |
|---|
| 823 | | rn->rs_lastrateattempts[i] = rn->rs_rateattempts[i]; |
|---|
| 824 | | rn->rs_ratesuccess[i] = 0; |
|---|
| 825 | | rn->rs_rateattempts[i] = 0; |
|---|
| 826 | | } else { |
|---|
| 827 | | rn->rs_lastratesuccess[i] = 0; |
|---|
| 828 | | rn->rs_lastrateattempts[i] = 0; |
|---|
| 829 | | } |
|---|
| 830 | | |
|---|
| 831 | | /* Sample less often below the 10% chance of success. |
|---|
| 832 | | * Sample less often above the 95% chance of success. |
|---|
| 833 | | * 'rn->rs_probability' has a scale of 0 (0%) to 18000 (100%), which avoids rounding issues.*/ |
|---|
| 834 | | if ((rn->rs_probability[i] > 17100) || (rn->rs_probability[i] < 1800)) { |
|---|
| 835 | | rn->retry_adjusted_count[i] = rn->retry_count[i] >> 1; |
|---|
| 836 | | if (rn->retry_adjusted_count[i] > 2) |
|---|
| 837 | | rn->retry_adjusted_count[i] = 2; |
|---|
| 838 | | } else |
|---|
| 839 | | rn->retry_adjusted_count[i] = rn->retry_count[i]; |
|---|
| 840 | | if (rn->retry_adjusted_count[i] == 0) |
|---|
| 841 | | rn->retry_adjusted_count[i] = 1; |
|---|
| 842 | | } |
|---|
| 843 | | |
|---|
| 844 | | /* The High speed rates (e.g 54Mbps) is checked last. If |
|---|
| 845 | | * throughput is the same for two rates, we prefer the |
|---|
| 846 | | * lower rate, as this has a better chance of success. */ |
|---|
| 847 | | max_prob = 0; |
|---|
| 848 | | index_max_prob = 0; |
|---|
| 849 | | max_tp = 0; |
|---|
| 850 | | index_max_tp = 0; |
|---|
| 851 | | index_max_tp2 = 0; |
|---|
| 852 | | |
|---|
| 853 | | /* This code could have been moved up into the previous |
|---|
| 854 | | * loop. More readable to have it here */ |
|---|
| 855 | | for (i = 0; i < rs->rs_nrates; i++) { |
|---|
| 856 | | if (max_tp < rn->rs_this_tp[i]) { |
|---|
| 857 | | index_max_tp = i; |
|---|
| 858 | | max_tp = rn->rs_this_tp[i]; |
|---|
| 859 | | } |
|---|
| 860 | | |
|---|
| 861 | | if (max_prob < rn->rs_probability[i]) { |
|---|
| 862 | | index_max_prob = i; |
|---|
| 863 | | max_prob = rn->rs_probability[i]; |
|---|
| 864 | | } |
|---|
| 865 | | } |
|---|
| 866 | | |
|---|
| 867 | | max_tp = 0; |
|---|
| 868 | | for (i = 0; i < rs->rs_nrates; i++) { |
|---|
| 869 | | if ((i != index_max_tp) && (max_tp < rn->rs_this_tp[i])) { |
|---|
| 870 | | index_max_tp2 = i; |
|---|
| 871 | | max_tp = rn->rs_this_tp[i]; |
|---|
| 872 | | } |
|---|
| 873 | | } |
|---|
| 874 | | |
|---|
| 875 | | rn->max_tp_rate = index_max_tp; |
|---|
| 876 | | rn->max_tp_rate2 = index_max_tp2; |
|---|
| 877 | | rn->max_prob_rate = index_max_prob; |
|---|
| 878 | | rn->current_rate = index_max_tp; |
|---|
| | 819 | struct ath_node *an = (struct ath_node *) ni; |
|---|
| | 820 | struct ieee80211_rateset *rs = &ni->ni_rates; |
|---|
| | 821 | struct minstrel_node *rn = ATH_NODE_MINSTREL(an); |
|---|
| | 822 | unsigned int i; |
|---|
| | 823 | u_int32_t p; |
|---|
| | 824 | u_int32_t micro_secs; |
|---|
| | 825 | u_int32_t max_prob, index_max_prob; |
|---|
| | 826 | u_int32_t max_tp, index_max_tp, index_max_tp2; |
|---|
| | 827 | |
|---|
| | 828 | /* Calculate statistics for each date rate in the table */ |
|---|
| | 829 | /* 'micro_secs' is the time to transmit 1200 bytes, or 9600 bits. */ |
|---|
| | 830 | for (i = 0; i < rs->rs_nrates; i++) { |
|---|
| | 831 | micro_secs = rn->perfect_tx_time[i]; |
|---|
| | 832 | if (micro_secs == 0) |
|---|
| | 833 | micro_secs = ONE_SECOND; |
|---|
| | 834 | |
|---|
| | 835 | if (rn->rs_rateattempts[i] != 0) { |
|---|
| | 836 | p = (rn->rs_ratesuccess[i] * 18000) / |
|---|
| | 837 | rn->rs_rateattempts[i]; |
|---|
| | 838 | rn->rs_succ_hist[i] += rn->rs_ratesuccess[i]; |
|---|
| | 839 | rn->rs_att_hist[i] += rn->rs_rateattempts[i]; |
|---|
| | 840 | rn->rs_thisprob[i] = p; |
|---|
| | 841 | p = ((p * (100 - ath_ewma_level)) + |
|---|
| | 842 | (rn->rs_probability[i] * ath_ewma_level)) / 100; |
|---|
| | 843 | rn->rs_probability[i] = p; |
|---|
| | 844 | rn->rs_this_tp[i] = p * (ONE_SECOND / micro_secs); |
|---|
| | 845 | rn->rs_lastratesuccess[i] = rn->rs_ratesuccess[i]; |
|---|
| | 846 | rn->rs_lastrateattempts[i] = rn->rs_rateattempts[i]; |
|---|
| | 847 | rn->rs_ratesuccess[i] = 0; |
|---|
| | 848 | rn->rs_rateattempts[i] = 0; |
|---|
| | 849 | } else { |
|---|
| | 850 | rn->rs_lastratesuccess[i] = 0; |
|---|
| | 851 | rn->rs_lastrateattempts[i] = 0; |
|---|
| | 852 | } |
|---|
| | 853 | |
|---|
| | 854 | /* Sample less often below the 10% chance of success. |
|---|
| | 855 | * Sample less often above the 95% chance of success. |
|---|
| | 856 | * 'rn->rs_probability' has a scale of 0 (0%) to 18000 (100%), |
|---|
| | 857 | * which avoids rounding issues.*/ |
|---|
| | 858 | if ((rn->rs_probability[i] > 17100) || |
|---|
| | 859 | (rn->rs_probability[i] < 1800)) { |
|---|
| | 860 | rn->retry_adjusted_count[i] = rn->retry_count[i] >> 1; |
|---|
| | 861 | if (rn->retry_adjusted_count[i] > 2) |
|---|
| | 862 | rn->retry_adjusted_count[i] = 2; |
|---|
| | 863 | } else |
|---|
| | 864 | rn->retry_adjusted_count[i] = rn->retry_count[i]; |
|---|
| | 865 | if (rn->retry_adjusted_count[i] == 0) |
|---|
| | 866 | rn->retry_adjusted_count[i] = 1; |
|---|
| | 867 | } |
|---|
| | 868 | |
|---|
| | 869 | /* The High speed rates (e.g 54Mbps) is checked last. If |
|---|
| | 870 | * throughput is the same for two rates, we prefer the |
|---|
| | 871 | * lower rate, as this has a better chance of success. */ |
|---|
| | 872 | max_prob = 0; |
|---|
| | 873 | index_max_prob = 0; |
|---|
| | 874 | max_tp = 0; |
|---|
| | 875 | index_max_tp = 0; |
|---|
| | 876 | index_max_tp2 = 0; |
|---|
| | 877 | |
|---|
| | 878 | /* This code could have been moved up into the previous |
|---|
| | 879 | * loop. More readable to have it here */ |
|---|
| | 880 | for (i = 0; i < rs->rs_nrates; i++) { |
|---|
| | 881 | if (max_tp < rn->rs_this_tp[i]) { |
|---|
| | 882 | index_max_tp = i; |
|---|
| | 883 | max_tp = rn->rs_this_tp[i]; |
|---|
| | 884 | } |
|---|
| | 885 | |
|---|
| | 886 | if (max_prob < rn->rs_probability[i]) { |
|---|
| | 887 | index_max_prob = i; |
|---|
| | 888 | max_prob = rn->rs_probability[i]; |
|---|
| | 889 | } |
|---|
| | 890 | } |
|---|
| | 891 | |
|---|
| | 892 | max_tp = 0; |
|---|
| | 893 | for (i = 0; i < rs->rs_nrates; i++) { |
|---|
| | 894 | if ((i != index_max_tp) && (max_tp < rn->rs_this_tp[i])) { |
|---|
| | 895 | index_max_tp2 = i; |
|---|
| | 896 | max_tp = rn->rs_this_tp[i]; |
|---|
| | 897 | } |
|---|
| | 898 | } |
|---|
| | 899 | |
|---|
| | 900 | rn->max_tp_rate = index_max_tp; |
|---|
| | 901 | rn->max_tp_rate2 = index_max_tp2; |
|---|
| | 902 | rn->max_prob_rate = index_max_prob; |
|---|
| | 903 | rn->current_rate = index_max_tp; |
|---|