hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/net/mac80211/rc80211_minstrel_ht.c
....@@ -1,9 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2010-2013 Felix Fietkau <nbd@openwrt.org>
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License version 2 as
6
- * published by the Free Software Foundation.
4
+ * Copyright (C) 2019-2020 Intel Corporation
75 */
86 #include <linux/netdevice.h>
97 #include <linux/types.h>
....@@ -20,6 +18,8 @@
2018
2119 #define AVG_AMPDU_SIZE 16
2220 #define AVG_PKT_SIZE 1200
21
+
22
+#define SAMPLE_SWITCH_THR 100
2323
2424 /* Number of bits for an average sized packet */
2525 #define MCS_NBITS ((AVG_PKT_SIZE * AVG_AMPDU_SIZE) << 3)
....@@ -51,25 +51,39 @@
5151 MINSTREL_MAX_STREAMS * _sgi + \
5252 _streams - 1
5353
54
+#define _MAX(a, b) (((a)>(b))?(a):(b))
55
+
56
+#define GROUP_SHIFT(duration) \
57
+ _MAX(0, 16 - __builtin_clz(duration))
58
+
5459 /* MCS rate information for an MCS group */
55
-#define MCS_GROUP(_streams, _sgi, _ht40) \
60
+#define __MCS_GROUP(_streams, _sgi, _ht40, _s) \
5661 [GROUP_IDX(_streams, _sgi, _ht40)] = { \
5762 .streams = _streams, \
63
+ .shift = _s, \
64
+ .bw = _ht40, \
5865 .flags = \
5966 IEEE80211_TX_RC_MCS | \
6067 (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \
6168 (_ht40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \
6269 .duration = { \
63
- MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26), \
64
- MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52), \
65
- MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78), \
66
- MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104), \
67
- MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156), \
68
- MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208), \
69
- MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234), \
70
- MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) \
70
+ MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26) >> _s, \
71
+ MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52) >> _s, \
72
+ MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78) >> _s, \
73
+ MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104) >> _s, \
74
+ MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156) >> _s, \
75
+ MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208) >> _s, \
76
+ MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234) >> _s, \
77
+ MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) >> _s \
7178 } \
7279 }
80
+
81
+#define MCS_GROUP_SHIFT(_streams, _sgi, _ht40) \
82
+ GROUP_SHIFT(MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26))
83
+
84
+#define MCS_GROUP(_streams, _sgi, _ht40) \
85
+ __MCS_GROUP(_streams, _sgi, _ht40, \
86
+ MCS_GROUP_SHIFT(_streams, _sgi, _ht40))
7387
7488 #define VHT_GROUP_IDX(_streams, _sgi, _bw) \
7589 (MINSTREL_VHT_GROUP_0 + \
....@@ -80,9 +94,11 @@
8094 #define BW2VBPS(_bw, r3, r2, r1) \
8195 (_bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1)
8296
83
-#define VHT_GROUP(_streams, _sgi, _bw) \
97
+#define __VHT_GROUP(_streams, _sgi, _bw, _s) \
8498 [VHT_GROUP_IDX(_streams, _sgi, _bw)] = { \
8599 .streams = _streams, \
100
+ .shift = _s, \
101
+ .bw = _bw, \
86102 .flags = \
87103 IEEE80211_TX_RC_VHT_MCS | \
88104 (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \
....@@ -90,27 +106,35 @@
90106 _bw == BW_40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \
91107 .duration = { \
92108 MCS_DURATION(_streams, _sgi, \
93
- BW2VBPS(_bw, 117, 54, 26)), \
109
+ BW2VBPS(_bw, 117, 54, 26)) >> _s, \
94110 MCS_DURATION(_streams, _sgi, \
95
- BW2VBPS(_bw, 234, 108, 52)), \
111
+ BW2VBPS(_bw, 234, 108, 52)) >> _s, \
96112 MCS_DURATION(_streams, _sgi, \
97
- BW2VBPS(_bw, 351, 162, 78)), \
113
+ BW2VBPS(_bw, 351, 162, 78)) >> _s, \
98114 MCS_DURATION(_streams, _sgi, \
99
- BW2VBPS(_bw, 468, 216, 104)), \
115
+ BW2VBPS(_bw, 468, 216, 104)) >> _s, \
100116 MCS_DURATION(_streams, _sgi, \
101
- BW2VBPS(_bw, 702, 324, 156)), \
117
+ BW2VBPS(_bw, 702, 324, 156)) >> _s, \
102118 MCS_DURATION(_streams, _sgi, \
103
- BW2VBPS(_bw, 936, 432, 208)), \
119
+ BW2VBPS(_bw, 936, 432, 208)) >> _s, \
104120 MCS_DURATION(_streams, _sgi, \
105
- BW2VBPS(_bw, 1053, 486, 234)), \
121
+ BW2VBPS(_bw, 1053, 486, 234)) >> _s, \
106122 MCS_DURATION(_streams, _sgi, \
107
- BW2VBPS(_bw, 1170, 540, 260)), \
123
+ BW2VBPS(_bw, 1170, 540, 260)) >> _s, \
108124 MCS_DURATION(_streams, _sgi, \
109
- BW2VBPS(_bw, 1404, 648, 312)), \
125
+ BW2VBPS(_bw, 1404, 648, 312)) >> _s, \
110126 MCS_DURATION(_streams, _sgi, \
111
- BW2VBPS(_bw, 1560, 720, 346)) \
127
+ BW2VBPS(_bw, 1560, 720, 346)) >> _s \
112128 } \
113129 }
130
+
131
+#define VHT_GROUP_SHIFT(_streams, _sgi, _bw) \
132
+ GROUP_SHIFT(MCS_DURATION(_streams, _sgi, \
133
+ BW2VBPS(_bw, 117, 54, 26)))
134
+
135
+#define VHT_GROUP(_streams, _sgi, _bw) \
136
+ __VHT_GROUP(_streams, _sgi, _bw, \
137
+ VHT_GROUP_SHIFT(_streams, _sgi, _bw))
114138
115139 #define CCK_DURATION(_bitrate, _short, _len) \
116140 (1000 * (10 /* SIFS */ + \
....@@ -121,28 +145,33 @@
121145 (CCK_DURATION((_bitrate > 10 ? 20 : 10), false, 60) + \
122146 CCK_DURATION(_bitrate, _short, AVG_PKT_SIZE))
123147
124
-#define CCK_DURATION_LIST(_short) \
125
- CCK_ACK_DURATION(10, _short), \
126
- CCK_ACK_DURATION(20, _short), \
127
- CCK_ACK_DURATION(55, _short), \
128
- CCK_ACK_DURATION(110, _short)
148
+#define CCK_DURATION_LIST(_short, _s) \
149
+ CCK_ACK_DURATION(10, _short) >> _s, \
150
+ CCK_ACK_DURATION(20, _short) >> _s, \
151
+ CCK_ACK_DURATION(55, _short) >> _s, \
152
+ CCK_ACK_DURATION(110, _short) >> _s
129153
130
-#define CCK_GROUP \
154
+#define __CCK_GROUP(_s) \
131155 [MINSTREL_CCK_GROUP] = { \
132156 .streams = 1, \
133157 .flags = 0, \
158
+ .shift = _s, \
134159 .duration = { \
135
- CCK_DURATION_LIST(false), \
136
- CCK_DURATION_LIST(true) \
160
+ CCK_DURATION_LIST(false, _s), \
161
+ CCK_DURATION_LIST(true, _s) \
137162 } \
138163 }
139164
140
-#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
165
+#define CCK_GROUP_SHIFT \
166
+ GROUP_SHIFT(CCK_ACK_DURATION(10, false))
167
+
168
+#define CCK_GROUP __CCK_GROUP(CCK_GROUP_SHIFT)
169
+
170
+
141171 static bool minstrel_vht_only = true;
142172 module_param(minstrel_vht_only, bool, 0644);
143173 MODULE_PARM_DESC(minstrel_vht_only,
144174 "Use only VHT rates when VHT is supported by sta.");
145
-#endif
146175
147176 /*
148177 * To enable sufficiently targeted rate sampling, MCS rates are divided into
....@@ -156,46 +185,54 @@
156185 MCS_GROUP(1, 0, BW_20),
157186 MCS_GROUP(2, 0, BW_20),
158187 MCS_GROUP(3, 0, BW_20),
188
+ MCS_GROUP(4, 0, BW_20),
159189
160190 MCS_GROUP(1, 1, BW_20),
161191 MCS_GROUP(2, 1, BW_20),
162192 MCS_GROUP(3, 1, BW_20),
193
+ MCS_GROUP(4, 1, BW_20),
163194
164195 MCS_GROUP(1, 0, BW_40),
165196 MCS_GROUP(2, 0, BW_40),
166197 MCS_GROUP(3, 0, BW_40),
198
+ MCS_GROUP(4, 0, BW_40),
167199
168200 MCS_GROUP(1, 1, BW_40),
169201 MCS_GROUP(2, 1, BW_40),
170202 MCS_GROUP(3, 1, BW_40),
203
+ MCS_GROUP(4, 1, BW_40),
171204
172205 CCK_GROUP,
173206
174
-#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
175207 VHT_GROUP(1, 0, BW_20),
176208 VHT_GROUP(2, 0, BW_20),
177209 VHT_GROUP(3, 0, BW_20),
210
+ VHT_GROUP(4, 0, BW_20),
178211
179212 VHT_GROUP(1, 1, BW_20),
180213 VHT_GROUP(2, 1, BW_20),
181214 VHT_GROUP(3, 1, BW_20),
215
+ VHT_GROUP(4, 1, BW_20),
182216
183217 VHT_GROUP(1, 0, BW_40),
184218 VHT_GROUP(2, 0, BW_40),
185219 VHT_GROUP(3, 0, BW_40),
220
+ VHT_GROUP(4, 0, BW_40),
186221
187222 VHT_GROUP(1, 1, BW_40),
188223 VHT_GROUP(2, 1, BW_40),
189224 VHT_GROUP(3, 1, BW_40),
225
+ VHT_GROUP(4, 1, BW_40),
190226
191227 VHT_GROUP(1, 0, BW_80),
192228 VHT_GROUP(2, 0, BW_80),
193229 VHT_GROUP(3, 0, BW_80),
230
+ VHT_GROUP(4, 0, BW_80),
194231
195232 VHT_GROUP(1, 1, BW_80),
196233 VHT_GROUP(2, 1, BW_80),
197234 VHT_GROUP(3, 1, BW_80),
198
-#endif
235
+ VHT_GROUP(4, 1, BW_80),
199236 };
200237
201238 static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly;
....@@ -295,35 +332,45 @@
295332 return &mi->groups[index / MCS_GROUP_RATES].rates[index % MCS_GROUP_RATES];
296333 }
297334
335
+static unsigned int
336
+minstrel_ht_avg_ampdu_len(struct minstrel_ht_sta *mi)
337
+{
338
+ if (!mi->avg_ampdu_len)
339
+ return AVG_AMPDU_SIZE;
340
+
341
+ return MINSTREL_TRUNC(mi->avg_ampdu_len);
342
+}
343
+
298344 /*
299345 * Return current throughput based on the average A-MPDU length, taking into
300346 * account the expected number of retransmissions and their expected length
301347 */
302348 int
303349 minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate,
304
- int prob_ewma)
350
+ int prob_avg)
305351 {
306352 unsigned int nsecs = 0;
307353
308354 /* do not account throughput if sucess prob is below 10% */
309
- if (prob_ewma < MINSTREL_FRAC(10, 100))
355
+ if (prob_avg < MINSTREL_FRAC(10, 100))
310356 return 0;
311357
312358 if (group != MINSTREL_CCK_GROUP)
313
- nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len);
359
+ nsecs = 1000 * mi->overhead / minstrel_ht_avg_ampdu_len(mi);
314360
315
- nsecs += minstrel_mcs_groups[group].duration[rate];
361
+ nsecs += minstrel_mcs_groups[group].duration[rate] <<
362
+ minstrel_mcs_groups[group].shift;
316363
317364 /*
318365 * For the throughput calculation, limit the probability value to 90% to
319366 * account for collision related packet error rate fluctuation
320367 * (prob is scaled - see MINSTREL_FRAC above)
321368 */
322
- if (prob_ewma > MINSTREL_FRAC(90, 100))
369
+ if (prob_avg > MINSTREL_FRAC(90, 100))
323370 return MINSTREL_TRUNC(100000 * ((MINSTREL_FRAC(90, 100) * 1000)
324371 / nsecs));
325372 else
326
- return MINSTREL_TRUNC(100000 * ((prob_ewma * 1000) / nsecs));
373
+ return MINSTREL_TRUNC(100000 * ((prob_avg * 1000) / nsecs));
327374 }
328375
329376 /*
....@@ -343,13 +390,13 @@
343390
344391 cur_group = index / MCS_GROUP_RATES;
345392 cur_idx = index % MCS_GROUP_RATES;
346
- cur_prob = mi->groups[cur_group].rates[cur_idx].prob_ewma;
393
+ cur_prob = mi->groups[cur_group].rates[cur_idx].prob_avg;
347394 cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx, cur_prob);
348395
349396 do {
350397 tmp_group = tp_list[j - 1] / MCS_GROUP_RATES;
351398 tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES;
352
- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
399
+ tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
353400 tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx,
354401 tmp_prob);
355402 if (cur_tp_avg < tmp_tp_avg ||
....@@ -386,7 +433,7 @@
386433
387434 tmp_group = mi->max_prob_rate / MCS_GROUP_RATES;
388435 tmp_idx = mi->max_prob_rate % MCS_GROUP_RATES;
389
- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
436
+ tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
390437 tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
391438
392439 /* if max_tp_rate[0] is from MCS_GROUP max_prob_rate get selected from
....@@ -398,11 +445,11 @@
398445
399446 max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES;
400447 max_gpr_idx = mg->max_group_prob_rate % MCS_GROUP_RATES;
401
- max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_ewma;
448
+ max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg;
402449
403
- if (mrs->prob_ewma > MINSTREL_FRAC(75, 100)) {
450
+ if (mrs->prob_avg > MINSTREL_FRAC(75, 100)) {
404451 cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx,
405
- mrs->prob_ewma);
452
+ mrs->prob_avg);
406453 if (cur_tp_avg > tmp_tp_avg)
407454 mi->max_prob_rate = index;
408455
....@@ -412,9 +459,9 @@
412459 if (cur_tp_avg > max_gpr_tp_avg)
413460 mg->max_group_prob_rate = index;
414461 } else {
415
- if (mrs->prob_ewma > tmp_prob)
462
+ if (mrs->prob_avg > tmp_prob)
416463 mi->max_prob_rate = index;
417
- if (mrs->prob_ewma > max_gpr_prob)
464
+ if (mrs->prob_avg > max_gpr_prob)
418465 mg->max_group_prob_rate = index;
419466 }
420467 }
....@@ -436,12 +483,12 @@
436483
437484 tmp_group = tmp_cck_tp_rate[0] / MCS_GROUP_RATES;
438485 tmp_idx = tmp_cck_tp_rate[0] % MCS_GROUP_RATES;
439
- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
486
+ tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
440487 tmp_cck_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
441488
442489 tmp_group = tmp_mcs_tp_rate[0] / MCS_GROUP_RATES;
443490 tmp_idx = tmp_mcs_tp_rate[0] % MCS_GROUP_RATES;
444
- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
491
+ tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
445492 tmp_mcs_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
446493
447494 if (tmp_cck_tp > tmp_mcs_tp) {
....@@ -472,7 +519,7 @@
472519 continue;
473520
474521 tmp_idx = mg->max_group_prob_rate % MCS_GROUP_RATES;
475
- tmp_prob = mi->groups[group].rates[tmp_idx].prob_ewma;
522
+ tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg;
476523
477524 if (tmp_tp < minstrel_ht_get_tp_avg(mi, group, tmp_idx, tmp_prob) &&
478525 (minstrel_mcs_groups[group].streams < tmp_max_streams)) {
....@@ -482,6 +529,133 @@
482529 tmp_prob);
483530 }
484531 }
532
+}
533
+
534
+static inline int
535
+minstrel_get_duration(int index)
536
+{
537
+ const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
538
+ unsigned int duration = group->duration[index % MCS_GROUP_RATES];
539
+ return duration << group->shift;
540
+}
541
+
542
+static bool
543
+minstrel_ht_probe_group(struct minstrel_ht_sta *mi, const struct mcs_group *tp_group,
544
+ int tp_idx, const struct mcs_group *group)
545
+{
546
+ if (group->bw < tp_group->bw)
547
+ return false;
548
+
549
+ if (group->streams == tp_group->streams)
550
+ return true;
551
+
552
+ if (tp_idx < 4 && group->streams == tp_group->streams - 1)
553
+ return true;
554
+
555
+ return group->streams == tp_group->streams + 1;
556
+}
557
+
558
+static void
559
+minstrel_ht_find_probe_rates(struct minstrel_ht_sta *mi, u16 *rates, int *n_rates,
560
+ bool faster_rate)
561
+{
562
+ const struct mcs_group *group, *tp_group;
563
+ int i, g, max_dur;
564
+ int tp_idx;
565
+
566
+ tp_group = &minstrel_mcs_groups[mi->max_tp_rate[0] / MCS_GROUP_RATES];
567
+ tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES;
568
+
569
+ max_dur = minstrel_get_duration(mi->max_tp_rate[0]);
570
+ if (faster_rate)
571
+ max_dur -= max_dur / 16;
572
+
573
+ for (g = 0; g < MINSTREL_GROUPS_NB; g++) {
574
+ u16 supported = mi->supported[g];
575
+
576
+ if (!supported)
577
+ continue;
578
+
579
+ group = &minstrel_mcs_groups[g];
580
+ if (!minstrel_ht_probe_group(mi, tp_group, tp_idx, group))
581
+ continue;
582
+
583
+ for (i = 0; supported; supported >>= 1, i++) {
584
+ int idx;
585
+
586
+ if (!(supported & 1))
587
+ continue;
588
+
589
+ if ((group->duration[i] << group->shift) > max_dur)
590
+ continue;
591
+
592
+ idx = g * MCS_GROUP_RATES + i;
593
+ if (idx == mi->max_tp_rate[0])
594
+ continue;
595
+
596
+ rates[(*n_rates)++] = idx;
597
+ break;
598
+ }
599
+ }
600
+}
601
+
602
+static void
603
+minstrel_ht_rate_sample_switch(struct minstrel_priv *mp,
604
+ struct minstrel_ht_sta *mi)
605
+{
606
+ struct minstrel_rate_stats *mrs;
607
+ u16 rates[MINSTREL_GROUPS_NB];
608
+ int n_rates = 0;
609
+ int probe_rate = 0;
610
+ bool faster_rate;
611
+ int i;
612
+ u8 random;
613
+
614
+ /*
615
+ * Use rate switching instead of probing packets for devices with
616
+ * little control over retry fallback behavior
617
+ */
618
+ if (mp->hw->max_rates > 1)
619
+ return;
620
+
621
+ /*
622
+ * If the current EWMA prob is >75%, look for a rate that's 6.25%
623
+ * faster than the max tp rate.
624
+ * If that fails, look again for a rate that is at least as fast
625
+ */
626
+ mrs = minstrel_get_ratestats(mi, mi->max_tp_rate[0]);
627
+ faster_rate = mrs->prob_avg > MINSTREL_FRAC(75, 100);
628
+ minstrel_ht_find_probe_rates(mi, rates, &n_rates, faster_rate);
629
+ if (!n_rates && faster_rate)
630
+ minstrel_ht_find_probe_rates(mi, rates, &n_rates, false);
631
+
632
+ /* If no suitable rate was found, try to pick the next one in the group */
633
+ if (!n_rates) {
634
+ int g_idx = mi->max_tp_rate[0] / MCS_GROUP_RATES;
635
+ u16 supported = mi->supported[g_idx];
636
+
637
+ supported >>= mi->max_tp_rate[0] % MCS_GROUP_RATES;
638
+ for (i = 0; supported; supported >>= 1, i++) {
639
+ if (!(supported & 1))
640
+ continue;
641
+
642
+ probe_rate = mi->max_tp_rate[0] + i;
643
+ goto out;
644
+ }
645
+
646
+ return;
647
+ }
648
+
649
+ i = 0;
650
+ if (n_rates > 1) {
651
+ random = prandom_u32();
652
+ i = random % n_rates;
653
+ }
654
+ probe_rate = rates[i];
655
+
656
+out:
657
+ mi->sample_rate = probe_rate;
658
+ mi->sample_mode = MINSTREL_SAMPLE_ACTIVE;
485659 }
486660
487661 /*
....@@ -494,7 +668,8 @@
494668 * higher throughput rates, even if the probablity is a bit lower
495669 */
496670 static void
497
-minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
671
+minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
672
+ bool sample)
498673 {
499674 struct minstrel_mcs_group_data *mg;
500675 struct minstrel_rate_stats *mrs;
....@@ -502,9 +677,25 @@
502677 u16 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES];
503678 u16 tmp_cck_tp_rate[MAX_THR_RATES], index;
504679
680
+ mi->sample_mode = MINSTREL_SAMPLE_IDLE;
681
+
682
+ if (sample) {
683
+ mi->total_packets_cur = mi->total_packets -
684
+ mi->total_packets_last;
685
+ mi->total_packets_last = mi->total_packets;
686
+ }
687
+ if (!mp->sample_switch)
688
+ sample = false;
689
+ if (mi->total_packets_cur < SAMPLE_SWITCH_THR && mp->sample_switch != 1)
690
+ sample = false;
691
+
505692 if (mi->ampdu_packets > 0) {
506
- mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len,
507
- MINSTREL_FRAC(mi->ampdu_len, mi->ampdu_packets), EWMA_LEVEL);
693
+ if (!ieee80211_hw_check(mp->hw, TX_STATUS_NO_AMPDU_LEN))
694
+ mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len,
695
+ MINSTREL_FRAC(mi->ampdu_len, mi->ampdu_packets),
696
+ EWMA_LEVEL);
697
+ else
698
+ mi->avg_ampdu_len = 0;
508699 mi->ampdu_len = 0;
509700 mi->ampdu_packets = 0;
510701 }
....@@ -512,11 +703,19 @@
512703 mi->sample_slow = 0;
513704 mi->sample_count = 0;
514705
515
- /* Initialize global rate indexes */
516
- for(j = 0; j < MAX_THR_RATES; j++){
517
- tmp_mcs_tp_rate[j] = 0;
518
- tmp_cck_tp_rate[j] = 0;
519
- }
706
+ memset(tmp_mcs_tp_rate, 0, sizeof(tmp_mcs_tp_rate));
707
+ memset(tmp_cck_tp_rate, 0, sizeof(tmp_cck_tp_rate));
708
+ if (mi->supported[MINSTREL_CCK_GROUP])
709
+ for (j = 0; j < ARRAY_SIZE(tmp_cck_tp_rate); j++)
710
+ tmp_cck_tp_rate[j] = MINSTREL_CCK_GROUP * MCS_GROUP_RATES;
711
+
712
+ if (mi->supported[MINSTREL_VHT_GROUP_0])
713
+ index = MINSTREL_VHT_GROUP_0 * MCS_GROUP_RATES;
714
+ else
715
+ index = MINSTREL_HT_GROUP_0 * MCS_GROUP_RATES;
716
+
717
+ for (j = 0; j < ARRAY_SIZE(tmp_mcs_tp_rate); j++)
718
+ tmp_mcs_tp_rate[j] = index;
520719
521720 /* Find best rate sets within all MCS groups*/
522721 for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) {
....@@ -539,8 +738,8 @@
539738
540739 mrs = &mg->rates[i];
541740 mrs->retry_updated = false;
542
- minstrel_calc_rate_stats(mrs);
543
- cur_prob = mrs->prob_ewma;
741
+ minstrel_calc_rate_stats(mp, mrs);
742
+ cur_prob = mrs->prob_avg;
544743
545744 if (minstrel_ht_get_tp_avg(mi, group, i, cur_prob) == 0)
546745 continue;
....@@ -575,6 +774,11 @@
575774
576775 /* try to sample all available rates during each interval */
577776 mi->sample_count *= 8;
777
+ if (mp->new_avg)
778
+ mi->sample_count /= 2;
779
+
780
+ if (sample)
781
+ minstrel_ht_rate_sample_switch(mp, mi);
578782
579783 #ifdef CONFIG_MAC80211_DEBUGFS
580784 /* use fixed index if set */
....@@ -582,6 +786,7 @@
582786 for (i = 0; i < 4; i++)
583787 mi->max_tp_rate[i] = mp->fixed_rate_idx;
584788 mi->max_prob_rate = mp->fixed_rate_idx;
789
+ mi->sample_mode = MINSTREL_SAMPLE_IDLE;
585790 }
586791 #endif
587792
....@@ -685,14 +890,17 @@
685890 struct minstrel_ht_sta_priv *msp = priv_sta;
686891 struct minstrel_ht_sta *mi = &msp->ht;
687892 struct ieee80211_tx_rate *ar = info->status.rates;
688
- struct minstrel_rate_stats *rate, *rate2;
893
+ struct minstrel_rate_stats *rate, *rate2, *rate_sample = NULL;
689894 struct minstrel_priv *mp = priv;
895
+ u32 update_interval = mp->update_interval / 2;
690896 bool last, update = false;
897
+ bool sample_status = false;
691898 int i;
692899
693900 if (!msp->is_ht)
694901 return mac80211_minstrel.tx_status_ext(priv, sband,
695902 &msp->legacy, st);
903
+
696904
697905 /* This packet was aggregated but doesn't carry status info */
698906 if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
....@@ -709,7 +917,9 @@
709917 mi->ampdu_len += info->status.ampdu_len;
710918
711919 if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) {
712
- mi->sample_wait = 16 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len);
920
+ int avg_ampdu_len = minstrel_ht_avg_ampdu_len(mi);
921
+
922
+ mi->sample_wait = 16 + 2 * avg_ampdu_len;
713923 mi->sample_tries = 1;
714924 mi->sample_count--;
715925 }
....@@ -717,12 +927,17 @@
717927 if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
718928 mi->sample_packets += info->status.ampdu_len;
719929
930
+ if (mi->sample_mode != MINSTREL_SAMPLE_IDLE)
931
+ rate_sample = minstrel_get_ratestats(mi, mi->sample_rate);
932
+
720933 last = !minstrel_ht_txstat_valid(mp, &ar[0]);
721934 for (i = 0; !last; i++) {
722935 last = (i == IEEE80211_TX_MAX_RATES - 1) ||
723936 !minstrel_ht_txstat_valid(mp, &ar[i + 1]);
724937
725938 rate = minstrel_ht_get_stats(mp, mi, &ar[i]);
939
+ if (rate == rate_sample)
940
+ sample_status = true;
726941
727942 if (last)
728943 rate->success += info->status.ampdu_ack_len;
....@@ -730,30 +945,55 @@
730945 rate->attempts += ar[i].count * info->status.ampdu_len;
731946 }
732947
733
- /*
734
- * check for sudden death of spatial multiplexing,
735
- * downgrade to a lower number of streams if necessary.
736
- */
737
- rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]);
738
- if (rate->attempts > 30 &&
739
- MINSTREL_FRAC(rate->success, rate->attempts) <
740
- MINSTREL_FRAC(20, 100)) {
741
- minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true);
948
+ switch (mi->sample_mode) {
949
+ case MINSTREL_SAMPLE_IDLE:
950
+ if (mp->new_avg &&
951
+ (mp->hw->max_rates > 1 ||
952
+ mi->total_packets_cur < SAMPLE_SWITCH_THR))
953
+ update_interval /= 2;
954
+ break;
955
+
956
+ case MINSTREL_SAMPLE_ACTIVE:
957
+ if (!sample_status)
958
+ break;
959
+
960
+ mi->sample_mode = MINSTREL_SAMPLE_PENDING;
742961 update = true;
962
+ break;
963
+
964
+ case MINSTREL_SAMPLE_PENDING:
965
+ if (sample_status)
966
+ break;
967
+
968
+ update = true;
969
+ minstrel_ht_update_stats(mp, mi, false);
970
+ break;
743971 }
744972
745
- rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]);
746
- if (rate2->attempts > 30 &&
747
- MINSTREL_FRAC(rate2->success, rate2->attempts) <
748
- MINSTREL_FRAC(20, 100)) {
749
- minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false);
750
- update = true;
973
+
974
+ if (mp->hw->max_rates > 1) {
975
+ /*
976
+ * check for sudden death of spatial multiplexing,
977
+ * downgrade to a lower number of streams if necessary.
978
+ */
979
+ rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]);
980
+ if (rate->attempts > 30 &&
981
+ rate->success < rate->attempts / 4) {
982
+ minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true);
983
+ update = true;
984
+ }
985
+
986
+ rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]);
987
+ if (rate2->attempts > 30 &&
988
+ rate2->success < rate2->attempts / 4) {
989
+ minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false);
990
+ update = true;
991
+ }
751992 }
752993
753
- if (time_after(jiffies, mi->last_stats_update +
754
- (mp->update_interval / 2 * HZ) / 1000)) {
994
+ if (time_after(jiffies, mi->last_stats_update + update_interval)) {
755995 update = true;
756
- minstrel_ht_update_stats(mp, mi);
996
+ minstrel_ht_update_stats(mp, mi, true);
757997 }
758998
759999 if (update)
....@@ -765,16 +1005,15 @@
7651005 int index)
7661006 {
7671007 struct minstrel_rate_stats *mrs;
768
- const struct mcs_group *group;
7691008 unsigned int tx_time, tx_time_rtscts, tx_time_data;
7701009 unsigned int cw = mp->cw_min;
7711010 unsigned int ctime = 0;
7721011 unsigned int t_slot = 9; /* FIXME */
773
- unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len);
1012
+ unsigned int ampdu_len = minstrel_ht_avg_ampdu_len(mi);
7741013 unsigned int overhead = 0, overhead_rtscts = 0;
7751014
7761015 mrs = minstrel_get_ratestats(mi, index);
777
- if (mrs->prob_ewma < MINSTREL_FRAC(1, 10)) {
1016
+ if (mrs->prob_avg < MINSTREL_FRAC(1, 10)) {
7781017 mrs->retry_count = 1;
7791018 mrs->retry_count_rtscts = 1;
7801019 return;
....@@ -784,8 +1023,7 @@
7841023 mrs->retry_count_rtscts = 2;
7851024 mrs->retry_updated = true;
7861025
787
- group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
788
- tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len / 1000;
1026
+ tx_time_data = minstrel_get_duration(index) * ampdu_len / 1000;
7891027
7901028 /* Contention time for first 2 tries */
7911029 ctime = (t_slot * cw) >> 1;
....@@ -832,7 +1070,7 @@
8321070 if (!mrs->retry_updated)
8331071 minstrel_calc_retransmit(mp, mi, index);
8341072
835
- if (mrs->prob_ewma < MINSTREL_FRAC(20, 100) || !mrs->retry_count) {
1073
+ if (mrs->prob_avg < MINSTREL_FRAC(20, 100) || !mrs->retry_count) {
8361074 ratetbl->rate[offset].count = 2;
8371075 ratetbl->rate[offset].count_rts = 2;
8381076 ratetbl->rate[offset].count_cts = 2;
....@@ -866,11 +1104,11 @@
8661104 }
8671105
8681106 static inline int
869
-minstrel_ht_get_prob_ewma(struct minstrel_ht_sta *mi, int rate)
1107
+minstrel_ht_get_prob_avg(struct minstrel_ht_sta *mi, int rate)
8701108 {
8711109 int group = rate / MCS_GROUP_RATES;
8721110 rate %= MCS_GROUP_RATES;
873
- return mi->groups[group].rates[rate].prob_ewma;
1111
+ return mi->groups[group].rates[rate].prob_avg;
8741112 }
8751113
8761114 static int
....@@ -879,20 +1117,24 @@
8791117 int group = mi->max_prob_rate / MCS_GROUP_RATES;
8801118 const struct mcs_group *g = &minstrel_mcs_groups[group];
8811119 int rate = mi->max_prob_rate % MCS_GROUP_RATES;
1120
+ unsigned int duration;
8821121
8831122 /* Disable A-MSDU if max_prob_rate is bad */
884
- if (mi->groups[group].rates[rate].prob_ewma < MINSTREL_FRAC(50, 100))
1123
+ if (mi->groups[group].rates[rate].prob_avg < MINSTREL_FRAC(50, 100))
8851124 return 1;
8861125
1126
+ duration = g->duration[rate];
1127
+ duration <<= g->shift;
1128
+
8871129 /* If the rate is slower than single-stream MCS1, make A-MSDU limit small */
888
- if (g->duration[rate] > MCS_DURATION(1, 0, 52))
1130
+ if (duration > MCS_DURATION(1, 0, 52))
8891131 return 500;
8901132
8911133 /*
8921134 * If the rate is slower than single-stream MCS4, limit A-MSDU to usual
8931135 * data packet size
8941136 */
895
- if (g->duration[rate] > MCS_DURATION(1, 0, 104))
1137
+ if (duration > MCS_DURATION(1, 0, 104))
8961138 return 1600;
8971139
8981140 /*
....@@ -900,8 +1142,8 @@
9001142 * rate success probability is less than 75%, limit A-MSDU to twice the usual
9011143 * data packet size
9021144 */
903
- if (g->duration[rate] > MCS_DURATION(1, 0, 260) ||
904
- (minstrel_ht_get_prob_ewma(mi, mi->max_tp_rate[0]) <
1145
+ if (duration > MCS_DURATION(1, 0, 260) ||
1146
+ (minstrel_ht_get_prob_avg(mi, mi->max_tp_rate[0]) <
9051147 MINSTREL_FRAC(75, 100)))
9061148 return 3200;
9071149
....@@ -922,14 +1164,18 @@
9221164 minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
9231165 {
9241166 struct ieee80211_sta_rates *rates;
1167
+ u16 first_rate = mi->max_tp_rate[0];
9251168 int i = 0;
1169
+
1170
+ if (mi->sample_mode == MINSTREL_SAMPLE_ACTIVE)
1171
+ first_rate = mi->sample_rate;
9261172
9271173 rates = kzalloc(sizeof(*rates), GFP_ATOMIC);
9281174 if (!rates)
9291175 return;
9301176
9311177 /* Start with max_tp_rate[0] */
932
- minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate[0]);
1178
+ minstrel_ht_set_rate(mp, mi, rates, i++, first_rate);
9331179
9341180 if (mp->hw->max_rates >= 3) {
9351181 /* At least 3 tx rates supported, use max_tp_rate[1] next */
....@@ -937,21 +1183,12 @@
9371183 }
9381184
9391185 if (mp->hw->max_rates >= 2) {
940
- /*
941
- * At least 2 tx rates supported, use max_prob_rate next */
9421186 minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_prob_rate);
9431187 }
9441188
9451189 mi->sta->max_rc_amsdu_len = minstrel_ht_get_max_amsdu_len(mi);
9461190 rates->rate[i].idx = -1;
9471191 rate_control_set_rates(mp->hw, mi->sta, rates);
948
-}
949
-
950
-static inline int
951
-minstrel_get_duration(int index)
952
-{
953
- const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
954
- return group->duration[index % MCS_GROUP_RATES];
9551192 }
9561193
9571194 static int
....@@ -962,6 +1199,11 @@
9621199 unsigned int sample_dur, sample_group, cur_max_tp_streams;
9631200 int tp_rate1, tp_rate2;
9641201 int sample_idx = 0;
1202
+
1203
+ if (mp->hw->max_rates == 1 && mp->sample_switch &&
1204
+ (mi->total_packets_cur >= SAMPLE_SWITCH_THR ||
1205
+ mp->sample_switch == 1))
1206
+ return -1;
9651207
9661208 if (mi->sample_wait > 0) {
9671209 mi->sample_wait--;
....@@ -1001,10 +1243,28 @@
10011243 return -1;
10021244
10031245 /*
1004
- * Do not sample if the probability is already higher than 95%
1005
- * to avoid wasting airtime.
1246
+ * Do not sample if the probability is already higher than 95%,
1247
+ * or if the rate is 3 times slower than the current max probability
1248
+ * rate, to avoid wasting airtime.
10061249 */
1007
- if (mrs->prob_ewma > MINSTREL_FRAC(95, 100))
1250
+ sample_dur = minstrel_get_duration(sample_idx);
1251
+ if (mrs->prob_avg > MINSTREL_FRAC(95, 100) ||
1252
+ minstrel_get_duration(mi->max_prob_rate) * 3 < sample_dur)
1253
+ return -1;
1254
+
1255
+
1256
+ /*
1257
+ * For devices with no configurable multi-rate retry, skip sampling
1258
+ * below the per-group max throughput rate, and only use one sampling
1259
+ * attempt per rate
1260
+ */
1261
+ if (mp->hw->max_rates == 1 &&
1262
+ (minstrel_get_duration(mg->max_group_tp_rate[0]) < sample_dur ||
1263
+ mrs->attempts))
1264
+ return -1;
1265
+
1266
+ /* Skip already sampled slow rates */
1267
+ if (sample_dur >= minstrel_get_duration(tp_rate1) && mrs->attempts)
10081268 return -1;
10091269
10101270 /*
....@@ -1014,7 +1274,6 @@
10141274
10151275 cur_max_tp_streams = minstrel_mcs_groups[tp_rate1 /
10161276 MCS_GROUP_RATES].streams;
1017
- sample_dur = minstrel_get_duration(sample_idx);
10181277 if (sample_dur >= minstrel_get_duration(tp_rate2) &&
10191278 (cur_max_tp_streams - 1 <
10201279 minstrel_mcs_groups[sample_group].streams ||
....@@ -1041,9 +1300,6 @@
10411300 struct minstrel_ht_sta *mi = &msp->ht;
10421301 struct minstrel_priv *mp = priv;
10431302 int sample_idx;
1044
-
1045
- if (rate_control_send_low(sta, priv_sta, txrc))
1046
- return;
10471303
10481304 if (!msp->is_ht)
10491305 return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc);
....@@ -1136,13 +1392,14 @@
11361392 struct minstrel_ht_sta_priv *msp = priv_sta;
11371393 struct minstrel_ht_sta *mi = &msp->ht;
11381394 struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs;
1139
- u16 sta_cap = sta->ht_cap.cap;
1395
+ u16 ht_cap = sta->ht_cap.cap;
11401396 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
11411397 int use_vht;
11421398 int n_supported = 0;
11431399 int ack_dur;
11441400 int stbc;
11451401 int i;
1402
+ bool ldpc;
11461403
11471404 /* fall back to the old minstrel for legacy stations */
11481405 if (!sta->ht_cap.ht_supported)
....@@ -1150,12 +1407,10 @@
11501407
11511408 BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != MINSTREL_GROUPS_NB);
11521409
1153
-#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
11541410 if (vht_cap->vht_supported)
11551411 use_vht = vht_cap->vht_mcs.tx_mcs_map != cpu_to_le16(~0);
11561412 else
1157
-#endif
1158
- use_vht = 0;
1413
+ use_vht = 0;
11591414
11601415 msp->is_ht = true;
11611416 memset(mi, 0, sizeof(*mi));
....@@ -1180,15 +1435,21 @@
11801435 }
11811436 mi->sample_tries = 4;
11821437
1183
- /* TODO tx_flags for vht - ATM the RC API is not fine-grained enough */
11841438 if (!use_vht) {
1185
- stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >>
1439
+ stbc = (ht_cap & IEEE80211_HT_CAP_RX_STBC) >>
11861440 IEEE80211_HT_CAP_RX_STBC_SHIFT;
1187
- mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT;
11881441
1189
- if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING)
1190
- mi->tx_flags |= IEEE80211_TX_CTL_LDPC;
1442
+ ldpc = ht_cap & IEEE80211_HT_CAP_LDPC_CODING;
1443
+ } else {
1444
+ stbc = (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK) >>
1445
+ IEEE80211_VHT_CAP_RXSTBC_SHIFT;
1446
+
1447
+ ldpc = vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC;
11911448 }
1449
+
1450
+ mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT;
1451
+ if (ldpc)
1452
+ mi->tx_flags |= IEEE80211_TX_CTL_LDPC;
11921453
11931454 for (i = 0; i < ARRAY_SIZE(mi->groups); i++) {
11941455 u32 gflags = minstrel_mcs_groups[i].flags;
....@@ -1202,10 +1463,10 @@
12021463
12031464 if (gflags & IEEE80211_TX_RC_SHORT_GI) {
12041465 if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
1205
- if (!(sta_cap & IEEE80211_HT_CAP_SGI_40))
1466
+ if (!(ht_cap & IEEE80211_HT_CAP_SGI_40))
12061467 continue;
12071468 } else {
1208
- if (!(sta_cap & IEEE80211_HT_CAP_SGI_20))
1469
+ if (!(ht_cap & IEEE80211_HT_CAP_SGI_20))
12091470 continue;
12101471 }
12111472 }
....@@ -1222,10 +1483,9 @@
12221483
12231484 /* HT rate */
12241485 if (gflags & IEEE80211_TX_RC_MCS) {
1225
-#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
12261486 if (use_vht && minstrel_vht_only)
12271487 continue;
1228
-#endif
1488
+
12291489 mi->supported[i] = mcs->rx_mask[nss - 1];
12301490 if (mi->supported[i])
12311491 n_supported++;
....@@ -1266,7 +1526,7 @@
12661526 mi->supported[MINSTREL_CCK_GROUP] |= mi->cck_supported_short << 4;
12671527
12681528 /* create an initial rate table with the lowest supported rates */
1269
- minstrel_ht_update_stats(mp, mi);
1529
+ minstrel_ht_update_stats(mp, mi, true);
12701530 minstrel_ht_update_rates(mp, mi);
12711531
12721532 return;
....@@ -1344,16 +1604,101 @@
13441604 kfree(msp);
13451605 }
13461606
1347
-static void *
1348
-minstrel_ht_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
1607
+static void
1608
+minstrel_ht_init_cck_rates(struct minstrel_priv *mp)
13491609 {
1350
- return mac80211_minstrel.alloc(hw, debugfsdir);
1610
+ static const int bitrates[4] = { 10, 20, 55, 110 };
1611
+ struct ieee80211_supported_band *sband;
1612
+ u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef);
1613
+ int i, j;
1614
+
1615
+ sband = mp->hw->wiphy->bands[NL80211_BAND_2GHZ];
1616
+ if (!sband)
1617
+ return;
1618
+
1619
+ for (i = 0; i < sband->n_bitrates; i++) {
1620
+ struct ieee80211_rate *rate = &sband->bitrates[i];
1621
+
1622
+ if (rate->flags & IEEE80211_RATE_ERP_G)
1623
+ continue;
1624
+
1625
+ if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
1626
+ continue;
1627
+
1628
+ for (j = 0; j < ARRAY_SIZE(bitrates); j++) {
1629
+ if (rate->bitrate != bitrates[j])
1630
+ continue;
1631
+
1632
+ mp->cck_rates[j] = i;
1633
+ break;
1634
+ }
1635
+ }
13511636 }
1637
+
1638
+static void *
1639
+minstrel_ht_alloc(struct ieee80211_hw *hw)
1640
+{
1641
+ struct minstrel_priv *mp;
1642
+
1643
+ mp = kzalloc(sizeof(struct minstrel_priv), GFP_ATOMIC);
1644
+ if (!mp)
1645
+ return NULL;
1646
+
1647
+ mp->sample_switch = -1;
1648
+
1649
+ /* contention window settings
1650
+ * Just an approximation. Using the per-queue values would complicate
1651
+ * the calculations and is probably unnecessary */
1652
+ mp->cw_min = 15;
1653
+ mp->cw_max = 1023;
1654
+
1655
+ /* number of packets (in %) to use for sampling other rates
1656
+ * sample less often for non-mrr packets, because the overhead
1657
+ * is much higher than with mrr */
1658
+ mp->lookaround_rate = 5;
1659
+ mp->lookaround_rate_mrr = 10;
1660
+
1661
+ /* maximum time that the hw is allowed to stay in one MRR segment */
1662
+ mp->segment_size = 6000;
1663
+
1664
+ if (hw->max_rate_tries > 0)
1665
+ mp->max_retry = hw->max_rate_tries;
1666
+ else
1667
+ /* safe default, does not necessarily have to match hw properties */
1668
+ mp->max_retry = 7;
1669
+
1670
+ if (hw->max_rates >= 4)
1671
+ mp->has_mrr = true;
1672
+
1673
+ mp->hw = hw;
1674
+ mp->update_interval = HZ / 10;
1675
+ mp->new_avg = true;
1676
+
1677
+ minstrel_ht_init_cck_rates(mp);
1678
+
1679
+ return mp;
1680
+}
1681
+
1682
+#ifdef CONFIG_MAC80211_DEBUGFS
1683
+static void minstrel_ht_add_debugfs(struct ieee80211_hw *hw, void *priv,
1684
+ struct dentry *debugfsdir)
1685
+{
1686
+ struct minstrel_priv *mp = priv;
1687
+
1688
+ mp->fixed_rate_idx = (u32) -1;
1689
+ debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir,
1690
+ &mp->fixed_rate_idx);
1691
+ debugfs_create_u32("sample_switch", S_IRUGO | S_IWUSR, debugfsdir,
1692
+ &mp->sample_switch);
1693
+ debugfs_create_bool("new_avg", S_IRUGO | S_IWUSR, debugfsdir,
1694
+ &mp->new_avg);
1695
+}
1696
+#endif
13521697
13531698 static void
13541699 minstrel_ht_free(void *priv)
13551700 {
1356
- mac80211_minstrel.free(priv);
1701
+ kfree(priv);
13571702 }
13581703
13591704 static u32 minstrel_ht_get_expected_throughput(void *priv_sta)
....@@ -1367,7 +1712,7 @@
13671712
13681713 i = mi->max_tp_rate[0] / MCS_GROUP_RATES;
13691714 j = mi->max_tp_rate[0] % MCS_GROUP_RATES;
1370
- prob = mi->groups[i].rates[j].prob_ewma;
1715
+ prob = mi->groups[i].rates[j].prob_avg;
13711716
13721717 /* convert tp_avg from pkt per second in kbps */
13731718 tp_avg = minstrel_ht_get_tp_avg(mi, i, j, prob) * 10;
....@@ -1387,8 +1732,8 @@
13871732 .alloc = minstrel_ht_alloc,
13881733 .free = minstrel_ht_free,
13891734 #ifdef CONFIG_MAC80211_DEBUGFS
1735
+ .add_debugfs = minstrel_ht_add_debugfs,
13901736 .add_sta_debugfs = minstrel_ht_add_sta_debugfs,
1391
- .remove_sta_debugfs = minstrel_ht_remove_sta_debugfs,
13921737 #endif
13931738 .get_expected_throughput = minstrel_ht_get_expected_throughput,
13941739 };
....@@ -1413,14 +1758,14 @@
14131758 }
14141759
14151760 int __init
1416
-rc80211_minstrel_ht_init(void)
1761
+rc80211_minstrel_init(void)
14171762 {
14181763 init_sample_table();
14191764 return ieee80211_rate_control_register(&mac80211_minstrel_ht);
14201765 }
14211766
14221767 void
1423
-rc80211_minstrel_ht_exit(void)
1768
+rc80211_minstrel_exit(void)
14241769 {
14251770 ieee80211_rate_control_unregister(&mac80211_minstrel_ht);
14261771 }