diff options
Diffstat (limited to 'net/wireless/util.c')
-rw-r--r-- | net/wireless/util.c | 74 |
1 files changed, 73 insertions, 1 deletions
diff --git a/net/wireless/util.c b/net/wireless/util.c index db61fe8a6b6..3cce6e48621 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -944,14 +944,86 @@ static u32 cfg80211_calculate_bitrate_60g(struct rate_info *rate) | |||
944 | return __mcs2bitrate[rate->mcs]; | 944 | return __mcs2bitrate[rate->mcs]; |
945 | } | 945 | } |
946 | 946 | ||
947 | static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate) | ||
948 | { | ||
949 | static const u32 base[4][10] = { | ||
950 | { 6500000, | ||
951 | 13000000, | ||
952 | 19500000, | ||
953 | 26000000, | ||
954 | 39000000, | ||
955 | 52000000, | ||
956 | 58500000, | ||
957 | 65000000, | ||
958 | 78000000, | ||
959 | 0, | ||
960 | }, | ||
961 | { 13500000, | ||
962 | 27000000, | ||
963 | 40500000, | ||
964 | 54000000, | ||
965 | 81000000, | ||
966 | 108000000, | ||
967 | 121500000, | ||
968 | 135000000, | ||
969 | 162000000, | ||
970 | 180000000, | ||
971 | }, | ||
972 | { 29300000, | ||
973 | 58500000, | ||
974 | 87800000, | ||
975 | 117000000, | ||
976 | 175500000, | ||
977 | 234000000, | ||
978 | 263300000, | ||
979 | 292500000, | ||
980 | 351000000, | ||
981 | 390000000, | ||
982 | }, | ||
983 | { 58500000, | ||
984 | 117000000, | ||
985 | 175500000, | ||
986 | 234000000, | ||
987 | 351000000, | ||
988 | 468000000, | ||
989 | 526500000, | ||
990 | 585000000, | ||
991 | 702000000, | ||
992 | 780000000, | ||
993 | }, | ||
994 | }; | ||
995 | u32 bitrate; | ||
996 | int idx; | ||
997 | |||
998 | if (WARN_ON_ONCE(rate->mcs > 9)) | ||
999 | return 0; | ||
1000 | |||
1001 | idx = rate->flags & (RATE_INFO_FLAGS_160_MHZ_WIDTH | | ||
1002 | RATE_INFO_FLAGS_80P80_MHZ_WIDTH) ? 3 : | ||
1003 | rate->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH ? 2 : | ||
1004 | rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH ? 1 : 0; | ||
1005 | |||
1006 | bitrate = base[idx][rate->mcs]; | ||
1007 | bitrate *= rate->nss; | ||
1008 | |||
1009 | if (rate->flags & RATE_INFO_FLAGS_SHORT_GI) | ||
1010 | bitrate = (bitrate / 9) * 10; | ||
1011 | |||
1012 | /* do NOT round down here */ | ||
1013 | return (bitrate + 50000) / 100000; | ||
1014 | } | ||
1015 | |||
947 | u32 cfg80211_calculate_bitrate(struct rate_info *rate) | 1016 | u32 cfg80211_calculate_bitrate(struct rate_info *rate) |
948 | { | 1017 | { |
949 | int modulation, streams, bitrate; | 1018 | int modulation, streams, bitrate; |
950 | 1019 | ||
951 | if (!(rate->flags & RATE_INFO_FLAGS_MCS)) | 1020 | if (!(rate->flags & RATE_INFO_FLAGS_MCS) && |
1021 | !(rate->flags & RATE_INFO_FLAGS_VHT_MCS)) | ||
952 | return rate->legacy; | 1022 | return rate->legacy; |
953 | if (rate->flags & RATE_INFO_FLAGS_60G) | 1023 | if (rate->flags & RATE_INFO_FLAGS_60G) |
954 | return cfg80211_calculate_bitrate_60g(rate); | 1024 | return cfg80211_calculate_bitrate_60g(rate); |
1025 | if (rate->flags & RATE_INFO_FLAGS_VHT_MCS) | ||
1026 | return cfg80211_calculate_bitrate_vht(rate); | ||
955 | 1027 | ||
956 | /* the formula below does only work for MCS values smaller than 32 */ | 1028 | /* the formula below does only work for MCS values smaller than 32 */ |
957 | if (WARN_ON_ONCE(rate->mcs >= 32)) | 1029 | if (WARN_ON_ONCE(rate->mcs >= 32)) |