diff options
Diffstat (limited to 'package/kernel/mac80211/patches/subsys/343-mac80211-minstrel_ht-fix-max-probability-rate-select.patch')
-rw-r--r-- | package/kernel/mac80211/patches/subsys/343-mac80211-minstrel_ht-fix-max-probability-rate-select.patch | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/subsys/343-mac80211-minstrel_ht-fix-max-probability-rate-select.patch b/package/kernel/mac80211/patches/subsys/343-mac80211-minstrel_ht-fix-max-probability-rate-select.patch new file mode 100644 index 0000000000..a0b918c9a1 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/343-mac80211-minstrel_ht-fix-max-probability-rate-select.patch @@ -0,0 +1,116 @@ +From: Felix Fietkau <nbd@nbd.name> +Date: Sat, 26 Dec 2020 19:09:08 +0100 +Subject: [PATCH] mac80211: minstrel_ht: fix max probability rate selection + +- do not select rates faster than the max throughput rate if probability is lower +- reset previous rate before sorting again + +This ensures that the max prob rate gets set to a more reliable rate + +Signed-off-by: Felix Fietkau <nbd@nbd.name> +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -495,12 +495,13 @@ minstrel_ht_sort_best_tp_rates(struct mi + * Find and set the topmost probability rate per sta and per group + */ + static void +-minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 index) ++minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 *dest, u16 index) + { + struct minstrel_mcs_group_data *mg; + struct minstrel_rate_stats *mrs; + int tmp_group, tmp_idx, tmp_tp_avg, tmp_prob; +- int max_tp_group, cur_tp_avg, cur_group, cur_idx; ++ int max_tp_group, max_tp_idx, max_tp_prob; ++ int cur_tp_avg, cur_group, cur_idx; + int max_gpr_group, max_gpr_idx; + int max_gpr_tp_avg, max_gpr_prob; + +@@ -509,18 +510,26 @@ minstrel_ht_set_best_prob_rate(struct mi + mg = &mi->groups[index / MCS_GROUP_RATES]; + mrs = &mg->rates[index % MCS_GROUP_RATES]; + +- tmp_group = mi->max_prob_rate / MCS_GROUP_RATES; +- tmp_idx = mi->max_prob_rate % MCS_GROUP_RATES; ++ tmp_group = *dest / MCS_GROUP_RATES; ++ tmp_idx = *dest % MCS_GROUP_RATES; + tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; + tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob); + + /* if max_tp_rate[0] is from MCS_GROUP max_prob_rate get selected from + * MCS_GROUP as well as CCK_GROUP rates do not allow aggregation */ + max_tp_group = mi->max_tp_rate[0] / MCS_GROUP_RATES; ++ max_tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES; ++ max_tp_prob = mi->groups[max_tp_group].rates[max_tp_idx].prob_avg; ++ + if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES) && + !minstrel_ht_is_legacy_group(max_tp_group)) + return; + ++ /* skip rates faster than max tp rate with lower prob */ ++ if (minstrel_get_duration(mi->max_tp_rate[0]) > minstrel_get_duration(index) && ++ mrs->prob_avg < max_tp_prob) ++ return; ++ + max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES; + max_gpr_idx = mg->max_group_prob_rate % MCS_GROUP_RATES; + max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg; +@@ -538,7 +547,7 @@ minstrel_ht_set_best_prob_rate(struct mi + mg->max_group_prob_rate = index; + } else { + if (mrs->prob_avg > tmp_prob) +- mi->max_prob_rate = index; ++ *dest = index; + if (mrs->prob_avg > max_gpr_prob) + mg->max_group_prob_rate = index; + } +@@ -816,7 +825,8 @@ minstrel_ht_update_stats(struct minstrel + struct minstrel_rate_stats *mrs; + int group, i, j, cur_prob; + u16 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES]; +- u16 tmp_legacy_tp_rate[MAX_THR_RATES], index; ++ u16 tmp_legacy_tp_rate[MAX_THR_RATES], tmp_max_prob_rate; ++ u16 index; + bool ht_supported = mi->sta->ht_cap.ht_supported; + + mi->sample_mode = MINSTREL_SAMPLE_IDLE; +@@ -903,9 +913,6 @@ minstrel_ht_update_stats(struct minstrel + /* Find max throughput rate set within a group */ + minstrel_ht_sort_best_tp_rates(mi, index, + tmp_group_tp_rate); +- +- /* Find max probability rate per group and global */ +- minstrel_ht_set_best_prob_rate(mi, index); + } + + memcpy(mg->max_group_tp_rate, tmp_group_tp_rate, +@@ -917,6 +924,27 @@ minstrel_ht_update_stats(struct minstrel + tmp_legacy_tp_rate); + memcpy(mi->max_tp_rate, tmp_mcs_tp_rate, sizeof(mi->max_tp_rate)); + ++ for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { ++ if (!mi->supported[group]) ++ continue; ++ ++ mg = &mi->groups[group]; ++ mg->max_group_prob_rate = MCS_GROUP_RATES * group; ++ ++ for (i = 0; i < MCS_GROUP_RATES; i++) { ++ if (!(mi->supported[group] & BIT(i))) ++ continue; ++ ++ index = MCS_GROUP_RATES * group + i; ++ ++ /* Find max probability rate per group and global */ ++ minstrel_ht_set_best_prob_rate(mi, &tmp_max_prob_rate, ++ index); ++ } ++ } ++ ++ mi->max_prob_rate = tmp_max_prob_rate; ++ + /* Try to increase robustness of max_prob_rate*/ + minstrel_ht_prob_rate_reduce_streams(mi); + |