]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: ath11k: Add initialization and deinitialization sequence for CFR module
authorVenkateswara Naralasetty <quic_vnaralas@quicinc.com>
Tue, 30 Dec 2025 08:25:15 +0000 (13:55 +0530)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Fri, 16 Jan 2026 01:19:37 +0000 (17:19 -0800)
Channel Frequency Response (CFR) module will be initialized only when
the following criteria passes:
 * Enabled CFR support for the hardware through the hardware param
   'cfr_support'
 * WMI service enabled for the CFR support
   'WMI_TLV_SERVICE_CFR_CAPTURE_SUPPORT'

Also, provide a configuration option CONFIG_ATH11K_CFR to enable CFR
feature support during the compilation time.

CFR module initialization includes Direct Buffer(DB) ring initialization
where hardware uses the DB ring buffers to copy CFR data to host.
Number of buffers and buffer size of the ring is based on the DB ring
capabilities advertised by the firmware through WMI service ready.
Also ring configurations are sent to firmware through
ath11k_dbring_wmi_cfg_setup().

Predefine ath11k_cfr_dma_hdr, ath11k_look_up_table, and ath11k_cfr
structs and fields for subsequent patches.

Tested-on: IPQ8074 hw2.0 PCI IPQ8074 WLAN.HK.2.5.0.1-00991-QCAHKSWPL_SILICONZ-1
Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-04685-QCAHSPSWPL_V1_V2_SILICONZ_IOE-1

Signed-off-by: Venkateswara Naralasetty <quic_vnaralas@quicinc.com>
Co-developed-by: Yu Zhang (Yuriy) <yu.zhang@oss.qualcomm.com>
Signed-off-by: Yu Zhang (Yuriy) <yu.zhang@oss.qualcomm.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Signed-off-by: Qian Zhang <qian.zhang@oss.qualcomm.com>
Link: https://patch.msgid.link/20251230082520.3401007-2-qian.zhang@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath11k/Kconfig
drivers/net/wireless/ath/ath11k/Makefile
drivers/net/wireless/ath/ath11k/cfr.c [new file with mode: 0644]
drivers/net/wireless/ath/ath11k/cfr.h [new file with mode: 0644]
drivers/net/wireless/ath/ath11k/core.c
drivers/net/wireless/ath/ath11k/core.h
drivers/net/wireless/ath/ath11k/dbring.c
drivers/net/wireless/ath/ath11k/dbring.h
drivers/net/wireless/ath/ath11k/hal.c
drivers/net/wireless/ath/ath11k/hw.h
drivers/net/wireless/ath/ath11k/wmi.h

index 659ef134ef168f5e5ad9a532ccd485d20d8701d5..47dfd39caa89abfeb9d4441d80447dedeec146d6 100644 (file)
@@ -58,3 +58,14 @@ config ATH11K_SPECTRAL
          Enable ath11k spectral scan support
 
          Say Y to enable access to the FFT/spectral data via debugfs.
+
+config ATH11K_CFR
+       bool "ath11k channel frequency response support"
+       depends on ATH11K_DEBUGFS
+       depends on RELAY
+       help
+         Enable ath11k channel frequency response dump support.
+         This option exposes debugfs nodes that will allow the user
+         to enable, disable, and dump data.
+
+         Say Y to enable CFR data dump collection via debugfs.
index d9092414b362d056d539d8e49b15a878b7e28b85..b1435fcf3e1bfe0ed6ed1a127f245de09bc09599 100644 (file)
@@ -28,6 +28,7 @@ ath11k-$(CONFIG_THERMAL) += thermal.o
 ath11k-$(CONFIG_ATH11K_SPECTRAL) += spectral.o
 ath11k-$(CONFIG_PM) += wow.o
 ath11k-$(CONFIG_DEV_COREDUMP) += coredump.o
+ath11k-$(CONFIG_ATH11K_CFR) += cfr.o
 
 obj-$(CONFIG_ATH11K_AHB) += ath11k_ahb.o
 ath11k_ahb-y += ahb.o
diff --git a/drivers/net/wireless/ath/ath11k/cfr.c b/drivers/net/wireless/ath/ath11k/cfr.c
new file mode 100644 (file)
index 0000000..78e3566
--- /dev/null
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: BSD-3-Clause-Clear
+/*
+ * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/relay.h>
+#include "core.h"
+#include "debug.h"
+
+static int ath11k_cfr_process_data(struct ath11k *ar,
+                                  struct ath11k_dbring_data *param)
+{
+       return 0;
+}
+
+void ath11k_cfr_lut_update_paddr(struct ath11k *ar, dma_addr_t paddr,
+                                u32 buf_id)
+{
+       struct ath11k_cfr *cfr = &ar->cfr;
+
+       if (cfr->lut)
+               cfr->lut[buf_id].dbr_address = paddr;
+}
+
+static void ath11k_cfr_ring_free(struct ath11k *ar)
+{
+       struct ath11k_cfr *cfr = &ar->cfr;
+
+       ath11k_dbring_buf_cleanup(ar, &cfr->rx_ring);
+       ath11k_dbring_srng_cleanup(ar, &cfr->rx_ring);
+}
+
+static int ath11k_cfr_ring_alloc(struct ath11k *ar,
+                                struct ath11k_dbring_cap *db_cap)
+{
+       struct ath11k_cfr *cfr = &ar->cfr;
+       int ret;
+
+       ret = ath11k_dbring_srng_setup(ar, &cfr->rx_ring,
+                                      ATH11K_CFR_NUM_RING_ENTRIES,
+                                      db_cap->min_elem);
+       if (ret) {
+               ath11k_warn(ar->ab, "failed to setup db ring: %d\n", ret);
+               return ret;
+       }
+
+       ath11k_dbring_set_cfg(ar, &cfr->rx_ring,
+                             ATH11K_CFR_NUM_RESP_PER_EVENT,
+                             ATH11K_CFR_EVENT_TIMEOUT_MS,
+                             ath11k_cfr_process_data);
+
+       ret = ath11k_dbring_buf_setup(ar, &cfr->rx_ring, db_cap);
+       if (ret) {
+               ath11k_warn(ar->ab, "failed to setup db ring buffer: %d\n", ret);
+               goto srng_cleanup;
+       }
+
+       ret = ath11k_dbring_wmi_cfg_setup(ar, &cfr->rx_ring, WMI_DIRECT_BUF_CFR);
+       if (ret) {
+               ath11k_warn(ar->ab, "failed to setup db ring cfg: %d\n", ret);
+               goto buffer_cleanup;
+       }
+
+       return 0;
+
+buffer_cleanup:
+       ath11k_dbring_buf_cleanup(ar, &cfr->rx_ring);
+srng_cleanup:
+       ath11k_dbring_srng_cleanup(ar, &cfr->rx_ring);
+       return ret;
+}
+
+void ath11k_cfr_deinit(struct ath11k_base *ab)
+{
+       struct ath11k_cfr *cfr;
+       struct ath11k *ar;
+       int i;
+
+       if (!test_bit(WMI_TLV_SERVICE_CFR_CAPTURE_SUPPORT, ab->wmi_ab.svc_map) ||
+           !ab->hw_params.cfr_support)
+               return;
+
+       for (i = 0; i <  ab->num_radios; i++) {
+               ar = ab->pdevs[i].ar;
+               cfr = &ar->cfr;
+
+               if (!cfr->enabled)
+                       continue;
+
+               ath11k_cfr_ring_free(ar);
+
+               spin_lock_bh(&cfr->lut_lock);
+               kfree(cfr->lut);
+               cfr->lut = NULL;
+               cfr->enabled = false;
+               spin_unlock_bh(&cfr->lut_lock);
+       }
+}
+
+int ath11k_cfr_init(struct ath11k_base *ab)
+{
+       struct ath11k_dbring_cap db_cap;
+       struct ath11k_cfr *cfr;
+       u32 num_lut_entries;
+       struct ath11k *ar;
+       int i, ret;
+
+       if (!test_bit(WMI_TLV_SERVICE_CFR_CAPTURE_SUPPORT, ab->wmi_ab.svc_map) ||
+           !ab->hw_params.cfr_support)
+               return 0;
+
+       for (i = 0; i < ab->num_radios; i++) {
+               ar = ab->pdevs[i].ar;
+               cfr = &ar->cfr;
+
+               ret = ath11k_dbring_get_cap(ar->ab, ar->pdev_idx,
+                                           WMI_DIRECT_BUF_CFR, &db_cap);
+               if (ret)
+                       continue;
+
+               idr_init(&cfr->rx_ring.bufs_idr);
+               spin_lock_init(&cfr->rx_ring.idr_lock);
+               spin_lock_init(&cfr->lock);
+               spin_lock_init(&cfr->lut_lock);
+
+               num_lut_entries = min_t(u32, CFR_MAX_LUT_ENTRIES, db_cap.min_elem);
+               cfr->lut = kcalloc(num_lut_entries, sizeof(*cfr->lut),
+                                  GFP_KERNEL);
+               if (!cfr->lut) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
+
+               ret = ath11k_cfr_ring_alloc(ar, &db_cap);
+               if (ret) {
+                       ath11k_warn(ab, "failed to init cfr ring for pdev %d: %d\n",
+                                   i, ret);
+                       spin_lock_bh(&cfr->lut_lock);
+                       kfree(cfr->lut);
+                       cfr->lut = NULL;
+                       cfr->enabled = false;
+                       spin_unlock_bh(&cfr->lut_lock);
+                       goto err;
+               }
+
+               cfr->lut_num = num_lut_entries;
+               cfr->enabled = true;
+       }
+
+       return 0;
+
+err:
+       for (i = i - 1; i >= 0; i--) {
+               ar = ab->pdevs[i].ar;
+               cfr = &ar->cfr;
+
+               if (!cfr->enabled)
+                       continue;
+
+               ath11k_cfr_ring_free(ar);
+
+               spin_lock_bh(&cfr->lut_lock);
+               kfree(cfr->lut);
+               cfr->lut = NULL;
+               cfr->enabled = false;
+               spin_unlock_bh(&cfr->lut_lock);
+       }
+       return ret;
+}
diff --git a/drivers/net/wireless/ath/ath11k/cfr.h b/drivers/net/wireless/ath/ath11k/cfr.h
new file mode 100644 (file)
index 0000000..3534176
--- /dev/null
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: BSD-3-Clause-Clear */
+/*
+ * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef ATH11K_CFR_H
+#define ATH11K_CFR_H
+
+#include "dbring.h"
+#include "wmi.h"
+
+#define ATH11K_CFR_NUM_RESP_PER_EVENT   1
+#define ATH11K_CFR_EVENT_TIMEOUT_MS     1
+#define ATH11K_CFR_NUM_RING_ENTRIES     1
+
+#define CFR_MAX_LUT_ENTRIES 136
+
+#define HOST_MAX_CHAINS 8
+
+struct ath11k_cfr_dma_hdr {
+       u16 info0;
+       u16 info1;
+       u16 sw_peer_id;
+       u16 phy_ppdu_id;
+};
+
+struct ath11k_look_up_table {
+       bool dbr_recv;
+       bool tx_recv;
+       u8 *data;
+       u32 data_len;
+       u16 dbr_ppdu_id;
+       u16 tx_ppdu_id;
+       dma_addr_t dbr_address;
+       struct ath11k_cfr_dma_hdr hdr;
+       u64 txrx_tstamp;
+       u64 dbr_tstamp;
+       u32 header_length;
+       u32 payload_length;
+       struct ath11k_dbring_element *buff;
+};
+
+struct ath11k_cfr {
+       struct ath11k_dbring rx_ring;
+       /* Protects cfr data */
+       spinlock_t lock;
+       /* Protect for lut entries */
+       spinlock_t lut_lock;
+       struct ath11k_look_up_table *lut;
+       u32 lut_num;
+       u64 tx_evt_cnt;
+       u64 dbr_evt_cnt;
+       u64 release_cnt;
+       u64 tx_peer_status_cfr_fail;
+       u64 tx_evt_status_cfr_fail;
+       u64 tx_dbr_lookup_fail;
+       u64 last_success_tstamp;
+       u64 flush_dbr_cnt;
+       u64 clear_txrx_event;
+       u64 cfr_dma_aborts;
+       bool enabled;
+};
+
+#ifdef CONFIG_ATH11K_CFR
+int ath11k_cfr_init(struct ath11k_base *ab);
+void ath11k_cfr_deinit(struct ath11k_base *ab);
+void ath11k_cfr_lut_update_paddr(struct ath11k *ar, dma_addr_t paddr,
+                                u32 buf_id);
+#else
+static inline int ath11k_cfr_init(struct ath11k_base *ab)
+{
+       return 0;
+}
+
+static inline void ath11k_cfr_deinit(struct ath11k_base *ab)
+{
+}
+
+static inline void ath11k_cfr_lut_update_paddr(struct ath11k *ar,
+                                              dma_addr_t paddr, u32 buf_id)
+{
+}
+#endif /* CONFIG_ATH11K_CFR */
+#endif /* ATH11K_CFR_H */
index 03dddc1cd003ad857a7ba802428c0ad781d817ea..1ae9e9427bbea2a53dd4b767473f095b8b00f021 100644 (file)
@@ -1,7 +1,6 @@
 // SPDX-License-Identifier: BSD-3-Clause-Clear
 /*
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
  */
 
@@ -126,6 +125,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .smp2p_wow_exit = false,
                .support_dual_stations = false,
                .pdev_suspend = false,
+               .cfr_support = true,
+               .cfr_num_stream_bufs = 255,
+               .cfr_stream_buf_size = 8200,
        },
        {
                .hw_rev = ATH11K_HW_IPQ6018_HW10,
@@ -211,6 +213,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .support_fw_mac_sequence = false,
                .support_dual_stations = false,
                .pdev_suspend = false,
+               .cfr_support = false,
+               .cfr_num_stream_bufs = 0,
+               .cfr_stream_buf_size = 0,
        },
        {
                .name = "qca6390 hw2.0",
@@ -301,6 +306,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .support_fw_mac_sequence = true,
                .support_dual_stations = true,
                .pdev_suspend = false,
+               .cfr_support = false,
+               .cfr_num_stream_bufs = 0,
+               .cfr_stream_buf_size = 0,
        },
        {
                .name = "qcn9074 hw1.0",
@@ -385,6 +393,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .support_fw_mac_sequence = false,
                .support_dual_stations = false,
                .pdev_suspend = false,
+               .cfr_support = false,
+               .cfr_num_stream_bufs = 0,
+               .cfr_stream_buf_size = 0,
        },
        {
                .name = "wcn6855 hw2.0",
@@ -475,6 +486,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .support_fw_mac_sequence = true,
                .support_dual_stations = true,
                .pdev_suspend = false,
+               .cfr_support = false,
+               .cfr_num_stream_bufs = 0,
+               .cfr_stream_buf_size = 0,
        },
        {
                .name = "wcn6855 hw2.1",
@@ -563,6 +577,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .support_fw_mac_sequence = true,
                .support_dual_stations = true,
                .pdev_suspend = false,
+               .cfr_support = true,
+               .cfr_num_stream_bufs = 255,
+               .cfr_stream_buf_size = 8200,
        },
        {
                .name = "wcn6750 hw1.0",
@@ -646,6 +663,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .support_fw_mac_sequence = true,
                .support_dual_stations = false,
                .pdev_suspend = true,
+               .cfr_support = false,
+               .cfr_num_stream_bufs = 0,
+               .cfr_stream_buf_size = 0,
        },
        {
                .hw_rev = ATH11K_HW_IPQ5018_HW10,
@@ -729,6 +749,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .support_fw_mac_sequence = false,
                .support_dual_stations = false,
                .pdev_suspend = false,
+               .cfr_support = false,
+               .cfr_num_stream_bufs = 0,
+               .cfr_stream_buf_size = 0,
        },
        {
                .name = "qca2066 hw2.1",
@@ -818,6 +841,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .smp2p_wow_exit = false,
                .support_fw_mac_sequence = true,
                .support_dual_stations = true,
+               .cfr_support = false,
+               .cfr_num_stream_bufs = 0,
+               .cfr_stream_buf_size = 0,
        },
        {
                .name = "qca6698aq hw2.1",
@@ -906,6 +932,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .support_fw_mac_sequence = true,
                .support_dual_stations = true,
                .pdev_suspend = false,
+               .cfr_support = true,
+               .cfr_num_stream_bufs = 255,
+               .cfr_stream_buf_size = 8200,
        },
 };
 
@@ -2015,8 +2044,16 @@ static int ath11k_core_pdev_create(struct ath11k_base *ab)
                goto err_thermal_unregister;
        }
 
+       ret = ath11k_cfr_init(ab);
+       if (ret) {
+               ath11k_err(ab, "failed to init cfr %d\n", ret);
+               goto err_spectral_unregister;
+       }
+
        return 0;
 
+err_spectral_unregister:
+       ath11k_spectral_deinit(ab);
 err_thermal_unregister:
        ath11k_thermal_unregister(ab);
 err_mac_unregister:
@@ -2066,6 +2103,7 @@ static void ath11k_core_pdev_suspend_target(struct ath11k_base *ab)
 
 static void ath11k_core_pdev_destroy(struct ath11k_base *ab)
 {
+       ath11k_cfr_deinit(ab);
        ath11k_spectral_deinit(ab);
        ath11k_thermal_unregister(ab);
        ath11k_mac_unregister(ab);
@@ -2278,6 +2316,7 @@ static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
        mutex_lock(&ab->core_lock);
        ath11k_thermal_unregister(ab);
        ath11k_dp_pdev_free(ab);
+       ath11k_cfr_deinit(ab);
        ath11k_spectral_deinit(ab);
        ath11k_ce_cleanup_pipes(ab);
        ath11k_wmi_detach(ab);
index e8780b05ce11e39bdd93dd02d39812be90689b40..40fb7cee3e433975108e8ba11b6a50e7e4ac11e8 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause-Clear */
 /*
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
  */
 
 #ifndef ATH11K_CORE_H
@@ -35,6 +35,7 @@
 #include "wow.h"
 #include "fw.h"
 #include "coredump.h"
+#include "cfr.h"
 
 #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
 
@@ -795,6 +796,11 @@ struct ath11k {
        bool ps_state_enable;
        bool ps_timekeeper_enable;
        s8 max_allowed_tx_power;
+
+#ifdef CONFIG_ATH11K_CFR
+       struct ath11k_cfr cfr;
+#endif
+       bool cfr_enabled;
 };
 
 struct ath11k_band_cap {
index 520d8b8662a282ca3ba396b3941d6155fd5ca353..ed2b781a6bab64ea8269678e15c5e1a3fd2b6f5a 100644 (file)
@@ -1,7 +1,6 @@
 // SPDX-License-Identifier: BSD-3-Clause-Clear
 /*
  * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
  */
 
@@ -37,10 +36,10 @@ static void ath11k_dbring_fill_magic_value(struct ath11k *ar,
        memset32(buffer, ATH11K_DB_MAGIC_VALUE, size);
 }
 
-static int ath11k_dbring_bufs_replenish(struct ath11k *ar,
-                                       struct ath11k_dbring *ring,
-                                       struct ath11k_dbring_element *buff,
-                                       enum wmi_direct_buffer_module id)
+int ath11k_dbring_bufs_replenish(struct ath11k *ar,
+                                struct ath11k_dbring *ring,
+                                struct ath11k_dbring_element *buff,
+                                enum wmi_direct_buffer_module id)
 {
        struct ath11k_base *ab = ar->ab;
        struct hal_srng *srng;
@@ -80,6 +79,9 @@ static int ath11k_dbring_bufs_replenish(struct ath11k *ar,
                goto err_idr_remove;
        }
 
+       if (id == WMI_DIRECT_BUF_CFR)
+               ath11k_cfr_lut_update_paddr(ar, paddr, buf_id);
+
        buff->paddr = paddr;
 
        cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, ar->pdev_idx) |
@@ -155,12 +157,11 @@ int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar,
                                enum wmi_direct_buffer_module id)
 {
        struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd param = {};
-       int ret;
+       int ret, i;
 
        if (id >= WMI_DIRECT_BUF_MAX)
                return -EINVAL;
 
-       param.pdev_id           = DP_SW2HW_MACID(ring->pdev_id);
        param.module_id         = id;
        param.base_paddr_lo     = lower_32_bits(ring->refill_srng.paddr);
        param.base_paddr_hi     = upper_32_bits(ring->refill_srng.paddr);
@@ -173,10 +174,23 @@ int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar,
        param.num_resp_per_event = ring->num_resp_per_event;
        param.event_timeout_ms  = ring->event_timeout_ms;
 
-       ret = ath11k_wmi_pdev_dma_ring_cfg(ar, &param);
-       if (ret) {
-               ath11k_warn(ar->ab, "failed to setup db ring cfg\n");
-               return ret;
+       /* For single pdev, 2GHz and 5GHz use one DBR. */
+       if (ar->ab->hw_params.single_pdev_only) {
+               for (i = 0; i < ar->ab->target_pdev_count; i++) {
+                       param.pdev_id = ar->ab->target_pdev_ids[i].pdev_id;
+                       ret = ath11k_wmi_pdev_dma_ring_cfg(ar, &param);
+                       if (ret) {
+                               ath11k_warn(ar->ab, "failed to setup db ring cfg\n");
+                               return ret;
+                       }
+               }
+       } else {
+               param.pdev_id = DP_SW2HW_MACID(ring->pdev_id);
+               ret = ath11k_wmi_pdev_dma_ring_cfg(ar, &param);
+               if (ret) {
+                       ath11k_warn(ar->ab, "failed to setup db ring cfg\n");
+                       return ret;
+               }
        }
 
        return 0;
@@ -285,6 +299,10 @@ int ath11k_dbring_buffer_release_event(struct ath11k_base *ab,
        pdev_idx = ev->fixed.pdev_id;
        module_id = ev->fixed.module_id;
 
+       if (ab->hw_params.single_pdev_only &&
+           pdev_idx < ab->target_pdev_count)
+               pdev_idx = 0;
+
        if (pdev_idx >= ab->num_radios) {
                ath11k_warn(ab, "Invalid pdev id %d\n", pdev_idx);
                return -EINVAL;
index 2f93b78a50df0edbdfe1fb435b713b751d184c79..0a380120f7a0ebfb1aa164e18d03e7a078dbb237 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause-Clear */
 /*
  * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
  */
 
 #ifndef ATH11K_DBRING_H
@@ -61,6 +61,10 @@ int ath11k_dbring_set_cfg(struct ath11k *ar,
                          u32 event_timeout_ms,
                          int (*handler)(struct ath11k *,
                                         struct ath11k_dbring_data *));
+int ath11k_dbring_bufs_replenish(struct ath11k *ar,
+                                struct ath11k_dbring *ring,
+                                struct ath11k_dbring_element *buff,
+                                enum wmi_direct_buffer_module id);
 int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar,
                                struct ath11k_dbring *ring,
                                enum wmi_direct_buffer_module id);
index 0c797b8d0a276a24cdfb6869953a8ee4bdbf35c0..e821e5a62c1c0a54b841c26fda49a4c0f1a4e804 100644 (file)
@@ -1,7 +1,6 @@
 // SPDX-License-Identifier: BSD-3-Clause-Clear
 /*
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
  */
 #include <linux/dma-mapping.h>
@@ -184,7 +183,7 @@ static const struct hal_srng_config hw_srng_config_template[] = {
        },
        { /* RXDMA DIR BUF */
                .start_ring_id = HAL_SRNG_RING_ID_RXDMA_DIR_BUF,
-               .max_rings = 1,
+               .max_rings = 2,
                .entry_size = 8 >> 2, /* TODO: Define the struct */
                .lmac_ring = true,
                .ring_dir = HAL_SRNG_DIR_SRC,
index 52d9f4c13b1366f2339b8900cf9db91e6ff1bcff..e13ca02a9d057bddda4f04000b9f4a0b08c6352c 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause-Clear */
 /*
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
  */
 
 #ifndef ATH11K_HW_H
@@ -228,6 +228,9 @@ struct ath11k_hw_params {
        bool support_fw_mac_sequence;
        bool support_dual_stations;
        bool pdev_suspend;
+       bool cfr_support;
+       u32 cfr_num_stream_bufs;
+       u32 cfr_stream_buf_size;
 };
 
 struct ath11k_hw_ops {
index 0f0de24a384089c1d36722a115aa007c042916c2..7a55fe0879c088aae8b76bda904ede6d860296f0 100644 (file)
@@ -981,6 +981,7 @@ enum wmi_tlv_pdev_param {
        WMI_PDEV_PARAM_RADIO_CHAN_STATS_ENABLE,
        WMI_PDEV_PARAM_RADIO_DIAGNOSIS_ENABLE,
        WMI_PDEV_PARAM_MESH_MCAST_ENABLE,
+       WMI_PDEV_PARAM_PER_PEER_CFR_ENABLE = 0xa8,
        WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD = 0xbc,
        WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC = 0xbe,
        WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT = 0xc6,