summaryrefslogtreecommitdiff
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-11-09 13:56:41 (GMT)
committerJohannes Berg <johannes.berg@intel.com>2012-11-26 11:42:59 (GMT)
commitdb9c64cf8d9d3fcbc34b09d037f266d1fc9f928c (patch)
tree86326193fa7ad6762023e1777402bc3662c53597 /net/wireless/nl80211.c
parent4bf88530be971bf95a7830ca61b4120980bf4347 (diff)
downloadlinux-fsl-qoriq-db9c64cf8d9d3fcbc34b09d037f266d1fc9f928c.tar.xz
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 15158a3..d038fa4 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,
rate = nla_nest_start(msg, attr);
if (!rate)
- goto nla_put_failure;
+ return false;
/* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
bitrate = cfg80211_calculate_bitrate(info);
/* report 16-bit bitrate only if we can */
bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
- if ((bitrate > 0 &&
- nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate)) ||
- (bitrate_compat > 0 &&
- nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat)) ||
- ((info->flags & RATE_INFO_FLAGS_MCS) &&
- nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs)) ||
- ((info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) &&
- nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH)) ||
- ((info->flags & RATE_INFO_FLAGS_SHORT_GI) &&
- nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI)))
- goto nla_put_failure;
+ if (bitrate > 0 &&
+ nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate))
+ return false;
+ if (bitrate_compat > 0 &&
+ nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
+ return false;
+
+ if (info->flags & RATE_INFO_FLAGS_MCS) {
+ if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
+ return false;
+ if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH &&
+ nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH))
+ return false;
+ if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
+ nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
+ return false;
+ } else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
+ if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
+ return false;
+ if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
+ return false;
+ if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH &&
+ nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH))
+ return false;
+ if (info->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH &&
+ nla_put_flag(msg, NL80211_RATE_INFO_80_MHZ_WIDTH))
+ return false;
+ if (info->flags & RATE_INFO_FLAGS_80P80_MHZ_WIDTH &&
+ nla_put_flag(msg, NL80211_RATE_INFO_80P80_MHZ_WIDTH))
+ return false;
+ if (info->flags & RATE_INFO_FLAGS_160_MHZ_WIDTH &&
+ nla_put_flag(msg, NL80211_RATE_INFO_160_MHZ_WIDTH))
+ return false;
+ if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
+ nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
+ return false;
+ }
nla_nest_end(msg, rate);
return true;
-
-nla_put_failure:
- return false;
}
static 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)
if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef))
return -EINVAL;
+ if (ibss.chandef.width > NL80211_CHAN_WIDTH_40)
+ return -EINVAL;
+ if (ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
+ !(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
+
ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];