mirror of https://github.com/hak5/openwrt.git
mac80211: add more minstrel fixes
Improves 2.4 GHz throughput Signed-off-by: Felix Fietkau <nbd@nbd.name>openwrt-18.06
parent
55bd80f6d8
commit
d59c6b53f4
|
@ -218,21 +218,53 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For the throughput calculation, limit the probability value to 90% to
|
* 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;
|
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] * 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 */
|
/* Contention time for first 2 tries */
|
||||||
ctime = (t_slot * cw) >> 1;
|
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;
|
return 1;
|
||||||
|
|
||||||
|
+ duration = g->duration[rate];
|
||||||
|
+ duration <<= g->shift;
|
||||||
|
+
|
||||||
/* If the rate is slower than single-stream MCS1, make A-MSDU limit small */
|
/* 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] > 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;
|
return 500;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -240,28 +272,33 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
* data packet size
|
* data packet size
|
||||||
*/
|
*/
|
||||||
- if (g->duration[rate] > MCS_DURATION(1, 0, 104))
|
- 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;
|
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
|
* rate success probability is less than 75%, limit A-MSDU to twice the usual
|
||||||
* data packet size
|
* data packet size
|
||||||
*/
|
*/
|
||||||
- if (g->duration[rate] > MCS_DURATION(1, 0, 260) ||
|
- 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_ht_get_prob_ewma(mi, mi->max_tp_rate[0]) <
|
||||||
MINSTREL_FRAC(75, 100)))
|
MINSTREL_FRAC(75, 100)))
|
||||||
return 3200;
|
return 3200;
|
||||||
@@ -946,7 +950,7 @@ static inline int
|
@@ -942,13 +956,6 @@ minstrel_ht_update_rates(struct minstrel
|
||||||
minstrel_get_duration(int index)
|
rate_control_set_rates(mp->hw, mi->sta, rates);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-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
|
static int
|
||||||
|
minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
|
||||||
|
{
|
||||||
--- a/net/mac80211/rc80211_minstrel_ht.h
|
--- a/net/mac80211/rc80211_minstrel_ht.h
|
||||||
+++ b/net/mac80211/rc80211_minstrel_ht.h
|
+++ b/net/mac80211/rc80211_minstrel_ht.h
|
||||||
@@ -33,9 +33,10 @@
|
@@ -33,9 +33,10 @@
|
||||||
|
@ -280,21 +317,42 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
extern const struct mcs_group minstrel_mcs_groups[];
|
extern const struct mcs_group minstrel_mcs_groups[];
|
||||||
--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
|
--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
|
||||||
+++ b/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);
|
p += sprintf(p, " %3u ", idx);
|
||||||
|
|
||||||
/* tx_time[rate(i)] in usec */
|
/* tx_time[rate(i)] in usec */
|
||||||
- tx_time = DIV_ROUND_CLOSEST(mg->duration[j], 1000);
|
- 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);
|
p += sprintf(p, "%6u ", tx_time);
|
||||||
|
|
||||||
tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
|
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);
|
p += sprintf(p, "%u,", idx);
|
||||||
- tx_time = DIV_ROUND_CLOSEST(mg->duration[j], 1000);
|
- 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);
|
p += sprintf(p, "%u,", tx_time);
|
||||||
|
|
||||||
tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
|
tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
|
||||||
|
|
|
@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
|
||||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||||
+++ b/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;
|
goto use_legacy;
|
||||||
|
|
||||||
if (test_sta_flag(sinfo, WLAN_STA_SHORT_PREAMBLE))
|
if (test_sta_flag(sinfo, WLAN_STA_SHORT_PREAMBLE))
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
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 <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- 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 = { \
|
|
@ -0,0 +1,57 @@
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
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 <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- 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;
|
Loading…
Reference in New Issue