diff options
author | Daniel Halperin <dhalperi@cs.washington.edu> | 2011-05-10 22:00:45 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-05-12 14:10:48 -0400 |
commit | 8fddddff0ad4ccc2787464207eba9ed3063e69cd (patch) | |
tree | 6f219c46e9fdae5df766deb784c3cfc00e3e4106 /net/mac80211 | |
parent | 56d1893d94bc06d0b1aa3a53f924ed02f9e207bf (diff) |
mac80211: fix contention time computation in minstrel, minstrel_ht
When transmitting a frame, the transmitter waits a random number of
slots between 0 and cw. Thus, the contention time is (cw / 2) * t_slot
which we can represent instead as (cw * t_slot) >> 1. Also fix a few
other accounting bugs around contention time, and add comments.
Signed-off-by: Daniel Halperin <dhalperi@cs.washington.edu>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/rc80211_minstrel.c | 4 | ||||
-rw-r--r-- | net/mac80211/rc80211_minstrel_ht.c | 27 |
2 files changed, 23 insertions, 8 deletions
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 778c604d7939..8adac67395f7 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -417,8 +417,8 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
417 | tx_time_single = mr->ack_time + mr->perfect_tx_time; | 417 | tx_time_single = mr->ack_time + mr->perfect_tx_time; |
418 | 418 | ||
419 | /* contention window */ | 419 | /* contention window */ |
420 | tx_time_single += t_slot + min(cw, mp->cw_max); | 420 | tx_time_single += (t_slot * cw) >> 1; |
421 | cw = (cw << 1) | 1; | 421 | cw = min((cw << 1) | 1, mp->cw_max); |
422 | 422 | ||
423 | tx_time += tx_time_single; | 423 | tx_time += tx_time_single; |
424 | tx_time_cts += tx_time_single + mi->sp_ack_dur; | 424 | tx_time_cts += tx_time_single + mi->sp_ack_dur; |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index dbdebeda097f..3d09c58938e2 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -464,6 +464,7 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, | |||
464 | const struct mcs_group *group; | 464 | const struct mcs_group *group; |
465 | unsigned int tx_time, tx_time_rtscts, tx_time_data; | 465 | unsigned int tx_time, tx_time_rtscts, tx_time_data; |
466 | unsigned int cw = mp->cw_min; | 466 | unsigned int cw = mp->cw_min; |
467 | unsigned int ctime = 0; | ||
467 | unsigned int t_slot = 9; /* FIXME */ | 468 | unsigned int t_slot = 9; /* FIXME */ |
468 | unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len); | 469 | unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len); |
469 | 470 | ||
@@ -480,13 +481,27 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, | |||
480 | 481 | ||
481 | group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; | 482 | group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; |
482 | tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len; | 483 | tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len; |
483 | tx_time = 2 * (t_slot + mi->overhead + tx_time_data); | 484 | |
484 | tx_time_rtscts = 2 * (t_slot + mi->overhead_rtscts + tx_time_data); | 485 | /* Contention time for first 2 tries */ |
486 | ctime = (t_slot * cw) >> 1; | ||
487 | cw = min((cw << 1) | 1, mp->cw_max); | ||
488 | ctime += (t_slot * cw) >> 1; | ||
489 | cw = min((cw << 1) | 1, mp->cw_max); | ||
490 | |||
491 | /* Total TX time for data and Contention after first 2 tries */ | ||
492 | tx_time = ctime + 2 * (mi->overhead + tx_time_data); | ||
493 | tx_time_rtscts = ctime + 2 * (mi->overhead_rtscts + tx_time_data); | ||
494 | |||
495 | /* See how many more tries we can fit inside segment size */ | ||
485 | do { | 496 | do { |
486 | cw = (cw << 1) | 1; | 497 | /* Contention time for this try */ |
487 | cw = min(cw, mp->cw_max); | 498 | ctime = (t_slot * cw) >> 1; |
488 | tx_time += cw + t_slot + mi->overhead; | 499 | cw = min((cw << 1) | 1, mp->cw_max); |
489 | tx_time_rtscts += cw + t_slot + mi->overhead_rtscts; | 500 | |
501 | /* Total TX time after this try */ | ||
502 | tx_time += ctime + mi->overhead + tx_time_data; | ||
503 | tx_time_rtscts += ctime + mi->overhead_rtscts + tx_time_data; | ||
504 | |||
490 | if (tx_time_rtscts < mp->segment_size) | 505 | if (tx_time_rtscts < mp->segment_size) |
491 | mr->retry_count_rtscts++; | 506 | mr->retry_count_rtscts++; |
492 | } while ((tx_time < mp->segment_size) && | 507 | } while ((tx_time < mp->segment_size) && |