Search Linux Wireless

[PATCH wireless-next v2 2/3] wifi: mac80211: add support to handle incumbent signal detected event from driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Hari Chandrakanthan <quic_haric@xxxxxxxxxxx>

Add a new API ieee80211_incumbent_signal_detected() that can be used by
wireless drivers to notify the higher layers about the interference of
incumbent signals in 6 GHz band with the operating channel (mandatory to
pass during MLO) and the interference bitmap in which each bit denotes
the affected 20 MHz in the operating channel.

Signed-off-by: Hari Chandrakanthan <quic_haric@xxxxxxxxxxx>
Co-developed-by: Aditya Kumar Singh <aditya.kumar.singh@xxxxxxxxxxxxxxxx>
Signed-off-by: Aditya Kumar Singh <aditya.kumar.singh@xxxxxxxxxxxxxxxx>
Signed-off-by: Amith A <quic_amitajit@xxxxxxxxxxx>
---
 include/net/mac80211.h     | 18 ++++++++++++++++++
 net/mac80211/ieee80211_i.h |  5 +++++
 net/mac80211/main.c        |  3 +++
 net/mac80211/trace.h       | 26 +++++++++++++++++++++++++
 net/mac80211/util.c        | 39 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 91 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index a45e4bee65d4..678e58609280 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -257,6 +257,8 @@ struct ieee80211_chan_req {
  *	after RTS/CTS handshake to receive SMPS MIMO transmissions;
  *	this will always be >= @rx_chains_static.
  * @radar_enabled: whether radar detection is enabled on this channel.
+ * @incumbt_sig_intf_bmap: Bitmap indicating the sub-channels where an
+ *	incumbent signal's interference was detected.
  * @drv_priv: data area for driver use, will always be aligned to
  *	sizeof(void *), size is determined in hw information.
  */
@@ -270,6 +272,8 @@ struct ieee80211_chanctx_conf {
 
 	bool radar_enabled;
 
+	u32 incumbt_sig_intf_bmap;
+
 	u8 drv_priv[] __aligned(sizeof(void *));
 };
 
@@ -7834,4 +7838,18 @@ int ieee80211_emulate_switch_vif_chanctx(struct ieee80211_hw *hw,
 					 int n_vifs,
 					 enum ieee80211_chanctx_switch_mode mode);
 
+/**
+ * ieee80211_incumbent_signal_detected - inform that an incumbent signal
+ *	interference was detected
+ * @hw: pointer as obtained from ieee80211_alloc_hw()
+ * @chanctx_conf: Channel context on which the signal interference was detected.
+ *	Mandatory to pass a valid pointer for MLO. For non-MLO %NULL can be
+ *	passed
+ * @incumbt_sig_intf_bmap: Bitmap indicating where the incumbent signal was
+ *	detected.
+ */
+void ieee80211_incumbent_signal_detected(struct ieee80211_hw *hw,
+					 struct ieee80211_chanctx_conf *chanctx_conf,
+					 u32 incumbt_sig_intf_bmap);
+
 #endif /* MAC80211_H */
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 07f5fb11569b..6f389c4adf9b 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1683,6 +1683,8 @@ struct ieee80211_local {
 	u8 ext_capa[8];
 
 	bool wbrf_supported;
+
+	struct wiphy_work incumbent_signal_detected_work;
 };
 
 static inline struct ieee80211_sub_if_data *
@@ -2892,4 +2894,7 @@ ieee80211_determine_chan_mode(struct ieee80211_sub_if_data *sdata,
 #define VISIBLE_IF_MAC80211_KUNIT static
 #endif
 
+void ieee80211_incumbent_signal_detected_work(struct wiphy *wiphy,
+					      struct wiphy_work *work);
+
 #endif /* IEEE80211_I_H */
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index e8c85aa77c56..0c40183a33f7 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1002,6 +1002,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
 
 	wiphy_work_init(&local->radar_detected_work,
 			ieee80211_dfs_radar_detected_work);
+	wiphy_work_init(&local->incumbent_signal_detected_work,
+			ieee80211_incumbent_signal_detected_work);
 
 	wiphy_work_init(&local->reconfig_filter, ieee80211_reconfig_filter);
 
@@ -1675,6 +1677,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
 	wiphy_work_cancel(local->hw.wiphy, &local->reconfig_filter);
 	wiphy_work_cancel(local->hw.wiphy, &local->sched_scan_stopped_work);
 	wiphy_work_cancel(local->hw.wiphy, &local->radar_detected_work);
+	wiphy_work_cancel(local->hw.wiphy, &local->incumbent_signal_detected_work);
 	wiphy_unlock(local->hw.wiphy);
 	rtnl_unlock();
 
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 0bfbce157486..ce97faab1765 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -3136,6 +3136,32 @@ TRACE_EVENT(api_radar_detected,
 	)
 );
 
+TRACE_EVENT(api_incumbent_signal_detected,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_chanctx_conf *chanctx_conf),
+
+	TP_ARGS(local, chanctx_conf),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		CHANDEF_ENTRY
+		__field(u32, bitmap)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		CHANDEF_ASSIGN(&chanctx_conf->def)
+		__entry->bitmap =
+			chanctx_conf ? chanctx_conf->incumbt_sig_intf_bmap : 0;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT " Incumbent signal detected."
+		CHANDEF_PR_FMT " Bitmap: 0x%x ",
+		LOCAL_PR_ARG, CHANDEF_PR_ARG, __entry->bitmap
+	)
+);
+
 TRACE_EVENT(api_request_smps,
 	TP_PROTO(struct ieee80211_local *local,
 		 struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 9eb35e3b9e52..dc43f2e0f2af 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -3534,6 +3534,32 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local,
 	}
 }
 
+void ieee80211_incumbent_signal_detected_work(struct wiphy *wiphy,
+					      struct wiphy_work *work)
+{
+	struct ieee80211_local *local =
+		container_of(work, struct ieee80211_local,
+			     incumbent_signal_detected_work);
+	struct ieee80211_chanctx_conf *conf;
+	struct ieee80211_chanctx *ctx;
+
+	lockdep_assert_wiphy(local->hw.wiphy);
+
+	list_for_each_entry(ctx, &local->chanctx_list, list) {
+		if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER)
+			continue;
+
+		if (!ctx->conf.incumbt_sig_intf_bmap)
+			continue;
+
+		conf = &ctx->conf;
+		cfg80211_incumbent_signal_detect_event(local->hw.wiphy,
+						       &conf->def,
+						       conf->incumbt_sig_intf_bmap,
+						       GFP_KERNEL);
+	}
+}
+
 void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy,
 				       struct wiphy_work *work)
 {
@@ -3592,6 +3618,19 @@ void ieee80211_radar_detected(struct ieee80211_hw *hw,
 }
 EXPORT_SYMBOL(ieee80211_radar_detected);
 
+void ieee80211_incumbent_signal_detected(struct ieee80211_hw *hw,
+					 struct ieee80211_chanctx_conf *chanctx_conf,
+					 u32 incumbt_sig_intf_bmap)
+{
+	struct ieee80211_local *local = hw_to_local(hw);
+
+	chanctx_conf->incumbt_sig_intf_bmap = incumbt_sig_intf_bmap;
+
+	trace_api_incumbent_signal_detected(local, chanctx_conf);
+	wiphy_work_queue(hw->wiphy, &local->incumbent_signal_detected_work);
+}
+EXPORT_SYMBOL(ieee80211_incumbent_signal_detected);
+
 void ieee80211_chandef_downgrade(struct cfg80211_chan_def *c,
 				 struct ieee80211_conn_settings *conn)
 {
-- 
2.34.1





[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux