blob: 0dbfa9d4fb430e9d0f230e8d27d569a1e3aec6f8 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From: Felix Fietkau <nbd@nbd.name>
2Date: Sat, 26 Dec 2020 19:09:08 +0100
3Subject: [PATCH] mac80211: minstrel_ht: fix max probability rate selection
4
5- do not select rates faster than the max throughput rate if probability is lower
6- reset previous rate before sorting again
7
8This ensures that the max prob rate gets set to a more reliable rate
9
10Signed-off-by: Felix Fietkau <nbd@nbd.name>
11---
12
13--- a/net/mac80211/rc80211_minstrel_ht.c
14+++ b/net/mac80211/rc80211_minstrel_ht.c
15@@ -495,12 +495,13 @@ minstrel_ht_sort_best_tp_rates(struct mi
16 * Find and set the topmost probability rate per sta and per group
17 */
18 static void
19-minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 index)
20+minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 *dest, u16 index)
21 {
22 struct minstrel_mcs_group_data *mg;
23 struct minstrel_rate_stats *mrs;
24 int tmp_group, tmp_idx, tmp_tp_avg, tmp_prob;
25- int max_tp_group, cur_tp_avg, cur_group, cur_idx;
26+ int max_tp_group, max_tp_idx, max_tp_prob;
27+ int cur_tp_avg, cur_group, cur_idx;
28 int max_gpr_group, max_gpr_idx;
29 int max_gpr_tp_avg, max_gpr_prob;
30
31@@ -509,18 +510,26 @@ minstrel_ht_set_best_prob_rate(struct mi
32 mg = &mi->groups[index / MCS_GROUP_RATES];
33 mrs = &mg->rates[index % MCS_GROUP_RATES];
34
35- tmp_group = mi->max_prob_rate / MCS_GROUP_RATES;
36- tmp_idx = mi->max_prob_rate % MCS_GROUP_RATES;
37+ tmp_group = *dest / MCS_GROUP_RATES;
38+ tmp_idx = *dest % MCS_GROUP_RATES;
39 tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
40 tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
41
42 /* if max_tp_rate[0] is from MCS_GROUP max_prob_rate get selected from
43 * MCS_GROUP as well as CCK_GROUP rates do not allow aggregation */
44 max_tp_group = mi->max_tp_rate[0] / MCS_GROUP_RATES;
45+ max_tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES;
46+ max_tp_prob = mi->groups[max_tp_group].rates[max_tp_idx].prob_avg;
47+
48 if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES) &&
49 !minstrel_ht_is_legacy_group(max_tp_group))
50 return;
51
52+ /* skip rates faster than max tp rate with lower prob */
53+ if (minstrel_get_duration(mi->max_tp_rate[0]) > minstrel_get_duration(index) &&
54+ mrs->prob_avg < max_tp_prob)
55+ return;
56+
57 max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES;
58 max_gpr_idx = mg->max_group_prob_rate % MCS_GROUP_RATES;
59 max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg;
60@@ -538,7 +547,7 @@ minstrel_ht_set_best_prob_rate(struct mi
61 mg->max_group_prob_rate = index;
62 } else {
63 if (mrs->prob_avg > tmp_prob)
64- mi->max_prob_rate = index;
65+ *dest = index;
66 if (mrs->prob_avg > max_gpr_prob)
67 mg->max_group_prob_rate = index;
68 }
69@@ -816,7 +825,8 @@ minstrel_ht_update_stats(struct minstrel
70 struct minstrel_rate_stats *mrs;
71 int group, i, j, cur_prob;
72 u16 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES];
73- u16 tmp_legacy_tp_rate[MAX_THR_RATES], index;
74+ u16 tmp_legacy_tp_rate[MAX_THR_RATES], tmp_max_prob_rate;
75+ u16 index;
76 bool ht_supported = mi->sta->ht_cap.ht_supported;
77
78 mi->sample_mode = MINSTREL_SAMPLE_IDLE;
79@@ -863,6 +873,7 @@ minstrel_ht_update_stats(struct minstrel
80 else
81 index = MINSTREL_OFDM_GROUP * MCS_GROUP_RATES;
82
83+ tmp_max_prob_rate = index;
84 for (j = 0; j < ARRAY_SIZE(tmp_mcs_tp_rate); j++)
85 tmp_mcs_tp_rate[j] = index;
86
87@@ -903,9 +914,6 @@ minstrel_ht_update_stats(struct minstrel
88 /* Find max throughput rate set within a group */
89 minstrel_ht_sort_best_tp_rates(mi, index,
90 tmp_group_tp_rate);
91-
92- /* Find max probability rate per group and global */
93- minstrel_ht_set_best_prob_rate(mi, index);
94 }
95
96 memcpy(mg->max_group_tp_rate, tmp_group_tp_rate,
97@@ -917,6 +925,27 @@ minstrel_ht_update_stats(struct minstrel
98 tmp_legacy_tp_rate);
99 memcpy(mi->max_tp_rate, tmp_mcs_tp_rate, sizeof(mi->max_tp_rate));
100
101+ for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) {
102+ if (!mi->supported[group])
103+ continue;
104+
105+ mg = &mi->groups[group];
106+ mg->max_group_prob_rate = MCS_GROUP_RATES * group;
107+
108+ for (i = 0; i < MCS_GROUP_RATES; i++) {
109+ if (!(mi->supported[group] & BIT(i)))
110+ continue;
111+
112+ index = MCS_GROUP_RATES * group + i;
113+
114+ /* Find max probability rate per group and global */
115+ minstrel_ht_set_best_prob_rate(mi, &tmp_max_prob_rate,
116+ index);
117+ }
118+ }
119+
120+ mi->max_prob_rate = tmp_max_prob_rate;
121+
122 /* Try to increase robustness of max_prob_rate*/
123 minstrel_ht_prob_rate_reduce_streams(mi);
124