aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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