Skip to contentSkip to conversation

add offchannel radar chain support

PATCH Superseded Lorenzo Bianconi 1 participant 5 messages Oct 19, 2021

Subsystems (2)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover add offchannel radar chain support

Introduce the capability to configure a dedicated chain available for radar detection on some hw (e.g. mt7915). The driver is supposed to implement CAC management in sw or fw while hostapd will implement the logic to select and configure the monitored channel.
Using a dedicated chain to perform the CAC, the AP can avoid the CAC downtime switching to a new DFS channel.

Changes since rfc:
- rely on NL80211_CMD_RADAR_DETECT netlink msg to configure offchannel radar chain

Lorenzo Bianconi (4):
mac80211: introduce set_radar_offchan callback
cfg80211: introduce NL80211_ATTR_RADAR_OFFCHAN netlink attribute
cfg80211: introduce cfg80211_cac_offchan_event routine
cfg80211: introduce NL80211_EXT_FEATURE_RADAR_OFFCHAN feature flag

 include/net/cfg80211.h       | 19 +++++++++++++++++++
 include/net/mac80211.h       |  5 +++++
 include/uapi/linux/nl80211.h | 10 ++++++++++
 net/mac80211/cfg.c           | 13 +++++++++++++
 net/wireless/mlme.c          | 26 ++++++++++++++++++++++++++
 net/wireless/nl80211.c       | 16 ++++++++++++++--
 net/wireless/rdev-ops.h      | 17 +++++++++++++++++
 net/wireless/trace.h         | 19 +++++++++++++++++++
 8 files changed, 123 insertions(+), 2 deletions(-)
Signature · 1 line
2.31.1
#1 lore raw

PATCH 1/4 mac80211: introduce set_radar_offchan callback

Introduce set_radar_offchan callback in cfg80211/mac80211_ops in order to configure a dedicated chain available on some hw (e.g. mt7915) to perform offchannel CAC detection.

---
 include/net/cfg80211.h  |  6 ++++++
 include/net/mac80211.h  |  5 +++++
 net/mac80211/cfg.c      | 13 +++++++++++++
 net/wireless/rdev-ops.h | 17 +++++++++++++++++
 net/wireless/trace.h    | 19 +++++++++++++++++++
 5 files changed, 60 insertions(+)
include/net/cfg80211.h +6 -0
index e9e313aa991f..af62af6bf369 100644
@@ -4072,6 +4072,10 @@ 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 chain available for radar detection
+ *	on some hw. The chain can't be used to transmits or receives frames.
+ *	The driver is supposed to implement CAC management in sw or fw.
  */
 struct cfg80211_ops {
 	int	(*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -4404,6 +4408,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);
 };
 
 /*
include/net/mac80211.h +5 -0
index 13cad5e9e6c0..faf6ede80f2b 100644
@@ -3944,6 +3944,9 @@ 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 chain available for radar detection
+ *	on some hw. The chain can't be used to transmits or receives frames.
+ *	The driver is supposed to implement CAC management in sw or fw.
  */
 struct ieee80211_ops {
 	void (*tx)(struct ieee80211_hw *hw,
@@ -4272,6 +4275,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);
 };
 
 /**
net/mac80211/cfg.c +13 -0
index e2b791c37591..1ab84830a38f 100644
@@ -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,
 };
net/wireless/rdev-ops.h +17 -0
index cc1efec4b27b..8672b3ef99e4 100644
@@ -1395,4 +1395,21 @@ 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;
+
+	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 */
net/wireless/trace.h +19 -0
index ad6c16a06bcb..0b27eaa14a18 100644
@@ -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
Signature · 1 line
2.31.1
#2 lore raw

PATCH 2/4 cfg80211: introduce NL80211_ATTR_RADAR_OFFCHAN netlink attribute

In reply to Lorenzo Bianconi

Introduce NL80211_ATTR_RADAR_OFFCHAN netlink attribute in order to configure offchannel radar chain if supported by the underlay driver.

---
 include/uapi/linux/nl80211.h |  6 ++++++
 net/wireless/nl80211.c       | 12 ++++++++++--
 2 files changed, 16 insertions(+), 2 deletions(-)
