forked from Minki/linux
wireless: report reasonable bitrate for MCS rates through wext
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: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
a252e749f1
commit
254416aae7
|
@ -378,6 +378,8 @@ int rdev_set_freq(struct cfg80211_registered_device *rdev,
|
||||||
struct wireless_dev *for_wdev,
|
struct wireless_dev *for_wdev,
|
||||||
int freq, enum nl80211_channel_type channel_type);
|
int freq, enum nl80211_channel_type channel_type);
|
||||||
|
|
||||||
|
u16 cfg80211_calculate_bitrate(struct rate_info *rate);
|
||||||
|
|
||||||
#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
|
#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
|
||||||
#define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond)
|
#define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond)
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1637,39 +1637,6 @@ static int parse_station_flags(struct genl_info *info,
|
||||||
return 0;
|
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,
|
static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
|
||||||
int flags, struct net_device *dev,
|
int flags, struct net_device *dev,
|
||||||
u8 *mac_addr, struct station_info *sinfo)
|
u8 *mac_addr, struct station_info *sinfo)
|
||||||
|
@ -1716,8 +1683,8 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
|
||||||
if (!txrate)
|
if (!txrate)
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
|
||||||
/* nl80211_calculate_bitrate will return 0 for mcs >= 32 */
|
/* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
|
||||||
bitrate = nl80211_calculate_bitrate(&sinfo->txrate);
|
bitrate = cfg80211_calculate_bitrate(&sinfo->txrate);
|
||||||
if (bitrate > 0)
|
if (bitrate > 0)
|
||||||
NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
|
NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
|
||||||
|
|
||||||
|
|
|
@ -720,3 +720,36 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
|
||||||
|
|
||||||
return err;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -1256,10 +1256,7 @@ int cfg80211_wext_giwrate(struct net_device *dev,
|
||||||
if (!(sinfo.filled & STATION_INFO_TX_BITRATE))
|
if (!(sinfo.filled & STATION_INFO_TX_BITRATE))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
rate->value = 0;
|
rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo.txrate);
|
||||||
|
|
||||||
if (!(sinfo.txrate.flags & RATE_INFO_FLAGS_MCS))
|
|
||||||
rate->value = 100000 * sinfo.txrate.legacy;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user