Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 /*
0003  * Copyright (C) 2019 Felix Fietkau <nbd@nbd.name>
0004  * Copyright (C) 2021-2022 Intel Corporation
0005  */
0006 
0007 #include <net/mac80211.h>
0008 #include "ieee80211_i.h"
0009 #include "sta_info.h"
0010 
0011 #define AVG_PKT_SIZE    1024
0012 
0013 /* Number of bits for an average sized packet */
0014 #define MCS_NBITS (AVG_PKT_SIZE << 3)
0015 
0016 /* Number of kilo-symbols (symbols * 1024) for a packet with (bps) bits per
0017  * symbol. We use k-symbols to avoid rounding in the _TIME macros below.
0018  */
0019 #define MCS_N_KSYMS(bps) DIV_ROUND_UP(MCS_NBITS << 10, (bps))
0020 
0021 /* Transmission time (in 1024 * usec) for a packet containing (ksyms) * 1024
0022  * symbols.
0023  */
0024 #define MCS_SYMBOL_TIME(sgi, ksyms)                 \
0025     (sgi ?                              \
0026       ((ksyms) * 4 * 18) / 20 :     /* 3.6 us per sym */    \
0027       ((ksyms) * 4)         /* 4.0 us per sym */    \
0028     )
0029 
0030 /* Transmit duration for the raw data part of an average sized packet */
0031 #define MCS_DURATION(streams, sgi, bps) \
0032     ((u32)MCS_SYMBOL_TIME(sgi, MCS_N_KSYMS((streams) * (bps))))
0033 
0034 #define MCS_DURATION_S(shift, streams, sgi, bps)        \
0035     ((u16)((MCS_DURATION(streams, sgi, bps) >> shift)))
0036 
0037 /* These should match the values in enum nl80211_he_gi */
0038 #define HE_GI_08 0
0039 #define HE_GI_16 1
0040 #define HE_GI_32 2
0041 
0042 /* Transmission time (1024 usec) for a packet containing (ksyms) * k-symbols */
0043 #define HE_SYMBOL_TIME(gi, ksyms)                   \
0044     (gi == HE_GI_08 ?                       \
0045      ((ksyms) * 16 * 17) / 20 :     /* 13.6 us per sym */   \
0046      (gi == HE_GI_16 ?                      \
0047       ((ksyms) * 16 * 18) / 20 :        /* 14.4 us per sym */   \
0048       ((ksyms) * 16)            /* 16.0 us per sym */   \
0049      ))
0050 
0051 /* Transmit duration for the raw data part of an average sized packet */
0052 #define HE_DURATION(streams, gi, bps) \
0053     ((u32)HE_SYMBOL_TIME(gi, MCS_N_KSYMS((streams) * (bps))))
0054 
0055 #define HE_DURATION_S(shift, streams, gi, bps)      \
0056     (HE_DURATION(streams, gi, bps) >> shift)
0057 
0058 #define BW_20           0
0059 #define BW_40           1
0060 #define BW_80           2
0061 #define BW_160          3
0062 
0063 /*
0064  * Define group sort order: HT40 -> SGI -> #streams
0065  */
0066 #define IEEE80211_MAX_STREAMS       4
0067 #define IEEE80211_HT_STREAM_GROUPS  4 /* BW(=2) * SGI(=2) */
0068 #define IEEE80211_VHT_STREAM_GROUPS 8 /* BW(=4) * SGI(=2) */
0069 
0070 #define IEEE80211_HE_MAX_STREAMS    8
0071 
0072 #define IEEE80211_HT_GROUPS_NB  (IEEE80211_MAX_STREAMS *    \
0073                  IEEE80211_HT_STREAM_GROUPS)
0074 #define IEEE80211_VHT_GROUPS_NB (IEEE80211_MAX_STREAMS *    \
0075                      IEEE80211_VHT_STREAM_GROUPS)
0076 
0077 #define IEEE80211_HT_GROUP_0    0
0078 #define IEEE80211_VHT_GROUP_0   (IEEE80211_HT_GROUP_0 + IEEE80211_HT_GROUPS_NB)
0079 #define IEEE80211_HE_GROUP_0    (IEEE80211_VHT_GROUP_0 + IEEE80211_VHT_GROUPS_NB)
0080 
0081 #define MCS_GROUP_RATES     12
0082 
0083 #define HT_GROUP_IDX(_streams, _sgi, _ht40) \
0084     IEEE80211_HT_GROUP_0 +          \
0085     IEEE80211_MAX_STREAMS * 2 * _ht40 + \
0086     IEEE80211_MAX_STREAMS * _sgi +      \
0087     _streams - 1
0088 
0089 #define _MAX(a, b) (((a)>(b))?(a):(b))
0090 
0091 #define GROUP_SHIFT(duration)                       \
0092     _MAX(0, 16 - __builtin_clz(duration))
0093 
0094 /* MCS rate information for an MCS group */
0095 #define __MCS_GROUP(_streams, _sgi, _ht40, _s)              \
0096     [HT_GROUP_IDX(_streams, _sgi, _ht40)] = {           \
0097     .shift = _s,                            \
0098     .duration = {                           \
0099         MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 54 : 26),    \
0100         MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 108 : 52),   \
0101         MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 162 : 78),   \
0102         MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 216 : 104),  \
0103         MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 324 : 156),  \
0104         MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 432 : 208),  \
0105         MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 486 : 234),  \
0106         MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 540 : 260)   \
0107     }                               \
0108 }
0109 
0110 #define MCS_GROUP_SHIFT(_streams, _sgi, _ht40)              \
0111     GROUP_SHIFT(MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26))
0112 
0113 #define MCS_GROUP(_streams, _sgi, _ht40)                \
0114     __MCS_GROUP(_streams, _sgi, _ht40,              \
0115             MCS_GROUP_SHIFT(_streams, _sgi, _ht40))
0116 
0117 #define VHT_GROUP_IDX(_streams, _sgi, _bw)              \
0118     (IEEE80211_VHT_GROUP_0 +                    \
0119      IEEE80211_MAX_STREAMS * 2 * (_bw) +                \
0120      IEEE80211_MAX_STREAMS * (_sgi) +               \
0121      (_streams) - 1)
0122 
0123 #define BW2VBPS(_bw, r4, r3, r2, r1)                    \
0124     (_bw == BW_160 ? r4 : _bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1)
0125 
0126 #define __VHT_GROUP(_streams, _sgi, _bw, _s)                \
0127     [VHT_GROUP_IDX(_streams, _sgi, _bw)] = {            \
0128     .shift = _s,                            \
0129     .duration = {                           \
0130         MCS_DURATION_S(_s, _streams, _sgi,          \
0131                    BW2VBPS(_bw,  234,  117,  54,  26)), \
0132         MCS_DURATION_S(_s, _streams, _sgi,          \
0133                    BW2VBPS(_bw,  468,  234, 108,  52)), \
0134         MCS_DURATION_S(_s, _streams, _sgi,          \
0135                    BW2VBPS(_bw,  702,  351, 162,  78)), \
0136         MCS_DURATION_S(_s, _streams, _sgi,          \
0137                    BW2VBPS(_bw,  936,  468, 216, 104)), \
0138         MCS_DURATION_S(_s, _streams, _sgi,          \
0139                    BW2VBPS(_bw, 1404,  702, 324, 156)), \
0140         MCS_DURATION_S(_s, _streams, _sgi,          \
0141                    BW2VBPS(_bw, 1872,  936, 432, 208)), \
0142         MCS_DURATION_S(_s, _streams, _sgi,          \
0143                    BW2VBPS(_bw, 2106, 1053, 486, 234)), \
0144         MCS_DURATION_S(_s, _streams, _sgi,          \
0145                    BW2VBPS(_bw, 2340, 1170, 540, 260)), \
0146         MCS_DURATION_S(_s, _streams, _sgi,          \
0147                    BW2VBPS(_bw, 2808, 1404, 648, 312)), \
0148         MCS_DURATION_S(_s, _streams, _sgi,          \
0149                    BW2VBPS(_bw, 3120, 1560, 720, 346))  \
0150         }                               \
0151 }
0152 
0153 #define VHT_GROUP_SHIFT(_streams, _sgi, _bw)                \
0154     GROUP_SHIFT(MCS_DURATION(_streams, _sgi,            \
0155                  BW2VBPS(_bw, 243, 117,  54,  26)))
0156 
0157 #define VHT_GROUP(_streams, _sgi, _bw)                  \
0158     __VHT_GROUP(_streams, _sgi, _bw,                \
0159             VHT_GROUP_SHIFT(_streams, _sgi, _bw))
0160 
0161 
0162 #define HE_GROUP_IDX(_streams, _gi, _bw)                \
0163     (IEEE80211_HE_GROUP_0 +                 \
0164      IEEE80211_HE_MAX_STREAMS * 3 * (_bw) +         \
0165      IEEE80211_HE_MAX_STREAMS * (_gi) +             \
0166      (_streams) - 1)
0167 
0168 #define __HE_GROUP(_streams, _gi, _bw, _s)              \
0169     [HE_GROUP_IDX(_streams, _gi, _bw)] = {          \
0170     .shift = _s,                            \
0171     .duration = {                           \
0172         HE_DURATION_S(_s, _streams, _gi,            \
0173                   BW2VBPS(_bw,   979,  489,  230,  115)),   \
0174         HE_DURATION_S(_s, _streams, _gi,            \
0175                   BW2VBPS(_bw,  1958,  979,  475,  230)),   \
0176         HE_DURATION_S(_s, _streams, _gi,            \
0177                   BW2VBPS(_bw,  2937, 1468,  705,  345)),   \
0178         HE_DURATION_S(_s, _streams, _gi,            \
0179                   BW2VBPS(_bw,  3916, 1958,  936,  475)),   \
0180         HE_DURATION_S(_s, _streams, _gi,            \
0181                   BW2VBPS(_bw,  5875, 2937, 1411,  705)),   \
0182         HE_DURATION_S(_s, _streams, _gi,            \
0183                   BW2VBPS(_bw,  7833, 3916, 1872,  936)),   \
0184         HE_DURATION_S(_s, _streams, _gi,            \
0185                   BW2VBPS(_bw,  8827, 4406, 2102, 1051)),   \
0186         HE_DURATION_S(_s, _streams, _gi,            \
0187                   BW2VBPS(_bw,  9806, 4896, 2347, 1166)),   \
0188         HE_DURATION_S(_s, _streams, _gi,            \
0189                   BW2VBPS(_bw, 11764, 5875, 2808, 1411)),   \
0190         HE_DURATION_S(_s, _streams, _gi,            \
0191                   BW2VBPS(_bw, 13060, 6523, 3124, 1555)),   \
0192         HE_DURATION_S(_s, _streams, _gi,            \
0193                   BW2VBPS(_bw, 14702, 7344, 3513, 1756)),   \
0194         HE_DURATION_S(_s, _streams, _gi,            \
0195                   BW2VBPS(_bw, 16329, 8164, 3902, 1944))    \
0196         }                               \
0197 }
0198 
0199 #define HE_GROUP_SHIFT(_streams, _gi, _bw)              \
0200     GROUP_SHIFT(HE_DURATION(_streams, _gi,          \
0201                 BW2VBPS(_bw,   979,  489,  230,  115)))
0202 
0203 #define HE_GROUP(_streams, _gi, _bw)                    \
0204     __HE_GROUP(_streams, _gi, _bw,              \
0205            HE_GROUP_SHIFT(_streams, _gi, _bw))
0206 struct mcs_group {
0207     u8 shift;
0208     u16 duration[MCS_GROUP_RATES];
0209 };
0210 
0211 static const struct mcs_group airtime_mcs_groups[] = {
0212     MCS_GROUP(1, 0, BW_20),
0213     MCS_GROUP(2, 0, BW_20),
0214     MCS_GROUP(3, 0, BW_20),
0215     MCS_GROUP(4, 0, BW_20),
0216 
0217     MCS_GROUP(1, 1, BW_20),
0218     MCS_GROUP(2, 1, BW_20),
0219     MCS_GROUP(3, 1, BW_20),
0220     MCS_GROUP(4, 1, BW_20),
0221 
0222     MCS_GROUP(1, 0, BW_40),
0223     MCS_GROUP(2, 0, BW_40),
0224     MCS_GROUP(3, 0, BW_40),
0225     MCS_GROUP(4, 0, BW_40),
0226 
0227     MCS_GROUP(1, 1, BW_40),
0228     MCS_GROUP(2, 1, BW_40),
0229     MCS_GROUP(3, 1, BW_40),
0230     MCS_GROUP(4, 1, BW_40),
0231 
0232     VHT_GROUP(1, 0, BW_20),
0233     VHT_GROUP(2, 0, BW_20),
0234     VHT_GROUP(3, 0, BW_20),
0235     VHT_GROUP(4, 0, BW_20),
0236 
0237     VHT_GROUP(1, 1, BW_20),
0238     VHT_GROUP(2, 1, BW_20),
0239     VHT_GROUP(3, 1, BW_20),
0240     VHT_GROUP(4, 1, BW_20),
0241 
0242     VHT_GROUP(1, 0, BW_40),
0243     VHT_GROUP(2, 0, BW_40),
0244     VHT_GROUP(3, 0, BW_40),
0245     VHT_GROUP(4, 0, BW_40),
0246 
0247     VHT_GROUP(1, 1, BW_40),
0248     VHT_GROUP(2, 1, BW_40),
0249     VHT_GROUP(3, 1, BW_40),
0250     VHT_GROUP(4, 1, BW_40),
0251 
0252     VHT_GROUP(1, 0, BW_80),
0253     VHT_GROUP(2, 0, BW_80),
0254     VHT_GROUP(3, 0, BW_80),
0255     VHT_GROUP(4, 0, BW_80),
0256 
0257     VHT_GROUP(1, 1, BW_80),
0258     VHT_GROUP(2, 1, BW_80),
0259     VHT_GROUP(3, 1, BW_80),
0260     VHT_GROUP(4, 1, BW_80),
0261 
0262     VHT_GROUP(1, 0, BW_160),
0263     VHT_GROUP(2, 0, BW_160),
0264     VHT_GROUP(3, 0, BW_160),
0265     VHT_GROUP(4, 0, BW_160),
0266 
0267     VHT_GROUP(1, 1, BW_160),
0268     VHT_GROUP(2, 1, BW_160),
0269     VHT_GROUP(3, 1, BW_160),
0270     VHT_GROUP(4, 1, BW_160),
0271 
0272     HE_GROUP(1, HE_GI_08, BW_20),
0273     HE_GROUP(2, HE_GI_08, BW_20),
0274     HE_GROUP(3, HE_GI_08, BW_20),
0275     HE_GROUP(4, HE_GI_08, BW_20),
0276     HE_GROUP(5, HE_GI_08, BW_20),
0277     HE_GROUP(6, HE_GI_08, BW_20),
0278     HE_GROUP(7, HE_GI_08, BW_20),
0279     HE_GROUP(8, HE_GI_08, BW_20),
0280 
0281     HE_GROUP(1, HE_GI_16, BW_20),
0282     HE_GROUP(2, HE_GI_16, BW_20),
0283     HE_GROUP(3, HE_GI_16, BW_20),
0284     HE_GROUP(4, HE_GI_16, BW_20),
0285     HE_GROUP(5, HE_GI_16, BW_20),
0286     HE_GROUP(6, HE_GI_16, BW_20),
0287     HE_GROUP(7, HE_GI_16, BW_20),
0288     HE_GROUP(8, HE_GI_16, BW_20),
0289 
0290     HE_GROUP(1, HE_GI_32, BW_20),
0291     HE_GROUP(2, HE_GI_32, BW_20),
0292     HE_GROUP(3, HE_GI_32, BW_20),
0293     HE_GROUP(4, HE_GI_32, BW_20),
0294     HE_GROUP(5, HE_GI_32, BW_20),
0295     HE_GROUP(6, HE_GI_32, BW_20),
0296     HE_GROUP(7, HE_GI_32, BW_20),
0297     HE_GROUP(8, HE_GI_32, BW_20),
0298 
0299     HE_GROUP(1, HE_GI_08, BW_40),
0300     HE_GROUP(2, HE_GI_08, BW_40),
0301     HE_GROUP(3, HE_GI_08, BW_40),
0302     HE_GROUP(4, HE_GI_08, BW_40),
0303     HE_GROUP(5, HE_GI_08, BW_40),
0304     HE_GROUP(6, HE_GI_08, BW_40),
0305     HE_GROUP(7, HE_GI_08, BW_40),
0306     HE_GROUP(8, HE_GI_08, BW_40),
0307 
0308     HE_GROUP(1, HE_GI_16, BW_40),
0309     HE_GROUP(2, HE_GI_16, BW_40),
0310     HE_GROUP(3, HE_GI_16, BW_40),
0311     HE_GROUP(4, HE_GI_16, BW_40),
0312     HE_GROUP(5, HE_GI_16, BW_40),
0313     HE_GROUP(6, HE_GI_16, BW_40),
0314     HE_GROUP(7, HE_GI_16, BW_40),
0315     HE_GROUP(8, HE_GI_16, BW_40),
0316 
0317     HE_GROUP(1, HE_GI_32, BW_40),
0318     HE_GROUP(2, HE_GI_32, BW_40),
0319     HE_GROUP(3, HE_GI_32, BW_40),
0320     HE_GROUP(4, HE_GI_32, BW_40),
0321     HE_GROUP(5, HE_GI_32, BW_40),
0322     HE_GROUP(6, HE_GI_32, BW_40),
0323     HE_GROUP(7, HE_GI_32, BW_40),
0324     HE_GROUP(8, HE_GI_32, BW_40),
0325 
0326     HE_GROUP(1, HE_GI_08, BW_80),
0327     HE_GROUP(2, HE_GI_08, BW_80),
0328     HE_GROUP(3, HE_GI_08, BW_80),
0329     HE_GROUP(4, HE_GI_08, BW_80),
0330     HE_GROUP(5, HE_GI_08, BW_80),
0331     HE_GROUP(6, HE_GI_08, BW_80),
0332     HE_GROUP(7, HE_GI_08, BW_80),
0333     HE_GROUP(8, HE_GI_08, BW_80),
0334 
0335     HE_GROUP(1, HE_GI_16, BW_80),
0336     HE_GROUP(2, HE_GI_16, BW_80),
0337     HE_GROUP(3, HE_GI_16, BW_80),
0338     HE_GROUP(4, HE_GI_16, BW_80),
0339     HE_GROUP(5, HE_GI_16, BW_80),
0340     HE_GROUP(6, HE_GI_16, BW_80),
0341     HE_GROUP(7, HE_GI_16, BW_80),
0342     HE_GROUP(8, HE_GI_16, BW_80),
0343 
0344     HE_GROUP(1, HE_GI_32, BW_80),
0345     HE_GROUP(2, HE_GI_32, BW_80),
0346     HE_GROUP(3, HE_GI_32, BW_80),
0347     HE_GROUP(4, HE_GI_32, BW_80),
0348     HE_GROUP(5, HE_GI_32, BW_80),
0349     HE_GROUP(6, HE_GI_32, BW_80),
0350     HE_GROUP(7, HE_GI_32, BW_80),
0351     HE_GROUP(8, HE_GI_32, BW_80),
0352 
0353     HE_GROUP(1, HE_GI_08, BW_160),
0354     HE_GROUP(2, HE_GI_08, BW_160),
0355     HE_GROUP(3, HE_GI_08, BW_160),
0356     HE_GROUP(4, HE_GI_08, BW_160),
0357     HE_GROUP(5, HE_GI_08, BW_160),
0358     HE_GROUP(6, HE_GI_08, BW_160),
0359     HE_GROUP(7, HE_GI_08, BW_160),
0360     HE_GROUP(8, HE_GI_08, BW_160),
0361 
0362     HE_GROUP(1, HE_GI_16, BW_160),
0363     HE_GROUP(2, HE_GI_16, BW_160),
0364     HE_GROUP(3, HE_GI_16, BW_160),
0365     HE_GROUP(4, HE_GI_16, BW_160),
0366     HE_GROUP(5, HE_GI_16, BW_160),
0367     HE_GROUP(6, HE_GI_16, BW_160),
0368     HE_GROUP(7, HE_GI_16, BW_160),
0369     HE_GROUP(8, HE_GI_16, BW_160),
0370 
0371     HE_GROUP(1, HE_GI_32, BW_160),
0372     HE_GROUP(2, HE_GI_32, BW_160),
0373     HE_GROUP(3, HE_GI_32, BW_160),
0374     HE_GROUP(4, HE_GI_32, BW_160),
0375     HE_GROUP(5, HE_GI_32, BW_160),
0376     HE_GROUP(6, HE_GI_32, BW_160),
0377     HE_GROUP(7, HE_GI_32, BW_160),
0378     HE_GROUP(8, HE_GI_32, BW_160),
0379 };
0380 
0381 static u32
0382 ieee80211_calc_legacy_rate_duration(u16 bitrate, bool short_pre,
0383                     bool cck, int len)
0384 {
0385     u32 duration;
0386 
0387     if (cck) {
0388         duration = 144 + 48; /* preamble + PLCP */
0389         if (short_pre)
0390             duration >>= 1;
0391 
0392         duration += 10; /* SIFS */
0393     } else {
0394         duration = 20 + 16; /* premable + SIFS */
0395     }
0396 
0397     len <<= 3;
0398     duration += (len * 10) / bitrate;
0399 
0400     return duration;
0401 }
0402 
0403 static u32 ieee80211_get_rate_duration(struct ieee80211_hw *hw,
0404                        struct ieee80211_rx_status *status,
0405                        u32 *overhead)
0406 {
0407     bool sgi = status->enc_flags & RX_ENC_FLAG_SHORT_GI;
0408     int bw, streams;
0409     int group, idx;
0410     u32 duration;
0411 
0412     switch (status->bw) {
0413     case RATE_INFO_BW_20:
0414         bw = BW_20;
0415         break;
0416     case RATE_INFO_BW_40:
0417         bw = BW_40;
0418         break;
0419     case RATE_INFO_BW_80:
0420         bw = BW_80;
0421         break;
0422     case RATE_INFO_BW_160:
0423         bw = BW_160;
0424         break;
0425     default:
0426         WARN_ON_ONCE(1);
0427         return 0;
0428     }
0429 
0430     switch (status->encoding) {
0431     case RX_ENC_VHT:
0432         streams = status->nss;
0433         idx = status->rate_idx;
0434         group = VHT_GROUP_IDX(streams, sgi, bw);
0435         break;
0436     case RX_ENC_HT:
0437         streams = ((status->rate_idx >> 3) & 3) + 1;
0438         idx = status->rate_idx & 7;
0439         group = HT_GROUP_IDX(streams, sgi, bw);
0440         break;
0441     case RX_ENC_HE:
0442         streams = status->nss;
0443         idx = status->rate_idx;
0444         group = HE_GROUP_IDX(streams, status->he_gi, bw);
0445         break;
0446     default:
0447         WARN_ON_ONCE(1);
0448         return 0;
0449     }
0450 
0451     if (WARN_ON_ONCE((status->encoding != RX_ENC_HE && streams > 4) ||
0452              (status->encoding == RX_ENC_HE && streams > 8)))
0453         return 0;
0454 
0455     duration = airtime_mcs_groups[group].duration[idx];
0456     duration <<= airtime_mcs_groups[group].shift;
0457     *overhead = 36 + (streams << 2);
0458 
0459     return duration;
0460 }
0461 
0462 
0463 u32 ieee80211_calc_rx_airtime(struct ieee80211_hw *hw,
0464                   struct ieee80211_rx_status *status,
0465                   int len)
0466 {
0467     struct ieee80211_supported_band *sband;
0468     u32 duration, overhead = 0;
0469 
0470     if (status->encoding == RX_ENC_LEGACY) {
0471         const struct ieee80211_rate *rate;
0472         bool sp = status->enc_flags & RX_ENC_FLAG_SHORTPRE;
0473         bool cck;
0474 
0475         /* on 60GHz or sub-1GHz band, there are no legacy rates */
0476         if (WARN_ON_ONCE(status->band == NL80211_BAND_60GHZ ||
0477                  status->band == NL80211_BAND_S1GHZ))
0478             return 0;
0479 
0480         sband = hw->wiphy->bands[status->band];
0481         if (!sband || status->rate_idx >= sband->n_bitrates)
0482             return 0;
0483 
0484         rate = &sband->bitrates[status->rate_idx];
0485         cck = rate->flags & IEEE80211_RATE_MANDATORY_B;
0486 
0487         return ieee80211_calc_legacy_rate_duration(rate->bitrate, sp,
0488                                cck, len);
0489     }
0490 
0491     duration = ieee80211_get_rate_duration(hw, status, &overhead);
0492     if (!duration)
0493         return 0;
0494 
0495     duration *= len;
0496     duration /= AVG_PKT_SIZE;
0497     duration /= 1024;
0498 
0499     return duration + overhead;
0500 }
0501 EXPORT_SYMBOL_GPL(ieee80211_calc_rx_airtime);
0502 
0503 static bool ieee80211_fill_rate_info(struct ieee80211_hw *hw,
0504                      struct ieee80211_rx_status *stat, u8 band,
0505                      struct rate_info *ri)
0506 {
0507     struct ieee80211_supported_band *sband = hw->wiphy->bands[band];
0508     int i;
0509 
0510     if (!ri || !sband)
0511         return false;
0512 
0513     stat->bw = ri->bw;
0514     stat->nss = ri->nss;
0515     stat->rate_idx = ri->mcs;
0516 
0517     if (ri->flags & RATE_INFO_FLAGS_HE_MCS)
0518         stat->encoding = RX_ENC_HE;
0519     else if (ri->flags & RATE_INFO_FLAGS_VHT_MCS)
0520         stat->encoding = RX_ENC_VHT;
0521     else if (ri->flags & RATE_INFO_FLAGS_MCS)
0522         stat->encoding = RX_ENC_HT;
0523     else
0524         stat->encoding = RX_ENC_LEGACY;
0525 
0526     if (ri->flags & RATE_INFO_FLAGS_SHORT_GI)
0527         stat->enc_flags |= RX_ENC_FLAG_SHORT_GI;
0528 
0529     stat->he_gi = ri->he_gi;
0530 
0531     if (stat->encoding != RX_ENC_LEGACY)
0532         return true;
0533 
0534     stat->rate_idx = 0;
0535     for (i = 0; i < sband->n_bitrates; i++) {
0536         if (ri->legacy != sband->bitrates[i].bitrate)
0537             continue;
0538 
0539         stat->rate_idx = i;
0540         return true;
0541     }
0542 
0543     return false;
0544 }
0545 
0546 static int ieee80211_fill_rx_status(struct ieee80211_rx_status *stat,
0547                     struct ieee80211_hw *hw,
0548                     struct ieee80211_tx_rate *rate,
0549                     struct rate_info *ri, u8 band, int len)
0550 {
0551     memset(stat, 0, sizeof(*stat));
0552     stat->band = band;
0553 
0554     if (ieee80211_fill_rate_info(hw, stat, band, ri))
0555         return 0;
0556 
0557     if (rate->idx < 0 || !rate->count)
0558         return -1;
0559 
0560     if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
0561         stat->bw = RATE_INFO_BW_160;
0562     else if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
0563         stat->bw = RATE_INFO_BW_80;
0564     else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
0565         stat->bw = RATE_INFO_BW_40;
0566     else
0567         stat->bw = RATE_INFO_BW_20;
0568 
0569     stat->enc_flags = 0;
0570     if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
0571         stat->enc_flags |= RX_ENC_FLAG_SHORTPRE;
0572     if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
0573         stat->enc_flags |= RX_ENC_FLAG_SHORT_GI;
0574 
0575     stat->rate_idx = rate->idx;
0576     if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
0577         stat->encoding = RX_ENC_VHT;
0578         stat->rate_idx = ieee80211_rate_get_vht_mcs(rate);
0579         stat->nss = ieee80211_rate_get_vht_nss(rate);
0580     } else if (rate->flags & IEEE80211_TX_RC_MCS) {
0581         stat->encoding = RX_ENC_HT;
0582     } else {
0583         stat->encoding = RX_ENC_LEGACY;
0584     }
0585 
0586     return 0;
0587 }
0588 
0589 static u32 ieee80211_calc_tx_airtime_rate(struct ieee80211_hw *hw,
0590                       struct ieee80211_tx_rate *rate,
0591                       struct rate_info *ri,
0592                       u8 band, int len)
0593 {
0594     struct ieee80211_rx_status stat;
0595 
0596     if (ieee80211_fill_rx_status(&stat, hw, rate, ri, band, len))
0597         return 0;
0598 
0599     return ieee80211_calc_rx_airtime(hw, &stat, len);
0600 }
0601 
0602 u32 ieee80211_calc_tx_airtime(struct ieee80211_hw *hw,
0603                   struct ieee80211_tx_info *info,
0604                   int len)
0605 {
0606     u32 duration = 0;
0607     int i;
0608 
0609     for (i = 0; i < ARRAY_SIZE(info->status.rates); i++) {
0610         struct ieee80211_tx_rate *rate = &info->status.rates[i];
0611         u32 cur_duration;
0612 
0613         cur_duration = ieee80211_calc_tx_airtime_rate(hw, rate, NULL,
0614                                   info->band, len);
0615         if (!cur_duration)
0616             break;
0617 
0618         duration += cur_duration * rate->count;
0619     }
0620 
0621     return duration;
0622 }
0623 EXPORT_SYMBOL_GPL(ieee80211_calc_tx_airtime);
0624 
0625 u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw,
0626                        struct ieee80211_vif *vif,
0627                        struct ieee80211_sta *pubsta,
0628                        int len, bool ampdu)
0629 {
0630     struct ieee80211_supported_band *sband;
0631     struct ieee80211_chanctx_conf *conf;
0632     int rateidx, shift = 0;
0633     bool cck, short_pream;
0634     u32 basic_rates;
0635     u8 band = 0;
0636     u16 rate;
0637 
0638     len += 38; /* Ethernet header length */
0639 
0640     conf = rcu_dereference(vif->bss_conf.chanctx_conf);
0641     if (conf) {
0642         band = conf->def.chan->band;
0643         shift = ieee80211_chandef_get_shift(&conf->def);
0644     }
0645 
0646     if (pubsta) {
0647         struct sta_info *sta = container_of(pubsta, struct sta_info,
0648                             sta);
0649         struct ieee80211_rx_status stat;
0650         struct ieee80211_tx_rate *tx_rate = &sta->deflink.tx_stats.last_rate;
0651         struct rate_info *ri = &sta->deflink.tx_stats.last_rate_info;
0652         u32 duration, overhead;
0653         u8 agg_shift;
0654 
0655         if (ieee80211_fill_rx_status(&stat, hw, tx_rate, ri, band, len))
0656             return 0;
0657 
0658         if (stat.encoding == RX_ENC_LEGACY || !ampdu)
0659             return ieee80211_calc_rx_airtime(hw, &stat, len);
0660 
0661         duration = ieee80211_get_rate_duration(hw, &stat, &overhead);
0662         /*
0663          * Assume that HT/VHT transmission on any AC except VO will
0664          * use aggregation. Since we don't have reliable reporting
0665          * of aggregation length, assume an average size based on the
0666          * tx rate.
0667          * This will not be very accurate, but much better than simply
0668          * assuming un-aggregated tx in all cases.
0669          */
0670         if (duration > 400 * 1024) /* <= VHT20 MCS2 1S */
0671             agg_shift = 1;
0672         else if (duration > 250 * 1024) /* <= VHT20 MCS3 1S or MCS1 2S */
0673             agg_shift = 2;
0674         else if (duration > 150 * 1024) /* <= VHT20 MCS5 1S or MCS2 2S */
0675             agg_shift = 3;
0676         else if (duration > 70 * 1024) /* <= VHT20 MCS5 2S */
0677             agg_shift = 4;
0678         else if (stat.encoding != RX_ENC_HE ||
0679              duration > 20 * 1024) /* <= HE40 MCS6 2S */
0680             agg_shift = 5;
0681         else
0682             agg_shift = 6;
0683 
0684         duration *= len;
0685         duration /= AVG_PKT_SIZE;
0686         duration /= 1024;
0687         duration += (overhead >> agg_shift);
0688 
0689         return max_t(u32, duration, 4);
0690     }
0691 
0692     if (!conf)
0693         return 0;
0694 
0695     /* No station to get latest rate from, so calculate the worst-case
0696      * duration using the lowest configured basic rate.
0697      */
0698     sband = hw->wiphy->bands[band];
0699 
0700     basic_rates = vif->bss_conf.basic_rates;
0701     short_pream = vif->bss_conf.use_short_preamble;
0702 
0703     rateidx = basic_rates ? ffs(basic_rates) - 1 : 0;
0704     rate = sband->bitrates[rateidx].bitrate << shift;
0705     cck = sband->bitrates[rateidx].flags & IEEE80211_RATE_MANDATORY_B;
0706 
0707     return ieee80211_calc_legacy_rate_duration(rate, short_pream, cck, len);
0708 }