aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.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/nl80211.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/nl80211.c')
-rw-r--r--net/wireless/nl80211.c58
1 files changed, 43 insertions, 15 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 15158a3d64a..d038fa45ecd 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2890,29 +2890,52 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
2890 2890
2891 rate = nla_nest_start(msg, attr); 2891 rate = nla_nest_start(msg, attr);
2892 if (!rate) 2892 if (!rate)
2893 goto nla_put_failure; 2893 return false;
2894 2894
2895 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */ 2895 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
2896 bitrate = cfg80211_calculate_bitrate(info); 2896 bitrate = cfg80211_calculate_bitrate(info);
2897 /* report 16-bit bitrate only if we can */ 2897 /* report 16-bit bitrate only if we can */
2898 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0; 2898 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
2899 if ((bitrate > 0 && 2899 if (bitrate > 0 &&
2900 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate)) || 2900 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate))
2901 (bitrate_compat > 0 && 2901 return false;
2902 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat)) || 2902 if (bitrate_compat > 0 &&
2903 ((info->flags & RATE_INFO_FLAGS_MCS) && 2903 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
2904 nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs)) || 2904 return false;
2905 ((info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) && 2905
2906 nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH)) || 2906 if (info->flags & RATE_INFO_FLAGS_MCS) {
2907 ((info->flags & RATE_INFO_FLAGS_SHORT_GI) && 2907 if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
2908 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))) 2908 return false;
2909 goto nla_put_failure; 2909 if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH &&
2910 nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH))
2911 return false;
2912 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
2913 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
2914 return false;
2915 } else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
2916 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
2917 return false;
2918 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
2919 return false;
2920 if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH &&
2921 nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH))
2922 return false;
2923 if (info->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH &&
2924 nla_put_flag(msg, NL80211_RATE_INFO_80_MHZ_WIDTH))
2925 return false;
2926 if (info->flags & RATE_INFO_FLAGS_80P80_MHZ_WIDTH &&
2927 nla_put_flag(msg, NL80211_RATE_INFO_80P80_MHZ_WIDTH))
2928 return false;
2929 if (info->flags & RATE_INFO_FLAGS_160_MHZ_WIDTH &&
2930 nla_put_flag(msg, NL80211_RATE_INFO_160_MHZ_WIDTH))
2931 return false;
2932 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
2933 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
2934 return false;
2935 }
2910 2936
2911 nla_nest_end(msg, rate); 2937 nla_nest_end(msg, rate);
2912 return true; 2938 return true;
2913
2914nla_put_failure:
2915 return false;
2916} 2939}
2917 2940
2918static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, 2941static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
@@ -5475,6 +5498,11 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
5475 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef)) 5498 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef))
5476 return -EINVAL; 5499 return -EINVAL;
5477 5500
5501 if (ibss.chandef.width > NL80211_CHAN_WIDTH_40)
5502 return -EINVAL;
5503 if (ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
5504 !(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
5505
5478 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; 5506 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
5479 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; 5507 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
5480 5508