BACKPORT: {nl,cfg}80211: support high bitrates

Until now, a u16 value was used to represent bitrate value.
With VHT bitrates this becomes too small.

Introduce a new 32-bit bitrate attribute. nl80211 will report
both the new and the old attribute, unless the bitrate doesn't
fit into the old u16 attribute in which case only the new one
will be reported.

User space tools encouraged to prefer the 32-bit attribute, if
available (since it won't be available on older kernels.)

Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
[reword commit message and comments a bit]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

[AdrianDC] Includes if () improvements from commit
           "nl80211/cfg80211: add VHT MCS support"
           by Johannes Berg, Fri, 9 Nov 2012

Change-Id: Ib5823475ba368954e51ac4129b400a58fd74e28d
Signed-off-by: Adrian DC <radian.dc@gmail.com>
Signed-off-by: Kevin F. Haggerty <haggertk@lineageos.org>
This commit is contained in:
Vladimir Kondratiev 2012-07-05 14:25:49 +03:00 committed by Francescodario Cuzzocrea
parent 701b0f9b09
commit f11f83aa75
5 changed files with 22 additions and 6 deletions

View File

@ -1956,12 +1956,20 @@ struct nl80211_sta_flag_update {
*
* These attribute types are used with %NL80211_STA_INFO_TXRATE
* when getting information about the bitrate of a station.
* There are 2 attributes for bitrate, a legacy one that represents
* a 16-bit value, and new one that represents a 32-bit value.
* If the rate value fits into 16 bit, both attributes are reported
* with the same value. If the rate is too high to fit into 16 bits
* (>6.5535Gbps) only 32-bit attribute is included.
* User space tools encouraged to use the 32-bit attribute and fall
* back to the 16-bit one for compatibility with older kernels.
*
* @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved
* @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s)
* @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8)
* @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 MHz dualchannel bitrate
* @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval
* @NL80211_RATE_INFO_BITRATE32: total bitrate (u32, 100kbit/s)
* @NL80211_RATE_INFO_MAX: highest rate_info number currently defined
* @NL80211_RATE_INFO_VHT_MCS: MCS index for VHT (u8)
* @NL80211_RATE_INFO_VHT_NSS: number of streams in VHT (u8)
@ -1976,6 +1984,7 @@ enum nl80211_rate_info {
NL80211_RATE_INFO_MCS,
NL80211_RATE_INFO_40_MHZ_WIDTH,
NL80211_RATE_INFO_SHORT_GI,
NL80211_RATE_INFO_BITRATE32,
NL80211_RATE_INFO_VHT_MCS,
NL80211_RATE_INFO_VHT_NSS,
NL80211_RATE_INFO_80_MHZ_WIDTH,

View File

@ -3778,7 +3778,7 @@ void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
*
* return 0 if MCS index >= 32
*/
u16 cfg80211_calculate_bitrate(struct rate_info *rate);
u32 cfg80211_calculate_bitrate(struct rate_info *rate);
/**
* struct cfg80211_ft_event - FT Information Elements

View File

@ -444,7 +444,7 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev, int freq,
enum nl80211_channel_type channel_type);
u16 cfg80211_calculate_bitrate(struct rate_info *rate);
u32 cfg80211_calculate_bitrate(struct rate_info *rate);
int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
const u8 *rates, unsigned int n_rates,
u32 *mask);

View File

@ -2554,7 +2554,8 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
int attr)
{
struct nlattr *rate;
u16 bitrate;
u32 bitrate;
u16 bitrate_compat;
rate = nla_nest_start(msg, attr);
if (!rate)
@ -2562,8 +2563,14 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
/* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
bitrate = cfg80211_calculate_bitrate(info);
if (bitrate > 0)
nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
/* 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))
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))

View File

@ -968,7 +968,7 @@ static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate)
return (bitrate + 50000) / 100000;
}
u16 cfg80211_calculate_bitrate(struct rate_info *rate)
u32 cfg80211_calculate_bitrate(struct rate_info *rate)
{
int modulation, streams, bitrate;