linux/net/mac80211/rc80211_minstrel_ht.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2010-2013 Felix Fietkau <nbd@openwrt.org>
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 as
   6 * published by the Free Software Foundation.
   7 */
   8#include <linux/netdevice.h>
   9#include <linux/types.h>
  10#include <linux/skbuff.h>
  11#include <linux/debugfs.h>
  12#include <linux/random.h>
  13#include <linux/moduleparam.h>
  14#include <linux/ieee80211.h>
  15#include <net/mac80211.h>
  16#include "rate.h"
  17#include "sta_info.h"
  18#include "rc80211_minstrel.h"
  19#include "rc80211_minstrel_ht.h"
  20
  21#define AVG_AMPDU_SIZE  16
  22#define AVG_PKT_SIZE    1200
  23
  24/* Number of bits for an average sized packet */
  25#define MCS_NBITS ((AVG_PKT_SIZE * AVG_AMPDU_SIZE) << 3)
  26
  27/* Number of symbols for a packet with (bps) bits per symbol */
  28#define MCS_NSYMS(bps) DIV_ROUND_UP(MCS_NBITS, (bps))
  29
  30/* Transmission time (nanoseconds) for a packet containing (syms) symbols */
  31#define MCS_SYMBOL_TIME(sgi, syms)                                      \
  32        (sgi ?                                                          \
  33          ((syms) * 18000 + 4000) / 5 : /* syms * 3.6 us */             \
  34          ((syms) * 1000) << 2          /* syms * 4 us */               \
  35        )
  36
  37/* Transmit duration for the raw data part of an average sized packet */
  38#define MCS_DURATION(streams, sgi, bps) \
  39        (MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps))) / AVG_AMPDU_SIZE)
  40
  41#define BW_20                   0
  42#define BW_40                   1
  43#define BW_80                   2
  44
  45/*
  46 * Define group sort order: HT40 -> SGI -> #streams
  47 */
  48#define GROUP_IDX(_streams, _sgi, _ht40)        \
  49        MINSTREL_HT_GROUP_0 +                   \
  50        MINSTREL_MAX_STREAMS * 2 * _ht40 +      \
  51        MINSTREL_MAX_STREAMS * _sgi +   \
  52        _streams - 1
  53
  54/* MCS rate information for an MCS group */
  55#define MCS_GROUP(_streams, _sgi, _ht40)                                \
  56        [GROUP_IDX(_streams, _sgi, _ht40)] = {                          \
  57        .streams = _streams,                                            \
  58        .flags =                                                        \
  59                IEEE80211_TX_RC_MCS |                                   \
  60                (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) |                 \
  61                (_ht40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0),             \
  62        .duration = {                                                   \
  63                MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26),          \
  64                MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52),         \
  65                MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78),         \
  66                MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104),        \
  67                MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156),        \
  68                MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208),        \
  69                MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234),        \
  70                MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260)         \
  71        }                                                               \
  72}
  73
  74#define VHT_GROUP_IDX(_streams, _sgi, _bw)                              \
  75        (MINSTREL_VHT_GROUP_0 +                                         \
  76         MINSTREL_MAX_STREAMS * 2 * (_bw) +                             \
  77         MINSTREL_MAX_STREAMS * (_sgi) +                                \
  78         (_streams) - 1)
  79
  80#define BW2VBPS(_bw, r3, r2, r1)                                        \
  81        (_bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1)
  82
  83#define VHT_GROUP(_streams, _sgi, _bw)                                  \
  84        [VHT_GROUP_IDX(_streams, _sgi, _bw)] = {                        \
  85        .streams = _streams,                                            \
  86        .flags =                                                        \
  87                IEEE80211_TX_RC_VHT_MCS |                               \
  88                (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) |                 \
  89                (_bw == BW_80 ? IEEE80211_TX_RC_80_MHZ_WIDTH :          \
  90                 _bw == BW_40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0),      \
  91        .duration = {                                                   \
  92                MCS_DURATION(_streams, _sgi,                            \
  93                             BW2VBPS(_bw,  117,  54,  26)),             \
  94                MCS_DURATION(_streams, _sgi,                            \
  95                             BW2VBPS(_bw,  234, 108,  52)),             \
  96                MCS_DURATION(_streams, _sgi,                            \
  97                             BW2VBPS(_bw,  351, 162,  78)),             \
  98                MCS_DURATION(_streams, _sgi,                            \
  99                             BW2VBPS(_bw,  468, 216, 104)),             \
 100                MCS_DURATION(_streams, _sgi,                            \
 101                             BW2VBPS(_bw,  702, 324, 156)),             \
 102                MCS_DURATION(_streams, _sgi,                            \
 103                             BW2VBPS(_bw,  936, 432, 208)),             \
 104                MCS_DURATION(_streams, _sgi,                            \
 105                             BW2VBPS(_bw, 1053, 486, 234)),             \
 106                MCS_DURATION(_streams, _sgi,                            \
 107                             BW2VBPS(_bw, 1170, 540, 260)),             \
 108                MCS_DURATION(_streams, _sgi,                            \
 109                             BW2VBPS(_bw, 1404, 648, 312)),             \
 110                MCS_DURATION(_streams, _sgi,                            \
 111                             BW2VBPS(_bw, 1560, 720, 346))              \
 112        }                                                               \
 113}
 114
 115#define CCK_DURATION(_bitrate, _short, _len)            \
 116        (1000 * (10 /* SIFS */ +                        \
 117         (_short ? 72 + 24 : 144 + 48) +                \
 118         (8 * (_len + 4) * 10) / (_bitrate)))
 119
 120#define CCK_ACK_DURATION(_bitrate, _short)                      \
 121        (CCK_DURATION((_bitrate > 10 ? 20 : 10), false, 60) +   \
 122         CCK_DURATION(_bitrate, _short, AVG_PKT_SIZE))
 123
 124#define CCK_DURATION_LIST(_short)                       \
 125        CCK_ACK_DURATION(10, _short),                   \
 126        CCK_ACK_DURATION(20, _short),                   \
 127        CCK_ACK_DURATION(55, _short),                   \
 128        CCK_ACK_DURATION(110, _short)
 129
 130#define CCK_GROUP                                       \
 131        [MINSTREL_CCK_GROUP] = {                        \
 132                .streams = 0,                           \
 133                .flags = 0,                             \
 134                .duration = {                           \
 135                        CCK_DURATION_LIST(false),       \
 136                        CCK_DURATION_LIST(true)         \
 137                }                                       \
 138        }
 139
 140#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
 141static bool minstrel_vht_only = true;
 142module_param(minstrel_vht_only, bool, 0644);
 143MODULE_PARM_DESC(minstrel_vht_only,
 144                 "Use only VHT rates when VHT is supported by sta.");
 145#endif
 146
 147/*
 148 * To enable sufficiently targeted rate sampling, MCS rates are divided into
 149 * groups, based on the number of streams and flags (HT40, SGI) that they
 150 * use.
 151 *
 152 * Sortorder has to be fixed for GROUP_IDX macro to be applicable:
 153 * BW -> SGI -> #streams
 154 */
 155const struct mcs_group minstrel_mcs_groups[] = {
 156        MCS_GROUP(1, 0, BW_20),
 157        MCS_GROUP(2, 0, BW_20),
 158        MCS_GROUP(3, 0, BW_20),
 159
 160        MCS_GROUP(1, 1, BW_20),
 161        MCS_GROUP(2, 1, BW_20),
 162        MCS_GROUP(3, 1, BW_20),
 163
 164        MCS_GROUP(1, 0, BW_40),
 165        MCS_GROUP(2, 0, BW_40),
 166        MCS_GROUP(3, 0, BW_40),
 167
 168        MCS_GROUP(1, 1, BW_40),
 169        MCS_GROUP(2, 1, BW_40),
 170        MCS_GROUP(3, 1, BW_40),
 171
 172        CCK_GROUP,
 173
 174#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
 175        VHT_GROUP(1, 0, BW_20),
 176        VHT_GROUP(2, 0, BW_20),
 177        VHT_GROUP(3, 0, BW_20),
 178
 179        VHT_GROUP(1, 1, BW_20),
 180        VHT_GROUP(2, 1, BW_20),
 181        VHT_GROUP(3, 1, BW_20),
 182
 183        VHT_GROUP(1, 0, BW_40),
 184        VHT_GROUP(2, 0, BW_40),
 185        VHT_GROUP(3, 0, BW_40),
 186
 187        VHT_GROUP(1, 1, BW_40),
 188        VHT_GROUP(2, 1, BW_40),
 189        VHT_GROUP(3, 1, BW_40),
 190
 191        VHT_GROUP(1, 0, BW_80),
 192        VHT_GROUP(2, 0, BW_80),
 193        VHT_GROUP(3, 0, BW_80),
 194
 195        VHT_GROUP(1, 1, BW_80),
 196        VHT_GROUP(2, 1, BW_80),
 197        VHT_GROUP(3, 1, BW_80),
 198#endif
 199};
 200
 201static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly;
 202
 203static void
 204minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi);
 205
 206/*
 207 * Some VHT MCSes are invalid (when Ndbps / Nes is not an integer)
 208 * e.g for MCS9@20MHzx1Nss: Ndbps=8x52*(5/6) Nes=1
 209 *
 210 * Returns the valid mcs map for struct minstrel_mcs_group_data.supported
 211 */
 212static u16
 213minstrel_get_valid_vht_rates(int bw, int nss, __le16 mcs_map)
 214{
 215        u16 mask = 0;
 216
 217        if (bw == BW_20) {
 218                if (nss != 3 && nss != 6)
 219                        mask = BIT(9);
 220        } else if (bw == BW_80) {
 221                if (nss == 3 || nss == 7)
 222                        mask = BIT(6);
 223                else if (nss == 6)
 224                        mask = BIT(9);
 225        } else {
 226                WARN_ON(bw != BW_40);
 227        }
 228
 229        switch ((le16_to_cpu(mcs_map) >> (2 * (nss - 1))) & 3) {
 230        case IEEE80211_VHT_MCS_SUPPORT_0_7:
 231                mask |= 0x300;
 232                break;
 233        case IEEE80211_VHT_MCS_SUPPORT_0_8:
 234                mask |= 0x200;
 235                break;
 236        case IEEE80211_VHT_MCS_SUPPORT_0_9:
 237                break;
 238        default:
 239                mask = 0x3ff;
 240        }
 241
 242        return 0x3ff & ~mask;
 243}
 244
 245/*
 246 * Look up an MCS group index based on mac80211 rate information
 247 */
 248static int
 249minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate)
 250{
 251        return GROUP_IDX((rate->idx / 8) + 1,
 252                         !!(rate->flags & IEEE80211_TX_RC_SHORT_GI),
 253                         !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH));
 254}
 255
 256static int
 257minstrel_vht_get_group_idx(struct ieee80211_tx_rate *rate)
 258{
 259        return VHT_GROUP_IDX(ieee80211_rate_get_vht_nss(rate),
 260                             !!(rate->flags & IEEE80211_TX_RC_SHORT_GI),
 261                             !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) +
 262                             2*!!(rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH));
 263}
 264
 265static struct minstrel_rate_stats *
 266minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
 267                      struct ieee80211_tx_rate *rate)
 268{
 269        int group, idx;
 270
 271        if (rate->flags & IEEE80211_TX_RC_MCS) {
 272                group = minstrel_ht_get_group_idx(rate);
 273                idx = rate->idx % 8;
 274        } else if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
 275                group = minstrel_vht_get_group_idx(rate);
 276                idx = ieee80211_rate_get_vht_mcs(rate);
 277        } else {
 278                group = MINSTREL_CCK_GROUP;
 279
 280                for (idx = 0; idx < ARRAY_SIZE(mp->cck_rates); idx++)
 281                        if (rate->idx == mp->cck_rates[idx])
 282                                break;
 283
 284                /* short preamble */
 285                if (!(mi->supported[group] & BIT(idx)))
 286                        idx += 4;
 287        }
 288        return &mi->groups[group].rates[idx];
 289}
 290
 291static inline struct minstrel_rate_stats *
 292minstrel_get_ratestats(struct minstrel_ht_sta *mi, int index)
 293{
 294        return &mi->groups[index / MCS_GROUP_RATES].rates[index % MCS_GROUP_RATES];
 295}
 296
 297/*
 298 * Return current throughput based on the average A-MPDU length, taking into
 299 * account the expected number of retransmissions and their expected length
 300 */
 301int
 302minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate,
 303                       int prob_ewma)
 304{
 305        unsigned int nsecs = 0;
 306
 307        /* do not account throughput if sucess prob is below 10% */
 308        if (prob_ewma < MINSTREL_FRAC(10, 100))
 309                return 0;
 310
 311        if (group != MINSTREL_CCK_GROUP)
 312                nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len);
 313
 314        nsecs += minstrel_mcs_groups[group].duration[rate];
 315
 316        /*
 317         * For the throughput calculation, limit the probability value to 90% to
 318         * account for collision related packet error rate fluctuation
 319         * (prob is scaled - see MINSTREL_FRAC above)
 320         */
 321        if (prob_ewma > MINSTREL_FRAC(90, 100))
 322                return MINSTREL_TRUNC(100000 * ((MINSTREL_FRAC(90, 100) * 1000)
 323                                                                      / nsecs));
 324        else
 325                return MINSTREL_TRUNC(100000 * ((prob_ewma * 1000) / nsecs));
 326}
 327
 328/*
 329 * Find & sort topmost throughput rates
 330 *
 331 * If multiple rates provide equal throughput the sorting is based on their
 332 * current success probability. Higher success probability is preferred among
 333 * MCS groups, CCK rates do not provide aggregation and are therefore at last.
 334 */
 335static void
 336minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u16 index,
 337                               u16 *tp_list)
 338{
 339        int cur_group, cur_idx, cur_tp_avg, cur_prob;
 340        int tmp_group, tmp_idx, tmp_tp_avg, tmp_prob;
 341        int j = MAX_THR_RATES;
 342
 343        cur_group = index / MCS_GROUP_RATES;
 344        cur_idx = index  % MCS_GROUP_RATES;
 345        cur_prob = mi->groups[cur_group].rates[cur_idx].prob_ewma;
 346        cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx, cur_prob);
 347
 348        do {
 349                tmp_group = tp_list[j - 1] / MCS_GROUP_RATES;
 350                tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES;
 351                tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
 352                tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx,
 353                                                    tmp_prob);
 354                if (cur_tp_avg < tmp_tp_avg ||
 355                    (cur_tp_avg == tmp_tp_avg && cur_prob <= tmp_prob))
 356                        break;
 357                j--;
 358        } while (j > 0);
 359
 360        if (j < MAX_THR_RATES - 1) {
 361                memmove(&tp_list[j + 1], &tp_list[j], (sizeof(*tp_list) *
 362                       (MAX_THR_RATES - (j + 1))));
 363        }
 364        if (j < MAX_THR_RATES)
 365                tp_list[j] = index;
 366}
 367
 368/*
 369 * Find and set the topmost probability rate per sta and per group
 370 */
 371static void
 372minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 index)
 373{
 374        struct minstrel_mcs_group_data *mg;
 375        struct minstrel_rate_stats *mrs;
 376        int tmp_group, tmp_idx, tmp_tp_avg, tmp_prob;
 377        int max_tp_group, cur_tp_avg, cur_group, cur_idx;
 378        int max_gpr_group, max_gpr_idx;
 379        int max_gpr_tp_avg, max_gpr_prob;
 380
 381        cur_group = index / MCS_GROUP_RATES;
 382        cur_idx = index % MCS_GROUP_RATES;
 383        mg = &mi->groups[index / MCS_GROUP_RATES];
 384        mrs = &mg->rates[index % MCS_GROUP_RATES];
 385
 386        tmp_group = mi->max_prob_rate / MCS_GROUP_RATES;
 387        tmp_idx = mi->max_prob_rate % MCS_GROUP_RATES;
 388        tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
 389        tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
 390
 391        /* if max_tp_rate[0] is from MCS_GROUP max_prob_rate get selected from
 392         * MCS_GROUP as well as CCK_GROUP rates do not allow aggregation */
 393        max_tp_group = mi->max_tp_rate[0] / MCS_GROUP_RATES;
 394        if((index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) &&
 395            (max_tp_group != MINSTREL_CCK_GROUP))
 396                return;
 397
 398        max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES;
 399        max_gpr_idx = mg->max_group_prob_rate % MCS_GROUP_RATES;
 400        max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_ewma;
 401
 402        if (mrs->prob_ewma > MINSTREL_FRAC(75, 100)) {
 403                cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx,
 404                                                    mrs->prob_ewma);
 405                if (cur_tp_avg > tmp_tp_avg)
 406                        mi->max_prob_rate = index;
 407
 408                max_gpr_tp_avg = minstrel_ht_get_tp_avg(mi, max_gpr_group,
 409                                                        max_gpr_idx,
 410                                                        max_gpr_prob);
 411                if (cur_tp_avg > max_gpr_tp_avg)
 412                        mg->max_group_prob_rate = index;
 413        } else {
 414                if (mrs->prob_ewma > tmp_prob)
 415                        mi->max_prob_rate = index;
 416                if (mrs->prob_ewma > max_gpr_prob)
 417                        mg->max_group_prob_rate = index;
 418        }
 419}
 420
 421
 422/*
 423 * Assign new rate set per sta and use CCK rates only if the fastest
 424 * rate (max_tp_rate[0]) is from CCK group. This prohibits such sorted
 425 * rate sets where MCS and CCK rates are mixed, because CCK rates can
 426 * not use aggregation.
 427 */
 428static void
 429minstrel_ht_assign_best_tp_rates(struct minstrel_ht_sta *mi,
 430                                 u16 tmp_mcs_tp_rate[MAX_THR_RATES],
 431                                 u16 tmp_cck_tp_rate[MAX_THR_RATES])
 432{
 433        unsigned int tmp_group, tmp_idx, tmp_cck_tp, tmp_mcs_tp, tmp_prob;
 434        int i;
 435
 436        tmp_group = tmp_cck_tp_rate[0] / MCS_GROUP_RATES;
 437        tmp_idx = tmp_cck_tp_rate[0] % MCS_GROUP_RATES;
 438        tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
 439        tmp_cck_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
 440
 441        tmp_group = tmp_mcs_tp_rate[0] / MCS_GROUP_RATES;
 442        tmp_idx = tmp_mcs_tp_rate[0] % MCS_GROUP_RATES;
 443        tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
 444        tmp_mcs_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
 445
 446        if (tmp_cck_tp > tmp_mcs_tp) {
 447                for(i = 0; i < MAX_THR_RATES; i++) {
 448                        minstrel_ht_sort_best_tp_rates(mi, tmp_cck_tp_rate[i],
 449                                                       tmp_mcs_tp_rate);
 450                }
 451        }
 452
 453}
 454
 455/*
 456 * Try to increase robustness of max_prob rate by decrease number of
 457 * streams if possible.
 458 */
 459static inline void
 460minstrel_ht_prob_rate_reduce_streams(struct minstrel_ht_sta *mi)
 461{
 462        struct minstrel_mcs_group_data *mg;
 463        int tmp_max_streams, group, tmp_idx, tmp_prob;
 464        int tmp_tp = 0;
 465
 466        tmp_max_streams = minstrel_mcs_groups[mi->max_tp_rate[0] /
 467                          MCS_GROUP_RATES].streams;
 468        for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) {
 469                mg = &mi->groups[group];
 470                if (!mi->supported[group] || group == MINSTREL_CCK_GROUP)
 471                        continue;
 472
 473                tmp_idx = mg->max_group_prob_rate % MCS_GROUP_RATES;
 474                tmp_prob = mi->groups[group].rates[tmp_idx].prob_ewma;
 475
 476                if (tmp_tp < minstrel_ht_get_tp_avg(mi, group, tmp_idx, tmp_prob) &&
 477                   (minstrel_mcs_groups[group].streams < tmp_max_streams)) {
 478                                mi->max_prob_rate = mg->max_group_prob_rate;
 479                                tmp_tp = minstrel_ht_get_tp_avg(mi, group,
 480                                                                tmp_idx,
 481                                                                tmp_prob);
 482                }
 483        }
 484}
 485
 486/*
 487 * Update rate statistics and select new primary rates
 488 *
 489 * Rules for rate selection:
 490 *  - max_prob_rate must use only one stream, as a tradeoff between delivery
 491 *    probability and throughput during strong fluctuations
 492 *  - as long as the max prob rate has a probability of more than 75%, pick
 493 *    higher throughput rates, even if the probablity is a bit lower
 494 */
 495static void
 496minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
 497{
 498        struct minstrel_mcs_group_data *mg;
 499        struct minstrel_rate_stats *mrs;
 500        int group, i, j, cur_prob;
 501        u16 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES];
 502        u16 tmp_cck_tp_rate[MAX_THR_RATES], index;
 503
 504        if (mi->ampdu_packets > 0) {
 505                mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len,
 506                        MINSTREL_FRAC(mi->ampdu_len, mi->ampdu_packets), EWMA_LEVEL);
 507                mi->ampdu_len = 0;
 508                mi->ampdu_packets = 0;
 509        }
 510
 511        mi->sample_slow = 0;
 512        mi->sample_count = 0;
 513
 514        /* Initialize global rate indexes */
 515        for(j = 0; j < MAX_THR_RATES; j++){
 516                tmp_mcs_tp_rate[j] = 0;
 517                tmp_cck_tp_rate[j] = 0;
 518        }
 519
 520        /* Find best rate sets within all MCS groups*/
 521        for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) {
 522
 523                mg = &mi->groups[group];
 524                if (!mi->supported[group])
 525                        continue;
 526
 527                mi->sample_count++;
 528
 529                /* (re)Initialize group rate indexes */
 530                for(j = 0; j < MAX_THR_RATES; j++)
 531                        tmp_group_tp_rate[j] = group;
 532
 533                for (i = 0; i < MCS_GROUP_RATES; i++) {
 534                        if (!(mi->supported[group] & BIT(i)))
 535                                continue;
 536
 537                        index = MCS_GROUP_RATES * group + i;
 538
 539                        mrs = &mg->rates[i];
 540                        mrs->retry_updated = false;
 541                        minstrel_calc_rate_stats(mrs);
 542                        cur_prob = mrs->prob_ewma;
 543
 544                        if (minstrel_ht_get_tp_avg(mi, group, i, cur_prob) == 0)
 545                                continue;
 546
 547                        /* Find max throughput rate set */
 548                        if (group != MINSTREL_CCK_GROUP) {
 549                                minstrel_ht_sort_best_tp_rates(mi, index,
 550                                                               tmp_mcs_tp_rate);
 551                        } else if (group == MINSTREL_CCK_GROUP) {
 552                                minstrel_ht_sort_best_tp_rates(mi, index,
 553                                                               tmp_cck_tp_rate);
 554                        }
 555
 556                        /* Find max throughput rate set within a group */
 557                        minstrel_ht_sort_best_tp_rates(mi, index,
 558                                                       tmp_group_tp_rate);
 559
 560                        /* Find max probability rate per group and global */
 561                        minstrel_ht_set_best_prob_rate(mi, index);
 562                }
 563
 564                memcpy(mg->max_group_tp_rate, tmp_group_tp_rate,
 565                       sizeof(mg->max_group_tp_rate));
 566        }
 567
 568        /* Assign new rate set per sta */
 569        minstrel_ht_assign_best_tp_rates(mi, tmp_mcs_tp_rate, tmp_cck_tp_rate);
 570        memcpy(mi->max_tp_rate, tmp_mcs_tp_rate, sizeof(mi->max_tp_rate));
 571
 572        /* Try to increase robustness of max_prob_rate*/
 573        minstrel_ht_prob_rate_reduce_streams(mi);
 574
 575        /* try to sample all available rates during each interval */
 576        mi->sample_count *= 8;
 577
 578#ifdef CONFIG_MAC80211_DEBUGFS
 579        /* use fixed index if set */
 580        if (mp->fixed_rate_idx != -1) {
 581                for (i = 0; i < 4; i++)
 582                        mi->max_tp_rate[i] = mp->fixed_rate_idx;
 583                mi->max_prob_rate = mp->fixed_rate_idx;
 584        }
 585#endif
 586
 587        /* Reset update timer */
 588        mi->last_stats_update = jiffies;
 589}
 590
 591static bool
 592minstrel_ht_txstat_valid(struct minstrel_priv *mp, struct ieee80211_tx_rate *rate)
 593{
 594        if (rate->idx < 0)
 595                return false;
 596
 597        if (!rate->count)
 598                return false;
 599
 600        if (rate->flags & IEEE80211_TX_RC_MCS ||
 601            rate->flags & IEEE80211_TX_RC_VHT_MCS)
 602                return true;
 603
 604        return rate->idx == mp->cck_rates[0] ||
 605               rate->idx == mp->cck_rates[1] ||
 606               rate->idx == mp->cck_rates[2] ||
 607               rate->idx == mp->cck_rates[3];
 608}
 609
 610static void
 611minstrel_set_next_sample_idx(struct minstrel_ht_sta *mi)
 612{
 613        struct minstrel_mcs_group_data *mg;
 614
 615        for (;;) {
 616                mi->sample_group++;
 617                mi->sample_group %= ARRAY_SIZE(minstrel_mcs_groups);
 618                mg = &mi->groups[mi->sample_group];
 619
 620                if (!mi->supported[mi->sample_group])
 621                        continue;
 622
 623                if (++mg->index >= MCS_GROUP_RATES) {
 624                        mg->index = 0;
 625                        if (++mg->column >= ARRAY_SIZE(sample_table))
 626                                mg->column = 0;
 627                }
 628                break;
 629        }
 630}
 631
 632static void
 633minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary)
 634{
 635        int group, orig_group;
 636
 637        orig_group = group = *idx / MCS_GROUP_RATES;
 638        while (group > 0) {
 639                group--;
 640
 641                if (!mi->supported[group])
 642                        continue;
 643
 644                if (minstrel_mcs_groups[group].streams >
 645                    minstrel_mcs_groups[orig_group].streams)
 646                        continue;
 647
 648                if (primary)
 649                        *idx = mi->groups[group].max_group_tp_rate[0];
 650                else
 651                        *idx = mi->groups[group].max_group_tp_rate[1];
 652                break;
 653        }
 654}
 655
 656static void
 657minstrel_aggr_check(struct ieee80211_sta *pubsta, struct sk_buff *skb)
 658{
 659        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 660        struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
 661        u16 tid;
 662
 663        if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO)
 664                return;
 665
 666        if (unlikely(!ieee80211_is_data_qos(hdr->frame_control)))
 667                return;
 668
 669        if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE)))
 670                return;
 671
 672        tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
 673        if (likely(sta->ampdu_mlme.tid_tx[tid]))
 674                return;
 675
 676        ieee80211_start_tx_ba_session(pubsta, tid, 0);
 677}
 678
 679static void
 680minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
 681                      void *priv_sta, struct ieee80211_tx_status *st)
 682{
 683        struct ieee80211_tx_info *info = st->info;
 684        struct minstrel_ht_sta_priv *msp = priv_sta;
 685        struct minstrel_ht_sta *mi = &msp->ht;
 686        struct ieee80211_tx_rate *ar = info->status.rates;
 687        struct minstrel_rate_stats *rate, *rate2;
 688        struct minstrel_priv *mp = priv;
 689        bool last, update = false;
 690        int i;
 691
 692        if (!msp->is_ht)
 693                return mac80211_minstrel.tx_status_ext(priv, sband,
 694                                                       &msp->legacy, st);
 695
 696        /* This packet was aggregated but doesn't carry status info */
 697        if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
 698            !(info->flags & IEEE80211_TX_STAT_AMPDU))
 699                return;
 700
 701        if (!(info->flags & IEEE80211_TX_STAT_AMPDU)) {
 702                info->status.ampdu_ack_len =
 703                        (info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0);
 704                info->status.ampdu_len = 1;
 705        }
 706
 707        mi->ampdu_packets++;
 708        mi->ampdu_len += info->status.ampdu_len;
 709
 710        if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) {
 711                mi->sample_wait = 16 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len);
 712                mi->sample_tries = 1;
 713                mi->sample_count--;
 714        }
 715
 716        if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
 717                mi->sample_packets += info->status.ampdu_len;
 718
 719        last = !minstrel_ht_txstat_valid(mp, &ar[0]);
 720        for (i = 0; !last; i++) {
 721                last = (i == IEEE80211_TX_MAX_RATES - 1) ||
 722                       !minstrel_ht_txstat_valid(mp, &ar[i + 1]);
 723
 724                rate = minstrel_ht_get_stats(mp, mi, &ar[i]);
 725
 726                if (last)
 727                        rate->success += info->status.ampdu_ack_len;
 728
 729                rate->attempts += ar[i].count * info->status.ampdu_len;
 730        }
 731
 732        /*
 733         * check for sudden death of spatial multiplexing,
 734         * downgrade to a lower number of streams if necessary.
 735         */
 736        rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]);
 737        if (rate->attempts > 30 &&
 738            MINSTREL_FRAC(rate->success, rate->attempts) <
 739            MINSTREL_FRAC(20, 100)) {
 740                minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true);
 741                update = true;
 742        }
 743
 744        rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]);
 745        if (rate2->attempts > 30 &&
 746            MINSTREL_FRAC(rate2->success, rate2->attempts) <
 747            MINSTREL_FRAC(20, 100)) {
 748                minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false);
 749                update = true;
 750        }
 751
 752        if (time_after(jiffies, mi->last_stats_update +
 753                                (mp->update_interval / 2 * HZ) / 1000)) {
 754                update = true;
 755                minstrel_ht_update_stats(mp, mi);
 756        }
 757
 758        if (update)
 759                minstrel_ht_update_rates(mp, mi);
 760}
 761
 762static void
 763minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
 764                         int index)
 765{
 766        struct minstrel_rate_stats *mrs;
 767        const struct mcs_group *group;
 768        unsigned int tx_time, tx_time_rtscts, tx_time_data;
 769        unsigned int cw = mp->cw_min;
 770        unsigned int ctime = 0;
 771        unsigned int t_slot = 9; /* FIXME */
 772        unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len);
 773        unsigned int overhead = 0, overhead_rtscts = 0;
 774
 775        mrs = minstrel_get_ratestats(mi, index);
 776        if (mrs->prob_ewma < MINSTREL_FRAC(1, 10)) {
 777                mrs->retry_count = 1;
 778                mrs->retry_count_rtscts = 1;
 779                return;
 780        }
 781
 782        mrs->retry_count = 2;
 783        mrs->retry_count_rtscts = 2;
 784        mrs->retry_updated = true;
 785
 786        group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
 787        tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len / 1000;
 788
 789        /* Contention time for first 2 tries */
 790        ctime = (t_slot * cw) >> 1;
 791        cw = min((cw << 1) | 1, mp->cw_max);
 792        ctime += (t_slot * cw) >> 1;
 793        cw = min((cw << 1) | 1, mp->cw_max);
 794
 795        if (index / MCS_GROUP_RATES != MINSTREL_CCK_GROUP) {
 796                overhead = mi->overhead;
 797                overhead_rtscts = mi->overhead_rtscts;
 798        }
 799
 800        /* Total TX time for data and Contention after first 2 tries */
 801        tx_time = ctime + 2 * (overhead + tx_time_data);
 802        tx_time_rtscts = ctime + 2 * (overhead_rtscts + tx_time_data);
 803
 804        /* See how many more tries we can fit inside segment size */
 805        do {
 806                /* Contention time for this try */
 807                ctime = (t_slot * cw) >> 1;
 808                cw = min((cw << 1) | 1, mp->cw_max);
 809
 810                /* Total TX time after this try */
 811                tx_time += ctime + overhead + tx_time_data;
 812                tx_time_rtscts += ctime + overhead_rtscts + tx_time_data;
 813
 814                if (tx_time_rtscts < mp->segment_size)
 815                        mrs->retry_count_rtscts++;
 816        } while ((tx_time < mp->segment_size) &&
 817                 (++mrs->retry_count < mp->max_retry));
 818}
 819
 820
 821static void
 822minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
 823                     struct ieee80211_sta_rates *ratetbl, int offset, int index)
 824{
 825        const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
 826        struct minstrel_rate_stats *mrs;
 827        u8 idx;
 828        u16 flags = group->flags;
 829
 830        mrs = minstrel_get_ratestats(mi, index);
 831        if (!mrs->retry_updated)
 832                minstrel_calc_retransmit(mp, mi, index);
 833
 834        if (mrs->prob_ewma < MINSTREL_FRAC(20, 100) || !mrs->retry_count) {
 835                ratetbl->rate[offset].count = 2;
 836                ratetbl->rate[offset].count_rts = 2;
 837                ratetbl->rate[offset].count_cts = 2;
 838        } else {
 839                ratetbl->rate[offset].count = mrs->retry_count;
 840                ratetbl->rate[offset].count_cts = mrs->retry_count;
 841                ratetbl->rate[offset].count_rts = mrs->retry_count_rtscts;
 842        }
 843
 844        if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP)
 845                idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)];
 846        else if (flags & IEEE80211_TX_RC_VHT_MCS)
 847                idx = ((group->streams - 1) << 4) |
 848                      ((index % MCS_GROUP_RATES) & 0xF);
 849        else
 850                idx = index % MCS_GROUP_RATES + (group->streams - 1) * 8;
 851
 852        /* enable RTS/CTS if needed:
 853         *  - if station is in dynamic SMPS (and streams > 1)
 854         *  - for fallback rates, to increase chances of getting through
 855         */
 856        if (offset > 0 ||
 857            (mi->sta->smps_mode == IEEE80211_SMPS_DYNAMIC &&
 858             group->streams > 1)) {
 859                ratetbl->rate[offset].count = ratetbl->rate[offset].count_rts;
 860                flags |= IEEE80211_TX_RC_USE_RTS_CTS;
 861        }
 862
 863        ratetbl->rate[offset].idx = idx;
 864        ratetbl->rate[offset].flags = flags;
 865}
 866
 867static inline int
 868minstrel_ht_get_prob_ewma(struct minstrel_ht_sta *mi, int rate)
 869{
 870        int group = rate / MCS_GROUP_RATES;
 871        rate %= MCS_GROUP_RATES;
 872        return mi->groups[group].rates[rate].prob_ewma;
 873}
 874
 875static int
 876minstrel_ht_get_max_amsdu_len(struct minstrel_ht_sta *mi)
 877{
 878        int group = mi->max_prob_rate / MCS_GROUP_RATES;
 879        const struct mcs_group *g = &minstrel_mcs_groups[group];
 880        int rate = mi->max_prob_rate % MCS_GROUP_RATES;
 881
 882        /* Disable A-MSDU if max_prob_rate is bad */
 883        if (mi->groups[group].rates[rate].prob_ewma < MINSTREL_FRAC(50, 100))
 884                return 1;
 885
 886        /* If the rate is slower than single-stream MCS1, make A-MSDU limit small */
 887        if (g->duration[rate] > MCS_DURATION(1, 0, 52))
 888                return 500;
 889
 890        /*
 891         * If the rate is slower than single-stream MCS4, limit A-MSDU to usual
 892         * data packet size
 893         */
 894        if (g->duration[rate] > MCS_DURATION(1, 0, 104))
 895                return 1600;
 896
 897        /*
 898         * If the rate is slower than single-stream MCS7, or if the max throughput
 899         * rate success probability is less than 75%, limit A-MSDU to twice the usual
 900         * data packet size
 901         */
 902        if (g->duration[rate] > MCS_DURATION(1, 0, 260) ||
 903            (minstrel_ht_get_prob_ewma(mi, mi->max_tp_rate[0]) <
 904             MINSTREL_FRAC(75, 100)))
 905                return 3200;
 906
 907        /*
 908         * HT A-MPDU limits maximum MPDU size under BA agreement to 4095 bytes.
 909         * Since aggregation sessions are started/stopped without txq flush, use
 910         * the limit here to avoid the complexity of having to de-aggregate
 911         * packets in the queue.
 912         */
 913        if (!mi->sta->vht_cap.vht_supported)
 914                return IEEE80211_MAX_MPDU_LEN_HT_BA;
 915
 916        /* unlimited */
 917        return 0;
 918}
 919
 920static void
 921minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
 922{
 923        struct ieee80211_sta_rates *rates;
 924        int i = 0;
 925
 926        rates = kzalloc(sizeof(*rates), GFP_ATOMIC);
 927        if (!rates)
 928                return;
 929
 930        /* Start with max_tp_rate[0] */
 931        minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate[0]);
 932
 933        if (mp->hw->max_rates >= 3) {
 934                /* At least 3 tx rates supported, use max_tp_rate[1] next */
 935                minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate[1]);
 936        }
 937
 938        if (mp->hw->max_rates >= 2) {
 939                /*
 940                 * At least 2 tx rates supported, use max_prob_rate next */
 941                minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_prob_rate);
 942        }
 943
 944        mi->sta->max_rc_amsdu_len = minstrel_ht_get_max_amsdu_len(mi);
 945        rates->rate[i].idx = -1;
 946        rate_control_set_rates(mp->hw, mi->sta, rates);
 947}
 948
 949static inline int
 950minstrel_get_duration(int index)
 951{
 952        const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
 953        return group->duration[index % MCS_GROUP_RATES];
 954}
 955
 956static int
 957minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
 958{
 959        struct minstrel_rate_stats *mrs;
 960        struct minstrel_mcs_group_data *mg;
 961        unsigned int sample_dur, sample_group, cur_max_tp_streams;
 962        int tp_rate1, tp_rate2;
 963        int sample_idx = 0;
 964
 965        if (mi->sample_wait > 0) {
 966                mi->sample_wait--;
 967                return -1;
 968        }
 969
 970        if (!mi->sample_tries)
 971                return -1;
 972
 973        sample_group = mi->sample_group;
 974        mg = &mi->groups[sample_group];
 975        sample_idx = sample_table[mg->column][mg->index];
 976        minstrel_set_next_sample_idx(mi);
 977
 978        if (!(mi->supported[sample_group] & BIT(sample_idx)))
 979                return -1;
 980
 981        mrs = &mg->rates[sample_idx];
 982        sample_idx += sample_group * MCS_GROUP_RATES;
 983
 984        /* Set tp_rate1, tp_rate2 to the highest / second highest max_tp_rate */
 985        if (minstrel_get_duration(mi->max_tp_rate[0]) >
 986            minstrel_get_duration(mi->max_tp_rate[1])) {
 987                tp_rate1 = mi->max_tp_rate[1];
 988                tp_rate2 = mi->max_tp_rate[0];
 989        } else {
 990                tp_rate1 = mi->max_tp_rate[0];
 991                tp_rate2 = mi->max_tp_rate[1];
 992        }
 993
 994        /*
 995         * Sampling might add some overhead (RTS, no aggregation)
 996         * to the frame. Hence, don't use sampling for the highest currently
 997         * used highest throughput or probability rate.
 998         */
 999        if (sample_idx == mi->max_tp_rate[0] || sample_idx == mi->max_prob_rate)
1000                return -1;
1001
1002        /*
1003         * Do not sample if the probability is already higher than 95%
1004         * to avoid wasting airtime.
1005         */
1006        if (mrs->prob_ewma > MINSTREL_FRAC(95, 100))
1007                return -1;
1008
1009        /*
1010         * Make sure that lower rates get sampled only occasionally,
1011         * if the link is working perfectly.
1012         */
1013
1014        cur_max_tp_streams = minstrel_mcs_groups[tp_rate1 /
1015                MCS_GROUP_RATES].streams;
1016        sample_dur = minstrel_get_duration(sample_idx);
1017        if (sample_dur >= minstrel_get_duration(tp_rate2) &&
1018            (cur_max_tp_streams - 1 <
1019             minstrel_mcs_groups[sample_group].streams ||
1020             sample_dur >= minstrel_get_duration(mi->max_prob_rate))) {
1021                if (mrs->sample_skipped < 20)
1022                        return -1;
1023
1024                if (mi->sample_slow++ > 2)
1025                        return -1;
1026        }
1027        mi->sample_tries--;
1028
1029        return sample_idx;
1030}
1031
1032static void
1033minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
1034                     struct ieee80211_tx_rate_control *txrc)
1035{
1036        const struct mcs_group *sample_group;
1037        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
1038        struct ieee80211_tx_rate *rate = &info->status.rates[0];
1039        struct minstrel_ht_sta_priv *msp = priv_sta;
1040        struct minstrel_ht_sta *mi = &msp->ht;
1041        struct minstrel_priv *mp = priv;
1042        int sample_idx;
1043
1044        if (rate_control_send_low(sta, priv_sta, txrc))
1045                return;
1046
1047        if (!msp->is_ht)
1048                return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc);
1049
1050        if (!(info->flags & IEEE80211_TX_CTL_AMPDU) &&
1051            mi->max_prob_rate / MCS_GROUP_RATES != MINSTREL_CCK_GROUP)
1052                minstrel_aggr_check(sta, txrc->skb);
1053
1054        info->flags |= mi->tx_flags;
1055
1056#ifdef CONFIG_MAC80211_DEBUGFS
1057        if (mp->fixed_rate_idx != -1)
1058                return;
1059#endif
1060
1061        /* Don't use EAPOL frames for sampling on non-mrr hw */
1062        if (mp->hw->max_rates == 1 &&
1063            (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO))
1064                sample_idx = -1;
1065        else
1066                sample_idx = minstrel_get_sample_rate(mp, mi);
1067
1068        mi->total_packets++;
1069
1070        /* wraparound */
1071        if (mi->total_packets == ~0) {
1072                mi->total_packets = 0;
1073                mi->sample_packets = 0;
1074        }
1075
1076        if (sample_idx < 0)
1077                return;
1078
1079        sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES];
1080        info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
1081        rate->count = 1;
1082
1083        if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) {
1084                int idx = sample_idx % ARRAY_SIZE(mp->cck_rates);
1085                rate->idx = mp->cck_rates[idx];
1086        } else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) {
1087                ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES,
1088                                       sample_group->streams);
1089        } else {
1090                rate->idx = sample_idx % MCS_GROUP_RATES +
1091                            (sample_group->streams - 1) * 8;
1092        }
1093
1094        rate->flags = sample_group->flags;
1095}
1096
1097static void
1098minstrel_ht_update_cck(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
1099                       struct ieee80211_supported_band *sband,
1100                       struct ieee80211_sta *sta)
1101{
1102        int i;
1103
1104        if (sband->band != NL80211_BAND_2GHZ)
1105                return;
1106
1107        if (!ieee80211_hw_check(mp->hw, SUPPORTS_HT_CCK_RATES))
1108                return;
1109
1110        mi->cck_supported = 0;
1111        mi->cck_supported_short = 0;
1112        for (i = 0; i < 4; i++) {
1113                if (!rate_supported(sta, sband->band, mp->cck_rates[i]))
1114                        continue;
1115
1116                mi->cck_supported |= BIT(i);
1117                if (sband->bitrates[i].flags & IEEE80211_RATE_SHORT_PREAMBLE)
1118                        mi->cck_supported_short |= BIT(i);
1119        }
1120
1121        mi->supported[MINSTREL_CCK_GROUP] = mi->cck_supported;
1122}
1123
1124static void
1125minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
1126                        struct cfg80211_chan_def *chandef,
1127                        struct ieee80211_sta *sta, void *priv_sta)
1128{
1129        struct minstrel_priv *mp = priv;
1130        struct minstrel_ht_sta_priv *msp = priv_sta;
1131        struct minstrel_ht_sta *mi = &msp->ht;
1132        struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs;
1133        u16 sta_cap = sta->ht_cap.cap;
1134        struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
1135        struct sta_info *sinfo = container_of(sta, struct sta_info, sta);
1136        int use_vht;
1137        int n_supported = 0;
1138        int ack_dur;
1139        int stbc;
1140        int i;
1141
1142        /* fall back to the old minstrel for legacy stations */
1143        if (!sta->ht_cap.ht_supported)
1144                goto use_legacy;
1145
1146        BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != MINSTREL_GROUPS_NB);
1147
1148#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
1149        if (vht_cap->vht_supported)
1150                use_vht = vht_cap->vht_mcs.tx_mcs_map != cpu_to_le16(~0);
1151        else
1152#endif
1153        use_vht = 0;
1154
1155        msp->is_ht = true;
1156        memset(mi, 0, sizeof(*mi));
1157
1158        mi->sta = sta;
1159        mi->last_stats_update = jiffies;
1160
1161        ack_dur = ieee80211_frame_duration(sband->band, 10, 60, 1, 1, 0);
1162        mi->overhead = ieee80211_frame_duration(sband->band, 0, 60, 1, 1, 0);
1163        mi->overhead += ack_dur;
1164        mi->overhead_rtscts = mi->overhead + 2 * ack_dur;
1165
1166        mi->avg_ampdu_len = MINSTREL_FRAC(1, 1);
1167
1168        /* When using MRR, sample more on the first attempt, without delay */
1169        if (mp->has_mrr) {
1170                mi->sample_count = 16;
1171                mi->sample_wait = 0;
1172        } else {
1173                mi->sample_count = 8;
1174                mi->sample_wait = 8;
1175        }
1176        mi->sample_tries = 4;
1177
1178        /* TODO tx_flags for vht - ATM the RC API is not fine-grained enough */
1179        if (!use_vht) {
1180                stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >>
1181                        IEEE80211_HT_CAP_RX_STBC_SHIFT;
1182                mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT;
1183
1184                if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING)
1185                        mi->tx_flags |= IEEE80211_TX_CTL_LDPC;
1186        }
1187
1188        for (i = 0; i < ARRAY_SIZE(mi->groups); i++) {
1189                u32 gflags = minstrel_mcs_groups[i].flags;
1190                int bw, nss;
1191
1192                mi->supported[i] = 0;
1193                if (i == MINSTREL_CCK_GROUP) {
1194                        minstrel_ht_update_cck(mp, mi, sband, sta);
1195                        continue;
1196                }
1197
1198                if (gflags & IEEE80211_TX_RC_SHORT_GI) {
1199                        if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
1200                                if (!(sta_cap & IEEE80211_HT_CAP_SGI_40))
1201                                        continue;
1202                        } else {
1203                                if (!(sta_cap & IEEE80211_HT_CAP_SGI_20))
1204                                        continue;
1205                        }
1206                }
1207
1208                if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH &&
1209                    sta->bandwidth < IEEE80211_STA_RX_BW_40)
1210                        continue;
1211
1212                nss = minstrel_mcs_groups[i].streams;
1213
1214                /* Mark MCS > 7 as unsupported if STA is in static SMPS mode */
1215                if (sta->smps_mode == IEEE80211_SMPS_STATIC && nss > 1)
1216                        continue;
1217
1218                /* HT rate */
1219                if (gflags & IEEE80211_TX_RC_MCS) {
1220#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
1221                        if (use_vht && minstrel_vht_only)
1222                                continue;
1223#endif
1224                        mi->supported[i] = mcs->rx_mask[nss - 1];
1225                        if (mi->supported[i])
1226                                n_supported++;
1227                        continue;
1228                }
1229
1230                /* VHT rate */
1231                if (!vht_cap->vht_supported ||
1232                    WARN_ON(!(gflags & IEEE80211_TX_RC_VHT_MCS)) ||
1233                    WARN_ON(gflags & IEEE80211_TX_RC_160_MHZ_WIDTH))
1234                        continue;
1235
1236                if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH) {
1237                        if (sta->bandwidth < IEEE80211_STA_RX_BW_80 ||
1238                            ((gflags & IEEE80211_TX_RC_SHORT_GI) &&
1239                             !(vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_80))) {
1240                                continue;
1241                        }
1242                }
1243
1244                if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1245                        bw = BW_40;
1246                else if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH)
1247                        bw = BW_80;
1248                else
1249                        bw = BW_20;
1250
1251                mi->supported[i] = minstrel_get_valid_vht_rates(bw, nss,
1252                                vht_cap->vht_mcs.tx_mcs_map);
1253
1254                if (mi->supported[i])
1255                        n_supported++;
1256        }
1257
1258        if (!n_supported)
1259                goto use_legacy;
1260
1261        if (test_sta_flag(sinfo, WLAN_STA_SHORT_PREAMBLE))
1262                mi->cck_supported_short |= mi->cck_supported_short << 4;
1263
1264        /* create an initial rate table with the lowest supported rates */
1265        minstrel_ht_update_stats(mp, mi);
1266        minstrel_ht_update_rates(mp, mi);
1267
1268        return;
1269
1270use_legacy:
1271        msp->is_ht = false;
1272        memset(&msp->legacy, 0, sizeof(msp->legacy));
1273        msp->legacy.r = msp->ratelist;
1274        msp->legacy.sample_table = msp->sample_table;
1275        return mac80211_minstrel.rate_init(priv, sband, chandef, sta,
1276                                           &msp->legacy);
1277}
1278
1279static void
1280minstrel_ht_rate_init(void *priv, struct ieee80211_supported_band *sband,
1281                      struct cfg80211_chan_def *chandef,
1282                      struct ieee80211_sta *sta, void *priv_sta)
1283{
1284        minstrel_ht_update_caps(priv, sband, chandef, sta, priv_sta);
1285}
1286
1287static void
1288minstrel_ht_rate_update(void *priv, struct ieee80211_supported_band *sband,
1289                        struct cfg80211_chan_def *chandef,
1290                        struct ieee80211_sta *sta, void *priv_sta,
1291                        u32 changed)
1292{
1293        minstrel_ht_update_caps(priv, sband, chandef, sta, priv_sta);
1294}
1295
1296static void *
1297minstrel_ht_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
1298{
1299        struct ieee80211_supported_band *sband;
1300        struct minstrel_ht_sta_priv *msp;
1301        struct minstrel_priv *mp = priv;
1302        struct ieee80211_hw *hw = mp->hw;
1303        int max_rates = 0;
1304        int i;
1305
1306        for (i = 0; i < NUM_NL80211_BANDS; i++) {
1307                sband = hw->wiphy->bands[i];
1308                if (sband && sband->n_bitrates > max_rates)
1309                        max_rates = sband->n_bitrates;
1310        }
1311
1312        msp = kzalloc(sizeof(*msp), gfp);
1313        if (!msp)
1314                return NULL;
1315
1316        msp->ratelist = kzalloc(sizeof(struct minstrel_rate) * max_rates, gfp);
1317        if (!msp->ratelist)
1318                goto error;
1319
1320        msp->sample_table = kmalloc(SAMPLE_COLUMNS * max_rates, gfp);
1321        if (!msp->sample_table)
1322                goto error1;
1323
1324        return msp;
1325
1326error1:
1327        kfree(msp->ratelist);
1328error:
1329        kfree(msp);
1330        return NULL;
1331}
1332
1333static void
1334minstrel_ht_free_sta(void *priv, struct ieee80211_sta *sta, void *priv_sta)
1335{
1336        struct minstrel_ht_sta_priv *msp = priv_sta;
1337
1338        kfree(msp->sample_table);
1339        kfree(msp->ratelist);
1340        kfree(msp);
1341}
1342
1343static void *
1344minstrel_ht_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
1345{
1346        return mac80211_minstrel.alloc(hw, debugfsdir);
1347}
1348
1349static void
1350minstrel_ht_free(void *priv)
1351{
1352        mac80211_minstrel.free(priv);
1353}
1354
1355static u32 minstrel_ht_get_expected_throughput(void *priv_sta)
1356{
1357        struct minstrel_ht_sta_priv *msp = priv_sta;
1358        struct minstrel_ht_sta *mi = &msp->ht;
1359        int i, j, prob, tp_avg;
1360
1361        if (!msp->is_ht)
1362                return mac80211_minstrel.get_expected_throughput(priv_sta);
1363
1364        i = mi->max_tp_rate[0] / MCS_GROUP_RATES;
1365        j = mi->max_tp_rate[0] % MCS_GROUP_RATES;
1366        prob = mi->groups[i].rates[j].prob_ewma;
1367
1368        /* convert tp_avg from pkt per second in kbps */
1369        tp_avg = minstrel_ht_get_tp_avg(mi, i, j, prob) * 10;
1370        tp_avg = tp_avg * AVG_PKT_SIZE * 8 / 1024;
1371
1372        return tp_avg;
1373}
1374
1375static const struct rate_control_ops mac80211_minstrel_ht = {
1376        .name = "minstrel_ht",
1377        .tx_status_ext = minstrel_ht_tx_status,
1378        .get_rate = minstrel_ht_get_rate,
1379        .rate_init = minstrel_ht_rate_init,
1380        .rate_update = minstrel_ht_rate_update,
1381        .alloc_sta = minstrel_ht_alloc_sta,
1382        .free_sta = minstrel_ht_free_sta,
1383        .alloc = minstrel_ht_alloc,
1384        .free = minstrel_ht_free,
1385#ifdef CONFIG_MAC80211_DEBUGFS
1386        .add_sta_debugfs = minstrel_ht_add_sta_debugfs,
1387        .remove_sta_debugfs = minstrel_ht_remove_sta_debugfs,
1388#endif
1389        .get_expected_throughput = minstrel_ht_get_expected_throughput,
1390};
1391
1392
1393static void __init init_sample_table(void)
1394{
1395        int col, i, new_idx;
1396        u8 rnd[MCS_GROUP_RATES];
1397
1398        memset(sample_table, 0xff, sizeof(sample_table));
1399        for (col = 0; col < SAMPLE_COLUMNS; col++) {
1400                prandom_bytes(rnd, sizeof(rnd));
1401                for (i = 0; i < MCS_GROUP_RATES; i++) {
1402                        new_idx = (i + rnd[i]) % MCS_GROUP_RATES;
1403                        while (sample_table[col][new_idx] != 0xff)
1404                                new_idx = (new_idx + 1) % MCS_GROUP_RATES;
1405
1406                        sample_table[col][new_idx] = i;
1407                }
1408        }
1409}
1410
1411int __init
1412rc80211_minstrel_ht_init(void)
1413{
1414        init_sample_table();
1415        return ieee80211_rate_control_register(&mac80211_minstrel_ht);
1416}
1417
1418void
1419rc80211_minstrel_ht_exit(void)
1420{
1421        ieee80211_rate_control_unregister(&mac80211_minstrel_ht);
1422}
1423