From d59c6b53f495b22e09563c848bb21dadee575e95 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 1 Mar 2018 13:34:41 +0100 Subject: [PATCH] mac80211: add more minstrel fixes Improves 2.4 GHz throughput Signed-off-by: Felix Fietkau --- ...trel-reduce-minstrel_mcs_groups-size.patch | 94 +++++++++++++++---- ...l-fix-using-short-preamble-CCK-rates.patch | 2 +- ...rel-fix-CCK-rate-group-streams-value.patch | 20 ++++ ...l-fix-sampling-reporting-of-CCK-rate.patch | 57 +++++++++++ 4 files changed, 154 insertions(+), 19 deletions(-) create mode 100644 package/kernel/mac80211/patches/336-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch create mode 100644 package/kernel/mac80211/patches/337-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch diff --git a/package/kernel/mac80211/patches/328-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch b/package/kernel/mac80211/patches/328-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch index d62c362053..fa51f1be7e 100644 --- a/package/kernel/mac80211/patches/328-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch +++ b/package/kernel/mac80211/patches/328-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch @@ -218,21 +218,53 @@ Signed-off-by: Felix Fietkau /* * For the throughput calculation, limit the probability value to 90% to -@@ -780,7 +784,7 @@ minstrel_calc_retransmit(struct minstrel +@@ -755,12 +759,19 @@ minstrel_ht_tx_status(void *priv, struct + minstrel_ht_update_rates(mp, mi); + } + ++static inline int ++minstrel_get_duration(int index) ++{ ++ const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; ++ unsigned int duration = group->duration[index % MCS_GROUP_RATES]; ++ return duration << group->shift; ++} ++ + static void + minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, + int index) + { + struct minstrel_rate_stats *mrs; +- const struct mcs_group *group; + unsigned int tx_time, tx_time_rtscts, tx_time_data; + unsigned int cw = mp->cw_min; + unsigned int ctime = 0; +@@ -779,8 +790,7 @@ minstrel_calc_retransmit(struct minstrel + mrs->retry_count_rtscts = 2; mrs->retry_updated = true; - group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; +- group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; - tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len / 1000; -+ tx_time_data = (group->duration[index % MCS_GROUP_RATES] << group->shift) * ampdu_len / 1000; ++ tx_time_data = minstrel_get_duration(index) * ampdu_len / 1000; /* Contention time for first 2 tries */ ctime = (t_slot * cw) >> 1; -@@ -880,14 +884,14 @@ minstrel_ht_get_max_amsdu_len(struct min +@@ -874,20 +884,24 @@ minstrel_ht_get_max_amsdu_len(struct min + int group = mi->max_prob_rate / MCS_GROUP_RATES; + const struct mcs_group *g = &minstrel_mcs_groups[group]; + int rate = mi->max_prob_rate % MCS_GROUP_RATES; ++ unsigned int duration; + + /* Disable A-MSDU if max_prob_rate is bad */ + if (mi->groups[group].rates[rate].prob_ewma < MINSTREL_FRAC(50, 100)) return 1; ++ duration = g->duration[rate]; ++ duration <<= g->shift; ++ /* If the rate is slower than single-stream MCS1, make A-MSDU limit small */ - if (g->duration[rate] > MCS_DURATION(1, 0, 52)) -+ if ((g->duration[rate] << g->shift) > MCS_DURATION(1, 0, 52)) ++ if (duration > MCS_DURATION(1, 0, 52)) return 500; /* @@ -240,28 +272,33 @@ Signed-off-by: Felix Fietkau * data packet size */ - if (g->duration[rate] > MCS_DURATION(1, 0, 104)) -+ if ((g->duration[rate] << g->shift) > MCS_DURATION(1, 0, 104)) ++ if (duration > MCS_DURATION(1, 0, 104)) return 1600; /* -@@ -895,7 +899,7 @@ minstrel_ht_get_max_amsdu_len(struct min +@@ -895,7 +909,7 @@ minstrel_ht_get_max_amsdu_len(struct min * rate success probability is less than 75%, limit A-MSDU to twice the usual * data packet size */ - if (g->duration[rate] > MCS_DURATION(1, 0, 260) || -+ if ((g->duration[rate] << g->shift) > MCS_DURATION(1, 0, 260) || ++ if (duration > MCS_DURATION(1, 0, 260) || (minstrel_ht_get_prob_ewma(mi, mi->max_tp_rate[0]) < MINSTREL_FRAC(75, 100))) return 3200; -@@ -946,7 +950,7 @@ static inline int - minstrel_get_duration(int index) - { - const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; -- return group->duration[index % MCS_GROUP_RATES]; -+ return group->duration[index % MCS_GROUP_RATES] << group->shift; +@@ -942,13 +956,6 @@ minstrel_ht_update_rates(struct minstrel + rate_control_set_rates(mp->hw, mi->sta, rates); } +-static inline int +-minstrel_get_duration(int index) +-{ +- const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; +- return group->duration[index % MCS_GROUP_RATES]; +-} +- static int + minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) + { --- a/net/mac80211/rc80211_minstrel_ht.h +++ b/net/mac80211/rc80211_minstrel_ht.h @@ -33,9 +33,10 @@ @@ -280,21 +317,42 @@ Signed-off-by: Felix Fietkau extern const struct mcs_group minstrel_mcs_groups[]; --- a/net/mac80211/rc80211_minstrel_ht_debugfs.c +++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c -@@ -95,7 +95,7 @@ minstrel_ht_stats_dump(struct minstrel_h +@@ -58,6 +58,7 @@ minstrel_ht_stats_dump(struct minstrel_h + static const int bitrates[4] = { 10, 20, 55, 110 }; + int idx = i * MCS_GROUP_RATES + j; + unsigned int prob_ewmsd; ++ unsigned int duration; + + if (!(mi->supported[i] & BIT(j))) + continue; +@@ -95,7 +96,9 @@ minstrel_ht_stats_dump(struct minstrel_h p += sprintf(p, " %3u ", idx); /* tx_time[rate(i)] in usec */ - tx_time = DIV_ROUND_CLOSEST(mg->duration[j], 1000); -+ tx_time = DIV_ROUND_CLOSEST(mg->duration[j] << mg->shift, 1000); ++ duration = mg->duration[j]; ++ duration <<= mg->shift; ++ tx_time = DIV_ROUND_CLOSEST(duration, 1000); p += sprintf(p, "%6u ", tx_time); tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); -@@ -238,7 +238,7 @@ minstrel_ht_stats_csv_dump(struct minstr +@@ -204,6 +207,7 @@ minstrel_ht_stats_csv_dump(struct minstr + static const int bitrates[4] = { 10, 20, 55, 110 }; + int idx = i * MCS_GROUP_RATES + j; + unsigned int prob_ewmsd; ++ unsigned int duration; + + if (!(mi->supported[i] & BIT(j))) + continue; +@@ -238,7 +242,10 @@ minstrel_ht_stats_csv_dump(struct minstr } p += sprintf(p, "%u,", idx); - tx_time = DIV_ROUND_CLOSEST(mg->duration[j], 1000); -+ tx_time = DIV_ROUND_CLOSEST(mg->duration[j] << mg->shift, 1000); ++ ++ duration = mg->duration[j]; ++ duration <<= mg->shift; ++ tx_time = DIV_ROUND_CLOSEST(duration, 1000); p += sprintf(p, "%u,", tx_time); tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); diff --git a/package/kernel/mac80211/patches/329-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch b/package/kernel/mac80211/patches/329-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch index 5b298e677c..1255da992c 100644 --- a/package/kernel/mac80211/patches/329-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch +++ b/package/kernel/mac80211/patches/329-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch @@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -1265,7 +1265,8 @@ minstrel_ht_update_caps(void *priv, stru +@@ -1268,7 +1268,8 @@ minstrel_ht_update_caps(void *priv, stru goto use_legacy; if (test_sta_flag(sinfo, WLAN_STA_SHORT_PREAMBLE)) diff --git a/package/kernel/mac80211/patches/336-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch b/package/kernel/mac80211/patches/336-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch new file mode 100644 index 0000000000..f0ffcd9655 --- /dev/null +++ b/package/kernel/mac80211/patches/336-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch @@ -0,0 +1,20 @@ +From: Felix Fietkau +Date: Thu, 1 Mar 2018 13:27:54 +0100 +Subject: [PATCH] mac80211: minstrel: fix CCK rate group streams value + +Fixes a harmless underflow issue when CCK rates are actively being used + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -131,7 +131,7 @@ + + #define CCK_GROUP(_s) \ + [MINSTREL_CCK_GROUP] = { \ +- .streams = 0, \ ++ .streams = 1, \ + .flags = 0, \ + .shift = _s, \ + .duration = { \ diff --git a/package/kernel/mac80211/patches/337-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch b/package/kernel/mac80211/patches/337-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch new file mode 100644 index 0000000000..ff2f3450b2 --- /dev/null +++ b/package/kernel/mac80211/patches/337-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch @@ -0,0 +1,57 @@ +From: Felix Fietkau +Date: Thu, 1 Mar 2018 13:28:48 +0100 +Subject: [PATCH] mac80211: minstrel: fix sampling/reporting of CCK rates + in HT mode + +Long/short preamble selection cannot be sampled separately, since it +depends on the BSS state. Because of that, sampling attempts to +currently not used preamble modes are not counted in the statistics, +which leads to CCK rates being sampled too often. + +Fix statistics accounting for long/short preamble by increasing the +index where necessary. +Fix excessive CCK rate sampling by dropping unsupported sample attempts. + +This improves throughput on 2.4 GHz channels + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -281,7 +281,8 @@ minstrel_ht_get_stats(struct minstrel_pr + break; + + /* short preamble */ +- if (!(mi->supported[group] & BIT(idx))) ++ if ((mi->supported[group] & BIT(idx + 4)) && ++ (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)) + idx += 4; + } + return &mi->groups[group].rates[idx]; +@@ -1080,18 +1081,22 @@ minstrel_ht_get_rate(void *priv, struct + return; + + sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES]; ++ sample_idx %= MCS_GROUP_RATES; ++ ++ if ((sample_idx >= 4) != txrc->short_preamble) ++ return; ++ + info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; + rate->count = 1; + +- if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { ++ if (sample_group == &minstrel_mcs_groups[MINSTREL_CCK_GROUP]) { + int idx = sample_idx % ARRAY_SIZE(mp->cck_rates); + rate->idx = mp->cck_rates[idx]; + } else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) { + ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES, + sample_group->streams); + } else { +- rate->idx = sample_idx % MCS_GROUP_RATES + +- (sample_group->streams - 1) * 8; ++ rate->idx = sample_idx + (sample_group->streams - 1) * 8; + } + + rate->flags = sample_group->flags;