cfg80211: Scan results to also report the per chain signal strength
authorSunil Dutt <usdutt@qti.qualcomm.com>
Wed, 13 Dec 2017 17:51:36 +0000 (19:51 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 19 Dec 2017 09:37:31 +0000 (10:37 +0100)
This commit enhances the scan results to report the per chain signal
strength based on the latest BSS update. This provides similar
information to what is already available through STA information.

Signed-off-by: Sunil Dutt <usdutt@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/wireless/nl80211.c
net/wireless/scan.c

index d7f8e7b96bcbf31815a855494914b1360a71f980..3a4a1a903a4d0670b38174f9663dd52d122e22da 100644 (file)
@@ -1773,6 +1773,8 @@ enum cfg80211_signal_type {
  *     by %parent_bssid.
  * @parent_bssid: the BSS according to which %parent_tsf is set. This is set to
  *     the BSS that requested the scan in which the beacon/probe was received.
+ * @chains: bitmask for filled values in @chain_signal.
+ * @chain_signal: per-chain signal strength of last received BSS in dBm.
  */
 struct cfg80211_inform_bss {
        struct ieee80211_channel *chan;
@@ -1781,6 +1783,8 @@ struct cfg80211_inform_bss {
        u64 boottime_ns;
        u64 parent_tsf;
        u8 parent_bssid[ETH_ALEN] __aligned(2);
+       u8 chains;
+       s8 chain_signal[IEEE80211_MAX_CHAINS];
 };
 
 /**
@@ -1824,6 +1828,8 @@ struct cfg80211_bss_ies {
  *     that holds the beacon data. @beacon_ies is still valid, of course, and
  *     points to the same data as hidden_beacon_bss->beacon_ies in that case.
  * @signal: signal strength value (type depends on the wiphy's signal_type)
+ * @chains: bitmask for filled values in @chain_signal.
+ * @chain_signal: per-chain signal strength of last received BSS in dBm.
  * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes
  */
 struct cfg80211_bss {
@@ -1842,6 +1848,8 @@ struct cfg80211_bss {
        u16 capability;
 
        u8 bssid[ETH_ALEN];
+       u8 chains;
+       s8 chain_signal[IEEE80211_MAX_CHAINS];
 
        u8 priv[0] __aligned(sizeof(void *));
 };
index f882fe1f9709d889036ad2131ce1cde98e9fd60e..c587a61c32bfbc04c838db73df2cea737496803e 100644 (file)
@@ -3862,6 +3862,9 @@ enum nl80211_bss_scan_width {
  *     @NL80211_BSS_PARENT_BSSID. (u64).
  * @NL80211_BSS_PARENT_BSSID: the BSS according to which @NL80211_BSS_PARENT_TSF
  *     is set.
+ * @NL80211_BSS_CHAIN_SIGNAL: per-chain signal strength of last BSS update.
+ *     Contains a nested array of signal strength attributes (u8, dBm),
+ *     using the nesting index as the antenna number.
  * @__NL80211_BSS_AFTER_LAST: internal
  * @NL80211_BSS_MAX: highest BSS attribute
  */
@@ -3885,6 +3888,7 @@ enum nl80211_bss {
        NL80211_BSS_PAD,
        NL80211_BSS_PARENT_TSF,
        NL80211_BSS_PARENT_BSSID,
+       NL80211_BSS_CHAIN_SIGNAL,
 
        /* keep last */
        __NL80211_BSS_AFTER_LAST,
index e4dddfb64ced9a2195d6f8bf9668540dc3f2ad72..b3f8970c3a4773da2b323bb843ee6eb782d96869 100644 (file)
@@ -7839,6 +7839,11 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
                              intbss->ts_boottime, NL80211_BSS_PAD))
                goto nla_put_failure;
 
+       if (!nl80211_put_signal(msg, intbss->pub.chains,
+                               intbss->pub.chain_signal,
+                               NL80211_BSS_CHAIN_SIGNAL))
+               goto nla_put_failure;
+
        switch (rdev->wiphy.signal_type) {
        case CFG80211_SIGNAL_TYPE_MBM:
                if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal))
index f6c5fe4825065ddb0bc99f882d36aa390129d540..d36c3eb7b9311fc75bdaa020aa0318546efd4128 100644 (file)
@@ -981,6 +981,9 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,
                found->ts = tmp->ts;
                found->ts_boottime = tmp->ts_boottime;
                found->parent_tsf = tmp->parent_tsf;
+               found->pub.chains = tmp->pub.chains;
+               memcpy(found->pub.chain_signal, tmp->pub.chain_signal,
+                      IEEE80211_MAX_CHAINS);
                ether_addr_copy(found->parent_bssid, tmp->parent_bssid);
        } else {
                struct cfg80211_internal_bss *new;
@@ -1233,6 +1236,8 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
        tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
        tmp.ts_boottime = data->boottime_ns;
        tmp.parent_tsf = data->parent_tsf;
+       tmp.pub.chains = data->chains;
+       memcpy(tmp.pub.chain_signal, data->chain_signal, IEEE80211_MAX_CHAINS);
        ether_addr_copy(tmp.parent_bssid, data->parent_bssid);
 
        signal_valid = abs(data->chan->center_freq - channel->center_freq) <=