8 #include <linux/netdevice.h>
9 #include <linux/types.h>
12 #include <linux/random.h>
19 #define AVG_PKT_SIZE 1200
20 #define SAMPLE_COLUMNS 10
24 #define MCS_NBITS (AVG_PKT_SIZE << 3)
27 #define MCS_NSYMS(bps) ((MCS_NBITS + (bps) - 1) / (bps))
30 #define MCS_SYMBOL_TIME(sgi, syms) \
32 ((syms) * 18 + 4) / 5 : \
37 #define MCS_DURATION(streams, sgi, bps) MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps)))
42 #define GROUP_IDX(_streams, _sgi, _ht40) \
43 MINSTREL_MAX_STREAMS * 2 * _ht40 + \
44 MINSTREL_MAX_STREAMS * _sgi + \
48 #define MCS_GROUP(_streams, _sgi, _ht40) \
49 [GROUP_IDX(_streams, _sgi, _ht40)] = { \
50 .streams = _streams, \
52 (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \
53 (_ht40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \
55 MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26), \
56 MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52), \
57 MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78), \
58 MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104), \
59 MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156), \
60 MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208), \
61 MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234), \
62 MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) \
77 #if MINSTREL_MAX_STREAMS >= 3
83 #if MINSTREL_MAX_STREAMS >= 3
89 #if MINSTREL_MAX_STREAMS >= 3
95 #if MINSTREL_MAX_STREAMS >= 3
106 minstrel_ewma(
int old,
int new,
int weight)
108 return (
new * (100 - weight) + old * weight) / 100;
206 for (group = 0; group <
ARRAY_SIZE(minstrel_mcs_groups); group++) {
227 index = MCS_GROUP_RATES * group +
i;
228 minstrel_calc_rate_ewma(mr);
229 minstrel_ht_calc_tp(mi, group, i);
235 if (!i && minstrel_mcs_groups[group].
streams == 1)
245 if (mr->
cur_tp > cur_tp) {
248 mr = minstrel_get_ratestats(mi, index);
254 if (mr->
cur_tp > cur_tp2) {
268 for (group = 0; group <
ARRAY_SIZE(minstrel_mcs_groups); group++) {
274 if (cur_prob_tp < mr->cur_tp &&
275 minstrel_mcs_groups[group].
streams == 1) {
282 if (cur_tp < mr->cur_tp) {
290 if (cur_tp2 < mr->cur_tp) {
324 if (++mg->
index >= MCS_GROUP_RATES) {
337 int group, orig_group;
343 if (!mi->
groups[group].supported)
346 if (minstrel_mcs_groups[group].
streams >
347 minstrel_mcs_groups[orig_group].
streams)
372 if (
likely(sta->ampdu_mlme.tid_tx[tid]))
405 info->
status.ampdu_ack_len =
407 info->
status.ampdu_len = 1;
422 for (i = 0; !last; i++) {
424 !minstrel_ht_txstat_valid(&ar[i + 1]);
426 if (!minstrel_ht_txstat_valid(&ar[i]))
429 group = minstrel_ht_get_group_idx(&ar[i]);
442 rate = minstrel_get_ratestats(mi, mi->
max_tp_rate);
446 minstrel_downgrade_rate(mi, &mi->
max_tp_rate,
true);
455 minstrel_ht_update_stats(mp, mi);
457 minstrel_aggr_check(sta, skb);
467 unsigned int tx_time, tx_time_rtscts, tx_time_data;
468 unsigned int cw = mp->
cw_min;
469 unsigned int ctime = 0;
470 unsigned int t_slot = 9;
473 mr = minstrel_get_ratestats(mi, index);
488 ctime = (t_slot * cw) >> 1;
490 ctime += (t_slot * cw) >> 1;
494 tx_time = ctime + 2 * (mi->
overhead + tx_time_data);
500 ctime = (t_slot * cw) >> 1;
504 tx_time += ctime + mi->
overhead + tx_time_data;
507 if (tx_time_rtscts < mp->segment_size)
509 }
while ((tx_time < mp->segment_size) &&
522 mr = minstrel_get_ratestats(mi, index);
524 minstrel_calc_retransmit(mp, mi, index);
538 rate->
idx = index % MCS_GROUP_RATES + (group->
streams - 1) * MCS_GROUP_RATES;
542 minstrel_get_duration(
int index)
566 mr = &mg->
rates[sample_idx];
568 minstrel_next_sample_idx(mi);
588 if (minstrel_get_duration(sample_idx) >
601 minstrel_ht_get_rate(
void *priv,
struct ieee80211_sta *sta,
void *priv_sta,
621 if (mp->
hw->max_rates == 1 &&
625 sample_idx = minstrel_get_sample_rate(mp, mi);
627 #ifdef CONFIG_MAC80211_DEBUGFS
629 if (mp->fixed_rate_idx != -1) {
637 if (sample_idx >= 0) {
639 minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx,
643 minstrel_ht_set_rate(mp, mi, &ar[0], mi->
max_tp_rate,
647 if (mp->
hw->max_rates >= 3) {
654 minstrel_ht_set_rate(mp, mi, &ar[1], mi->
max_tp_rate,
665 }
else if (mp->
hw->max_rates == 2) {
707 if (!sta->
ht_cap.ht_supported)
714 memset(mi, 0,
sizeof(*mi));
757 if ((sta_cap & req) !=
req)
762 minstrel_mcs_groups[i].
streams > 1)
768 if (mi->
groups[i].supported)
789 minstrel_ht_update_caps(priv, sband, sta, priv_sta);
797 minstrel_ht_update_caps(priv, sband, sta, priv_sta);
811 sband = hw->
wiphy->bands[
i];
816 msp = kzalloc(
sizeof(*msp), gfp);
838 minstrel_ht_free_sta(
void *priv,
struct ieee80211_sta *sta,
void *priv_sta)
854 minstrel_ht_free(
void *priv)
860 .name =
"minstrel_ht",
861 .tx_status = minstrel_ht_tx_status,
862 .get_rate = minstrel_ht_get_rate,
863 .rate_init = minstrel_ht_rate_init,
864 .rate_update = minstrel_ht_rate_update,
865 .alloc_sta = minstrel_ht_alloc_sta,
866 .free_sta = minstrel_ht_free_sta,
867 .alloc = minstrel_ht_alloc,
868 .free = minstrel_ht_free,
869 #ifdef CONFIG_MAC80211_DEBUGFS
877 init_sample_table(
void)
882 memset(sample_table, 0xff,
sizeof(sample_table));
886 new_idx = (i + rnd[
i]) % MCS_GROUP_RATES;
888 while (sample_table[col][new_idx] != 0xff)
889 new_idx = (new_idx + 1) % MCS_GROUP_RATES;
891 sample_table[col][new_idx] =
i;