include/uapi/linux/nl80211.h +6 -0
index eda608b1eb09..96e622777bb2 100644
@@ -2639,6 +2639,10 @@ enum nl80211_commands {
  *	Mandatory parameter for the transmitting interface to enable MBSSID.
  *	Optional for the non-transmitting interfaces.
  *
+ * @NL80211_ATTR_RADAR_OFFCHAN: Configure dedicated chain available for radar
+ *	detection on some hw. The chain can't be used to transmits or receives
+ *	frames. The driver is supposed to implement CAC management in sw or fw.
+ *
  * @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 +3149,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,
net/wireless/nl80211.c +10 -2
index 3f37e4d5c5d2..a296f180624e 100644
@@ -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 */
@@ -9279,10 +9280,12 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
 	if (err)
 		return err;
 
-	if (netif_carrier_ok(dev))
+	if (!nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN]) &&
+	    netif_carrier_ok(dev))
 		return -EBUSY;
 
-	if (wdev->cac_started)
+	if (!nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN]) &&
+	    wdev->cac_started)
 		return -EBUSY;
 
 	err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
@@ -9299,6 +9302,11 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
 	if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD))
 		return -EOPNOTSUPP;
 
+	if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN])) {
+		/* offchannel radar detection */
+		return rdev_set_radar_offchan(rdev, &chandef);
+	}
+
 	if (!rdev->ops->start_radar_detection)
 		return -EOPNOTSUPP;
 
Signature · 1 line
2.31.1
#3 lore raw

PATCH 3/4 cfg80211: introduce cfg80211_cac_offchan_event routine

In reply to Lorenzo Bianconi

Introduce cfg80211_cac_offchan_event routine in order to notify userland when a Channel Availability Check (CAC) is finished or aborted by offchannel dedicated chain.

---
 include/net/cfg80211.h | 13 +++++++++++++
 net/wireless/mlme.c    | 26 ++++++++++++++++++++++++++
 2 files changed, 39 insertions(+)
include/net/cfg80211.h +13 -0
index af62af6bf369..2419b4e192ae 100644
@@ -7630,6 +7630,19 @@ void cfg80211_cac_event(struct net_device *netdev,
 			const struct cfg80211_chan_def *chandef,
 			enum nl80211_radar_event event, gfp_t gfp);
 
+/**
+ * cfg80211_cac_offchan_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
+ * or aborted by offchannel dedicated chain.
+ */
+void cfg80211_cac_offchan_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
net/wireless/mlme.c +26 -0
index 3aa69b375a10..4362f4f49bb4 100644
@@ -968,3 +968,29 @@ void cfg80211_cac_event(struct net_device *netdev,
 	nl80211_radar_notify(rdev, chandef, event, netdev, gfp);
 }
 EXPORT_SYMBOL(cfg80211_cac_event);
+
+void cfg80211_cac_offchan_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);
+
+	switch (event) {
+	case NL80211_RADAR_CAC_FINISHED:
+		cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
+		memcpy(&rdev->cac_done_chandef, chandef,
+		       sizeof(struct cfg80211_chan_def));
+		queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk);
+		cfg80211_sched_dfs_chan_update(rdev);
+		break;
+	case NL80211_RADAR_CAC_ABORTED:
+	case NL80211_RADAR_CAC_STARTED:
+		break;
+	default:
+		WARN_ON(1);
+		return;
+	}
+
+	nl80211_radar_notify(rdev, chandef, event, NULL, gfp);
+}
+EXPORT_SYMBOL(cfg80211_cac_offchan_event);
Signature · 1 line
2.31.1
#4 lore raw

PATCH 4/4 cfg80211: introduce NL80211_EXT_FEATURE_RADAR_OFFCHAN feature flag

In reply to Lorenzo Bianconi

Introduce NL80211_EXT_FEATURE_RADAR_OFFCHAN feature flag in order to notify userland the underlay hw supports offchannel radar/CAC detection.

---
 include/uapi/linux/nl80211.h | 4 ++++
 net/wireless/nl80211.c       | 4 ++++
 2 files changed, 8 insertions(+)
include/uapi/linux/nl80211.h +4 -0
index 96e622777bb2..d856c95ea736 100644
@@ -6055,6 +6055,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.
  */
@@ -6121,6 +6124,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,
net/wireless/nl80211.c +4 -0
index a296f180624e..9f19ff5b13c5 100644
@@ -9304,6 +9304,10 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
 
 	if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN])) {
 		/* offchannel radar detection */
+		if (!wiphy_ext_feature_isset(wiphy,
+					     NL80211_EXT_FEATURE_RADAR_OFFCHAN))
+			return -EOPNOTSUPP;
+
 		return rdev_set_radar_offchan(rdev, &chandef);
 	}
 
Signature · 1 line
2.31.1