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

mac80211: minstrel_ht: use bitfields to encode rate indexes

Get rid of a lot of divisions and modulo operations
Reduces code size and improves performance
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
Link: https://lore.kernel.org/r/20210127055735.78599-1-nbd@nbd.nameSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 9e6d5126
...@@ -379,13 +379,13 @@ minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, ...@@ -379,13 +379,13 @@ minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
static inline struct minstrel_rate_stats * static inline struct minstrel_rate_stats *
minstrel_get_ratestats(struct minstrel_ht_sta *mi, int index) minstrel_get_ratestats(struct minstrel_ht_sta *mi, int index)
{ {
return &mi->groups[index / MCS_GROUP_RATES].rates[index % MCS_GROUP_RATES]; return &mi->groups[MI_RATE_GROUP(index)].rates[MI_RATE_IDX(index)];
} }
static inline int minstrel_get_duration(int index) static inline int minstrel_get_duration(int index)
{ {
const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; const struct mcs_group *group = &minstrel_mcs_groups[MI_RATE_GROUP(index)];
unsigned int duration = group->duration[index % MCS_GROUP_RATES]; unsigned int duration = group->duration[MI_RATE_IDX(index)];
return duration << group->shift; return duration << group->shift;
} }
...@@ -398,7 +398,7 @@ minstrel_ht_avg_ampdu_len(struct minstrel_ht_sta *mi) ...@@ -398,7 +398,7 @@ minstrel_ht_avg_ampdu_len(struct minstrel_ht_sta *mi)
if (mi->avg_ampdu_len) if (mi->avg_ampdu_len)
return MINSTREL_TRUNC(mi->avg_ampdu_len); return MINSTREL_TRUNC(mi->avg_ampdu_len);
if (minstrel_ht_is_legacy_group(mi->max_tp_rate[0] / MCS_GROUP_RATES)) if (minstrel_ht_is_legacy_group(MI_RATE_GROUP(mi->max_tp_rate[0])))
return 1; return 1;
duration = minstrel_get_duration(mi->max_tp_rate[0]); duration = minstrel_get_duration(mi->max_tp_rate[0]);
...@@ -465,14 +465,14 @@ minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u16 index, ...@@ -465,14 +465,14 @@ minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u16 index,
int tmp_group, tmp_idx, tmp_tp_avg, tmp_prob; int tmp_group, tmp_idx, tmp_tp_avg, tmp_prob;
int j = MAX_THR_RATES; int j = MAX_THR_RATES;
cur_group = index / MCS_GROUP_RATES; cur_group = MI_RATE_GROUP(index);
cur_idx = index % MCS_GROUP_RATES; cur_idx = MI_RATE_IDX(index);
cur_prob = mi->groups[cur_group].rates[cur_idx].prob_avg; cur_prob = mi->groups[cur_group].rates[cur_idx].prob_avg;
cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx, cur_prob); cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx, cur_prob);
do { do {
tmp_group = tp_list[j - 1] / MCS_GROUP_RATES; tmp_group = MI_RATE_GROUP(tp_list[j - 1]);
tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES; tmp_idx = MI_RATE_IDX(tp_list[j - 1]);
tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; 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_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx,
tmp_prob); tmp_prob);
...@@ -504,23 +504,23 @@ minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 *dest, u16 index) ...@@ -504,23 +504,23 @@ minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 *dest, u16 index)
int max_gpr_group, max_gpr_idx; int max_gpr_group, max_gpr_idx;
int max_gpr_tp_avg, max_gpr_prob; int max_gpr_tp_avg, max_gpr_prob;
cur_group = index / MCS_GROUP_RATES; cur_group = MI_RATE_GROUP(index);
cur_idx = index % MCS_GROUP_RATES; cur_idx = MI_RATE_IDX(index);
mg = &mi->groups[index / MCS_GROUP_RATES]; mg = &mi->groups[cur_group];
mrs = &mg->rates[index % MCS_GROUP_RATES]; mrs = &mg->rates[cur_idx];
tmp_group = *dest / MCS_GROUP_RATES; tmp_group = MI_RATE_GROUP(*dest);
tmp_idx = *dest % MCS_GROUP_RATES; tmp_idx = MI_RATE_IDX(*dest);
tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; 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); 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 /* 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 */ * 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_group = MI_RATE_GROUP(mi->max_tp_rate[0]);
max_tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES; max_tp_idx = MI_RATE_IDX(mi->max_tp_rate[0]);
max_tp_prob = mi->groups[max_tp_group].rates[max_tp_idx].prob_avg; max_tp_prob = mi->groups[max_tp_group].rates[max_tp_idx].prob_avg;
if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES) && if (minstrel_ht_is_legacy_group(MI_RATE_GROUP(index)) &&
!minstrel_ht_is_legacy_group(max_tp_group)) !minstrel_ht_is_legacy_group(max_tp_group))
return; return;
...@@ -529,8 +529,8 @@ minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 *dest, u16 index) ...@@ -529,8 +529,8 @@ minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 *dest, u16 index)
mrs->prob_avg < max_tp_prob) mrs->prob_avg < max_tp_prob)
return; return;
max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES; max_gpr_group = MI_RATE_GROUP(mg->max_group_prob_rate);
max_gpr_idx = mg->max_group_prob_rate % MCS_GROUP_RATES; max_gpr_idx = MI_RATE_IDX(mg->max_group_prob_rate);
max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg; max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg;
if (mrs->prob_avg > MINSTREL_FRAC(75, 100)) { if (mrs->prob_avg > MINSTREL_FRAC(75, 100)) {
...@@ -567,13 +567,13 @@ minstrel_ht_assign_best_tp_rates(struct minstrel_ht_sta *mi, ...@@ -567,13 +567,13 @@ minstrel_ht_assign_best_tp_rates(struct minstrel_ht_sta *mi,
unsigned int tmp_group, tmp_idx, tmp_cck_tp, tmp_mcs_tp, tmp_prob; unsigned int tmp_group, tmp_idx, tmp_cck_tp, tmp_mcs_tp, tmp_prob;
int i; int i;
tmp_group = tmp_legacy_tp_rate[0] / MCS_GROUP_RATES; tmp_group = MI_RATE_GROUP(tmp_legacy_tp_rate[0]);
tmp_idx = tmp_legacy_tp_rate[0] % MCS_GROUP_RATES; tmp_idx = MI_RATE_IDX(tmp_legacy_tp_rate[0]);
tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
tmp_cck_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob); tmp_cck_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
tmp_group = tmp_mcs_tp_rate[0] / MCS_GROUP_RATES; tmp_group = MI_RATE_GROUP(tmp_mcs_tp_rate[0]);
tmp_idx = tmp_mcs_tp_rate[0] % MCS_GROUP_RATES; tmp_idx = MI_RATE_IDX(tmp_mcs_tp_rate[0]);
tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
tmp_mcs_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob); tmp_mcs_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
...@@ -600,14 +600,14 @@ minstrel_ht_prob_rate_reduce_streams(struct minstrel_ht_sta *mi) ...@@ -600,14 +600,14 @@ minstrel_ht_prob_rate_reduce_streams(struct minstrel_ht_sta *mi)
if (!mi->sta->ht_cap.ht_supported) if (!mi->sta->ht_cap.ht_supported)
return; return;
tmp_max_streams = minstrel_mcs_groups[mi->max_tp_rate[0] / group = MI_RATE_GROUP(mi->max_tp_rate[0]);
MCS_GROUP_RATES].streams; tmp_max_streams = minstrel_mcs_groups[group].streams;
for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) {
mg = &mi->groups[group]; mg = &mi->groups[group];
if (!mi->supported[group] || group == MINSTREL_CCK_GROUP) if (!mi->supported[group] || group == MINSTREL_CCK_GROUP)
continue; continue;
tmp_idx = mg->max_group_prob_rate % MCS_GROUP_RATES; tmp_idx = MI_RATE_IDX(mg->max_group_prob_rate);
tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg; tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg;
if (tmp_tp < minstrel_ht_get_tp_avg(mi, group, tmp_idx, tmp_prob) && if (tmp_tp < minstrel_ht_get_tp_avg(mi, group, tmp_idx, tmp_prob) &&
...@@ -644,8 +644,8 @@ minstrel_ht_find_probe_rates(struct minstrel_ht_sta *mi, u16 *rates, int *n_rate ...@@ -644,8 +644,8 @@ minstrel_ht_find_probe_rates(struct minstrel_ht_sta *mi, u16 *rates, int *n_rate
int i, g, max_dur; int i, g, max_dur;
int tp_idx; int tp_idx;
tp_group = &minstrel_mcs_groups[mi->max_tp_rate[0] / MCS_GROUP_RATES]; tp_group = &minstrel_mcs_groups[MI_RATE_GROUP(mi->max_tp_rate[0])];
tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES; tp_idx = MI_RATE_IDX(mi->max_tp_rate[0]);
max_dur = minstrel_get_duration(mi->max_tp_rate[0]); max_dur = minstrel_get_duration(mi->max_tp_rate[0]);
if (faster_rate) if (faster_rate)
...@@ -670,7 +670,7 @@ minstrel_ht_find_probe_rates(struct minstrel_ht_sta *mi, u16 *rates, int *n_rate ...@@ -670,7 +670,7 @@ minstrel_ht_find_probe_rates(struct minstrel_ht_sta *mi, u16 *rates, int *n_rate
if ((group->duration[i] << group->shift) > max_dur) if ((group->duration[i] << group->shift) > max_dur)
continue; continue;
idx = g * MCS_GROUP_RATES + i; idx = MI_RATE(g, i);
if (idx == mi->max_tp_rate[0]) if (idx == mi->max_tp_rate[0])
continue; continue;
...@@ -712,10 +712,10 @@ minstrel_ht_rate_sample_switch(struct minstrel_priv *mp, ...@@ -712,10 +712,10 @@ minstrel_ht_rate_sample_switch(struct minstrel_priv *mp,
/* If no suitable rate was found, try to pick the next one in the group */ /* If no suitable rate was found, try to pick the next one in the group */
if (!n_rates) { if (!n_rates) {
int g_idx = mi->max_tp_rate[0] / MCS_GROUP_RATES; int g_idx = MI_RATE_GROUP(mi->max_tp_rate[0]);
u16 supported = mi->supported[g_idx]; u16 supported = mi->supported[g_idx];
supported >>= mi->max_tp_rate[0] % MCS_GROUP_RATES; supported >>= MI_RATE_IDX(mi->max_tp_rate[0]);
for (i = 0; supported; supported >>= 1, i++) { for (i = 0; supported; supported >>= 1, i++) {
if (!(supported & 1)) if (!(supported & 1))
continue; continue;
...@@ -854,24 +854,27 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, ...@@ -854,24 +854,27 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
mi->sample_slow = 0; mi->sample_slow = 0;
mi->sample_count = 0; mi->sample_count = 0;
memset(tmp_mcs_tp_rate, 0, sizeof(tmp_mcs_tp_rate));
memset(tmp_legacy_tp_rate, 0, sizeof(tmp_legacy_tp_rate));
if (mi->supported[MINSTREL_CCK_GROUP]) if (mi->supported[MINSTREL_CCK_GROUP])
for (j = 0; j < ARRAY_SIZE(tmp_legacy_tp_rate); j++) group = MINSTREL_CCK_GROUP;
tmp_legacy_tp_rate[j] = MINSTREL_CCK_GROUP * MCS_GROUP_RATES;
else if (mi->supported[MINSTREL_OFDM_GROUP]) else if (mi->supported[MINSTREL_OFDM_GROUP])
for (j = 0; j < ARRAY_SIZE(tmp_legacy_tp_rate); j++) group = MINSTREL_OFDM_GROUP;
tmp_legacy_tp_rate[j] = MINSTREL_OFDM_GROUP * MCS_GROUP_RATES; else
group = 0;
index = MI_RATE(group, 0);
for (j = 0; j < ARRAY_SIZE(tmp_legacy_tp_rate); j++)
tmp_legacy_tp_rate[j] = index;
if (mi->supported[MINSTREL_VHT_GROUP_0]) if (mi->supported[MINSTREL_VHT_GROUP_0])
index = MINSTREL_VHT_GROUP_0 * MCS_GROUP_RATES; group = MINSTREL_VHT_GROUP_0;
else if (ht_supported) else if (ht_supported)
index = MINSTREL_HT_GROUP_0 * MCS_GROUP_RATES; group = MINSTREL_HT_GROUP_0;
else if (mi->supported[MINSTREL_CCK_GROUP]) else if (mi->supported[MINSTREL_CCK_GROUP])
index = MINSTREL_CCK_GROUP * MCS_GROUP_RATES; group = MINSTREL_CCK_GROUP;
else else
index = MINSTREL_OFDM_GROUP * MCS_GROUP_RATES; group = MINSTREL_OFDM_GROUP;
index = MI_RATE(group, 0);
tmp_max_prob_rate = index; tmp_max_prob_rate = index;
for (j = 0; j < ARRAY_SIZE(tmp_mcs_tp_rate); j++) for (j = 0; j < ARRAY_SIZE(tmp_mcs_tp_rate); j++)
tmp_mcs_tp_rate[j] = index; tmp_mcs_tp_rate[j] = index;
...@@ -888,7 +891,7 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, ...@@ -888,7 +891,7 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
/* (re)Initialize group rate indexes */ /* (re)Initialize group rate indexes */
for(j = 0; j < MAX_THR_RATES; j++) for(j = 0; j < MAX_THR_RATES; j++)
tmp_group_tp_rate[j] = MCS_GROUP_RATES * group; tmp_group_tp_rate[j] = MI_RATE(group, 0);
if (group == MINSTREL_CCK_GROUP && ht_supported) if (group == MINSTREL_CCK_GROUP && ht_supported)
tp_rate = tmp_legacy_tp_rate; tp_rate = tmp_legacy_tp_rate;
...@@ -897,7 +900,7 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, ...@@ -897,7 +900,7 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
if (!(mi->supported[group] & BIT(i))) if (!(mi->supported[group] & BIT(i)))
continue; continue;
index = MCS_GROUP_RATES * group + i; index = MI_RATE(group, i);
mrs = &mg->rates[i]; mrs = &mg->rates[i];
mrs->retry_updated = false; mrs->retry_updated = false;
...@@ -929,13 +932,13 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, ...@@ -929,13 +932,13 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
continue; continue;
mg = &mi->groups[group]; mg = &mi->groups[group];
mg->max_group_prob_rate = MCS_GROUP_RATES * group; mg->max_group_prob_rate = MI_RATE(group, 0);
for (i = 0; i < MCS_GROUP_RATES; i++) { for (i = 0; i < MCS_GROUP_RATES; i++) {
if (!(mi->supported[group] & BIT(i))) if (!(mi->supported[group] & BIT(i)))
continue; continue;
index = MCS_GROUP_RATES * group + i; index = MI_RATE(group, i);
/* Find max probability rate per group and global */ /* Find max probability rate per group and global */
minstrel_ht_set_best_prob_rate(mi, &tmp_max_prob_rate, minstrel_ht_set_best_prob_rate(mi, &tmp_max_prob_rate,
...@@ -1022,7 +1025,7 @@ minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary) ...@@ -1022,7 +1025,7 @@ minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary)
{ {
int group, orig_group; int group, orig_group;
orig_group = group = *idx / MCS_GROUP_RATES; orig_group = group = MI_RATE_GROUP(*idx);
while (group > 0) { while (group > 0) {
group--; group--;
...@@ -1206,7 +1209,7 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, ...@@ -1206,7 +1209,7 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
ctime += (t_slot * cw) >> 1; ctime += (t_slot * cw) >> 1;
cw = min((cw << 1) | 1, mp->cw_max); cw = min((cw << 1) | 1, mp->cw_max);
if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES)) { if (minstrel_ht_is_legacy_group(MI_RATE_GROUP(index))) {
overhead = mi->overhead_legacy; overhead = mi->overhead_legacy;
overhead_rtscts = mi->overhead_legacy_rtscts; overhead_rtscts = mi->overhead_legacy_rtscts;
} else { } else {
...@@ -1239,7 +1242,7 @@ static void ...@@ -1239,7 +1242,7 @@ static void
minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
struct ieee80211_sta_rates *ratetbl, int offset, int index) struct ieee80211_sta_rates *ratetbl, int offset, int index)
{ {
int group_idx = index / MCS_GROUP_RATES; int group_idx = MI_RATE_GROUP(index);
const struct mcs_group *group = &minstrel_mcs_groups[group_idx]; const struct mcs_group *group = &minstrel_mcs_groups[group_idx];
struct minstrel_rate_stats *mrs; struct minstrel_rate_stats *mrs;
u8 idx; u8 idx;
...@@ -1259,7 +1262,7 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, ...@@ -1259,7 +1262,7 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
ratetbl->rate[offset].count_rts = mrs->retry_count_rtscts; ratetbl->rate[offset].count_rts = mrs->retry_count_rtscts;
} }
index %= MCS_GROUP_RATES; index = MI_RATE_IDX(index);
if (group_idx == MINSTREL_CCK_GROUP) if (group_idx == MINSTREL_CCK_GROUP)
idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)];
else if (group_idx == MINSTREL_OFDM_GROUP) else if (group_idx == MINSTREL_OFDM_GROUP)
...@@ -1289,17 +1292,17 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, ...@@ -1289,17 +1292,17 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
static inline int static inline int
minstrel_ht_get_prob_avg(struct minstrel_ht_sta *mi, int rate) minstrel_ht_get_prob_avg(struct minstrel_ht_sta *mi, int rate)
{ {
int group = rate / MCS_GROUP_RATES; int group = MI_RATE_GROUP(rate);
rate %= MCS_GROUP_RATES; rate = MI_RATE_IDX(rate);
return mi->groups[group].rates[rate].prob_avg; return mi->groups[group].rates[rate].prob_avg;
} }
static int static int
minstrel_ht_get_max_amsdu_len(struct minstrel_ht_sta *mi) minstrel_ht_get_max_amsdu_len(struct minstrel_ht_sta *mi)
{ {
int group = mi->max_prob_rate / MCS_GROUP_RATES; int group = MI_RATE_GROUP(mi->max_prob_rate);
const struct mcs_group *g = &minstrel_mcs_groups[group]; const struct mcs_group *g = &minstrel_mcs_groups[group];
int rate = mi->max_prob_rate % MCS_GROUP_RATES; int rate = MI_RATE_IDX(mi->max_prob_rate);
unsigned int duration; unsigned int duration;
/* Disable A-MSDU if max_prob_rate is bad */ /* Disable A-MSDU if max_prob_rate is bad */
...@@ -1405,7 +1408,7 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) ...@@ -1405,7 +1408,7 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
return -1; return -1;
mrs = &mg->rates[sample_idx]; mrs = &mg->rates[sample_idx];
sample_idx += sample_group * MCS_GROUP_RATES; sample_idx += MI_RATE(sample_group, 0);
tp_rate1 = mi->max_tp_rate[0]; tp_rate1 = mi->max_tp_rate[0];
...@@ -1455,8 +1458,7 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) ...@@ -1455,8 +1458,7 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
* if the link is working perfectly. * if the link is working perfectly.
*/ */
cur_max_tp_streams = minstrel_mcs_groups[tp_rate1 / cur_max_tp_streams = minstrel_mcs_groups[MI_RATE_GROUP(tp_rate1)].streams;
MCS_GROUP_RATES].streams;
if (sample_dur >= minstrel_get_duration(tp_rate2) && if (sample_dur >= minstrel_get_duration(tp_rate2) &&
(cur_max_tp_streams - 1 < (cur_max_tp_streams - 1 <
minstrel_mcs_groups[sample_group].streams || minstrel_mcs_groups[sample_group].streams ||
...@@ -1484,7 +1486,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, ...@@ -1484,7 +1486,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
int sample_idx; int sample_idx;
if (!(info->flags & IEEE80211_TX_CTL_AMPDU) && if (!(info->flags & IEEE80211_TX_CTL_AMPDU) &&
!minstrel_ht_is_legacy_group(mi->max_prob_rate / MCS_GROUP_RATES)) !minstrel_ht_is_legacy_group(MI_RATE_GROUP(mi->max_prob_rate)))
minstrel_aggr_check(sta, txrc->skb); minstrel_aggr_check(sta, txrc->skb);
info->flags |= mi->tx_flags; info->flags |= mi->tx_flags;
...@@ -1512,8 +1514,8 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, ...@@ -1512,8 +1514,8 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
if (sample_idx < 0) if (sample_idx < 0)
return; return;
sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES]; sample_group = &minstrel_mcs_groups[MI_RATE_GROUP(sample_idx)];
sample_idx %= MCS_GROUP_RATES; sample_idx = MI_RATE_IDX(sample_idx);
if (sample_group == &minstrel_mcs_groups[MINSTREL_CCK_GROUP] && if (sample_group == &minstrel_mcs_groups[MINSTREL_CCK_GROUP] &&
(sample_idx >= 4) != txrc->short_preamble) (sample_idx >= 4) != txrc->short_preamble)
...@@ -1529,7 +1531,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, ...@@ -1529,7 +1531,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
int idx = sample_idx % ARRAY_SIZE(mp->ofdm_rates[0]); int idx = sample_idx % ARRAY_SIZE(mp->ofdm_rates[0]);
rate->idx = mp->ofdm_rates[mi->band][idx]; rate->idx = mp->ofdm_rates[mi->band][idx];
} else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) { } else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) {
ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES, ieee80211_rate_set_vht(rate, MI_RATE_IDX(sample_idx),
sample_group->streams); sample_group->streams);
} else { } else {
rate->idx = sample_idx + (sample_group->streams - 1) * 8; rate->idx = sample_idx + (sample_group->streams - 1) * 8;
...@@ -1898,8 +1900,8 @@ static u32 minstrel_ht_get_expected_throughput(void *priv_sta) ...@@ -1898,8 +1900,8 @@ static u32 minstrel_ht_get_expected_throughput(void *priv_sta)
struct minstrel_ht_sta *mi = priv_sta; struct minstrel_ht_sta *mi = priv_sta;
int i, j, prob, tp_avg; int i, j, prob, tp_avg;
i = mi->max_tp_rate[0] / MCS_GROUP_RATES; i = MI_RATE_GROUP(mi->max_tp_rate[0]);
j = mi->max_tp_rate[0] % MCS_GROUP_RATES; j = MI_RATE_IDX(mi->max_tp_rate[0]);
prob = mi->groups[i].rates[j].prob_avg; prob = mi->groups[i].rates[j].prob_avg;
/* convert tp_avg from pkt per second in kbps */ /* convert tp_avg from pkt per second in kbps */
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#ifndef __RC_MINSTREL_HT_H #ifndef __RC_MINSTREL_HT_H
#define __RC_MINSTREL_HT_H #define __RC_MINSTREL_HT_H
#include <linux/bitfield.h>
/* number of highest throughput rates to consider*/ /* number of highest throughput rates to consider*/
#define MAX_THR_RATES 4 #define MAX_THR_RATES 4
#define SAMPLE_COLUMNS 10 /* number of columns in sample table */ #define SAMPLE_COLUMNS 10 /* number of columns in sample table */
...@@ -57,6 +59,17 @@ ...@@ -57,6 +59,17 @@
#define MCS_GROUP_RATES 10 #define MCS_GROUP_RATES 10
#define MI_RATE_IDX_MASK GENMASK(3, 0)
#define MI_RATE_GROUP_MASK GENMASK(15, 4)
#define MI_RATE(_group, _idx) \
(FIELD_PREP(MI_RATE_GROUP_MASK, _group) | \
FIELD_PREP(MI_RATE_IDX_MASK, _idx))
#define MI_RATE_IDX(_rate) FIELD_GET(MI_RATE_IDX_MASK, _rate)
#define MI_RATE_GROUP(_rate) FIELD_GET(MI_RATE_GROUP_MASK, _rate)
struct minstrel_priv { struct minstrel_priv {
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
bool has_mrr; bool has_mrr;
......
...@@ -56,7 +56,7 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) ...@@ -56,7 +56,7 @@ 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];
int idx = i * MCS_GROUP_RATES + j; int idx = MI_RATE(i, j);
unsigned int duration; unsigned int duration;
if (!(mi->supported[i] & BIT(j))) if (!(mi->supported[i] & BIT(j)))
...@@ -201,7 +201,7 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p) ...@@ -201,7 +201,7 @@ 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];
int idx = i * MCS_GROUP_RATES + j; int idx = MI_RATE(i, j);
unsigned int duration; unsigned int duration;
if (!(mi->supported[i] & BIT(j))) if (!(mi->supported[i] & BIT(j)))
......
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