aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>2012-07-05 07:25:49 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-07-05 09:18:30 -0400
commit8eb41c8dfb9e2396d2452ada9023a83d610b9051 (patch)
tree26bf8e96976e639a65441e3f2b1c03b1bcf2e7be
parentc5a7e582490c423f0685e42ee5cfb7c6de81adb0 (diff)
{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>
-rw-r--r--include/linux/nl80211.h9
-rw-r--r--include/net/cfg80211.h2
-rw-r--r--net/wireless/nl80211.c9
-rw-r--r--net/wireless/util.c2
4 files changed, 18 insertions, 4 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 74cc55c1bf28..db961a59247f 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1638,12 +1638,20 @@ struct nl80211_sta_flag_update {
1638 * 1638 *
1639 * These attribute types are used with %NL80211_STA_INFO_TXRATE 1639 * These attribute types are used with %NL80211_STA_INFO_TXRATE
1640 * when getting information about the bitrate of a station. 1640 * when getting information about the bitrate of a station.
1641 * There are 2 attributes for bitrate, a legacy one that represents
1642 * a 16-bit value, and new one that represents a 32-bit value.
1643 * If the rate value fits into 16 bit, both attributes are reported
1644 * with the same value. If the rate is too high to fit into 16 bits
1645 * (>6.5535Gbps) only 32-bit attribute is included.
1646 * User space tools encouraged to use the 32-bit attribute and fall
1647 * back to the 16-bit one for compatibility with older kernels.
1641 * 1648 *
1642 * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved 1649 * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved
1643 * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) 1650 * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s)
1644 * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) 1651 * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8)
1645 * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate 1652 * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate
1646 * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval 1653 * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval
1654 * @NL80211_RATE_INFO_BITRATE32: total bitrate (u32, 100kbit/s)
1647 * @NL80211_RATE_INFO_MAX: highest rate_info number currently defined 1655 * @NL80211_RATE_INFO_MAX: highest rate_info number currently defined
1648 * @__NL80211_RATE_INFO_AFTER_LAST: internal use 1656 * @__NL80211_RATE_INFO_AFTER_LAST: internal use
1649 */ 1657 */
@@ -1653,6 +1661,7 @@ enum nl80211_rate_info {
1653 NL80211_RATE_INFO_MCS, 1661 NL80211_RATE_INFO_MCS,
1654 NL80211_RATE_INFO_40_MHZ_WIDTH, 1662 NL80211_RATE_INFO_40_MHZ_WIDTH,
1655 NL80211_RATE_INFO_SHORT_GI, 1663 NL80211_RATE_INFO_SHORT_GI,
1664 NL80211_RATE_INFO_BITRATE32,
1656 1665
1657 /* keep last */ 1666 /* keep last */
1658 __NL80211_RATE_INFO_AFTER_LAST, 1667 __NL80211_RATE_INFO_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0b564e83a24b..8837efc368f9 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3487,7 +3487,7 @@ void cfg80211_ch_switch_notify(struct net_device *dev, int freq,
3487 * 3487 *
3488 * return 0 if MCS index >= 32 3488 * return 0 if MCS index >= 32
3489 */ 3489 */
3490u16 cfg80211_calculate_bitrate(struct rate_info *rate); 3490u32 cfg80211_calculate_bitrate(struct rate_info *rate);
3491 3491
3492/* Logging, debugging and troubleshooting/diagnostic helpers. */ 3492/* Logging, debugging and troubleshooting/diagnostic helpers. */
3493 3493
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 77102e66f1ea..2a5cdb60bc6e 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2618,7 +2618,8 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
2618 int attr) 2618 int attr)
2619{ 2619{
2620 struct nlattr *rate; 2620 struct nlattr *rate;
2621 u16 bitrate; 2621 u32 bitrate;
2622 u16 bitrate_compat;
2622 2623
2623 rate = nla_nest_start(msg, attr); 2624 rate = nla_nest_start(msg, attr);
2624 if (!rate) 2625 if (!rate)
@@ -2626,8 +2627,12 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
2626 2627
2627 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */ 2628 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
2628 bitrate = cfg80211_calculate_bitrate(info); 2629 bitrate = cfg80211_calculate_bitrate(info);
2630 /* report 16-bit bitrate only if we can */
2631 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
2629 if ((bitrate > 0 && 2632 if ((bitrate > 0 &&
2630 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate)) || 2633 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate)) ||
2634 (bitrate_compat > 0 &&
2635 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat)) ||
2631 ((info->flags & RATE_INFO_FLAGS_MCS) && 2636 ((info->flags & RATE_INFO_FLAGS_MCS) &&
2632 nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs)) || 2637 nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs)) ||
2633 ((info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) && 2638 ((info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) &&
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 0228c64e73d8..6e52726f7fe3 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -900,7 +900,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
900 return err; 900 return err;
901} 901}
902 902
903u16 cfg80211_calculate_bitrate(struct rate_info *rate) 903u32 cfg80211_calculate_bitrate(struct rate_info *rate)
904{ 904{
905 int modulation, streams, bitrate; 905 int modulation, streams, bitrate;
906 906