nl80211/cfg80211: Specify band specific min RSSI thresholds with sched scan

This commit adds the support to specify the RSSI thresholds per
band for each match set. This enhances the current behavior which
specifies a single rssi_threshold across all the bands by
introducing the rssi_threshold_per_band. These per band rssi
thresholds are referred through NL80211_BAND_* (enum nl80211_band)
variables  as attribute types. Such attributes/values per each
band are nested through NL80211_ATTR_SCHED_SCAN_MIN_RSSI.
These band specific rssi thresholds shall take precedence over
the current rssi_thold per match set.
Drivers indicate this support through
%NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD.
These per band rssi attributes/values does not specify
"default RSSI filter" as done by
NL80211_SCHED_SCAN_MATCH_ATTR_RSSI to stay backward compatible.
That said, these per band rssi values have to be specified for
the corresponding matchset.

Signed-off-by: vamsi krishna <vamsin@codeaurora.org>
Signed-off-by: Srinivas Dasari <dasaris@codeaurora.org>
[rebase on refactoring, add policy]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
vamsi krishna
2019-02-01 18:34:51 +05:30
committed by Johannes Berg
parent d39f3b4f33
commit 1e1b11b6a1
3 changed files with 74 additions and 0 deletions

View File

@@ -617,12 +617,21 @@ nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
[NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN },
};
static const struct nla_policy
nl80211_match_band_rssi_policy[NUM_NL80211_BANDS] = {
[NL80211_BAND_2GHZ] = { .type = NLA_S32 },
[NL80211_BAND_5GHZ] = { .type = NLA_S32 },
[NL80211_BAND_60GHZ] = { .type = NLA_S32 },
};
static const struct nla_policy
nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
.len = IEEE80211_MAX_SSID_LEN },
[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID] = { .len = ETH_ALEN },
[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
[NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI] =
NLA_POLICY_NESTED(nl80211_match_band_rssi_policy),
};
static const struct nla_policy
@@ -7537,6 +7546,41 @@ nl80211_parse_sched_scan_plans(struct wiphy *wiphy, int n_plans,
return 0;
}
static int
nl80211_parse_sched_scan_per_band_rssi(struct wiphy *wiphy,
struct cfg80211_match_set *match_sets,
struct nlattr *tb_band_rssi,
s32 rssi_thold)
{
struct nlattr *attr;
int i, tmp, ret = 0;
if (!wiphy_ext_feature_isset(wiphy,
NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD)) {
if (tb_band_rssi)
ret = -EOPNOTSUPP;
else
for (i = 0; i < NUM_NL80211_BANDS; i++)
match_sets->per_band_rssi_thold[i] =
NL80211_SCAN_RSSI_THOLD_OFF;
return ret;
}
for (i = 0; i < NUM_NL80211_BANDS; i++)
match_sets->per_band_rssi_thold[i] = rssi_thold;
nla_for_each_nested(attr, tb_band_rssi, tmp) {
enum nl80211_band band = nla_type(attr);
if (band < 0 || band >= NUM_NL80211_BANDS)
return -EINVAL;
match_sets->per_band_rssi_thold[band] = nla_get_s32(attr);
}
return 0;
}
static struct cfg80211_sched_scan_request *
nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
struct nlattr **attrs, int max_match_sets)
@@ -7816,6 +7860,15 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
if (rssi)
request->match_sets[i].rssi_thold =
nla_get_s32(rssi);
/* Parse per band RSSI attribute */
err = nl80211_parse_sched_scan_per_band_rssi(wiphy,
&request->match_sets[i],
tb[NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI],
request->match_sets[i].rssi_thold);
if (err)
goto out_free;
i++;
}