From: Felix Fietkau Date: Sat, 2 Mar 2013 21:00:58 +0000 (+0000) Subject: mac80211: merge minstrel_ht rate control performance improvements X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=5f079aacd700427524cfeb1f37f21ae05a1c3dbe;p=openwrt%2Fstaging%2Fstintel.git mac80211: merge minstrel_ht rate control performance improvements SVN-Revision: 35847 --- diff --git a/package/mac80211/patches/300-pending_work.patch b/package/mac80211/patches/300-pending_work.patch index 2d46059c35..a1bb7023e9 100644 --- a/package/mac80211/patches/300-pending_work.patch +++ b/package/mac80211/patches/300-pending_work.patch @@ -623,3 +623,132 @@ BIT(NL80211_IFTYPE_WDS); rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -26,11 +26,11 @@ + /* Number of symbols for a packet with (bps) bits per symbol */ + #define MCS_NSYMS(bps) ((MCS_NBITS + (bps) - 1) / (bps)) + +-/* Transmission time for a packet containing (syms) symbols */ ++/* Transmission time (nanoseconds) for a packet containing (syms) symbols */ + #define MCS_SYMBOL_TIME(sgi, syms) \ + (sgi ? \ +- ((syms) * 18 + 4) / 5 : /* syms * 3.6 us */ \ +- (syms) << 2 /* syms * 4 us */ \ ++ ((syms) * 18000 + 4000) / 5 : /* syms * 3.6 us */ \ ++ ((syms) * 1000) << 2 /* syms * 4 us */ \ + ) + + /* Transmit duration for the raw data part of an average sized packet */ +@@ -64,9 +64,9 @@ + } + + #define CCK_DURATION(_bitrate, _short, _len) \ +- (10 /* SIFS */ + \ ++ (1000 * (10 /* SIFS */ + \ + (_short ? 72 + 24 : 144 + 48 ) + \ +- (8 * (_len + 4) * 10) / (_bitrate)) ++ (8 * (_len + 4) * 10) / (_bitrate))) + + #define CCK_ACK_DURATION(_bitrate, _short) \ + (CCK_DURATION((_bitrate > 10 ? 20 : 10), false, 60) + \ +@@ -211,7 +211,8 @@ static void + minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate) + { + struct minstrel_rate_stats *mr; +- unsigned int usecs = 0; ++ unsigned int nsecs = 0; ++ unsigned int tp; + + mr = &mi->groups[group].rates[rate]; + +@@ -221,10 +222,12 @@ minstrel_ht_calc_tp(struct minstrel_ht_s + } + + if (group != MINSTREL_CCK_GROUP) +- usecs = mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); ++ nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); + +- usecs += minstrel_mcs_groups[group].duration[rate]; +- mr->cur_tp = MINSTREL_TRUNC((1000000 / usecs) * mr->probability); ++ nsecs += minstrel_mcs_groups[group].duration[rate]; ++ tp = 1000000 * ((mr->probability * 1000) / nsecs); ++ ++ mr->cur_tp = MINSTREL_TRUNC(tp); + } + + /* +@@ -243,6 +246,7 @@ minstrel_ht_update_stats(struct minstrel + struct minstrel_rate_stats *mr; + int cur_prob, cur_prob_tp, cur_tp, cur_tp2; + int group, i, index; ++ int prob_max_streams = 1; + + if (mi->ampdu_packets > 0) { + mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, +@@ -308,8 +312,8 @@ minstrel_ht_update_stats(struct minstrel + } + } + +- /* try to sample up to half of the available rates during each interval */ +- mi->sample_count *= 4; ++ /* try to sample all available rates during each interval */ ++ mi->sample_count *= 8; + + cur_prob = 0; + cur_prob_tp = 0; +@@ -320,20 +324,13 @@ minstrel_ht_update_stats(struct minstrel + if (!mg->supported) + continue; + +- mr = minstrel_get_ratestats(mi, mg->max_prob_rate); +- if (cur_prob_tp < mr->cur_tp && +- minstrel_mcs_groups[group].streams == 1) { +- mi->max_prob_rate = mg->max_prob_rate; +- cur_prob = mr->cur_prob; +- cur_prob_tp = mr->cur_tp; +- } +- + mr = minstrel_get_ratestats(mi, mg->max_tp_rate); + if (cur_tp < mr->cur_tp) { + mi->max_tp_rate2 = mi->max_tp_rate; + cur_tp2 = cur_tp; + mi->max_tp_rate = mg->max_tp_rate; + cur_tp = mr->cur_tp; ++ prob_max_streams = minstrel_mcs_groups[group].streams - 1; + } + + mr = minstrel_get_ratestats(mi, mg->max_tp_rate2); +@@ -343,6 +340,23 @@ minstrel_ht_update_stats(struct minstrel + } + } + ++ if (prob_max_streams < 1) ++ prob_max_streams = 1; ++ ++ for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { ++ mg = &mi->groups[group]; ++ if (!mg->supported) ++ continue; ++ mr = minstrel_get_ratestats(mi, mg->max_prob_rate); ++ if (cur_prob_tp < mr->cur_tp && ++ minstrel_mcs_groups[group].streams <= prob_max_streams) { ++ mi->max_prob_rate = mg->max_prob_rate; ++ cur_prob = mr->cur_prob; ++ cur_prob_tp = mr->cur_tp; ++ } ++ } ++ ++ + mi->stats_update = jiffies; + } + +@@ -536,7 +550,7 @@ minstrel_calc_retransmit(struct minstrel + mr->retry_updated = true; + + 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 / 1000; + + /* Contention time for first 2 tries */ + ctime = (t_slot * cw) >> 1;