Commit a7844a53 authored by Felix Fietkau's avatar Felix Fietkau Committed by Johannes Berg

mac80211: minstrel_ht: add support for OFDM rates on non-HT clients

The legacy minstrel code is essentially unmaintained and receives only very
little testing. In order to bring the significant algorithm improvements from
minstrel_ht to legacy clients, this patch adds support for OFDM rates to
minstrel_ht and removes the fallback to the legacy codepath.
This also makes it work much better on hardware with rate selection constraints,
e.g. mt76.
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
Link: https://lore.kernel.org/r/20210115120242.89616-3-nbd@nbd.nameSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent f84de063
...@@ -152,6 +152,7 @@ struct minstrel_priv { ...@@ -152,6 +152,7 @@ struct minstrel_priv {
unsigned int lookaround_rate_mrr; unsigned int lookaround_rate_mrr;
u8 cck_rates[4]; u8 cck_rates[4];
u8 ofdm_rates[NUM_NL80211_BANDS][8];
#ifdef CONFIG_MAC80211_DEBUGFS #ifdef CONFIG_MAC80211_DEBUGFS
/* /*
......
This diff is collapsed.
...@@ -18,14 +18,15 @@ ...@@ -18,14 +18,15 @@
MINSTREL_HT_STREAM_GROUPS) MINSTREL_HT_STREAM_GROUPS)
#define MINSTREL_VHT_GROUPS_NB (MINSTREL_MAX_STREAMS * \ #define MINSTREL_VHT_GROUPS_NB (MINSTREL_MAX_STREAMS * \
MINSTREL_VHT_STREAM_GROUPS) MINSTREL_VHT_STREAM_GROUPS)
#define MINSTREL_CCK_GROUPS_NB 1 #define MINSTREL_LEGACY_GROUPS_NB 2
#define MINSTREL_GROUPS_NB (MINSTREL_HT_GROUPS_NB + \ #define MINSTREL_GROUPS_NB (MINSTREL_HT_GROUPS_NB + \
MINSTREL_VHT_GROUPS_NB + \ MINSTREL_VHT_GROUPS_NB + \
MINSTREL_CCK_GROUPS_NB) MINSTREL_LEGACY_GROUPS_NB)
#define MINSTREL_HT_GROUP_0 0 #define MINSTREL_HT_GROUP_0 0
#define MINSTREL_CCK_GROUP (MINSTREL_HT_GROUP_0 + MINSTREL_HT_GROUPS_NB) #define MINSTREL_CCK_GROUP (MINSTREL_HT_GROUP_0 + MINSTREL_HT_GROUPS_NB)
#define MINSTREL_VHT_GROUP_0 (MINSTREL_CCK_GROUP + 1) #define MINSTREL_OFDM_GROUP (MINSTREL_CCK_GROUP + 1)
#define MINSTREL_VHT_GROUP_0 (MINSTREL_OFDM_GROUP + 1)
#define MCS_GROUP_RATES 10 #define MCS_GROUP_RATES 10
...@@ -37,6 +38,8 @@ struct mcs_group { ...@@ -37,6 +38,8 @@ struct mcs_group {
u16 duration[MCS_GROUP_RATES]; u16 duration[MCS_GROUP_RATES];
}; };
extern const s16 minstrel_cck_bitrates[4];
extern const s16 minstrel_ofdm_bitrates[8];
extern const struct mcs_group minstrel_mcs_groups[]; extern const struct mcs_group minstrel_mcs_groups[];
struct minstrel_mcs_group_data { struct minstrel_mcs_group_data {
...@@ -99,6 +102,8 @@ struct minstrel_ht_sta { ...@@ -99,6 +102,8 @@ struct minstrel_ht_sta {
/* current MCS group to be sampled */ /* current MCS group to be sampled */
u8 sample_group; u8 sample_group;
u8 band;
/* Bitfield of supported MCS rates of all groups */ /* Bitfield of supported MCS rates of all groups */
u16 supported[MINSTREL_GROUPS_NB]; u16 supported[MINSTREL_GROUPS_NB];
...@@ -107,13 +112,9 @@ struct minstrel_ht_sta { ...@@ -107,13 +112,9 @@ struct minstrel_ht_sta {
}; };
struct minstrel_ht_sta_priv { struct minstrel_ht_sta_priv {
union {
struct minstrel_ht_sta ht; struct minstrel_ht_sta ht;
struct minstrel_sta_info legacy;
};
void *ratelist; void *ratelist;
void *sample_table; void *sample_table;
bool is_ht;
}; };
void minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); void minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
......
...@@ -52,7 +52,6 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) ...@@ -52,7 +52,6 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
for (j = 0; j < MCS_GROUP_RATES; j++) { for (j = 0; j < MCS_GROUP_RATES; j++) {
struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j]; struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j];
static const int bitrates[4] = { 10, 20, 55, 110 };
int idx = i * MCS_GROUP_RATES + j; int idx = i * MCS_GROUP_RATES + j;
unsigned int duration; unsigned int duration;
...@@ -67,6 +66,9 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) ...@@ -67,6 +66,9 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
p += sprintf(p, "VHT%c0 ", htmode); p += sprintf(p, "VHT%c0 ", htmode);
p += sprintf(p, "%cGI ", gimode); p += sprintf(p, "%cGI ", gimode);
p += sprintf(p, "%d ", mg->streams); p += sprintf(p, "%d ", mg->streams);
} else if (i == MINSTREL_OFDM_GROUP) {
p += sprintf(p, "OFDM ");
p += sprintf(p, "1 ");
} else { } else {
p += sprintf(p, "CCK "); p += sprintf(p, "CCK ");
p += sprintf(p, "%cP ", j < 4 ? 'L' : 'S'); p += sprintf(p, "%cP ", j < 4 ? 'L' : 'S');
...@@ -84,7 +86,12 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) ...@@ -84,7 +86,12 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
} else if (gflags & IEEE80211_TX_RC_VHT_MCS) { } else if (gflags & IEEE80211_TX_RC_VHT_MCS) {
p += sprintf(p, " MCS%-1u/%1u", j, mg->streams); p += sprintf(p, " MCS%-1u/%1u", j, mg->streams);
} else { } else {
int r = bitrates[j % 4]; int r;
if (i == MINSTREL_OFDM_GROUP)
r = minstrel_ofdm_bitrates[j % 8];
else
r = minstrel_cck_bitrates[j % 4];
p += sprintf(p, " %2u.%1uM", r / 10, r % 10); p += sprintf(p, " %2u.%1uM", r / 10, r % 10);
} }
...@@ -124,16 +131,8 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file) ...@@ -124,16 +131,8 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file)
struct minstrel_ht_sta *mi = &msp->ht; struct minstrel_ht_sta *mi = &msp->ht;
struct minstrel_debugfs_info *ms; struct minstrel_debugfs_info *ms;
unsigned int i; unsigned int i;
int ret;
char *p; char *p;
if (!msp->is_ht) {
inode->i_private = &msp->legacy;
ret = minstrel_stats_open(inode, file);
inode->i_private = msp;
return ret;
}
ms = kmalloc(32768, GFP_KERNEL); ms = kmalloc(32768, GFP_KERNEL);
if (!ms) if (!ms)
return -ENOMEM; return -ENOMEM;
...@@ -199,7 +198,6 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p) ...@@ -199,7 +198,6 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p)
for (j = 0; j < MCS_GROUP_RATES; j++) { for (j = 0; j < MCS_GROUP_RATES; j++) {
struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j]; struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j];
static const int bitrates[4] = { 10, 20, 55, 110 };
int idx = i * MCS_GROUP_RATES + j; int idx = i * MCS_GROUP_RATES + j;
unsigned int duration; unsigned int duration;
...@@ -214,6 +212,8 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p) ...@@ -214,6 +212,8 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p)
p += sprintf(p, "VHT%c0,", htmode); p += sprintf(p, "VHT%c0,", htmode);
p += sprintf(p, "%cGI,", gimode); p += sprintf(p, "%cGI,", gimode);
p += sprintf(p, "%d,", mg->streams); p += sprintf(p, "%d,", mg->streams);
} else if (i == MINSTREL_OFDM_GROUP) {
p += sprintf(p, "OFDM,,1,");
} else { } else {
p += sprintf(p, "CCK,"); p += sprintf(p, "CCK,");
p += sprintf(p, "%cP,", j < 4 ? 'L' : 'S'); p += sprintf(p, "%cP,", j < 4 ? 'L' : 'S');
...@@ -231,7 +231,13 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p) ...@@ -231,7 +231,13 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p)
} else if (gflags & IEEE80211_TX_RC_VHT_MCS) { } else if (gflags & IEEE80211_TX_RC_VHT_MCS) {
p += sprintf(p, ",MCS%-1u/%1u,", j, mg->streams); p += sprintf(p, ",MCS%-1u/%1u,", j, mg->streams);
} else { } else {
int r = bitrates[j % 4]; int r;
if (i == MINSTREL_OFDM_GROUP)
r = minstrel_ofdm_bitrates[j % 8];
else
r = minstrel_cck_bitrates[j % 4];
p += sprintf(p, ",%2u.%1uM,", r / 10, r % 10); p += sprintf(p, ",%2u.%1uM,", r / 10, r % 10);
} }
...@@ -274,18 +280,9 @@ minstrel_ht_stats_csv_open(struct inode *inode, struct file *file) ...@@ -274,18 +280,9 @@ minstrel_ht_stats_csv_open(struct inode *inode, struct file *file)
struct minstrel_ht_sta *mi = &msp->ht; struct minstrel_ht_sta *mi = &msp->ht;
struct minstrel_debugfs_info *ms; struct minstrel_debugfs_info *ms;
unsigned int i; unsigned int i;
int ret;
char *p; char *p;
if (!msp->is_ht) {
inode->i_private = &msp->legacy;
ret = minstrel_stats_csv_open(inode, file);
inode->i_private = msp;
return ret;
}
ms = kmalloc(32768, GFP_KERNEL); ms = kmalloc(32768, GFP_KERNEL);
if (!ms) if (!ms)
return -ENOMEM; return -ENOMEM;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment