[RFC 2/7] cfg80211: introduce nl80211_set_offchan_chain callback
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: 2021-09-28 15:14:53
Subsystem:
802.11 (including cfg80211/nl80211), the rest · Maintainers:
Johannes Berg, Linus Torvalds
Introduce NL80211_CMD_OFFCHAN_CHAIN command in order to configure offchannel chain if supported by the underlay driver. Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> --- include/uapi/linux/nl80211.h | 6 ++++++ net/wireless/nl80211.c | 41 ++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+)
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index c2efea98e060..51ddd6f198d4 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h@@ -1200,6 +1200,10 @@ * @NL80211_CMD_COLOR_CHANGE_COMPLETED: Notify userland that the color change * has completed * + * @NL80211_CMD_OFFCHAN_CHAIN: Configure dedicated chain available for radar + * detection on some hw. The driver is supposed to implement CAC + * management in sw or fw. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */
@@ -1440,6 +1444,8 @@ enum nl80211_commands { NL80211_CMD_COLOR_CHANGE_ABORTED, NL80211_CMD_COLOR_CHANGE_COMPLETED, + NL80211_CMD_OFFCHAN_CHAIN, + /* 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 bf7cd4752547..7c0902d35635 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c@@ -9064,6 +9064,39 @@ static int nl80211_stop_sched_scan(struct sk_buff *skb, return cfg80211_stop_sched_scan_req(rdev, req, false); } +static int nl80211_set_offchan_chain(struct sk_buff *skb, + struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + enum nl80211_dfs_regions dfs_region; + struct wiphy *wiphy = &rdev->wiphy; + struct cfg80211_chan_def chandef; + 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, NL80211_IFTYPE_AP); + if (err < 0) + return err; + + if (!err) + return -EINVAL; + + if (!cfg80211_chandef_dfs_usable(wiphy, &chandef)) + return -EINVAL; + + if (!rdev->ops->set_offchan_chain) + return -EOPNOTSUPP; + + return rdev_set_offchan_chain(rdev, &chandef); +} + static int nl80211_start_radar_detection(struct sk_buff *skb, struct genl_info *info) {
@@ -15907,6 +15940,14 @@ static const struct genl_small_ops nl80211_small_ops[] = { .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, + { + .cmd = NL80211_CMD_OFFCHAN_CHAIN, + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, + .doit = nl80211_set_offchan_chain, + .flags = GENL_UNS_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_WIPHY | + NL80211_FLAG_NEED_RTNL, + }, }; static struct genl_family nl80211_fam __ro_after_init = {
--
2.31.1