aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/nl80211.h3
-rw-r--r--include/net/cfg80211.h5
-rw-r--r--net/wireless/nl80211.c56
3 files changed, 44 insertions, 20 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 821ffb954f14..30022189104d 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1243,6 +1243,8 @@ enum nl80211_rate_info {
1243 * @NL80211_STA_INFO_LLID: the station's mesh LLID 1243 * @NL80211_STA_INFO_LLID: the station's mesh LLID
1244 * @NL80211_STA_INFO_PLID: the station's mesh PLID 1244 * @NL80211_STA_INFO_PLID: the station's mesh PLID
1245 * @NL80211_STA_INFO_PLINK_STATE: peer link state for the station 1245 * @NL80211_STA_INFO_PLINK_STATE: peer link state for the station
1246 * @NL80211_STA_INFO_RX_BITRATE: last unicast data frame rx rate, nested
1247 * attribute, like NL80211_STA_INFO_TX_BITRATE.
1246 * @__NL80211_STA_INFO_AFTER_LAST: internal 1248 * @__NL80211_STA_INFO_AFTER_LAST: internal
1247 * @NL80211_STA_INFO_MAX: highest possible station info attribute 1249 * @NL80211_STA_INFO_MAX: highest possible station info attribute
1248 */ 1250 */
@@ -1261,6 +1263,7 @@ enum nl80211_sta_info {
1261 NL80211_STA_INFO_TX_RETRIES, 1263 NL80211_STA_INFO_TX_RETRIES,
1262 NL80211_STA_INFO_TX_FAILED, 1264 NL80211_STA_INFO_TX_FAILED,
1263 NL80211_STA_INFO_SIGNAL_AVG, 1265 NL80211_STA_INFO_SIGNAL_AVG,
1266 NL80211_STA_INFO_RX_BITRATE,
1264 1267
1265 /* keep last */ 1268 /* keep last */
1266 __NL80211_STA_INFO_AFTER_LAST, 1269 __NL80211_STA_INFO_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 679a0494b5f2..1ac5786da14b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -413,7 +413,7 @@ struct station_parameters {
413 * @STATION_INFO_PLID: @plid filled 413 * @STATION_INFO_PLID: @plid filled
414 * @STATION_INFO_PLINK_STATE: @plink_state filled 414 * @STATION_INFO_PLINK_STATE: @plink_state filled
415 * @STATION_INFO_SIGNAL: @signal filled 415 * @STATION_INFO_SIGNAL: @signal filled
416 * @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled 416 * @STATION_INFO_TX_BITRATE: @txrate fields are filled
417 * (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) 417 * (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs)
418 * @STATION_INFO_RX_PACKETS: @rx_packets filled 418 * @STATION_INFO_RX_PACKETS: @rx_packets filled
419 * @STATION_INFO_TX_PACKETS: @tx_packets filled 419 * @STATION_INFO_TX_PACKETS: @tx_packets filled
@@ -421,6 +421,7 @@ struct station_parameters {
421 * @STATION_INFO_TX_FAILED: @tx_failed filled 421 * @STATION_INFO_TX_FAILED: @tx_failed filled
422 * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled 422 * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled
423 * @STATION_INFO_SIGNAL_AVG: @signal_avg filled 423 * @STATION_INFO_SIGNAL_AVG: @signal_avg filled
424 * @STATION_INFO_RX_BITRATE: @rxrate fields are filled
424 */ 425 */
425enum station_info_flags { 426enum station_info_flags {
426 STATION_INFO_INACTIVE_TIME = 1<<0, 427 STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -437,6 +438,7 @@ enum station_info_flags {
437 STATION_INFO_TX_FAILED = 1<<11, 438 STATION_INFO_TX_FAILED = 1<<11,
438 STATION_INFO_RX_DROP_MISC = 1<<12, 439 STATION_INFO_RX_DROP_MISC = 1<<12,
439 STATION_INFO_SIGNAL_AVG = 1<<13, 440 STATION_INFO_SIGNAL_AVG = 1<<13,
441 STATION_INFO_RX_BITRATE = 1<<14,
440}; 442};
441 443
442/** 444/**
@@ -506,6 +508,7 @@ struct station_info {
506 s8 signal; 508 s8 signal;
507 s8 signal_avg; 509 s8 signal_avg;
508 struct rate_info txrate; 510 struct rate_info txrate;
511 struct rate_info rxrate;
509 u32 rx_packets; 512 u32 rx_packets;
510 u32 tx_packets; 513 u32 tx_packets;
511 u32 tx_retries; 514 u32 tx_retries;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 864ddfbeff2f..4ebce4284e9d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1968,13 +1968,41 @@ static int parse_station_flags(struct genl_info *info,
1968 return 0; 1968 return 0;
1969} 1969}
1970 1970
1971static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
1972 int attr)
1973{
1974 struct nlattr *rate;
1975 u16 bitrate;
1976
1977 rate = nla_nest_start(msg, attr);
1978 if (!rate)
1979 goto nla_put_failure;
1980
1981 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
1982 bitrate = cfg80211_calculate_bitrate(info);
1983 if (bitrate > 0)
1984 NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
1985
1986 if (info->flags & RATE_INFO_FLAGS_MCS)
1987 NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS, info->mcs);
1988 if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
1989 NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
1990 if (info->flags & RATE_INFO_FLAGS_SHORT_GI)
1991 NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);
1992
1993 nla_nest_end(msg, rate);
1994 return true;
1995
1996nla_put_failure:
1997 return false;
1998}
1999
1971static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, 2000static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
1972 int flags, struct net_device *dev, 2001 int flags, struct net_device *dev,
1973 const u8 *mac_addr, struct station_info *sinfo) 2002 const u8 *mac_addr, struct station_info *sinfo)
1974{ 2003{
1975 void *hdr; 2004 void *hdr;
1976 struct nlattr *sinfoattr, *txrate; 2005 struct nlattr *sinfoattr;
1977 u16 bitrate;
1978 2006
1979 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); 2007 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
1980 if (!hdr) 2008 if (!hdr)
@@ -2013,24 +2041,14 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
2013 NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG, 2041 NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG,
2014 sinfo->signal_avg); 2042 sinfo->signal_avg);
2015 if (sinfo->filled & STATION_INFO_TX_BITRATE) { 2043 if (sinfo->filled & STATION_INFO_TX_BITRATE) {
2016 txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE); 2044 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
2017 if (!txrate) 2045 NL80211_STA_INFO_TX_BITRATE))
2046 goto nla_put_failure;
2047 }
2048 if (sinfo->filled & STATION_INFO_RX_BITRATE) {
2049 if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
2050 NL80211_STA_INFO_RX_BITRATE))
2018 goto nla_put_failure; 2051 goto nla_put_failure;
2019
2020 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
2021 bitrate = cfg80211_calculate_bitrate(&sinfo->txrate);
2022 if (bitrate > 0)
2023 NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
2024
2025 if (sinfo->txrate.flags & RATE_INFO_FLAGS_MCS)
2026 NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS,
2027 sinfo->txrate.mcs);
2028 if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
2029 NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
2030 if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI)
2031 NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);
2032
2033 nla_nest_end(msg, txrate);
2034 } 2052 }
2035 if (sinfo->filled & STATION_INFO_RX_PACKETS) 2053 if (sinfo->filled & STATION_INFO_RX_PACKETS)
2036 NLA_PUT_U32(msg, NL80211_STA_INFO_RX_PACKETS, 2054 NLA_PUT_U32(msg, NL80211_STA_INFO_RX_PACKETS,