summaryrefslogtreecommitdiff
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorLorenzo Bianconi <lorenzo@kernel.org>2021-11-16 17:03:36 +0300
committerJohannes Berg <johannes.berg@intel.com>2021-11-26 13:50:27 +0300
commit8415816493b7589e74ff4e1e7eaf3aadc7b73621 (patch)
tree1e942d46d143e0e5685a1fdf770a0af3d5f94002 /net/wireless/nl80211.c
parentc47240cb46a10c40686ce4e25c64aaed676f71c9 (diff)
downloadlinux-8415816493b7589e74ff4e1e7eaf3aadc7b73621.tar.xz
cfg80211: allow continuous radar monitoring on offchannel chain
Allow continuous radar detection on the offchannel chain in order to switch to the monitored channel whenever the underlying driver reports a radar pattern on the main channel. Tested-by: Owen Peng <owen.peng@mediatek.com> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Link: https://lore.kernel.org/r/d46217310a49b14ff0e9c002f0a6e0547d70fd2c.1637071350.git.lorenzo@kernel.org Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c62
1 files changed, 42 insertions, 20 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 83a1ba96e172..65693c96b407 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -9275,42 +9275,60 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
struct cfg80211_chan_def chandef;
enum nl80211_dfs_regions dfs_region;
unsigned int cac_time_ms;
- int err;
+ int err = -EINVAL;
+
+ flush_delayed_work(&rdev->dfs_update_channels_wk);
+
+ wiphy_lock(wiphy);
dfs_region = reg_get_dfs_region(wiphy);
if (dfs_region == NL80211_DFS_UNSET)
- return -EINVAL;
+ goto unlock;
err = nl80211_parse_chandef(rdev, info, &chandef);
if (err)
- return err;
+ goto unlock;
err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
if (err < 0)
- return err;
+ goto unlock;
- if (err == 0)
- return -EINVAL;
+ if (err == 0) {
+ err = -EINVAL;
+ goto unlock;
+ }
- if (!cfg80211_chandef_dfs_usable(wiphy, &chandef))
- return -EINVAL;
+ if (!cfg80211_chandef_dfs_usable(wiphy, &chandef)) {
+ err = -EINVAL;
+ goto unlock;
+ }
- if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN]))
- return cfg80211_start_offchan_radar_detection(rdev, wdev,
- &chandef);
+ if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN])) {
+ err = cfg80211_start_offchan_radar_detection(rdev, wdev,
+ &chandef);
+ goto unlock;
+ }
- if (netif_carrier_ok(dev))
- return -EBUSY;
+ if (netif_carrier_ok(dev)) {
+ err = -EBUSY;
+ goto unlock;
+ }
- if (wdev->cac_started)
- return -EBUSY;
+ if (wdev->cac_started) {
+ err = -EBUSY;
+ goto unlock;
+ }
/* CAC start is offloaded to HW and can't be started manually */
- if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD))
- return -EOPNOTSUPP;
+ if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD)) {
+ err = -EOPNOTSUPP;
+ goto unlock;
+ }
- if (!rdev->ops->start_radar_detection)
- return -EOPNOTSUPP;
+ if (!rdev->ops->start_radar_detection) {
+ err = -EOPNOTSUPP;
+ goto unlock;
+ }
cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef);
if (WARN_ON(!cac_time_ms))
@@ -9323,6 +9341,9 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
wdev->cac_start_time = jiffies;
wdev->cac_time_ms = cac_time_ms;
}
+unlock:
+ wiphy_unlock(wiphy);
+
return err;
}
@@ -15959,7 +15980,8 @@ static const struct genl_small_ops nl80211_small_ops[] = {
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = nl80211_start_radar_detection,
.flags = GENL_UNS_ADMIN_PERM,
- .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NO_WIPHY_MTX,
},
{
.cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,