Changeset 3364
- Timestamp:
- 02/25/08 04:18:21 (4 years ago)
- Files:
-
- madwifi/trunk/ath_rate/minstrel/minstrel.c (modified) (22 diffs)
- madwifi/trunk/ath_rate/minstrel/minstrel.txt (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
madwifi/trunk/ath_rate/minstrel/minstrel.c
r3363 r3364 125 125 #define DPRINTF(sc, _fmt, ...) do { \ 126 126 if (sc->sc_debug & ATH_DEBUG_RATE) \ 127 printk( _fmt, __VA_ARGS__);\127 printk("%s: " _fmt, SC_DEV_NAME(sc), __VA_ARGS__); \ 128 128 } while (0) 129 129 #else … … 141 141 #define ENABLE_MRR 1 142 142 143 static int ath_timer_interval = (1000 / 10); /* every 1/10 second, timer runs*/144 static void ath_timer_function(unsigned long data);145 146 /* 10% of the time, send a packet at something other than the optimal rate, which fills147 * the statistics tables nicely. This percentage is applied to the first packet ofthe148 * multi rate retry chain. */143 /* Interval (in ms) between successive rate statistics, default to 100 ms. */ 144 static int ath_timer_interval = 100; 145 146 /* 10% of the time, send a packet at something other than the optimal rate, 147 * which fills the statistics tables nicely. This percentage is applied to the 148 * first packet of the multi rate retry chain. */ 149 149 static int ath_lookaround_rate = 10; 150 150 static int ath_ewma_level = 75; … … 168 168 module_param(ath_segment_size, int, 0600); 169 169 #endif 170 MODULE_PARM_DESC(ath_lookaround_rate, " % of packets sent to fill statistics table (10) "); 171 MODULE_PARM_DESC(ath_ewma_level, " scaling % used in ewma rolloff calculations (75) "); 172 MODULE_PARM_DESC(ath_segment_size, " max duration of time to spend in either of the first two mrr segments (6000)"); 170 MODULE_PARM_DESC(ath_lookaround_rate, " % of packets sent to fill statistics " 171 "table (10) "); 172 MODULE_PARM_DESC(ath_ewma_level, " scaling % used in ewma rolloff " 173 "calculations (75) "); 174 MODULE_PARM_DESC(ath_segment_size, " max duration of time to spend in either " 175 "of the first two mrr segments (6000)"); 173 176 174 177 … … 254 257 if (!rt->info[cix].rateKbps) { 255 258 #if 0 256 printk(KERN_WARNING "cix %d (%d) bad ratekbps %d mode %u\n", 257 cix, rt->info[cix].dot11Rate, 258 rt->info[cix].rateKbps, 259 sc->sc_curmode); 259 printk(KERN_WARNING 260 "cix %d (%d) bad ratekbps %d mode %u\n", 261 cix, rt->info[cix].dot11Rate, 262 rt->info[cix].rateKbps, 263 sc->sc_curmode); 260 264 #endif 261 265 return 0; … … 305 309 { 306 310 struct minstrel_node *odst = ATH_NODE_MINSTREL(dst); 307 const struct minstrel_node *osrc = (const struct minstrel_node *)&src[1]; 311 const struct minstrel_node *osrc = 312 (const struct minstrel_node *)&src[1]; 308 313 memcpy(odst, osrc, sizeof(struct minstrel_node)); 309 314 } … … 327 332 } 328 333 329 mrr = sc->sc_mrretry && !(ic->ic_flags & IEEE80211_F_USEPROT) && ENABLE_MRR; 334 mrr = sc->sc_mrretry && 335 !(ic->ic_flags & IEEE80211_F_USEPROT) && 336 ENABLE_MRR; 330 337 331 338 if (sn->static_rate_ndx >= 0) { … … 353 360 * the slowest rate was used to establish the 354 361 * link in the first place. */ 355 ndx = sn->rs_sampleTable[sn->rs_sampleIndex][sn->rs_sampleColumn]; 362 ndx = sn->rs_sampleTable[sn->rs_sampleIndex] 363 [sn->rs_sampleColumn]; 356 364 357 365 sn->rs_sampleIndex++; … … 365 373 sn->rs_sample_rate = ndx; 366 374 sn->rs_sample_rate_slower = 367 sn->perfect_tx_time[ndx] > sn->perfect_tx_time[sn->max_tp_rate]; 375 (sn->perfect_tx_time[ndx] > 376 sn->perfect_tx_time[sn->max_tp_rate]); 368 377 if (sn->rs_sample_rate_slower) 369 378 ndx = sn->max_tp_rate; … … 395 404 { 396 405 struct minstrel_node *sn = ATH_NODE_MINSTREL(an); 397 int rc1, rc2, rc3; /* Index into the rate table, so for example, it is 0..11 */ 406 /* Index into the rate table, so for example, it is 0..11. */ 407 int rc1, rc2, rc3; 398 408 399 409 if (sn->is_sampling) { … … 473 483 /* 'tries' is the total number of times we have endeavoured to 474 484 * send this packet, and is a sum of the #attempts at each 475 * level in the multi-rate retry chain */485 * level in the multi-rate retry chain. */ 476 486 tries = ts->ts_shortretry + ts->ts_longretry + 1; 477 487 … … 485 495 sn->rs_ratesuccess[final_ndx]++; 486 496 487 mrr = sc->sc_mrretry && !(ic->ic_flags & IEEE80211_F_USEPROT) && ENABLE_MRR; 497 mrr = sc->sc_mrretry && 498 !(ic->ic_flags & IEEE80211_F_USEPROT) && 499 ENABLE_MRR; 488 500 489 501 if (!mrr) { 490 502 if ((0 <= final_ndx) && (final_ndx < sn->num_rates)) { 491 sn->rs_rateattempts[final_ndx] += tries; /* only one rate was used */ 503 /* only one rate was used */ 504 sn->rs_rateattempts[final_ndx] += tries; 492 505 } 493 506 return; 494 507 } 495 508 496 /* Now, query the hal/hardware to find out the contents of the multirate retry chain. 497 * If we have it set to 6,3,2,2, this call will always return 6,3,2,2. For some packets, we can 498 * get a mrr of 0, -1, -1, -1, which indicates there is no chain installed for that packet */ 509 /* Now, query the HAL/hardware to find out the contents of the 510 * multirate retry chain. If we have it set to 6, 3, 2, 2, this 511 * call will always return 6,3,2,2. For some packets, we can 512 * get a mrr of 0, -1, -1, -1, which indicates there is no 513 * chain installed for that packet */ 499 514 rate0 = sc->sc_hwmap[MS(ds->ds_ctl3, AR_XmitRate0)].ieeerate; 500 515 tries0 = MS(ds->ds_ctl2, AR_XmitDataTries0); … … 547 562 548 563 static void 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; 582 596 } 583 597 } 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 } 584 729 585 730 #if 0 586 char rates[200]; 587 char *p; 588 for (column_index = 0; column_index < MINSTREL_COLUMNS; column_index++) { 589 p = rates + sprintf(rates, "rates :: %d ", column_index); 590 for (i = 0; i < num_sample_rates; i++) 591 p += sprintf(p, "%2u ", sn->rs_sampleTable[i][column_index]); 592 DPRINTF(sc, "%s\n", rates); 593 }; 731 DPRINTF(sc, "%s: Retry table for this node\n", __func__); 732 for (x = 0; x < ni->ni_rates.rs_nrates; x++) 733 DPRINTF(sc, "%2d %2d %6d \n", x, sn->retry_count[x], 734 sn->perfect_tx_time[x]); 594 735 #endif 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; 728 744 } 729 745 … … 742 758 if (newstate == IEEE80211_S_RUN) { 743 759 if (ic->ic_opmode != IEEE80211_M_STA) { 744 /* Sync rates for associated stations and neighbors. */ 745 ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_cb, NULL); 760 /* Sync rates for associated stations and 761 * neighbors. */ 762 ieee80211_iterate_nodes(&ic->ic_sta, 763 ath_rate_cb, NULL); 746 764 } 747 ath_rate_newassoc(ic->ic_dev->priv, ATH_NODE(vap->iv_bss), 1); 765 ath_rate_newassoc(ic->ic_dev->priv, 766 ATH_NODE(vap->iv_bss), 1); 748 767 } 749 768 } … … 752 771 ath_timer_function(unsigned long data) 753 772 { 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); 793 814 } 794 815 … … 796 817 ath_rate_statistics(void *arg, struct ieee80211_node *ni) 797 818 { 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; 879 904 } 880 905 … … 882 907 ath_rate_attach(struct ath_softc *sc) 883 908 { 884 struct minstrel_softc *osc;885 DPRINTF(sc, "%s: %s\n", dev_info, __func__);886 887 _MOD_INC_USE(THIS_MODULE, return NULL);888 osc = kmalloc(sizeof(struct minstrel_softc), GFP_ATOMIC);889 if (osc == NULL) {890 _MOD_DEC_USE(THIS_MODULE);891 return NULL;892 }893 894 osc->arc.arc_space = sizeof(struct minstrel_node);895 osc->arc.arc_vap_space = 0;896 897 osc->close_timer_now = 0;898 init_timer(&osc->timer);909 struct minstrel_softc *osc; 910 DPRINTF(sc, "%s: %s\n", dev_info, __func__); 911 912 _MOD_INC_USE(THIS_MODULE, return NULL); 913 osc = kmalloc(sizeof(struct minstrel_softc), GFP_ATOMIC); 914 if (osc == NULL) { 915 _MOD_DEC_USE(THIS_MODULE); 916 return NULL; 917 } 918 919 osc->arc.arc_space = sizeof(struct minstrel_node); 920 osc->arc.arc_vap_space = 0; 921 922 osc->close_timer_now = 0; 923 init_timer(&osc->timer); 899 924 osc->sc = sc; 900 osc->sc_dev = sc->sc_dev;901 osc->timer.function = ath_timer_function;902 osc->timer.data = (unsigned long)osc;903 904 osc->timer.expires = jiffies + HZ;905 add_timer(&osc->timer);906 907 return &osc->arc;925 osc->sc_dev = sc->sc_dev; 926 osc->timer.function = ath_timer_function; 927 osc->timer.data = (unsigned long)osc; 928 929 osc->timer.expires = jiffies + HZ; 930 add_timer(&osc->timer); 931 932 return &osc->arc; 908 933 } 909 934 … … 922 947 ath_proc_read_nodes(struct ieee80211vap *vap, char *buf, int space) 923 948 { 924 char *p = buf; 925 struct ieee80211_node *ni; 926 struct ath_node *an; 927 struct minstrel_node *odst; 928 struct ieee80211_node_table *nt = 929 (struct ieee80211_node_table *) &vap->iv_ic->ic_sta; 930 unsigned int x = 0; 931 unsigned int this_tp, this_prob, this_eprob; 932 struct ath_softc *sc = vap->iv_ic->ic_dev->priv;; 933 934 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 935 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { 936 /* Assume each node needs 1500 bytes */ 937 if ((buf + space) < (p + 1500)) { 938 if ((buf + space) > (p + 100)) { 939 p += sprintf(p, "out of room for node " MAC_FMT "\n\n", MAC_ADDR(ni->ni_macaddr)); 940 break; 941 } 942 DPRINTF(sc, "%s: out of memeory to write tall of the nodes\n", __func__); 943 break; 949 char *p = buf; 950 struct ieee80211_node *ni; 951 struct minstrel_node *odst; 952 struct ieee80211_node_table *nt = 953 (struct ieee80211_node_table *) &vap->iv_ic->ic_sta; 954 unsigned int x = 0; 955 unsigned int this_tp, this_prob, this_eprob; 956 struct ath_softc *sc = vap->iv_ic->ic_dev->priv;; 957 958 IEEE80211_NODE_TABLE_LOCK_IRQ(nt); 959 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { 960 /* Assume each node needs 1500 bytes */ 961 if ((buf + space) < (p + 1500)) { 962 if ((buf + space) > (p + 100)) { 963 p += sprintf(p, "out of room for node " 964 MAC_FMT "\n\n", 965 MAC_ADDR(ni->ni_macaddr)); 966 break; 944 967 } 945 an = ATH_NODE(ni); 946 odst = ATH_NODE_MINSTREL(an); 947 /* Skip ourself */ 948 if (IEEE80211_ADDR_EQ(vap->iv_myaddr, ni->ni_macaddr)) 949 continue; 950 951 p += sprintf(p, "rate data for node: " MAC_FMT "\n", MAC_ADDR(ni->ni_macaddr)); 952 p += sprintf(p, "rate throughput ewma prob this prob this succ/attempt success attempts\n"); 953 for (x = 0; x < odst->num_rates; x++) { 954 p += sprintf(p, "%s", 955 (x == odst->current_rate) ? "T" : " "); 956 957 p += sprintf(p, "%s", 958 (x == odst->max_tp_rate2) ? "t" : " "); 959 960 p += sprintf(p, "%s", 961 (x == odst->max_prob_rate) ? "P" : " "); 962 963 p += sprintf(p, "%3u%s", 964 odst->rates[x].rate / 2, 965 (odst->rates[x].rate & 0x1) != 0 ? ".5" : " "); 966 967 this_tp = ((odst->rs_this_tp[x] / 18000) * 96) >> 10; 968 this_prob = odst->rs_thisprob[x] / 18; 969 this_eprob = odst->rs_probability[x] / 18; 970 p += sprintf(p, " %6u.%1u %6u.%1u %6u.%1u %3u(%3u) %8llu %8llu\n", 971 this_tp / 10, this_tp % 10, 972 this_eprob / 10, this_eprob % 10, 973 this_prob / 10, this_prob % 10, 974 odst->rs_lastratesuccess[x], 975 odst->rs_lastrateattempts[x], 976 (unsigned long long)odst->rs_succ_hist[x], 977 (unsigned long long)odst->rs_att_hist[x]); 978 } 979 p += sprintf(p, "\n"); 980 981 p += sprintf(p, "Total packet count:: ideal %d lookaround %d\n\n", odst->packet_count, odst->sample_count); 982 } 983 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 984 985 return (p - buf); 968 DPRINTF(sc, "%s: out of memeory to write " 969 "all of the nodes\n", __func__); 970 break; 971 } 972 odst = ATH_NODE_MINSTREL(ATH_NODE(ni)); 973 /* Skip ourself */ 974 if (IEEE80211_ADDR_EQ(vap->iv_myaddr, ni->ni_macaddr)) 975 continue; 976 977 p += sprintf(p, "rate data for node: " MAC_FMT "\n", 978 MAC_ADDR(ni->ni_macaddr)); 979 p += sprintf(p, " rate throughput EWMA prob this prob this " 980 "succ/attempt success attempts\n"); 981 for (x = 0; x < odst->num_rates; x++) { 982 p += sprintf(p, "%c", 983 (x == odst->current_rate) ? 'T' : ' '); 984 985 p += sprintf(p, "%c", 986 (x == odst->max_tp_rate2) ? 't' : ' '); 987 988 p += sprintf(p, "%c", 989 (x == odst->max_prob_rate) ? 'P' : ' '); 990 991 p += sprintf(p, " %2u%s", 992 odst->rates[x].rate / 2, 993 (odst->rates[x].rate & 0x1) != 0 ? 994 ".5" : " "); 995 996 this_tp = ((odst->rs_this_tp[x] / 18000) * 96) >> 10; 997 this_prob = odst->rs_thisprob[x] / 18; 998 this_eprob = odst->rs_probability[x] / 18; 999 p += sprintf(p, " %2u.%1u %2u.%1u %6u.%1u" 1000 " %3u(%3u) %8llu %8llu\n", 1001 this_tp / 10, this_tp % 10, 1002 this_eprob / 10, this_eprob % 10, 1003 this_prob / 10, this_prob % 10, 1004 odst->rs_lastratesuccess[x], 1005 odst->rs_lastrateattempts[x], 1006 (unsigned long long)odst->rs_succ_hist[x], 1007 (unsigned long long)odst->rs_att_hist[x]); 1008 } 1009 p += sprintf(p, "\n"); 1010 1011 p += sprintf(p, "Total packet count:: ideal %d " 1012 "lookaround %d\n\n", 1013 odst->packet_count, odst->sample_count); 1014 } 1015 IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); 1016 1017 return (p - buf); 986 1018 } 987 1019 … … 989 1021 ath_proc_ratesample_open(struct inode *inode, struct file *file) 990 1022 { 991 struct proc_ieee80211_priv *pv = NULL;992 struct proc_dir_entry *dp = PDE(inode);993 struct ieee80211vap *vap = dp->data;994 995 if (!(file->private_data = kmalloc(sizeof(struct proc_ieee80211_priv),996 GFP_KERNEL)))997 return -ENOMEM;998 999 /* Initially allocate both read and write buffers */1000 pv = (struct proc_ieee80211_priv *) file->private_data;1001 memset(pv, 0, sizeof(struct proc_ieee80211_priv));1002 pv->rbuf = vmalloc(MAX_PROC_IEEE80211_SIZE);1003 if (!pv->rbuf) {1004 kfree(pv);1005 return -ENOMEM;1006 }1007 pv->wbuf = vmalloc(MAX_PROC_IEEE80211_SIZE);1008 if (!pv->wbuf) {1009 vfree(pv->rbuf);1010 kfree(pv);1011 return -ENOMEM;1012 }1013 1014 memset(pv->wbuf, 0, MAX_PROC_IEEE80211_SIZE);1015 memset(pv->rbuf, 0, MAX_PROC_IEEE80211_SIZE);1016 pv->max_wlen = MAX_PROC_IEEE80211_SIZE;1017 pv->max_rlen = MAX_PROC_IEEE80211_SIZE;1018 1019 /* Now read the data into the buffer */1020 pv->rlen = ath_proc_read_nodes(vap, pv->rbuf, MAX_PROC_IEEE80211_SIZE);1021 return 0;1023 struct proc_ieee80211_priv *pv = NULL; 1024 struct proc_dir_entry *dp = PDE(inode); 1025 struct ieee80211vap *vap = dp->data; 1026 1027 if (!(file->private_data = kmalloc(sizeof(struct proc_ieee80211_priv), 1028 GFP_KERNEL))) 1029 return -ENOMEM; 1030 1031 /* Initially allocate both read and write buffers */ 1032 pv = (struct proc_ieee80211_priv *) file->private_data; 1033 memset(pv, 0, sizeof(struct proc_ieee80211_priv)); 1034 pv->rbuf = vmalloc(MAX_PROC_IEEE80211_SIZE); 1035 if (!pv->rbuf) { 1036 kfree(pv); 1037 return -ENOMEM; 1038 } 1039 pv->wbuf = vmalloc(MAX_PROC_IEEE80211_SIZE); 1040 if (!pv->wbuf) { 1041 vfree(pv->rbuf); 1042 kfree(pv); 1043 return -ENOMEM; 1044 } 1045 1046 memset(pv->wbuf, 0, MAX_PROC_IEEE80211_SIZE); 1047 memset(pv->rbuf, 0, MAX_PROC_IEEE80211_SIZE); 1048 pv->max_wlen = MAX_PROC_IEEE80211_SIZE; 1049 pv->max_rlen = MAX_PROC_IEEE80211_SIZE; 1050 1051 /* Now read the data into the buffer */ 1052 pv->rlen = ath_proc_read_nodes(vap, pv->rbuf, MAX_PROC_IEEE80211_SIZE); 1053 return 0; 1022 1054 } 1023 1055 1024 1056 static struct file_operations ath_proc_ratesample_ops = { 1025 .read = NULL,1026 .write = NULL,1027 .open = ath_proc_ratesample_open,1028 .release = NULL,1057 .read = NULL, 1058 .write = NULL, 1059 .open = ath_proc_ratesample_open, 1060 .release = NULL, 1029 1061 }; 1030 1062 … … 1032 1064 ath_rate_dynamic_proc_register(struct ieee80211vap *vap) 1033 1065 { 1034 /* Create proc entries for the rate control algorithm */1035 ieee80211_proc_vcreate(vap, &ath_proc_ratesample_ops, "rate_info");1066 /* Create proc entries for the rate control algorithm */ 1067 ieee80211_proc_vcreate(vap, &ath_proc_ratesample_ops, "rate_info"); 1036 1068 } 1037 1069 … … 1039 1071 1040 1072 static struct ieee80211_rate_ops ath_rate_ops = { 1041 .ratectl_id = IEEE80211_RATE_MINSTREL,1042 .node_init = ath_rate_node_init,1043 .node_cleanup = ath_rate_node_cleanup,1044 .findrate = ath_rate_findrate,1045 .get_mrr = ath_rate_get_mrr,1046 .tx_complete = ath_rate_tx_complete,1047 .newassoc = ath_rate_newassoc,1048 .newstate = ath_rate_newstate,1049 .attach = ath_rate_attach,1050 .detach = ath_rate_detach,1051 .dynamic_proc_register = ath_rate_dynamic_proc_register,1073 .ratectl_id = IEEE80211_RATE_MINSTREL, 1074 .node_init = ath_rate_node_init, 1075 .node_cleanup = ath_rate_node_cleanup, 1076 .findrate = ath_rate_findrate, 1077 .get_mrr = ath_rate_get_mrr, 1078 .tx_complete = ath_rate_tx_complete, 1079 .newassoc = ath_rate_newassoc, 1080 .newstate = ath_rate_newstate, 1081 .attach = ath_rate_attach, 1082 .detach = ath_rate_detach, 1083 .dynamic_proc_register = ath_rate_dynamic_proc_register, 1052 1084 }; 1053 1085 … … 1063 1095 static int __init ath_rate_minstrel_init(void) 1064 1096 { 1065 printk(KERN_INFO "%s: Minstrel automatic rate control "1066 "algorithm %s\n", dev_info, version);1067 printk(KERN_INFO "%s: look around rate set to %d%%\n",1068 dev_info, ath_lookaround_rate);1069 printk(KERN_INFO "%s: EWMA rolloff level set to %d%%\n",1070 dev_info, ath_ewma_level);1071 printk(KERN_INFO "%s: max segment size in the mrr set "1072 "to %d us\n", dev_info, ath_segment_size);1073 return ieee80211_rate_register(&ath_rate_ops);1097 printk(KERN_INFO "%s: Minstrel automatic rate control " 1098 "algorithm %s\n", dev_info, version); 1099 printk(KERN_INFO "%s: look around rate set to %d%%\n", 1100 dev_info, ath_lookaround_rate); 1101 printk(KERN_INFO "%s: EWMA rolloff level set to %d%%\n", 1102 dev_info, ath_ewma_level); 1103 printk(KERN_INFO "%s: max segment size in the mrr set " 1104 "to %d us\n", dev_info, ath_segment_size); 1105 return ieee80211_rate_register(&ath_rate_ops); 1074 1106 } 1075 1107 module_init(ath_rate_minstrel_init); … … 1077 1109 static void __exit ath_rate_minstrel_exit(void) 1078 1110 { 1079 ieee80211_rate_unregister(&ath_rate_ops);1080 printk(KERN_INFO "%s: unloaded\n", dev_info);1111 ieee80211_rate_unregister(&ath_rate_ops); 1112 printk(KERN_INFO "%s: unloaded\n", dev_info); 1081 1113 } 1082 1114 module_exit(ath_rate_minstrel_exit); madwifi/trunk/ath_rate/minstrel/minstrel.txt
r2695 r3364 1 2 Minstrel 1 minstrel 3 2 4 3 Introduction 5 ================================================================== 4 ============================================================================== 5 6 6 This code is called minstrel, because we have taken a wandering minstrel 7 approach. Wander around the different rates, singing wherever you 8 can. And then, look at the performance, and make a choice. Note that the 9 wandering minstrel will always wander in directions where he/she feels he/she 10 will get paid the best for his/her work. 11 12 The Minstrel autorate selection algorithm is an EWMA based algorithm and is 13 derived from 14 1)An initial rate module we released in 2005, 7 approach. Wander around the different rates, singing wherever you can. And 8 then, look at the performance, and make a choice. Note that the wandering 9 minstrel will always wander in directions where he/she feels he/she will get 10 paid the best for his/her work. 11 12 The minstrel autorate selection algorithm is an EWMA based algorithm and is 13 derived from 14 15 1) An initial rate module we released in 2005, 15 16 http://sourceforge.net/mailarchive/forum.php?forum_id=33966&max_rows=25&style=flat&viewmonth=200501&viewday=5 16 17 17 2)the "sample" module in the madwifi-ng source tree. 18 19 The code released in 2005 had some algorithmic and implementation 20 flaws (one of which was that it was based on the old madwifi codebase) 21 and was shown to be unstable. Performance of the sample module is poor 22 (http://www.madwifi.org/ticket/989), and we have observed similar 23 issues. 18 2) the "sample" module in the madwifi-ng source tree. 19 20 The code released in 2005 had some algorithmic and implementation flaws (one 21 of which was that it was based on the old madwifi codebase) and was shown to 22 be unstable. Performance of the sample module is poor 23 (http://www.madwifi.org/ticket/989), and we have observed similar issues. 24 24 25 25 We noted: 26 1)The rate chosen by sample did not alter to match changes in the radio 26 27 1) The rate chosen by sample did not alter to match changes in the radio 27 28 environment. 28 2)Higher throughput (between two nodes) could often be achieved by fixing the 29 bitrate of both nodes to some value. 30 3)After a long period of operation, "sample" appeared to be stuck in a low 29 30 2) Higher throughput (between two nodes) could often be achieved by fixing 31 the bitrate of both nodes to some value. 32 33 3) After a long period of operation, "sample" appeared to be stuck in a low 31 34 data rate, and would not move to a higher data rate. 32 35 33 We examined the code in sample, and decided the best approach was a 34 rewritebased on sample and the module we released in January 2005.36 We examined the code in sample, and decided the best approach was a rewrite 37 based on sample and the module we released in January 2005. 35 38 36 39 Theory of operation 37 ================================================================== 38 39 We defined the measure of successfulness (of packet transmission) as40 41 mega-bits-transmitted42 Prob_success_transmission * ---------------------- 43 elapsed time44 45 This measure of successfulness will therefore adjust the transmission speed to 40 ============================================================================== 41 42 We defined the measure of successfulness (of packet transmission) as 43 44 Mega bits transmitted 45 Prob_success_transmission * ----------------------- 46 elapsed time 47 48 This measure of successfulness will therefore adjust the transmission speed to 46 49 get the maximum number of data bits through the radio interface. Further, it 47 means that the 1 mb/secrate (which has a very high probability of successful48 transmission) will not be used in preference to the 11 mb/secrate.50 means that the 1 Mbps rate (which has a very high probability of successful 51 transmission) will not be used in preference to the 11 Mbps rate. 49 52 50 53 We decided that the module should record the successfulness of all packets … … 55 58 rates regarded as non optimal. 56 59 57 10 times a second (this frequency is alterable by changing the driver code) 58 atimer fires, which evaluates the statistics table. EWMA calculations60 10 times a second (this frequency is alterable by changing the driver code) a 61 timer fires, which evaluates the statistics table. EWMA calculations 59 62 (described below) are used to process the success history of each rate. On 60 63 completion of the calculation, a decision is made as to the rate which has the 61 best throughput, second best throughput, and highest probability of success.64 best throughput, second best throughput, and highest probability of success. 62 65 This data is used for populating the retry chain during the next 100 ms. 63 66 64 67 As stated above, the minstrel algorithm collects statistics from all packet 65 attempts. Minstrel spends a particular percentage of frames, doing "look66 around" i.e. randomly trying other rates, to gather statistics. The 67 percentage of "look around" frames, is set at boot time via the module 68 parameter "ath_lookaround_rate" and defaults to 10%. The distribution of 69 lookaround frames is also randomised somewhat to avoid any potential 70 "strobing" of lookaround between similar nodes. 71 72 TCP theory tells us that each packet sent must be delivered in under 26 ms. Any73 longer duration, and the TCP network layers will start to back off. A delay of 74 26ms implies that there is congestion in the network, and that fewer packets 75 should be injected to the device. Our conclusion was to adjust the retry chain 76 of each packet so the retry chain was guaranteed to be finished in under 26ms. 77 68 attempts. Minstrel spends a particular percentage of frames, doing "look 69 around" i.e. randomly trying other rates, to gather statistics. The percentage 70 of "look around" frames, is set at boot time via the module parameter 71 "ath_lookaround_rate" and defaults to 10%. The distribution of lookaround 72 frames is also randomised somewhat to avoid any potential "strobing" of 73 lookaround between similar nodes. 74 75 TCP theory tells us that each packet sent must be delivered in under 26 76 ms. Any longer duration, and the TCP network layers will start to back off. A 77 delay of 26 ms implies that there is congestion in the network, and that fewer 78 packets should be injected to the device. Our conclusion was to adjust the 79 retry chain of each packet so the retry chain was guaranteed to be finished in 80 under 26 ms. 78 81 79 82 Retry Chain 80 ================================================================== 83 ============================================================================== 84 81 85 The HAL provides a multirate retry chain - which consists of four 82 86 segments. Each segment is an advisement to the HAL to try to send the current … … 84 88 successfully transmitted, the remainder of the retry chain is 85 89 ignored. Selection of the number of retry attempts was based on the desire to 86 get the packet out in under 26 ms, or fail. We provided a module parameter,90 get the packet out in under 26 ms, or fail. We provided a module parameter, 87 91 ath_segment_size, which has units of microseconds, and specifies the maximum 88 92 duration one segment in the retry chain can last. This module parameter has a … … 91 95 92 96 There is some room for movement here - if the traffic is UDP then the limit of 93 26 ms for the retry chain length is "meaningless".However, one may argue that97 26 ms for the retry chain length is "meaningless". However, one may argue that 94 98 if the packet was not transmitted after some time period, it should 95 99 fail. Further, one does expect UDP packets to fail in transmission. We leave … … 116 120 After some discussion, we have adjusted the code so that the lowest rate is 117 121 never used for the lookaround packet. Our view is that since this rate is used 118 for management packets, this rate must be working. - Alternatively, the link119 is set up with management packets, data packets are acknowledged with 120 management packets. Should the lowest rate stop working, the link is going to 121 diereasonably soon.122 123 Analysis of information in the /proc/net/madwifi/athX/rate_info file 124 showed that the system was sampling too hard at some rates. For those 125 rates that never work (54mb, 500m range) there is no point in sending 126 10 sample packets (<6ms time). Consequently, for the very very low 127 probability rates, wesample at most twice.128 129 The retry chain above does "work", but performance is suboptimal. The 130 key problem being that when the link is good, too much time is spent 131 s ampling the slower rates. Thus, for two nodes adjacent to each other,132 the throughput between them was several megabits/sec below using a 133 fixed rate. The view was that minstrel should not sample at the slower 134 rates if the link is doing well. However, if the link deteriorates, 135 minstrel should immediately sample atthe lower rates.136 137 Some time later, we realised that the only way to code this reliably 138 was to use the retry chain as the method of determining if the slower 139 rates aresampled. The retry chain was modified as:122 for management packets, this rate must be working. Alternatively, the link is 123 set up with management packets, data packets are acknowledged with management 124 packets. Should the lowest rate stop working, the link is going to die 125 reasonably soon. 126 127 Analysis of information in the /proc/net/madwifi/athX/rate_info file showed 128 that the system was sampling too hard at some rates. For those rates that 129 never work (54mb, 500m range) there is no point in sending 10 sample packets 130 (< 6 ms time). Consequently, for the very very low probability rates, we 131 sample at most twice. 132 133 The retry chain above does "work", but performance is suboptimal. The key 134 problem being that when the link is good, too much time is spent sampling the 135 slower rates. Thus, for two nodes adjacent to each other, the throughput 136 between them was several Mbps below using a fixed rate. The view was that 137 minstrel should not sample at the slower rates if the link is doing 138 well. However, if the link deteriorates, minstrel should immediately sample at 139 the lower rates. 140 141 Some time later, we realised that the only way to code this reliably was to 142 use the retry chain as the method of determining if the slower rates are 143 sampled. The retry chain was modified as: 140 144 141 145 Try | Lookaround rate | Normal rate … … 150 154 current best throughput, the randomly selected rate is placed second in the 151 155 chain. If the link is not good, then there will be data collected at the 152 randomly selected rate. Thus, if the best throughput rate is currently 54 mbs,153 the only time slower rates are sampled is when a packet fails in156 randomly selected rate. Thus, if the best throughput rate is currently 54 157 Mbps, the only time slower rates are sampled is when a packet fails in 154 158 transmission. Consequently, if the link is ideal, all packets will be sent at 155 the full rate of 54 mbs. Which is good.159 the full rate of 54 Mbps. Which is good. 156 160 157 161 EWMA 158 ================================================================== 162 ============================================================================== 159 163 160 164 The EWMA calculation is carried out 10 times a second, and is run for each 161 rate. This calculation has a smoothing effect, so that new results have 162 a reasonable (but not large) influence on the selected rate. However, with 163 time, a series of new results in some particular direction will predominate. 164 Giventhis smoothing, we can use words like inertia to describe the EWMA.165 166 By "new results", we mean the results collected in the just completed 100 ms165 rate. This calculation has a smoothing effect, so that new results have a 166 reasonable (but not large) influence on the selected rate. However, with time, 167 a series of new results in some particular direction will predominate. Given 168 this smoothing, we can use words like inertia to describe the EWMA. 169 170 By "new results", we mean the results collected in the just completed 100 ms 167 171 interval. Old results are the EWMA scaling values from before the just 168 completed 100 ms interval.172 completed 100 ms interval. 169 173 170 174 EWMA scaling is set by the module parameter ath_ewma_level, and defaults to 171 75%. A value of 0% means use only the new results, ignore the old results. 172 A value of 99% means use the old results, with a tiny influence from the new 173 results. 174 175 175 75%. A value of 0% means use only the new results, ignore the old results. A 176 value of 99% means use the old results, with a tiny influence from the new 177 results. 176 178 177 179 The calculation (performed for each rate, at each timer interrupt) of the 178 probability of success is:180 probability of success is: 179 181 180 182 Psucces_this_time_interval * (100 - ath_ewma_level) + (Pold * ath_ewma_level) … … 193 195 inserted), then Pnew is calculated from above with Pold set to 0. 194 196 195 The appropriate update interval was selected on the basis of choosing a compromise 196 between 197 *collecting enough success/failure information to be meaningful 198 *minimising the amount of cpu time spent do the updates 199 *providing a means to recover quickly enough from a bad rate selection. 200 The first two points are self explanatory. When there is a sudden change in the radio 201 environment, an update interval of 100ms will mean that the rates marked as optimal are 202 very quickly marked as poor. Consequently, the sudden change in radio environment will 203 mean that minstrel will very quickly switch to a better rate. 197 The appropriate update interval was selected on the basis of choosing a 198 compromise between 199 200 * collecting enough success/failure information to be meaningful 201 * minimising the amount of cpu time spent do the updates 202 * providing a means to recover quickly enough from a bad rate selection. 203 204 The first two points are self explanatory. When there is a sudden change in 205 the radio environment, an update interval of 100 ms will mean that the rates 206 marked as optimal are very quickly marked as poor. Consequently, the sudden 207 change in radio environment will mean that minstrel will very quickly switch 208 to a better rate. 204 209 205 210 A sudden change in the transmission probabilities will happen when the … … 210 215 layers. 211 216 212 213 214 217 Module Parameters 215 ==================================================== 218 ============================================================================== 216 219 The module has three parameters: 217 220 … … 226 229 227 230 Test Network 228 ==================================================== 229 We used three computers in our test network. The first two, equipped with 231 ============================================================================== 232 233 We used three computers in our test network. The first two, equipped with 230 234 atheros cards running in adhoc mode. We used a program that sends a fixed 231 235 number of TCP packets between computers, and reports on the data rate. The … … 239 243 240 244 It was from monitoring the results on the third computer that we started to 241 get some confidence in the correctness of the code. We observed TCP 242 backoffs (described above) on this box. There was much celebration when the 243 throughput increased simply because the retry chain was finished in under 26 244 ms. 245 246 Our view was that throughput between the two computers should be as 247 close as possible (or better than) what can be achieved by setting 248 both ends to fixed rates. Thus, if setting the both ends to fixed 249 rates significantly increases the throughput, a reasonable conclusion 250 is that a fault exists in the adaptive rate rate. 245 get some confidence in the correctness of the code. We observed TCP backoffs 246 (described above) on this box. There was much celebration when the throughput 247 increased simply because the retry chain was finished in under 26 ms. 248 249 Our view was that throughput between the two computers should be as close as 250 possible (or better than) what can be achieved by setting both ends to fixed 251 rates. Thus, if setting the both ends to fixed rates significantly increases 252 the throughput, a reasonable conclusion is that a fault exists in the adaptive 253 rate rate. 251 254 252 255 We recorded throughputs (with minstrel) that are within 10% of what is 253 achieved with the experimentally determined optimum fixed rate. 256 achieved with the experimentally determined optimum fixed rate. 254 257 255 258 256 259 Notes on Timing 257 ==================================================== 258 259 As noted above, Minstrel calculates the throughput for each rate. This260 calculation (using a packet of size 1200 bytes) determines the 261 t ransmission time on the radio medium. In these calculations, we assume a262 contention windowmin and max value of 4 and 10 microseconds respectively.260 ============================================================================== 261 262 As noted above, minstrel calculates the throughput for each rate. This 263 calculation (using a packet of size 1200 bytes) determines the transmission 264 time on the radio medium. In these calculations, we assume a contention window 265 min and max value of 4 and 10 microseconds respectively. 263 266 264 267 Further, calculation of the transmission time is required so that we can 265 guarantee a packet is transmitted (or dropped) in a minimum time period. 266 The transmission time is used in determining how many times a packet 267 istransmitted in each segment of the retry chain.268 guarantee a packet is transmitted (or dropped) in a minimum time period. The 269 transmission time is used in determining how many times a packet is 270 transmitted in each segment of the retry chain. 268 271 269 272 Indeed, the card will supply the cwmin/cwmax values directly 270 273 iwpriv if_name get_cwmin <0|1|2|3> <0|1> 271 274 272 We have not made direct calls to determine cwmin/cwmax - this is an area 273 f or future work. Indeed, the cwmin/cwmax determination code could check to274 see ifthe user has altered these values with the appropriate iwpriv.275 276 The contention window size does vary with traffic class. For example, 277 videoand voice have a contention window min of 3 and 2 microseconds275 We have not made direct calls to determine cwmin/cwmax - this is an area for 276 future work. Indeed, the cwmin/cwmax determination code could check to see if 277 the user has altered these values with the appropriate iwpriv. 278 279 The contention window size does vary with traffic class. For example, video 280 and voice have a contention window min of 3 and 2 microseconds 278 281 respectively. Currently, minstrel does not check traffic class. 279 282 280 Calculating the throughputs based on traffic class and bit rate and 281 variable packet size will significantly complicate the code and require282 many more sample packets. More sample packets will lower the throughput 283 achieved. Thus, our view is that for this release, we should take a simple 284 (but reasonable)approach that works stably and gives good throughputs.283 Calculating the throughputs based on traffic class and bit rate and variable 284 packet size will significantly complicate the code and require many more 285 sample packets. More sample packets will lower the throughput achieved. Thus, 286 our view is that for this release, we should take a simple (but reasonable) 287 approach that works stably and gives good throughputs. 285 288 286 289 … … 292 295 293 296 Internal variable reporting 294 ==================================================== 297 ============================================================================== 298 295 299 The minstrel algorithm reports to the proc file system its internal 296 300 statistics, which can be viewed as text. A sample output is below: … … 326 330 T, t, and P respectively. 327 331 328 The statistics gathered in the last 100 ms time period are displayed in the332 The statistics gathered in the last 100 ms time period are displayed in the 329 333 "this prob" and "this succ/attempt" columns. 330 334 … … 335 339 analysing reports from the hal. The word "attempt" or "attempts" means the 336 340 count of packets that we transmitted. Thus, the number in the success column 337 will always be lower than the number in the attempts column. 338 339 340 When the two nodes are brought closer together, the statistics start changing, 341 and you see more successful attempts at the higher rates. The ewma prob at the 342 higher rates increases and then most packets are conveyed at the higher rates. 343 344 When the rate is not on auto, but fixed, this table is still 345 available, and will report the throughput etc for the current bit 346 rate. Changing the rate from auto to fixed to auto will completely 347 reset this table, and the operation of the minstrel module. 348 349 350 351 352 353 354 355 356 341 will always be lower than the number in the attempts column. 342 343 When the two nodes are brought closer together, the statistics starts 344 changing, and you see more successful attempts at the higher rates. The ewma 345 prob at the higher rates increases and then most packets are conveyed at the 346 higher rates. 347 348 When the rate is not on auto, but fixed, this table is still available, and 349 will report the throughput etc for the current bit rate. Changing the rate 350 from auto to fixed to auto will completely reset this table, and the operation 351 of the minstrel module.
