aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211')
-rw-r--r--package/kernel/mac80211/patches/343-mac80211-minstrel_ht-improve-sample-rate-skip-logic.patch77
1 files changed, 77 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/343-mac80211-minstrel_ht-improve-sample-rate-skip-logic.patch b/package/kernel/mac80211/patches/343-mac80211-minstrel_ht-improve-sample-rate-skip-logic.patch
new file mode 100644
index 0000000000..55ff817009
--- /dev/null
+++ b/package/kernel/mac80211/patches/343-mac80211-minstrel_ht-improve-sample-rate-skip-logic.patch
@@ -0,0 +1,77 @@
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Thu, 3 Mar 2016 23:20:06 +0100
+Subject: [PATCH] mac80211: minstrel_ht: improve sample rate skip logic
+
+There were a few issues that were slowing down the process of finding
+the optimal rate, especially on devices with multi-rate retry
+limitations:
+
+When max_tp_rate[0] was slower than max_tp_rate[1], the code did not
+sample max_tp_rate[1], which would often allow it to switch places with
+max_tp_rate[0] (e.g. if only the first sampling attempts were bad, but the
+rate is otherwise good).
+
+Also, sample attempts of rates between max_tp_rate[0] and [1] were being
+ignored in this case, because the code only checked if the rate was
+slower than [1].
+
+Fix this by checking against the fastest / second fastest max_tp_rate
+instead of assuming a specific order between the two.
+
+In my tests this patch significantly reduces the time until minstrel_ht
+finds the optimal rate right after assoc
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+---
+
+--- a/net/mac80211/rc80211_minstrel_ht.c
++++ b/net/mac80211/rc80211_minstrel_ht.c
+@@ -958,6 +958,7 @@ minstrel_get_sample_rate(struct minstrel
+ struct minstrel_rate_stats *mrs;
+ struct minstrel_mcs_group_data *mg;
+ unsigned int sample_dur, sample_group, cur_max_tp_streams;
++ int tp_rate1, tp_rate2;
+ int sample_idx = 0;
+
+ if (mi->sample_wait > 0) {
+@@ -979,14 +980,22 @@ minstrel_get_sample_rate(struct minstrel
+ mrs = &mg->rates[sample_idx];
+ sample_idx += sample_group * MCS_GROUP_RATES;
+
++ /* Set tp_rate1, tp_rate2 to the highest / second highest max_tp_rate */
++ if (minstrel_get_duration(mi->max_tp_rate[0]) >
++ minstrel_get_duration(mi->max_tp_rate[1])) {
++ tp_rate1 = mi->max_tp_rate[1];
++ tp_rate2 = mi->max_tp_rate[0];
++ } else {
++ tp_rate1 = mi->max_tp_rate[0];
++ tp_rate2 = mi->max_tp_rate[1];
++ }
++
+ /*
+ * Sampling might add some overhead (RTS, no aggregation)
+- * to the frame. Hence, don't use sampling for the currently
+- * used rates.
++ * to the frame. Hence, don't use sampling for the highest currently
++ * used highest throughput or probability rate.
+ */
+- if (sample_idx == mi->max_tp_rate[0] ||
+- sample_idx == mi->max_tp_rate[1] ||
+- sample_idx == mi->max_prob_rate)
++ if (sample_idx == mi->max_tp_rate[0] || sample_idx == mi->max_prob_rate)
+ return -1;
+
+ /*
+@@ -1001,10 +1010,10 @@ minstrel_get_sample_rate(struct minstrel
+ * if the link is working perfectly.
+ */
+
+- cur_max_tp_streams = minstrel_mcs_groups[mi->max_tp_rate[0] /
++ cur_max_tp_streams = minstrel_mcs_groups[tp_rate1 /
+ MCS_GROUP_RATES].streams;
+ sample_dur = minstrel_get_duration(sample_idx);
+- if (sample_dur >= minstrel_get_duration(mi->max_tp_rate[1]) &&
++ if (sample_dur >= minstrel_get_duration(tp_rate2) &&
+ (cur_max_tp_streams - 1 <
+ minstrel_mcs_groups[sample_group].streams ||
+ sample_dur >= minstrel_get_duration(mi->max_prob_rate))) {
/a> 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340