* [PATCH v2 mac80211-next 1/6] cfg80211: introduce set_radar_offchan callback
2021-10-23 9:10 [PATCH v2 mac80211-next 0/6] add offchannel radar chain support Lorenzo Bianconi
@ 2021-10-23 9:10 ` Lorenzo Bianconi
2021-10-23 9:10 ` [PATCH v2 mac80211-next 2/6] mac80211: " Lorenzo Bianconi
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Lorenzo Bianconi @ 2021-10-23 9:10 UTC (permalink / raw)
To: johannes; +Cc: nbd, linux-wireless, lorenzo.bianconi, ryder.lee, evelyn.tsai
Introduce set_radar_offchan callback in cfg80211_ops in order to
configure a dedicated offchannel chain available for radar/CAC
detection on some hw. This chain can't be used to transmit
or receive frames and it is bounded to a running wdev.
Offchannel radar/CAC detection allows to avoid the CAC downtime
switching on a different channel during CAC detection on the selected
radar channel.
Tested-by: Evelyn Tsai <evelyn.tsai@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
include/net/cfg80211.h | 11 +++++++++++
net/wireless/rdev-ops.h | 18 ++++++++++++++++++
net/wireless/trace.h | 19 +++++++++++++++++++
3 files changed, 48 insertions(+)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 7c9d5db4f0e6..3bb76835f4b1 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -4072,6 +4072,15 @@ struct mgmt_frame_regs {
* @set_fils_aad: Set FILS AAD data to the AP driver so that the driver can use
* those to decrypt (Re)Association Request and encrypt (Re)Association
* Response frame.
+ *
+ * @set_radar_offchan: Configure dedicated offchannel chain available for
+ * radar/CAC detection on some hw. This chain can't be used to transmit
+ * or receive frames and it is bounded to a running wdev.
+ * Offchannel radar/CAC detection allows to avoid the CAC downtime
+ * switching to a different channel during CAC detection on the selected
+ * radar channel.
+ * The caller is expected to set chandef pointer to NULL in order to
+ * disable offchannel CAC/radar detection.
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -4404,6 +4413,8 @@ struct cfg80211_ops {
struct cfg80211_color_change_settings *params);
int (*set_fils_aad)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_fils_aad *fils_aad);
+ int (*set_radar_offchan)(struct wiphy *wiphy,
+ struct cfg80211_chan_def *chandef);
};
/*
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index cc1efec4b27b..980f1403e000 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -1395,4 +1395,22 @@ rdev_set_fils_aad(struct cfg80211_registered_device *rdev,
return ret;
}
+static inline int
+rdev_set_radar_offchan(struct cfg80211_registered_device *rdev,
+ struct cfg80211_chan_def *chandef)
+{
+ struct wiphy *wiphy = &rdev->wiphy;
+ int ret;
+
+ if (!rdev->ops->set_radar_offchan)
+ return -EOPNOTSUPP;
+
+ if (chandef)
+ trace_rdev_set_radar_offchan(wiphy, chandef);
+ ret = rdev->ops->set_radar_offchan(wiphy, chandef);
+ trace_rdev_return_int(wiphy, ret);
+
+ return ret;
+}
+
#endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index ad6c16a06bcb..0b27eaa14a18 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -3674,6 +3674,25 @@ TRACE_EVENT(cfg80211_bss_color_notify,
__entry->color_bitmap)
);
+TRACE_EVENT(rdev_set_radar_offchan,
+ TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef),
+
+ TP_ARGS(wiphy, chandef),
+
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ CHAN_DEF_ENTRY
+ ),
+
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ CHAN_DEF_ASSIGN(chandef)
+ ),
+
+ TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
+ WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
+);
+
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH
--
2.31.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 mac80211-next 2/6] mac80211: introduce set_radar_offchan callback
2021-10-23 9:10 [PATCH v2 mac80211-next 0/6] add offchannel radar chain support Lorenzo Bianconi
2021-10-23 9:10 ` [PATCH v2 mac80211-next 1/6] cfg80211: introduce set_radar_offchan callback Lorenzo Bianconi
@ 2021-10-23 9:10 ` Lorenzo Bianconi
2021-10-23 9:10 ` [PATCH v2 mac80211-next 3/6] cfg80211: introduce the capability to configure offchannel CAC detection Lorenzo Bianconi
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Lorenzo Bianconi @ 2021-10-23 9:10 UTC (permalink / raw)
To: johannes; +Cc: nbd, linux-wireless, lorenzo.bianconi, ryder.lee, evelyn.tsai
Similar to cfg80211, introduce set_radar_offchan callback in mac80211_ops
in order to configure a dedicated offchannel chain available on some hw
(e.g. mt7915) to perform offchannel CAC detection and avoid tx/rx downtime.
Tested-by: Evelyn Tsai <evelyn.tsai@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
include/net/mac80211.h | 10 ++++++++++
net/mac80211/cfg.c | 13 +++++++++++++
2 files changed, 23 insertions(+)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index dd757f0987b0..775dbb982654 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3944,6 +3944,14 @@ struct ieee80211_prep_tx_info {
* twt structure.
* @twt_teardown_request: Update the hw with TWT teardown request received
* from the peer.
+ * @set_radar_offchan: Configure dedicated offchannel chain available for
+ * radar/CAC detection on some hw. This chain can't be used to transmit
+ * or receive frames and it is bounded to a running wdev.
+ * Offchannel radar/CAC detection allows to avoid the CAC downtime
+ * switching to a different channel during CAC detection on the selected
+ * radar channel.
+ * The caller is expected to set chandef pointer to NULL in order to
+ * disable offchannel CAC/radar detection.
*/
struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw,
@@ -4272,6 +4280,8 @@ struct ieee80211_ops {
struct ieee80211_twt_setup *twt);
void (*twt_teardown_request)(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, u8 flowid);
+ int (*set_radar_offchan)(struct ieee80211_hw *hw,
+ struct cfg80211_chan_def *chandef);
};
/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index e2b791c37591..1ab84830a38f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -4379,6 +4379,18 @@ ieee80211_color_change(struct wiphy *wiphy, struct net_device *dev,
return err;
}
+static int
+ieee80211_set_radar_offchan(struct wiphy *wiphy,
+ struct cfg80211_chan_def *chandef)
+{
+ struct ieee80211_local *local = wiphy_priv(wiphy);
+
+ if (!local->ops->set_radar_offchan)
+ return -EOPNOTSUPP;
+
+ return local->ops->set_radar_offchan(&local->hw, chandef);
+}
+
const struct cfg80211_ops mac80211_config_ops = {
.add_virtual_intf = ieee80211_add_iface,
.del_virtual_intf = ieee80211_del_iface,
@@ -4483,4 +4495,5 @@ const struct cfg80211_ops mac80211_config_ops = {
.reset_tid_config = ieee80211_reset_tid_config,
.set_sar_specs = ieee80211_set_sar_specs,
.color_change = ieee80211_color_change,
+ .set_radar_offchan = ieee80211_set_radar_offchan,
};
--
2.31.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 mac80211-next 3/6] cfg80211: introduce the capability to configure offchannel CAC detection
2021-10-23 9:10 [PATCH v2 mac80211-next 0/6] add offchannel radar chain support Lorenzo Bianconi
2021-10-23 9:10 ` [PATCH v2 mac80211-next 1/6] cfg80211: introduce set_radar_offchan callback Lorenzo Bianconi
2021-10-23 9:10 ` [PATCH v2 mac80211-next 2/6] mac80211: " Lorenzo Bianconi
@ 2021-10-23 9:10 ` Lorenzo Bianconi
2021-10-23 9:10 ` [PATCH v2 mac80211-next 4/6] cfg80211: introduce cfg80211_cac_offchan_event routine Lorenzo Bianconi
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Lorenzo Bianconi @ 2021-10-23 9:10 UTC (permalink / raw)
To: johannes; +Cc: nbd, linux-wireless, lorenzo.bianconi, ryder.lee, evelyn.tsai
Introduce NL80211_ATTR_RADAR_OFFCHAN netlink attribute in order to
configure a offchannel radar chain if supported by the underlay driver.
Since the offchannel chain is commonly shared between multiple wireless
devices, offchan_radar_wdev pointer refers to the current owner of the
chain. Offchannel can't be used by multiple wdev at the same time.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
include/uapi/linux/nl80211.h | 9 ++++++++
net/wireless/ap.c | 2 ++
net/wireless/core.c | 1 +
net/wireless/core.h | 11 ++++++++++
net/wireless/mlme.c | 40 ++++++++++++++++++++++++++++++++++++
net/wireless/nl80211.c | 17 +++++++++------
6 files changed, 74 insertions(+), 6 deletions(-)
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 61cab81e920d..87ece3e68b8b 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2639,6 +2639,13 @@ enum nl80211_commands {
* Mandatory parameter for the transmitting interface to enable MBSSID.
* Optional for the non-transmitting interfaces.
*
+ * @NL80211_ATTR_RADAR_OFFCHAN: Configure dedicated offchannel chain available for
+ * radar/CAC detection on some hw. This chain can't be used to transmit
+ * or receive frames and it is bounded to a running wdev.
+ * Offchannel radar/CAC detection allows to avoid the CAC downtime
+ * switching on a different channel during CAC detection on the selected
+ * radar channel.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3145,6 +3152,8 @@ enum nl80211_attrs {
NL80211_ATTR_MBSSID_CONFIG,
NL80211_ATTR_MBSSID_ELEMS,
+ NL80211_ATTR_RADAR_OFFCHAN,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/ap.c b/net/wireless/ap.c
index 550ac9d827fe..608fe3447158 100644
--- a/net/wireless/ap.c
+++ b/net/wireless/ap.c
@@ -25,6 +25,8 @@ int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
if (!wdev->beacon_interval)
return -ENOENT;
+ cfg80211_stop_offchan_radar_detection(rdev);
+
err = rdev_stop_ap(rdev, dev);
if (!err) {
wdev->conn_owner_nlportid = 0;
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 45be124a98f1..385c3654b385 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -498,6 +498,7 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
}
mutex_init(&rdev->wiphy.mtx);
+ mutex_init(&rdev->offchan_mutex);
INIT_LIST_HEAD(&rdev->wiphy.wdev_list);
INIT_LIST_HEAD(&rdev->beacon_registrations);
spin_lock_init(&rdev->beacon_registrations_lock);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index b35d0db12f1d..6e4d18fb93b1 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -84,6 +84,9 @@ struct cfg80211_registered_device {
struct delayed_work dfs_update_channels_wk;
+ struct mutex offchan_mutex; /* protect offchan_radar_wdev */
+ struct wireless_dev *offchan_radar_wdev;
+
/* netlink port which started critical protocol (0 means not started) */
u32 crit_proto_nlportid;
@@ -489,6 +492,14 @@ cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev);
+int
+cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev,
+ struct cfg80211_chan_def *chandef);
+
+int
+cfg80211_stop_offchan_radar_detection(struct cfg80211_registered_device *rdev);
+
bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
struct ieee80211_channel *chan);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 3aa69b375a10..053293f51188 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -968,3 +968,43 @@ void cfg80211_cac_event(struct net_device *netdev,
nl80211_radar_notify(rdev, chandef, event, netdev, gfp);
}
EXPORT_SYMBOL(cfg80211_cac_event);
+
+int
+cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev,
+ struct cfg80211_chan_def *chandef)
+{
+ int err = -EBUSY;
+
+ mutex_lock(&rdev->offchan_mutex);
+ if (rdev->offchan_radar_wdev)
+ goto out;
+
+ err = rdev_set_radar_offchan(rdev, chandef);
+ if (err)
+ goto out;
+
+ rdev->offchan_radar_wdev = wdev;
+out:
+ mutex_unlock(&rdev->offchan_mutex);
+ return err;
+}
+
+int
+cfg80211_stop_offchan_radar_detection(struct cfg80211_registered_device *rdev)
+{
+ int err = 0;
+
+ mutex_lock(&rdev->offchan_mutex);
+ if (!rdev->offchan_radar_wdev)
+ goto out;
+
+ err = rdev_set_radar_offchan(rdev, NULL);
+ if (err)
+ goto out;
+
+ rdev->offchan_radar_wdev = NULL;
+out:
+ mutex_unlock(&rdev->offchan_mutex);
+ return err;
+}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 81232b73df8f..25ee16558dfa 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -776,6 +776,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_MBSSID_CONFIG] =
NLA_POLICY_NESTED(nl80211_mbssid_config_policy),
[NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED },
+ [NL80211_ATTR_RADAR_OFFCHAN] = { .type = NLA_FLAG },
};
/* policy for the key attributes */
@@ -9280,12 +9281,6 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
if (err)
return err;
- if (netif_carrier_ok(dev))
- return -EBUSY;
-
- if (wdev->cac_started)
- return -EBUSY;
-
err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
if (err < 0)
return err;
@@ -9296,6 +9291,16 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
if (!cfg80211_chandef_dfs_usable(wiphy, &chandef))
return -EINVAL;
+ if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN]))
+ return cfg80211_start_offchan_radar_detection(rdev, wdev,
+ &chandef);
+
+ if (netif_carrier_ok(dev))
+ return -EBUSY;
+
+ if (wdev->cac_started)
+ return -EBUSY;
+
/* 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;
--
2.31.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 mac80211-next 4/6] cfg80211: introduce cfg80211_cac_offchan_event routine
2021-10-23 9:10 [PATCH v2 mac80211-next 0/6] add offchannel radar chain support Lorenzo Bianconi
` (2 preceding siblings ...)
2021-10-23 9:10 ` [PATCH v2 mac80211-next 3/6] cfg80211: introduce the capability to configure offchannel CAC detection Lorenzo Bianconi
@ 2021-10-23 9:10 ` Lorenzo Bianconi
2021-10-23 9:10 ` [PATCH v2 mac80211-next 5/6] cfg80211: introduce offchannel cac delayed work Lorenzo Bianconi
2021-10-23 9:10 ` [PATCH v2 mac80211-next 6/6] cfg80211: introduce NL80211_EXT_FEATURE_RADAR_OFFCHAN feature flag Lorenzo Bianconi
5 siblings, 0 replies; 7+ messages in thread
From: Lorenzo Bianconi @ 2021-10-23 9:10 UTC (permalink / raw)
To: johannes; +Cc: nbd, linux-wireless, lorenzo.bianconi, ryder.lee, evelyn.tsai
Introduce cfg80211_cac_offchan_event routine in order to notify
userland when a Channel Availability Check (CAC) is finished, started
or aborted by a offchannel dedicated chain.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
include/net/cfg80211.h | 13 ++++++++++
net/wireless/mlme.c | 57 ++++++++++++++++++++++++++++++++++++++++--
2 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 3bb76835f4b1..8d075e11a1f8 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -7646,6 +7646,19 @@ void cfg80211_cac_event(struct net_device *netdev,
const struct cfg80211_chan_def *chandef,
enum nl80211_radar_event event, gfp_t gfp);
+/**
+ * cfg80211_offchan_cac_event - Channel Availability Check (CAC) offchan event
+ * @wiphy: the wiphy
+ * @chandef: chandef for the current channel
+ * @event: type of event
+ * @gfp: context flags
+ *
+ * This function is called when a Channel Availability Check (CAC) is finished,
+ * started or aborted by a offchannel dedicated chain.
+ */
+void cfg80211_offchan_cac_event(struct wiphy *wiphy,
+ const struct cfg80211_chan_def *chandef,
+ enum nl80211_radar_event event, gfp_t gfp);
/**
* cfg80211_gtk_rekey_notify - notify userspace about driver rekeying
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 053293f51188..9f379a91d7fd 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -969,6 +969,57 @@ void cfg80211_cac_event(struct net_device *netdev,
}
EXPORT_SYMBOL(cfg80211_cac_event);
+static void
+__cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev,
+ const struct cfg80211_chan_def *chandef,
+ enum nl80211_radar_event event, gfp_t gfp)
+{
+ struct wiphy *wiphy = &rdev->wiphy;
+ struct net_device *netdev;
+
+ lockdep_assert_held(&rdev->offchan_mutex);
+
+ if (event != NL80211_RADAR_CAC_STARTED && !rdev->offchan_radar_wdev)
+ return;
+
+ switch (event) {
+ case NL80211_RADAR_CAC_FINISHED:
+ cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
+ memcpy(&rdev->cac_done_chandef, chandef, sizeof(*chandef));
+ queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk);
+ cfg80211_sched_dfs_chan_update(rdev);
+ wdev = rdev->offchan_radar_wdev;
+ rdev->offchan_radar_wdev = NULL;
+ break;
+ case NL80211_RADAR_CAC_ABORTED:
+ wdev = rdev->offchan_radar_wdev;
+ rdev->offchan_radar_wdev = NULL;
+ break;
+ case NL80211_RADAR_CAC_STARTED:
+ WARN_ON(!wdev);
+ rdev->offchan_radar_wdev = wdev;
+ break;
+ default:
+ return;
+ }
+
+ netdev = wdev ? wdev->netdev : NULL;
+ nl80211_radar_notify(rdev, chandef, event, netdev, gfp);
+}
+
+void cfg80211_offchan_cac_event(struct wiphy *wiphy,
+ const struct cfg80211_chan_def *chandef,
+ enum nl80211_radar_event event, gfp_t gfp)
+{
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+
+ mutex_lock(&rdev->offchan_mutex);
+ __cfg80211_offchan_cac_event(rdev, NULL, chandef, event, gfp);
+ mutex_unlock(&rdev->offchan_mutex);
+}
+EXPORT_SYMBOL(cfg80211_offchan_cac_event);
+
int
cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev,
@@ -984,7 +1035,8 @@ cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev,
if (err)
goto out;
- rdev->offchan_radar_wdev = wdev;
+ __cfg80211_offchan_cac_event(rdev, wdev, chandef,
+ NL80211_RADAR_CAC_STARTED, GFP_KERNEL);
out:
mutex_unlock(&rdev->offchan_mutex);
return err;
@@ -1003,7 +1055,8 @@ cfg80211_stop_offchan_radar_detection(struct cfg80211_registered_device *rdev)
if (err)
goto out;
- rdev->offchan_radar_wdev = NULL;
+ __cfg80211_offchan_cac_event(rdev, NULL, NULL,
+ NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
out:
mutex_unlock(&rdev->offchan_mutex);
return err;
--
2.31.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 mac80211-next 5/6] cfg80211: introduce offchannel cac delayed work
2021-10-23 9:10 [PATCH v2 mac80211-next 0/6] add offchannel radar chain support Lorenzo Bianconi
` (3 preceding siblings ...)
2021-10-23 9:10 ` [PATCH v2 mac80211-next 4/6] cfg80211: introduce cfg80211_cac_offchan_event routine Lorenzo Bianconi
@ 2021-10-23 9:10 ` Lorenzo Bianconi
2021-10-23 9:10 ` [PATCH v2 mac80211-next 6/6] cfg80211: introduce NL80211_EXT_FEATURE_RADAR_OFFCHAN feature flag Lorenzo Bianconi
5 siblings, 0 replies; 7+ messages in thread
From: Lorenzo Bianconi @ 2021-10-23 9:10 UTC (permalink / raw)
To: johannes; +Cc: nbd, linux-wireless, lorenzo.bianconi, ryder.lee, evelyn.tsai
Introduce cac delayed work in order to report NL80211_RADAR_CAC_FINISHED
to userspace.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
net/wireless/core.c | 1 +
net/wireless/core.h | 4 ++++
net/wireless/mlme.c | 20 ++++++++++++++++++++
3 files changed, 25 insertions(+)
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 385c3654b385..57e825bc37ea 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -545,6 +545,7 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work);
INIT_WORK(&rdev->conn_work, cfg80211_conn_work);
INIT_WORK(&rdev->event_work, cfg80211_event_work);
+ INIT_DELAYED_WORK(&rdev->offchan_cac_work, cfg80211_offchan_cac_work);
init_waitqueue_head(&rdev->dev_wait);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 6e4d18fb93b1..c129311834a0 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -86,6 +86,8 @@ struct cfg80211_registered_device {
struct mutex offchan_mutex; /* protect offchan_radar_wdev */
struct wireless_dev *offchan_radar_wdev;
+ struct cfg80211_chan_def offchan_radar_chandef;
+ struct delayed_work offchan_cac_work;
/* netlink port which started critical protocol (0 means not started) */
u32 crit_proto_nlportid;
@@ -500,6 +502,8 @@ cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev,
int
cfg80211_stop_offchan_radar_detection(struct cfg80211_registered_device *rdev);
+void cfg80211_offchan_cac_work(struct work_struct *work);
+
bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
struct ieee80211_channel *chan);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 9f379a91d7fd..532df85d1c26 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -969,6 +969,17 @@ void cfg80211_cac_event(struct net_device *netdev,
}
EXPORT_SYMBOL(cfg80211_cac_event);
+void cfg80211_offchan_cac_work(struct work_struct *work)
+{
+ struct delayed_work *delayed_work = to_delayed_work(work);
+ struct cfg80211_registered_device *rdev;
+
+ rdev = container_of(delayed_work, struct cfg80211_registered_device,
+ offchan_cac_work);
+ cfg80211_offchan_cac_event(&rdev->wiphy, &rdev->offchan_radar_chandef,
+ NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
+}
+
static void
__cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev,
@@ -993,6 +1004,7 @@ __cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev,
rdev->offchan_radar_wdev = NULL;
break;
case NL80211_RADAR_CAC_ABORTED:
+ cancel_delayed_work(&rdev->offchan_cac_work);
wdev = rdev->offchan_radar_wdev;
rdev->offchan_radar_wdev = NULL;
break;
@@ -1025,6 +1037,7 @@ cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev,
struct cfg80211_chan_def *chandef)
{
+ unsigned int cac_time_ms;
int err = -EBUSY;
mutex_lock(&rdev->offchan_mutex);
@@ -1035,8 +1048,15 @@ cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev,
if (err)
goto out;
+ cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, chandef);
+ if (!cac_time_ms)
+ cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
+
+ rdev->offchan_radar_chandef = *chandef;
__cfg80211_offchan_cac_event(rdev, wdev, chandef,
NL80211_RADAR_CAC_STARTED, GFP_KERNEL);
+ queue_delayed_work(cfg80211_wq, &rdev->offchan_cac_work,
+ msecs_to_jiffies(cac_time_ms));
out:
mutex_unlock(&rdev->offchan_mutex);
return err;
--
2.31.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 mac80211-next 6/6] cfg80211: introduce NL80211_EXT_FEATURE_RADAR_OFFCHAN feature flag
2021-10-23 9:10 [PATCH v2 mac80211-next 0/6] add offchannel radar chain support Lorenzo Bianconi
` (4 preceding siblings ...)
2021-10-23 9:10 ` [PATCH v2 mac80211-next 5/6] cfg80211: introduce offchannel cac delayed work Lorenzo Bianconi
@ 2021-10-23 9:10 ` Lorenzo Bianconi
5 siblings, 0 replies; 7+ messages in thread
From: Lorenzo Bianconi @ 2021-10-23 9:10 UTC (permalink / raw)
To: johannes; +Cc: nbd, linux-wireless, lorenzo.bianconi, ryder.lee, evelyn.tsai
Introduce NL80211_EXT_FEATURE_RADAR_OFFCHAN feature flag in order to
notify userland the underlay hw supports offchannel radar/CAC detection.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
include/uapi/linux/nl80211.h | 4 ++++
net/wireless/mlme.c | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 87ece3e68b8b..3e734826792f 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -6060,6 +6060,9 @@ enum nl80211_feature_flags {
* frames. Userspace has to share FILS AAD details to the driver by using
* @NL80211_CMD_SET_FILS_AAD.
*
+ * @NL80211_EXT_FEATURE_RADAR_OFFCHAN: Device supports offchannel radar/CAC
+ * detection.
+ *
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
*/
@@ -6126,6 +6129,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE,
NL80211_EXT_FEATURE_BSS_COLOR,
NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD,
+ NL80211_EXT_FEATURE_RADAR_OFFCHAN,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 532df85d1c26..247ee0a01e8b 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -1040,6 +1040,10 @@ cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev,
unsigned int cac_time_ms;
int err = -EBUSY;
+ if (!wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_RADAR_OFFCHAN))
+ return -EOPNOTSUPP;
+
mutex_lock(&rdev->offchan_mutex);
if (rdev->offchan_radar_wdev)
goto out;
--
2.31.1
^ permalink raw reply related [flat|nested] 7+ messages in thread