提交 8fddddff 编写于 作者: D Daniel Halperin 提交者: John W. Linville

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: NDaniel Halperin <dhalperi@cs.washington.edu>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 56d1893d
...@@ -417,8 +417,8 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, ...@@ -417,8 +417,8 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband,
tx_time_single = mr->ack_time + mr->perfect_tx_time; tx_time_single = mr->ack_time + mr->perfect_tx_time;
/* contention window */ /* contention window */
tx_time_single += t_slot + min(cw, mp->cw_max); tx_time_single += (t_slot * cw) >> 1;
cw = (cw << 1) | 1; cw = min((cw << 1) | 1, mp->cw_max);
tx_time += tx_time_single; tx_time += tx_time_single;
tx_time_cts += tx_time_single + mi->sp_ack_dur; tx_time_cts += tx_time_single + mi->sp_ack_dur;
......
...@@ -464,6 +464,7 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, ...@@ -464,6 +464,7 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
const struct mcs_group *group; const struct mcs_group *group;
unsigned int tx_time, tx_time_rtscts, tx_time_data; unsigned int tx_time, tx_time_rtscts, tx_time_data;
unsigned int cw = mp->cw_min; unsigned int cw = mp->cw_min;
unsigned int ctime = 0;
unsigned int t_slot = 9; /* FIXME */ unsigned int t_slot = 9; /* FIXME */
unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len); unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len);
...@@ -480,13 +481,27 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, ...@@ -480,13 +481,27 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len; tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len;
tx_time = 2 * (t_slot + mi->overhead + tx_time_data);
tx_time_rtscts = 2 * (t_slot + mi->overhead_rtscts + tx_time_data); /* Contention time for first 2 tries */
ctime = (t_slot * cw) >> 1;
cw = min((cw << 1) | 1, mp->cw_max);
ctime += (t_slot * cw) >> 1;
cw = min((cw << 1) | 1, mp->cw_max);
/* Total TX time for data and Contention after first 2 tries */
tx_time = ctime + 2 * (mi->overhead + tx_time_data);
tx_time_rtscts = ctime + 2 * (mi->overhead_rtscts + tx_time_data);
/* See how many more tries we can fit inside segment size */
do { do {
cw = (cw << 1) | 1; /* Contention time for this try */
cw = min(cw, mp->cw_max); ctime = (t_slot * cw) >> 1;
tx_time += cw + t_slot + mi->overhead; cw = min((cw << 1) | 1, mp->cw_max);
tx_time_rtscts += cw + t_slot + mi->overhead_rtscts;
/* Total TX time after this try */
tx_time += ctime + mi->overhead + tx_time_data;
tx_time_rtscts += ctime + mi->overhead_rtscts + tx_time_data;
if (tx_time_rtscts < mp->segment_size) if (tx_time_rtscts < mp->segment_size)
mr->retry_count_rtscts++; mr->retry_count_rtscts++;
} while ((tx_time < mp->segment_size) && } while ((tx_time < mp->segment_size) &&
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册