cfg80211: add support for per-chain signal strength reporting

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Felix Fietkau 2013-04-22 16:29:30 +02:00 committed by Johannes Berg
parent f722406faa
commit 119363c7dc
3 changed files with 58 additions and 0 deletions

View File

@ -753,6 +753,8 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
* @STATION_INFO_LOCAL_PM: @local_pm filled * @STATION_INFO_LOCAL_PM: @local_pm filled
* @STATION_INFO_PEER_PM: @peer_pm filled * @STATION_INFO_PEER_PM: @peer_pm filled
* @STATION_INFO_NONPEER_PM: @nonpeer_pm filled * @STATION_INFO_NONPEER_PM: @nonpeer_pm filled
* @STATION_INFO_CHAIN_SIGNAL: @chain_signal filled
* @STATION_INFO_CHAIN_SIGNAL_AVG: @chain_signal_avg filled
*/ */
enum station_info_flags { enum station_info_flags {
STATION_INFO_INACTIVE_TIME = 1<<0, STATION_INFO_INACTIVE_TIME = 1<<0,
@ -781,6 +783,8 @@ enum station_info_flags {
STATION_INFO_NONPEER_PM = 1<<23, STATION_INFO_NONPEER_PM = 1<<23,
STATION_INFO_RX_BYTES64 = 1<<24, STATION_INFO_RX_BYTES64 = 1<<24,
STATION_INFO_TX_BYTES64 = 1<<25, STATION_INFO_TX_BYTES64 = 1<<25,
STATION_INFO_CHAIN_SIGNAL = 1<<26,
STATION_INFO_CHAIN_SIGNAL_AVG = 1<<27,
}; };
/** /**
@ -857,6 +861,8 @@ struct sta_bss_parameters {
u16 beacon_interval; u16 beacon_interval;
}; };
#define IEEE80211_MAX_CHAINS 4
/** /**
* struct station_info - station information * struct station_info - station information
* *
@ -874,6 +880,9 @@ struct sta_bss_parameters {
* For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
* @signal_avg: Average signal strength, type depends on the wiphy's signal_type. * @signal_avg: Average signal strength, type depends on the wiphy's signal_type.
* For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
* @chains: bitmask for filled values in @chain_signal, @chain_signal_avg
* @chain_signal: per-chain signal strength of last received packet in dBm
* @chain_signal_avg: per-chain signal strength average in dBm
* @txrate: current unicast bitrate from this station * @txrate: current unicast bitrate from this station
* @rxrate: current unicast bitrate to this station * @rxrate: current unicast bitrate to this station
* @rx_packets: packets received from this station * @rx_packets: packets received from this station
@ -909,6 +918,11 @@ struct station_info {
u8 plink_state; u8 plink_state;
s8 signal; s8 signal;
s8 signal_avg; s8 signal_avg;
u8 chains;
s8 chain_signal[IEEE80211_MAX_CHAINS];
s8 chain_signal_avg[IEEE80211_MAX_CHAINS];
struct rate_info txrate; struct rate_info txrate;
struct rate_info rxrate; struct rate_info rxrate;
u32 rx_packets; u32 rx_packets;

View File

@ -1991,6 +1991,10 @@ enum nl80211_sta_bss_param {
* @NL80211_STA_INFO_PEER_PM: peer mesh STA link-specific power mode * @NL80211_STA_INFO_PEER_PM: peer mesh STA link-specific power mode
* @NL80211_STA_INFO_NONPEER_PM: neighbor mesh STA power save mode towards * @NL80211_STA_INFO_NONPEER_PM: neighbor mesh STA power save mode towards
* non-peer STA * non-peer STA
* @NL80211_STA_INFO_CHAIN_SIGNAL: per-chain signal strength of last PPDU
* Contains a nested array of signal strength attributes (u8, dBm)
* @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average
* Same format as NL80211_STA_INFO_CHAIN_SIGNAL.
* @__NL80211_STA_INFO_AFTER_LAST: internal * @__NL80211_STA_INFO_AFTER_LAST: internal
* @NL80211_STA_INFO_MAX: highest possible station info attribute * @NL80211_STA_INFO_MAX: highest possible station info attribute
*/ */
@ -2020,6 +2024,8 @@ enum nl80211_sta_info {
NL80211_STA_INFO_NONPEER_PM, NL80211_STA_INFO_NONPEER_PM,
NL80211_STA_INFO_RX_BYTES64, NL80211_STA_INFO_RX_BYTES64,
NL80211_STA_INFO_TX_BYTES64, NL80211_STA_INFO_TX_BYTES64,
NL80211_STA_INFO_CHAIN_SIGNAL,
NL80211_STA_INFO_CHAIN_SIGNAL_AVG,
/* keep last */ /* keep last */
__NL80211_STA_INFO_AFTER_LAST, __NL80211_STA_INFO_AFTER_LAST,

View File

@ -3376,6 +3376,32 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
return true; return true;
} }
static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
int id)
{
void *attr;
int i = 0;
if (!mask)
return true;
attr = nla_nest_start(msg, id);
if (!attr)
return false;
for (i = 0; i < IEEE80211_MAX_CHAINS; i++) {
if (!(mask & BIT(i)))
continue;
if (nla_put_u8(msg, i, signal[i]))
return false;
}
nla_nest_end(msg, attr);
return true;
}
static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
int flags, int flags,
struct cfg80211_registered_device *rdev, struct cfg80211_registered_device *rdev,
@ -3447,6 +3473,18 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
default: default:
break; break;
} }
if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL) {
if (!nl80211_put_signal(msg, sinfo->chains,
sinfo->chain_signal,
NL80211_STA_INFO_CHAIN_SIGNAL))
goto nla_put_failure;
}
if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL_AVG) {
if (!nl80211_put_signal(msg, sinfo->chains,
sinfo->chain_signal_avg,
NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
goto nla_put_failure;
}
if (sinfo->filled & STATION_INFO_TX_BITRATE) { if (sinfo->filled & STATION_INFO_TX_BITRATE) {
if (!nl80211_put_sta_rate(msg, &sinfo->txrate, if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
NL80211_STA_INFO_TX_BITRATE)) NL80211_STA_INFO_TX_BITRATE))