Commit 46615c1f authored by John W. Linville's avatar John W. Linville Committed by Greg Kroah-Hartman

wireless: report reasonable bitrate for MCS rates through wext

commit 254416aa upstream.

Previously, cfg80211 had reported "0" for MCS (i.e. 802.11n) bitrates
through the wireless extensions interface.  However, nl80211 was
converting MCS rates into a reasonable bitrate number.  This patch moves
the nl80211 code to cfg80211 where it is now shared between both the
nl80211 interface and the wireless extensions interface.
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
Cc: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 009503a9
......@@ -385,6 +385,8 @@ int rdev_set_freq(struct cfg80211_registered_device *rdev,
struct wireless_dev *for_wdev,
int freq, enum nl80211_channel_type channel_type);
u16 cfg80211_calculate_bitrate(struct rate_info *rate);
#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
#define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond)
#else
......
......@@ -1562,39 +1562,6 @@ static int parse_station_flags(struct genl_info *info,
return 0;
}
static u16 nl80211_calculate_bitrate(struct rate_info *rate)
{
int modulation, streams, bitrate;
if (!(rate->flags & RATE_INFO_FLAGS_MCS))
return rate->legacy;
/* the formula below does only work for MCS values smaller than 32 */
if (rate->mcs >= 32)
return 0;
modulation = rate->mcs & 7;
streams = (rate->mcs >> 3) + 1;
bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ?
13500000 : 6500000;
if (modulation < 4)
bitrate *= (modulation + 1);
else if (modulation == 4)
bitrate *= (modulation + 2);
else
bitrate *= (modulation + 3);
bitrate *= streams;
if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
bitrate = (bitrate / 9) * 10;
/* do NOT round down here */
return (bitrate + 50000) / 100000;
}
static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
int flags, struct net_device *dev,
u8 *mac_addr, struct station_info *sinfo)
......@@ -1641,8 +1608,8 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
if (!txrate)
goto nla_put_failure;
/* nl80211_calculate_bitrate will return 0 for mcs >= 32 */
bitrate = nl80211_calculate_bitrate(&sinfo->txrate);
/* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
bitrate = cfg80211_calculate_bitrate(&sinfo->txrate);
if (bitrate > 0)
NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
......
......@@ -682,3 +682,36 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
return err;
}
u16 cfg80211_calculate_bitrate(struct rate_info *rate)
{
int modulation, streams, bitrate;
if (!(rate->flags & RATE_INFO_FLAGS_MCS))
return rate->legacy;
/* the formula below does only work for MCS values smaller than 32 */
if (rate->mcs >= 32)
return 0;
modulation = rate->mcs & 7;
streams = (rate->mcs >> 3) + 1;
bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ?
13500000 : 6500000;
if (modulation < 4)
bitrate *= (modulation + 1);
else if (modulation == 4)
bitrate *= (modulation + 2);
else
bitrate *= (modulation + 3);
bitrate *= streams;
if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
bitrate = (bitrate / 9) * 10;
/* do NOT round down here */
return (bitrate + 50000) / 100000;
}
......@@ -1227,10 +1227,7 @@ int cfg80211_wext_giwrate(struct net_device *dev,
if (!(sinfo.filled & STATION_INFO_TX_BITRATE))
return -EOPNOTSUPP;
rate->value = 0;
if (!(sinfo.txrate.flags & RATE_INFO_FLAGS_MCS))
rate->value = 100000 * sinfo.txrate.legacy;
rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo.txrate);
return 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment