aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rc80211_minstrel_ht.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2013-03-02 15:20:12 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-03-06 10:35:51 -0500
commited97a13c540eb8fdbb6250eaa6471a4263204af8 (patch)
treeddcea367a65e89414cfd550120368203ebf6fd1a /net/mac80211/rc80211_minstrel_ht.c
parent355199e02b831fd4f652c34d6c7673d973da1369 (diff)
mac80211/minstrel_ht: improve accuracy of throughput metric at high data rates
At high data rates the average frame transmission durations are small enough for rounding errors to matter, sometimes causing minstrel to use slightly lower transmit rates than necessary. To fix this, change the unit of the duration value to nanoseconds instead of microseconds, and reorder the multiplications/divisions when calculating the throughput metric so that they don't overflow or truncate prematurely. At 2-stream HT40 this makes TCP throughput a bit more stable. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/rc80211_minstrel_ht.c')
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 3af141c69712..0b5cdd94d4f0 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -26,11 +26,11 @@
26/* Number of symbols for a packet with (bps) bits per symbol */ 26/* Number of symbols for a packet with (bps) bits per symbol */
27#define MCS_NSYMS(bps) ((MCS_NBITS + (bps) - 1) / (bps)) 27#define MCS_NSYMS(bps) ((MCS_NBITS + (bps) - 1) / (bps))
28 28
29/* Transmission time for a packet containing (syms) symbols */ 29/* Transmission time (nanoseconds) for a packet containing (syms) symbols */
30#define MCS_SYMBOL_TIME(sgi, syms) \ 30#define MCS_SYMBOL_TIME(sgi, syms) \
31 (sgi ? \ 31 (sgi ? \
32 ((syms) * 18 + 4) / 5 : /* syms * 3.6 us */ \ 32 ((syms) * 18000 + 4000) / 5 : /* syms * 3.6 us */ \
33 (syms) << 2 /* syms * 4 us */ \ 33 ((syms) * 1000) << 2 /* syms * 4 us */ \
34 ) 34 )
35 35
36/* Transmit duration for the raw data part of an average sized packet */ 36/* Transmit duration for the raw data part of an average sized packet */
@@ -64,9 +64,9 @@
64} 64}
65 65
66#define CCK_DURATION(_bitrate, _short, _len) \ 66#define CCK_DURATION(_bitrate, _short, _len) \
67 (10 /* SIFS */ + \ 67 (1000 * (10 /* SIFS */ + \
68 (_short ? 72 + 24 : 144 + 48 ) + \ 68 (_short ? 72 + 24 : 144 + 48 ) + \
69 (8 * (_len + 4) * 10) / (_bitrate)) 69 (8 * (_len + 4) * 10) / (_bitrate)))
70 70
71#define CCK_ACK_DURATION(_bitrate, _short) \ 71#define CCK_ACK_DURATION(_bitrate, _short) \
72 (CCK_DURATION((_bitrate > 10 ? 20 : 10), false, 60) + \ 72 (CCK_DURATION((_bitrate > 10 ? 20 : 10), false, 60) + \
@@ -211,7 +211,8 @@ static void
211minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate) 211minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate)
212{ 212{
213 struct minstrel_rate_stats *mr; 213 struct minstrel_rate_stats *mr;
214 unsigned int usecs = 0; 214 unsigned int nsecs = 0;
215 unsigned int tp;
215 216
216 mr = &mi->groups[group].rates[rate]; 217 mr = &mi->groups[group].rates[rate];
217 218
@@ -221,10 +222,12 @@ minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate)
221 } 222 }
222 223
223 if (group != MINSTREL_CCK_GROUP) 224 if (group != MINSTREL_CCK_GROUP)
224 usecs = mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); 225 nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len);
225 226
226 usecs += minstrel_mcs_groups[group].duration[rate]; 227 nsecs += minstrel_mcs_groups[group].duration[rate];
227 mr->cur_tp = MINSTREL_TRUNC((1000000 / usecs) * mr->probability); 228 tp = 1000000 * ((mr->probability * 1000) / nsecs);
229
230 mr->cur_tp = MINSTREL_TRUNC(tp);
228} 231}
229 232
230/* 233/*
@@ -536,7 +539,7 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
536 mr->retry_updated = true; 539 mr->retry_updated = true;
537 540
538 group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; 541 group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
539 tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len; 542 tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len / 1000;
540 543
541 /* Contention time for first 2 tries */ 544 /* Contention time for first 2 tries */
542 ctime = (t_slot * cw) >> 1; 545 ctime = (t_slot * cw) >> 1;