aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorDaniel Halperin <dhalperi@cs.washington.edu>2011-05-10 22:00:45 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-05-12 14:10:48 -0400
commit8fddddff0ad4ccc2787464207eba9ed3063e69cd (patch)
tree6f219c46e9fdae5df766deb784c3cfc00e3e4106 /net/mac80211
parent56d1893d94bc06d0b1aa3a53f924ed02f9e207bf (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.c4
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c27
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) &&