Search Linux Wireless

[RFC 1/2] nl80211: specify RSSI threshold when scanning

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Support configuring an RSSI threshold in dBm (s32) when scanning,
below which a BSS won't be reported by the cfg80211 driver.

Signed-off-by: Thomas Pedersen <c_tpeder@xxxxxxxxxxxxxxxx>
---
 include/linux/nl80211.h |    6 ++++++
 include/net/cfg80211.h  |    7 +++++++
 net/wireless/nl80211.c  |   17 +++++++++++++++++
 3 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index a6959f7..dc051a8 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1222,6 +1222,10 @@ enum nl80211_commands {
  * @NL80211_ATTR_BG_SCAN_PERIOD: Background scan period in seconds
  *      or 0 to disable background scan.
  *
+ * @NL80211_ATTR_SCAN_RSSI: rssi threshold (in s32 dBm) below which a BSS is
+ *	not reported in scan results. Will be disabled if 0 or not specified.
+ *	Supported in %NL80211_CMD_START_SCHED_SCAN and %NL80211_TRIGGER_SCAN.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1473,6 +1477,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_BG_SCAN_PERIOD,
 
+	NL80211_ATTR_SCAN_RSSI,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0289d4c..39d293b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -920,6 +920,7 @@ struct cfg80211_ssid {
  * @dev: the interface
  * @aborted: (internal) scan request was notified as aborted
  * @no_cck: used to send probe requests at non CCK rate in 2GHz band
+ * @rssi: don't report scan results below this threshold
  */
 struct cfg80211_scan_request {
 	struct cfg80211_ssid *ssids;
@@ -935,6 +936,7 @@ struct cfg80211_scan_request {
 	struct net_device *dev;
 	bool aborted;
 	bool no_cck;
+	s32 rssi;
 
 	/* keep last */
 	struct ieee80211_channel *channels[0];
@@ -966,6 +968,7 @@ struct cfg80211_match_set {
  * @wiphy: the wiphy this was for
  * @dev: the interface
  * @channels: channels to scan
+ * @rssi: don't report scan results below this threshold
  */
 struct cfg80211_sched_scan_request {
 	struct cfg80211_ssid *ssids;
@@ -976,6 +979,7 @@ struct cfg80211_sched_scan_request {
 	size_t ie_len;
 	struct cfg80211_match_set *match_sets;
 	int n_match_sets;
+	s32 rssi;
 
 	/* internal */
 	struct wiphy *wiphy;
@@ -1794,6 +1798,8 @@ struct cfg80211_ops {
  *	responds to probe-requests in hardware.
  * @WIPHY_FLAG_OFFCHAN_TX: Device supports direct off-channel TX.
  * @WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL: Device supports remain-on-channel call.
+ * @WIPHY_FLAG_SUPPORTS_RSSI_SCAN: Device supports filtering scan results by
+ *	 RSSI (in dBm).
  */
 enum wiphy_flags {
 	WIPHY_FLAG_CUSTOM_REGULATORY		= BIT(0),
@@ -1817,6 +1823,7 @@ enum wiphy_flags {
 	WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD	= BIT(19),
 	WIPHY_FLAG_OFFCHAN_TX			= BIT(20),
 	WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL	= BIT(21),
+	WIPHY_FLAG_SUPPORTS_RSSI_SCAN		= BIT(22),
 };
 
 /**
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 206465d..6886ca1 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -206,6 +206,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
 	[NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
 	[NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
 	[NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
+	[NL80211_ATTR_SCAN_RSSI] = { .type = NLA_U32 },
 };
 
 /* policy for the key attributes */
@@ -3846,6 +3847,10 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 	if (!rdev->ops->scan)
 		return -EOPNOTSUPP;
 
+	if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_RSSI_SCAN) &&
+	    info->attrs[NL80211_ATTR_SCAN_RSSI])
+		return -EOPNOTSUPP;
+
 	if (rdev->scan_req)
 		return -EBUSY;
 
@@ -3991,6 +3996,10 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 	request->no_cck =
 		nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
 
+	if (info->attrs[NL80211_ATTR_SCAN_RSSI])
+		request->rssi =
+			nla_get_u32(info->attrs[NL80211_ATTR_SCAN_RSSI]);
+
 	request->dev = dev;
 	request->wiphy = &rdev->wiphy;
 
@@ -4027,6 +4036,10 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
 	    !rdev->ops->sched_scan_start)
 		return -EOPNOTSUPP;
 
+	if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_RSSI_SCAN) &&
+	    info->attrs[NL80211_ATTR_SCAN_RSSI])
+		return -EOPNOTSUPP;
+
 	if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
 		return -EINVAL;
 
@@ -4212,6 +4225,10 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
 		       request->ie_len);
 	}
 
+	if (info->attrs[NL80211_ATTR_SCAN_RSSI])
+		request->rssi =
+			nla_get_u32(info->attrs[NL80211_ATTR_SCAN_RSSI]);
+
 	request->dev = dev;
 	request->wiphy = &rdev->wiphy;
 	request->interval = interval;
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux