wifi: ath12k: handle radar detection with MLO
authorAditya Kumar Singh <quic_adisi@quicinc.com>
Wed, 18 Dec 2024 03:41:34 +0000 (09:11 +0530)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Wed, 8 Jan 2025 00:29:58 +0000 (16:29 -0800)
ieee80211_radar_detected() expects the driver to pass a channel context
configuration during MLO. This is used to identify exactly which link
detected the radar.

Add support to pass this to mac80211. Since the link arvif is not known in
the WMI event, introduce a helper iterator API,
ath12k_mac_get_any_chanctx_conf_iter(), to get the channel context
configuration.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1

Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
Acked-by: Kalle Valo <kvalo@kernel.org>
Link: https://patch.msgid.link/20241218-ath12k_mlo_dfs-v1-3-058e783bcfc7@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/mac.c
drivers/net/wireless/ath/ath12k/mac.h
drivers/net/wireless/ath/ath12k/wmi.c

index 7f1e39d9c3b4a4f85b9154da73800599fa8c3e9f..9a5402803d72dffe7ee30afa54ccb609c4c5b0f0 100644 (file)
@@ -751,6 +751,17 @@ static struct ath12k *ath12k_get_ar_by_vif(struct ieee80211_hw *hw,
        return NULL;
 }
 
+void ath12k_mac_get_any_chanctx_conf_iter(struct ieee80211_hw *hw,
+                                         struct ieee80211_chanctx_conf *conf,
+                                         void *data)
+{
+       struct ath12k_mac_get_any_chanctx_conf_arg *arg = data;
+       struct ath12k *ctx_ar = ath12k_get_ar_by_ctx(hw, conf);
+
+       if (ctx_ar == arg->ar)
+               arg->chanctx_conf = conf;
+}
+
 static struct ath12k_link_vif *ath12k_mac_get_vif_up(struct ath12k *ar)
 {
        struct ath12k_link_vif *arvif;
index 81cfb950e6cddfcf31747e46c7a9a805b94f55dd..3594729b63974e942b91eed0ebdfcabcb6a3c3a1 100644 (file)
@@ -59,6 +59,11 @@ enum ath12k_supported_bw {
        ATH12K_BW_320   = 4,
 };
 
+struct ath12k_mac_get_any_chanctx_conf_arg {
+       struct ath12k *ar;
+       struct ieee80211_chanctx_conf *chanctx_conf;
+};
+
 extern const struct htt_rx_ring_tlv_filter ath12k_mac_mon_status_filter_default;
 
 void ath12k_mac_destroy(struct ath12k_hw_group *ag);
@@ -100,5 +105,8 @@ int ath12k_mac_mlo_setup(struct ath12k_hw_group *ag);
 int ath12k_mac_mlo_ready(struct ath12k_hw_group *ag);
 void ath12k_mac_mlo_teardown(struct ath12k_hw_group *ag);
 int ath12k_mac_vdev_stop(struct ath12k_link_vif *arvif);
+void ath12k_mac_get_any_chanctx_conf_iter(struct ieee80211_hw *hw,
+                                         struct ieee80211_chanctx_conf *conf,
+                                         void *data);
 
 #endif
index d0ae7f142c11ab4720bf95c0c95990ff40bd2815..9a96c4d70e6007d3701af63278b23dd1a79cc4b1 100644 (file)
@@ -6935,6 +6935,7 @@ static void
 ath12k_wmi_pdev_dfs_radar_detected_event(struct ath12k_base *ab, struct sk_buff *skb)
 {
        const void **tb;
+       struct ath12k_mac_get_any_chanctx_conf_arg arg;
        const struct ath12k_wmi_pdev_radar_event *ev;
        struct ath12k *ar;
        int ret;
@@ -6970,13 +6971,22 @@ ath12k_wmi_pdev_dfs_radar_detected_event(struct ath12k_base *ab, struct sk_buff
                goto exit;
        }
 
+       arg.ar = ar;
+       arg.chanctx_conf = NULL;
+       ieee80211_iter_chan_contexts_atomic(ath12k_ar_to_hw(ar),
+                                           ath12k_mac_get_any_chanctx_conf_iter, &arg);
+       if (!arg.chanctx_conf) {
+               ath12k_warn(ab, "failed to find valid chanctx_conf in radar detected event\n");
+               goto exit;
+       }
+
        ath12k_dbg(ar->ab, ATH12K_DBG_REG, "DFS Radar Detected in pdev %d\n",
                   ev->pdev_id);
 
        if (ar->dfs_block_radar_events)
                ath12k_info(ab, "DFS Radar detected, but ignored as requested\n");
        else
-               ieee80211_radar_detected(ath12k_ar_to_hw(ar), NULL);
+               ieee80211_radar_detected(ath12k_ar_to_hw(ar), arg.chanctx_conf);
 
 exit:
        rcu_read_unlock();