diff mbox series

nl80211: Add support to notify radar event info received from STA

Message ID 1539940356-1335-1-git-send-email-srirrama@codeaurora.org (mailing list archive)
State Superseded
Delegated to: Johannes Berg
Headers show
Series nl80211: Add support to notify radar event info received from STA | expand

Commit Message

Sriram R Oct. 19, 2018, 9:12 a.m. UTC
Currently radar detection and corresponding channel switch is handled
at the AP device. STA ignores these detected radar events since the
radar signal can be seen mostly by the AP as well. But in scenarios where
a radar signal is seen only at STA, notifying this event to the AP which
can trigger a channel switch can be useful.
Stations can report such radar events autonomously through Spectrum
management (Measurement Report) action frame to its AP. The userspace on
processing the report can notify the kernel with the use of the added
NL80211_CMD_NOTIFY_RADAR to indicate the detected event and inturn adding
the reported channel to NOL.

Signed-off-by: Sriram R <srirrama@codeaurora.org>
---
 include/uapi/linux/nl80211.h |  7 ++++++
 net/wireless/nl80211.c       | 52 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)

Comments

Johannes Berg Nov. 9, 2018, 12:04 p.m. UTC | #1
On Fri, 2018-10-19 at 14:42 +0530, Sriram R wrote:
[...]

This looks fine, but I think it would be nice to have some extended
netlink error reporting for at least some of these errors:

> +	dfs_region = reg_get_dfs_region(wiphy);
> +	if (dfs_region == NL80211_DFS_UNSET)
> +		return -EINVAL;
> +
> +	err = nl80211_parse_chandef(rdev, info, &chandef);
> +	if (err)
> +		return err;
> +
> +	err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
> +	if (err < 0)
> +		return err;
> +
> +	if (err == 0)
> +		return -EINVAL;
> +
> +	/* Do not process this notification if radar is already detected
> +	 * by kernel on this channel
> +	 */
> +	if (chandef.chan->dfs_state == NL80211_DFS_UNAVAILABLE)
> +		return -EINVAL;

And maybe that last one should just return 0?

johannes
Sriram R Nov. 12, 2018, 10:59 a.m. UTC | #2
On 2018-11-09 17:34, Johannes Berg wrote:
> On Fri, 2018-10-19 at 14:42 +0530, Sriram R wrote:
> [...]
> 
> This looks fine, but I think it would be nice to have some extended
> netlink error reporting for at least some of these errors:
> 
Sure Johannes, I'll add them in the next patch revision.
>> +	dfs_region = reg_get_dfs_region(wiphy);
>> +	if (dfs_region == NL80211_DFS_UNSET)
>> +		return -EINVAL;
>> +
>> +	err = nl80211_parse_chandef(rdev, info, &chandef);
>> +	if (err)
>> +		return err;
>> +
>> +	err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
>> +	if (err < 0)
>> +		return err;
>> +
>> +	if (err == 0)
>> +		return -EINVAL;
>> +
>> +	/* Do not process this notification if radar is already detected
>> +	 * by kernel on this channel
>> +	 */
>> +	if (chandef.chan->dfs_state == NL80211_DFS_UNAVAILABLE)
>> +		return -EINVAL;
> 
> And maybe that last one should just return 0?
You're right. I'll return success here.
Thanks,
Sriram.R

> 
> johannes
diff mbox series

Patch

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index dc6d5a1..192b358 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1036,6 +1036,11 @@ 
  * @NL80211_CMD_GET_FTM_RESPONDER_STATS: Retrieve FTM responder statistics, in
  *	the %NL80211_ATTR_FTM_RESPONDER_STATS attribute.
  *
+ * @NL80211_CMD_NOTIFY_RADAR: Notify the kernel that a radar signal was
+ *	detected and reported by a neighboring device on the channel
+ *	indicated by %NL80211_ATTR_WIPHY_FREQ and other attributes
+ *	determining the width and type.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1250,6 +1255,8 @@  enum nl80211_commands {
 
 	NL80211_CMD_GET_FTM_RESPONDER_STATS,
 
+	NL80211_CMD_NOTIFY_RADAR,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 9a20c66a..cb462a9 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7920,6 +7920,50 @@  static int nl80211_start_radar_detection(struct sk_buff *skb,
 	return err;
 }
 
+static int nl80211_notify_radar_detection(struct sk_buff *skb,
+					  struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+	struct net_device *dev = info->user_ptr[1];
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
+	struct cfg80211_chan_def chandef;
+	enum nl80211_dfs_regions dfs_region;
+	int err;
+
+	dfs_region = reg_get_dfs_region(wiphy);
+	if (dfs_region == NL80211_DFS_UNSET)
+		return -EINVAL;
+
+	err = nl80211_parse_chandef(rdev, info, &chandef);
+	if (err)
+		return err;
+
+	err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
+	if (err < 0)
+		return err;
+
+	if (err == 0)
+		return -EINVAL;
+
+	/* Do not process this notification if radar is already detected
+	 * by kernel on this channel
+	 */
+	if (chandef.chan->dfs_state == NL80211_DFS_UNAVAILABLE)
+		return -EINVAL;
+
+	cfg80211_set_dfs_state(wiphy, &chandef, NL80211_DFS_UNAVAILABLE);
+
+	cfg80211_sched_dfs_chan_update(rdev);
+
+	memcpy(&rdev->radar_chandef, &chandef, sizeof(chandef));
+
+	/* Propagate this notification to other radios as well */
+	queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
+
+	return 0;
+}
+
 static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
 {
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -14035,6 +14079,14 @@  static const struct genl_ops nl80211_ops[] = {
 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
 				  NL80211_FLAG_NEED_RTNL,
 	},
+	{
+		.cmd = NL80211_CMD_NOTIFY_RADAR,
+		.doit = nl80211_notify_radar_detection,
+		.policy = nl80211_policy,
+		.flags = GENL_UNS_ADMIN_PERM,
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+				  NL80211_FLAG_NEED_RTNL,
+	},
 };
 
 static struct genl_family nl80211_fam __ro_after_init = {