aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/util.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-11-09 08:56:41 -0500
committerJohannes Berg <johannes.berg@intel.com>2012-11-26 06:42:59 -0500
commitdb9c64cf8d9d3fcbc34b09d037f266d1fc9f928c (patch)
tree86326193fa7ad6762023e1777402bc3662c53597 /net/wireless/util.c
parent4bf88530be971bf95a7830ca61b4120980bf4347 (diff)
nl80211/cfg80211: add VHT MCS support
Add support for reporting and calculating VHT MCSes. Note that I'm not completely sure that the bitrate calculations are correct, nor that they can't be simplified. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/util.c')
-rw-r--r--net/wireless/util.c74
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
947static 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
947u32 cfg80211_calculate_bitrate(struct rate_info *rate) 1016u32 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))