diff options
-rw-r--r-- | include/linux/nl80211.h | 9 | ||||
-rw-r--r-- | include/net/cfg80211.h | 2 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 9 | ||||
-rw-r--r-- | net/wireless/util.c | 2 |
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 | */ |
3490 | u16 cfg80211_calculate_bitrate(struct rate_info *rate); | 3490 | u32 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 | ||
903 | u16 cfg80211_calculate_bitrate(struct rate_info *rate) | 903 | u32 cfg80211_calculate_bitrate(struct rate_info *rate) |
904 | { | 904 | { |
905 | int modulation, streams, bitrate; | 905 | int modulation, streams, bitrate; |
906 | 906 | ||