b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame^] | 1 | From: Felix Fietkau <nbd@nbd.name> |
| 2 | Date: Thu, 21 Jan 2021 18:29:30 +0100 |
| 3 | Subject: [PATCH] mac80211: minstrel_ht: use bitfields to encode rate |
| 4 | indexes |
| 5 | |
| 6 | Get rid of a lot of divisions and modulo operations |
| 7 | Reduces code size and improves performance |
| 8 | |
| 9 | Signed-off-by: Felix Fietkau <nbd@nbd.name> |
| 10 | --- |
| 11 | |
| 12 | --- a/net/mac80211/rc80211_minstrel_ht.c |
| 13 | +++ b/net/mac80211/rc80211_minstrel_ht.c |
| 14 | @@ -379,14 +379,14 @@ out: |
| 15 | static inline struct minstrel_rate_stats * |
| 16 | minstrel_get_ratestats(struct minstrel_ht_sta *mi, int index) |
| 17 | { |
| 18 | - return &mi->groups[index / MCS_GROUP_RATES].rates[index % MCS_GROUP_RATES]; |
| 19 | + return &mi->groups[MI_RATE_GROUP(index)].rates[MI_RATE_IDX(index)]; |
| 20 | } |
| 21 | |
| 22 | -static inline int |
| 23 | -minstrel_get_duration(int index) |
| 24 | +static inline int minstrel_get_duration(int index) |
| 25 | { |
| 26 | - const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; |
| 27 | - unsigned int duration = group->duration[index % MCS_GROUP_RATES]; |
| 28 | + const struct mcs_group *group = &minstrel_mcs_groups[MI_RATE_GROUP(index)]; |
| 29 | + unsigned int duration = group->duration[MI_RATE_IDX(index)]; |
| 30 | + |
| 31 | return duration << group->shift; |
| 32 | } |
| 33 | |
| 34 | @@ -398,7 +398,7 @@ minstrel_ht_avg_ampdu_len(struct minstre |
| 35 | if (mi->avg_ampdu_len) |
| 36 | return MINSTREL_TRUNC(mi->avg_ampdu_len); |
| 37 | |
| 38 | - if (minstrel_ht_is_legacy_group(mi->max_tp_rate[0] / MCS_GROUP_RATES)) |
| 39 | + if (minstrel_ht_is_legacy_group(MI_RATE_GROUP(mi->max_tp_rate[0]))) |
| 40 | return 1; |
| 41 | |
| 42 | duration = minstrel_get_duration(mi->max_tp_rate[0]); |
| 43 | @@ -465,14 +465,14 @@ minstrel_ht_sort_best_tp_rates(struct mi |
| 44 | int tmp_group, tmp_idx, tmp_tp_avg, tmp_prob; |
| 45 | int j = MAX_THR_RATES; |
| 46 | |
| 47 | - cur_group = index / MCS_GROUP_RATES; |
| 48 | - cur_idx = index % MCS_GROUP_RATES; |
| 49 | + cur_group = MI_RATE_GROUP(index); |
| 50 | + cur_idx = MI_RATE_IDX(index); |
| 51 | cur_prob = mi->groups[cur_group].rates[cur_idx].prob_avg; |
| 52 | cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx, cur_prob); |
| 53 | |
| 54 | do { |
| 55 | - tmp_group = tp_list[j - 1] / MCS_GROUP_RATES; |
| 56 | - tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES; |
| 57 | + tmp_group = MI_RATE_GROUP(tp_list[j - 1]); |
| 58 | + tmp_idx = MI_RATE_IDX(tp_list[j - 1]); |
| 59 | tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; |
| 60 | tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, |
| 61 | tmp_prob); |
| 62 | @@ -504,23 +504,23 @@ minstrel_ht_set_best_prob_rate(struct mi |
| 63 | int max_gpr_group, max_gpr_idx; |
| 64 | int max_gpr_tp_avg, max_gpr_prob; |
| 65 | |
| 66 | - cur_group = index / MCS_GROUP_RATES; |
| 67 | - cur_idx = index % MCS_GROUP_RATES; |
| 68 | - mg = &mi->groups[index / MCS_GROUP_RATES]; |
| 69 | - mrs = &mg->rates[index % MCS_GROUP_RATES]; |
| 70 | + cur_group = MI_RATE_GROUP(index); |
| 71 | + cur_idx = MI_RATE_IDX(index); |
| 72 | + mg = &mi->groups[cur_group]; |
| 73 | + mrs = &mg->rates[cur_idx]; |
| 74 | |
| 75 | - tmp_group = *dest / MCS_GROUP_RATES; |
| 76 | - tmp_idx = *dest % MCS_GROUP_RATES; |
| 77 | + tmp_group = MI_RATE_GROUP(*dest); |
| 78 | + tmp_idx = MI_RATE_IDX(*dest); |
| 79 | tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; |
| 80 | tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob); |
| 81 | |
| 82 | /* if max_tp_rate[0] is from MCS_GROUP max_prob_rate get selected from |
| 83 | * MCS_GROUP as well as CCK_GROUP rates do not allow aggregation */ |
| 84 | - max_tp_group = mi->max_tp_rate[0] / MCS_GROUP_RATES; |
| 85 | - max_tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES; |
| 86 | + max_tp_group = MI_RATE_GROUP(mi->max_tp_rate[0]); |
| 87 | + max_tp_idx = MI_RATE_IDX(mi->max_tp_rate[0]); |
| 88 | max_tp_prob = mi->groups[max_tp_group].rates[max_tp_idx].prob_avg; |
| 89 | |
| 90 | - if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES) && |
| 91 | + if (minstrel_ht_is_legacy_group(MI_RATE_GROUP(index)) && |
| 92 | !minstrel_ht_is_legacy_group(max_tp_group)) |
| 93 | return; |
| 94 | |
| 95 | @@ -529,8 +529,8 @@ minstrel_ht_set_best_prob_rate(struct mi |
| 96 | mrs->prob_avg < max_tp_prob) |
| 97 | return; |
| 98 | |
| 99 | - max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES; |
| 100 | - max_gpr_idx = mg->max_group_prob_rate % MCS_GROUP_RATES; |
| 101 | + max_gpr_group = MI_RATE_GROUP(mg->max_group_prob_rate); |
| 102 | + max_gpr_idx = MI_RATE_IDX(mg->max_group_prob_rate); |
| 103 | max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg; |
| 104 | |
| 105 | if (mrs->prob_avg > MINSTREL_FRAC(75, 100)) { |
| 106 | @@ -567,13 +567,13 @@ minstrel_ht_assign_best_tp_rates(struct |
| 107 | unsigned int tmp_group, tmp_idx, tmp_cck_tp, tmp_mcs_tp, tmp_prob; |
| 108 | int i; |
| 109 | |
| 110 | - tmp_group = tmp_legacy_tp_rate[0] / MCS_GROUP_RATES; |
| 111 | - tmp_idx = tmp_legacy_tp_rate[0] % MCS_GROUP_RATES; |
| 112 | + tmp_group = MI_RATE_GROUP(tmp_legacy_tp_rate[0]); |
| 113 | + tmp_idx = MI_RATE_IDX(tmp_legacy_tp_rate[0]); |
| 114 | tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; |
| 115 | tmp_cck_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob); |
| 116 | |
| 117 | - tmp_group = tmp_mcs_tp_rate[0] / MCS_GROUP_RATES; |
| 118 | - tmp_idx = tmp_mcs_tp_rate[0] % MCS_GROUP_RATES; |
| 119 | + tmp_group = MI_RATE_GROUP(tmp_mcs_tp_rate[0]); |
| 120 | + tmp_idx = MI_RATE_IDX(tmp_mcs_tp_rate[0]); |
| 121 | tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; |
| 122 | tmp_mcs_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob); |
| 123 | |
| 124 | @@ -600,14 +600,14 @@ minstrel_ht_prob_rate_reduce_streams(str |
| 125 | if (!mi->sta->ht_cap.ht_supported) |
| 126 | return; |
| 127 | |
| 128 | - tmp_max_streams = minstrel_mcs_groups[mi->max_tp_rate[0] / |
| 129 | - MCS_GROUP_RATES].streams; |
| 130 | + group = MI_RATE_GROUP(mi->max_tp_rate[0]); |
| 131 | + tmp_max_streams = minstrel_mcs_groups[group].streams; |
| 132 | for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { |
| 133 | mg = &mi->groups[group]; |
| 134 | if (!mi->supported[group] || group == MINSTREL_CCK_GROUP) |
| 135 | continue; |
| 136 | |
| 137 | - tmp_idx = mg->max_group_prob_rate % MCS_GROUP_RATES; |
| 138 | + tmp_idx = MI_RATE_IDX(mg->max_group_prob_rate); |
| 139 | tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg; |
| 140 | |
| 141 | if (tmp_tp < minstrel_ht_get_tp_avg(mi, group, tmp_idx, tmp_prob) && |
| 142 | @@ -644,8 +644,8 @@ minstrel_ht_find_probe_rates(struct mins |
| 143 | int i, g, max_dur; |
| 144 | int tp_idx; |
| 145 | |
| 146 | - tp_group = &minstrel_mcs_groups[mi->max_tp_rate[0] / MCS_GROUP_RATES]; |
| 147 | - tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES; |
| 148 | + tp_group = &minstrel_mcs_groups[MI_RATE_GROUP(mi->max_tp_rate[0])]; |
| 149 | + tp_idx = MI_RATE_IDX(mi->max_tp_rate[0]); |
| 150 | |
| 151 | max_dur = minstrel_get_duration(mi->max_tp_rate[0]); |
| 152 | if (faster_rate) |
| 153 | @@ -670,7 +670,7 @@ minstrel_ht_find_probe_rates(struct mins |
| 154 | if ((group->duration[i] << group->shift) > max_dur) |
| 155 | continue; |
| 156 | |
| 157 | - idx = g * MCS_GROUP_RATES + i; |
| 158 | + idx = MI_RATE(g, i); |
| 159 | if (idx == mi->max_tp_rate[0]) |
| 160 | continue; |
| 161 | |
| 162 | @@ -712,10 +712,10 @@ minstrel_ht_rate_sample_switch(struct mi |
| 163 | |
| 164 | /* If no suitable rate was found, try to pick the next one in the group */ |
| 165 | if (!n_rates) { |
| 166 | - int g_idx = mi->max_tp_rate[0] / MCS_GROUP_RATES; |
| 167 | + int g_idx = MI_RATE_GROUP(mi->max_tp_rate[0]); |
| 168 | u16 supported = mi->supported[g_idx]; |
| 169 | |
| 170 | - supported >>= mi->max_tp_rate[0] % MCS_GROUP_RATES; |
| 171 | + supported >>= MI_RATE_IDX(mi->max_tp_rate[0]); |
| 172 | for (i = 0; supported; supported >>= 1, i++) { |
| 173 | if (!(supported & 1)) |
| 174 | continue; |
| 175 | @@ -854,24 +854,27 @@ minstrel_ht_update_stats(struct minstrel |
| 176 | mi->sample_slow = 0; |
| 177 | mi->sample_count = 0; |
| 178 | |
| 179 | - memset(tmp_mcs_tp_rate, 0, sizeof(tmp_mcs_tp_rate)); |
| 180 | - memset(tmp_legacy_tp_rate, 0, sizeof(tmp_legacy_tp_rate)); |
| 181 | if (mi->supported[MINSTREL_CCK_GROUP]) |
| 182 | - for (j = 0; j < ARRAY_SIZE(tmp_legacy_tp_rate); j++) |
| 183 | - tmp_legacy_tp_rate[j] = MINSTREL_CCK_GROUP * MCS_GROUP_RATES; |
| 184 | + group = MINSTREL_CCK_GROUP; |
| 185 | else if (mi->supported[MINSTREL_OFDM_GROUP]) |
| 186 | - for (j = 0; j < ARRAY_SIZE(tmp_legacy_tp_rate); j++) |
| 187 | - tmp_legacy_tp_rate[j] = MINSTREL_OFDM_GROUP * MCS_GROUP_RATES; |
| 188 | + group = MINSTREL_OFDM_GROUP; |
| 189 | + else |
| 190 | + group = 0; |
| 191 | + |
| 192 | + index = MI_RATE(group, 0); |
| 193 | + for (j = 0; j < ARRAY_SIZE(tmp_legacy_tp_rate); j++) |
| 194 | + tmp_legacy_tp_rate[j] = index; |
| 195 | |
| 196 | if (mi->supported[MINSTREL_VHT_GROUP_0]) |
| 197 | - index = MINSTREL_VHT_GROUP_0 * MCS_GROUP_RATES; |
| 198 | + group = MINSTREL_VHT_GROUP_0; |
| 199 | else if (ht_supported) |
| 200 | - index = MINSTREL_HT_GROUP_0 * MCS_GROUP_RATES; |
| 201 | + group = MINSTREL_HT_GROUP_0; |
| 202 | else if (mi->supported[MINSTREL_CCK_GROUP]) |
| 203 | - index = MINSTREL_CCK_GROUP * MCS_GROUP_RATES; |
| 204 | + group = MINSTREL_CCK_GROUP; |
| 205 | else |
| 206 | - index = MINSTREL_OFDM_GROUP * MCS_GROUP_RATES; |
| 207 | + group = MINSTREL_OFDM_GROUP; |
| 208 | |
| 209 | + index = MI_RATE(group, 0); |
| 210 | tmp_max_prob_rate = index; |
| 211 | for (j = 0; j < ARRAY_SIZE(tmp_mcs_tp_rate); j++) |
| 212 | tmp_mcs_tp_rate[j] = index; |
| 213 | @@ -888,7 +891,7 @@ minstrel_ht_update_stats(struct minstrel |
| 214 | |
| 215 | /* (re)Initialize group rate indexes */ |
| 216 | for(j = 0; j < MAX_THR_RATES; j++) |
| 217 | - tmp_group_tp_rate[j] = MCS_GROUP_RATES * group; |
| 218 | + tmp_group_tp_rate[j] = MI_RATE(group, 0); |
| 219 | |
| 220 | if (group == MINSTREL_CCK_GROUP && ht_supported) |
| 221 | tp_rate = tmp_legacy_tp_rate; |
| 222 | @@ -897,7 +900,7 @@ minstrel_ht_update_stats(struct minstrel |
| 223 | if (!(mi->supported[group] & BIT(i))) |
| 224 | continue; |
| 225 | |
| 226 | - index = MCS_GROUP_RATES * group + i; |
| 227 | + index = MI_RATE(group, i); |
| 228 | |
| 229 | mrs = &mg->rates[i]; |
| 230 | mrs->retry_updated = false; |
| 231 | @@ -929,13 +932,13 @@ minstrel_ht_update_stats(struct minstrel |
| 232 | continue; |
| 233 | |
| 234 | mg = &mi->groups[group]; |
| 235 | - mg->max_group_prob_rate = MCS_GROUP_RATES * group; |
| 236 | + mg->max_group_prob_rate = MI_RATE(group, 0); |
| 237 | |
| 238 | for (i = 0; i < MCS_GROUP_RATES; i++) { |
| 239 | if (!(mi->supported[group] & BIT(i))) |
| 240 | continue; |
| 241 | |
| 242 | - index = MCS_GROUP_RATES * group + i; |
| 243 | + index = MI_RATE(group, i); |
| 244 | |
| 245 | /* Find max probability rate per group and global */ |
| 246 | minstrel_ht_set_best_prob_rate(mi, &tmp_max_prob_rate, |
| 247 | @@ -1022,7 +1025,7 @@ minstrel_downgrade_rate(struct minstrel_ |
| 248 | { |
| 249 | int group, orig_group; |
| 250 | |
| 251 | - orig_group = group = *idx / MCS_GROUP_RATES; |
| 252 | + orig_group = group = MI_RATE_GROUP(*idx); |
| 253 | while (group > 0) { |
| 254 | group--; |
| 255 | |
| 256 | @@ -1206,7 +1209,7 @@ minstrel_calc_retransmit(struct minstrel |
| 257 | ctime += (t_slot * cw) >> 1; |
| 258 | cw = min((cw << 1) | 1, mp->cw_max); |
| 259 | |
| 260 | - if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES)) { |
| 261 | + if (minstrel_ht_is_legacy_group(MI_RATE_GROUP(index))) { |
| 262 | overhead = mi->overhead_legacy; |
| 263 | overhead_rtscts = mi->overhead_legacy_rtscts; |
| 264 | } else { |
| 265 | @@ -1239,7 +1242,7 @@ static void |
| 266 | minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, |
| 267 | struct ieee80211_sta_rates *ratetbl, int offset, int index) |
| 268 | { |
| 269 | - int group_idx = index / MCS_GROUP_RATES; |
| 270 | + int group_idx = MI_RATE_GROUP(index); |
| 271 | const struct mcs_group *group = &minstrel_mcs_groups[group_idx]; |
| 272 | struct minstrel_rate_stats *mrs; |
| 273 | u8 idx; |
| 274 | @@ -1259,7 +1262,7 @@ minstrel_ht_set_rate(struct minstrel_pri |
| 275 | ratetbl->rate[offset].count_rts = mrs->retry_count_rtscts; |
| 276 | } |
| 277 | |
| 278 | - index %= MCS_GROUP_RATES; |
| 279 | + index = MI_RATE_IDX(index); |
| 280 | if (group_idx == MINSTREL_CCK_GROUP) |
| 281 | idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; |
| 282 | else if (group_idx == MINSTREL_OFDM_GROUP) |
| 283 | @@ -1289,17 +1292,17 @@ minstrel_ht_set_rate(struct minstrel_pri |
| 284 | static inline int |
| 285 | minstrel_ht_get_prob_avg(struct minstrel_ht_sta *mi, int rate) |
| 286 | { |
| 287 | - int group = rate / MCS_GROUP_RATES; |
| 288 | - rate %= MCS_GROUP_RATES; |
| 289 | + int group = MI_RATE_GROUP(rate); |
| 290 | + rate = MI_RATE_IDX(rate); |
| 291 | return mi->groups[group].rates[rate].prob_avg; |
| 292 | } |
| 293 | |
| 294 | static int |
| 295 | minstrel_ht_get_max_amsdu_len(struct minstrel_ht_sta *mi) |
| 296 | { |
| 297 | - int group = mi->max_prob_rate / MCS_GROUP_RATES; |
| 298 | + int group = MI_RATE_GROUP(mi->max_prob_rate); |
| 299 | const struct mcs_group *g = &minstrel_mcs_groups[group]; |
| 300 | - int rate = mi->max_prob_rate % MCS_GROUP_RATES; |
| 301 | + int rate = MI_RATE_IDX(mi->max_prob_rate); |
| 302 | unsigned int duration; |
| 303 | |
| 304 | /* Disable A-MSDU if max_prob_rate is bad */ |
| 305 | @@ -1405,7 +1408,7 @@ minstrel_get_sample_rate(struct minstrel |
| 306 | return -1; |
| 307 | |
| 308 | mrs = &mg->rates[sample_idx]; |
| 309 | - sample_idx += sample_group * MCS_GROUP_RATES; |
| 310 | + sample_idx += MI_RATE(sample_group, 0); |
| 311 | |
| 312 | tp_rate1 = mi->max_tp_rate[0]; |
| 313 | |
| 314 | @@ -1455,8 +1458,7 @@ minstrel_get_sample_rate(struct minstrel |
| 315 | * if the link is working perfectly. |
| 316 | */ |
| 317 | |
| 318 | - cur_max_tp_streams = minstrel_mcs_groups[tp_rate1 / |
| 319 | - MCS_GROUP_RATES].streams; |
| 320 | + cur_max_tp_streams = minstrel_mcs_groups[MI_RATE_GROUP(tp_rate1)].streams; |
| 321 | if (sample_dur >= minstrel_get_duration(tp_rate2) && |
| 322 | (cur_max_tp_streams - 1 < |
| 323 | minstrel_mcs_groups[sample_group].streams || |
| 324 | @@ -1484,7 +1486,7 @@ minstrel_ht_get_rate(void *priv, struct |
| 325 | int sample_idx; |
| 326 | |
| 327 | if (!(info->flags & IEEE80211_TX_CTL_AMPDU) && |
| 328 | - !minstrel_ht_is_legacy_group(mi->max_prob_rate / MCS_GROUP_RATES)) |
| 329 | + !minstrel_ht_is_legacy_group(MI_RATE_GROUP(mi->max_prob_rate))) |
| 330 | minstrel_aggr_check(sta, txrc->skb); |
| 331 | |
| 332 | info->flags |= mi->tx_flags; |
| 333 | @@ -1512,8 +1514,8 @@ minstrel_ht_get_rate(void *priv, struct |
| 334 | if (sample_idx < 0) |
| 335 | return; |
| 336 | |
| 337 | - sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES]; |
| 338 | - sample_idx %= MCS_GROUP_RATES; |
| 339 | + sample_group = &minstrel_mcs_groups[MI_RATE_GROUP(sample_idx)]; |
| 340 | + sample_idx = MI_RATE_IDX(sample_idx); |
| 341 | |
| 342 | if (sample_group == &minstrel_mcs_groups[MINSTREL_CCK_GROUP] && |
| 343 | (sample_idx >= 4) != txrc->short_preamble) |
| 344 | @@ -1529,7 +1531,7 @@ minstrel_ht_get_rate(void *priv, struct |
| 345 | int idx = sample_idx % ARRAY_SIZE(mp->ofdm_rates[0]); |
| 346 | rate->idx = mp->ofdm_rates[mi->band][idx]; |
| 347 | } else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) { |
| 348 | - ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES, |
| 349 | + ieee80211_rate_set_vht(rate, MI_RATE_IDX(sample_idx), |
| 350 | sample_group->streams); |
| 351 | } else { |
| 352 | rate->idx = sample_idx + (sample_group->streams - 1) * 8; |
| 353 | @@ -1898,8 +1900,8 @@ static u32 minstrel_ht_get_expected_thro |
| 354 | struct minstrel_ht_sta *mi = priv_sta; |
| 355 | int i, j, prob, tp_avg; |
| 356 | |
| 357 | - i = mi->max_tp_rate[0] / MCS_GROUP_RATES; |
| 358 | - j = mi->max_tp_rate[0] % MCS_GROUP_RATES; |
| 359 | + i = MI_RATE_GROUP(mi->max_tp_rate[0]); |
| 360 | + j = MI_RATE_IDX(mi->max_tp_rate[0]); |
| 361 | prob = mi->groups[i].rates[j].prob_avg; |
| 362 | |
| 363 | /* convert tp_avg from pkt per second in kbps */ |
| 364 | --- a/net/mac80211/rc80211_minstrel_ht.h |
| 365 | +++ b/net/mac80211/rc80211_minstrel_ht.h |
| 366 | @@ -6,6 +6,8 @@ |
| 367 | #ifndef __RC_MINSTREL_HT_H |
| 368 | #define __RC_MINSTREL_HT_H |
| 369 | |
| 370 | +#include <linux/bitfield.h> |
| 371 | + |
| 372 | /* number of highest throughput rates to consider*/ |
| 373 | #define MAX_THR_RATES 4 |
| 374 | #define SAMPLE_COLUMNS 10 /* number of columns in sample table */ |
| 375 | @@ -57,6 +59,17 @@ |
| 376 | |
| 377 | #define MCS_GROUP_RATES 10 |
| 378 | |
| 379 | +#define MI_RATE_IDX_MASK GENMASK(3, 0) |
| 380 | +#define MI_RATE_GROUP_MASK GENMASK(15, 4) |
| 381 | + |
| 382 | +#define MI_RATE(_group, _idx) \ |
| 383 | + (FIELD_PREP(MI_RATE_GROUP_MASK, _group) | \ |
| 384 | + FIELD_PREP(MI_RATE_IDX_MASK, _idx)) |
| 385 | + |
| 386 | +#define MI_RATE_IDX(_rate) FIELD_GET(MI_RATE_IDX_MASK, _rate) |
| 387 | +#define MI_RATE_GROUP(_rate) FIELD_GET(MI_RATE_GROUP_MASK, _rate) |
| 388 | + |
| 389 | + |
| 390 | struct minstrel_priv { |
| 391 | struct ieee80211_hw *hw; |
| 392 | bool has_mrr; |
| 393 | --- a/net/mac80211/rc80211_minstrel_ht_debugfs.c |
| 394 | +++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c |
| 395 | @@ -56,7 +56,7 @@ minstrel_ht_stats_dump(struct minstrel_h |
| 396 | |
| 397 | for (j = 0; j < MCS_GROUP_RATES; j++) { |
| 398 | struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j]; |
| 399 | - int idx = i * MCS_GROUP_RATES + j; |
| 400 | + int idx = MI_RATE(i, j); |
| 401 | unsigned int duration; |
| 402 | |
| 403 | if (!(mi->supported[i] & BIT(j))) |
| 404 | @@ -201,7 +201,7 @@ minstrel_ht_stats_csv_dump(struct minstr |
| 405 | |
| 406 | for (j = 0; j < MCS_GROUP_RATES; j++) { |
| 407 | struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j]; |
| 408 | - int idx = i * MCS_GROUP_RATES + j; |
| 409 | + int idx = MI_RATE(i, j); |
| 410 | unsigned int duration; |
| 411 | |
| 412 | if (!(mi->supported[i] & BIT(j))) |