From 78b160227742ff4b2fdc4f462fa2f7662d3d7f8e Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:27 +0530 Subject: [PATCH 001/140] wifi: ath12k: Restructure PCI code to common and Wi-Fi 7 specific logic Refactor pci.c to split common and hardware family specific components. Retain shared logic such as probe and initialization sequences in common pci.c to support reuse across device families and move Wi-Fi 7 specific initialization and configuration to a new pci_wifi7.c file. Register device specific routines via callbacks to keep the common PCI code generic and extensible for future hardware families. This improves maintainability and prepare the codebase for additional device family support. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-1-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/core.c | 5 +- drivers/net/wireless/ath/ath12k/core.h | 6 + drivers/net/wireless/ath/ath12k/pci.c | 200 +++++++------------- drivers/net/wireless/ath/ath12k/pci.h | 21 +- drivers/net/wireless/ath/ath12k/pci_wifi7.c | 173 +++++++++++++++++ drivers/net/wireless/ath/ath12k/pci_wifi7.h | 12 ++ 7 files changed, 278 insertions(+), 140 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/pci_wifi7.c create mode 100644 drivers/net/wireless/ath/ath12k/pci_wifi7.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index d95ee525a6cd0..1a26e00627b0a 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -19,6 +19,7 @@ ath12k-y += core.o \ hw.o \ mhi.o \ pci.o \ + pci_wifi7.o \ dp_mon.o \ fw.o \ p2p.o diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index cc352eef19399..7b02e0c8b1919 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -21,6 +21,7 @@ #include "hif.h" #include "pci.h" #include "wow.h" +#include "pci_wifi7.h" static int ahb_err, pci_err; unsigned int ath12k_debug_mask; @@ -2297,7 +2298,7 @@ static int ath12k_init(void) if (ahb_err) pr_warn("Failed to initialize ath12k AHB device: %d\n", ahb_err); - pci_err = ath12k_pci_init(); + pci_err = ath12k_wifi7_pci_init(); if (pci_err) pr_warn("Failed to initialize ath12k PCI device: %d\n", pci_err); @@ -2308,7 +2309,7 @@ static int ath12k_init(void) static void ath12k_exit(void) { if (!pci_err) - ath12k_pci_exit(); + ath12k_wifi7_pci_exit(); if (!ahb_err) ath12k_ahb_exit(); diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 3c1e0069be1e7..60c2237cb055e 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1035,6 +1035,12 @@ struct ath12k_mem_profile_based_param { struct ath12k_dp_profile_params dp_params; }; +enum ath12k_device_family { + ATH12K_DEVICE_FAMILY_START, + ATH12K_DEVICE_FAMILY_WIFI7 = ATH12K_DEVICE_FAMILY_START, + ATH12K_DEVICE_FAMILY_MAX, +}; + /* Master structure to hold the hw data which may be used in core module */ struct ath12k_base { enum ath12k_hw_rev hw_rev; diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index a12c8379cb466..3e119cc329de2 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -28,44 +28,17 @@ #define WINDOW_RANGE_MASK GENMASK(18, 0) #define WINDOW_STATIC_MASK GENMASK(31, 6) -#define TCSR_SOC_HW_VERSION 0x1B00000 -#define TCSR_SOC_HW_VERSION_MAJOR_MASK GENMASK(11, 8) -#define TCSR_SOC_HW_VERSION_MINOR_MASK GENMASK(7, 4) - /* BAR0 + 4k is always accessible, and no * need to force wakeup. * 4K - 32 = 0xFE0 */ #define ACCESS_ALWAYS_OFF 0xFE0 -#define QCN9274_DEVICE_ID 0x1109 -#define WCN7850_DEVICE_ID 0x1107 - #define PCIE_LOCAL_REG_QRTR_NODE_ID 0x1E03164 #define DOMAIN_NUMBER_MASK GENMASK(7, 4) #define BUS_NUMBER_MASK GENMASK(3, 0) -static const struct pci_device_id ath12k_pci_id_table[] = { - { PCI_VDEVICE(QCOM, QCN9274_DEVICE_ID) }, - { PCI_VDEVICE(QCOM, WCN7850_DEVICE_ID) }, - {} -}; - -MODULE_DEVICE_TABLE(pci, ath12k_pci_id_table); - -/* TODO: revisit IRQ mapping for new SRNG's */ -static const struct ath12k_msi_config ath12k_msi_config[] = { - { - .total_vectors = 16, - .total_users = 3, - .users = (struct ath12k_msi_user[]) { - { .name = "MHI", .num_vectors = 3, .base_vector = 0 }, - { .name = "CE", .num_vectors = 5, .base_vector = 3 }, - { .name = "DP", .num_vectors = 8, .base_vector = 8 }, - }, - }, -}; - +static struct ath12k_pci_driver *ath12k_pci_family_drivers[ATH12K_DEVICE_FAMILY_MAX]; static const struct ath12k_msi_config msi_config_one_msi = { .total_vectors = 1, .total_users = 4, @@ -136,30 +109,6 @@ static const char *irq_name[ATH12K_IRQ_NUM_MAX] = { "tcl2host-status-ring", }; -static int ath12k_pci_bus_wake_up(struct ath12k_base *ab) -{ - struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); - - return mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); -} - -static void ath12k_pci_bus_release(struct ath12k_base *ab) -{ - struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); - - mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); -} - -static const struct ath12k_pci_ops ath12k_pci_ops_qcn9274 = { - .wakeup = NULL, - .release = NULL, -}; - -static const struct ath12k_pci_ops ath12k_pci_ops_wcn7850 = { - .wakeup = ath12k_pci_bus_wake_up, - .release = ath12k_pci_bus_release, -}; - static void ath12k_pci_select_window(struct ath12k_pci *ab_pci, u32 offset) { struct ath12k_base *ab = ab_pci->ab; @@ -1549,28 +1498,34 @@ static const struct ath12k_hif_ops ath12k_pci_hif_ops = { #endif }; -static -void ath12k_pci_read_hw_version(struct ath12k_base *ab, u32 *major, u32 *minor) +static enum ath12k_device_family +ath12k_get_device_family(const struct pci_device_id *pci_dev) { - u32 soc_hw_version; + enum ath12k_device_family device_family_id; + const struct pci_device_id *id; - soc_hw_version = ath12k_pci_read32(ab, TCSR_SOC_HW_VERSION); - *major = FIELD_GET(TCSR_SOC_HW_VERSION_MAJOR_MASK, - soc_hw_version); - *minor = FIELD_GET(TCSR_SOC_HW_VERSION_MINOR_MASK, - soc_hw_version); + for (device_family_id = ATH12K_DEVICE_FAMILY_START; + device_family_id < ATH12K_DEVICE_FAMILY_MAX; device_family_id++) { + if (!ath12k_pci_family_drivers[device_family_id]) + continue; + + id = ath12k_pci_family_drivers[device_family_id]->id_table; + while (id->device) { + if (id->device == pci_dev->device) + return device_family_id; + id += 1; + } + } - ath12k_dbg(ab, ATH12K_DBG_PCI, - "pci tcsr_soc_hw_version major %d minor %d\n", - *major, *minor); + return ATH12K_DEVICE_FAMILY_MAX; } static int ath12k_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_dev) { - struct ath12k_base *ab; + enum ath12k_device_family device_id; struct ath12k_pci *ab_pci; - u32 soc_hw_version_major, soc_hw_version_minor; + struct ath12k_base *ab; int ret; ab = ath12k_core_alloc(&pdev->dev, sizeof(*ab_pci), ATH12K_BUS_PCI); @@ -1605,56 +1560,24 @@ static int ath12k_pci_probe(struct pci_dev *pdev, ab->id.subsystem_vendor = pdev->subsystem_vendor; ab->id.subsystem_device = pdev->subsystem_device; - switch (pci_dev->device) { - case QCN9274_DEVICE_ID: - ab_pci->msi_config = &ath12k_msi_config[0]; - ab->static_window_map = true; - ab_pci->pci_ops = &ath12k_pci_ops_qcn9274; - ab->hal_rx_ops = &hal_rx_qcn9274_ops; - ath12k_pci_read_hw_version(ab, &soc_hw_version_major, - &soc_hw_version_minor); - ab->target_mem_mode = ath12k_core_get_memory_mode(ab); - switch (soc_hw_version_major) { - case ATH12K_PCI_SOC_HW_VERSION_2: - ab->hw_rev = ATH12K_HW_QCN9274_HW20; - break; - case ATH12K_PCI_SOC_HW_VERSION_1: - ab->hw_rev = ATH12K_HW_QCN9274_HW10; - break; - default: - dev_err(&pdev->dev, - "Unknown hardware version found for QCN9274: 0x%x\n", - soc_hw_version_major); - ret = -EOPNOTSUPP; - goto err_pci_free_region; - } - break; - case WCN7850_DEVICE_ID: - ab->id.bdf_search = ATH12K_BDF_SEARCH_BUS_AND_BOARD; - ab_pci->msi_config = &ath12k_msi_config[0]; - ab->static_window_map = false; - ab_pci->pci_ops = &ath12k_pci_ops_wcn7850; - ab->hal_rx_ops = &hal_rx_wcn7850_ops; - ath12k_pci_read_hw_version(ab, &soc_hw_version_major, - &soc_hw_version_minor); - ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT; - switch (soc_hw_version_major) { - case ATH12K_PCI_SOC_HW_VERSION_2: - ab->hw_rev = ATH12K_HW_WCN7850_HW20; - break; - default: - dev_err(&pdev->dev, - "Unknown hardware version found for WCN7850: 0x%x\n", - soc_hw_version_major); - ret = -EOPNOTSUPP; - goto err_pci_free_region; - } - break; + device_id = ath12k_get_device_family(pci_dev); + if (device_id >= ATH12K_DEVICE_FAMILY_MAX) { + ath12k_err(ab, "failed to get device family id\n"); + ret = -EINVAL; + goto err_pci_free_region; + } + + ath12k_dbg(ab, ATH12K_DBG_PCI, "PCI device family id: %d\n", device_id); + + ab_pci->device_family_ops = &ath12k_pci_family_drivers[device_id]->ops; - default: - dev_err(&pdev->dev, "Unknown PCI device found: 0x%x\n", - pci_dev->device); - ret = -EOPNOTSUPP; + /* Call device specific probe. This is the callback that can + * be used to override any ops in future + * probe is validated for NULL during registration. + */ + ret = ab_pci->device_family_ops->probe(pdev, pci_dev); + if (ret) { + ath12k_err(ab, "failed to probe device: %d\n", ret); goto err_pci_free_region; } @@ -1862,32 +1785,43 @@ static const struct dev_pm_ops __maybe_unused ath12k_pci_pm_ops = { ath12k_pci_pm_resume_early) }; -static struct pci_driver ath12k_pci_driver = { - .name = "ath12k_pci", - .id_table = ath12k_pci_id_table, - .probe = ath12k_pci_probe, - .remove = ath12k_pci_remove, - .shutdown = ath12k_pci_shutdown, - .driver.pm = &ath12k_pci_pm_ops, -}; - -int ath12k_pci_init(void) +int ath12k_pci_register_driver(const enum ath12k_device_family device_id, + struct ath12k_pci_driver *driver) { - int ret; + struct pci_driver *pci_driver; - ret = pci_register_driver(&ath12k_pci_driver); - if (ret) { - pr_err("failed to register ath12k pci driver: %d\n", - ret); - return ret; + if (device_id >= ATH12K_DEVICE_FAMILY_MAX) + return -EINVAL; + + if (!driver || !driver->ops.probe) + return -EINVAL; + + if (ath12k_pci_family_drivers[device_id]) { + pr_err("Driver already registered for %d\n", device_id); + return -EALREADY; } - return 0; + ath12k_pci_family_drivers[device_id] = driver; + + pci_driver = &ath12k_pci_family_drivers[device_id]->driver; + pci_driver->name = driver->name; + pci_driver->id_table = driver->id_table; + pci_driver->probe = ath12k_pci_probe; + pci_driver->remove = ath12k_pci_remove; + pci_driver->shutdown = ath12k_pci_shutdown; + pci_driver->driver.pm = &ath12k_pci_pm_ops; + + return pci_register_driver(pci_driver); } -void ath12k_pci_exit(void) +void ath12k_pci_unregister_driver(const enum ath12k_device_family device_id) { - pci_unregister_driver(&ath12k_pci_driver); + if (device_id >= ATH12K_DEVICE_FAMILY_MAX || + !ath12k_pci_family_drivers[device_id]) + return; + + pci_unregister_driver(&ath12k_pci_family_drivers[device_id]->driver); + ath12k_pci_family_drivers[device_id] = NULL; } /* firmware files */ diff --git a/drivers/net/wireless/ath/ath12k/pci.h b/drivers/net/wireless/ath/ath12k/pci.h index d1ec8aad7f6c3..1b7ecc329a017 100644 --- a/drivers/net/wireless/ath/ath12k/pci.h +++ b/drivers/net/wireless/ath/ath12k/pci.h @@ -7,6 +7,7 @@ #define ATH12K_PCI_H #include +#include #include "core.h" @@ -70,9 +71,6 @@ #define QRTR_PCI_DOMAIN_NR_MASK GENMASK(7, 4) #define QRTR_PCI_BUS_NUMBER_MASK GENMASK(3, 0) -#define ATH12K_PCI_SOC_HW_VERSION_1 1 -#define ATH12K_PCI_SOC_HW_VERSION_2 2 - struct ath12k_msi_user { const char *name; int num_vectors; @@ -97,6 +95,10 @@ struct ath12k_pci_ops { void (*release)(struct ath12k_base *ab); }; +struct ath12k_pci_device_family_ops { + int (*probe)(struct pci_dev *pdev, const struct pci_device_id *pci_dev); +}; + struct ath12k_pci { struct pci_dev *pdev; struct ath12k_base *ab; @@ -119,6 +121,14 @@ struct ath12k_pci { const struct ath12k_pci_ops *pci_ops; u32 qmi_instance; u64 dma_mask; + const struct ath12k_pci_device_family_ops *device_family_ops; +}; + +struct ath12k_pci_driver { + const char *name; + const struct pci_device_id *id_table; + struct ath12k_pci_device_family_ops ops; + struct pci_driver driver; }; static inline struct ath12k_pci *ath12k_pci_priv(struct ath12k_base *ab) @@ -148,6 +158,7 @@ void ath12k_pci_stop(struct ath12k_base *ab); int ath12k_pci_start(struct ath12k_base *ab); int ath12k_pci_power_up(struct ath12k_base *ab); void ath12k_pci_power_down(struct ath12k_base *ab, bool is_suspend); -int ath12k_pci_init(void); -void ath12k_pci_exit(void); +int ath12k_pci_register_driver(const enum ath12k_device_family device_id, + struct ath12k_pci_driver *driver); +void ath12k_pci_unregister_driver(const enum ath12k_device_family device_id); #endif /* ATH12K_PCI_H */ diff --git a/drivers/net/wireless/ath/ath12k/pci_wifi7.c b/drivers/net/wireless/ath/ath12k/pci_wifi7.c new file mode 100644 index 0000000000000..8c7718153534c --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/pci_wifi7.c @@ -0,0 +1,173 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include + +#include "pci.h" +#include "pci_wifi7.h" +#include "core.h" +#include "hif.h" +#include "mhi.h" + +#define QCN9274_DEVICE_ID 0x1109 +#define WCN7850_DEVICE_ID 0x1107 + +#define ATH12K_PCI_W7_SOC_HW_VERSION_1 1 +#define ATH12K_PCI_W7_SOC_HW_VERSION_2 2 + +#define TCSR_SOC_HW_VERSION 0x1B00000 +#define TCSR_SOC_HW_VERSION_MAJOR_MASK GENMASK(11, 8) +#define TCSR_SOC_HW_VERSION_MINOR_MASK GENMASK(7, 4) + +static const struct pci_device_id ath12k_wifi7_pci_id_table[] = { + { PCI_VDEVICE(QCOM, QCN9274_DEVICE_ID) }, + { PCI_VDEVICE(QCOM, WCN7850_DEVICE_ID) }, + {} +}; + +MODULE_DEVICE_TABLE(pci, ath12k_wifi7_pci_id_table); + +/* TODO: revisit IRQ mapping for new SRNG's */ +static const struct ath12k_msi_config ath12k_wifi7_msi_config[] = { + { + .total_vectors = 16, + .total_users = 3, + .users = (struct ath12k_msi_user[]) { + { .name = "MHI", .num_vectors = 3, .base_vector = 0 }, + { .name = "CE", .num_vectors = 5, .base_vector = 3 }, + { .name = "DP", .num_vectors = 8, .base_vector = 8 }, + }, + }, +}; + +static const struct ath12k_pci_ops ath12k_pci_ops_qcn9274 = { + .wakeup = NULL, + .release = NULL, +}; + +static int ath12k_wifi7_pci_bus_wake_up(struct ath12k_base *ab) +{ + struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); + + return mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); +} + +static void ath12k_wifi7_pci_bus_release(struct ath12k_base *ab) +{ + struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); + + mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); +} + +static const struct ath12k_pci_ops ath12k_pci_ops_wcn7850 = { + .wakeup = ath12k_wifi7_pci_bus_wake_up, + .release = ath12k_wifi7_pci_bus_release, +}; + +static +void ath12k_wifi7_pci_read_hw_version(struct ath12k_base *ab, + u32 *major, u32 *minor) +{ + u32 soc_hw_version; + + soc_hw_version = ath12k_pci_read32(ab, TCSR_SOC_HW_VERSION); + *major = u32_get_bits(soc_hw_version, TCSR_SOC_HW_VERSION_MAJOR_MASK); + *minor = u32_get_bits(soc_hw_version, TCSR_SOC_HW_VERSION_MINOR_MASK); +} + +static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *pci_dev) +{ + u32 soc_hw_version_major, soc_hw_version_minor; + struct ath12k_pci *ab_pci; + struct ath12k_base *ab; + + ab = pci_get_drvdata(pdev); + if (!ab) + return -EINVAL; + + ab_pci = ath12k_pci_priv(ab); + if (!ab_pci) + return -EINVAL; + + switch (pci_dev->device) { + case QCN9274_DEVICE_ID: + ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; + ab->static_window_map = true; + ab_pci->pci_ops = &ath12k_pci_ops_qcn9274; + ab->hal_rx_ops = &hal_rx_qcn9274_ops; + ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major, + &soc_hw_version_minor); + ab->target_mem_mode = ath12k_core_get_memory_mode(ab); + switch (soc_hw_version_major) { + case ATH12K_PCI_W7_SOC_HW_VERSION_2: + ab->hw_rev = ATH12K_HW_QCN9274_HW20; + break; + case ATH12K_PCI_W7_SOC_HW_VERSION_1: + ab->hw_rev = ATH12K_HW_QCN9274_HW10; + break; + default: + dev_err(&pdev->dev, + "Unknown hardware version found for QCN9274: 0x%x\n", + soc_hw_version_major); + return -EOPNOTSUPP; + } + break; + case WCN7850_DEVICE_ID: + ab->id.bdf_search = ATH12K_BDF_SEARCH_BUS_AND_BOARD; + ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; + ab->static_window_map = false; + ab_pci->pci_ops = &ath12k_pci_ops_wcn7850; + ab->hal_rx_ops = &hal_rx_wcn7850_ops; + ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major, + &soc_hw_version_minor); + ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT; + switch (soc_hw_version_major) { + case ATH12K_PCI_W7_SOC_HW_VERSION_2: + ab->hw_rev = ATH12K_HW_WCN7850_HW20; + break; + default: + dev_err(&pdev->dev, + "Unknown hardware version found for WCN7850: 0x%x\n", + soc_hw_version_major); + return -EOPNOTSUPP; + } + break; + + default: + dev_err(&pdev->dev, "Unknown Wi-Fi 7 PCI device found: 0x%x\n", + pci_dev->device); + return -EOPNOTSUPP; + } + + return 0; +} + +static struct ath12k_pci_driver ath12k_pci_wifi7_driver = { + .name = "ath12k_wifi7_pci", + .id_table = ath12k_wifi7_pci_id_table, + .ops.probe = ath12k_wifi7_pci_probe, +}; + +int ath12k_wifi7_pci_init(void) +{ + int ret; + + ret = ath12k_pci_register_driver(ATH12K_DEVICE_FAMILY_WIFI7, + &ath12k_pci_wifi7_driver); + if (ret) { + pr_err("Failed to register ath12k Wi-Fi 7 driver: %d\n", + ret); + return ret; + } + + return 0; +} + +void ath12k_wifi7_pci_exit(void) +{ + ath12k_pci_unregister_driver(ATH12K_DEVICE_FAMILY_WIFI7); +} diff --git a/drivers/net/wireless/ath/ath12k/pci_wifi7.h b/drivers/net/wireless/ath/ath12k/pci_wifi7.h new file mode 100644 index 0000000000000..662a8bab0ce7f --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/pci_wifi7.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#ifndef ATH12K_PCI_WIFI7_H +#define ATH12K_PCI_WIFI7_H + +int ath12k_wifi7_pci_init(void); +void ath12k_wifi7_pci_exit(void); + +#endif /* ATH12K_PCI_WIFI7_H */ From e8725be7367f4d9fb110311e85a806939df4ccbf Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:28 +0530 Subject: [PATCH 002/140] wifi: ath12k: Move Copy Engine configuration to Wi-Fi 7 specific file Relocate Copy Engine (CE) assignment logic from ce.c to a new ce_wifi7.c file to consolidate Wi-Fi 7 specific CE configuration in one place. Move CE service map and target configuration from hw.c to ce_wifi7.c. This reorganization improves code clarity and modularity by isolating device-specific logic. It is part of a broader effort to separate common and hardware-specific code into distinct modules. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-2-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/ce.c | 301 ------- drivers/net/wireless/ath/ath12k/ce.h | 4 - drivers/net/wireless/ath/ath12k/ce_wifi7.c | 970 +++++++++++++++++++++ drivers/net/wireless/ath/ath12k/ce_wifi7.h | 22 + drivers/net/wireless/ath/ath12k/hw.c | 629 +------------ 6 files changed, 994 insertions(+), 933 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/ce_wifi7.c create mode 100644 drivers/net/wireless/ath/ath12k/ce_wifi7.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index 1a26e00627b0a..e4776887c939a 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -14,6 +14,7 @@ ath12k-y += core.o \ dp_rx.o \ debug.o \ ce.o \ + ce_wifi7.o \ peer.o \ dbring.o \ hw.o \ diff --git a/drivers/net/wireless/ath/ath12k/ce.c b/drivers/net/wireless/ath/ath12k/ce.c index 9a63608838ace..7b8abc13a5e1c 100644 --- a/drivers/net/wireless/ath/ath12k/ce.c +++ b/drivers/net/wireless/ath/ath12k/ce.c @@ -8,307 +8,6 @@ #include "debug.h" #include "hif.h" -const struct ce_attr ath12k_host_ce_config_qcn9274[] = { - /* CE0: host->target HTC control and raw streams */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 16, - .src_sz_max = 2048, - .dest_nentries = 0, - }, - - /* CE1: target->host HTT + HTC control */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 512, - .recv_cb = ath12k_htc_rx_completion_handler, - }, - - /* CE2: target->host WMI */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 128, - .recv_cb = ath12k_htc_rx_completion_handler, - }, - - /* CE3: host->target WMI (mac0) */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 32, - .src_sz_max = 2048, - .dest_nentries = 0, - }, - - /* CE4: host->target HTT */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 2048, - .src_sz_max = 256, - .dest_nentries = 0, - }, - - /* CE5: target->host pktlog */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 512, - .recv_cb = ath12k_dp_htt_htc_t2h_msg_handler, - }, - - /* CE6: target autonomous hif_memcpy */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE7: host->target WMI (mac1) */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 32, - .src_sz_max = 2048, - .dest_nentries = 0, - }, - - /* CE8: target autonomous hif_memcpy */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE9: MHI */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE10: MHI */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE11: MHI */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE12: CV Prefetch */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE13: CV Prefetch */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE14: target->host dbg log */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 512, - .recv_cb = ath12k_htc_rx_completion_handler, - }, - - /* CE15: reserved for future use */ - { - .flags = (CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, -}; - -const struct ce_attr ath12k_host_ce_config_wcn7850[] = { - /* CE0: host->target HTC control and raw streams */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 16, - .src_sz_max = 2048, - .dest_nentries = 0, - }, - - /* CE1: target->host HTT + HTC control */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 512, - .recv_cb = ath12k_htc_rx_completion_handler, - }, - - /* CE2: target->host WMI */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 64, - .recv_cb = ath12k_htc_rx_completion_handler, - }, - - /* CE3: host->target WMI (mac0) */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 32, - .src_sz_max = 2048, - .dest_nentries = 0, - }, - - /* CE4: host->target HTT */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 2048, - .src_sz_max = 256, - .dest_nentries = 0, - }, - - /* CE5: target->host pktlog */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE6: target autonomous hif_memcpy */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE7: host->target WMI (mac1) */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 0, - }, - - /* CE8: target autonomous hif_memcpy */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - -}; - -const struct ce_attr ath12k_host_ce_config_ipq5332[] = { - /* CE0: host->target HTC control and raw streams */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 16, - .src_sz_max = 2048, - .dest_nentries = 0, - }, - /* CE1: target->host HTT + HTC control */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 512, - .recv_cb = ath12k_htc_rx_completion_handler, - }, - /* CE2: target->host WMI */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 128, - .recv_cb = ath12k_htc_rx_completion_handler, - }, - /* CE3: host->target WMI */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 32, - .src_sz_max = 2048, - .dest_nentries = 0, - }, - /* CE4: host->target HTT */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 2048, - .src_sz_max = 256, - .dest_nentries = 0, - }, - /* CE5: target -> host PKTLOG */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 512, - .recv_cb = ath12k_dp_htt_htc_t2h_msg_handler, - }, - /* CE6: Target autonomous HIF_memcpy */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - /* CE7: CV Prefetch */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - /* CE8: Target HIF memcpy (Generic HIF memcypy) */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - /* CE9: WMI logging/CFR/Spectral/Radar */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 128, - }, - /* CE10: Unused */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - /* CE11: Unused */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, -}; - static int ath12k_ce_rx_buf_enqueue_pipe(struct ath12k_ce_pipe *pipe, struct sk_buff *skb, dma_addr_t paddr) { diff --git a/drivers/net/wireless/ath/ath12k/ce.h b/drivers/net/wireless/ath/ath12k/ce.h index 57f75899ee03d..f44ce2244bcfd 100644 --- a/drivers/net/wireless/ath/ath12k/ce.h +++ b/drivers/net/wireless/ath/ath12k/ce.h @@ -173,10 +173,6 @@ struct ath12k_ce { struct ath12k_hp_update_timer hp_timer[CE_COUNT_MAX]; }; -extern const struct ce_attr ath12k_host_ce_config_qcn9274[]; -extern const struct ce_attr ath12k_host_ce_config_wcn7850[]; -extern const struct ce_attr ath12k_host_ce_config_ipq5332[]; - void ath12k_ce_cleanup_pipes(struct ath12k_base *ab); void ath12k_ce_rx_replenish_retry(struct timer_list *t); void ath12k_ce_per_engine_service(struct ath12k_base *ab, u16 ce_id); diff --git a/drivers/net/wireless/ath/ath12k/ce_wifi7.c b/drivers/net/wireless/ath/ath12k/ce_wifi7.c new file mode 100644 index 0000000000000..cf27259d15a0e --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/ce_wifi7.c @@ -0,0 +1,970 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include + +#include "core.h" +#include "ce.h" +#include "ce_wifi7.h" +#include "dp_rx.h" + +/* Copy Engine (CE) configs for QCN9274 */ +/* Target firmware's Copy Engine configuration. */ +const struct ce_pipe_config ath12k_target_ce_config_wlan_qcn9274[] = { + /* CE0: host->target HTC control and raw streams */ + { + .pipenum = __cpu_to_le32(0), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE1: target->host HTT + HTC control */ + { + .pipenum = __cpu_to_le32(1), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE2: target->host WMI */ + { + .pipenum = __cpu_to_le32(2), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE3: host->target WMI (mac0) */ + { + .pipenum = __cpu_to_le32(3), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE4: host->target HTT */ + { + .pipenum = __cpu_to_le32(4), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(256), + .nbytes_max = __cpu_to_le32(256), + .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), + .reserved = __cpu_to_le32(0), + }, + + /* CE5: target->host Pktlog */ + { + .pipenum = __cpu_to_le32(5), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE6: Reserved for target autonomous hif_memcpy */ + { + .pipenum = __cpu_to_le32(6), + .pipedir = __cpu_to_le32(PIPEDIR_INOUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(16384), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE7: host->target WMI (mac1) */ + { + .pipenum = __cpu_to_le32(7), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE8: Reserved for target autonomous hif_memcpy */ + { + .pipenum = __cpu_to_le32(8), + .pipedir = __cpu_to_le32(PIPEDIR_INOUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(16384), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE9, 10 and 11: Reserved for MHI */ + + /* CE12: Target CV prefetch */ + { + .pipenum = __cpu_to_le32(12), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE13: Target CV prefetch */ + { + .pipenum = __cpu_to_le32(13), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE14: WMI logging/CFR/Spectral/Radar */ + { + .pipenum = __cpu_to_le32(14), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE15: Reserved */ +}; + +/* Map from service/endpoint to Copy Engine. + * This table is derived from the CE_PCI TABLE, above. + * It is passed to the Target at startup for use by firmware. + * Pipe direction: + * PIPEDIR_OUT = UL = host -> target + * PIPEDIR_IN = DL = target -> host + */ +const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_qcn9274[] = { + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(0), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(1), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_TEST_RAW_STREAMS), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(0), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_TEST_RAW_STREAMS), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(1), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(4), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(1), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_MAC1), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(7), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_MAC1), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_PKT_LOG), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(5), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_DIAG), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(14), + }, + + /* (Additions here) */ + + { /* must be last */ + __cpu_to_le32(0), + __cpu_to_le32(0), + __cpu_to_le32(0), + }, +}; + +const struct ce_attr ath12k_host_ce_config_qcn9274[] = { + /* CE0: host->target HTC control and raw streams */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 16, + .src_sz_max = 2048, + .dest_nentries = 0, + }, + + /* CE1: target->host HTT + HTC control */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 512, + .recv_cb = ath12k_htc_rx_completion_handler, + }, + + /* CE2: target->host WMI */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 128, + .recv_cb = ath12k_htc_rx_completion_handler, + }, + + /* CE3: host->target WMI (mac0) */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 32, + .src_sz_max = 2048, + .dest_nentries = 0, + }, + + /* CE4: host->target HTT */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 2048, + .src_sz_max = 256, + .dest_nentries = 0, + }, + + /* CE5: target->host pktlog */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 512, + .recv_cb = ath12k_dp_htt_htc_t2h_msg_handler, + }, + + /* CE6: target autonomous hif_memcpy */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE7: host->target WMI (mac1) */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 32, + .src_sz_max = 2048, + .dest_nentries = 0, + }, + + /* CE8: target autonomous hif_memcpy */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE9: MHI */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE10: MHI */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE11: MHI */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE12: CV Prefetch */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE13: CV Prefetch */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE14: target->host dbg log */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 512, + .recv_cb = ath12k_htc_rx_completion_handler, + }, + + /* CE15: reserved for future use */ + { + .flags = (CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, +}; + +/* Copy Engine (CE) configs for WCN7850 */ +/* Target firmware's Copy Engine configuration. */ +const struct ce_pipe_config ath12k_target_ce_config_wlan_wcn7850[] = { + /* CE0: host->target HTC control and raw streams */ + { + .pipenum = __cpu_to_le32(0), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE1: target->host HTT + HTC control */ + { + .pipenum = __cpu_to_le32(1), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE2: target->host WMI */ + { + .pipenum = __cpu_to_le32(2), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE3: host->target WMI */ + { + .pipenum = __cpu_to_le32(3), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE4: host->target HTT */ + { + .pipenum = __cpu_to_le32(4), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(256), + .nbytes_max = __cpu_to_le32(256), + .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), + .reserved = __cpu_to_le32(0), + }, + + /* CE5: target->host Pktlog */ + { + .pipenum = __cpu_to_le32(5), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE6: Reserved for target autonomous hif_memcpy */ + { + .pipenum = __cpu_to_le32(6), + .pipedir = __cpu_to_le32(PIPEDIR_INOUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(16384), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE7 used only by Host */ + { + .pipenum = __cpu_to_le32(7), + .pipedir = __cpu_to_le32(PIPEDIR_INOUT_H2H), + .nentries = __cpu_to_le32(0), + .nbytes_max = __cpu_to_le32(0), + .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), + .reserved = __cpu_to_le32(0), + }, + + /* CE8 target->host used only by IPA */ + { + .pipenum = __cpu_to_le32(8), + .pipedir = __cpu_to_le32(PIPEDIR_INOUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(16384), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + /* CE 9, 10, 11 are used by MHI driver */ +}; + +const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_wcn7850[] = { + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(0), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(4), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(1), + }, + + /* (Additions here) */ + + { /* must be last */ + __cpu_to_le32(0), + __cpu_to_le32(0), + __cpu_to_le32(0), + }, +}; + +const struct ce_attr ath12k_host_ce_config_wcn7850[] = { + /* CE0: host->target HTC control and raw streams */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 16, + .src_sz_max = 2048, + .dest_nentries = 0, + }, + + /* CE1: target->host HTT + HTC control */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 512, + .recv_cb = ath12k_htc_rx_completion_handler, + }, + + /* CE2: target->host WMI */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 64, + .recv_cb = ath12k_htc_rx_completion_handler, + }, + + /* CE3: host->target WMI (mac0) */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 32, + .src_sz_max = 2048, + .dest_nentries = 0, + }, + + /* CE4: host->target HTT */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 2048, + .src_sz_max = 256, + .dest_nentries = 0, + }, + + /* CE5: target->host pktlog */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE6: target autonomous hif_memcpy */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE7: host->target WMI (mac1) */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 0, + }, + + /* CE8: target autonomous hif_memcpy */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, +}; + +/* Copy Engine (CE) configs for IPQ5332 */ +/* Target firmware's Copy Engine configuration. */ +const struct ce_pipe_config ath12k_target_ce_config_wlan_ipq5332[] = { + /* CE0: host->target HTC control and raw streams */ + { + .pipenum = __cpu_to_le32(0), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE1: target->host HTT */ + { + .pipenum = __cpu_to_le32(1), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE2: target->host WMI + HTC control */ + { + .pipenum = __cpu_to_le32(2), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE3: host->target WMI */ + { + .pipenum = __cpu_to_le32(3), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE4: host->target HTT */ + { + .pipenum = __cpu_to_le32(4), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(256), + .nbytes_max = __cpu_to_le32(256), + .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), + .reserved = __cpu_to_le32(0), + }, + + /* CE5: Target -> host PKTLOG */ + { + .pipenum = __cpu_to_le32(5), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE6: Reserved for target autonomous HIF_memcpy */ + { + .pipenum = __cpu_to_le32(6), + .pipedir = __cpu_to_le32(PIPEDIR_INOUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(16384), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE7: Reserved for CV Prefetch */ + { + .pipenum = __cpu_to_le32(7), + .pipedir = __cpu_to_le32(PIPEDIR_OUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE8: Reserved for target generic HIF memcpy */ + { + .pipenum = __cpu_to_le32(8), + .pipedir = __cpu_to_le32(PIPEDIR_INOUT), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(16384), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE9: WMI logging/CFR/Spectral/Radar/ */ + { + .pipenum = __cpu_to_le32(9), + .pipedir = __cpu_to_le32(PIPEDIR_IN), + .nentries = __cpu_to_le32(32), + .nbytes_max = __cpu_to_le32(2048), + .flags = __cpu_to_le32(CE_ATTR_FLAGS), + .reserved = __cpu_to_le32(0), + }, + + /* CE10: Unused TBD */ + { + .pipenum = __cpu_to_le32(10), + .pipedir = __cpu_to_le32(PIPEDIR_NONE), + .nentries = __cpu_to_le32(0), + .nbytes_max = __cpu_to_le32(0), + .flags = __cpu_to_le32(0), + .reserved = __cpu_to_le32(0), + }, + /* CE11: Unused TBD */ + { + .pipenum = __cpu_to_le32(11), + .pipedir = __cpu_to_le32(PIPEDIR_NONE), + .nentries = __cpu_to_le32(0), + .nbytes_max = __cpu_to_le32(0), + .flags = __cpu_to_le32(0), + .reserved = __cpu_to_le32(0), + }, +}; + +const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_ipq5332[] = { + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(3), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(2), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(0), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(1), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_TEST_RAW_STREAMS), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(0), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_TEST_RAW_STREAMS), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(1), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), + __cpu_to_le32(PIPEDIR_OUT), + __cpu_to_le32(4), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(1), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_PKT_LOG), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(5), + }, + { + __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_DIAG), + __cpu_to_le32(PIPEDIR_IN), + __cpu_to_le32(9), + }, + /* (Additions here) */ + + { /* must be last */ + __cpu_to_le32(0), + __cpu_to_le32(0), + __cpu_to_le32(0), + }, +}; + +const struct ce_attr ath12k_host_ce_config_ipq5332[] = { + /* CE0: host->target HTC control and raw streams */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 16, + .src_sz_max = 2048, + .dest_nentries = 0, + }, + + /* CE1: target->host HTT + HTC control */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 512, + .recv_cb = ath12k_htc_rx_completion_handler, + }, + + /* CE2: target->host WMI */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 128, + .recv_cb = ath12k_htc_rx_completion_handler, + }, + + /* CE3: host->target WMI */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 32, + .src_sz_max = 2048, + .dest_nentries = 0, + }, + + /* CE4: host->target HTT */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 2048, + .src_sz_max = 256, + .dest_nentries = 0, + }, + + /* CE5: target -> host PKTLOG */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 512, + .recv_cb = ath12k_dp_htt_htc_t2h_msg_handler, + }, + + /* CE6: Target autonomous HIF_memcpy */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE7: CV Prefetch */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE8: Target HIF memcpy (Generic HIF memcypy) */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE9: WMI logging/CFR/Spectral/Radar */ + { + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, + .dest_nentries = 128, + }, + + /* CE10: Unused */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, + + /* CE11: Unused */ + { + .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, + .src_nentries = 0, + .src_sz_max = 0, + .dest_nentries = 0, + }, +}; diff --git a/drivers/net/wireless/ath/ath12k/ce_wifi7.h b/drivers/net/wireless/ath/ath12k/ce_wifi7.h new file mode 100644 index 0000000000000..1e211e8c24672 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/ce_wifi7.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_WIFI7_CE_H +#define ATH12K_WIFI7_CE_H + +extern const struct ce_pipe_config ath12k_target_ce_config_wlan_qcn9274[]; +extern const struct ce_pipe_config ath12k_target_ce_config_wlan_wcn7850[]; +extern const struct ce_pipe_config ath12k_target_ce_config_wlan_ipq5332[]; + +extern const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_qcn9274[]; +extern const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_wcn7850[]; +extern const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_ipq5332[]; + +extern const struct ce_attr ath12k_host_ce_config_qcn9274[]; +extern const struct ce_attr ath12k_host_ce_config_wcn7850[]; +extern const struct ce_attr ath12k_host_ce_config_ipq5332[]; + +#endif /* ATH12K_WIFI7_CE_H */ diff --git a/drivers/net/wireless/ath/ath12k/hw.c b/drivers/net/wireless/ath/ath12k/hw.c index 6791ae1d64e50..dd60e27cc4996 100644 --- a/drivers/net/wireless/ath/ath12k/hw.c +++ b/drivers/net/wireless/ath/ath12k/hw.c @@ -11,6 +11,7 @@ #include "debug.h" #include "core.h" #include "ce.h" +#include "ce_wifi7.h" #include "hw.h" #include "mhi.h" #include "dp_rx.h" @@ -177,634 +178,6 @@ static const struct ath12k_hw_ops wcn7850_ops = { #define ATH12K_RX_MON_STATUS_RING_MASK_1 0x2 #define ATH12K_RX_MON_STATUS_RING_MASK_2 0x4 -/* Target firmware's Copy Engine configuration. */ -static const struct ce_pipe_config ath12k_target_ce_config_wlan_qcn9274[] = { - /* CE0: host->target HTC control and raw streams */ - { - .pipenum = __cpu_to_le32(0), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE1: target->host HTT + HTC control */ - { - .pipenum = __cpu_to_le32(1), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE2: target->host WMI */ - { - .pipenum = __cpu_to_le32(2), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE3: host->target WMI (mac0) */ - { - .pipenum = __cpu_to_le32(3), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE4: host->target HTT */ - { - .pipenum = __cpu_to_le32(4), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(256), - .nbytes_max = __cpu_to_le32(256), - .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), - .reserved = __cpu_to_le32(0), - }, - - /* CE5: target->host Pktlog */ - { - .pipenum = __cpu_to_le32(5), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE6: Reserved for target autonomous hif_memcpy */ - { - .pipenum = __cpu_to_le32(6), - .pipedir = __cpu_to_le32(PIPEDIR_INOUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(16384), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE7: host->target WMI (mac1) */ - { - .pipenum = __cpu_to_le32(7), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE8: Reserved for target autonomous hif_memcpy */ - { - .pipenum = __cpu_to_le32(8), - .pipedir = __cpu_to_le32(PIPEDIR_INOUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(16384), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE9, 10 and 11: Reserved for MHI */ - - /* CE12: Target CV prefetch */ - { - .pipenum = __cpu_to_le32(12), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE13: Target CV prefetch */ - { - .pipenum = __cpu_to_le32(13), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE14: WMI logging/CFR/Spectral/Radar */ - { - .pipenum = __cpu_to_le32(14), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE15: Reserved */ -}; - -/* Target firmware's Copy Engine configuration. */ -static const struct ce_pipe_config ath12k_target_ce_config_wlan_wcn7850[] = { - /* CE0: host->target HTC control and raw streams */ - { - .pipenum = __cpu_to_le32(0), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE1: target->host HTT + HTC control */ - { - .pipenum = __cpu_to_le32(1), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE2: target->host WMI */ - { - .pipenum = __cpu_to_le32(2), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE3: host->target WMI */ - { - .pipenum = __cpu_to_le32(3), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE4: host->target HTT */ - { - .pipenum = __cpu_to_le32(4), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(256), - .nbytes_max = __cpu_to_le32(256), - .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), - .reserved = __cpu_to_le32(0), - }, - - /* CE5: target->host Pktlog */ - { - .pipenum = __cpu_to_le32(5), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE6: Reserved for target autonomous hif_memcpy */ - { - .pipenum = __cpu_to_le32(6), - .pipedir = __cpu_to_le32(PIPEDIR_INOUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(16384), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - - /* CE7 used only by Host */ - { - .pipenum = __cpu_to_le32(7), - .pipedir = __cpu_to_le32(PIPEDIR_INOUT_H2H), - .nentries = __cpu_to_le32(0), - .nbytes_max = __cpu_to_le32(0), - .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), - .reserved = __cpu_to_le32(0), - }, - - /* CE8 target->host used only by IPA */ - { - .pipenum = __cpu_to_le32(8), - .pipedir = __cpu_to_le32(PIPEDIR_INOUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(16384), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* CE 9, 10, 11 are used by MHI driver */ -}; - -/* Map from service/endpoint to Copy Engine. - * This table is derived from the CE_PCI TABLE, above. - * It is passed to the Target at startup for use by firmware. - */ -static const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_qcn9274[] = { - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(0), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(1), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_TEST_RAW_STREAMS), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(0), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_TEST_RAW_STREAMS), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(1), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(4), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(1), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_MAC1), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(7), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_MAC1), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_PKT_LOG), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(5), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_DIAG), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(14), - }, - - /* (Additions here) */ - - { /* must be last */ - __cpu_to_le32(0), - __cpu_to_le32(0), - __cpu_to_le32(0), - }, -}; - -static const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_wcn7850[] = { - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(0), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), - __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ - __cpu_to_le32(4), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), - __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ - __cpu_to_le32(1), - }, - - /* (Additions here) */ - - { /* must be last */ - __cpu_to_le32(0), - __cpu_to_le32(0), - __cpu_to_le32(0), - }, -}; - -static const struct ce_pipe_config ath12k_target_ce_config_wlan_ipq5332[] = { - /* host->target HTC control and raw streams */ - { - .pipenum = __cpu_to_le32(0), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* target->host HTT */ - { - .pipenum = __cpu_to_le32(1), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* target->host WMI + HTC control */ - { - .pipenum = __cpu_to_le32(2), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* host->target WMI */ - { - .pipenum = __cpu_to_le32(3), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* host->target HTT */ - { - .pipenum = __cpu_to_le32(4), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(256), - .nbytes_max = __cpu_to_le32(256), - .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), - .reserved = __cpu_to_le32(0), - }, - /* Target -> host PKTLOG */ - { - .pipenum = __cpu_to_le32(5), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* Reserved for target autonomous HIF_memcpy */ - { - .pipenum = __cpu_to_le32(6), - .pipedir = __cpu_to_le32(PIPEDIR_INOUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(16384), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* CE7 Reserved for CV Prefetch */ - { - .pipenum = __cpu_to_le32(7), - .pipedir = __cpu_to_le32(PIPEDIR_OUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* CE8 Reserved for target generic HIF memcpy */ - { - .pipenum = __cpu_to_le32(8), - .pipedir = __cpu_to_le32(PIPEDIR_INOUT), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(16384), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* CE9 WMI logging/CFR/Spectral/Radar/ */ - { - .pipenum = __cpu_to_le32(9), - .pipedir = __cpu_to_le32(PIPEDIR_IN), - .nentries = __cpu_to_le32(32), - .nbytes_max = __cpu_to_le32(2048), - .flags = __cpu_to_le32(CE_ATTR_FLAGS), - .reserved = __cpu_to_le32(0), - }, - /* Unused TBD */ - { - .pipenum = __cpu_to_le32(10), - .pipedir = __cpu_to_le32(PIPEDIR_NONE), - .nentries = __cpu_to_le32(0), - .nbytes_max = __cpu_to_le32(0), - .flags = __cpu_to_le32(0), - .reserved = __cpu_to_le32(0), - }, - /* Unused TBD */ - { - .pipenum = __cpu_to_le32(11), - .pipedir = __cpu_to_le32(PIPEDIR_NONE), - .nentries = __cpu_to_le32(0), - .nbytes_max = __cpu_to_le32(0), - .flags = __cpu_to_le32(0), - .reserved = __cpu_to_le32(0), - }, -}; - -static const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_ipq5332[] = { - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), - __cpu_to_le32(PIPEDIR_OUT), - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), - __cpu_to_le32(PIPEDIR_OUT), - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BK), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), - __cpu_to_le32(PIPEDIR_OUT), - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_BE), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), - __cpu_to_le32(PIPEDIR_OUT), - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VI), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), - __cpu_to_le32(PIPEDIR_OUT), - __cpu_to_le32(3), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(2), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), - __cpu_to_le32(PIPEDIR_OUT), - __cpu_to_le32(0), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_RSVD_CTRL), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(1), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_TEST_RAW_STREAMS), - __cpu_to_le32(PIPEDIR_OUT), - __cpu_to_le32(0), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_TEST_RAW_STREAMS), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(1), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), - __cpu_to_le32(PIPEDIR_OUT), - __cpu_to_le32(4), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_HTT_DATA_MSG), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(1), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_PKT_LOG), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(5), - }, - { - __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_CONTROL_DIAG), - __cpu_to_le32(PIPEDIR_IN), - __cpu_to_le32(9), - }, - /* (Additions here) */ - - { /* must be last */ - __cpu_to_le32(0), - __cpu_to_le32(0), - __cpu_to_le32(0), - }, -}; - static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qcn9274 = { .tx = { ATH12K_TX_RING_MASK_0, From fbd8a6ed72d1ccbe6ecb99b0843d558e6ac30605 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:29 +0530 Subject: [PATCH 003/140] wifi: ath12k: Move Wi-Fi 7 WMI configuration to dedicated file Relocate Wi-Fi 7 specific WMI configuration from shared codebase to a new target-specific file. Isolate WMI settings per target to improve modularity and maintainability. This change is part of a broader effort to separate hardware-dependent logic into standalone modules, paving the way for cleaner support of multiple hardware families Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-3-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/hw.c | 1 + drivers/net/wireless/ath/ath12k/wmi.c | 97 ------------------ drivers/net/wireless/ath/ath12k/wmi.h | 4 - drivers/net/wireless/ath/ath12k/wmi_wifi7.c | 105 ++++++++++++++++++++ drivers/net/wireless/ath/ath12k/wmi_wifi7.h | 15 +++ 6 files changed, 122 insertions(+), 101 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/wmi_wifi7.c create mode 100644 drivers/net/wireless/ath/ath12k/wmi_wifi7.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index e4776887c939a..ee075ee68bb83 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -5,6 +5,7 @@ ath12k-y += core.o \ hal_tx.o \ hal_rx.o \ wmi.o \ + wmi_wifi7.o \ mac.o \ reg.o \ htc.o \ diff --git a/drivers/net/wireless/ath/ath12k/hw.c b/drivers/net/wireless/ath/ath12k/hw.c index dd60e27cc4996..df1b4439adc79 100644 --- a/drivers/net/wireless/ath/ath12k/hw.c +++ b/drivers/net/wireless/ath/ath12k/hw.c @@ -16,6 +16,7 @@ #include "mhi.h" #include "dp_rx.h" #include "peer.h" +#include "wmi_wifi7.h" static const guid_t wcn7850_uuid = GUID_INIT(0xf634f534, 0x6147, 0x11ec, 0x90, 0xd6, 0x02, 0x42, diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index be8b2943094f8..e87f1f8b95b94 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -206,103 +206,6 @@ static __le32 ath12k_wmi_tlv_cmd_hdr(u32 cmd, u32 len) return ath12k_wmi_tlv_hdr(cmd, len - TLV_HDR_SIZE); } -void ath12k_wmi_init_qcn9274(struct ath12k_base *ab, - struct ath12k_wmi_resource_config_arg *config) -{ - config->num_vdevs = ab->num_radios * TARGET_NUM_VDEVS(ab); - config->num_peers = ab->num_radios * - ath12k_core_get_max_peers_per_radio(ab); - config->num_offload_peers = TARGET_NUM_OFFLD_PEERS; - config->num_offload_reorder_buffs = TARGET_NUM_OFFLD_REORDER_BUFFS; - config->num_peer_keys = TARGET_NUM_PEER_KEYS; - config->ast_skid_limit = TARGET_AST_SKID_LIMIT; - config->tx_chain_mask = (1 << ab->target_caps.num_rf_chains) - 1; - config->rx_chain_mask = (1 << ab->target_caps.num_rf_chains) - 1; - config->rx_timeout_pri[0] = TARGET_RX_TIMEOUT_LO_PRI; - config->rx_timeout_pri[1] = TARGET_RX_TIMEOUT_LO_PRI; - config->rx_timeout_pri[2] = TARGET_RX_TIMEOUT_LO_PRI; - config->rx_timeout_pri[3] = TARGET_RX_TIMEOUT_HI_PRI; - - if (test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) - config->rx_decap_mode = TARGET_DECAP_MODE_RAW; - else - config->rx_decap_mode = TARGET_DECAP_MODE_NATIVE_WIFI; - - config->scan_max_pending_req = TARGET_SCAN_MAX_PENDING_REQS; - config->bmiss_offload_max_vdev = TARGET_BMISS_OFFLOAD_MAX_VDEV; - config->roam_offload_max_vdev = TARGET_ROAM_OFFLOAD_MAX_VDEV; - config->roam_offload_max_ap_profiles = TARGET_ROAM_OFFLOAD_MAX_AP_PROFILES; - config->num_mcast_groups = TARGET_NUM_MCAST_GROUPS; - config->num_mcast_table_elems = TARGET_NUM_MCAST_TABLE_ELEMS; - config->mcast2ucast_mode = TARGET_MCAST2UCAST_MODE; - config->tx_dbg_log_size = TARGET_TX_DBG_LOG_SIZE; - config->num_wds_entries = TARGET_NUM_WDS_ENTRIES; - config->dma_burst_size = TARGET_DMA_BURST_SIZE; - config->rx_skip_defrag_timeout_dup_detection_check = - TARGET_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK; - config->vow_config = TARGET_VOW_CONFIG; - config->gtk_offload_max_vdev = TARGET_GTK_OFFLOAD_MAX_VDEV; - config->num_msdu_desc = TARGET_NUM_MSDU_DESC; - config->beacon_tx_offload_max_vdev = ab->num_radios * TARGET_MAX_BCN_OFFLD; - config->rx_batchmode = TARGET_RX_BATCHMODE; - /* Indicates host supports peer map v3 and unmap v2 support */ - config->peer_map_unmap_version = 0x32; - config->twt_ap_pdev_count = ab->num_radios; - config->twt_ap_sta_count = 1000; - config->ema_max_vap_cnt = ab->num_radios; - config->ema_max_profile_period = TARGET_EMA_MAX_PROFILE_PERIOD; - config->beacon_tx_offload_max_vdev += config->ema_max_vap_cnt; - - if (test_bit(WMI_TLV_SERVICE_PEER_METADATA_V1A_V1B_SUPPORT, ab->wmi_ab.svc_map)) - config->peer_metadata_ver = ATH12K_PEER_METADATA_V1B; -} - -void ath12k_wmi_init_wcn7850(struct ath12k_base *ab, - struct ath12k_wmi_resource_config_arg *config) -{ - config->num_vdevs = 4; - config->num_peers = 16; - config->num_tids = 32; - - config->num_offload_peers = 3; - config->num_offload_reorder_buffs = 3; - config->num_peer_keys = TARGET_NUM_PEER_KEYS; - config->ast_skid_limit = TARGET_AST_SKID_LIMIT; - config->tx_chain_mask = (1 << ab->target_caps.num_rf_chains) - 1; - config->rx_chain_mask = (1 << ab->target_caps.num_rf_chains) - 1; - config->rx_timeout_pri[0] = TARGET_RX_TIMEOUT_LO_PRI; - config->rx_timeout_pri[1] = TARGET_RX_TIMEOUT_LO_PRI; - config->rx_timeout_pri[2] = TARGET_RX_TIMEOUT_LO_PRI; - config->rx_timeout_pri[3] = TARGET_RX_TIMEOUT_HI_PRI; - config->rx_decap_mode = TARGET_DECAP_MODE_NATIVE_WIFI; - config->scan_max_pending_req = TARGET_SCAN_MAX_PENDING_REQS; - config->bmiss_offload_max_vdev = TARGET_BMISS_OFFLOAD_MAX_VDEV; - config->roam_offload_max_vdev = TARGET_ROAM_OFFLOAD_MAX_VDEV; - config->roam_offload_max_ap_profiles = TARGET_ROAM_OFFLOAD_MAX_AP_PROFILES; - config->num_mcast_groups = 0; - config->num_mcast_table_elems = 0; - config->mcast2ucast_mode = 0; - config->tx_dbg_log_size = TARGET_TX_DBG_LOG_SIZE; - config->num_wds_entries = 0; - config->dma_burst_size = 0; - config->rx_skip_defrag_timeout_dup_detection_check = 0; - config->vow_config = TARGET_VOW_CONFIG; - config->gtk_offload_max_vdev = 2; - config->num_msdu_desc = 0x400; - config->beacon_tx_offload_max_vdev = 2; - config->rx_batchmode = TARGET_RX_BATCHMODE; - - config->peer_map_unmap_version = 0x1; - config->use_pdev_id = 1; - config->max_frag_entries = 0xa; - config->num_tdls_vdevs = 0x1; - config->num_tdls_conn_table_entries = 8; - config->beacon_tx_offload_max_vdev = 0x2; - config->num_multicast_filter_entries = 0x20; - config->num_wow_filters = 0x16; - config->num_keep_alive_pattern = 0; -} - #define PRIMAP(_hw_mode_) \ [_hw_mode_] = _hw_mode_##_PRI diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index f99fced1610e6..b1ba1f8b6bb2d 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -6323,10 +6323,6 @@ struct ath12k_wmi_rssi_dbm_conv_info_arg { s8 min_nf_dbm; }; -void ath12k_wmi_init_qcn9274(struct ath12k_base *ab, - struct ath12k_wmi_resource_config_arg *config); -void ath12k_wmi_init_wcn7850(struct ath12k_base *ab, - struct ath12k_wmi_resource_config_arg *config); int ath12k_wmi_cmd_send(struct ath12k_wmi_pdev *wmi, struct sk_buff *skb, u32 cmd_id); struct sk_buff *ath12k_wmi_alloc_skb(struct ath12k_wmi_base *wmi_sc, u32 len); diff --git a/drivers/net/wireless/ath/ath12k/wmi_wifi7.c b/drivers/net/wireless/ath/ath12k/wmi_wifi7.c new file mode 100644 index 0000000000000..f27fa56210e83 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wmi_wifi7.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "core.h" +#include "wmi_wifi7.h" + +void ath12k_wmi_init_qcn9274(struct ath12k_base *ab, + struct ath12k_wmi_resource_config_arg *config) +{ + config->num_vdevs = ab->num_radios * TARGET_NUM_VDEVS(ab); + config->num_peers = ab->num_radios * + ath12k_core_get_max_peers_per_radio(ab); + config->num_offload_peers = TARGET_NUM_OFFLD_PEERS; + config->num_offload_reorder_buffs = TARGET_NUM_OFFLD_REORDER_BUFFS; + config->num_peer_keys = TARGET_NUM_PEER_KEYS; + config->ast_skid_limit = TARGET_AST_SKID_LIMIT; + config->tx_chain_mask = (1 << ab->target_caps.num_rf_chains) - 1; + config->rx_chain_mask = (1 << ab->target_caps.num_rf_chains) - 1; + config->rx_timeout_pri[0] = TARGET_RX_TIMEOUT_LO_PRI; + config->rx_timeout_pri[1] = TARGET_RX_TIMEOUT_LO_PRI; + config->rx_timeout_pri[2] = TARGET_RX_TIMEOUT_LO_PRI; + config->rx_timeout_pri[3] = TARGET_RX_TIMEOUT_HI_PRI; + + if (test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) + config->rx_decap_mode = TARGET_DECAP_MODE_RAW; + else + config->rx_decap_mode = TARGET_DECAP_MODE_NATIVE_WIFI; + + config->scan_max_pending_req = TARGET_SCAN_MAX_PENDING_REQS; + config->bmiss_offload_max_vdev = TARGET_BMISS_OFFLOAD_MAX_VDEV; + config->roam_offload_max_vdev = TARGET_ROAM_OFFLOAD_MAX_VDEV; + config->roam_offload_max_ap_profiles = TARGET_ROAM_OFFLOAD_MAX_AP_PROFILES; + config->num_mcast_groups = TARGET_NUM_MCAST_GROUPS; + config->num_mcast_table_elems = TARGET_NUM_MCAST_TABLE_ELEMS; + config->mcast2ucast_mode = TARGET_MCAST2UCAST_MODE; + config->tx_dbg_log_size = TARGET_TX_DBG_LOG_SIZE; + config->num_wds_entries = TARGET_NUM_WDS_ENTRIES; + config->dma_burst_size = TARGET_DMA_BURST_SIZE; + config->rx_skip_defrag_timeout_dup_detection_check = + TARGET_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK; + config->vow_config = TARGET_VOW_CONFIG; + config->gtk_offload_max_vdev = TARGET_GTK_OFFLOAD_MAX_VDEV; + config->num_msdu_desc = TARGET_NUM_MSDU_DESC; + config->beacon_tx_offload_max_vdev = ab->num_radios * TARGET_MAX_BCN_OFFLD; + config->rx_batchmode = TARGET_RX_BATCHMODE; + /* Indicates host supports peer map v3 and unmap v2 support */ + config->peer_map_unmap_version = 0x32; + config->twt_ap_pdev_count = ab->num_radios; + config->twt_ap_sta_count = 1000; + config->ema_max_vap_cnt = ab->num_radios; + config->ema_max_profile_period = TARGET_EMA_MAX_PROFILE_PERIOD; + config->beacon_tx_offload_max_vdev += config->ema_max_vap_cnt; + + if (test_bit(WMI_TLV_SERVICE_PEER_METADATA_V1A_V1B_SUPPORT, ab->wmi_ab.svc_map)) + config->peer_metadata_ver = ATH12K_PEER_METADATA_V1B; +} + +void ath12k_wmi_init_wcn7850(struct ath12k_base *ab, + struct ath12k_wmi_resource_config_arg *config) +{ + config->num_vdevs = 4; + config->num_peers = 16; + config->num_tids = 32; + + config->num_offload_peers = 3; + config->num_offload_reorder_buffs = 3; + config->num_peer_keys = TARGET_NUM_PEER_KEYS; + config->ast_skid_limit = TARGET_AST_SKID_LIMIT; + config->tx_chain_mask = (1 << ab->target_caps.num_rf_chains) - 1; + config->rx_chain_mask = (1 << ab->target_caps.num_rf_chains) - 1; + config->rx_timeout_pri[0] = TARGET_RX_TIMEOUT_LO_PRI; + config->rx_timeout_pri[1] = TARGET_RX_TIMEOUT_LO_PRI; + config->rx_timeout_pri[2] = TARGET_RX_TIMEOUT_LO_PRI; + config->rx_timeout_pri[3] = TARGET_RX_TIMEOUT_HI_PRI; + config->rx_decap_mode = TARGET_DECAP_MODE_NATIVE_WIFI; + config->scan_max_pending_req = TARGET_SCAN_MAX_PENDING_REQS; + config->bmiss_offload_max_vdev = TARGET_BMISS_OFFLOAD_MAX_VDEV; + config->roam_offload_max_vdev = TARGET_ROAM_OFFLOAD_MAX_VDEV; + config->roam_offload_max_ap_profiles = TARGET_ROAM_OFFLOAD_MAX_AP_PROFILES; + config->num_mcast_groups = 0; + config->num_mcast_table_elems = 0; + config->mcast2ucast_mode = 0; + config->tx_dbg_log_size = TARGET_TX_DBG_LOG_SIZE; + config->num_wds_entries = 0; + config->dma_burst_size = 0; + config->rx_skip_defrag_timeout_dup_detection_check = 0; + config->vow_config = TARGET_VOW_CONFIG; + config->gtk_offload_max_vdev = 2; + config->num_msdu_desc = 0x400; + config->beacon_tx_offload_max_vdev = 2; + config->rx_batchmode = TARGET_RX_BATCHMODE; + + config->peer_map_unmap_version = 0x1; + config->use_pdev_id = 1; + config->max_frag_entries = 0xa; + config->num_tdls_vdevs = 0x1; + config->num_tdls_conn_table_entries = 8; + config->beacon_tx_offload_max_vdev = 0x2; + config->num_multicast_filter_entries = 0x20; + config->num_wow_filters = 0x16; + config->num_keep_alive_pattern = 0; +} diff --git a/drivers/net/wireless/ath/ath12k/wmi_wifi7.h b/drivers/net/wireless/ath/ath12k/wmi_wifi7.h new file mode 100644 index 0000000000000..1514e3e8d4cb6 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wmi_wifi7.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_WMI_WIFI7_H +#define ATH12K_WMI_WIFI7_H + +void ath12k_wmi_init_qcn9274(struct ath12k_base *ab, + struct ath12k_wmi_resource_config_arg *config); +void ath12k_wmi_init_wcn7850(struct ath12k_base *ab, + struct ath12k_wmi_resource_config_arg *config); + +#endif From f11b8f2115e732ba4fa0bf8383f8c3233ae1ac28 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:30 +0530 Subject: [PATCH 004/140] wifi: ath12k: Move Wi-Fi 7 MHI configuration to dedicated file Relocate target-specific MHI configuration to a new mhi_wifi7.c file to isolate Wi-Fi 7 related logic from the common codebase. Improve modularity by separating hardware-dependent code from shared components. Enhance maintainability and prepare the driver for clean integration of additional device families. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-4-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/hw.c | 1 + drivers/net/wireless/ath/ath12k/mhi.c | 130 ------------------ drivers/net/wireless/ath/ath12k/mhi.h | 4 +- drivers/net/wireless/ath/ath12k/mhi_wifi7.c | 138 ++++++++++++++++++++ drivers/net/wireless/ath/ath12k/mhi_wifi7.h | 11 ++ 6 files changed, 152 insertions(+), 133 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/mhi_wifi7.c create mode 100644 drivers/net/wireless/ath/ath12k/mhi_wifi7.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index ee075ee68bb83..fb968884f6560 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -20,6 +20,7 @@ ath12k-y += core.o \ dbring.o \ hw.o \ mhi.o \ + mhi_wifi7.o \ pci.o \ pci_wifi7.o \ dp_mon.o \ diff --git a/drivers/net/wireless/ath/ath12k/hw.c b/drivers/net/wireless/ath/ath12k/hw.c index df1b4439adc79..ad372feaef28b 100644 --- a/drivers/net/wireless/ath/ath12k/hw.c +++ b/drivers/net/wireless/ath/ath12k/hw.c @@ -17,6 +17,7 @@ #include "dp_rx.h" #include "peer.h" #include "wmi_wifi7.h" +#include "mhi_wifi7.h" static const guid_t wcn7850_uuid = GUID_INIT(0xf634f534, 0x6147, 0x11ec, 0x90, 0xd6, 0x02, 0x42, diff --git a/drivers/net/wireless/ath/ath12k/mhi.c b/drivers/net/wireless/ath/ath12k/mhi.c index 08f44baf182a5..1f680f6e65d30 100644 --- a/drivers/net/wireless/ath/ath12k/mhi.c +++ b/drivers/net/wireless/ath/ath12k/mhi.c @@ -18,136 +18,6 @@ #define OTP_VALID_DUALMAC_BOARD_ID_MASK 0x1000 #define MHI_CB_INVALID 0xff -static const struct mhi_channel_config ath12k_mhi_channels_qcn9274[] = { - { - .num = 20, - .name = "IPCR", - .num_elements = 32, - .event_ring = 1, - .dir = DMA_TO_DEVICE, - .ee_mask = 0x4, - .pollcfg = 0, - .doorbell = MHI_DB_BRST_DISABLE, - .lpm_notify = false, - .offload_channel = false, - .doorbell_mode_switch = false, - .auto_queue = false, - }, - { - .num = 21, - .name = "IPCR", - .num_elements = 32, - .event_ring = 1, - .dir = DMA_FROM_DEVICE, - .ee_mask = 0x4, - .pollcfg = 0, - .doorbell = MHI_DB_BRST_DISABLE, - .lpm_notify = false, - .offload_channel = false, - .doorbell_mode_switch = false, - .auto_queue = true, - }, -}; - -static struct mhi_event_config ath12k_mhi_events_qcn9274[] = { - { - .num_elements = 32, - .irq_moderation_ms = 0, - .irq = 1, - .data_type = MHI_ER_CTRL, - .mode = MHI_DB_BRST_DISABLE, - .hardware_event = false, - .client_managed = false, - .offload_channel = false, - }, - { - .num_elements = 256, - .irq_moderation_ms = 1, - .irq = 2, - .mode = MHI_DB_BRST_DISABLE, - .priority = 1, - .hardware_event = false, - .client_managed = false, - .offload_channel = false, - }, -}; - -const struct mhi_controller_config ath12k_mhi_config_qcn9274 = { - .max_channels = 30, - .timeout_ms = 10000, - .use_bounce_buf = false, - .buf_len = 0, - .num_channels = ARRAY_SIZE(ath12k_mhi_channels_qcn9274), - .ch_cfg = ath12k_mhi_channels_qcn9274, - .num_events = ARRAY_SIZE(ath12k_mhi_events_qcn9274), - .event_cfg = ath12k_mhi_events_qcn9274, -}; - -static const struct mhi_channel_config ath12k_mhi_channels_wcn7850[] = { - { - .num = 20, - .name = "IPCR", - .num_elements = 64, - .event_ring = 1, - .dir = DMA_TO_DEVICE, - .ee_mask = 0x4, - .pollcfg = 0, - .doorbell = MHI_DB_BRST_DISABLE, - .lpm_notify = false, - .offload_channel = false, - .doorbell_mode_switch = false, - .auto_queue = false, - }, - { - .num = 21, - .name = "IPCR", - .num_elements = 64, - .event_ring = 1, - .dir = DMA_FROM_DEVICE, - .ee_mask = 0x4, - .pollcfg = 0, - .doorbell = MHI_DB_BRST_DISABLE, - .lpm_notify = false, - .offload_channel = false, - .doorbell_mode_switch = false, - .auto_queue = true, - }, -}; - -static struct mhi_event_config ath12k_mhi_events_wcn7850[] = { - { - .num_elements = 32, - .irq_moderation_ms = 0, - .irq = 1, - .mode = MHI_DB_BRST_DISABLE, - .data_type = MHI_ER_CTRL, - .hardware_event = false, - .client_managed = false, - .offload_channel = false, - }, - { - .num_elements = 256, - .irq_moderation_ms = 1, - .irq = 2, - .mode = MHI_DB_BRST_DISABLE, - .priority = 1, - .hardware_event = false, - .client_managed = false, - .offload_channel = false, - }, -}; - -const struct mhi_controller_config ath12k_mhi_config_wcn7850 = { - .max_channels = 128, - .timeout_ms = 2000, - .use_bounce_buf = false, - .buf_len = 8192, - .num_channels = ARRAY_SIZE(ath12k_mhi_channels_wcn7850), - .ch_cfg = ath12k_mhi_channels_wcn7850, - .num_events = ARRAY_SIZE(ath12k_mhi_events_wcn7850), - .event_cfg = ath12k_mhi_events_wcn7850, -}; - void ath12k_mhi_set_mhictrl_reset(struct ath12k_base *ab) { u32 val; diff --git a/drivers/net/wireless/ath/ath12k/mhi.h b/drivers/net/wireless/ath/ath12k/mhi.h index 7358b8477536a..5e1363650a9a7 100644 --- a/drivers/net/wireless/ath/ath12k/mhi.h +++ b/drivers/net/wireless/ath/ath12k/mhi.h @@ -2,6 +2,7 @@ /* * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. * Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef _ATH12K_MHI_H #define _ATH12K_MHI_H @@ -31,9 +32,6 @@ enum ath12k_mhi_state { ATH12K_MHI_RDDM_DONE, }; -extern const struct mhi_controller_config ath12k_mhi_config_qcn9274; -extern const struct mhi_controller_config ath12k_mhi_config_wcn7850; - int ath12k_mhi_start(struct ath12k_pci *ar_pci); void ath12k_mhi_stop(struct ath12k_pci *ar_pci, bool is_suspend); int ath12k_mhi_register(struct ath12k_pci *ar_pci); diff --git a/drivers/net/wireless/ath/ath12k/mhi_wifi7.c b/drivers/net/wireless/ath/ath12k/mhi_wifi7.c new file mode 100644 index 0000000000000..be74df152f6f8 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/mhi_wifi7.c @@ -0,0 +1,138 @@ +// 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 "mhi.h" +#include "mhi_wifi7.h" + +static const struct mhi_channel_config ath12k_mhi_channels_qcn9274[] = { + { + .num = 20, + .name = "IPCR", + .num_elements = 32, + .event_ring = 1, + .dir = DMA_TO_DEVICE, + .ee_mask = 0x4, + .pollcfg = 0, + .doorbell = MHI_DB_BRST_DISABLE, + .lpm_notify = false, + .offload_channel = false, + .doorbell_mode_switch = false, + .auto_queue = false, + }, + { + .num = 21, + .name = "IPCR", + .num_elements = 32, + .event_ring = 1, + .dir = DMA_FROM_DEVICE, + .ee_mask = 0x4, + .pollcfg = 0, + .doorbell = MHI_DB_BRST_DISABLE, + .lpm_notify = false, + .offload_channel = false, + .doorbell_mode_switch = false, + .auto_queue = true, + }, +}; + +static struct mhi_event_config ath12k_mhi_events_qcn9274[] = { + { + .num_elements = 32, + .irq_moderation_ms = 0, + .irq = 1, + .data_type = MHI_ER_CTRL, + .mode = MHI_DB_BRST_DISABLE, + .hardware_event = false, + .client_managed = false, + .offload_channel = false, + }, + { + .num_elements = 256, + .irq_moderation_ms = 1, + .irq = 2, + .mode = MHI_DB_BRST_DISABLE, + .priority = 1, + .hardware_event = false, + .client_managed = false, + .offload_channel = false, + }, +}; + +const struct mhi_controller_config ath12k_mhi_config_qcn9274 = { + .max_channels = 30, + .timeout_ms = 10000, + .use_bounce_buf = false, + .buf_len = 0, + .num_channels = ARRAY_SIZE(ath12k_mhi_channels_qcn9274), + .ch_cfg = ath12k_mhi_channels_qcn9274, + .num_events = ARRAY_SIZE(ath12k_mhi_events_qcn9274), + .event_cfg = ath12k_mhi_events_qcn9274, +}; + +static const struct mhi_channel_config ath12k_mhi_channels_wcn7850[] = { + { + .num = 20, + .name = "IPCR", + .num_elements = 64, + .event_ring = 1, + .dir = DMA_TO_DEVICE, + .ee_mask = 0x4, + .pollcfg = 0, + .doorbell = MHI_DB_BRST_DISABLE, + .lpm_notify = false, + .offload_channel = false, + .doorbell_mode_switch = false, + .auto_queue = false, + }, + { + .num = 21, + .name = "IPCR", + .num_elements = 64, + .event_ring = 1, + .dir = DMA_FROM_DEVICE, + .ee_mask = 0x4, + .pollcfg = 0, + .doorbell = MHI_DB_BRST_DISABLE, + .lpm_notify = false, + .offload_channel = false, + .doorbell_mode_switch = false, + .auto_queue = true, + }, +}; + +static struct mhi_event_config ath12k_mhi_events_wcn7850[] = { + { + .num_elements = 32, + .irq_moderation_ms = 0, + .irq = 1, + .mode = MHI_DB_BRST_DISABLE, + .data_type = MHI_ER_CTRL, + .hardware_event = false, + .client_managed = false, + .offload_channel = false, + }, + { + .num_elements = 256, + .irq_moderation_ms = 1, + .irq = 2, + .mode = MHI_DB_BRST_DISABLE, + .priority = 1, + .hardware_event = false, + .client_managed = false, + .offload_channel = false, + }, +}; + +const struct mhi_controller_config ath12k_mhi_config_wcn7850 = { + .max_channels = 128, + .timeout_ms = 2000, + .use_bounce_buf = false, + .buf_len = 8192, + .num_channels = ARRAY_SIZE(ath12k_mhi_channels_wcn7850), + .ch_cfg = ath12k_mhi_channels_wcn7850, + .num_events = ARRAY_SIZE(ath12k_mhi_events_wcn7850), + .event_cfg = ath12k_mhi_events_wcn7850, +}; diff --git a/drivers/net/wireless/ath/ath12k/mhi_wifi7.h b/drivers/net/wireless/ath/ath12k/mhi_wifi7.h new file mode 100644 index 0000000000000..8417a2bde0877 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/mhi_wifi7.h @@ -0,0 +1,11 @@ +/* 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 _ATH12K_WIFI7_MHI_H +#define _ATH12K_WIFI7_MHI_H +extern const struct mhi_controller_config ath12k_mhi_config_qcn9274; +extern const struct mhi_controller_config ath12k_mhi_config_wcn7850; +#endif /* _ATH12K_WIFI7_MHI_H */ From 18b3c1273b5aa4969465d3b2c0f401f0ff5c1279 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:31 +0530 Subject: [PATCH 005/140] wifi: ath12k: Rename hw.c to Wi-Fi 7 specific implementation file Rename hw.c to hw_wifi7.c to reflect its focus on Wi-Fi 7 chipset specific configurations. Clarify the files role in containing hardware dependent logic tailored to the Wi-Fi 7 family. This change is part of a broader effort to modularize the codebase by separating common and target specific components into distinct modules for improved clarity and maintainability. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-5-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 2 +- drivers/net/wireless/ath/ath12k/{hw.c => hw_wifi7.c} | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) rename drivers/net/wireless/ath/ath12k/{hw.c => hw_wifi7.c} (99%) diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index fb968884f6560..f1105d7adafff 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -18,7 +18,7 @@ ath12k-y += core.o \ ce_wifi7.o \ peer.o \ dbring.o \ - hw.o \ + hw_wifi7.o \ mhi.o \ mhi_wifi7.o \ pci.o \ diff --git a/drivers/net/wireless/ath/ath12k/hw.c b/drivers/net/wireless/ath/ath12k/hw_wifi7.c similarity index 99% rename from drivers/net/wireless/ath/ath12k/hw.c rename to drivers/net/wireless/ath/ath12k/hw_wifi7.c index ad372feaef28b..f6177f8e032d9 100644 --- a/drivers/net/wireless/ath/ath12k/hw.c +++ b/drivers/net/wireless/ath/ath12k/hw_wifi7.c @@ -1043,13 +1043,14 @@ int ath12k_hw_init(struct ath12k_base *ab) } if (i == ARRAY_SIZE(ath12k_hw_params)) { - ath12k_err(ab, "Unsupported hardware version: 0x%x\n", ab->hw_rev); + ath12k_err(ab, "Unsupported Wi-Fi 7 hardware version: 0x%x\n", + ab->hw_rev); return -EINVAL; } ab->hw_params = hw_params; - ath12k_info(ab, "Hardware name: %s\n", ab->hw_params->name); + ath12k_info(ab, "Wi-Fi 7 Hardware name: %s\n", ab->hw_params->name); return 0; } From 3965fc1916c8446e7f8acb9fa05a8cb412aa2b63 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:32 +0530 Subject: [PATCH 006/140] wifi: ath12k: Rename ahb_hif_ops to reflect generic usage Rename ahb_hif_ops structure to remove the IPQ5322 qualifier and reflect its generic applicability across multiple targets. Clarify its role as a container for common HIF callbacks. This renaming is part of a broader effort to modularize the codebase by separating common logic from device-specific implementations. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-6-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ahb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index b30527c402f6c..d3f7cc6417cca 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -698,7 +698,7 @@ static int ath12k_ahb_map_service_to_pipe(struct ath12k_base *ab, u16 service_id return 0; } -static const struct ath12k_hif_ops ath12k_ahb_hif_ops_ipq5332 = { +static const struct ath12k_hif_ops ath12k_ahb_hif_ops = { .start = ath12k_ahb_start, .stop = ath12k_ahb_stop, .read32 = ath12k_ahb_read32, @@ -1011,7 +1011,7 @@ static int ath12k_ahb_probe(struct platform_device *pdev) hw_rev = (enum ath12k_hw_rev)(kernel_ulong_t)of_device_get_match_data(&pdev->dev); switch (hw_rev) { case ATH12K_HW_IPQ5332_HW10: - hif_ops = &ath12k_ahb_hif_ops_ipq5332; + hif_ops = &ath12k_ahb_hif_ops; userpd_id = ATH12K_IPQ5332_USERPD_ID; break; default: From 73d6083c4313ef349d5a1c8f4cb72674d39e0413 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:33 +0530 Subject: [PATCH 007/140] wifi: ath12k: Restructure ahb.c into common and Wi-Fi 7 specific modules Split ahb.c into a common module (ahb.c) and a Wi-Fi 7 specific module (ahb_wifi7.c). Retain shared logic-such as probe and initialization sequences-in ahb.c to support reuse across hardware families. Move Wi-Fi 7 specific initialization and configuration routines to ahb_wifi7.c and register them via callbacks. This modular approach improves code organization and prepares the driver for scalable support of additional hardware families. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.3.1-00130-QCAHKSWPL_SILICONZ-1 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-7-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 2 +- drivers/net/wireless/ath/ath12k/ahb.c | 128 +++++++++++++------- drivers/net/wireless/ath/ath12k/ahb.h | 27 +++-- drivers/net/wireless/ath/ath12k/ahb_wifi7.c | 63 ++++++++++ drivers/net/wireless/ath/ath12k/ahb_wifi7.h | 20 +++ drivers/net/wireless/ath/ath12k/core.c | 5 +- 6 files changed, 190 insertions(+), 55 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/ahb_wifi7.c create mode 100644 drivers/net/wireless/ath/ath12k/ahb_wifi7.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index f1105d7adafff..5c044e3963305 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -27,7 +27,7 @@ ath12k-y += core.o \ fw.o \ p2p.o -ath12k-$(CONFIG_ATH12K_AHB) += ahb.o +ath12k-$(CONFIG_ATH12K_AHB) += ahb.o ahb_wifi7.o ath12k-$(CONFIG_ATH12K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o ath12k-$(CONFIG_ACPI) += acpi.o ath12k-$(CONFIG_ATH12K_TRACING) += trace.o diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index d3f7cc6417cca..777edaf0e58e5 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -16,18 +16,11 @@ #include "debug.h" #include "hif.h" -static const struct of_device_id ath12k_ahb_of_match[] = { - { .compatible = "qcom,ipq5332-wifi", - .data = (void *)ATH12K_HW_IPQ5332_HW10, - }, - { } -}; - -MODULE_DEVICE_TABLE(of, ath12k_ahb_of_match); - #define ATH12K_IRQ_CE0_OFFSET 4 #define ATH12K_MAX_UPDS 1 #define ATH12K_UPD_IRQ_WRD_LEN 18 + +static struct ath12k_ahb_driver *ath12k_ahb_family_drivers[ATH12K_DEVICE_FAMILY_MAX]; static const char ath12k_userpd_irq[][9] = {"spawn", "ready", "stop-ack"}; @@ -988,13 +981,34 @@ static void ath12k_ahb_resource_deinit(struct ath12k_base *ab) ab_ahb->xo_clk = NULL; } +static enum ath12k_device_family +ath12k_ahb_get_device_family(const struct platform_device *pdev) +{ + enum ath12k_device_family device_family_id; + struct ath12k_ahb_driver *driver; + const struct of_device_id *of_id; + + for (device_family_id = ATH12K_DEVICE_FAMILY_START; + device_family_id < ATH12K_DEVICE_FAMILY_MAX; device_family_id++) { + driver = ath12k_ahb_family_drivers[device_family_id]; + if (driver) { + of_id = of_match_device(driver->id_table, &pdev->dev); + if (of_id) { + /* Found the driver */ + return device_family_id; + } + } + } + + return ATH12K_DEVICE_FAMILY_MAX; +} + static int ath12k_ahb_probe(struct platform_device *pdev) { - struct ath12k_base *ab; - const struct ath12k_hif_ops *hif_ops; + enum ath12k_device_family device_id; struct ath12k_ahb *ab_ahb; - enum ath12k_hw_rev hw_rev; - u32 addr, userpd_id; + struct ath12k_base *ab; + u32 addr; int ret; ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); @@ -1008,25 +1022,32 @@ static int ath12k_ahb_probe(struct platform_device *pdev) if (!ab) return -ENOMEM; - hw_rev = (enum ath12k_hw_rev)(kernel_ulong_t)of_device_get_match_data(&pdev->dev); - switch (hw_rev) { - case ATH12K_HW_IPQ5332_HW10: - hif_ops = &ath12k_ahb_hif_ops; - userpd_id = ATH12K_IPQ5332_USERPD_ID; - break; - default: - ret = -EOPNOTSUPP; + ab_ahb = ath12k_ab_to_ahb(ab); + ab_ahb->ab = ab; + ab->hif.ops = &ath12k_ahb_hif_ops; + ab->pdev = pdev; + platform_set_drvdata(pdev, ab); + + device_id = ath12k_ahb_get_device_family(pdev); + if (device_id >= ATH12K_DEVICE_FAMILY_MAX) { + ath12k_err(ab, "failed to get device family: %d\n", device_id); + ret = -EINVAL; goto err_core_free; } - ab->hif.ops = hif_ops; - ab->pdev = pdev; - ab->hw_rev = hw_rev; - ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT; - platform_set_drvdata(pdev, ab); - ab_ahb = ath12k_ab_to_ahb(ab); - ab_ahb->ab = ab; - ab_ahb->userpd_id = userpd_id; + ath12k_dbg(ab, ATH12K_DBG_AHB, "AHB device family id: %d\n", device_id); + + ab_ahb->device_family_ops = &ath12k_ahb_family_drivers[device_id]->ops; + + /* Call device specific probe. This is the callback that can + * be used to override any ops in future + * probe is validated for NULL during registration. + */ + ret = ab_ahb->device_family_ops->probe(pdev); + if (ret) { + ath12k_err(ab, "failed to probe device: %d\n", ret); + goto err_core_free; + } /* Set fixed_mem_region to true for platforms that support fixed memory * reservation from DT. If memory is reserved from DT for FW, ath12k driver @@ -1136,21 +1157,44 @@ static void ath12k_ahb_remove(struct platform_device *pdev) ath12k_ahb_free_resources(ab); } -static struct platform_driver ath12k_ahb_driver = { - .driver = { - .name = "ath12k_ahb", - .of_match_table = ath12k_ahb_of_match, - }, - .probe = ath12k_ahb_probe, - .remove = ath12k_ahb_remove, -}; - -int ath12k_ahb_init(void) +int ath12k_ahb_register_driver(const enum ath12k_device_family device_id, + struct ath12k_ahb_driver *driver) { - return platform_driver_register(&ath12k_ahb_driver); + struct platform_driver *ahb_driver; + + if (device_id >= ATH12K_DEVICE_FAMILY_MAX) + return -EINVAL; + + if (!driver || !driver->ops.probe) + return -EINVAL; + + if (ath12k_ahb_family_drivers[device_id]) { + pr_err("Driver already registered for id %d\n", device_id); + return -EALREADY; + } + + ath12k_ahb_family_drivers[device_id] = driver; + + ahb_driver = &ath12k_ahb_family_drivers[device_id]->driver; + ahb_driver->driver.name = driver->name; + ahb_driver->driver.of_match_table = driver->id_table; + ahb_driver->probe = ath12k_ahb_probe; + ahb_driver->remove = ath12k_ahb_remove; + + return platform_driver_register(ahb_driver); } -void ath12k_ahb_exit(void) +void ath12k_ahb_unregister_driver(const enum ath12k_device_family device_id) { - platform_driver_unregister(&ath12k_ahb_driver); + struct platform_driver *ahb_driver; + + if (device_id >= ATH12K_DEVICE_FAMILY_MAX) + return; + + if (!ath12k_ahb_family_drivers[device_id]) + return; + + ahb_driver = &ath12k_ahb_family_drivers[device_id]->driver; + platform_driver_unregister(ahb_driver); + ath12k_ahb_family_drivers[device_id] = NULL; } diff --git a/drivers/net/wireless/ath/ath12k/ahb.h b/drivers/net/wireless/ath/ath12k/ahb.h index d56244b20a6a6..fce02e3af5fb4 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.h +++ b/drivers/net/wireless/ath/ath12k/ahb.h @@ -8,6 +8,7 @@ #include #include +#include #include "core.h" #define ATH12K_AHB_RECOVERY_TIMEOUT (3 * HZ) @@ -43,6 +44,10 @@ enum ath12k_ahb_userpd_irq { struct ath12k_base; +struct ath12k_ahb_device_family_ops { + int (*probe)(struct platform_device *pdev); +}; + struct ath12k_ahb { struct ath12k_base *ab; struct rproc *tgt_rproc; @@ -59,6 +64,15 @@ struct ath12k_ahb { u32 spawn_bit; u32 stop_bit; int userpd_irq_num[ATH12K_USERPD_MAX_IRQ]; + const struct ath12k_ahb_ops *ahb_ops; + const struct ath12k_ahb_device_family_ops *device_family_ops; +}; + +struct ath12k_ahb_driver { + const char *name; + const struct of_device_id *id_table; + struct ath12k_ahb_device_family_ops ops; + struct platform_driver driver; }; static inline struct ath12k_ahb *ath12k_ab_to_ahb(struct ath12k_base *ab) @@ -66,15 +80,8 @@ static inline struct ath12k_ahb *ath12k_ab_to_ahb(struct ath12k_base *ab) return (struct ath12k_ahb *)ab->drv_priv; } -#ifdef CONFIG_ATH12K_AHB -int ath12k_ahb_init(void); -void ath12k_ahb_exit(void); -#else -static inline int ath12k_ahb_init(void) -{ - return 0; -} +int ath12k_ahb_register_driver(const enum ath12k_device_family device_id, + struct ath12k_ahb_driver *driver); +void ath12k_ahb_unregister_driver(const enum ath12k_device_family device_id); -static inline void ath12k_ahb_exit(void) {}; -#endif #endif diff --git a/drivers/net/wireless/ath/ath12k/ahb_wifi7.c b/drivers/net/wireless/ath/ath12k/ahb_wifi7.c new file mode 100644 index 0000000000000..7a869722b77e6 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/ahb_wifi7.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include "ahb.h" +#include "ahb_wifi7.h" +#include "debug.h" +#include "hif.h" + +static const struct of_device_id ath12k_wifi7_ahb_of_match[] = { + { .compatible = "qcom,ipq5332-wifi", + .data = (void *)ATH12K_HW_IPQ5332_HW10, + }, + { } +}; + +MODULE_DEVICE_TABLE(of, ath12k_wifi7_ahb_of_match); + +static int ath12k_wifi7_ahb_probe(struct platform_device *pdev) +{ + struct ath12k_ahb *ab_ahb; + enum ath12k_hw_rev hw_rev; + struct ath12k_base *ab; + + ab = platform_get_drvdata(pdev); + ab_ahb = ath12k_ab_to_ahb(ab); + + hw_rev = (enum ath12k_hw_rev)(kernel_ulong_t)of_device_get_match_data(&pdev->dev); + switch (hw_rev) { + case ATH12K_HW_IPQ5332_HW10: + ab_ahb->userpd_id = ATH12K_IPQ5332_USERPD_ID; + break; + default: + return -EOPNOTSUPP; + } + + ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT; + ab->hw_rev = hw_rev; + + return 0; +} + +static struct ath12k_ahb_driver ath12k_wifi7_ahb_driver = { + .name = "ath12k_wifi7_ahb", + .id_table = ath12k_wifi7_ahb_of_match, + .ops.probe = ath12k_wifi7_ahb_probe, +}; + +int ath12k_wifi7_ahb_init(void) +{ + return ath12k_ahb_register_driver(ATH12K_DEVICE_FAMILY_WIFI7, + &ath12k_wifi7_ahb_driver); +} + +void ath12k_wifi7_ahb_exit(void) +{ + ath12k_ahb_unregister_driver(ATH12K_DEVICE_FAMILY_WIFI7); +} diff --git a/drivers/net/wireless/ath/ath12k/ahb_wifi7.h b/drivers/net/wireless/ath/ath12k/ahb_wifi7.h new file mode 100644 index 0000000000000..5974c7cad69ae --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/ahb_wifi7.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#ifndef ATH12K_AHB_WIFI7_H +#define ATH12K_AHB_WIFI7_H + +#ifdef CONFIG_ATH12K_AHB +int ath12k_wifi7_ahb_init(void); +void ath12k_wifi7_ahb_exit(void); +#else +static inline int ath12k_wifi7_ahb_init(void) +{ + return 0; +} + +static inline void ath12k_wifi7_ahb_exit(void) {} +#endif +#endif /* ATH12K_AHB_WIFI7_H */ diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 7b02e0c8b1919..1842777b362e6 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -22,6 +22,7 @@ #include "pci.h" #include "wow.h" #include "pci_wifi7.h" +#include "ahb_wifi7.h" static int ahb_err, pci_err; unsigned int ath12k_debug_mask; @@ -2294,7 +2295,7 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size, static int ath12k_init(void) { - ahb_err = ath12k_ahb_init(); + ahb_err = ath12k_wifi7_ahb_init(); if (ahb_err) pr_warn("Failed to initialize ath12k AHB device: %d\n", ahb_err); @@ -2312,7 +2313,7 @@ static void ath12k_exit(void) ath12k_wifi7_pci_exit(); if (!ahb_err) - ath12k_ahb_exit(); + ath12k_wifi7_ahb_exit(); } module_init(ath12k_init); From 0c8dd001e2978418c0dc270cd63e95e22d5a7967 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:34 +0530 Subject: [PATCH 008/140] wifi: ath12k: Move Wi-Fi 7 specific init routines to dedicated file Move Wi-Fi 7 specific module initialization and exit routines from core.c to a new core_wifi7.c file. Decouple these routines from common module entry points to improve modularity. This restructuring is part of a broader effort to modularize the ATH12K driver by separating common logic from hardware family-specific implementations, improving maintainability and scalability. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.3.1-00130-QCAHKSWPL_SILICONZ-1 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-8-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/core.c | 32 -------------- drivers/net/wireless/ath/ath12k/core_wifi7.c | 44 ++++++++++++++++++++ 3 files changed, 45 insertions(+), 32 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/core_wifi7.c diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index 5c044e3963305..9c7a32930ed60 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: BSD-3-Clause-Clear obj-$(CONFIG_ATH12K) += ath12k.o ath12k-y += core.o \ + core_wifi7.o \ hal.o \ hal_tx.o \ hal_rx.o \ diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 1842777b362e6..ce080071473c7 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -21,10 +21,7 @@ #include "hif.h" #include "pci.h" #include "wow.h" -#include "pci_wifi7.h" -#include "ahb_wifi7.h" -static int ahb_err, pci_err; unsigned int ath12k_debug_mask; module_param_named(debug_mask, ath12k_debug_mask, uint, 0644); MODULE_PARM_DESC(debug_mask, "Debugging mask"); @@ -2292,32 +2289,3 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size, kfree(ab); return NULL; } - -static int ath12k_init(void) -{ - ahb_err = ath12k_wifi7_ahb_init(); - if (ahb_err) - pr_warn("Failed to initialize ath12k AHB device: %d\n", ahb_err); - - pci_err = ath12k_wifi7_pci_init(); - if (pci_err) - pr_warn("Failed to initialize ath12k PCI device: %d\n", pci_err); - - /* If both failed, return one of the failures (arbitrary) */ - return ahb_err && pci_err ? ahb_err : 0; -} - -static void ath12k_exit(void) -{ - if (!pci_err) - ath12k_wifi7_pci_exit(); - - if (!ahb_err) - ath12k_wifi7_ahb_exit(); -} - -module_init(ath12k_init); -module_exit(ath12k_exit); - -MODULE_DESCRIPTION("Driver support for Qualcomm Technologies 802.11be WLAN devices"); -MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/ath/ath12k/core_wifi7.c b/drivers/net/wireless/ath/ath12k/core_wifi7.c new file mode 100644 index 0000000000000..85ea8904672cb --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/core_wifi7.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include "ahb.h" +#include "pci.h" +#include "pci_wifi7.h" +#include "ahb_wifi7.h" + +static int ahb_err, pci_err; + +static int ath12k_wifi7_init(void) +{ + ahb_err = ath12k_wifi7_ahb_init(); + if (ahb_err) + pr_warn("Failed to initialize ath12k Wi-Fi 7 AHB device: %d\n", + ahb_err); + + pci_err = ath12k_wifi7_pci_init(); + if (pci_err) + pr_warn("Failed to initialize ath12k Wi-Fi 7 PCI device: %d\n", + pci_err); + + /* If both failed, return one of the failures (arbitrary) */ + return ahb_err && pci_err ? ahb_err : 0; +} + +static void ath12k_wifi7_exit(void) +{ + if (!pci_err) + ath12k_wifi7_pci_exit(); + + if (!ahb_err) + ath12k_wifi7_ahb_exit(); +} + +module_init(ath12k_wifi7_init); +module_exit(ath12k_wifi7_exit); + +MODULE_DESCRIPTION("Driver support for Qualcomm Technologies 802.11be WLAN devices"); +MODULE_LICENSE("Dual BSD/GPL"); From bf6832bae03e8a229f0abba7b31d1ada3e1960f2 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:35 +0530 Subject: [PATCH 009/140] wifi: ath12k: Move hw_init invocation to target-specific probe Relocate hw_init call from the shared probe path to target-specific probe implementations. Handle Wi-Fi 7 initialization entirely within its corresponding target-specific file. Improve modularity by decoupling hardware-dependent initialization from common probe logic. Support broader effort to separate shared and target-specific code paths. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.3.1-00130-QCAHKSWPL_SILICONZ-1 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-9-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ahb_wifi7.c | 8 ++++++++ drivers/net/wireless/ath/ath12k/core.c | 7 ------- drivers/net/wireless/ath/ath12k/hw.h | 2 -- drivers/net/wireless/ath/ath12k/hw_wifi7.c | 3 ++- drivers/net/wireless/ath/ath12k/hw_wifi7.h | 13 +++++++++++++ drivers/net/wireless/ath/ath12k/pci_wifi7.c | 8 ++++++++ 6 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/hw_wifi7.h diff --git a/drivers/net/wireless/ath/ath12k/ahb_wifi7.c b/drivers/net/wireless/ath/ath12k/ahb_wifi7.c index 7a869722b77e6..ff4f041bafbc4 100644 --- a/drivers/net/wireless/ath/ath12k/ahb_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/ahb_wifi7.c @@ -11,6 +11,7 @@ #include "ahb_wifi7.h" #include "debug.h" #include "hif.h" +#include "hw_wifi7.h" static const struct of_device_id ath12k_wifi7_ahb_of_match[] = { { .compatible = "qcom,ipq5332-wifi", @@ -26,6 +27,7 @@ static int ath12k_wifi7_ahb_probe(struct platform_device *pdev) struct ath12k_ahb *ab_ahb; enum ath12k_hw_rev hw_rev; struct ath12k_base *ab; + int ret; ab = platform_get_drvdata(pdev); ab_ahb = ath12k_ab_to_ahb(ab); @@ -42,6 +44,12 @@ static int ath12k_wifi7_ahb_probe(struct platform_device *pdev) ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT; ab->hw_rev = hw_rev; + ret = ath12k_wifi7_hw_init(ab); + if (ret) { + ath12k_err(ab, "WiFi-7 hw_init for AHB failed: %d\n", ret); + return ret; + } + return 0; } diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index ce080071473c7..b4a8923d6d48d 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -1742,13 +1742,6 @@ enum ath12k_qmi_mem_mode ath12k_core_get_memory_mode(struct ath12k_base *ab) int ath12k_core_pre_init(struct ath12k_base *ab) { const struct ath12k_mem_profile_based_param *param; - int ret; - - ret = ath12k_hw_init(ab); - if (ret) { - ath12k_err(ab, "failed to init hw params: %d\n", ret); - return ret; - } param = &ath12k_mem_profile_based_param[ab->target_mem_mode]; ab->profile_param = param; diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h index 8ce11c3e6d5c2..35d6900720fee 100644 --- a/drivers/net/wireless/ath/ath12k/hw.h +++ b/drivers/net/wireless/ath/ath12k/hw.h @@ -377,6 +377,4 @@ static inline const char *ath12k_bd_ie_type_str(enum ath12k_bd_ie_type type) return "unknown"; } -int ath12k_hw_init(struct ath12k_base *ab); - #endif diff --git a/drivers/net/wireless/ath/ath12k/hw_wifi7.c b/drivers/net/wireless/ath/ath12k/hw_wifi7.c index f6177f8e032d9..5f5d3c57b288c 100644 --- a/drivers/net/wireless/ath/ath12k/hw_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/hw_wifi7.c @@ -13,6 +13,7 @@ #include "ce.h" #include "ce_wifi7.h" #include "hw.h" +#include "hw_wifi7.h" #include "mhi.h" #include "dp_rx.h" #include "peer.h" @@ -1030,7 +1031,7 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { }, }; -int ath12k_hw_init(struct ath12k_base *ab) +int ath12k_wifi7_hw_init(struct ath12k_base *ab) { const struct ath12k_hw_params *hw_params = NULL; int i; diff --git a/drivers/net/wireless/ath/ath12k/hw_wifi7.h b/drivers/net/wireless/ath/ath12k/hw_wifi7.h new file mode 100644 index 0000000000000..643b6fdfdb66f --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/hw_wifi7.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_WIFI7_HW_H +#define ATH12K_WIFI7_HW_H + +struct ath12k_base; +int ath12k_wifi7_hw_init(struct ath12k_base *ab); + +#endif /* ATH12K_WIFI7_HW_H */ diff --git a/drivers/net/wireless/ath/ath12k/pci_wifi7.c b/drivers/net/wireless/ath/ath12k/pci_wifi7.c index 8c7718153534c..a680cd9a04e33 100644 --- a/drivers/net/wireless/ath/ath12k/pci_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/pci_wifi7.c @@ -11,6 +11,7 @@ #include "core.h" #include "hif.h" #include "mhi.h" +#include "hw_wifi7.h" #define QCN9274_DEVICE_ID 0x1109 #define WCN7850_DEVICE_ID 0x1107 @@ -84,6 +85,7 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, u32 soc_hw_version_major, soc_hw_version_minor; struct ath12k_pci *ab_pci; struct ath12k_base *ab; + int ret; ab = pci_get_drvdata(pdev); if (!ab) @@ -143,6 +145,12 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, return -EOPNOTSUPP; } + ret = ath12k_wifi7_hw_init(ab); + if (ret) { + dev_err(&pdev->dev, "WiFi-7 hw_init for PCI failed: %d\n", ret); + return ret; + } + return 0; } From 14eb62d8c5e4b2460d0eb6ff61894cdcdb102933 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:36 +0530 Subject: [PATCH 010/140] wifi: ath12k: Modularize driver into common and Wi-Fi 7 specific components Split the ath12k driver into two kernel modules: - ath12k.ko for shared logic across multiple targets - ath12k_wifi7.ko for Wi-Fi 7 specific configuration and routines The common module (ath12k.ko) must be loaded prior to any device-specific module, as the latter depends on exported symbols from the former. As part of this restructuring, Wi-Fi 7 specific files are moved into a dedicated `wifi7/` directory and built as a separate module. Common symbols are exported accordingly, with further adjustments planned in upcoming patches to support architecture-dependent separation. This modularization improves maintainability and scalability by enabling clean separation of hardware-specific logic from the shared driver core. +-----------------+ | | | ath12k.ko | | (common) | +---------------+ | | | | +-----------------+ | ath12k.ko | ===========> | | +------------------+ +---------------+ | | | ath12k_wifi7.ko | | (wifi7 family) | | | +------------------+ Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.3.1-00130-QCAHKSWPL_SILICONZ-1 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-10-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 11 ++++------- drivers/net/wireless/ath/ath12k/ahb.c | 2 ++ drivers/net/wireless/ath/ath12k/core.c | 5 +++++ drivers/net/wireless/ath/ath12k/debug.c | 4 ++++ drivers/net/wireless/ath/ath12k/dp_rx.c | 3 +++ drivers/net/wireless/ath/ath12k/hal.c | 4 ++++ drivers/net/wireless/ath/ath12k/htc.c | 2 ++ drivers/net/wireless/ath/ath12k/pci.c | 7 +++---- drivers/net/wireless/ath/ath12k/peer.c | 2 ++ drivers/net/wireless/ath/ath12k/wifi7/Makefile | 10 ++++++++++ .../ath/ath12k/{ahb_wifi7.c => wifi7/ahb.c} | 8 ++++---- .../ath/ath12k/{ahb_wifi7.h => wifi7/ahb.h} | 0 .../ath/ath12k/{ce_wifi7.c => wifi7/ce.c} | 6 +++--- .../ath/ath12k/{ce_wifi7.h => wifi7/ce.h} | 0 .../ath/ath12k/{core_wifi7.c => wifi7/core.c} | 6 +++--- .../ath/ath12k/{hw_wifi7.c => wifi7/hw.c} | 16 ++++++++-------- .../ath/ath12k/{hw_wifi7.h => wifi7/hw.h} | 0 .../ath/ath12k/{mhi_wifi7.c => wifi7/mhi.c} | 2 +- .../ath/ath12k/{mhi_wifi7.h => wifi7/mhi.h} | 0 .../ath/ath12k/{pci_wifi7.c => wifi7/pci.c} | 10 +++++----- .../ath/ath12k/{pci_wifi7.h => wifi7/pci.h} | 0 .../ath/ath12k/{wmi_wifi7.c => wifi7/wmi.c} | 4 ++-- .../ath/ath12k/{wmi_wifi7.h => wifi7/wmi.h} | 0 23 files changed, 65 insertions(+), 37 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/Makefile rename drivers/net/wireless/ath/ath12k/{ahb_wifi7.c => wifi7/ahb.c} (95%) rename drivers/net/wireless/ath/ath12k/{ahb_wifi7.h => wifi7/ahb.h} (100%) rename drivers/net/wireless/ath/ath12k/{ce_wifi7.c => wifi7/ce.c} (99%) rename drivers/net/wireless/ath/ath12k/{ce_wifi7.h => wifi7/ce.h} (100%) rename drivers/net/wireless/ath/ath12k/{core_wifi7.c => wifi7/core.c} (95%) rename drivers/net/wireless/ath/ath12k/{hw_wifi7.c => wifi7/hw.c} (99%) rename drivers/net/wireless/ath/ath12k/{hw_wifi7.h => wifi7/hw.h} (100%) rename drivers/net/wireless/ath/ath12k/{mhi_wifi7.c => wifi7/mhi.c} (99%) rename drivers/net/wireless/ath/ath12k/{mhi_wifi7.h => wifi7/mhi.h} (100%) rename drivers/net/wireless/ath/ath12k/{pci_wifi7.c => wifi7/pci.c} (97%) rename drivers/net/wireless/ath/ath12k/{pci_wifi7.h => wifi7/pci.h} (100%) rename drivers/net/wireless/ath/ath12k/{wmi_wifi7.c => wifi7/wmi.c} (99%) rename drivers/net/wireless/ath/ath12k/{wmi_wifi7.h => wifi7/wmi.h} (100%) diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index 9c7a32930ed60..8dd77729f52f5 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -1,12 +1,10 @@ # SPDX-License-Identifier: BSD-3-Clause-Clear obj-$(CONFIG_ATH12K) += ath12k.o ath12k-y += core.o \ - core_wifi7.o \ hal.o \ hal_tx.o \ hal_rx.o \ wmi.o \ - wmi_wifi7.o \ mac.o \ reg.o \ htc.o \ @@ -16,19 +14,18 @@ ath12k-y += core.o \ dp_rx.o \ debug.o \ ce.o \ - ce_wifi7.o \ peer.o \ dbring.o \ - hw_wifi7.o \ mhi.o \ - mhi_wifi7.o \ pci.o \ - pci_wifi7.o \ dp_mon.o \ fw.o \ p2p.o -ath12k-$(CONFIG_ATH12K_AHB) += ahb.o ahb_wifi7.o +ath12k-$(CONFIG_ATH12K_AHB) += ahb.o + +obj-$(CONFIG_ATH12K) += wifi7/ + ath12k-$(CONFIG_ATH12K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o ath12k-$(CONFIG_ACPI) += acpi.o ath12k-$(CONFIG_ATH12K_TRACING) += trace.o diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index 777edaf0e58e5..5fe2b5b7db499 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -1183,6 +1183,7 @@ int ath12k_ahb_register_driver(const enum ath12k_device_family device_id, return platform_driver_register(ahb_driver); } +EXPORT_SYMBOL(ath12k_ahb_register_driver); void ath12k_ahb_unregister_driver(const enum ath12k_device_family device_id) { @@ -1198,3 +1199,4 @@ void ath12k_ahb_unregister_driver(const enum ath12k_device_family device_id) platform_driver_unregister(ahb_driver); ath12k_ahb_family_drivers[device_id] = NULL; } +EXPORT_SYMBOL(ath12k_ahb_unregister_driver); diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index b4a8923d6d48d..301d1337ab8bd 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -631,6 +631,7 @@ u32 ath12k_core_get_max_peers_per_radio(struct ath12k_base *ab) { return ath12k_core_get_max_station_per_radio(ab) + TARGET_NUM_VDEVS(ab); } +EXPORT_SYMBOL(ath12k_core_get_max_peers_per_radio); struct reserved_mem *ath12k_core_get_reserved_mem(struct ath12k_base *ab, int index) @@ -1738,6 +1739,7 @@ enum ath12k_qmi_mem_mode ath12k_core_get_memory_mode(struct ath12k_base *ab) return ATH12K_QMI_MEMORY_MODE_DEFAULT; } +EXPORT_SYMBOL(ath12k_core_get_memory_mode); int ath12k_core_pre_init(struct ath12k_base *ab) { @@ -2282,3 +2284,6 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size, kfree(ab); return NULL; } + +MODULE_DESCRIPTION("Driver support for Qualcomm Technologies WLAN devices"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/ath/ath12k/debug.c b/drivers/net/wireless/ath/ath12k/debug.c index 5ce100cd9a9d1..9910c60f30ced 100644 --- a/drivers/net/wireless/ath/ath12k/debug.c +++ b/drivers/net/wireless/ath/ath12k/debug.c @@ -21,6 +21,7 @@ void ath12k_info(struct ath12k_base *ab, const char *fmt, ...) /* TODO: Trace the log */ va_end(args); } +EXPORT_SYMBOL(ath12k_info); void ath12k_err(struct ath12k_base *ab, const char *fmt, ...) { @@ -35,6 +36,7 @@ void ath12k_err(struct ath12k_base *ab, const char *fmt, ...) /* TODO: Trace the log */ va_end(args); } +EXPORT_SYMBOL(ath12k_err); void __ath12k_warn(struct device *dev, const char *fmt, ...) { @@ -49,6 +51,7 @@ void __ath12k_warn(struct device *dev, const char *fmt, ...) /* TODO: Trace the log */ va_end(args); } +EXPORT_SYMBOL(__ath12k_warn); #ifdef CONFIG_ATH12K_DEBUG @@ -72,6 +75,7 @@ void __ath12k_dbg(struct ath12k_base *ab, enum ath12k_debug_mask mask, va_end(args); } +EXPORT_SYMBOL(__ath12k_dbg); void ath12k_dbg_dump(struct ath12k_base *ab, enum ath12k_debug_mask mask, diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index d28d8ffec0f83..cd07bb5b8e9a4 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -2007,6 +2007,7 @@ void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, dev_kfree_skb_any(skb); } +EXPORT_SYMBOL(ath12k_dp_htt_htc_t2h_msg_handler); static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar, struct sk_buff_head *msdu_list, @@ -4563,6 +4564,7 @@ int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab) return ret; } +EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_qcn9274); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) { @@ -4605,6 +4607,7 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) return ret; } +EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_wcn7850); int ath12k_dp_rx_htt_setup(struct ath12k_base *ab) { diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 6406fcf5d69fd..022eea9515efd 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -746,6 +746,7 @@ const struct hal_rx_ops hal_rx_qcn9274_ops = { .rx_desc_get_desc_size = ath12k_hw_qcn9274_get_rx_desc_size, .rx_desc_get_msdu_src_link_id = ath12k_hw_qcn9274_rx_desc_get_msdu_src_link, }; +EXPORT_SYMBOL(hal_rx_qcn9274_ops); static bool ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu(struct hal_rx_desc *desc) { @@ -1093,6 +1094,7 @@ const struct hal_ops hal_qcn9274_ops = { .rxdma_ring_wmask_rx_msdu_end = ath12k_hal_qcn9274_rx_msdu_end_wmask_get, .get_hal_rx_compact_ops = ath12k_hal_qcn9274_get_hal_rx_compact_ops, }; +EXPORT_SYMBOL(hal_qcn9274_ops); static bool ath12k_hw_wcn7850_rx_desc_get_first_msdu(struct hal_rx_desc *desc) { @@ -1552,6 +1554,7 @@ const struct hal_rx_ops hal_rx_wcn7850_ops = { .rx_desc_get_desc_size = ath12k_hw_wcn7850_get_rx_desc_size, .rx_desc_get_msdu_src_link_id = ath12k_hw_wcn7850_rx_desc_get_msdu_src_link, }; +EXPORT_SYMBOL(hal_rx_wcn7850_ops); const struct hal_ops hal_wcn7850_ops = { .create_srng_config = ath12k_hal_srng_create_config_wcn7850, @@ -1560,6 +1563,7 @@ const struct hal_ops hal_wcn7850_ops = { .rxdma_ring_wmask_rx_msdu_end = NULL, .get_hal_rx_compact_ops = NULL, }; +EXPORT_SYMBOL(hal_wcn7850_ops); static int ath12k_hal_alloc_cont_rdp(struct ath12k_base *ab) { diff --git a/drivers/net/wireless/ath/ath12k/htc.c b/drivers/net/wireless/ath/ath12k/htc.c index d13616bf07f43..fe8218a56125b 100644 --- a/drivers/net/wireless/ath/ath12k/htc.c +++ b/drivers/net/wireless/ath/ath12k/htc.c @@ -2,6 +2,7 @@ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. * Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include #include @@ -376,6 +377,7 @@ void ath12k_htc_rx_completion_handler(struct ath12k_base *ab, out: kfree_skb(skb); } +EXPORT_SYMBOL(ath12k_htc_rx_completion_handler); static void ath12k_htc_control_rx_complete(struct ath12k_base *ab, struct sk_buff *skb) diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 3e119cc329de2..850eb9fa6169a 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -1193,6 +1193,7 @@ u32 ath12k_pci_read32(struct ath12k_base *ab, u32 offset) ab_pci->pci_ops->release(ab); return val; } +EXPORT_SYMBOL(ath12k_pci_read32); void ath12k_pci_write32(struct ath12k_base *ab, u32 offset, u32 value) { @@ -1813,6 +1814,7 @@ int ath12k_pci_register_driver(const enum ath12k_device_family device_id, return pci_register_driver(pci_driver); } +EXPORT_SYMBOL(ath12k_pci_register_driver); void ath12k_pci_unregister_driver(const enum ath12k_device_family device_id) { @@ -1823,7 +1825,4 @@ void ath12k_pci_unregister_driver(const enum ath12k_device_family device_id) pci_unregister_driver(&ath12k_pci_family_drivers[device_id]->driver); ath12k_pci_family_drivers[device_id] = NULL; } - -/* firmware files */ -MODULE_FIRMWARE(ATH12K_FW_DIR "/QCN9274/hw2.0/*"); -MODULE_FIRMWARE(ATH12K_FW_DIR "/WCN7850/hw2.0/*"); +EXPORT_SYMBOL(ath12k_pci_unregister_driver); diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index f1ae9e5b5af72..af95324f27086 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -23,6 +23,7 @@ struct ath12k_ml_peer *ath12k_peer_ml_find(struct ath12k_hw *ah, const u8 *addr) return NULL; } +EXPORT_SYMBOL(ath12k_peer_ml_find); struct ath12k_peer *ath12k_peer_find(struct ath12k_base *ab, int vdev_id, const u8 *addr) @@ -78,6 +79,7 @@ struct ath12k_peer *ath12k_peer_find_by_addr(struct ath12k_base *ab, return NULL; } +EXPORT_SYMBOL(ath12k_peer_find_by_addr); static struct ath12k_peer *ath12k_peer_find_by_ml_id(struct ath12k_base *ab, int ml_peer_id) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/Makefile b/drivers/net/wireless/ath/ath12k/wifi7/Makefile new file mode 100644 index 0000000000000..872ca620a5c50 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: BSD-3-Clause-Clear +obj-$(CONFIG_ATH12K) += ath12k_wifi7.o +ath12k_wifi7-y += core.o \ + pci.o \ + wmi.o \ + mhi.o \ + ce.o \ + hw.o + +ath12k_wifi7-$(CONFIG_ATH12K_AHB) += ahb.o diff --git a/drivers/net/wireless/ath/ath12k/ahb_wifi7.c b/drivers/net/wireless/ath/ath12k/wifi7/ahb.c similarity index 95% rename from drivers/net/wireless/ath/ath12k/ahb_wifi7.c rename to drivers/net/wireless/ath/ath12k/wifi7/ahb.c index ff4f041bafbc4..803e13207bc06 100644 --- a/drivers/net/wireless/ath/ath12k/ahb_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/ahb.c @@ -7,11 +7,11 @@ #include #include #include +#include "../ahb.h" #include "ahb.h" -#include "ahb_wifi7.h" -#include "debug.h" -#include "hif.h" -#include "hw_wifi7.h" +#include "../debug.h" +#include "../hif.h" +#include "hw.h" static const struct of_device_id ath12k_wifi7_ahb_of_match[] = { { .compatible = "qcom,ipq5332-wifi", diff --git a/drivers/net/wireless/ath/ath12k/ahb_wifi7.h b/drivers/net/wireless/ath/ath12k/wifi7/ahb.h similarity index 100% rename from drivers/net/wireless/ath/ath12k/ahb_wifi7.h rename to drivers/net/wireless/ath/ath12k/wifi7/ahb.h diff --git a/drivers/net/wireless/ath/ath12k/ce_wifi7.c b/drivers/net/wireless/ath/ath12k/wifi7/ce.c similarity index 99% rename from drivers/net/wireless/ath/ath12k/ce_wifi7.c rename to drivers/net/wireless/ath/ath12k/wifi7/ce.c index cf27259d15a0e..b4bd1136c2565 100644 --- a/drivers/net/wireless/ath/ath12k/ce_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/ce.c @@ -8,10 +8,10 @@ #include #include -#include "core.h" +#include "../core.h" +#include "../ce.h" #include "ce.h" -#include "ce_wifi7.h" -#include "dp_rx.h" +#include "../dp_rx.h" /* Copy Engine (CE) configs for QCN9274 */ /* Target firmware's Copy Engine configuration. */ diff --git a/drivers/net/wireless/ath/ath12k/ce_wifi7.h b/drivers/net/wireless/ath/ath12k/wifi7/ce.h similarity index 100% rename from drivers/net/wireless/ath/ath12k/ce_wifi7.h rename to drivers/net/wireless/ath/ath12k/wifi7/ce.h diff --git a/drivers/net/wireless/ath/ath12k/core_wifi7.c b/drivers/net/wireless/ath/ath12k/wifi7/core.c similarity index 95% rename from drivers/net/wireless/ath/ath12k/core_wifi7.c rename to drivers/net/wireless/ath/ath12k/wifi7/core.c index 85ea8904672cb..eb882e56e5ec2 100644 --- a/drivers/net/wireless/ath/ath12k/core_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/core.c @@ -5,10 +5,10 @@ */ #include -#include "ahb.h" +#include "../ahb.h" +#include "../pci.h" #include "pci.h" -#include "pci_wifi7.h" -#include "ahb_wifi7.h" +#include "ahb.h" static int ahb_err, pci_err; diff --git a/drivers/net/wireless/ath/ath12k/hw_wifi7.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c similarity index 99% rename from drivers/net/wireless/ath/ath12k/hw_wifi7.c rename to drivers/net/wireless/ath/ath12k/wifi7/hw.c index 5f5d3c57b288c..93f558847baed 100644 --- a/drivers/net/wireless/ath/ath12k/hw_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -8,17 +8,17 @@ #include #include -#include "debug.h" -#include "core.h" +#include "../debug.h" +#include "../core.h" +#include "../ce.h" #include "ce.h" -#include "ce_wifi7.h" +#include "../hw.h" #include "hw.h" -#include "hw_wifi7.h" +#include "../mhi.h" #include "mhi.h" -#include "dp_rx.h" -#include "peer.h" -#include "wmi_wifi7.h" -#include "mhi_wifi7.h" +#include "../dp_rx.h" +#include "../peer.h" +#include "wmi.h" static const guid_t wcn7850_uuid = GUID_INIT(0xf634f534, 0x6147, 0x11ec, 0x90, 0xd6, 0x02, 0x42, diff --git a/drivers/net/wireless/ath/ath12k/hw_wifi7.h b/drivers/net/wireless/ath/ath12k/wifi7/hw.h similarity index 100% rename from drivers/net/wireless/ath/ath12k/hw_wifi7.h rename to drivers/net/wireless/ath/ath12k/wifi7/hw.h diff --git a/drivers/net/wireless/ath/ath12k/mhi_wifi7.c b/drivers/net/wireless/ath/ath12k/wifi7/mhi.c similarity index 99% rename from drivers/net/wireless/ath/ath12k/mhi_wifi7.c rename to drivers/net/wireless/ath/ath12k/wifi7/mhi.c index be74df152f6f8..74d5f09645311 100644 --- a/drivers/net/wireless/ath/ath12k/mhi_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/mhi.c @@ -4,8 +4,8 @@ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ +#include "../mhi.h" #include "mhi.h" -#include "mhi_wifi7.h" static const struct mhi_channel_config ath12k_mhi_channels_qcn9274[] = { { diff --git a/drivers/net/wireless/ath/ath12k/mhi_wifi7.h b/drivers/net/wireless/ath/ath12k/wifi7/mhi.h similarity index 100% rename from drivers/net/wireless/ath/ath12k/mhi_wifi7.h rename to drivers/net/wireless/ath/ath12k/wifi7/mhi.h diff --git a/drivers/net/wireless/ath/ath12k/pci_wifi7.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c similarity index 97% rename from drivers/net/wireless/ath/ath12k/pci_wifi7.c rename to drivers/net/wireless/ath/ath12k/wifi7/pci.c index a680cd9a04e33..01a0b42f0e808 100644 --- a/drivers/net/wireless/ath/ath12k/pci_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -6,12 +6,12 @@ #include +#include "../pci.h" #include "pci.h" -#include "pci_wifi7.h" -#include "core.h" -#include "hif.h" -#include "mhi.h" -#include "hw_wifi7.h" +#include "../core.h" +#include "../hif.h" +#include "../mhi.h" +#include "hw.h" #define QCN9274_DEVICE_ID 0x1109 #define WCN7850_DEVICE_ID 0x1107 diff --git a/drivers/net/wireless/ath/ath12k/pci_wifi7.h b/drivers/net/wireless/ath/ath12k/wifi7/pci.h similarity index 100% rename from drivers/net/wireless/ath/ath12k/pci_wifi7.h rename to drivers/net/wireless/ath/ath12k/wifi7/pci.h diff --git a/drivers/net/wireless/ath/ath12k/wmi_wifi7.c b/drivers/net/wireless/ath/ath12k/wifi7/wmi.c similarity index 99% rename from drivers/net/wireless/ath/ath12k/wmi_wifi7.c rename to drivers/net/wireless/ath/ath12k/wifi7/wmi.c index f27fa56210e83..652c353f9fc58 100644 --- a/drivers/net/wireless/ath/ath12k/wmi_wifi7.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/wmi.c @@ -4,8 +4,8 @@ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ -#include "core.h" -#include "wmi_wifi7.h" +#include "../core.h" +#include "wmi.h" void ath12k_wmi_init_qcn9274(struct ath12k_base *ab, struct ath12k_wmi_resource_config_arg *config) diff --git a/drivers/net/wireless/ath/ath12k/wmi_wifi7.h b/drivers/net/wireless/ath/ath12k/wifi7/wmi.h similarity index 100% rename from drivers/net/wireless/ath/ath12k/wmi_wifi7.h rename to drivers/net/wireless/ath/ath12k/wifi7/wmi.h From 55c62028f547e6ecc964b0abbd767c7de746efd2 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:37 +0530 Subject: [PATCH 011/140] wifi: ath12k: Rename ath12k_* symbols to ath12k_wifi7_* for clarity Rename functions and global definitions from ath12k_* to ath12k_wifi7_* to reflect their association with the Wi-Fi 7 specific module. Align symbol naming with recent relocation of components into the ath12k/wifi7 directory. This change improves code clarity and supports the modularization effort that separates common and hardware-specific logic into distinct modules. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.3.1-00130-QCAHKSWPL_SILICONZ-1 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-11-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wifi7/ce.c | 21 +-- drivers/net/wireless/ath/ath12k/wifi7/ce.h | 18 +-- drivers/net/wireless/ath/ath12k/wifi7/hw.c | 150 +++++++++++--------- drivers/net/wireless/ath/ath12k/wifi7/mhi.c | 28 ++-- drivers/net/wireless/ath/ath12k/wifi7/mhi.h | 4 +- drivers/net/wireless/ath/ath12k/wifi7/pci.c | 13 +- drivers/net/wireless/ath/ath12k/wifi7/wmi.c | 8 +- drivers/net/wireless/ath/ath12k/wifi7/wmi.h | 8 +- 8 files changed, 132 insertions(+), 118 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/ce.c b/drivers/net/wireless/ath/ath12k/wifi7/ce.c index b4bd1136c2565..952d6c39c3334 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/ce.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/ce.c @@ -15,7 +15,7 @@ /* Copy Engine (CE) configs for QCN9274 */ /* Target firmware's Copy Engine configuration. */ -const struct ce_pipe_config ath12k_target_ce_config_wlan_qcn9274[] = { +const struct ce_pipe_config ath12k_wifi7_target_ce_config_wlan_qcn9274[] = { /* CE0: host->target HTC control and raw streams */ { .pipenum = __cpu_to_le32(0), @@ -148,7 +148,8 @@ const struct ce_pipe_config ath12k_target_ce_config_wlan_qcn9274[] = { * PIPEDIR_OUT = UL = host -> target * PIPEDIR_IN = DL = target -> host */ -const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_qcn9274[] = { +const struct service_to_pipe +ath12k_wifi7_target_service_to_ce_map_wlan_qcn9274[] = { { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), __cpu_to_le32(PIPEDIR_OUT), @@ -259,7 +260,7 @@ const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_qcn9274[] = { }, }; -const struct ce_attr ath12k_host_ce_config_qcn9274[] = { +const struct ce_attr ath12k_wifi7_host_ce_config_qcn9274[] = { /* CE0: host->target HTC control and raw streams */ { .flags = CE_ATTR_FLAGS, @@ -395,7 +396,7 @@ const struct ce_attr ath12k_host_ce_config_qcn9274[] = { /* Copy Engine (CE) configs for WCN7850 */ /* Target firmware's Copy Engine configuration. */ -const struct ce_pipe_config ath12k_target_ce_config_wlan_wcn7850[] = { +const struct ce_pipe_config ath12k_wifi7_target_ce_config_wlan_wcn7850[] = { /* CE0: host->target HTC control and raw streams */ { .pipenum = __cpu_to_le32(0), @@ -488,7 +489,8 @@ const struct ce_pipe_config ath12k_target_ce_config_wlan_wcn7850[] = { /* CE 9, 10, 11 are used by MHI driver */ }; -const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_wcn7850[] = { +const struct service_to_pipe +ath12k_wifi7_target_service_to_ce_map_wlan_wcn7850[] = { { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), __cpu_to_le32(PIPEDIR_OUT), @@ -569,7 +571,7 @@ const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_wcn7850[] = { }, }; -const struct ce_attr ath12k_host_ce_config_wcn7850[] = { +const struct ce_attr ath12k_wifi7_host_ce_config_wcn7850[] = { /* CE0: host->target HTC control and raw streams */ { .flags = CE_ATTR_FLAGS, @@ -647,7 +649,7 @@ const struct ce_attr ath12k_host_ce_config_wcn7850[] = { /* Copy Engine (CE) configs for IPQ5332 */ /* Target firmware's Copy Engine configuration. */ -const struct ce_pipe_config ath12k_target_ce_config_wlan_ipq5332[] = { +const struct ce_pipe_config ath12k_wifi7_target_ce_config_wlan_ipq5332[] = { /* CE0: host->target HTC control and raw streams */ { .pipenum = __cpu_to_le32(0), @@ -768,7 +770,8 @@ const struct ce_pipe_config ath12k_target_ce_config_wlan_ipq5332[] = { }, }; -const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_ipq5332[] = { +const struct service_to_pipe +ath12k_wifi7_target_service_to_ce_map_wlan_ipq5332[] = { { __cpu_to_le32(ATH12K_HTC_SVC_ID_WMI_DATA_VO), __cpu_to_le32(PIPEDIR_OUT), @@ -868,7 +871,7 @@ const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_ipq5332[] = { }, }; -const struct ce_attr ath12k_host_ce_config_ipq5332[] = { +const struct ce_attr ath12k_wifi7_host_ce_config_ipq5332[] = { /* CE0: host->target HTC control and raw streams */ { .flags = CE_ATTR_FLAGS, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/ce.h b/drivers/net/wireless/ath/ath12k/wifi7/ce.h index 1e211e8c24672..369a14472913b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/ce.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/ce.h @@ -7,16 +7,16 @@ #ifndef ATH12K_WIFI7_CE_H #define ATH12K_WIFI7_CE_H -extern const struct ce_pipe_config ath12k_target_ce_config_wlan_qcn9274[]; -extern const struct ce_pipe_config ath12k_target_ce_config_wlan_wcn7850[]; -extern const struct ce_pipe_config ath12k_target_ce_config_wlan_ipq5332[]; +extern const struct ce_pipe_config ath12k_wifi7_target_ce_config_wlan_qcn9274[]; +extern const struct ce_pipe_config ath12k_wifi7_target_ce_config_wlan_wcn7850[]; +extern const struct ce_pipe_config ath12k_wifi7_target_ce_config_wlan_ipq5332[]; -extern const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_qcn9274[]; -extern const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_wcn7850[]; -extern const struct service_to_pipe ath12k_target_service_to_ce_map_wlan_ipq5332[]; +extern const struct service_to_pipe ath12k_wifi7_target_service_to_ce_map_wlan_qcn9274[]; +extern const struct service_to_pipe ath12k_wifi7_target_service_to_ce_map_wlan_wcn7850[]; +extern const struct service_to_pipe ath12k_wifi7_target_service_to_ce_map_wlan_ipq5332[]; -extern const struct ce_attr ath12k_host_ce_config_qcn9274[]; -extern const struct ce_attr ath12k_host_ce_config_wcn7850[]; -extern const struct ce_attr ath12k_host_ce_config_ipq5332[]; +extern const struct ce_attr ath12k_wifi7_host_ce_config_qcn9274[]; +extern const struct ce_attr ath12k_wifi7_host_ce_config_wcn7850[]; +extern const struct ce_attr ath12k_wifi7_host_ce_config_ipq5332[]; #endif /* ATH12K_WIFI7_CE_H */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 93f558847baed..9995eccd32d39 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -24,29 +24,31 @@ static const guid_t wcn7850_uuid = GUID_INIT(0xf634f534, 0x6147, 0x11ec, 0x90, 0xd6, 0x02, 0x42, 0xac, 0x12, 0x00, 0x03); -static u8 ath12k_hw_qcn9274_mac_from_pdev_id(int pdev_idx) +static u8 ath12k_wifi7_hw_qcn9274_mac_from_pdev_id(int pdev_idx) { return pdev_idx; } -static int ath12k_hw_mac_id_to_pdev_id_qcn9274(const struct ath12k_hw_params *hw, - int mac_id) +static int +ath12k_wifi7_hw_mac_id_to_pdev_id_qcn9274(const struct ath12k_hw_params *hw, + int mac_id) { return mac_id; } -static int ath12k_hw_mac_id_to_srng_id_qcn9274(const struct ath12k_hw_params *hw, - int mac_id) +static int +ath12k_wifi7_hw_mac_id_to_srng_id_qcn9274(const struct ath12k_hw_params *hw, + int mac_id) { return 0; } -static u8 ath12k_hw_get_ring_selector_qcn9274(struct sk_buff *skb) +static u8 ath12k_wifi7_hw_get_ring_selector_qcn9274(struct sk_buff *skb) { return smp_processor_id(); } -static bool ath12k_dp_srng_is_comp_ring_qcn9274(int ring_num) +static bool ath12k_wifi7_dp_srng_is_comp_ring_qcn9274(int ring_num) { if (ring_num < 3 || ring_num == 4) return true; @@ -54,30 +56,33 @@ static bool ath12k_dp_srng_is_comp_ring_qcn9274(int ring_num) return false; } -static bool ath12k_is_frame_link_agnostic_qcn9274(struct ath12k_link_vif *arvif, - struct ieee80211_mgmt *mgmt) +static bool +ath12k_wifi7_is_frame_link_agnostic_qcn9274(struct ath12k_link_vif *arvif, + struct ieee80211_mgmt *mgmt) { return ieee80211_is_action(mgmt->frame_control); } -static int ath12k_hw_mac_id_to_pdev_id_wcn7850(const struct ath12k_hw_params *hw, - int mac_id) +static int +ath12k_wifi7_hw_mac_id_to_pdev_id_wcn7850(const struct ath12k_hw_params *hw, + int mac_id) { return 0; } -static int ath12k_hw_mac_id_to_srng_id_wcn7850(const struct ath12k_hw_params *hw, - int mac_id) +static int +ath12k_wifi7_hw_mac_id_to_srng_id_wcn7850(const struct ath12k_hw_params *hw, + int mac_id) { return mac_id; } -static u8 ath12k_hw_get_ring_selector_wcn7850(struct sk_buff *skb) +static u8 ath12k_wifi7_hw_get_ring_selector_wcn7850(struct sk_buff *skb) { return skb_get_queue_mapping(skb); } -static bool ath12k_dp_srng_is_comp_ring_wcn7850(int ring_num) +static bool ath12k_wifi7_dp_srng_is_comp_ring_wcn7850(int ring_num) { if (ring_num == 0 || ring_num == 2 || ring_num == 4) return true; @@ -99,8 +104,9 @@ static bool ath12k_is_addba_resp_action_code(struct ieee80211_mgmt *mgmt) return true; } -static bool ath12k_is_frame_link_agnostic_wcn7850(struct ath12k_link_vif *arvif, - struct ieee80211_mgmt *mgmt) +static bool +ath12k_wifi7_is_frame_link_agnostic_wcn7850(struct ath12k_link_vif *arvif, + struct ieee80211_mgmt *mgmt) { struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif); struct ath12k_hw *ah = ath12k_ar_to_ah(arvif->ar); @@ -132,23 +138,23 @@ static bool ath12k_is_frame_link_agnostic_wcn7850(struct ath12k_link_vif *arvif, } static const struct ath12k_hw_ops qcn9274_ops = { - .get_hw_mac_from_pdev_id = ath12k_hw_qcn9274_mac_from_pdev_id, - .mac_id_to_pdev_id = ath12k_hw_mac_id_to_pdev_id_qcn9274, - .mac_id_to_srng_id = ath12k_hw_mac_id_to_srng_id_qcn9274, + .get_hw_mac_from_pdev_id = ath12k_wifi7_hw_qcn9274_mac_from_pdev_id, + .mac_id_to_pdev_id = ath12k_wifi7_hw_mac_id_to_pdev_id_qcn9274, + .mac_id_to_srng_id = ath12k_wifi7_hw_mac_id_to_srng_id_qcn9274, .rxdma_ring_sel_config = ath12k_dp_rxdma_ring_sel_config_qcn9274, - .get_ring_selector = ath12k_hw_get_ring_selector_qcn9274, - .dp_srng_is_tx_comp_ring = ath12k_dp_srng_is_comp_ring_qcn9274, - .is_frame_link_agnostic = ath12k_is_frame_link_agnostic_qcn9274, + .get_ring_selector = ath12k_wifi7_hw_get_ring_selector_qcn9274, + .dp_srng_is_tx_comp_ring = ath12k_wifi7_dp_srng_is_comp_ring_qcn9274, + .is_frame_link_agnostic = ath12k_wifi7_is_frame_link_agnostic_qcn9274, }; static const struct ath12k_hw_ops wcn7850_ops = { - .get_hw_mac_from_pdev_id = ath12k_hw_qcn9274_mac_from_pdev_id, - .mac_id_to_pdev_id = ath12k_hw_mac_id_to_pdev_id_wcn7850, - .mac_id_to_srng_id = ath12k_hw_mac_id_to_srng_id_wcn7850, + .get_hw_mac_from_pdev_id = ath12k_wifi7_hw_qcn9274_mac_from_pdev_id, + .mac_id_to_pdev_id = ath12k_wifi7_hw_mac_id_to_pdev_id_wcn7850, + .mac_id_to_srng_id = ath12k_wifi7_hw_mac_id_to_srng_id_wcn7850, .rxdma_ring_sel_config = ath12k_dp_rxdma_ring_sel_config_wcn7850, - .get_ring_selector = ath12k_hw_get_ring_selector_wcn7850, - .dp_srng_is_tx_comp_ring = ath12k_dp_srng_is_comp_ring_wcn7850, - .is_frame_link_agnostic = ath12k_is_frame_link_agnostic_wcn7850, + .get_ring_selector = ath12k_wifi7_hw_get_ring_selector_wcn7850, + .dp_srng_is_tx_comp_ring = ath12k_wifi7_dp_srng_is_comp_ring_wcn7850, + .is_frame_link_agnostic = ath12k_wifi7_is_frame_link_agnostic_wcn7850, }; #define ATH12K_TX_RING_MASK_0 0x1 @@ -181,7 +187,7 @@ static const struct ath12k_hw_ops wcn7850_ops = { #define ATH12K_RX_MON_STATUS_RING_MASK_1 0x2 #define ATH12K_RX_MON_STATUS_RING_MASK_2 0x4 -static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qcn9274 = { +static const struct ath12k_hw_ring_mask ath12k_wifi7_hw_ring_mask_qcn9274 = { .tx = { ATH12K_TX_RING_MASK_0, ATH12K_TX_RING_MASK_1, @@ -223,7 +229,7 @@ static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_qcn9274 = { }, }; -static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_ipq5332 = { +static const struct ath12k_hw_ring_mask ath12k_wifi7_hw_ring_mask_ipq5332 = { .tx = { ATH12K_TX_RING_MASK_0, ATH12K_TX_RING_MASK_1, @@ -263,7 +269,7 @@ static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_ipq5332 = { }, }; -static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_wcn7850 = { +static const struct ath12k_hw_ring_mask ath12k_wifi7_hw_ring_mask_wcn7850 = { .tx = { ATH12K_TX_RING_MASK_0, ATH12K_TX_RING_MASK_1, @@ -654,7 +660,7 @@ static const struct ath12k_hw_regs wcn7850_regs = { .gcc_gcc_pcie_hot_rst = 0x1e40304, }; -static const struct ath12k_hw_hal_params ath12k_hw_hal_params_qcn9274 = { +static const struct ath12k_hw_hal_params ath12k_wifi7_hw_hal_params_qcn9274 = { .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW1_EN | @@ -663,7 +669,7 @@ static const struct ath12k_hw_hal_params ath12k_hw_hal_params_qcn9274 = { HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, }; -static const struct ath12k_hw_hal_params ath12k_hw_hal_params_wcn7850 = { +static const struct ath12k_hw_hal_params ath12k_wifi7_hw_hal_params_wcn7850 = { .rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM, .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN | @@ -671,7 +677,7 @@ static const struct ath12k_hw_hal_params ath12k_hw_hal_params_wcn7850 = { HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, }; -static const struct ath12k_hw_hal_params ath12k_hw_hal_params_ipq5332 = { +static const struct ath12k_hw_hal_params ath12k_wifi7_hw_hal_params_ipq5332 = { .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW1_EN | @@ -680,18 +686,18 @@ static const struct ath12k_hw_hal_params ath12k_hw_hal_params_ipq5332 = { HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, }; -static const struct ce_ie_addr ath12k_ce_ie_addr_ipq5332 = { +static const struct ce_ie_addr ath12k_wifi7_ce_ie_addr_ipq5332 = { .ie1_reg_addr = CE_HOST_IE_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE, .ie2_reg_addr = CE_HOST_IE_2_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE, .ie3_reg_addr = CE_HOST_IE_3_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE, }; -static const struct ce_remap ath12k_ce_remap_ipq5332 = { +static const struct ce_remap ath12k_wifi7_ce_remap_ipq5332 = { .base = HAL_IPQ5332_CE_WFSS_REG_BASE, .size = HAL_IPQ5332_CE_SIZE, }; -static const struct ath12k_hw_params ath12k_hw_params[] = { +static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { { .name = "qcn9274 hw1.0", .hw_rev = ATH12K_HW_QCN9274_HW10, @@ -707,17 +713,18 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .internal_sleep_clock = false, .hw_ops = &qcn9274_ops, - .ring_mask = &ath12k_hw_ring_mask_qcn9274, + .ring_mask = &ath12k_wifi7_hw_ring_mask_qcn9274, .regs = &qcn9274_v1_regs, - .host_ce_config = ath12k_host_ce_config_qcn9274, + .host_ce_config = ath12k_wifi7_host_ce_config_qcn9274, .ce_count = 16, - .target_ce_config = ath12k_target_ce_config_wlan_qcn9274, + .target_ce_config = ath12k_wifi7_target_ce_config_wlan_qcn9274, .target_ce_count = 12, - .svc_to_ce_map = ath12k_target_service_to_ce_map_wlan_qcn9274, + .svc_to_ce_map = + ath12k_wifi7_target_service_to_ce_map_wlan_qcn9274, .svc_to_ce_map_len = 18, - .hal_params = &ath12k_hw_hal_params_qcn9274, + .hal_params = &ath12k_wifi7_hw_hal_params_qcn9274, .rxdma1_enable = false, .num_rxdma_per_pdev = 1, @@ -741,9 +748,9 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .num_tcl_banks = 48, .max_tx_ring = 4, - .mhi_config = &ath12k_mhi_config_qcn9274, + .mhi_config = &ath12k_wifi7_mhi_config_qcn9274, - .wmi_init = ath12k_wmi_init_qcn9274, + .wmi_init = ath12k_wifi7_wmi_init_qcn9274, .hal_ops = &hal_qcn9274_ops, @@ -794,17 +801,18 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .internal_sleep_clock = true, .hw_ops = &wcn7850_ops, - .ring_mask = &ath12k_hw_ring_mask_wcn7850, + .ring_mask = &ath12k_wifi7_hw_ring_mask_wcn7850, .regs = &wcn7850_regs, - .host_ce_config = ath12k_host_ce_config_wcn7850, + .host_ce_config = ath12k_wifi7_host_ce_config_wcn7850, .ce_count = 9, - .target_ce_config = ath12k_target_ce_config_wlan_wcn7850, + .target_ce_config = ath12k_wifi7_target_ce_config_wlan_wcn7850, .target_ce_count = 9, - .svc_to_ce_map = ath12k_target_service_to_ce_map_wlan_wcn7850, + .svc_to_ce_map = + ath12k_wifi7_target_service_to_ce_map_wlan_wcn7850, .svc_to_ce_map_len = 14, - .hal_params = &ath12k_hw_hal_params_wcn7850, + .hal_params = &ath12k_wifi7_hw_hal_params_wcn7850, .rxdma1_enable = false, .num_rxdma_per_pdev = 2, @@ -829,9 +837,9 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .num_tcl_banks = 7, .max_tx_ring = 3, - .mhi_config = &ath12k_mhi_config_wcn7850, + .mhi_config = &ath12k_wifi7_mhi_config_wcn7850, - .wmi_init = ath12k_wmi_init_wcn7850, + .wmi_init = ath12k_wifi7_wmi_init_wcn7850, .hal_ops = &hal_wcn7850_ops, @@ -881,17 +889,18 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .internal_sleep_clock = false, .hw_ops = &qcn9274_ops, - .ring_mask = &ath12k_hw_ring_mask_qcn9274, + .ring_mask = &ath12k_wifi7_hw_ring_mask_qcn9274, .regs = &qcn9274_v2_regs, - .host_ce_config = ath12k_host_ce_config_qcn9274, + .host_ce_config = ath12k_wifi7_host_ce_config_qcn9274, .ce_count = 16, - .target_ce_config = ath12k_target_ce_config_wlan_qcn9274, + .target_ce_config = ath12k_wifi7_target_ce_config_wlan_qcn9274, .target_ce_count = 12, - .svc_to_ce_map = ath12k_target_service_to_ce_map_wlan_qcn9274, + .svc_to_ce_map = + ath12k_wifi7_target_service_to_ce_map_wlan_qcn9274, .svc_to_ce_map_len = 18, - .hal_params = &ath12k_hw_hal_params_qcn9274, + .hal_params = &ath12k_wifi7_hw_hal_params_qcn9274, .rxdma1_enable = true, .num_rxdma_per_pdev = 1, @@ -915,9 +924,9 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .num_tcl_banks = 48, .max_tx_ring = 4, - .mhi_config = &ath12k_mhi_config_qcn9274, + .mhi_config = &ath12k_wifi7_mhi_config_qcn9274, - .wmi_init = ath12k_wmi_init_qcn9274, + .wmi_init = ath12k_wifi7_wmi_init_qcn9274, .hal_ops = &hal_qcn9274_ops, @@ -967,16 +976,17 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .hw_ops = &qcn9274_ops, .regs = &ipq5332_regs, - .ring_mask = &ath12k_hw_ring_mask_ipq5332, + .ring_mask = &ath12k_wifi7_hw_ring_mask_ipq5332, - .host_ce_config = ath12k_host_ce_config_ipq5332, + .host_ce_config = ath12k_wifi7_host_ce_config_ipq5332, .ce_count = 12, - .target_ce_config = ath12k_target_ce_config_wlan_ipq5332, + .target_ce_config = ath12k_wifi7_target_ce_config_wlan_ipq5332, .target_ce_count = 12, - .svc_to_ce_map = ath12k_target_service_to_ce_map_wlan_ipq5332, + .svc_to_ce_map = + ath12k_wifi7_target_service_to_ce_map_wlan_ipq5332, .svc_to_ce_map_len = 18, - .hal_params = &ath12k_hw_hal_params_ipq5332, + .hal_params = &ath12k_wifi7_hw_hal_params_ipq5332, .rxdma1_enable = false, .num_rxdma_per_pdev = 1, @@ -999,7 +1009,7 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .num_tcl_banks = 48, .max_tx_ring = 4, - .wmi_init = &ath12k_wmi_init_qcn9274, + .wmi_init = &ath12k_wifi7_wmi_init_qcn9274, .hal_ops = &hal_qcn9274_ops, @@ -1023,8 +1033,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = { .iova_mask = 0, .supports_aspm = false, - .ce_ie_addr = &ath12k_ce_ie_addr_ipq5332, - .ce_remap = &ath12k_ce_remap_ipq5332, + .ce_ie_addr = &ath12k_wifi7_ce_ie_addr_ipq5332, + .ce_remap = &ath12k_wifi7_ce_remap_ipq5332, .bdf_addr_offset = 0xC00000, .dp_primary_link_only = true, @@ -1036,14 +1046,14 @@ int ath12k_wifi7_hw_init(struct ath12k_base *ab) const struct ath12k_hw_params *hw_params = NULL; int i; - for (i = 0; i < ARRAY_SIZE(ath12k_hw_params); i++) { - hw_params = &ath12k_hw_params[i]; + for (i = 0; i < ARRAY_SIZE(ath12k_wifi7_hw_params); i++) { + hw_params = &ath12k_wifi7_hw_params[i]; if (hw_params->hw_rev == ab->hw_rev) break; } - if (i == ARRAY_SIZE(ath12k_hw_params)) { + if (i == ARRAY_SIZE(ath12k_wifi7_hw_params)) { ath12k_err(ab, "Unsupported Wi-Fi 7 hardware version: 0x%x\n", ab->hw_rev); return -EINVAL; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/mhi.c b/drivers/net/wireless/ath/ath12k/wifi7/mhi.c index 74d5f09645311..b8d972659314b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/mhi.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/mhi.c @@ -7,7 +7,7 @@ #include "../mhi.h" #include "mhi.h" -static const struct mhi_channel_config ath12k_mhi_channels_qcn9274[] = { +static const struct mhi_channel_config ath12k_wifi7_mhi_channels_qcn9274[] = { { .num = 20, .name = "IPCR", @@ -38,7 +38,7 @@ static const struct mhi_channel_config ath12k_mhi_channels_qcn9274[] = { }, }; -static struct mhi_event_config ath12k_mhi_events_qcn9274[] = { +static struct mhi_event_config ath12k_wifi7_mhi_events_qcn9274[] = { { .num_elements = 32, .irq_moderation_ms = 0, @@ -61,18 +61,18 @@ static struct mhi_event_config ath12k_mhi_events_qcn9274[] = { }, }; -const struct mhi_controller_config ath12k_mhi_config_qcn9274 = { +const struct mhi_controller_config ath12k_wifi7_mhi_config_qcn9274 = { .max_channels = 30, .timeout_ms = 10000, .use_bounce_buf = false, .buf_len = 0, - .num_channels = ARRAY_SIZE(ath12k_mhi_channels_qcn9274), - .ch_cfg = ath12k_mhi_channels_qcn9274, - .num_events = ARRAY_SIZE(ath12k_mhi_events_qcn9274), - .event_cfg = ath12k_mhi_events_qcn9274, + .num_channels = ARRAY_SIZE(ath12k_wifi7_mhi_channels_qcn9274), + .ch_cfg = ath12k_wifi7_mhi_channels_qcn9274, + .num_events = ARRAY_SIZE(ath12k_wifi7_mhi_events_qcn9274), + .event_cfg = ath12k_wifi7_mhi_events_qcn9274, }; -static const struct mhi_channel_config ath12k_mhi_channels_wcn7850[] = { +static const struct mhi_channel_config ath12k_wifi7_mhi_channels_wcn7850[] = { { .num = 20, .name = "IPCR", @@ -103,7 +103,7 @@ static const struct mhi_channel_config ath12k_mhi_channels_wcn7850[] = { }, }; -static struct mhi_event_config ath12k_mhi_events_wcn7850[] = { +static struct mhi_event_config ath12k_wifi7_mhi_events_wcn7850[] = { { .num_elements = 32, .irq_moderation_ms = 0, @@ -126,13 +126,13 @@ static struct mhi_event_config ath12k_mhi_events_wcn7850[] = { }, }; -const struct mhi_controller_config ath12k_mhi_config_wcn7850 = { +const struct mhi_controller_config ath12k_wifi7_mhi_config_wcn7850 = { .max_channels = 128, .timeout_ms = 2000, .use_bounce_buf = false, .buf_len = 8192, - .num_channels = ARRAY_SIZE(ath12k_mhi_channels_wcn7850), - .ch_cfg = ath12k_mhi_channels_wcn7850, - .num_events = ARRAY_SIZE(ath12k_mhi_events_wcn7850), - .event_cfg = ath12k_mhi_events_wcn7850, + .num_channels = ARRAY_SIZE(ath12k_wifi7_mhi_channels_wcn7850), + .ch_cfg = ath12k_wifi7_mhi_channels_wcn7850, + .num_events = ARRAY_SIZE(ath12k_wifi7_mhi_events_wcn7850), + .event_cfg = ath12k_wifi7_mhi_events_wcn7850, }; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/mhi.h b/drivers/net/wireless/ath/ath12k/wifi7/mhi.h index 8417a2bde0877..2e2dd3503d830 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/mhi.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/mhi.h @@ -6,6 +6,6 @@ #ifndef _ATH12K_WIFI7_MHI_H #define _ATH12K_WIFI7_MHI_H -extern const struct mhi_controller_config ath12k_mhi_config_qcn9274; -extern const struct mhi_controller_config ath12k_mhi_config_wcn7850; +extern const struct mhi_controller_config ath12k_wifi7_mhi_config_qcn9274; +extern const struct mhi_controller_config ath12k_wifi7_mhi_config_wcn7850; #endif /* _ATH12K_WIFI7_MHI_H */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/pci.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c index 01a0b42f0e808..608669a83ea75 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/pci.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -12,6 +12,7 @@ #include "../hif.h" #include "../mhi.h" #include "hw.h" +#include "../hal.h" #define QCN9274_DEVICE_ID 0x1109 #define WCN7850_DEVICE_ID 0x1107 @@ -44,7 +45,7 @@ static const struct ath12k_msi_config ath12k_wifi7_msi_config[] = { }, }; -static const struct ath12k_pci_ops ath12k_pci_ops_qcn9274 = { +static const struct ath12k_pci_ops ath12k_wifi7_pci_ops_qcn9274 = { .wakeup = NULL, .release = NULL, }; @@ -63,7 +64,7 @@ static void ath12k_wifi7_pci_bus_release(struct ath12k_base *ab) mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); } -static const struct ath12k_pci_ops ath12k_pci_ops_wcn7850 = { +static const struct ath12k_pci_ops ath12k_wifi7_pci_ops_wcn7850 = { .wakeup = ath12k_wifi7_pci_bus_wake_up, .release = ath12k_wifi7_pci_bus_release, }; @@ -99,7 +100,7 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, case QCN9274_DEVICE_ID: ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; ab->static_window_map = true; - ab_pci->pci_ops = &ath12k_pci_ops_qcn9274; + ab_pci->pci_ops = &ath12k_wifi7_pci_ops_qcn9274; ab->hal_rx_ops = &hal_rx_qcn9274_ops; ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major, &soc_hw_version_minor); @@ -122,7 +123,7 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, ab->id.bdf_search = ATH12K_BDF_SEARCH_BUS_AND_BOARD; ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; ab->static_window_map = false; - ab_pci->pci_ops = &ath12k_pci_ops_wcn7850; + ab_pci->pci_ops = &ath12k_wifi7_pci_ops_wcn7850; ab->hal_rx_ops = &hal_rx_wcn7850_ops; ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major, &soc_hw_version_minor); @@ -154,7 +155,7 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, return 0; } -static struct ath12k_pci_driver ath12k_pci_wifi7_driver = { +static struct ath12k_pci_driver ath12k_wifi7_pci_driver = { .name = "ath12k_wifi7_pci", .id_table = ath12k_wifi7_pci_id_table, .ops.probe = ath12k_wifi7_pci_probe, @@ -165,7 +166,7 @@ int ath12k_wifi7_pci_init(void) int ret; ret = ath12k_pci_register_driver(ATH12K_DEVICE_FAMILY_WIFI7, - &ath12k_pci_wifi7_driver); + &ath12k_wifi7_pci_driver); if (ret) { pr_err("Failed to register ath12k Wi-Fi 7 driver: %d\n", ret); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/wmi.c b/drivers/net/wireless/ath/ath12k/wifi7/wmi.c index 652c353f9fc58..c575b44a33f3b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/wmi.c @@ -7,8 +7,8 @@ #include "../core.h" #include "wmi.h" -void ath12k_wmi_init_qcn9274(struct ath12k_base *ab, - struct ath12k_wmi_resource_config_arg *config) +void ath12k_wifi7_wmi_init_qcn9274(struct ath12k_base *ab, + struct ath12k_wmi_resource_config_arg *config) { config->num_vdevs = ab->num_radios * TARGET_NUM_VDEVS(ab); config->num_peers = ab->num_radios * @@ -58,8 +58,8 @@ void ath12k_wmi_init_qcn9274(struct ath12k_base *ab, config->peer_metadata_ver = ATH12K_PEER_METADATA_V1B; } -void ath12k_wmi_init_wcn7850(struct ath12k_base *ab, - struct ath12k_wmi_resource_config_arg *config) +void ath12k_wifi7_wmi_init_wcn7850(struct ath12k_base *ab, + struct ath12k_wmi_resource_config_arg *config) { config->num_vdevs = 4; config->num_peers = 16; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/wmi.h b/drivers/net/wireless/ath/ath12k/wifi7/wmi.h index 1514e3e8d4cb6..ae74e176fa2d3 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/wmi.h @@ -7,9 +7,9 @@ #ifndef ATH12K_WMI_WIFI7_H #define ATH12K_WMI_WIFI7_H -void ath12k_wmi_init_qcn9274(struct ath12k_base *ab, - struct ath12k_wmi_resource_config_arg *config); -void ath12k_wmi_init_wcn7850(struct ath12k_base *ab, - struct ath12k_wmi_resource_config_arg *config); +void ath12k_wifi7_wmi_init_qcn9274(struct ath12k_base *ab, + struct ath12k_wmi_resource_config_arg *config); +void ath12k_wifi7_wmi_init_wcn7850(struct ath12k_base *ab, + struct ath12k_wmi_resource_config_arg *config); #endif From aa91047a0631f82c5556acff617cf8508f63d518 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:38 +0530 Subject: [PATCH 012/140] wifi: ath12k: Remove HAL defines from shared PCI code Eliminate use of HAL-specific defines in the shared PCI implementation. Pass required register offsets during PCI registration and store them in the PCI context structure. Access offsets directly from the context to improve modularity and remove hardware-specific dependencies in the common code path. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-12-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/pci.c | 12 ++++++++---- drivers/net/wireless/ath/ath12k/pci.h | 7 +++++++ drivers/net/wireless/ath/ath12k/wifi7/pci.c | 6 ++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 850eb9fa6169a..1daccd5893a81 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -132,10 +132,12 @@ static void ath12k_pci_select_window(struct ath12k_pci *ab_pci, u32 offset) static void ath12k_pci_select_static_window(struct ath12k_pci *ab_pci) { - u32 umac_window = u32_get_bits(HAL_SEQ_WCSS_UMAC_OFFSET, WINDOW_VALUE_MASK); - u32 ce_window = u32_get_bits(HAL_CE_WFSS_CE_REG_BASE, WINDOW_VALUE_MASK); + u32 umac_window; + u32 ce_window; u32 window; + umac_window = u32_get_bits(ab_pci->reg_base->umac_base, WINDOW_VALUE_MASK); + ce_window = u32_get_bits(ab_pci->reg_base->ce_reg_base, WINDOW_VALUE_MASK); window = (umac_window << 12) | (ce_window << 6); spin_lock_bh(&ab_pci->window_lock); @@ -148,13 +150,14 @@ static void ath12k_pci_select_static_window(struct ath12k_pci *ab_pci) static u32 ath12k_pci_get_window_start(struct ath12k_base *ab, u32 offset) { + struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); u32 window_start; /* If offset lies within DP register range, use 3rd window */ - if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < WINDOW_RANGE_MASK) + if ((offset ^ ab_pci->reg_base->umac_base) < WINDOW_RANGE_MASK) window_start = 3 * WINDOW_START; /* If offset lies within CE register range, use 2nd window */ - else if ((offset ^ HAL_CE_WFSS_CE_REG_BASE) < WINDOW_RANGE_MASK) + else if ((offset ^ ab_pci->reg_base->ce_reg_base) < WINDOW_RANGE_MASK) window_start = 2 * WINDOW_START; else window_start = WINDOW_START; @@ -1571,6 +1574,7 @@ static int ath12k_pci_probe(struct pci_dev *pdev, ath12k_dbg(ab, ATH12K_DBG_PCI, "PCI device family id: %d\n", device_id); ab_pci->device_family_ops = &ath12k_pci_family_drivers[device_id]->ops; + ab_pci->reg_base = ath12k_pci_family_drivers[device_id]->reg_base; /* Call device specific probe. This is the callback that can * be used to override any ops in future diff --git a/drivers/net/wireless/ath/ath12k/pci.h b/drivers/net/wireless/ath/ath12k/pci.h index 1b7ecc329a017..5af33e5deacfd 100644 --- a/drivers/net/wireless/ath/ath12k/pci.h +++ b/drivers/net/wireless/ath/ath12k/pci.h @@ -99,6 +99,11 @@ struct ath12k_pci_device_family_ops { int (*probe)(struct pci_dev *pdev, const struct pci_device_id *pci_dev); }; +struct ath12k_pci_reg_base { + u32 umac_base; + u32 ce_reg_base; +}; + struct ath12k_pci { struct pci_dev *pdev; struct ath12k_base *ab; @@ -122,6 +127,7 @@ struct ath12k_pci { u32 qmi_instance; u64 dma_mask; const struct ath12k_pci_device_family_ops *device_family_ops; + const struct ath12k_pci_reg_base *reg_base; }; struct ath12k_pci_driver { @@ -129,6 +135,7 @@ struct ath12k_pci_driver { const struct pci_device_id *id_table; struct ath12k_pci_device_family_ops ops; struct pci_driver driver; + const struct ath12k_pci_reg_base *reg_base; }; static inline struct ath12k_pci *ath12k_pci_priv(struct ath12k_base *ab) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/pci.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c index 608669a83ea75..9b1acf6c7aa31 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/pci.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -155,10 +155,16 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, return 0; } +static const struct ath12k_pci_reg_base ath12k_wifi7_reg_base = { + .umac_base = HAL_SEQ_WCSS_UMAC_OFFSET, + .ce_reg_base = HAL_CE_WFSS_CE_REG_BASE, +}; + static struct ath12k_pci_driver ath12k_wifi7_pci_driver = { .name = "ath12k_wifi7_pci", .id_table = ath12k_wifi7_pci_id_table, .ops.probe = ath12k_wifi7_pci_probe, + .reg_base = &ath12k_wifi7_reg_base, }; int ath12k_wifi7_pci_init(void) From c374ed0f9e72abc670ef3bd3f03d438293d9dc27 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Tue, 12 Aug 2025 22:39:39 +0530 Subject: [PATCH 013/140] wifi: ath12k: Remove HAL define dependencies from shared AHB code Eliminate HAL-specific defines from the shared AHB implementation. Store the WFSS register base-already available in hw_params via the ce_remap structure-in the AHB context and access it directly. Add the CMEM offset to the ce_remap structure and use it consistently in shared code. Improve modularity by removing hardware abstraction layer dependencies from common code paths and enable cleaner separation of target-specific logic Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.3.1-00130-QCAHKSWPL_SILICONZ-1 Signed-off-by: Kiran Venkatappa Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250812-ath12k-mod-v1-13-8c9b0eb9335d@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ahb.c | 7 ++++--- drivers/net/wireless/ath/ath12k/ce.h | 1 + drivers/net/wireless/ath/ath12k/core.h | 1 + drivers/net/wireless/ath/ath12k/wifi7/hw.c | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index 5fe2b5b7db499..9348b5aa08c67 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -123,7 +123,7 @@ enum ext_irq_num { static u32 ath12k_ahb_read32(struct ath12k_base *ab, u32 offset) { - if (ab->ce_remap && offset < HAL_SEQ_WCSS_CMEM_OFFSET) + if (ab->ce_remap && offset < ab->cmem_offset) return ioread32(ab->mem_ce + offset); return ioread32(ab->mem + offset); } @@ -131,7 +131,7 @@ static u32 ath12k_ahb_read32(struct ath12k_base *ab, u32 offset) static void ath12k_ahb_write32(struct ath12k_base *ab, u32 offset, u32 value) { - if (ab->ce_remap && offset < HAL_SEQ_WCSS_CMEM_OFFSET) + if (ab->ce_remap && offset < ab->cmem_offset) iowrite32(value, ab->mem_ce + offset); else iowrite32(value, ab->mem + offset); @@ -928,7 +928,8 @@ static int ath12k_ahb_resource_init(struct ath12k_base *ab) goto err_mem_unmap; } ab->ce_remap = true; - ab->ce_remap_base_addr = HAL_IPQ5332_CE_WFSS_REG_BASE; + ab->cmem_offset = ce_remap->cmem_offset; + ab->ce_remap_base_addr = ce_remap->base; } ab_ahb->xo_clk = devm_clk_get(ab->dev, "xo"); diff --git a/drivers/net/wireless/ath/ath12k/ce.h b/drivers/net/wireless/ath/ath12k/ce.h index f44ce2244bcfd..38f986ea1cd2b 100644 --- a/drivers/net/wireless/ath/ath12k/ce.h +++ b/drivers/net/wireless/ath/ath12k/ce.h @@ -85,6 +85,7 @@ struct ce_ie_addr { struct ce_remap { u32 base; u32 size; + u32 cmem_offset; }; struct ce_attr { diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 60c2237cb055e..e1700c63b1bee 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1067,6 +1067,7 @@ struct ath12k_base { void __iomem *mem_ce; u32 ce_remap_base_addr; + u32 cmem_offset; bool ce_remap; struct { diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 9995eccd32d39..82b4f5b9f5700 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -695,6 +695,7 @@ static const struct ce_ie_addr ath12k_wifi7_ce_ie_addr_ipq5332 = { static const struct ce_remap ath12k_wifi7_ce_remap_ipq5332 = { .base = HAL_IPQ5332_CE_WFSS_REG_BASE, .size = HAL_IPQ5332_CE_SIZE, + .cmem_offset = HAL_SEQ_WCSS_CMEM_OFFSET, }; static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { From ee004c5bd4d8a860e622b2c592184dfe96eaee20 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:34 +0530 Subject: [PATCH 014/140] wifi: ath12k: Move hal_tx and hal_rx to wifi7 directory Move architecture-specific files hal_rx.c and hal_tx.c into the wifi7 directory as part of a broader effort to separate common and hardware -specific code into distinct modules. This modularization enables reuse of the common driver components across multiple hardware architectures. The relocated files remain part of ath12k.ko temporarily, until the corresponding infra for movement to the ath12k_wifi7.ko arrives in upcoming patches. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-2-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 5 +++-- drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_rx.c | 12 ++++++------ drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_tx.c | 10 +++++----- 3 files changed, 14 insertions(+), 13 deletions(-) rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_rx.c (99%) rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_tx.c (96%) diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index 8dd77729f52f5..b34cf83a24eb1 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -2,8 +2,6 @@ obj-$(CONFIG_ATH12K) += ath12k.o ath12k-y += core.o \ hal.o \ - hal_tx.o \ - hal_rx.o \ wmi.o \ mac.o \ reg.o \ @@ -24,6 +22,9 @@ ath12k-y += core.o \ ath12k-$(CONFIG_ATH12K_AHB) += ahb.o +ath12k-y += wifi7/hal_tx.o \ + wifi7/hal_rx.o \ + obj-$(CONFIG_ATH12K) += wifi7/ ath12k-$(CONFIG_ATH12K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o diff --git a/drivers/net/wireless/ath/ath12k/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c similarity index 99% rename from drivers/net/wireless/ath/ath12k/hal_rx.c rename to drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index c4443ca05cd65..d5f149bf29f4c 100644 --- a/drivers/net/wireless/ath/ath12k/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -4,12 +4,12 @@ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ -#include "debug.h" -#include "hal.h" -#include "hal_tx.h" -#include "hal_rx.h" -#include "hal_desc.h" -#include "hif.h" +#include "../debug.h" +#include "../hal.h" +#include "../hif.h" +#include "../hal_tx.h" +#include "../hal_rx.h" +#include "../hal_desc.h" static void ath12k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, u8 owner, u8 buffer_type, u32 magic) diff --git a/drivers/net/wireless/ath/ath12k/hal_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c similarity index 96% rename from drivers/net/wireless/ath/ath12k/hal_tx.c rename to drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c index 869e07e406fef..f58da63a1b021 100644 --- a/drivers/net/wireless/ath/ath12k/hal_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c @@ -1,13 +1,13 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ -#include "hal_desc.h" -#include "hal.h" -#include "hal_tx.h" -#include "hif.h" +#include "../hal_desc.h" +#include "../hal.h" +#include "../hal_tx.h" +#include "../hif.h" #define DSCP_TID_MAP_TBL_ENTRY_SIZE 64 From b87f122f984a2277d6069d27a985f5d2c55b9cc1 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:35 +0530 Subject: [PATCH 015/140] wifi: ath12k: Move hal_tx.h file to wifi7 directory Move wifi7 architecture specific file hal_tx.h to wifi7 directory, and move the common part from it to hal.h file which is in the common directory. It is as part of a broader effort to separate common and hardware-specific code into distinct modules. This modularization enables reuse of the common driver components across multiple hardware architectures. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-3-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 4 ++-- drivers/net/wireless/ath/ath12k/dp_tx.h | 4 ++-- drivers/net/wireless/ath/ath12k/hal.c | 4 ++-- drivers/net/wireless/ath/ath12k/hal.h | 9 ++++++++- drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c | 2 +- drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c | 2 +- .../net/wireless/ath/ath12k/{ => wifi7}/hal_tx.h | 13 +++---------- 7 files changed, 19 insertions(+), 19 deletions(-) rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_tx.h (95%) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 4a54b8c353111..ec6300eb38921 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1,13 +1,13 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 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. */ #include #include "core.h" #include "dp_tx.h" -#include "hal_tx.h" +#include "wifi7/hal_tx.h" #include "hif.h" #include "debug.h" #include "dp_rx.h" diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.h b/drivers/net/wireless/ath/ath12k/dp_tx.h index 10acdcf1fa8f7..aa2f6397bc83d 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/dp_tx.h @@ -1,14 +1,14 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022, 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_DP_TX_H #define ATH12K_DP_TX_H #include "core.h" -#include "hal_tx.h" +#include "wifi7/hal_tx.h" struct ath12k_dp_htt_wbm_tx_status { bool acked; diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 022eea9515efd..dbbdb6f3f8cfd 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -1,10 +1,10 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 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. */ #include -#include "hal_tx.h" +#include "wifi7/hal_tx.h" #include "hal_rx.h" #include "debug.h" #include "hal_desc.h" diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index efe00e1679986..e908e9f009657 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 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 ATH12K_HAL_H @@ -11,6 +11,13 @@ #include "rx_desc.h" struct ath12k_base; + +#define HAL_TX_ADDRX_EN 1 +#define HAL_TX_ADDRY_EN 2 + +#define HAL_TX_ADDR_SEARCH_DEFAULT 0 +#define HAL_TX_ADDR_SEARCH_INDEX 1 + #define HAL_CE_REMAP_REG_BASE (ab->ce_remap_base_addr) #define HAL_LINK_DESC_SIZE (32 << 2) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index d5f149bf29f4c..2be03db483a00 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -7,7 +7,7 @@ #include "../debug.h" #include "../hal.h" #include "../hif.h" -#include "../hal_tx.h" +#include "hal_tx.h" #include "../hal_rx.h" #include "../hal_desc.h" diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c index f58da63a1b021..87c1312c4f46d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c @@ -6,7 +6,7 @@ #include "../hal_desc.h" #include "../hal.h" -#include "../hal_tx.h" +#include "hal_tx.h" #include "../hif.h" #define DSCP_TID_MAP_TBL_ENTRY_SIZE 64 diff --git a/drivers/net/wireless/ath/ath12k/hal_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h similarity index 95% rename from drivers/net/wireless/ath/ath12k/hal_tx.h rename to drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h index eb065a79f6c64..b179320569ff7 100644 --- a/drivers/net/wireless/ath/ath12k/hal_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h @@ -1,21 +1,14 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022, 2024-2025 Qualcomm Innovation Center, Inc. - * All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_HAL_TX_H #define ATH12K_HAL_TX_H -#include "hal_desc.h" -#include "core.h" - -#define HAL_TX_ADDRX_EN 1 -#define HAL_TX_ADDRY_EN 2 - -#define HAL_TX_ADDR_SEARCH_DEFAULT 0 -#define HAL_TX_ADDR_SEARCH_INDEX 1 +#include "../hal_desc.h" +#include "../core.h" /* TODO: check all these data can be managed with struct ath12k_tx_desc_info for perf */ struct hal_tx_info { From 46a4fb020931c580564b932b0955b6f8b8774c45 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:36 +0530 Subject: [PATCH 016/140] wifi: ath12k: Move hal_rx.h file to wifi7 directory Move wifi7 architecture specific file hal_rx.h to wifi7 directory, and move the common part from it to hal.h file which is in the common directory. It is as part of a broader effort to separate common and hardware-specific code into distinct modules. This modularization enables reuse of the common driver components across multiple hardware architectures. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-4-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 2 +- drivers/net/wireless/ath/ath12k/dp.h | 4 +- drivers/net/wireless/ath/ath12k/dp_rx.c | 2 +- drivers/net/wireless/ath/ath12k/hal.c | 2 +- drivers/net/wireless/ath/ath12k/hal.h | 295 +++++++++++++++++ .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 2 +- .../wireless/ath/ath12k/{ => wifi7}/hal_rx.h | 299 +----------------- 7 files changed, 302 insertions(+), 304 deletions(-) rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_rx.h (83%) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index e1700c63b1bee..7eaf098ccc8f5 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -26,7 +26,7 @@ #include "ce.h" #include "mac.h" #include "hw.h" -#include "hal_rx.h" +#include "wifi7/hal_rx.h" #include "reg.h" #include "dbring.h" #include "fw.h" diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 4ffec6ad7d8d9..dc33a0f85f2af 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -1,14 +1,14 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 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 ATH12K_DP_H #define ATH12K_DP_H #include "hal_desc.h" -#include "hal_rx.h" +#include "wifi7/hal_rx.h" #include "hw.h" #define MAX_RXDMA_PER_PDEV 2 diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index cd07bb5b8e9a4..80fb1cc9ed599 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -13,7 +13,7 @@ #include "hal_desc.h" #include "hw.h" #include "dp_rx.h" -#include "hal_rx.h" +#include "wifi7/hal_rx.h" #include "dp_tx.h" #include "peer.h" #include "dp_mon.h" diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index dbbdb6f3f8cfd..f9ce60d22cc1a 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -5,7 +5,7 @@ */ #include #include "wifi7/hal_tx.h" -#include "hal_rx.h" +#include "wifi7/hal_rx.h" #include "debug.h" #include "hal_desc.h" #include "hif.h" diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index e908e9f009657..322ebfed9b011 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -12,12 +12,22 @@ struct ath12k_base; +#define HAL_INVALID_PEERID 0x3fff +#define VHT_SIG_SU_NSS_MASK 0x7 + #define HAL_TX_ADDRX_EN 1 #define HAL_TX_ADDRY_EN 2 #define HAL_TX_ADDR_SEARCH_DEFAULT 0 #define HAL_TX_ADDR_SEARCH_INDEX 1 +#define HAL_RX_MAX_MPDU 256 +#define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP (HAL_RX_MAX_MPDU >> 5) + +#define EHT_MAX_USER_INFO 4 +#define HAL_RX_MON_MAX_AGGR_SIZE 128 +#define HAL_MAX_UL_MU_USERS 37 + #define HAL_CE_REMAP_REG_BASE (ab->ce_remap_base_addr) #define HAL_LINK_DESC_SIZE (32 << 2) @@ -532,6 +542,64 @@ enum hal_srng_ring_id { #define HAL_SRNG_RING_ID_MAX (HAL_SRNG_RING_ID_DMAC_CMN_ID_END + \ HAL_SRNG_NUM_PMAC_RINGS) +enum hal_rx_su_mu_coding { + HAL_RX_SU_MU_CODING_BCC, + HAL_RX_SU_MU_CODING_LDPC, + HAL_RX_SU_MU_CODING_MAX, +}; + +enum hal_rx_gi { + HAL_RX_GI_0_8_US, + HAL_RX_GI_0_4_US, + HAL_RX_GI_1_6_US, + HAL_RX_GI_3_2_US, + HAL_RX_GI_MAX, +}; + +enum hal_rx_bw { + HAL_RX_BW_20MHZ, + HAL_RX_BW_40MHZ, + HAL_RX_BW_80MHZ, + HAL_RX_BW_160MHZ, + HAL_RX_BW_320MHZ, + HAL_RX_BW_MAX, +}; + +enum hal_rx_preamble { + HAL_RX_PREAMBLE_11A, + HAL_RX_PREAMBLE_11B, + HAL_RX_PREAMBLE_11N, + HAL_RX_PREAMBLE_11AC, + HAL_RX_PREAMBLE_11AX, + HAL_RX_PREAMBLE_11BA, + HAL_RX_PREAMBLE_11BE, + HAL_RX_PREAMBLE_MAX, +}; + +enum hal_rx_reception_type { + HAL_RX_RECEPTION_TYPE_SU, + HAL_RX_RECEPTION_TYPE_MU_MIMO, + HAL_RX_RECEPTION_TYPE_MU_OFDMA, + HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO, + HAL_RX_RECEPTION_TYPE_MAX, +}; + +enum hal_rx_legacy_rate { + HAL_RX_LEGACY_RATE_1_MBPS, + HAL_RX_LEGACY_RATE_2_MBPS, + HAL_RX_LEGACY_RATE_5_5_MBPS, + HAL_RX_LEGACY_RATE_6_MBPS, + HAL_RX_LEGACY_RATE_9_MBPS, + HAL_RX_LEGACY_RATE_11_MBPS, + HAL_RX_LEGACY_RATE_12_MBPS, + HAL_RX_LEGACY_RATE_18_MBPS, + HAL_RX_LEGACY_RATE_24_MBPS, + HAL_RX_LEGACY_RATE_36_MBPS, + HAL_RX_LEGACY_RATE_48_MBPS, + HAL_RX_LEGACY_RATE_54_MBPS, + HAL_RX_LEGACY_RATE_INVALID, +}; + enum hal_ring_type { HAL_REO_DST, HAL_REO_EXCEPTION, @@ -632,6 +700,158 @@ enum hal_srng_dir { HAL_SRNG_DIR_DST }; +struct hal_rx_user_status { + u32 mcs:4, + nss:3, + ofdma_info_valid:1, + ul_ofdma_ru_start_index:7, + ul_ofdma_ru_width:7, + ul_ofdma_ru_size:8; + u32 ul_ofdma_user_v0_word0; + u32 ul_ofdma_user_v0_word1; + u32 ast_index; + u32 tid; + u16 tcp_msdu_count; + u16 tcp_ack_msdu_count; + u16 udp_msdu_count; + u16 other_msdu_count; + u16 frame_control; + u8 frame_control_info_valid; + u8 data_sequence_control_info_valid; + u16 first_data_seq_ctrl; + u32 preamble_type; + u16 ht_flags; + u16 vht_flags; + u16 he_flags; + u8 rs_flags; + u8 ldpc; + u32 mpdu_cnt_fcs_ok; + u32 mpdu_cnt_fcs_err; + u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP]; + u32 mpdu_ok_byte_count; + u32 mpdu_err_byte_count; + bool ampdu_present; + u16 ampdu_id; +}; + +struct hal_rx_u_sig_info { + bool ul_dl; + u8 bw; + u8 ppdu_type_comp_mode; + u8 eht_sig_mcs; + u8 num_eht_sig_sym; + struct ieee80211_radiotap_eht_usig usig; +}; + +struct hal_rx_tlv_aggr_info { + bool in_progress; + u16 cur_len; + u16 tlv_tag; + u8 buf[HAL_RX_MON_MAX_AGGR_SIZE]; +}; + +struct hal_rx_radiotap_eht { + __le32 known; + __le32 data[9]; +}; + +struct hal_rx_eht_info { + u8 num_user_info; + struct hal_rx_radiotap_eht eht; + u32 user_info[EHT_MAX_USER_INFO]; +}; + +struct hal_rx_mon_ppdu_info { + u32 ppdu_id; + u32 last_ppdu_id; + u64 ppdu_ts; + u32 num_mpdu_fcs_ok; + u32 num_mpdu_fcs_err; + u32 preamble_type; + u32 mpdu_len; + u16 chan_num; + u16 freq; + u16 tcp_msdu_count; + u16 tcp_ack_msdu_count; + u16 udp_msdu_count; + u16 other_msdu_count; + u16 peer_id; + u8 rate; + u8 mcs; + u8 nss; + u8 bw; + u8 vht_flag_values1; + u8 vht_flag_values2; + u8 vht_flag_values3[4]; + u8 vht_flag_values4; + u8 vht_flag_values5; + u16 vht_flag_values6; + u8 is_stbc; + u8 gi; + u8 sgi; + u8 ldpc; + u8 beamformed; + u8 rssi_comb; + u16 tid; + u8 fc_valid; + u16 ht_flags; + u16 vht_flags; + u16 he_flags; + u16 he_mu_flags; + u8 dcm; + u8 ru_alloc; + u8 reception_type; + u64 tsft; + u64 rx_duration; + u16 frame_control; + u32 ast_index; + u8 rs_fcs_err; + u8 rs_flags; + u8 cck_flag; + u8 ofdm_flag; + u8 ulofdma_flag; + u8 frame_control_info_valid; + u16 he_per_user_1; + u16 he_per_user_2; + u8 he_per_user_position; + u8 he_per_user_known; + u16 he_flags1; + u16 he_flags2; + u8 he_RU[4]; + u16 he_data1; + u16 he_data2; + u16 he_data3; + u16 he_data4; + u16 he_data5; + u16 he_data6; + u32 ppdu_len; + u32 prev_ppdu_id; + u32 device_id; + u16 first_data_seq_ctrl; + u8 monitor_direct_used; + u8 data_sequence_control_info_valid; + u8 ltf_size; + u8 rxpcu_filter_pass; + s8 rssi_chain[8][8]; + u32 num_users; + u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP]; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u8 addr4[ETH_ALEN]; + struct hal_rx_user_status userstats[HAL_MAX_UL_MU_USERS]; + u8 userid; + bool first_msdu_in_mpdu; + bool is_ampdu; + u8 medium_prot_type; + bool ppdu_continuation; + bool eht_usig; + struct hal_rx_u_sig_info u_sig_info; + bool is_eht; + struct hal_rx_eht_info eht_info; + struct hal_rx_tlv_aggr_info tlv_aggr; +}; + /* srng flags */ #define HAL_SRNG_FLAGS_MSI_SWAP 0x00000008 #define HAL_SRNG_FLAGS_RING_PTR_SWAP 0x00000010 @@ -1061,6 +1281,81 @@ struct ath12k_hal_tcl_to_wbm_rbm_map { u8 rbm_id; }; +#define RU_INVALID 0 +#define RU_26 1 +#define RU_52 2 +#define RU_106 4 +#define RU_242 9 +#define RU_484 18 +#define RU_996 37 +#define RU_2X996 74 +#define RU_3X996 111 +#define RU_4X996 148 +#define RU_52_26 (RU_52 + RU_26) +#define RU_106_26 (RU_106 + RU_26) +#define RU_484_242 (RU_484 + RU_242) +#define RU_996_484 (RU_996 + RU_484) +#define RU_996_484_242 (RU_996 + RU_484_242) +#define RU_2X996_484 (RU_2X996 + RU_484) +#define RU_3X996_484 (RU_3X996 + RU_484) + +enum ath12k_eht_ru_size { + ATH12K_EHT_RU_26, + ATH12K_EHT_RU_52, + ATH12K_EHT_RU_106, + ATH12K_EHT_RU_242, + ATH12K_EHT_RU_484, + ATH12K_EHT_RU_996, + ATH12K_EHT_RU_996x2, + ATH12K_EHT_RU_996x4, + ATH12K_EHT_RU_52_26, + ATH12K_EHT_RU_106_26, + ATH12K_EHT_RU_484_242, + ATH12K_EHT_RU_996_484, + ATH12K_EHT_RU_996_484_242, + ATH12K_EHT_RU_996x2_484, + ATH12K_EHT_RU_996x3, + ATH12K_EHT_RU_996x3_484, + + /* Keep last */ + ATH12K_EHT_RU_INVALID, +}; + +#define HAL_RX_RU_ALLOC_TYPE_MAX ATH12K_EHT_RU_INVALID + +static inline +enum nl80211_he_ru_alloc ath12k_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones) +{ + enum nl80211_he_ru_alloc ret; + + switch (ru_tones) { + case RU_52: + ret = NL80211_RATE_INFO_HE_RU_ALLOC_52; + break; + case RU_106: + ret = NL80211_RATE_INFO_HE_RU_ALLOC_106; + break; + case RU_242: + ret = NL80211_RATE_INFO_HE_RU_ALLOC_242; + break; + case RU_484: + ret = NL80211_RATE_INFO_HE_RU_ALLOC_484; + break; + case RU_996: + ret = NL80211_RATE_INFO_HE_RU_ALLOC_996; + break; + case RU_2X996: + ret = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; + break; + case RU_26: + fallthrough; + default: + ret = NL80211_RATE_INFO_HE_RU_ALLOC_26; + break; + } + return ret; +} + struct hal_rx_ops { bool (*rx_desc_get_first_msdu)(struct hal_rx_desc *desc); bool (*rx_desc_get_last_msdu)(struct hal_rx_desc *desc); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index 2be03db483a00..e8379e660d3a5 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -8,7 +8,7 @@ #include "../hal.h" #include "../hif.h" #include "hal_tx.h" -#include "../hal_rx.h" +#include "hal_rx.h" #include "../hal_desc.h" static void ath12k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, diff --git a/drivers/net/wireless/ath/ath12k/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h similarity index 83% rename from drivers/net/wireless/ath/ath12k/hal_rx.h rename to drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index d1ad7747b82c4..d8d9d469c6704 100644 --- a/drivers/net/wireless/ath/ath12k/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 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 ATH12K_HAL_RX_H @@ -19,9 +19,6 @@ struct hal_rx_wbm_rel_info { bool hw_cc_done; }; -#define HAL_INVALID_PEERID 0x3fff -#define VHT_SIG_SU_NSS_MASK 0x7 - #define HAL_RX_MPDU_INFO_PN_GET_BYTE1(__val) \ le32_get_bits((__val), GENMASK(7, 0)) @@ -39,64 +36,6 @@ struct hal_rx_mon_status_tlv_hdr { u8 value[]; }; -enum hal_rx_su_mu_coding { - HAL_RX_SU_MU_CODING_BCC, - HAL_RX_SU_MU_CODING_LDPC, - HAL_RX_SU_MU_CODING_MAX, -}; - -enum hal_rx_gi { - HAL_RX_GI_0_8_US, - HAL_RX_GI_0_4_US, - HAL_RX_GI_1_6_US, - HAL_RX_GI_3_2_US, - HAL_RX_GI_MAX, -}; - -enum hal_rx_bw { - HAL_RX_BW_20MHZ, - HAL_RX_BW_40MHZ, - HAL_RX_BW_80MHZ, - HAL_RX_BW_160MHZ, - HAL_RX_BW_320MHZ, - HAL_RX_BW_MAX, -}; - -enum hal_rx_preamble { - HAL_RX_PREAMBLE_11A, - HAL_RX_PREAMBLE_11B, - HAL_RX_PREAMBLE_11N, - HAL_RX_PREAMBLE_11AC, - HAL_RX_PREAMBLE_11AX, - HAL_RX_PREAMBLE_11BA, - HAL_RX_PREAMBLE_11BE, - HAL_RX_PREAMBLE_MAX, -}; - -enum hal_rx_reception_type { - HAL_RX_RECEPTION_TYPE_SU, - HAL_RX_RECEPTION_TYPE_MU_MIMO, - HAL_RX_RECEPTION_TYPE_MU_OFDMA, - HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO, - HAL_RX_RECEPTION_TYPE_MAX, -}; - -enum hal_rx_legacy_rate { - HAL_RX_LEGACY_RATE_1_MBPS, - HAL_RX_LEGACY_RATE_2_MBPS, - HAL_RX_LEGACY_RATE_5_5_MBPS, - HAL_RX_LEGACY_RATE_6_MBPS, - HAL_RX_LEGACY_RATE_9_MBPS, - HAL_RX_LEGACY_RATE_11_MBPS, - HAL_RX_LEGACY_RATE_12_MBPS, - HAL_RX_LEGACY_RATE_18_MBPS, - HAL_RX_LEGACY_RATE_24_MBPS, - HAL_RX_LEGACY_RATE_36_MBPS, - HAL_RX_LEGACY_RATE_48_MBPS, - HAL_RX_LEGACY_RATE_54_MBPS, - HAL_RX_LEGACY_RATE_INVALID, -}; - #define HAL_TLV_STATUS_PPDU_NOT_DONE 0 #define HAL_TLV_STATUS_PPDU_DONE 1 #define HAL_TLV_STATUS_BUF_DONE 2 @@ -113,167 +52,6 @@ enum hal_rx_mon_status { HAL_RX_MON_STATUS_MSDU_END, }; -#define HAL_RX_MAX_MPDU 1024 -#define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP (HAL_RX_MAX_MPDU >> 5) - -struct hal_rx_user_status { - u32 mcs:4, - nss:3, - ofdma_info_valid:1, - ul_ofdma_ru_start_index:7, - ul_ofdma_ru_width:7, - ul_ofdma_ru_size:8; - u32 ul_ofdma_user_v0_word0; - u32 ul_ofdma_user_v0_word1; - u32 ast_index; - u32 tid; - u16 tcp_msdu_count; - u16 tcp_ack_msdu_count; - u16 udp_msdu_count; - u16 other_msdu_count; - u16 frame_control; - u8 frame_control_info_valid; - u8 data_sequence_control_info_valid; - u16 first_data_seq_ctrl; - u32 preamble_type; - u16 ht_flags; - u16 vht_flags; - u16 he_flags; - u8 rs_flags; - u8 ldpc; - u32 mpdu_cnt_fcs_ok; - u32 mpdu_cnt_fcs_err; - u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP]; - u32 mpdu_ok_byte_count; - u32 mpdu_err_byte_count; - bool ampdu_present; - u16 ampdu_id; -}; - -#define HAL_MAX_UL_MU_USERS 37 - -struct hal_rx_u_sig_info { - bool ul_dl; - u8 bw; - u8 ppdu_type_comp_mode; - u8 eht_sig_mcs; - u8 num_eht_sig_sym; - struct ieee80211_radiotap_eht_usig usig; -}; - -#define HAL_RX_MON_MAX_AGGR_SIZE 128 - -struct hal_rx_tlv_aggr_info { - bool in_progress; - u16 cur_len; - u16 tlv_tag; - u8 buf[HAL_RX_MON_MAX_AGGR_SIZE]; -}; - -struct hal_rx_radiotap_eht { - __le32 known; - __le32 data[9]; -}; - -#define EHT_MAX_USER_INFO 4 - -struct hal_rx_eht_info { - u8 num_user_info; - struct hal_rx_radiotap_eht eht; - u32 user_info[EHT_MAX_USER_INFO]; -}; - -struct hal_rx_mon_ppdu_info { - u32 ppdu_id; - u32 last_ppdu_id; - u64 ppdu_ts; - u32 num_mpdu_fcs_ok; - u32 num_mpdu_fcs_err; - u32 preamble_type; - u32 mpdu_len; - u16 chan_num; - u16 freq; - u16 tcp_msdu_count; - u16 tcp_ack_msdu_count; - u16 udp_msdu_count; - u16 other_msdu_count; - u16 peer_id; - u8 rate; - u8 mcs; - u8 nss; - u8 bw; - u8 vht_flag_values1; - u8 vht_flag_values2; - u8 vht_flag_values3[4]; - u8 vht_flag_values4; - u8 vht_flag_values5; - u16 vht_flag_values6; - u8 is_stbc; - u8 gi; - u8 sgi; - u8 ldpc; - u8 beamformed; - u8 rssi_comb; - u16 tid; - u8 fc_valid; - u16 ht_flags; - u16 vht_flags; - u16 he_flags; - u16 he_mu_flags; - u8 dcm; - u8 ru_alloc; - u8 reception_type; - u64 tsft; - u64 rx_duration; - u16 frame_control; - u32 ast_index; - u8 rs_fcs_err; - u8 rs_flags; - u8 cck_flag; - u8 ofdm_flag; - u8 ulofdma_flag; - u8 frame_control_info_valid; - u16 he_per_user_1; - u16 he_per_user_2; - u8 he_per_user_position; - u8 he_per_user_known; - u16 he_flags1; - u16 he_flags2; - u8 he_RU[4]; - u16 he_data1; - u16 he_data2; - u16 he_data3; - u16 he_data4; - u16 he_data5; - u16 he_data6; - u32 ppdu_len; - u32 prev_ppdu_id; - u32 device_id; - u16 first_data_seq_ctrl; - u8 monitor_direct_used; - u8 data_sequence_control_info_valid; - u8 ltf_size; - u8 rxpcu_filter_pass; - s8 rssi_chain[8][8]; - u32 num_users; - u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP]; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - u8 addr4[ETH_ALEN]; - struct hal_rx_user_status userstats[HAL_MAX_UL_MU_USERS]; - u8 userid; - bool first_msdu_in_mpdu; - bool is_ampdu; - u8 medium_prot_type; - bool ppdu_continuation; - bool eht_usig; - struct hal_rx_u_sig_info u_sig_info; - bool is_eht; - struct hal_rx_eht_info eht_info; - struct hal_rx_tlv_aggr_info tlv_aggr; -}; - #define HAL_RX_PPDU_START_INFO0_PPDU_ID GENMASK(15, 0) #define HAL_RX_PPDU_START_INFO1_CHAN_NUM GENMASK(15, 0) #define HAL_RX_PPDU_START_INFO1_CHAN_FREQ GENMASK(31, 16) @@ -1044,81 +822,6 @@ enum hal_mon_reception_type { #define HAL_RU_PER80(ru_per80, num_80mhz, ru_idx_per80mhz) \ (HAL_RU(ru_per80, num_80mhz, ru_idx_per80mhz)) -#define RU_INVALID 0 -#define RU_26 1 -#define RU_52 2 -#define RU_106 4 -#define RU_242 9 -#define RU_484 18 -#define RU_996 37 -#define RU_2X996 74 -#define RU_3X996 111 -#define RU_4X996 148 -#define RU_52_26 (RU_52 + RU_26) -#define RU_106_26 (RU_106 + RU_26) -#define RU_484_242 (RU_484 + RU_242) -#define RU_996_484 (RU_996 + RU_484) -#define RU_996_484_242 (RU_996 + RU_484_242) -#define RU_2X996_484 (RU_2X996 + RU_484) -#define RU_3X996_484 (RU_3X996 + RU_484) - -enum ath12k_eht_ru_size { - ATH12K_EHT_RU_26, - ATH12K_EHT_RU_52, - ATH12K_EHT_RU_106, - ATH12K_EHT_RU_242, - ATH12K_EHT_RU_484, - ATH12K_EHT_RU_996, - ATH12K_EHT_RU_996x2, - ATH12K_EHT_RU_996x4, - ATH12K_EHT_RU_52_26, - ATH12K_EHT_RU_106_26, - ATH12K_EHT_RU_484_242, - ATH12K_EHT_RU_996_484, - ATH12K_EHT_RU_996_484_242, - ATH12K_EHT_RU_996x2_484, - ATH12K_EHT_RU_996x3, - ATH12K_EHT_RU_996x3_484, - - /* Keep last */ - ATH12K_EHT_RU_INVALID, -}; - -#define HAL_RX_RU_ALLOC_TYPE_MAX ATH12K_EHT_RU_INVALID - -static inline -enum nl80211_he_ru_alloc ath12k_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones) -{ - enum nl80211_he_ru_alloc ret; - - switch (ru_tones) { - case RU_52: - ret = NL80211_RATE_INFO_HE_RU_ALLOC_52; - break; - case RU_106: - ret = NL80211_RATE_INFO_HE_RU_ALLOC_106; - break; - case RU_242: - ret = NL80211_RATE_INFO_HE_RU_ALLOC_242; - break; - case RU_484: - ret = NL80211_RATE_INFO_HE_RU_ALLOC_484; - break; - case RU_996: - ret = NL80211_RATE_INFO_HE_RU_ALLOC_996; - break; - case RU_2X996: - ret = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; - break; - case RU_26: - fallthrough; - default: - ret = NL80211_RATE_INFO_HE_RU_ALLOC_26; - break; - } - return ret; -} - void ath12k_hal_reo_status_queue_stats(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv, struct hal_reo_status *status); From d9551771d347c696bab15bdde8bf79e5e92f8c81 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:37 +0530 Subject: [PATCH 017/140] wifi: ath12k: Move HAL Rx wrapper APIs to dp_rx.h Move HAL Rx APIs from dp_rx.c to dp_rx.h to facilitate the separation of common and hardware-specific code that are dependent on these HAL Rx ops in upcoming patches. Move the following wrapper APIs to dp_rx.h ath12k_dp_rx_h_enctype ath12k_dp_rx_h_mesh_ctl_present ath12k_dp_rx_h_seq_ctrl_valid ath12k_dp_rx_h_fc_valid ath12k_dp_rx_h_more_frags ath12k_dp_rx_h_frag_no ath12k_dp_rx_h_seq_no ath12k_dp_rx_h_msdu_done ath12k_dp_rx_h_l4_cksum_fail ath12k_dp_rx_h_ip_cksum_fail ath12k_dp_rx_h_is_decrypted ath12k_dp_rx_h_msdu_len ath12k_dp_rx_h_sgi ath12k_dp_rx_h_rate_mcs ath12k_dp_rx_h_rx_bw ath12k_dp_rx_h_freq ath12k_dp_rx_h_pkt_type ath12k_dp_rx_h_nss ath12k_dp_rx_h_tid ath12k_dp_rx_h_peer_id ath12k_dp_rx_h_first_msdu ath12k_dp_rx_h_last_msdu ath12k_dp_rx_desc_end_tlv_copy ath12k_dp_rxdesc_set_msdu_len ath12k_dp_rx_h_is_da_mcbc ath12k_dp_rxdesc_mac_addr2_valid ath12k_dp_rxdesc_get_mpdu_start_addr2 ath12k_dp_rx_desc_get_dot11_hdr ath12k_dp_rx_desc_get_crypto_header ath12k_dp_rx_get_msdu_src_link Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-5-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 240 ------------------------ drivers/net/wireless/ath/ath12k/dp_rx.h | 239 ++++++++++++++++++++++- 2 files changed, 238 insertions(+), 241 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 80fb1cc9ed599..1b1d9f6ed8027 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -21,246 +21,6 @@ #define ATH12K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ) -static int ath12k_dp_rx_tid_delete_handler(struct ath12k_base *ab, - struct ath12k_dp_rx_tid_rxq *rx_tid); - -static enum hal_encrypt_type ath12k_dp_rx_h_enctype(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - if (!ab->hal_rx_ops->rx_desc_encrypt_valid(desc)) - return HAL_ENCRYPT_TYPE_OPEN; - - return ab->hal_rx_ops->rx_desc_get_encrypt_type(desc); -} - -u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_decap_type(desc); -} - -static u8 ath12k_dp_rx_h_mesh_ctl_present(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mesh_ctl(desc); -} - -static bool ath12k_dp_rx_h_seq_ctrl_valid(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_seq_ctl_vld(desc); -} - -static bool ath12k_dp_rx_h_fc_valid(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_fc_valid(desc); -} - -static bool ath12k_dp_rx_h_more_frags(struct ath12k_base *ab, - struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr; - - hdr = (struct ieee80211_hdr *)(skb->data + ab->hal.hal_desc_sz); - return ieee80211_has_morefrags(hdr->frame_control); -} - -static u16 ath12k_dp_rx_h_frag_no(struct ath12k_base *ab, - struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr; - - hdr = (struct ieee80211_hdr *)(skb->data + ab->hal.hal_desc_sz); - return le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; -} - -static u16 ath12k_dp_rx_h_seq_no(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_start_seq_no(desc); -} - -static bool ath12k_dp_rx_h_msdu_done(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_msdu_done(desc); -} - -static bool ath12k_dp_rx_h_l4_cksum_fail(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_l4_cksum_fail(desc); -} - -static bool ath12k_dp_rx_h_ip_cksum_fail(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_ip_cksum_fail(desc); -} - -static bool ath12k_dp_rx_h_is_decrypted(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_is_decrypted(desc); -} - -u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_mpdu_err(desc); -} - -static u16 ath12k_dp_rx_h_msdu_len(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_len(desc); -} - -static u8 ath12k_dp_rx_h_sgi(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_sgi(desc); -} - -static u8 ath12k_dp_rx_h_rate_mcs(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_rate_mcs(desc); -} - -static u8 ath12k_dp_rx_h_rx_bw(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_rx_bw(desc); -} - -static u32 ath12k_dp_rx_h_freq(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_freq(desc); -} - -static u8 ath12k_dp_rx_h_pkt_type(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_pkt_type(desc); -} - -static u8 ath12k_dp_rx_h_nss(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return hweight8(ab->hal_rx_ops->rx_desc_get_msdu_nss(desc)); -} - -static u8 ath12k_dp_rx_h_tid(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_tid(desc); -} - -static u16 ath12k_dp_rx_h_peer_id(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_peer_id(desc); -} - -u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_l3_pad_bytes(desc); -} - -static bool ath12k_dp_rx_h_first_msdu(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_first_msdu(desc); -} - -static bool ath12k_dp_rx_h_last_msdu(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_last_msdu(desc); -} - -static void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab, - struct hal_rx_desc *fdesc, - struct hal_rx_desc *ldesc) -{ - ab->hal_rx_ops->rx_desc_copy_end_tlv(fdesc, ldesc); -} - -static void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab, - struct hal_rx_desc *desc, - u16 len) -{ - ab->hal_rx_ops->rx_desc_set_msdu_len(desc, len); -} - -u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, - struct hal_rx_desc *rx_desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_ppdu_id(rx_desc); -} - -bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, - struct hal_rx_desc *rx_desc) -{ - u32 tlv_tag; - - tlv_tag = ab->hal_rx_ops->rx_desc_get_mpdu_start_tag(rx_desc); - - return tlv_tag == HAL_RX_MPDU_START; -} - -static bool ath12k_dp_rx_h_is_da_mcbc(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return (ath12k_dp_rx_h_first_msdu(ab, desc) && - ab->hal_rx_ops->rx_desc_is_da_mcbc(desc)); -} - -static bool ath12k_dp_rxdesc_mac_addr2_valid(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_mac_addr2_valid(desc); -} - -static u8 *ath12k_dp_rxdesc_get_mpdu_start_addr2(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_mpdu_start_addr2(desc); -} - -static void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab, - struct hal_rx_desc *desc, - struct ieee80211_hdr *hdr) -{ - ab->hal_rx_ops->rx_desc_get_dot11_hdr(desc, hdr); -} - -static void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, - struct hal_rx_desc *desc, - u8 *crypto_hdr, - enum hal_encrypt_type enctype) -{ - ab->hal_rx_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); -} - -static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_src_link_id(desc); -} - -static void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) -{ - struct sk_buff *skb; - - while ((skb = __skb_dequeue(skb_list))) - dev_kfree_skb_any(skb); -} - static size_t ath12k_dp_list_cut_nodes(struct list_head *list, struct list_head *head, size_t count) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 69d0a36a91d88..9d37684c1f011 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 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 ATH12K_DP_RX_H #define ATH12K_DP_RX_H @@ -117,6 +117,243 @@ static inline u32 ath12k_he_gi_to_nl80211_he_gi(u8 sgi) return ret; } +static inline enum hal_encrypt_type ath12k_dp_rx_h_enctype(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + if (!ab->hal_rx_ops->rx_desc_encrypt_valid(desc)) + return HAL_ENCRYPT_TYPE_OPEN; + + return ab->hal_rx_ops->rx_desc_get_encrypt_type(desc); +} + +static inline u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_decap_type(desc); +} + +static inline u8 ath12k_dp_rx_h_mesh_ctl_present(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_mesh_ctl(desc); +} + +static inline bool ath12k_dp_rx_h_seq_ctrl_valid(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_mpdu_seq_ctl_vld(desc); +} + +static inline bool ath12k_dp_rx_h_fc_valid(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_mpdu_fc_valid(desc); +} + +static inline bool ath12k_dp_rx_h_more_frags(struct ath12k_base *ab, + struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr; + + hdr = (struct ieee80211_hdr *)(skb->data + ab->hal.hal_desc_sz); + return ieee80211_has_morefrags(hdr->frame_control); +} + +static inline u16 ath12k_dp_rx_h_frag_no(struct ath12k_base *ab, + struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr; + + hdr = (struct ieee80211_hdr *)(skb->data + ab->hal.hal_desc_sz); + return le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; +} + +static inline u16 ath12k_dp_rx_h_seq_no(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_mpdu_start_seq_no(desc); +} + +static inline bool ath12k_dp_rx_h_msdu_done(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->dp_rx_h_msdu_done(desc); +} + +static inline bool ath12k_dp_rx_h_l4_cksum_fail(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->dp_rx_h_l4_cksum_fail(desc); +} + +static inline bool ath12k_dp_rx_h_ip_cksum_fail(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->dp_rx_h_ip_cksum_fail(desc); +} + +static inline bool ath12k_dp_rx_h_is_decrypted(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->dp_rx_h_is_decrypted(desc); +} + +static inline u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->dp_rx_h_mpdu_err(desc); +} + +static inline u16 ath12k_dp_rx_h_msdu_len(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_msdu_len(desc); +} + +static inline u8 ath12k_dp_rx_h_sgi(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_msdu_sgi(desc); +} + +static inline u8 ath12k_dp_rx_h_rate_mcs(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_msdu_rate_mcs(desc); +} + +static inline u8 ath12k_dp_rx_h_rx_bw(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_msdu_rx_bw(desc); +} + +static inline u32 ath12k_dp_rx_h_freq(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_msdu_freq(desc); +} + +static inline u8 ath12k_dp_rx_h_pkt_type(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_msdu_pkt_type(desc); +} + +static inline u8 ath12k_dp_rx_h_nss(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return hweight8(ab->hal_rx_ops->rx_desc_get_msdu_nss(desc)); +} + +static inline u8 ath12k_dp_rx_h_tid(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_mpdu_tid(desc); +} + +static inline u16 ath12k_dp_rx_h_peer_id(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_mpdu_peer_id(desc); +} + +static inline u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_l3_pad_bytes(desc); +} + +static inline bool ath12k_dp_rx_h_first_msdu(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_first_msdu(desc); +} + +static inline bool ath12k_dp_rx_h_last_msdu(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_last_msdu(desc); +} + +static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab, + struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc) +{ + ab->hal_rx_ops->rx_desc_copy_end_tlv(fdesc, ldesc); +} + +static inline void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab, + struct hal_rx_desc *desc, + u16 len) +{ + ab->hal_rx_ops->rx_desc_set_msdu_len(desc, len); +} + +static inline u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, + struct hal_rx_desc *rx_desc) +{ + return ab->hal_rx_ops->rx_desc_get_mpdu_ppdu_id(rx_desc); +} + +static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, + struct hal_rx_desc *rx_desc) +{ + u32 tlv_tag; + + tlv_tag = ab->hal_rx_ops->rx_desc_get_mpdu_start_tag(rx_desc); + + return tlv_tag == HAL_RX_MPDU_START; +} + +static inline bool ath12k_dp_rx_h_is_da_mcbc(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return (ath12k_dp_rx_h_first_msdu(ab, desc) && + ab->hal_rx_ops->rx_desc_is_da_mcbc(desc)); +} + +static inline bool ath12k_dp_rxdesc_mac_addr2_valid(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_mac_addr2_valid(desc); +} + +static inline u8 *ath12k_dp_rxdesc_get_mpdu_start_addr2(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_mpdu_start_addr2(desc); +} + +static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab, + struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr) +{ + ab->hal_rx_ops->rx_desc_get_dot11_hdr(desc, hdr); +} + +static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, + struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype) +{ + ab->hal_rx_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); +} + +static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hal_rx_ops->rx_desc_get_msdu_src_link_id(desc); +} + +static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) +{ + struct sk_buff *skb; + + while ((skb = __skb_dequeue(skb_list))) + dev_kfree_skb_any(skb); +} + int ath12k_dp_rx_ampdu_start(struct ath12k *ar, struct ieee80211_ampdu_params *params, u8 link_id); From 0789ce59d8c4723d140a32fe28e09ae6423cede0 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:38 +0530 Subject: [PATCH 018/140] wifi: ath12k: Move Rx error related functions to wifi7 directory Move wifi7 architecture specific Rx error functions from dp_rx.c to wifi7 directory. The new wifi7-specific dp_rx.c file will continue to be part of ath12k.ko temporarily until the corresponding infra for movement to the ath12k_wifi7.ko arrives in upcoming patches. Move following architecture specific APIs to wifi7 directory: ath12k_dp_rx_h_tkip_mic_err ath12k_dp_rx_h_rxdma_err ath12k_dp_rx_h_reo_err ath12k_dp_rx_wbm_err ath12k_dp_rx_process_wbm_err Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-6-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/dp.c | 2 +- drivers/net/wireless/ath/ath12k/dp_mon.c | 2 +- drivers/net/wireless/ath/ath12k/dp_rx.c | 370 +----------------- drivers/net/wireless/ath/ath12k/dp_rx.h | 18 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 350 +++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 14 + 7 files changed, 396 insertions(+), 361 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index b34cf83a24eb1..d7628bb7af029 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -24,6 +24,7 @@ ath12k-$(CONFIG_ATH12K_AHB) += ahb.o ath12k-y += wifi7/hal_tx.o \ wifi7/hal_rx.o \ + wifi7/dp_rx.o obj-$(CONFIG_ATH12K) += wifi7/ diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index ec6300eb38921..1faac4ab641c1 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -10,7 +10,7 @@ #include "wifi7/hal_tx.h" #include "hif.h" #include "debug.h" -#include "dp_rx.h" +#include "wifi7/dp_rx.h" #include "peer.h" #include "dp_mon.h" diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 39d1967584db8..803de9ca3e51a 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -6,7 +6,7 @@ #include "dp_mon.h" #include "debug.h" -#include "dp_rx.h" +#include "wifi7/dp_rx.h" #include "dp_tx.h" #include "peer.h" diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 1b1d9f6ed8027..6276a9cb26d86 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -2136,11 +2136,11 @@ static void ath12k_dp_rx_h_undecap_eth(struct ath12k *ar, ether_addr_copy(ieee80211_get_SA(hdr), sa); } -static void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, - struct hal_rx_desc *rx_desc, - enum hal_encrypt_type enctype, - struct ieee80211_rx_status *status, - bool decrypted) +void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, + struct hal_rx_desc *rx_desc, + enum hal_encrypt_type enctype, + struct ieee80211_rx_status *status, + bool decrypted) { struct ath12k_base *ab = ar->ab; u8 decap; @@ -2440,9 +2440,9 @@ void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info) ath12k_dp_rx_h_rate(ar, rx_info); } -static void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, - struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info) +void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, + struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info) { struct ath12k_base *ab = ar->ab; struct ieee80211_rx_status *rx_status; @@ -2512,9 +2512,9 @@ static void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *nap ieee80211_rx_napi(ath12k_ar_to_hw(ar), pubsta, msdu, napi); } -static bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, - struct hal_rx_desc *rx_desc, - struct sk_buff *msdu) +bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, + struct hal_rx_desc *rx_desc, + struct sk_buff *msdu) { struct ieee80211_hdr *hdr; u8 decap_type; @@ -3761,9 +3761,9 @@ static void ath12k_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, } } -static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info, - struct sk_buff_head *msdu_list) +int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info, + struct sk_buff_head *msdu_list) { struct ath12k_base *ab = ar->ab; u16 msdu_len; @@ -3831,348 +3831,6 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, return 0; } -static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info, - struct sk_buff_head *msdu_list) -{ - struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); - bool drop = false; - - ar->ab->device_stats.reo_error[rxcb->err_code]++; - - switch (rxcb->err_code) { - case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO: - if (ath12k_dp_rx_h_null_q_desc(ar, msdu, rx_info, msdu_list)) - drop = true; - break; - case HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED: - /* TODO: Do not drop PN failed packets in the driver; - * instead, it is good to drop such packets in mac80211 - * after incrementing the replay counters. - */ - fallthrough; - default: - /* TODO: Review other errors and process them to mac80211 - * as appropriate. - */ - drop = true; - break; - } - - return drop; -} - -static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info) -{ - struct ath12k_base *ab = ar->ab; - u16 msdu_len; - struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; - u8 l3pad_bytes; - struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; - - rxcb->is_first_msdu = ath12k_dp_rx_h_first_msdu(ab, desc); - rxcb->is_last_msdu = ath12k_dp_rx_h_last_msdu(ab, desc); - - l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc); - msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc); - - if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) { - ath12k_dbg(ab, ATH12K_DBG_DATA, - "invalid msdu len in tkip mic err %u\n", msdu_len); - ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", desc, - sizeof(*desc)); - return true; - } - - skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); - skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); - - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu))) - return true; - - ath12k_dp_rx_h_ppdu(ar, rx_info); - - rx_info->rx_status->flag |= (RX_FLAG_MMIC_STRIPPED | RX_FLAG_MMIC_ERROR | - RX_FLAG_DECRYPTED); - - ath12k_dp_rx_h_undecap(ar, msdu, desc, - HAL_ENCRYPT_TYPE_TKIP_MIC, rx_info->rx_status, false); - return false; -} - -static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info) -{ - struct ath12k_base *ab = ar->ab; - struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); - struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; - bool drop = false; - u32 err_bitmap; - - ar->ab->device_stats.rxdma_error[rxcb->err_code]++; - - switch (rxcb->err_code) { - case HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR: - case HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR: - err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc); - if (err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) { - ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info); - drop = ath12k_dp_rx_h_tkip_mic_err(ar, msdu, rx_info); - break; - } - fallthrough; - default: - /* TODO: Review other rxdma error code to check if anything is - * worth reporting to mac80211 - */ - drop = true; - break; - } - - return drop; -} - -static void ath12k_dp_rx_wbm_err(struct ath12k *ar, - struct napi_struct *napi, - struct sk_buff *msdu, - struct sk_buff_head *msdu_list) -{ - struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); - struct ieee80211_rx_status rxs = {}; - struct ath12k_dp_rx_info rx_info; - bool drop = true; - - rx_info.addr2_present = false; - rx_info.rx_status = &rxs; - - switch (rxcb->err_rel_src) { - case HAL_WBM_REL_SRC_MODULE_REO: - drop = ath12k_dp_rx_h_reo_err(ar, msdu, &rx_info, msdu_list); - break; - case HAL_WBM_REL_SRC_MODULE_RXDMA: - drop = ath12k_dp_rx_h_rxdma_err(ar, msdu, &rx_info); - break; - default: - /* msdu will get freed */ - break; - } - - if (drop) { - dev_kfree_skb_any(msdu); - return; - } - - rx_info.rx_status->flag |= RX_FLAG_SKIP_MONITOR; - - ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info); -} - -int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, - struct napi_struct *napi, int budget) -{ - struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; - struct ath12k_hw_group *ag = ab->ag; - struct ath12k *ar; - struct ath12k_dp *dp = &ab->dp; - struct dp_rxdma_ring *rx_ring; - struct hal_rx_wbm_rel_info err_info; - struct hal_srng *srng; - struct sk_buff *msdu; - struct sk_buff_head msdu_list, scatter_msdu_list; - struct ath12k_skb_rxcb *rxcb; - void *rx_desc; - int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; - int total_num_buffs_reaped = 0; - struct ath12k_rx_desc_info *desc_info; - struct ath12k_device_dp_stats *device_stats = &ab->device_stats; - struct ath12k_hw_link *hw_links = ag->hw_links; - struct ath12k_base *partner_ab; - u8 hw_link_id, device_id; - int ret, pdev_id; - struct hal_rx_desc *msdu_data; - - __skb_queue_head_init(&msdu_list); - __skb_queue_head_init(&scatter_msdu_list); - - for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) - INIT_LIST_HEAD(&rx_desc_used_list[device_id]); - - srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id]; - spin_lock_bh(&srng->lock); - - ath12k_hal_srng_access_begin(ab, srng); - - while (budget) { - rx_desc = ath12k_hal_srng_dst_get_next_entry(ab, srng); - if (!rx_desc) - break; - - ret = ath12k_hal_wbm_desc_parse_err(ab, rx_desc, &err_info); - if (ret) { - ath12k_warn(ab, - "failed to parse rx error in wbm_rel ring desc %d\n", - ret); - continue; - } - - desc_info = err_info.rx_desc; - - /* retry manual desc retrieval if hw cc is not done */ - if (!desc_info) { - desc_info = ath12k_dp_get_rx_desc(ab, err_info.cookie); - if (!desc_info) { - ath12k_warn(ab, "Invalid cookie in DP WBM rx error descriptor retrieval: 0x%x\n", - err_info.cookie); - continue; - } - } - - if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) - ath12k_warn(ab, "WBM RX err, Check HW CC implementation"); - - msdu = desc_info->skb; - desc_info->skb = NULL; - - device_id = desc_info->device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - if (unlikely(!partner_ab)) { - dev_kfree_skb_any(msdu); - - /* In any case continuation bit is set - * in the previous record, cleanup scatter_msdu_list - */ - ath12k_dp_clean_up_skb_list(&scatter_msdu_list); - continue; - } - - list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]); - - rxcb = ATH12K_SKB_RXCB(msdu); - dma_unmap_single(partner_ab->dev, rxcb->paddr, - msdu->len + skb_tailroom(msdu), - DMA_FROM_DEVICE); - - num_buffs_reaped[device_id]++; - total_num_buffs_reaped++; - - if (!err_info.continuation) - budget--; - - if (err_info.push_reason != - HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED) { - dev_kfree_skb_any(msdu); - continue; - } - - msdu_data = (struct hal_rx_desc *)msdu->data; - rxcb->err_rel_src = err_info.err_rel_src; - rxcb->err_code = err_info.err_code; - rxcb->is_first_msdu = err_info.first_msdu; - rxcb->is_last_msdu = err_info.last_msdu; - rxcb->is_continuation = err_info.continuation; - rxcb->rx_desc = msdu_data; - - if (err_info.continuation) { - __skb_queue_tail(&scatter_msdu_list, msdu); - continue; - } - - hw_link_id = ath12k_dp_rx_get_msdu_src_link(partner_ab, - msdu_data); - if (hw_link_id >= ATH12K_GROUP_MAX_RADIO) { - dev_kfree_skb_any(msdu); - - /* In any case continuation bit is set - * in the previous record, cleanup scatter_msdu_list - */ - ath12k_dp_clean_up_skb_list(&scatter_msdu_list); - continue; - } - - if (!skb_queue_empty(&scatter_msdu_list)) { - struct sk_buff *msdu; - - skb_queue_walk(&scatter_msdu_list, msdu) { - rxcb = ATH12K_SKB_RXCB(msdu); - rxcb->hw_link_id = hw_link_id; - } - - skb_queue_splice_tail_init(&scatter_msdu_list, - &msdu_list); - } - - rxcb = ATH12K_SKB_RXCB(msdu); - rxcb->hw_link_id = hw_link_id; - __skb_queue_tail(&msdu_list, msdu); - } - - /* In any case continuation bit is set in the - * last record, cleanup scatter_msdu_list - */ - ath12k_dp_clean_up_skb_list(&scatter_msdu_list); - - ath12k_hal_srng_access_end(ab, srng); - - spin_unlock_bh(&srng->lock); - - if (!total_num_buffs_reaped) - goto done; - - for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) { - if (!num_buffs_reaped[device_id]) - continue; - - partner_ab = ath12k_ag_to_ab(ag, device_id); - rx_ring = &partner_ab->dp.rx_refill_buf_ring; - - ath12k_dp_rx_bufs_replenish(ab, rx_ring, - &rx_desc_used_list[device_id], - num_buffs_reaped[device_id]); - } - - rcu_read_lock(); - while ((msdu = __skb_dequeue(&msdu_list))) { - rxcb = ATH12K_SKB_RXCB(msdu); - hw_link_id = rxcb->hw_link_id; - - device_id = hw_links[hw_link_id].device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - if (unlikely(!partner_ab)) { - ath12k_dbg(ab, ATH12K_DBG_DATA, - "Unable to process WBM error msdu due to invalid hw link id %d device id %d\n", - hw_link_id, device_id); - dev_kfree_skb_any(msdu); - continue; - } - - pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, - hw_links[hw_link_id].pdev_idx); - ar = partner_ab->pdevs[pdev_id].ar; - - if (!ar || !rcu_dereference(ar->ab->pdevs_active[pdev_id])) { - dev_kfree_skb_any(msdu); - continue; - } - - if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) { - dev_kfree_skb_any(msdu); - continue; - } - - if (rxcb->err_rel_src < HAL_WBM_REL_SRC_MODULE_MAX) { - device_id = ar->ab->device_id; - device_stats->rx_wbm_rel_source[rxcb->err_rel_src][device_id]++; - } - - ath12k_dp_rx_wbm_err(ar, napi, msdu, &msdu_list); - } - rcu_read_unlock(); -done: - return total_num_buffs_reaped; -} - void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab) { struct ath12k_dp *dp = &ab->dp; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 9d37684c1f011..939dc60ec4582 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -354,6 +354,20 @@ static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) dev_kfree_skb_any(skb); } +void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, + struct hal_rx_desc *rx_desc, + enum hal_encrypt_type enctype, + struct ieee80211_rx_status *status, + bool decrypted); +void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, + struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info); +bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, + struct hal_rx_desc *rx_desc, + struct sk_buff *msdu); +int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info, + struct sk_buff_head *msdu_list); int ath12k_dp_rx_ampdu_start(struct ath12k *ar, struct ieee80211_ampdu_params *params, u8 link_id); @@ -381,8 +395,6 @@ int ath12k_dp_rx_pdev_alloc(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab); void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab); -int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, - struct napi_struct *napi, int budget); int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, int budget); int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id, @@ -404,7 +416,6 @@ u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, struct hal_rx_desc *desc); u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, struct hal_rx_desc *desc); -void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info); int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); @@ -425,4 +436,5 @@ int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, enum hal_wbm_rel_bm_act action); bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); +void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info); #endif /* ATH12K_DP_RX_H */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c new file mode 100644 index 0000000000000..26539a4d4b303 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -0,0 +1,350 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "dp_rx.h" +#include "../dp_tx.h" + +static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info) +{ + struct ath12k_base *ab = ar->ab; + u16 msdu_len; + struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; + u8 l3pad_bytes; + struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); + u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + + rxcb->is_first_msdu = ath12k_dp_rx_h_first_msdu(ab, desc); + rxcb->is_last_msdu = ath12k_dp_rx_h_last_msdu(ab, desc); + + l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc); + msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc); + + if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) { + ath12k_dbg(ab, ATH12K_DBG_DATA, + "invalid msdu len in tkip mic err %u\n", msdu_len); + ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", desc, + sizeof(*desc)); + return true; + } + + skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); + skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); + + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu))) + return true; + + ath12k_dp_rx_h_ppdu(ar, rx_info); + + rx_info->rx_status->flag |= (RX_FLAG_MMIC_STRIPPED | RX_FLAG_MMIC_ERROR | + RX_FLAG_DECRYPTED); + + ath12k_dp_rx_h_undecap(ar, msdu, desc, + HAL_ENCRYPT_TYPE_TKIP_MIC, rx_info->rx_status, false); + return false; +} + +static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); + struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; + bool drop = false; + u32 err_bitmap; + + ar->ab->device_stats.rxdma_error[rxcb->err_code]++; + + switch (rxcb->err_code) { + case HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR: + case HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR: + err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc); + if (err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) { + ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info); + drop = ath12k_dp_rx_h_tkip_mic_err(ar, msdu, rx_info); + break; + } + fallthrough; + default: + /* TODO: Review other rxdma error code to check if anything is + * worth reporting to mac80211 + */ + drop = true; + break; + } + + return drop; +} + +static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info, + struct sk_buff_head *msdu_list) +{ + struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); + bool drop = false; + + ar->ab->device_stats.reo_error[rxcb->err_code]++; + + switch (rxcb->err_code) { + case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO: + if (ath12k_dp_rx_h_null_q_desc(ar, msdu, rx_info, msdu_list)) + drop = true; + break; + case HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED: + /* TODO: Do not drop PN failed packets in the driver; + * instead, it is good to drop such packets in mac80211 + * after incrementing the replay counters. + */ + fallthrough; + default: + /* TODO: Review other errors and process them to mac80211 + * as appropriate. + */ + drop = true; + break; + } + + return drop; +} + +static void ath12k_dp_rx_wbm_err(struct ath12k *ar, + struct napi_struct *napi, + struct sk_buff *msdu, + struct sk_buff_head *msdu_list) +{ + struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); + struct ieee80211_rx_status rxs = {}; + struct ath12k_dp_rx_info rx_info; + bool drop = true; + + rx_info.addr2_present = false; + rx_info.rx_status = &rxs; + + switch (rxcb->err_rel_src) { + case HAL_WBM_REL_SRC_MODULE_REO: + drop = ath12k_dp_rx_h_reo_err(ar, msdu, &rx_info, msdu_list); + break; + case HAL_WBM_REL_SRC_MODULE_RXDMA: + drop = ath12k_dp_rx_h_rxdma_err(ar, msdu, &rx_info); + break; + default: + /* msdu will get freed */ + break; + } + + if (drop) { + dev_kfree_skb_any(msdu); + return; + } + + rx_info.rx_status->flag |= RX_FLAG_SKIP_MONITOR; + + ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info); +} + +int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, + struct napi_struct *napi, int budget) +{ + struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; + struct ath12k_hw_group *ag = ab->ag; + struct ath12k *ar; + struct ath12k_dp *dp = &ab->dp; + struct dp_rxdma_ring *rx_ring; + struct hal_rx_wbm_rel_info err_info; + struct hal_srng *srng; + struct sk_buff *msdu; + struct sk_buff_head msdu_list, scatter_msdu_list; + struct ath12k_skb_rxcb *rxcb; + void *rx_desc; + int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; + int total_num_buffs_reaped = 0; + struct ath12k_rx_desc_info *desc_info; + struct ath12k_device_dp_stats *device_stats = &ab->device_stats; + struct ath12k_hw_link *hw_links = ag->hw_links; + struct ath12k_base *partner_ab; + u8 hw_link_id, device_id; + int ret, pdev_id; + struct hal_rx_desc *msdu_data; + + __skb_queue_head_init(&msdu_list); + __skb_queue_head_init(&scatter_msdu_list); + + for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) + INIT_LIST_HEAD(&rx_desc_used_list[device_id]); + + srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id]; + spin_lock_bh(&srng->lock); + + ath12k_hal_srng_access_begin(ab, srng); + + while (budget) { + rx_desc = ath12k_hal_srng_dst_get_next_entry(ab, srng); + if (!rx_desc) + break; + + ret = ath12k_hal_wbm_desc_parse_err(ab, rx_desc, &err_info); + if (ret) { + ath12k_warn(ab, + "failed to parse rx error in wbm_rel ring desc %d\n", + ret); + continue; + } + + desc_info = err_info.rx_desc; + + /* retry manual desc retrieval if hw cc is not done */ + if (!desc_info) { + desc_info = ath12k_dp_get_rx_desc(ab, err_info.cookie); + if (!desc_info) { + ath12k_warn(ab, "Invalid cookie in DP WBM rx error descriptor retrieval: 0x%x\n", + err_info.cookie); + continue; + } + } + + if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) + ath12k_warn(ab, "WBM RX err, Check HW CC implementation"); + + msdu = desc_info->skb; + desc_info->skb = NULL; + + device_id = desc_info->device_id; + partner_ab = ath12k_ag_to_ab(ag, device_id); + if (unlikely(!partner_ab)) { + dev_kfree_skb_any(msdu); + + /* In any case continuation bit is set + * in the previous record, cleanup scatter_msdu_list + */ + ath12k_dp_clean_up_skb_list(&scatter_msdu_list); + continue; + } + + list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]); + + rxcb = ATH12K_SKB_RXCB(msdu); + dma_unmap_single(partner_ab->dev, rxcb->paddr, + msdu->len + skb_tailroom(msdu), + DMA_FROM_DEVICE); + + num_buffs_reaped[device_id]++; + total_num_buffs_reaped++; + + if (!err_info.continuation) + budget--; + + if (err_info.push_reason != + HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED) { + dev_kfree_skb_any(msdu); + continue; + } + + msdu_data = (struct hal_rx_desc *)msdu->data; + rxcb->err_rel_src = err_info.err_rel_src; + rxcb->err_code = err_info.err_code; + rxcb->is_first_msdu = err_info.first_msdu; + rxcb->is_last_msdu = err_info.last_msdu; + rxcb->is_continuation = err_info.continuation; + rxcb->rx_desc = msdu_data; + + if (err_info.continuation) { + __skb_queue_tail(&scatter_msdu_list, msdu); + continue; + } + + hw_link_id = ath12k_dp_rx_get_msdu_src_link(partner_ab, + msdu_data); + if (hw_link_id >= ATH12K_GROUP_MAX_RADIO) { + dev_kfree_skb_any(msdu); + + /* In any case continuation bit is set + * in the previous record, cleanup scatter_msdu_list + */ + ath12k_dp_clean_up_skb_list(&scatter_msdu_list); + continue; + } + + if (!skb_queue_empty(&scatter_msdu_list)) { + struct sk_buff *msdu; + + skb_queue_walk(&scatter_msdu_list, msdu) { + rxcb = ATH12K_SKB_RXCB(msdu); + rxcb->hw_link_id = hw_link_id; + } + + skb_queue_splice_tail_init(&scatter_msdu_list, + &msdu_list); + } + + rxcb = ATH12K_SKB_RXCB(msdu); + rxcb->hw_link_id = hw_link_id; + __skb_queue_tail(&msdu_list, msdu); + } + + /* In any case continuation bit is set in the + * last record, cleanup scatter_msdu_list + */ + ath12k_dp_clean_up_skb_list(&scatter_msdu_list); + + ath12k_hal_srng_access_end(ab, srng); + + spin_unlock_bh(&srng->lock); + + if (!total_num_buffs_reaped) + goto done; + + for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) { + if (!num_buffs_reaped[device_id]) + continue; + + partner_ab = ath12k_ag_to_ab(ag, device_id); + rx_ring = &partner_ab->dp.rx_refill_buf_ring; + + ath12k_dp_rx_bufs_replenish(ab, rx_ring, + &rx_desc_used_list[device_id], + num_buffs_reaped[device_id]); + } + + rcu_read_lock(); + while ((msdu = __skb_dequeue(&msdu_list))) { + rxcb = ATH12K_SKB_RXCB(msdu); + hw_link_id = rxcb->hw_link_id; + + device_id = hw_links[hw_link_id].device_id; + partner_ab = ath12k_ag_to_ab(ag, device_id); + if (unlikely(!partner_ab)) { + ath12k_dbg(ab, ATH12K_DBG_DATA, + "Unable to process WBM error msdu due to invalid hw link id %d device id %d\n", + hw_link_id, device_id); + dev_kfree_skb_any(msdu); + continue; + } + + pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + hw_links[hw_link_id].pdev_idx); + ar = partner_ab->pdevs[pdev_id].ar; + + if (!ar || !rcu_dereference(ar->ab->pdevs_active[pdev_id])) { + dev_kfree_skb_any(msdu); + continue; + } + + if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) { + dev_kfree_skb_any(msdu); + continue; + } + + if (rxcb->err_rel_src < HAL_WBM_REL_SRC_MODULE_MAX) { + device_id = ar->ab->device_id; + device_stats->rx_wbm_rel_source[rxcb->err_rel_src][device_id]++; + } + + ath12k_dp_rx_wbm_err(ar, napi, msdu, &msdu_list); + } + rcu_read_unlock(); +done: + return total_num_buffs_reaped; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h new file mode 100644 index 0000000000000..a6da98962345d --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#ifndef ATH12K_DP_RX_WIFI7_H +#define ATH12K_DP_RX_WIFI7_H + +#include "../core.h" +#include "../dp_rx.h" + +int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, + struct napi_struct *napi, int budget); +#endif From 8168026d182917265586a595ac8267188a34e2f3 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:39 +0530 Subject: [PATCH 019/140] wifi: ath12k: Move hal_desc.h file to wifi7 directory Move wifi7 architecture specific file hal_desc.h to wifi7 directory, and move the common part from it to hal.h file which is in the common directory. It is as part of a broader effort to separate common and hardware-specific code into distinct modules. This modularization enables reuse of the common driver components across multiple hardware architectures. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-7-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.h | 2 +- drivers/net/wireless/ath/ath12k/dp_rx.c | 2 +- drivers/net/wireless/ath/ath12k/hal.c | 2 +- drivers/net/wireless/ath/ath12k/hal.h | 149 +++++++++++++++++- .../ath/ath12k/{ => wifi7}/hal_desc.h | 149 +----------------- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 2 +- .../net/wireless/ath/ath12k/wifi7/hal_tx.c | 2 +- .../net/wireless/ath/ath12k/wifi7/hal_tx.h | 2 +- 8 files changed, 156 insertions(+), 154 deletions(-) rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_desc.h (95%) diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index dc33a0f85f2af..e0c610f7ff885 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -7,7 +7,7 @@ #ifndef ATH12K_DP_H #define ATH12K_DP_H -#include "hal_desc.h" +#include "wifi7/hal_desc.h" #include "wifi7/hal_rx.h" #include "hw.h" diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 6276a9cb26d86..c1b489c000e23 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -10,7 +10,7 @@ #include #include "core.h" #include "debug.h" -#include "hal_desc.h" +#include "wifi7/hal_desc.h" #include "hw.h" #include "dp_rx.h" #include "wifi7/hal_rx.h" diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index f9ce60d22cc1a..144c26586b794 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -7,7 +7,7 @@ #include "wifi7/hal_tx.h" #include "wifi7/hal_rx.h" #include "debug.h" -#include "hal_desc.h" +#include "wifi7/hal_desc.h" #include "hif.h" static const struct hal_srng_config hw_srng_config_template[] = { diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 322ebfed9b011..8e408b81c7736 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -7,11 +7,13 @@ #ifndef ATH12K_HAL_H #define ATH12K_HAL_H -#include "hal_desc.h" +#include "wifi7/hal_desc.h" #include "rx_desc.h" struct ath12k_base; +#define HAL_DESC_REO_NON_QOS_TID 16 + #define HAL_INVALID_PEERID 0x3fff #define VHT_SIG_SU_NSS_MASK 0x7 @@ -672,6 +674,128 @@ enum hal_reo_cmd_status { HAL_REO_CMD_DRAIN = 0xff, }; +enum hal_tcl_encap_type { + HAL_TCL_ENCAP_TYPE_RAW, + HAL_TCL_ENCAP_TYPE_NATIVE_WIFI, + HAL_TCL_ENCAP_TYPE_ETHERNET, + HAL_TCL_ENCAP_TYPE_802_3 = 3, + HAL_TCL_ENCAP_TYPE_MAX +}; + +enum hal_tcl_desc_type { + HAL_TCL_DESC_TYPE_BUFFER, + HAL_TCL_DESC_TYPE_EXT_DESC, + HAL_TCL_DESC_TYPE_MAX, +}; + +enum hal_reo_dest_ring_buffer_type { + HAL_REO_DEST_RING_BUFFER_TYPE_MSDU, + HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC, +}; + +enum hal_reo_dest_ring_push_reason { + HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED, + HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION, +}; + +enum hal_reo_entr_rxdma_push_reason { + HAL_REO_ENTR_RING_RXDMA_PUSH_REASON_ERR_DETECTED, + HAL_REO_ENTR_RING_RXDMA_PUSH_REASON_ROUTING_INSTRUCTION, + HAL_REO_ENTR_RING_RXDMA_PUSH_REASON_RX_FLUSH, +}; + +enum hal_reo_dest_ring_error_code { + HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO, + HAL_REO_DEST_RING_ERROR_CODE_DESC_INVALID, + HAL_REO_DEST_RING_ERROR_CODE_AMPDU_IN_NON_BA, + HAL_REO_DEST_RING_ERROR_CODE_NON_BA_DUPLICATE, + HAL_REO_DEST_RING_ERROR_CODE_BA_DUPLICATE, + HAL_REO_DEST_RING_ERROR_CODE_FRAME_2K_JUMP, + HAL_REO_DEST_RING_ERROR_CODE_BAR_2K_JUMP, + HAL_REO_DEST_RING_ERROR_CODE_FRAME_OOR, + HAL_REO_DEST_RING_ERROR_CODE_BAR_OOR, + HAL_REO_DEST_RING_ERROR_CODE_NO_BA_SESSION, + HAL_REO_DEST_RING_ERROR_CODE_FRAME_SN_EQUALS_SSN, + HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED, + HAL_REO_DEST_RING_ERROR_CODE_2K_ERR_FLAG_SET, + HAL_REO_DEST_RING_ERROR_CODE_PN_ERR_FLAG_SET, + HAL_REO_DEST_RING_ERROR_CODE_DESC_BLOCKED, + HAL_REO_DEST_RING_ERROR_CODE_MAX, +}; + +enum hal_reo_entr_rxdma_ecode { + HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_FCS_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_UNECRYPTED_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LEN_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LIMIT_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_WIFI_PARSE_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_PARSE_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_SA_TIMEOUT_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_DA_TIMEOUT_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_FLOW_TIMEOUT_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_FRAG_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_MULTICAST_ECHO_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_MISMATCH_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_UNAUTH_WDS_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_GRPCAST_AMSDU_WDS_ERR, + HAL_REO_ENTR_RING_RXDMA_ECODE_MAX, +}; + +enum hal_wbm_htt_tx_comp_status { + HAL_WBM_REL_HTT_TX_COMP_STATUS_OK, + HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP, + HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL, + HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ, + HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT, + HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY, + HAL_WBM_REL_HTT_TX_COMP_STATUS_VDEVID_MISMATCH, + HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX, +}; + +enum hal_encrypt_type { + HAL_ENCRYPT_TYPE_WEP_40, + HAL_ENCRYPT_TYPE_WEP_104, + HAL_ENCRYPT_TYPE_TKIP_NO_MIC, + HAL_ENCRYPT_TYPE_WEP_128, + HAL_ENCRYPT_TYPE_TKIP_MIC, + HAL_ENCRYPT_TYPE_WAPI, + HAL_ENCRYPT_TYPE_CCMP_128, + HAL_ENCRYPT_TYPE_OPEN, + HAL_ENCRYPT_TYPE_CCMP_256, + HAL_ENCRYPT_TYPE_GCMP_128, + HAL_ENCRYPT_TYPE_AES_GCMP_256, + HAL_ENCRYPT_TYPE_WAPI_GCM_SM4, +}; + +enum hal_tx_rate_stats_bw { + HAL_TX_RATE_STATS_BW_20, + HAL_TX_RATE_STATS_BW_40, + HAL_TX_RATE_STATS_BW_80, + HAL_TX_RATE_STATS_BW_160, +}; + +enum hal_tx_rate_stats_pkt_type { + HAL_TX_RATE_STATS_PKT_TYPE_11A, + HAL_TX_RATE_STATS_PKT_TYPE_11B, + HAL_TX_RATE_STATS_PKT_TYPE_11N, + HAL_TX_RATE_STATS_PKT_TYPE_11AC, + HAL_TX_RATE_STATS_PKT_TYPE_11AX, + HAL_TX_RATE_STATS_PKT_TYPE_11BA, + HAL_TX_RATE_STATS_PKT_TYPE_11BE, +}; + +enum hal_tx_rate_stats_sgi { + HAL_TX_RATE_STATS_SGI_08US, + HAL_TX_RATE_STATS_SGI_04US, + HAL_TX_RATE_STATS_SGI_16US, + HAL_TX_RATE_STATS_SGI_32US, +}; + struct hal_wbm_idle_scatter_list { dma_addr_t paddr; struct hal_wbm_link_desc *vaddr; @@ -1281,6 +1405,29 @@ struct ath12k_hal_tcl_to_wbm_rbm_map { u8 rbm_id; }; +enum hal_wbm_rel_bm_act { + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE, + HAL_WBM_REL_BM_ACT_REL_MSDU, +}; + +/* hal_wbm_rel_bm_act + * + * put_in_idle_list + * Put the buffer or descriptor back in the idle list. In case of MSDU or + * MDPU link descriptor, BM does not need to check to release any + * individual MSDU buffers. + * + * release_msdu_list + * This BM action can only be used in combination with desc_type being + * msdu_link_descriptor. Field first_msdu_index points out which MSDU + * pointer in the MSDU link descriptor is the first of an MPDU that is + * released. BM shall release all the MSDU buffers linked to this first + * MSDU buffer pointer. All related MSDU buffer pointer entries shall be + * set to value 0, which represents the 'NULL' pointer. When all MSDU + * buffer pointers in the MSDU link descriptor are 'NULL', the MSDU link + * descriptor itself shall also be released. + */ + #define RU_INVALID 0 #define RU_26 1 #define RU_52 2 diff --git a/drivers/net/wireless/ath/ath12k/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h similarity index 95% rename from drivers/net/wireless/ath/ath12k/hal_desc.h rename to drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h index 13ddac4a94125..b884f4f089387 100644 --- a/drivers/net/wireless/ath/ath12k/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022, 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ -#include "core.h" +#include "../core.h" #ifndef ATH12K_HAL_DESC_H #define ATH12K_HAL_DESC_H @@ -820,35 +820,6 @@ struct rx_msdu_ext_desc { * Set to the link ID of the PMAC that received the frame */ -enum hal_reo_dest_ring_buffer_type { - HAL_REO_DEST_RING_BUFFER_TYPE_MSDU, - HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC, -}; - -enum hal_reo_dest_ring_push_reason { - HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED, - HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION, -}; - -enum hal_reo_dest_ring_error_code { - HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO, - HAL_REO_DEST_RING_ERROR_CODE_DESC_INVALID, - HAL_REO_DEST_RING_ERROR_CODE_AMPDU_IN_NON_BA, - HAL_REO_DEST_RING_ERROR_CODE_NON_BA_DUPLICATE, - HAL_REO_DEST_RING_ERROR_CODE_BA_DUPLICATE, - HAL_REO_DEST_RING_ERROR_CODE_FRAME_2K_JUMP, - HAL_REO_DEST_RING_ERROR_CODE_BAR_2K_JUMP, - HAL_REO_DEST_RING_ERROR_CODE_FRAME_OOR, - HAL_REO_DEST_RING_ERROR_CODE_BAR_OOR, - HAL_REO_DEST_RING_ERROR_CODE_NO_BA_SESSION, - HAL_REO_DEST_RING_ERROR_CODE_FRAME_SN_EQUALS_SSN, - HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED, - HAL_REO_DEST_RING_ERROR_CODE_2K_ERR_FLAG_SET, - HAL_REO_DEST_RING_ERROR_CODE_PN_ERR_FLAG_SET, - HAL_REO_DEST_RING_ERROR_CODE_DESC_BLOCKED, - HAL_REO_DEST_RING_ERROR_CODE_MAX, -}; - #define HAL_REO_DEST_RING_INFO0_BUFFER_TYPE BIT(0) #define HAL_REO_DEST_RING_INFO0_PUSH_REASON GENMASK(2, 1) #define HAL_REO_DEST_RING_INFO0_ERROR_CODE GENMASK(7, 3) @@ -986,35 +957,6 @@ struct hal_reo_to_ppe_ring { * More Segments followed */ -enum hal_reo_entr_rxdma_push_reason { - HAL_REO_ENTR_RING_RXDMA_PUSH_REASON_ERR_DETECTED, - HAL_REO_ENTR_RING_RXDMA_PUSH_REASON_ROUTING_INSTRUCTION, - HAL_REO_ENTR_RING_RXDMA_PUSH_REASON_RX_FLUSH, -}; - -enum hal_reo_entr_rxdma_ecode { - HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_FCS_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_UNECRYPTED_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LEN_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LIMIT_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_WIFI_PARSE_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_PARSE_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_SA_TIMEOUT_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_DA_TIMEOUT_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_FLOW_TIMEOUT_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_FRAG_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_MULTICAST_ECHO_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_MISMATCH_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_UNAUTH_WDS_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_GRPCAST_AMSDU_WDS_ERR, - HAL_REO_ENTR_RING_RXDMA_ECODE_MAX, -}; - enum hal_rx_reo_dest_ring { HAL_RX_REO_DEST_RING_TCL, HAL_RX_REO_DEST_RING_SW1, @@ -1269,46 +1211,6 @@ struct hal_reo_flush_cache { #define HAL_TCL_DATA_CMD_INFO5_RING_ID GENMASK(27, 20) #define HAL_TCL_DATA_CMD_INFO5_LOOPING_COUNT GENMASK(31, 28) -enum hal_encrypt_type { - HAL_ENCRYPT_TYPE_WEP_40, - HAL_ENCRYPT_TYPE_WEP_104, - HAL_ENCRYPT_TYPE_TKIP_NO_MIC, - HAL_ENCRYPT_TYPE_WEP_128, - HAL_ENCRYPT_TYPE_TKIP_MIC, - HAL_ENCRYPT_TYPE_WAPI, - HAL_ENCRYPT_TYPE_CCMP_128, - HAL_ENCRYPT_TYPE_OPEN, - HAL_ENCRYPT_TYPE_CCMP_256, - HAL_ENCRYPT_TYPE_GCMP_128, - HAL_ENCRYPT_TYPE_AES_GCMP_256, - HAL_ENCRYPT_TYPE_WAPI_GCM_SM4, -}; - -enum hal_tcl_encap_type { - HAL_TCL_ENCAP_TYPE_RAW, - HAL_TCL_ENCAP_TYPE_NATIVE_WIFI, - HAL_TCL_ENCAP_TYPE_ETHERNET, - HAL_TCL_ENCAP_TYPE_802_3 = 3, - HAL_TCL_ENCAP_TYPE_MAX -}; - -enum hal_tcl_desc_type { - HAL_TCL_DESC_TYPE_BUFFER, - HAL_TCL_DESC_TYPE_EXT_DESC, - HAL_TCL_DESC_TYPE_MAX, -}; - -enum hal_wbm_htt_tx_comp_status { - HAL_WBM_REL_HTT_TX_COMP_STATUS_OK, - HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP, - HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL, - HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ, - HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT, - HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY, - HAL_WBM_REL_HTT_TX_COMP_STATUS_VDEVID_MISMATCH, - HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX, -}; - struct hal_tcl_data_cmd { struct ath12k_buffer_addr buf_addr_info; __le32 info0; @@ -1765,30 +1667,6 @@ struct hal_ce_srng_dst_status_desc { #define HAL_TX_RATE_STATS_INFO0_OFDMA_TX BIT(16) #define HAL_TX_RATE_STATS_INFO0_TONES_IN_RU GENMASK(28, 17) -enum hal_tx_rate_stats_bw { - HAL_TX_RATE_STATS_BW_20, - HAL_TX_RATE_STATS_BW_40, - HAL_TX_RATE_STATS_BW_80, - HAL_TX_RATE_STATS_BW_160, -}; - -enum hal_tx_rate_stats_pkt_type { - HAL_TX_RATE_STATS_PKT_TYPE_11A, - HAL_TX_RATE_STATS_PKT_TYPE_11B, - HAL_TX_RATE_STATS_PKT_TYPE_11N, - HAL_TX_RATE_STATS_PKT_TYPE_11AC, - HAL_TX_RATE_STATS_PKT_TYPE_11AX, - HAL_TX_RATE_STATS_PKT_TYPE_11BA, - HAL_TX_RATE_STATS_PKT_TYPE_11BE, -}; - -enum hal_tx_rate_stats_sgi { - HAL_TX_RATE_STATS_SGI_08US, - HAL_TX_RATE_STATS_SGI_04US, - HAL_TX_RATE_STATS_SGI_16US, - HAL_TX_RATE_STATS_SGI_32US, -}; - struct hal_tx_rate_stats { __le32 info0; __le32 tsf; @@ -1844,28 +1722,6 @@ enum hal_wbm_rel_desc_type { * treat this is the same way as a link descriptor. */ -enum hal_wbm_rel_bm_act { - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE, - HAL_WBM_REL_BM_ACT_REL_MSDU, -}; - -/* hal_wbm_rel_bm_act - * - * put_in_idle_list - * Put the buffer or descriptor back in the idle list. In case of MSDU or - * MDPU link descriptor, BM does not need to check to release any - * individual MSDU buffers. - * - * release_msdu_list - * This BM action can only be used in combination with desc_type being - * msdu_link_descriptor. Field first_msdu_index points out which MSDU - * pointer in the MSDU link descriptor is the first of an MPDU that is - * released. BM shall release all the MSDU buffers linked to this first - * MSDU buffer pointer. All related MSDU buffer pointer entries shall be - * set to value 0, which represents the 'NULL' pointer. When all MSDU - * buffer pointers in the MSDU link descriptor are 'NULL', the MSDU link - * descriptor itself shall also be released. - */ #define HAL_WBM_COMPL_RX_INFO0_REL_SRC_MODULE GENMASK(2, 0) #define HAL_WBM_COMPL_RX_INFO0_BM_ACTION GENMASK(5, 3) #define HAL_WBM_COMPL_RX_INFO0_DESC_TYPE GENMASK(8, 6) @@ -2331,7 +2187,6 @@ enum hal_desc_buf_type { #define HAL_DESC_REO_OWNED 4 #define HAL_DESC_REO_QUEUE_DESC 8 #define HAL_DESC_REO_QUEUE_EXT_DESC 9 -#define HAL_DESC_REO_NON_QOS_TID 16 #define HAL_DESC_HDR_INFO0_OWNER GENMASK(3, 0) #define HAL_DESC_HDR_INFO0_BUF_TYPE GENMASK(7, 4) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index e8379e660d3a5..e539f3b1eeafc 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -9,7 +9,7 @@ #include "../hif.h" #include "hal_tx.h" #include "hal_rx.h" -#include "../hal_desc.h" +#include "hal_desc.h" static void ath12k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, u8 owner, u8 buffer_type, u32 magic) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c index 87c1312c4f46d..3a7d3163b1a56 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c @@ -4,7 +4,7 @@ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ -#include "../hal_desc.h" +#include "hal_desc.h" #include "../hal.h" #include "hal_tx.h" #include "../hif.h" diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h index b179320569ff7..412fe1ba22dcc 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h @@ -7,7 +7,7 @@ #ifndef ATH12K_HAL_TX_H #define ATH12K_HAL_TX_H -#include "../hal_desc.h" +#include "hal_desc.h" #include "../core.h" /* TODO: check all these data can be managed with struct ath12k_tx_desc_info for perf */ From 12223d68c849440ac00da5f6750e13882ffa6b6c Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:40 +0530 Subject: [PATCH 020/140] wifi: ath12k: Move rx_desc.h file to wifi7 directory Move wifi7 architecture specific file rx_desc.h to wifi7 directory and rename it to hal_rx_desc.h to match the naming convention used, and move the common part from it to hal.h file which is in the common directory. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-8-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.h | 2 +- drivers/net/wireless/ath/ath12k/hal.h | 48 ++++++++++++++++++- .../ath12k/{rx_desc.h => wifi7/hal_rx_desc.h} | 48 +------------------ 3 files changed, 49 insertions(+), 49 deletions(-) rename drivers/net/wireless/ath/ath12k/{rx_desc.h => wifi7/hal_rx_desc.h} (97%) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 939dc60ec4582..f06c102750733 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -7,7 +7,7 @@ #define ATH12K_DP_RX_H #include "core.h" -#include "rx_desc.h" +#include "wifi7/hal_rx_desc.h" #include "debug.h" #define DP_MAX_NWIFI_HDR_LEN 30 diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 8e408b81c7736..4b512fd3adc41 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -8,7 +8,7 @@ #define ATH12K_HAL_H #include "wifi7/hal_desc.h" -#include "rx_desc.h" +#include "wifi7/hal_rx_desc.h" struct ath12k_base; @@ -30,6 +30,11 @@ struct ath12k_base; #define HAL_RX_MON_MAX_AGGR_SIZE 128 #define HAL_MAX_UL_MU_USERS 37 +#define MAX_USER_POS 8 +#define MAX_MU_GROUP_ID 64 +#define MAX_MU_GROUP_SHOW 16 +#define MAX_MU_GROUP_LENGTH (6 * MAX_MU_GROUP_SHOW) + #define HAL_CE_REMAP_REG_BASE (ab->ce_remap_base_addr) #define HAL_LINK_DESC_SIZE (32 << 2) @@ -824,6 +829,47 @@ enum hal_srng_dir { HAL_SRNG_DIR_DST }; +enum rx_msdu_start_pkt_type { + RX_MSDU_START_PKT_TYPE_11A, + RX_MSDU_START_PKT_TYPE_11B, + RX_MSDU_START_PKT_TYPE_11N, + RX_MSDU_START_PKT_TYPE_11AC, + RX_MSDU_START_PKT_TYPE_11AX, + RX_MSDU_START_PKT_TYPE_11BA, + RX_MSDU_START_PKT_TYPE_11BE, +}; + +enum rx_msdu_start_sgi { + RX_MSDU_START_SGI_0_8_US, + RX_MSDU_START_SGI_0_4_US, + RX_MSDU_START_SGI_1_6_US, + RX_MSDU_START_SGI_3_2_US, +}; + +enum rx_msdu_start_recv_bw { + RX_MSDU_START_RECV_BW_20MHZ, + RX_MSDU_START_RECV_BW_40MHZ, + RX_MSDU_START_RECV_BW_80MHZ, + RX_MSDU_START_RECV_BW_160MHZ, +}; + +enum rx_msdu_start_reception_type { + RX_MSDU_START_RECEPTION_TYPE_SU, + RX_MSDU_START_RECEPTION_TYPE_DL_MU_MIMO, + RX_MSDU_START_RECEPTION_TYPE_DL_MU_OFDMA, + RX_MSDU_START_RECEPTION_TYPE_DL_MU_OFDMA_MIMO, + RX_MSDU_START_RECEPTION_TYPE_UL_MU_MIMO, + RX_MSDU_START_RECEPTION_TYPE_UL_MU_OFDMA, + RX_MSDU_START_RECEPTION_TYPE_UL_MU_OFDMA_MIMO, +}; + +enum rx_desc_decap_type { + RX_DESC_DECAP_TYPE_RAW, + RX_DESC_DECAP_TYPE_NATIVE_WIFI, + RX_DESC_DECAP_TYPE_ETHERNET2_DIX, + RX_DESC_DECAP_TYPE_8023, +}; + struct hal_rx_user_status { u32 mcs:4, nss:3, diff --git a/drivers/net/wireless/ath/ath12k/rx_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h similarity index 97% rename from drivers/net/wireless/ath/ath12k/rx_desc.h rename to drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h index 6c600473b4021..60f165a176e0f 100644 --- a/drivers/net/wireless/ath/ath12k/rx_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h @@ -1,18 +1,11 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 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 ATH12K_RX_DESC_H #define ATH12K_RX_DESC_H -enum rx_desc_decap_type { - RX_DESC_DECAP_TYPE_RAW, - RX_DESC_DECAP_TYPE_NATIVE_WIFI, - RX_DESC_DECAP_TYPE_ETHERNET2_DIX, - RX_DESC_DECAP_TYPE_8023, -}; - enum rx_desc_decrypt_status_code { RX_DESC_DECRYPT_STATUS_CODE_OK, RX_DESC_DECRYPT_STATUS_CODE_UNPROTECTED_FRAME, @@ -631,40 +624,6 @@ struct rx_mpdu_start_qcn9274_compact { * */ -enum rx_msdu_start_pkt_type { - RX_MSDU_START_PKT_TYPE_11A, - RX_MSDU_START_PKT_TYPE_11B, - RX_MSDU_START_PKT_TYPE_11N, - RX_MSDU_START_PKT_TYPE_11AC, - RX_MSDU_START_PKT_TYPE_11AX, - RX_MSDU_START_PKT_TYPE_11BA, - RX_MSDU_START_PKT_TYPE_11BE, -}; - -enum rx_msdu_start_sgi { - RX_MSDU_START_SGI_0_8_US, - RX_MSDU_START_SGI_0_4_US, - RX_MSDU_START_SGI_1_6_US, - RX_MSDU_START_SGI_3_2_US, -}; - -enum rx_msdu_start_recv_bw { - RX_MSDU_START_RECV_BW_20MHZ, - RX_MSDU_START_RECV_BW_40MHZ, - RX_MSDU_START_RECV_BW_80MHZ, - RX_MSDU_START_RECV_BW_160MHZ, -}; - -enum rx_msdu_start_reception_type { - RX_MSDU_START_RECEPTION_TYPE_SU, - RX_MSDU_START_RECEPTION_TYPE_DL_MU_MIMO, - RX_MSDU_START_RECEPTION_TYPE_DL_MU_OFDMA, - RX_MSDU_START_RECEPTION_TYPE_DL_MU_OFDMA_MIMO, - RX_MSDU_START_RECEPTION_TYPE_UL_MU_MIMO, - RX_MSDU_START_RECEPTION_TYPE_UL_MU_OFDMA, - RX_MSDU_START_RECEPTION_TYPE_UL_MU_OFDMA_MIMO, -}; - #define RX_MSDU_END_64_TLV_SRC_LINK_ID GENMASK(24, 22) #define RX_MSDU_END_INFO0_RXPCU_MPDU_FITLER GENMASK(1, 0) @@ -1536,9 +1495,4 @@ struct hal_rx_desc { } u; } __packed; -#define MAX_USER_POS 8 -#define MAX_MU_GROUP_ID 64 -#define MAX_MU_GROUP_SHOW 16 -#define MAX_MU_GROUP_LENGTH (6 * MAX_MU_GROUP_SHOW) - #endif /* ATH12K_RX_DESC_H */ From 6e23349dcb2e1cea5e3b3325a6e5b3dd9f75112f Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:41 +0530 Subject: [PATCH 021/140] wifi: ath12k: Move rxdma ring config functions to wifi7 directory Move architecture specific RxDMA functions to wifi7 directory. The moved APIs will be a part of dp_rx.c file inside wifi7 directory. wifi7/dp_rx.c file will continue to be part of ath12k.ko temporarily until the corresponding infra for movement to ath12k_wifi7.ko arrives in upcoming patches. Architecture specific APIs: ath12k_dp_rxdma_ring_sel_config_qcn9274 ath12k_dp_rxdma_ring_sel_config_wcn7850 Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-9-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 85 ------------------- drivers/net/wireless/ath/ath12k/dp_rx.h | 3 - drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 85 +++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 2 + drivers/net/wireless/ath/ath12k/wifi7/hw.c | 4 +- 5 files changed, 89 insertions(+), 90 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index c1b489c000e23..942f93a064b93 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -3942,91 +3942,6 @@ void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int mac_id) ath12k_dp_rx_pdev_srng_free(ar); } -int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab) -{ - struct ath12k_dp *dp = &ab->dp; - struct htt_rx_ring_tlv_filter tlv_filter = {}; - u32 ring_id; - int ret; - u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; - - ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; - - tlv_filter.rx_filter = HTT_RX_TLV_FLAGS_RXDMA_RING; - tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR; - tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST | - HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST | - HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA; - tlv_filter.offset_valid = true; - tlv_filter.rx_packet_offset = hal_rx_desc_sz; - - tlv_filter.rx_mpdu_start_offset = - ab->hal_rx_ops->rx_desc_get_mpdu_start_offset(); - tlv_filter.rx_msdu_end_offset = - ab->hal_rx_ops->rx_desc_get_msdu_end_offset(); - - if (ath12k_dp_wmask_compaction_rx_tlv_supported(ab)) { - tlv_filter.rx_mpdu_start_wmask = - ab->hw_params->hal_ops->rxdma_ring_wmask_rx_mpdu_start(); - tlv_filter.rx_msdu_end_wmask = - ab->hw_params->hal_ops->rxdma_ring_wmask_rx_msdu_end(); - ath12k_dbg(ab, ATH12K_DBG_DATA, - "Configuring compact tlv masks rx_mpdu_start_wmask 0x%x rx_msdu_end_wmask 0x%x\n", - tlv_filter.rx_mpdu_start_wmask, tlv_filter.rx_msdu_end_wmask); - } - - ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, 0, - HAL_RXDMA_BUF, - DP_RXDMA_REFILL_RING_SIZE, - &tlv_filter); - - return ret; -} -EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_qcn9274); - -int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) -{ - struct ath12k_dp *dp = &ab->dp; - struct htt_rx_ring_tlv_filter tlv_filter = {}; - u32 ring_id; - int ret = 0; - u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; - int i; - - ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; - - tlv_filter.rx_filter = HTT_RX_TLV_FLAGS_RXDMA_RING; - tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR; - tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST | - HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST | - HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA; - tlv_filter.offset_valid = true; - tlv_filter.rx_packet_offset = hal_rx_desc_sz; - - tlv_filter.rx_header_offset = offsetof(struct hal_rx_desc_wcn7850, pkt_hdr_tlv); - - tlv_filter.rx_mpdu_start_offset = - ab->hal_rx_ops->rx_desc_get_mpdu_start_offset(); - tlv_filter.rx_msdu_end_offset = - ab->hal_rx_ops->rx_desc_get_msdu_end_offset(); - - /* TODO: Selectively subscribe to required qwords within msdu_end - * and mpdu_start and setup the mask in below msg - * and modify the rx_desc struct - */ - - for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { - ring_id = dp->rx_mac_buf_ring[i].ring_id; - ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, i, - HAL_RXDMA_BUF, - DP_RXDMA_REFILL_RING_SIZE, - &tlv_filter); - } - - return ret; -} -EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_wcn7850); - int ath12k_dp_rx_htt_setup(struct ath12k_base *ab) { struct ath12k_dp *dp = &ab->dp; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index f06c102750733..417b18670096e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -416,9 +416,6 @@ u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, struct hal_rx_desc *desc); u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, struct hal_rx_desc *desc); -int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); -int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); - int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len, int (*iter)(struct ath12k_base *ar, u16 tag, u16 len, const void *ptr, void *data), diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 26539a4d4b303..a002e3839fff8 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -348,3 +348,88 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, done: return total_num_buffs_reaped; } + +int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab) +{ + struct ath12k_dp *dp = &ab->dp; + struct htt_rx_ring_tlv_filter tlv_filter = {}; + u32 ring_id; + int ret; + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; + + ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; + + tlv_filter.rx_filter = HTT_RX_TLV_FLAGS_RXDMA_RING; + tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR; + tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST | + HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST | + HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA; + tlv_filter.offset_valid = true; + tlv_filter.rx_packet_offset = hal_rx_desc_sz; + + tlv_filter.rx_mpdu_start_offset = + ab->hal_rx_ops->rx_desc_get_mpdu_start_offset(); + tlv_filter.rx_msdu_end_offset = + ab->hal_rx_ops->rx_desc_get_msdu_end_offset(); + + if (ath12k_dp_wmask_compaction_rx_tlv_supported(ab)) { + tlv_filter.rx_mpdu_start_wmask = + ab->hw_params->hal_ops->rxdma_ring_wmask_rx_mpdu_start(); + tlv_filter.rx_msdu_end_wmask = + ab->hw_params->hal_ops->rxdma_ring_wmask_rx_msdu_end(); + ath12k_dbg(ab, ATH12K_DBG_DATA, + "Configuring compact tlv masks rx_mpdu_start_wmask 0x%x rx_msdu_end_wmask 0x%x\n", + tlv_filter.rx_mpdu_start_wmask, tlv_filter.rx_msdu_end_wmask); + } + + ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, 0, + HAL_RXDMA_BUF, + DP_RXDMA_REFILL_RING_SIZE, + &tlv_filter); + + return ret; +} +EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_qcn9274); + +int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) +{ + struct ath12k_dp *dp = &ab->dp; + struct htt_rx_ring_tlv_filter tlv_filter = {}; + u32 ring_id; + int ret = 0; + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; + int i; + + ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; + + tlv_filter.rx_filter = HTT_RX_TLV_FLAGS_RXDMA_RING; + tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR; + tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST | + HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST | + HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA; + tlv_filter.offset_valid = true; + tlv_filter.rx_packet_offset = hal_rx_desc_sz; + + tlv_filter.rx_header_offset = offsetof(struct hal_rx_desc_wcn7850, pkt_hdr_tlv); + + tlv_filter.rx_mpdu_start_offset = + ab->hal_rx_ops->rx_desc_get_mpdu_start_offset(); + tlv_filter.rx_msdu_end_offset = + ab->hal_rx_ops->rx_desc_get_msdu_end_offset(); + + /* TODO: Selectively subscribe to required qwords within msdu_end + * and mpdu_start and setup the mask in below msg + * and modify the rx_desc struct + */ + + for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { + ring_id = dp->rx_mac_buf_ring[i].ring_id; + ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, i, + HAL_RXDMA_BUF, + DP_RXDMA_REFILL_RING_SIZE, + &tlv_filter); + } + + return ret; +} +EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_wcn7850); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index a6da98962345d..154018c221dad 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -11,4 +11,6 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, struct napi_struct *napi, int budget); +int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); +int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 82b4f5b9f5700..909f7311619cd 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 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. */ #include @@ -16,7 +16,7 @@ #include "hw.h" #include "../mhi.h" #include "mhi.h" -#include "../dp_rx.h" +#include "dp_rx.h" #include "../peer.h" #include "wmi.h" From 13b1e4e312fab05efe4dadfd6515eee5058c2494 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:42 +0530 Subject: [PATCH 022/140] wifi: ath12k: Move rx error and defrag functions to wifi7 directory Move arch specific RX error and defrag functions to wifi7 directory. The moved APIs will be a part of dp_rx.c file inside wifi7 directory. wifi7/dp_rx.c file will continue to be part of ath12k.ko temporarily until the corresponding infra for movement to ath12k_wifi7.ko arrives in upcoming patches. Architecture specific APIs: ath12k_dp_rx_h_defrag_validate_incr_pn ath12k_dp_rx_h_defrag_reo_reinject ath12k_dp_rx_h_defrag ath12k_dp_rx_frag_h_mpdu ath12k_dp_process_rx_err_buf ath12k_dp_rx_process_err ath12k_dp_rx_null_q_desc_sg_drop ath12k_dp_rx_h_null_q_desc Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-10-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 771 +----------------- drivers/net/wireless/ath/ath12k/dp_rx.h | 21 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 682 ++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 2 + 4 files changed, 714 insertions(+), 762 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 942f93a064b93..8abbf609899ad 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -19,8 +19,6 @@ #include "dp_mon.h" #include "debugfs_htt_stats.h" -#define ATH12K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ) - static size_t ath12k_dp_list_cut_nodes(struct list_head *list, struct list_head *head, size_t count) @@ -712,8 +710,8 @@ int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, return ret; } -static void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, - bool rel_link_desc) +void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, + bool rel_link_desc) { struct ath12k_buffer_addr *buf_addr_info; struct ath12k_base *ab = rx_tid->ab; @@ -2199,10 +2197,10 @@ ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu, return peer; } -static void ath12k_dp_rx_h_mpdu(struct ath12k *ar, - struct sk_buff *msdu, - struct hal_rx_desc *rx_desc, - struct ath12k_dp_rx_info *rx_info) +void ath12k_dp_rx_h_mpdu(struct ath12k *ar, + struct sk_buff *msdu, + struct hal_rx_desc *rx_desc, + struct ath12k_dp_rx_info *rx_info) { struct ath12k_base *ab = ar->ab; struct ath12k_skb_rxcb *rxcb; @@ -2947,8 +2945,8 @@ static int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, return ret; } -static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer, - struct sk_buff *msdu) +int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer, + struct sk_buff *msdu) { struct ath12k_base *ab = ar->ab; struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; @@ -3011,8 +3009,8 @@ static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer return -EINVAL; } -static void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu, - enum hal_encrypt_type enctype, u32 flags) +void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu, + enum hal_encrypt_type enctype, u32 flags) { struct ieee80211_hdr *hdr; size_t hdr_len; @@ -3042,222 +3040,6 @@ static void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu, } } -static int ath12k_dp_rx_h_defrag(struct ath12k *ar, - struct ath12k_peer *peer, - struct ath12k_dp_rx_tid *rx_tid, - struct sk_buff **defrag_skb) -{ - struct ath12k_base *ab = ar->ab; - struct hal_rx_desc *rx_desc; - struct sk_buff *skb, *first_frag, *last_frag; - struct ieee80211_hdr *hdr; - enum hal_encrypt_type enctype; - bool is_decrypted = false; - int msdu_len = 0; - int extra_space; - u32 flags, hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; - - first_frag = skb_peek(&rx_tid->rx_frags); - last_frag = skb_peek_tail(&rx_tid->rx_frags); - - skb_queue_walk(&rx_tid->rx_frags, skb) { - flags = 0; - rx_desc = (struct hal_rx_desc *)skb->data; - hdr = (struct ieee80211_hdr *)(skb->data + hal_rx_desc_sz); - - enctype = ath12k_dp_rx_h_enctype(ab, rx_desc); - if (enctype != HAL_ENCRYPT_TYPE_OPEN) - is_decrypted = ath12k_dp_rx_h_is_decrypted(ab, - rx_desc); - - if (is_decrypted) { - if (skb != first_frag) - flags |= RX_FLAG_IV_STRIPPED; - if (skb != last_frag) - flags |= RX_FLAG_ICV_STRIPPED | - RX_FLAG_MIC_STRIPPED; - } - - /* RX fragments are always raw packets */ - if (skb != last_frag) - skb_trim(skb, skb->len - FCS_LEN); - ath12k_dp_rx_h_undecap_frag(ar, skb, enctype, flags); - - if (skb != first_frag) - skb_pull(skb, hal_rx_desc_sz + - ieee80211_hdrlen(hdr->frame_control)); - msdu_len += skb->len; - } - - extra_space = msdu_len - (DP_RX_BUFFER_SIZE + skb_tailroom(first_frag)); - if (extra_space > 0 && - (pskb_expand_head(first_frag, 0, extra_space, GFP_ATOMIC) < 0)) - return -ENOMEM; - - __skb_unlink(first_frag, &rx_tid->rx_frags); - while ((skb = __skb_dequeue(&rx_tid->rx_frags))) { - skb_put_data(first_frag, skb->data, skb->len); - dev_kfree_skb_any(skb); - } - - hdr = (struct ieee80211_hdr *)(first_frag->data + hal_rx_desc_sz); - hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); - ATH12K_SKB_RXCB(first_frag)->is_frag = 1; - - if (ath12k_dp_rx_h_verify_tkip_mic(ar, peer, first_frag)) - first_frag = NULL; - - *defrag_skb = first_frag; - return 0; -} - -static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, - struct ath12k_dp_rx_tid *rx_tid, - struct sk_buff *defrag_skb) -{ - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; - struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)defrag_skb->data; - struct hal_reo_entrance_ring *reo_ent_ring; - struct hal_reo_dest_ring *reo_dest_ring; - struct dp_link_desc_bank *link_desc_banks; - struct hal_rx_msdu_link *msdu_link; - struct hal_rx_msdu_details *msdu0; - struct hal_srng *srng; - dma_addr_t link_paddr, buf_paddr; - u32 desc_bank, msdu_info, msdu_ext_info, mpdu_info; - u32 cookie, hal_rx_desc_sz, dest_ring_info0, queue_addr_hi; - int ret; - struct ath12k_rx_desc_info *desc_info; - enum hal_rx_buf_return_buf_manager idle_link_rbm = dp->idle_link_rbm; - u8 dst_ind; - - hal_rx_desc_sz = ab->hal.hal_desc_sz; - link_desc_banks = dp->link_desc_banks; - reo_dest_ring = rx_tid->dst_ring_desc; - - ath12k_hal_rx_reo_ent_paddr_get(ab, &reo_dest_ring->buf_addr_info, - &link_paddr, &cookie); - desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK); - - msdu_link = (struct hal_rx_msdu_link *)(link_desc_banks[desc_bank].vaddr + - (link_paddr - link_desc_banks[desc_bank].paddr)); - msdu0 = &msdu_link->msdu_link[0]; - msdu_ext_info = le32_to_cpu(msdu0->rx_msdu_ext_info.info0); - dst_ind = u32_get_bits(msdu_ext_info, RX_MSDU_EXT_DESC_INFO0_REO_DEST_IND); - - memset(msdu0, 0, sizeof(*msdu0)); - - msdu_info = u32_encode_bits(1, RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU) | - u32_encode_bits(1, RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU) | - u32_encode_bits(0, RX_MSDU_DESC_INFO0_MSDU_CONTINUATION) | - u32_encode_bits(defrag_skb->len - hal_rx_desc_sz, - RX_MSDU_DESC_INFO0_MSDU_LENGTH) | - u32_encode_bits(1, RX_MSDU_DESC_INFO0_VALID_SA) | - u32_encode_bits(1, RX_MSDU_DESC_INFO0_VALID_DA); - msdu0->rx_msdu_info.info0 = cpu_to_le32(msdu_info); - msdu0->rx_msdu_ext_info.info0 = cpu_to_le32(msdu_ext_info); - - /* change msdu len in hal rx desc */ - ath12k_dp_rxdesc_set_msdu_len(ab, rx_desc, defrag_skb->len - hal_rx_desc_sz); - - buf_paddr = dma_map_single(ab->dev, defrag_skb->data, - defrag_skb->len + skb_tailroom(defrag_skb), - DMA_TO_DEVICE); - if (dma_mapping_error(ab->dev, buf_paddr)) - return -ENOMEM; - - spin_lock_bh(&dp->rx_desc_lock); - desc_info = list_first_entry_or_null(&dp->rx_desc_free_list, - struct ath12k_rx_desc_info, - list); - if (!desc_info) { - spin_unlock_bh(&dp->rx_desc_lock); - ath12k_warn(ab, "failed to find rx desc for reinject\n"); - ret = -ENOMEM; - goto err_unmap_dma; - } - - desc_info->skb = defrag_skb; - desc_info->in_use = true; - - list_del(&desc_info->list); - spin_unlock_bh(&dp->rx_desc_lock); - - ATH12K_SKB_RXCB(defrag_skb)->paddr = buf_paddr; - - ath12k_hal_rx_buf_addr_info_set(&msdu0->buf_addr_info, buf_paddr, - desc_info->cookie, - HAL_RX_BUF_RBM_SW3_BM); - - /* Fill mpdu details into reo entrance ring */ - srng = &ab->hal.srng_list[dp->reo_reinject_ring.ring_id]; - - spin_lock_bh(&srng->lock); - ath12k_hal_srng_access_begin(ab, srng); - - reo_ent_ring = ath12k_hal_srng_src_get_next_entry(ab, srng); - if (!reo_ent_ring) { - ath12k_hal_srng_access_end(ab, srng); - spin_unlock_bh(&srng->lock); - ret = -ENOSPC; - goto err_free_desc; - } - memset(reo_ent_ring, 0, sizeof(*reo_ent_ring)); - - ath12k_hal_rx_buf_addr_info_set(&reo_ent_ring->buf_addr_info, link_paddr, - cookie, - idle_link_rbm); - - mpdu_info = u32_encode_bits(1, RX_MPDU_DESC_INFO0_MSDU_COUNT) | - u32_encode_bits(0, RX_MPDU_DESC_INFO0_FRAG_FLAG) | - u32_encode_bits(1, RX_MPDU_DESC_INFO0_RAW_MPDU) | - u32_encode_bits(1, RX_MPDU_DESC_INFO0_VALID_PN) | - u32_encode_bits(rx_tid->tid, RX_MPDU_DESC_INFO0_TID); - - reo_ent_ring->rx_mpdu_info.info0 = cpu_to_le32(mpdu_info); - reo_ent_ring->rx_mpdu_info.peer_meta_data = - reo_dest_ring->rx_mpdu_info.peer_meta_data; - - if (ab->hw_params->reoq_lut_support) { - reo_ent_ring->queue_addr_lo = reo_dest_ring->rx_mpdu_info.peer_meta_data; - queue_addr_hi = 0; - } else { - reo_ent_ring->queue_addr_lo = - cpu_to_le32(lower_32_bits(rx_tid->qbuf.paddr_aligned)); - queue_addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); - } - - reo_ent_ring->info0 = le32_encode_bits(queue_addr_hi, - HAL_REO_ENTR_RING_INFO0_QUEUE_ADDR_HI) | - le32_encode_bits(dst_ind, - HAL_REO_ENTR_RING_INFO0_DEST_IND); - - reo_ent_ring->info1 = le32_encode_bits(rx_tid->cur_sn, - HAL_REO_ENTR_RING_INFO1_MPDU_SEQ_NUM); - dest_ring_info0 = le32_get_bits(reo_dest_ring->info0, - HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); - reo_ent_ring->info2 = - cpu_to_le32(u32_get_bits(dest_ring_info0, - HAL_REO_ENTR_RING_INFO2_SRC_LINK_ID)); - - ath12k_hal_srng_access_end(ab, srng); - spin_unlock_bh(&srng->lock); - - return 0; - -err_free_desc: - spin_lock_bh(&dp->rx_desc_lock); - desc_info->in_use = false; - desc_info->skb = NULL; - list_add_tail(&desc_info->list, &dp->rx_desc_free_list); - spin_unlock_bh(&dp->rx_desc_lock); -err_unmap_dma: - dma_unmap_single(ab->dev, buf_paddr, defrag_skb->len + skb_tailroom(defrag_skb), - DMA_TO_DEVICE); - return ret; -} - static int ath12k_dp_rx_h_cmp_frags(struct ath12k_base *ab, struct sk_buff *a, struct sk_buff *b) { @@ -3269,9 +3051,9 @@ static int ath12k_dp_rx_h_cmp_frags(struct ath12k_base *ab, return frag1 - frag2; } -static void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, - struct sk_buff_head *frag_list, - struct sk_buff *cur_frag) +void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, + struct sk_buff_head *frag_list, + struct sk_buff *cur_frag) { struct sk_buff *skb; int cmp; @@ -3286,7 +3068,7 @@ static void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, __skb_queue_tail(frag_list, cur_frag); } -static u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb) +u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb) { struct ieee80211_hdr *hdr; u64 pn = 0; @@ -3306,531 +3088,6 @@ static u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb) return pn; } -static bool -ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, struct ath12k_dp_rx_tid *rx_tid) -{ - struct ath12k_base *ab = ar->ab; - enum hal_encrypt_type encrypt_type; - struct sk_buff *first_frag, *skb; - struct hal_rx_desc *desc; - u64 last_pn; - u64 cur_pn; - - first_frag = skb_peek(&rx_tid->rx_frags); - desc = (struct hal_rx_desc *)first_frag->data; - - encrypt_type = ath12k_dp_rx_h_enctype(ab, desc); - if (encrypt_type != HAL_ENCRYPT_TYPE_CCMP_128 && - encrypt_type != HAL_ENCRYPT_TYPE_CCMP_256 && - encrypt_type != HAL_ENCRYPT_TYPE_GCMP_128 && - encrypt_type != HAL_ENCRYPT_TYPE_AES_GCMP_256) - return true; - - last_pn = ath12k_dp_rx_h_get_pn(ar, first_frag); - skb_queue_walk(&rx_tid->rx_frags, skb) { - if (skb == first_frag) - continue; - - cur_pn = ath12k_dp_rx_h_get_pn(ar, skb); - if (cur_pn != last_pn + 1) - return false; - last_pn = cur_pn; - } - return true; -} - -static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, - struct sk_buff *msdu, - struct hal_reo_dest_ring *ring_desc) -{ - struct ath12k_base *ab = ar->ab; - struct hal_rx_desc *rx_desc; - struct ath12k_peer *peer; - struct ath12k_dp_rx_tid *rx_tid; - struct sk_buff *defrag_skb = NULL; - u32 peer_id; - u16 seqno, frag_no; - u8 tid; - int ret = 0; - bool more_frags; - - rx_desc = (struct hal_rx_desc *)msdu->data; - peer_id = ath12k_dp_rx_h_peer_id(ab, rx_desc); - tid = ath12k_dp_rx_h_tid(ab, rx_desc); - seqno = ath12k_dp_rx_h_seq_no(ab, rx_desc); - frag_no = ath12k_dp_rx_h_frag_no(ab, msdu); - more_frags = ath12k_dp_rx_h_more_frags(ab, msdu); - - if (!ath12k_dp_rx_h_seq_ctrl_valid(ab, rx_desc) || - !ath12k_dp_rx_h_fc_valid(ab, rx_desc) || - tid > IEEE80211_NUM_TIDS) - return -EINVAL; - - /* received unfragmented packet in reo - * exception ring, this shouldn't happen - * as these packets typically come from - * reo2sw srngs. - */ - if (WARN_ON_ONCE(!frag_no && !more_frags)) - return -EINVAL; - - spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); - if (!peer) { - ath12k_warn(ab, "failed to find the peer to de-fragment received fragment peer_id %d\n", - peer_id); - ret = -ENOENT; - goto out_unlock; - } - - if (!peer->dp_setup_done) { - ath12k_warn(ab, "The peer %pM [%d] has uninitialized datapath\n", - peer->addr, peer_id); - ret = -ENOENT; - goto out_unlock; - } - - rx_tid = &peer->rx_tid[tid]; - - if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) || - skb_queue_empty(&rx_tid->rx_frags)) { - /* Flush stored fragments and start a new sequence */ - ath12k_dp_rx_frags_cleanup(rx_tid, true); - rx_tid->cur_sn = seqno; - } - - if (rx_tid->rx_frag_bitmap & BIT(frag_no)) { - /* Fragment already present */ - ret = -EINVAL; - goto out_unlock; - } - - if ((!rx_tid->rx_frag_bitmap || frag_no > __fls(rx_tid->rx_frag_bitmap))) - __skb_queue_tail(&rx_tid->rx_frags, msdu); - else - ath12k_dp_rx_h_sort_frags(ab, &rx_tid->rx_frags, msdu); - - rx_tid->rx_frag_bitmap |= BIT(frag_no); - if (!more_frags) - rx_tid->last_frag_no = frag_no; - - if (frag_no == 0) { - rx_tid->dst_ring_desc = kmemdup(ring_desc, - sizeof(*rx_tid->dst_ring_desc), - GFP_ATOMIC); - if (!rx_tid->dst_ring_desc) { - ret = -ENOMEM; - goto out_unlock; - } - } else { - ath12k_dp_rx_link_desc_return(ab, &ring_desc->buf_addr_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); - } - - if (!rx_tid->last_frag_no || - rx_tid->rx_frag_bitmap != GENMASK(rx_tid->last_frag_no, 0)) { - mod_timer(&rx_tid->frag_timer, jiffies + - ATH12K_DP_RX_FRAGMENT_TIMEOUT_MS); - goto out_unlock; - } - - spin_unlock_bh(&ab->base_lock); - timer_delete_sync(&rx_tid->frag_timer); - spin_lock_bh(&ab->base_lock); - - peer = ath12k_peer_find_by_id(ab, peer_id); - if (!peer) - goto err_frags_cleanup; - - if (!ath12k_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid)) - goto err_frags_cleanup; - - if (ath12k_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb)) - goto err_frags_cleanup; - - if (!defrag_skb) - goto err_frags_cleanup; - - if (ath12k_dp_rx_h_defrag_reo_reinject(ar, rx_tid, defrag_skb)) - goto err_frags_cleanup; - - ath12k_dp_rx_frags_cleanup(rx_tid, false); - goto out_unlock; - -err_frags_cleanup: - dev_kfree_skb_any(defrag_skb); - ath12k_dp_rx_frags_cleanup(rx_tid, true); -out_unlock: - spin_unlock_bh(&ab->base_lock); - return ret; -} - -static int -ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc, - struct list_head *used_list, - bool drop, u32 cookie) -{ - struct ath12k_base *ab = ar->ab; - struct sk_buff *msdu; - struct ath12k_skb_rxcb *rxcb; - struct hal_rx_desc *rx_desc; - u16 msdu_len; - u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; - struct ath12k_rx_desc_info *desc_info; - u64 desc_va; - - desc_va = ((u64)le32_to_cpu(desc->buf_va_hi) << 32 | - le32_to_cpu(desc->buf_va_lo)); - desc_info = (struct ath12k_rx_desc_info *)((unsigned long)desc_va); - - /* retry manual desc retrieval */ - if (!desc_info) { - desc_info = ath12k_dp_get_rx_desc(ab, cookie); - if (!desc_info) { - ath12k_warn(ab, "Invalid cookie in DP rx error descriptor retrieval: 0x%x\n", - cookie); - return -EINVAL; - } - } - - if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) - ath12k_warn(ab, " RX Exception, Check HW CC implementation"); - - msdu = desc_info->skb; - desc_info->skb = NULL; - - list_add_tail(&desc_info->list, used_list); - - rxcb = ATH12K_SKB_RXCB(msdu); - dma_unmap_single(ar->ab->dev, rxcb->paddr, - msdu->len + skb_tailroom(msdu), - DMA_FROM_DEVICE); - - if (drop) { - dev_kfree_skb_any(msdu); - return 0; - } - - rcu_read_lock(); - if (!rcu_dereference(ar->ab->pdevs_active[ar->pdev_idx])) { - dev_kfree_skb_any(msdu); - goto exit; - } - - if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) { - dev_kfree_skb_any(msdu); - goto exit; - } - - rx_desc = (struct hal_rx_desc *)msdu->data; - msdu_len = ath12k_dp_rx_h_msdu_len(ar->ab, rx_desc); - if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { - ath12k_warn(ar->ab, "invalid msdu leng %u", msdu_len); - ath12k_dbg_dump(ar->ab, ATH12K_DBG_DATA, NULL, "", rx_desc, - sizeof(*rx_desc)); - dev_kfree_skb_any(msdu); - goto exit; - } - - skb_put(msdu, hal_rx_desc_sz + msdu_len); - - if (ath12k_dp_rx_frag_h_mpdu(ar, msdu, desc)) { - dev_kfree_skb_any(msdu); - ath12k_dp_rx_link_desc_return(ar->ab, &desc->buf_addr_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); - } -exit: - rcu_read_unlock(); - return 0; -} - -static int ath12k_dp_h_msdu_buffer_type(struct ath12k_base *ab, - struct list_head *list, - struct hal_reo_dest_ring *desc) -{ - struct ath12k_rx_desc_info *desc_info; - struct ath12k_skb_rxcb *rxcb; - struct sk_buff *msdu; - u64 desc_va; - - ab->device_stats.reo_excep_msdu_buf_type++; - - desc_va = (u64)le32_to_cpu(desc->buf_va_hi) << 32 | - le32_to_cpu(desc->buf_va_lo); - desc_info = (struct ath12k_rx_desc_info *)(uintptr_t)desc_va; - if (!desc_info) { - u32 cookie; - - cookie = le32_get_bits(desc->buf_addr_info.info1, - BUFFER_ADDR_INFO1_SW_COOKIE); - desc_info = ath12k_dp_get_rx_desc(ab, cookie); - if (!desc_info) { - ath12k_warn(ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n", - cookie); - return -EINVAL; - } - } - - if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) { - ath12k_warn(ab, "rx exception, magic check failed with value: %u\n", - desc_info->magic); - return -EINVAL; - } - - msdu = desc_info->skb; - desc_info->skb = NULL; - list_add_tail(&desc_info->list, list); - rxcb = ATH12K_SKB_RXCB(msdu); - dma_unmap_single(ab->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), - DMA_FROM_DEVICE); - dev_kfree_skb_any(msdu); - - return 0; -} - -int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, - int budget) -{ - struct ath12k_hw_group *ag = ab->ag; - struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; - u32 msdu_cookies[HAL_NUM_RX_MSDUS_PER_LINK_DESC]; - int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; - struct dp_link_desc_bank *link_desc_banks; - enum hal_rx_buf_return_buf_manager rbm; - struct hal_rx_msdu_link *link_desc_va; - int tot_n_bufs_reaped, quota, ret, i; - struct hal_reo_dest_ring *reo_desc; - struct dp_rxdma_ring *rx_ring; - struct dp_srng *reo_except; - struct ath12k_hw_link *hw_links = ag->hw_links; - struct ath12k_base *partner_ab; - u8 hw_link_id, device_id; - u32 desc_bank, num_msdus; - struct hal_srng *srng; - struct ath12k *ar; - dma_addr_t paddr; - bool is_frag; - bool drop; - int pdev_id; - - tot_n_bufs_reaped = 0; - quota = budget; - - for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) - INIT_LIST_HEAD(&rx_desc_used_list[device_id]); - - reo_except = &ab->dp.reo_except_ring; - - srng = &ab->hal.srng_list[reo_except->ring_id]; - - spin_lock_bh(&srng->lock); - - ath12k_hal_srng_access_begin(ab, srng); - - while (budget && - (reo_desc = ath12k_hal_srng_dst_get_next_entry(ab, srng))) { - drop = false; - ab->device_stats.err_ring_pkts++; - - hw_link_id = le32_get_bits(reo_desc->info0, - HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); - device_id = hw_links[hw_link_id].device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - - /* Below case is added to handle data packet from un-associated clients. - * As it is expected that AST lookup will fail for - * un-associated station's data packets. - */ - if (le32_get_bits(reo_desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE) == - HAL_REO_DEST_RING_BUFFER_TYPE_MSDU) { - if (!ath12k_dp_h_msdu_buffer_type(partner_ab, - &rx_desc_used_list[device_id], - reo_desc)) { - num_buffs_reaped[device_id]++; - tot_n_bufs_reaped++; - } - goto next_desc; - } - - ret = ath12k_hal_desc_reo_parse_err(ab, reo_desc, &paddr, - &desc_bank); - if (ret) { - ath12k_warn(ab, "failed to parse error reo desc %d\n", - ret); - continue; - } - - pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, - hw_links[hw_link_id].pdev_idx); - ar = partner_ab->pdevs[pdev_id].ar; - - link_desc_banks = partner_ab->dp.link_desc_banks; - link_desc_va = link_desc_banks[desc_bank].vaddr + - (paddr - link_desc_banks[desc_bank].paddr); - ath12k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies, - &rbm); - if (rbm != partner_ab->dp.idle_link_rbm && - rbm != HAL_RX_BUF_RBM_SW3_BM && - rbm != partner_ab->hw_params->hal_params->rx_buf_rbm) { - ab->device_stats.invalid_rbm++; - ath12k_warn(ab, "invalid return buffer manager %d\n", rbm); - ath12k_dp_rx_link_desc_return(partner_ab, - &reo_desc->buf_addr_info, - HAL_WBM_REL_BM_ACT_REL_MSDU); - continue; - } - - is_frag = !!(le32_to_cpu(reo_desc->rx_mpdu_info.info0) & - RX_MPDU_DESC_INFO0_FRAG_FLAG); - - /* Process only rx fragments with one msdu per link desc below, and drop - * msdu's indicated due to error reasons. - * Dynamic fragmentation not supported in Multi-link client, so drop the - * partner device buffers. - */ - if (!is_frag || num_msdus > 1 || - partner_ab->device_id != ab->device_id) { - drop = true; - - /* Return the link desc back to wbm idle list */ - ath12k_dp_rx_link_desc_return(partner_ab, - &reo_desc->buf_addr_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); - } - - for (i = 0; i < num_msdus; i++) { - if (!ath12k_dp_process_rx_err_buf(ar, reo_desc, - &rx_desc_used_list[device_id], - drop, - msdu_cookies[i])) { - num_buffs_reaped[device_id]++; - tot_n_bufs_reaped++; - } - } - -next_desc: - if (tot_n_bufs_reaped >= quota) { - tot_n_bufs_reaped = quota; - goto exit; - } - - budget = quota - tot_n_bufs_reaped; - } - -exit: - ath12k_hal_srng_access_end(ab, srng); - - spin_unlock_bh(&srng->lock); - - for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) { - if (!num_buffs_reaped[device_id]) - continue; - - partner_ab = ath12k_ag_to_ab(ag, device_id); - rx_ring = &partner_ab->dp.rx_refill_buf_ring; - - ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, - &rx_desc_used_list[device_id], - num_buffs_reaped[device_id]); - } - - return tot_n_bufs_reaped; -} - -static void ath12k_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, - int msdu_len, - struct sk_buff_head *msdu_list) -{ - struct sk_buff *skb, *tmp; - struct ath12k_skb_rxcb *rxcb; - int n_buffs; - - n_buffs = DIV_ROUND_UP(msdu_len, - (DP_RX_BUFFER_SIZE - ar->ab->hal.hal_desc_sz)); - - skb_queue_walk_safe(msdu_list, skb, tmp) { - rxcb = ATH12K_SKB_RXCB(skb); - if (rxcb->err_rel_src == HAL_WBM_REL_SRC_MODULE_REO && - rxcb->err_code == HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO) { - if (!n_buffs) - break; - __skb_unlink(skb, msdu_list); - dev_kfree_skb_any(skb); - n_buffs--; - } - } -} - -int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info, - struct sk_buff_head *msdu_list) -{ - struct ath12k_base *ab = ar->ab; - u16 msdu_len; - struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; - u8 l3pad_bytes; - struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; - - msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc); - - if (!rxcb->is_frag && ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE)) { - /* First buffer will be freed by the caller, so deduct it's length */ - msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - hal_rx_desc_sz); - ath12k_dp_rx_null_q_desc_sg_drop(ar, msdu_len, msdu_list); - return -EINVAL; - } - - /* Even after cleaning up the sg buffers in the msdu list with above check - * any msdu received with continuation flag needs to be dropped as invalid. - * This protects against some random err frame with continuation flag. - */ - if (rxcb->is_continuation) - return -EINVAL; - - if (!ath12k_dp_rx_h_msdu_done(ab, desc)) { - ath12k_warn(ar->ab, - "msdu_done bit not set in null_q_des processing\n"); - __skb_queue_purge(msdu_list); - return -EIO; - } - - /* Handle NULL queue descriptor violations arising out a missing - * REO queue for a given peer or a given TID. This typically - * may happen if a packet is received on a QOS enabled TID before the - * ADDBA negotiation for that TID, when the TID queue is setup. Or - * it may also happen for MC/BC frames if they are not routed to the - * non-QOS TID queue, in the absence of any other default TID queue. - * This error can show up both in a REO destination or WBM release ring. - */ - - if (rxcb->is_frag) { - skb_pull(msdu, hal_rx_desc_sz); - } else { - l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc); - - if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) - return -EINVAL; - - skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); - skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); - } - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu))) - return -EINVAL; - - ath12k_dp_rx_h_fetch_info(ab, desc, rx_info); - ath12k_dp_rx_h_ppdu(ar, rx_info); - ath12k_dp_rx_h_mpdu(ar, msdu, desc, rx_info); - - rxcb->tid = rx_info->tid; - - /* Please note that caller will having the access to msdu and completing - * rx with mac80211. Need not worry about cleaning up amsdu_list. - */ - - return 0; -} - void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab) { struct ath12k_dp *dp = &ab->dp; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 417b18670096e..8249eed39a9b7 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -59,6 +59,8 @@ struct ath12k_dp_rx_reo_cmd { enum hal_reo_cmd_status status); }; +#define ATH12K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ) + #define ATH12K_DP_RX_REO_DESC_FREE_THRES 64 #define ATH12K_DP_RX_REO_DESC_FREE_TIMEOUT_MS 1000 @@ -365,9 +367,20 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, struct sk_buff *msdu); -int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info, - struct sk_buff_head *msdu_list); +void ath12k_dp_rx_h_mpdu(struct ath12k *ar, + struct sk_buff *msdu, + struct hal_rx_desc *rx_desc, + struct ath12k_dp_rx_info *rx_info); +u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb); +void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, + struct sk_buff_head *frag_list, + struct sk_buff *cur_frag); +void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu, + enum hal_encrypt_type enctype, u32 flags); +int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer, + struct sk_buff *msdu); +void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, + bool rel_link_desc); int ath12k_dp_rx_ampdu_start(struct ath12k *ar, struct ieee80211_ampdu_params *params, u8 link_id); @@ -395,8 +408,6 @@ int ath12k_dp_rx_pdev_alloc(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab); void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab); -int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, - int budget); int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id, struct napi_struct *napi, int budget); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index a002e3839fff8..c2b108a1005bd 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -6,6 +6,688 @@ #include "dp_rx.h" #include "../dp_tx.h" +#include "../peer.h" + +static bool +ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, struct ath12k_dp_rx_tid *rx_tid) +{ + struct ath12k_base *ab = ar->ab; + enum hal_encrypt_type encrypt_type; + struct sk_buff *first_frag, *skb; + struct hal_rx_desc *desc; + u64 last_pn; + u64 cur_pn; + + first_frag = skb_peek(&rx_tid->rx_frags); + desc = (struct hal_rx_desc *)first_frag->data; + + encrypt_type = ath12k_dp_rx_h_enctype(ab, desc); + if (encrypt_type != HAL_ENCRYPT_TYPE_CCMP_128 && + encrypt_type != HAL_ENCRYPT_TYPE_CCMP_256 && + encrypt_type != HAL_ENCRYPT_TYPE_GCMP_128 && + encrypt_type != HAL_ENCRYPT_TYPE_AES_GCMP_256) + return true; + + last_pn = ath12k_dp_rx_h_get_pn(ar, first_frag); + skb_queue_walk(&rx_tid->rx_frags, skb) { + if (skb == first_frag) + continue; + + cur_pn = ath12k_dp_rx_h_get_pn(ar, skb); + if (cur_pn != last_pn + 1) + return false; + last_pn = cur_pn; + } + return true; +} + +static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, + struct ath12k_dp_rx_tid *rx_tid, + struct sk_buff *defrag_skb) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = &ab->dp; + struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)defrag_skb->data; + struct hal_reo_entrance_ring *reo_ent_ring; + struct hal_reo_dest_ring *reo_dest_ring; + struct dp_link_desc_bank *link_desc_banks; + struct hal_rx_msdu_link *msdu_link; + struct hal_rx_msdu_details *msdu0; + struct hal_srng *srng; + dma_addr_t link_paddr, buf_paddr; + u32 desc_bank, msdu_info, msdu_ext_info, mpdu_info; + u32 cookie, hal_rx_desc_sz, dest_ring_info0, queue_addr_hi; + int ret; + struct ath12k_rx_desc_info *desc_info; + enum hal_rx_buf_return_buf_manager idle_link_rbm = dp->idle_link_rbm; + u8 dst_ind; + + hal_rx_desc_sz = ab->hal.hal_desc_sz; + link_desc_banks = dp->link_desc_banks; + reo_dest_ring = rx_tid->dst_ring_desc; + + ath12k_hal_rx_reo_ent_paddr_get(ab, &reo_dest_ring->buf_addr_info, + &link_paddr, &cookie); + desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK); + + msdu_link = (struct hal_rx_msdu_link *)(link_desc_banks[desc_bank].vaddr + + (link_paddr - link_desc_banks[desc_bank].paddr)); + msdu0 = &msdu_link->msdu_link[0]; + msdu_ext_info = le32_to_cpu(msdu0->rx_msdu_ext_info.info0); + dst_ind = u32_get_bits(msdu_ext_info, RX_MSDU_EXT_DESC_INFO0_REO_DEST_IND); + + memset(msdu0, 0, sizeof(*msdu0)); + + msdu_info = u32_encode_bits(1, RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU) | + u32_encode_bits(1, RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU) | + u32_encode_bits(0, RX_MSDU_DESC_INFO0_MSDU_CONTINUATION) | + u32_encode_bits(defrag_skb->len - hal_rx_desc_sz, + RX_MSDU_DESC_INFO0_MSDU_LENGTH) | + u32_encode_bits(1, RX_MSDU_DESC_INFO0_VALID_SA) | + u32_encode_bits(1, RX_MSDU_DESC_INFO0_VALID_DA); + msdu0->rx_msdu_info.info0 = cpu_to_le32(msdu_info); + msdu0->rx_msdu_ext_info.info0 = cpu_to_le32(msdu_ext_info); + + /* change msdu len in hal rx desc */ + ath12k_dp_rxdesc_set_msdu_len(ab, rx_desc, defrag_skb->len - hal_rx_desc_sz); + + buf_paddr = dma_map_single(ab->dev, defrag_skb->data, + defrag_skb->len + skb_tailroom(defrag_skb), + DMA_TO_DEVICE); + if (dma_mapping_error(ab->dev, buf_paddr)) + return -ENOMEM; + + spin_lock_bh(&dp->rx_desc_lock); + desc_info = list_first_entry_or_null(&dp->rx_desc_free_list, + struct ath12k_rx_desc_info, + list); + if (!desc_info) { + spin_unlock_bh(&dp->rx_desc_lock); + ath12k_warn(ab, "failed to find rx desc for reinject\n"); + ret = -ENOMEM; + goto err_unmap_dma; + } + + desc_info->skb = defrag_skb; + desc_info->in_use = true; + + list_del(&desc_info->list); + spin_unlock_bh(&dp->rx_desc_lock); + + ATH12K_SKB_RXCB(defrag_skb)->paddr = buf_paddr; + + ath12k_hal_rx_buf_addr_info_set(&msdu0->buf_addr_info, buf_paddr, + desc_info->cookie, + HAL_RX_BUF_RBM_SW3_BM); + + /* Fill mpdu details into reo entrance ring */ + srng = &ab->hal.srng_list[dp->reo_reinject_ring.ring_id]; + + spin_lock_bh(&srng->lock); + ath12k_hal_srng_access_begin(ab, srng); + + reo_ent_ring = ath12k_hal_srng_src_get_next_entry(ab, srng); + if (!reo_ent_ring) { + ath12k_hal_srng_access_end(ab, srng); + spin_unlock_bh(&srng->lock); + ret = -ENOSPC; + goto err_free_desc; + } + memset(reo_ent_ring, 0, sizeof(*reo_ent_ring)); + + ath12k_hal_rx_buf_addr_info_set(&reo_ent_ring->buf_addr_info, link_paddr, + cookie, + idle_link_rbm); + + mpdu_info = u32_encode_bits(1, RX_MPDU_DESC_INFO0_MSDU_COUNT) | + u32_encode_bits(0, RX_MPDU_DESC_INFO0_FRAG_FLAG) | + u32_encode_bits(1, RX_MPDU_DESC_INFO0_RAW_MPDU) | + u32_encode_bits(1, RX_MPDU_DESC_INFO0_VALID_PN) | + u32_encode_bits(rx_tid->tid, RX_MPDU_DESC_INFO0_TID); + + reo_ent_ring->rx_mpdu_info.info0 = cpu_to_le32(mpdu_info); + reo_ent_ring->rx_mpdu_info.peer_meta_data = + reo_dest_ring->rx_mpdu_info.peer_meta_data; + + if (ab->hw_params->reoq_lut_support) { + reo_ent_ring->queue_addr_lo = reo_dest_ring->rx_mpdu_info.peer_meta_data; + queue_addr_hi = 0; + } else { + reo_ent_ring->queue_addr_lo = + cpu_to_le32(lower_32_bits(rx_tid->qbuf.paddr_aligned)); + queue_addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); + } + + reo_ent_ring->info0 = le32_encode_bits(queue_addr_hi, + HAL_REO_ENTR_RING_INFO0_QUEUE_ADDR_HI) | + le32_encode_bits(dst_ind, + HAL_REO_ENTR_RING_INFO0_DEST_IND); + + reo_ent_ring->info1 = le32_encode_bits(rx_tid->cur_sn, + HAL_REO_ENTR_RING_INFO1_MPDU_SEQ_NUM); + dest_ring_info0 = le32_get_bits(reo_dest_ring->info0, + HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); + reo_ent_ring->info2 = + cpu_to_le32(u32_get_bits(dest_ring_info0, + HAL_REO_ENTR_RING_INFO2_SRC_LINK_ID)); + + ath12k_hal_srng_access_end(ab, srng); + spin_unlock_bh(&srng->lock); + + return 0; + +err_free_desc: + spin_lock_bh(&dp->rx_desc_lock); + desc_info->in_use = false; + desc_info->skb = NULL; + list_add_tail(&desc_info->list, &dp->rx_desc_free_list); + spin_unlock_bh(&dp->rx_desc_lock); +err_unmap_dma: + dma_unmap_single(ab->dev, buf_paddr, defrag_skb->len + skb_tailroom(defrag_skb), + DMA_TO_DEVICE); + return ret; +} + +static int ath12k_dp_rx_h_defrag(struct ath12k *ar, + struct ath12k_peer *peer, + struct ath12k_dp_rx_tid *rx_tid, + struct sk_buff **defrag_skb) +{ + struct ath12k_base *ab = ar->ab; + struct hal_rx_desc *rx_desc; + struct sk_buff *skb, *first_frag, *last_frag; + struct ieee80211_hdr *hdr; + enum hal_encrypt_type enctype; + bool is_decrypted = false; + int msdu_len = 0; + int extra_space; + u32 flags, hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + + first_frag = skb_peek(&rx_tid->rx_frags); + last_frag = skb_peek_tail(&rx_tid->rx_frags); + + skb_queue_walk(&rx_tid->rx_frags, skb) { + flags = 0; + rx_desc = (struct hal_rx_desc *)skb->data; + hdr = (struct ieee80211_hdr *)(skb->data + hal_rx_desc_sz); + + enctype = ath12k_dp_rx_h_enctype(ab, rx_desc); + if (enctype != HAL_ENCRYPT_TYPE_OPEN) + is_decrypted = ath12k_dp_rx_h_is_decrypted(ab, + rx_desc); + + if (is_decrypted) { + if (skb != first_frag) + flags |= RX_FLAG_IV_STRIPPED; + if (skb != last_frag) + flags |= RX_FLAG_ICV_STRIPPED | + RX_FLAG_MIC_STRIPPED; + } + + /* RX fragments are always raw packets */ + if (skb != last_frag) + skb_trim(skb, skb->len - FCS_LEN); + ath12k_dp_rx_h_undecap_frag(ar, skb, enctype, flags); + + if (skb != first_frag) + skb_pull(skb, hal_rx_desc_sz + + ieee80211_hdrlen(hdr->frame_control)); + msdu_len += skb->len; + } + + extra_space = msdu_len - (DP_RX_BUFFER_SIZE + skb_tailroom(first_frag)); + if (extra_space > 0 && + (pskb_expand_head(first_frag, 0, extra_space, GFP_ATOMIC) < 0)) + return -ENOMEM; + + __skb_unlink(first_frag, &rx_tid->rx_frags); + while ((skb = __skb_dequeue(&rx_tid->rx_frags))) { + skb_put_data(first_frag, skb->data, skb->len); + dev_kfree_skb_any(skb); + } + + hdr = (struct ieee80211_hdr *)(first_frag->data + hal_rx_desc_sz); + hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); + ATH12K_SKB_RXCB(first_frag)->is_frag = 1; + + if (ath12k_dp_rx_h_verify_tkip_mic(ar, peer, first_frag)) + first_frag = NULL; + + *defrag_skb = first_frag; + return 0; +} + +static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, + struct sk_buff *msdu, + struct hal_reo_dest_ring *ring_desc) +{ + struct ath12k_base *ab = ar->ab; + struct hal_rx_desc *rx_desc; + struct ath12k_peer *peer; + struct ath12k_dp_rx_tid *rx_tid; + struct sk_buff *defrag_skb = NULL; + u32 peer_id; + u16 seqno, frag_no; + u8 tid; + int ret = 0; + bool more_frags; + + rx_desc = (struct hal_rx_desc *)msdu->data; + peer_id = ath12k_dp_rx_h_peer_id(ab, rx_desc); + tid = ath12k_dp_rx_h_tid(ab, rx_desc); + seqno = ath12k_dp_rx_h_seq_no(ab, rx_desc); + frag_no = ath12k_dp_rx_h_frag_no(ab, msdu); + more_frags = ath12k_dp_rx_h_more_frags(ab, msdu); + + if (!ath12k_dp_rx_h_seq_ctrl_valid(ab, rx_desc) || + !ath12k_dp_rx_h_fc_valid(ab, rx_desc) || + tid > IEEE80211_NUM_TIDS) + return -EINVAL; + + /* received unfragmented packet in reo + * exception ring, this shouldn't happen + * as these packets typically come from + * reo2sw srngs. + */ + if (WARN_ON_ONCE(!frag_no && !more_frags)) + return -EINVAL; + + spin_lock_bh(&ab->base_lock); + peer = ath12k_peer_find_by_id(ab, peer_id); + if (!peer) { + ath12k_warn(ab, "failed to find the peer to de-fragment received fragment peer_id %d\n", + peer_id); + ret = -ENOENT; + goto out_unlock; + } + + if (!peer->dp_setup_done) { + ath12k_warn(ab, "The peer %pM [%d] has uninitialized datapath\n", + peer->addr, peer_id); + ret = -ENOENT; + goto out_unlock; + } + + rx_tid = &peer->rx_tid[tid]; + + if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) || + skb_queue_empty(&rx_tid->rx_frags)) { + /* Flush stored fragments and start a new sequence */ + ath12k_dp_rx_frags_cleanup(rx_tid, true); + rx_tid->cur_sn = seqno; + } + + if (rx_tid->rx_frag_bitmap & BIT(frag_no)) { + /* Fragment already present */ + ret = -EINVAL; + goto out_unlock; + } + + if ((!rx_tid->rx_frag_bitmap || frag_no > __fls(rx_tid->rx_frag_bitmap))) + __skb_queue_tail(&rx_tid->rx_frags, msdu); + else + ath12k_dp_rx_h_sort_frags(ab, &rx_tid->rx_frags, msdu); + + rx_tid->rx_frag_bitmap |= BIT(frag_no); + if (!more_frags) + rx_tid->last_frag_no = frag_no; + + if (frag_no == 0) { + rx_tid->dst_ring_desc = kmemdup(ring_desc, + sizeof(*rx_tid->dst_ring_desc), + GFP_ATOMIC); + if (!rx_tid->dst_ring_desc) { + ret = -ENOMEM; + goto out_unlock; + } + } else { + ath12k_dp_rx_link_desc_return(ab, &ring_desc->buf_addr_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + } + + if (!rx_tid->last_frag_no || + rx_tid->rx_frag_bitmap != GENMASK(rx_tid->last_frag_no, 0)) { + mod_timer(&rx_tid->frag_timer, jiffies + + ATH12K_DP_RX_FRAGMENT_TIMEOUT_MS); + goto out_unlock; + } + + spin_unlock_bh(&ab->base_lock); + timer_delete_sync(&rx_tid->frag_timer); + spin_lock_bh(&ab->base_lock); + + peer = ath12k_peer_find_by_id(ab, peer_id); + if (!peer) + goto err_frags_cleanup; + + if (!ath12k_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid)) + goto err_frags_cleanup; + + if (ath12k_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb)) + goto err_frags_cleanup; + + if (!defrag_skb) + goto err_frags_cleanup; + + if (ath12k_dp_rx_h_defrag_reo_reinject(ar, rx_tid, defrag_skb)) + goto err_frags_cleanup; + + ath12k_dp_rx_frags_cleanup(rx_tid, false); + goto out_unlock; + +err_frags_cleanup: + dev_kfree_skb_any(defrag_skb); + ath12k_dp_rx_frags_cleanup(rx_tid, true); +out_unlock: + spin_unlock_bh(&ab->base_lock); + return ret; +} + +static int +ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc, + struct list_head *used_list, + bool drop, u32 cookie) +{ + struct ath12k_base *ab = ar->ab; + struct sk_buff *msdu; + struct ath12k_skb_rxcb *rxcb; + struct hal_rx_desc *rx_desc; + u16 msdu_len; + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; + struct ath12k_rx_desc_info *desc_info; + u64 desc_va; + + desc_va = ((u64)le32_to_cpu(desc->buf_va_hi) << 32 | + le32_to_cpu(desc->buf_va_lo)); + desc_info = (struct ath12k_rx_desc_info *)((unsigned long)desc_va); + + /* retry manual desc retrieval */ + if (!desc_info) { + desc_info = ath12k_dp_get_rx_desc(ab, cookie); + if (!desc_info) { + ath12k_warn(ab, "Invalid cookie in DP rx error descriptor retrieval: 0x%x\n", + cookie); + return -EINVAL; + } + } + + if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) + ath12k_warn(ab, " RX Exception, Check HW CC implementation"); + + msdu = desc_info->skb; + desc_info->skb = NULL; + + list_add_tail(&desc_info->list, used_list); + + rxcb = ATH12K_SKB_RXCB(msdu); + dma_unmap_single(ar->ab->dev, rxcb->paddr, + msdu->len + skb_tailroom(msdu), + DMA_FROM_DEVICE); + + if (drop) { + dev_kfree_skb_any(msdu); + return 0; + } + + rcu_read_lock(); + if (!rcu_dereference(ar->ab->pdevs_active[ar->pdev_idx])) { + dev_kfree_skb_any(msdu); + goto exit; + } + + if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) { + dev_kfree_skb_any(msdu); + goto exit; + } + + rx_desc = (struct hal_rx_desc *)msdu->data; + msdu_len = ath12k_dp_rx_h_msdu_len(ar->ab, rx_desc); + if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { + ath12k_warn(ar->ab, "invalid msdu leng %u", msdu_len); + ath12k_dbg_dump(ar->ab, ATH12K_DBG_DATA, NULL, "", rx_desc, + sizeof(*rx_desc)); + dev_kfree_skb_any(msdu); + goto exit; + } + + skb_put(msdu, hal_rx_desc_sz + msdu_len); + + if (ath12k_dp_rx_frag_h_mpdu(ar, msdu, desc)) { + dev_kfree_skb_any(msdu); + ath12k_dp_rx_link_desc_return(ar->ab, &desc->buf_addr_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + } +exit: + rcu_read_unlock(); + return 0; +} + +int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, + int budget) +{ + struct ath12k_hw_group *ag = ab->ag; + struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; + u32 msdu_cookies[HAL_NUM_RX_MSDUS_PER_LINK_DESC]; + int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; + struct dp_link_desc_bank *link_desc_banks; + enum hal_rx_buf_return_buf_manager rbm; + struct hal_rx_msdu_link *link_desc_va; + int tot_n_bufs_reaped, quota, ret, i; + struct hal_reo_dest_ring *reo_desc; + struct dp_rxdma_ring *rx_ring; + struct dp_srng *reo_except; + struct ath12k_hw_link *hw_links = ag->hw_links; + struct ath12k_base *partner_ab; + u8 hw_link_id, device_id; + u32 desc_bank, num_msdus; + struct hal_srng *srng; + struct ath12k *ar; + dma_addr_t paddr; + bool is_frag; + bool drop; + int pdev_id; + + tot_n_bufs_reaped = 0; + quota = budget; + + for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) + INIT_LIST_HEAD(&rx_desc_used_list[device_id]); + + reo_except = &ab->dp.reo_except_ring; + + srng = &ab->hal.srng_list[reo_except->ring_id]; + + spin_lock_bh(&srng->lock); + + ath12k_hal_srng_access_begin(ab, srng); + + while (budget && + (reo_desc = ath12k_hal_srng_dst_get_next_entry(ab, srng))) { + drop = false; + ab->device_stats.err_ring_pkts++; + + ret = ath12k_hal_desc_reo_parse_err(ab, reo_desc, &paddr, + &desc_bank); + if (ret) { + ath12k_warn(ab, "failed to parse error reo desc %d\n", + ret); + continue; + } + + hw_link_id = le32_get_bits(reo_desc->info0, + HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); + device_id = hw_links[hw_link_id].device_id; + partner_ab = ath12k_ag_to_ab(ag, device_id); + + pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + hw_links[hw_link_id].pdev_idx); + ar = partner_ab->pdevs[pdev_id].ar; + + link_desc_banks = partner_ab->dp.link_desc_banks; + link_desc_va = link_desc_banks[desc_bank].vaddr + + (paddr - link_desc_banks[desc_bank].paddr); + ath12k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies, + &rbm); + if (rbm != partner_ab->dp.idle_link_rbm && + rbm != HAL_RX_BUF_RBM_SW3_BM && + rbm != partner_ab->hw_params->hal_params->rx_buf_rbm) { + ab->device_stats.invalid_rbm++; + ath12k_warn(ab, "invalid return buffer manager %d\n", rbm); + ath12k_dp_rx_link_desc_return(partner_ab, + &reo_desc->buf_addr_info, + HAL_WBM_REL_BM_ACT_REL_MSDU); + continue; + } + + is_frag = !!(le32_to_cpu(reo_desc->rx_mpdu_info.info0) & + RX_MPDU_DESC_INFO0_FRAG_FLAG); + + /* Process only rx fragments with one msdu per link desc below, and drop + * msdu's indicated due to error reasons. + * Dynamic fragmentation not supported in Multi-link client, so drop the + * partner device buffers. + */ + if (!is_frag || num_msdus > 1 || + partner_ab->device_id != ab->device_id) { + drop = true; + + /* Return the link desc back to wbm idle list */ + ath12k_dp_rx_link_desc_return(partner_ab, + &reo_desc->buf_addr_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + } + + for (i = 0; i < num_msdus; i++) { + if (!ath12k_dp_process_rx_err_buf(ar, reo_desc, + &rx_desc_used_list[device_id], + drop, + msdu_cookies[i])) { + num_buffs_reaped[device_id]++; + tot_n_bufs_reaped++; + } + } + + if (tot_n_bufs_reaped >= quota) { + tot_n_bufs_reaped = quota; + goto exit; + } + + budget = quota - tot_n_bufs_reaped; + } + +exit: + ath12k_hal_srng_access_end(ab, srng); + + spin_unlock_bh(&srng->lock); + + for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) { + if (!num_buffs_reaped[device_id]) + continue; + + partner_ab = ath12k_ag_to_ab(ag, device_id); + rx_ring = &partner_ab->dp.rx_refill_buf_ring; + + ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, + &rx_desc_used_list[device_id], + num_buffs_reaped[device_id]); + } + + return tot_n_bufs_reaped; +} + +static void ath12k_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, + int msdu_len, + struct sk_buff_head *msdu_list) +{ + struct sk_buff *skb, *tmp; + struct ath12k_skb_rxcb *rxcb; + int n_buffs; + + n_buffs = DIV_ROUND_UP(msdu_len, + (DP_RX_BUFFER_SIZE - ar->ab->hal.hal_desc_sz)); + + skb_queue_walk_safe(msdu_list, skb, tmp) { + rxcb = ATH12K_SKB_RXCB(skb); + if (rxcb->err_rel_src == HAL_WBM_REL_SRC_MODULE_REO && + rxcb->err_code == HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO) { + if (!n_buffs) + break; + __skb_unlink(skb, msdu_list); + dev_kfree_skb_any(skb); + n_buffs--; + } + } +} + +static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info, + struct sk_buff_head *msdu_list) +{ + struct ath12k_base *ab = ar->ab; + u16 msdu_len; + struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; + u8 l3pad_bytes; + struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); + u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + + msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc); + + if (!rxcb->is_frag && ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE)) { + /* First buffer will be freed by the caller, so deduct it's length */ + msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - hal_rx_desc_sz); + ath12k_dp_rx_null_q_desc_sg_drop(ar, msdu_len, msdu_list); + return -EINVAL; + } + + /* Even after cleaning up the sg buffers in the msdu list with above check + * any msdu received with continuation flag needs to be dropped as invalid. + * This protects against some random err frame with continuation flag. + */ + if (rxcb->is_continuation) + return -EINVAL; + + if (!ath12k_dp_rx_h_msdu_done(ab, desc)) { + ath12k_warn(ar->ab, + "msdu_done bit not set in null_q_des processing\n"); + __skb_queue_purge(msdu_list); + return -EIO; + } + + /* Handle NULL queue descriptor violations arising out a missing + * REO queue for a given peer or a given TID. This typically + * may happen if a packet is received on a QOS enabled TID before the + * ADDBA negotiation for that TID, when the TID queue is setup. Or + * it may also happen for MC/BC frames if they are not routed to the + * non-QOS TID queue, in the absence of any other default TID queue. + * This error can show up both in a REO destination or WBM release ring. + */ + + if (rxcb->is_frag) { + skb_pull(msdu, hal_rx_desc_sz); + } else { + l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc); + + if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) + return -EINVAL; + + skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); + skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); + } + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu))) + return -EINVAL; + + ath12k_dp_rx_h_fetch_info(ab, desc, rx_info); + ath12k_dp_rx_h_ppdu(ar, rx_info); + ath12k_dp_rx_h_mpdu(ar, msdu, desc, rx_info); + + rxcb->tid = rx_info->tid; + + /* Please note that caller will having the access to msdu and completing + * rx with mac80211. Need not worry about cleaning up amsdu_list. + */ + + return 0; +} static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, struct ath12k_dp_rx_info *rx_info) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 154018c221dad..9c2114c62ba2e 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -11,6 +11,8 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, struct napi_struct *napi, int budget); +int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, + int budget); int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); #endif From 806fbe9fd607dab4a49e26b7a43720177f79e661 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:43 +0530 Subject: [PATCH 023/140] wifi: ath12k: Move regular msdu processing functions to wifi7 directory Move arch specific RX MSDU processing related functions to wifi7 directory. The moved APIs will be a part of dp_rx.c file inside wifi7 directory. wifi7/dp_rx.c file will continue to be part of ath12k.ko temporarily until the corresponding infra for movement to ath12k_wifi7.ko arrives in upcoming patches. Architecture specific APIs: ath12k_dp_rx_msdu_coalesce ath12k_dp_rx_h_csum_offload ath12k_dp_rx_h_mpdu ath12k_dp_rx_process ath12k_dp_rx_process_received_packets ath12k_dp_rx_h_verify_tkip_mic ath12k_dp_rx_process_msdu Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-11-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 543 +----------------- drivers/net/wireless/ath/ath12k/dp_rx.h | 18 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 527 +++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 3 + 4 files changed, 547 insertions(+), 544 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 8abbf609899ad..478d83ba82742 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -1767,95 +1767,8 @@ void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, } EXPORT_SYMBOL(ath12k_dp_htt_htc_t2h_msg_handler); -static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar, - struct sk_buff_head *msdu_list, - struct sk_buff *first, struct sk_buff *last, - u8 l3pad_bytes, int msdu_len) -{ - struct ath12k_base *ab = ar->ab; - struct sk_buff *skb; - struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(first); - int buf_first_hdr_len, buf_first_len; - struct hal_rx_desc *ldesc; - int space_extra, rem_len, buf_len; - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; - bool is_continuation; - - /* As the msdu is spread across multiple rx buffers, - * find the offset to the start of msdu for computing - * the length of the msdu in the first buffer. - */ - buf_first_hdr_len = hal_rx_desc_sz + l3pad_bytes; - buf_first_len = DP_RX_BUFFER_SIZE - buf_first_hdr_len; - - if (WARN_ON_ONCE(msdu_len <= buf_first_len)) { - skb_put(first, buf_first_hdr_len + msdu_len); - skb_pull(first, buf_first_hdr_len); - return 0; - } - - ldesc = (struct hal_rx_desc *)last->data; - rxcb->is_first_msdu = ath12k_dp_rx_h_first_msdu(ab, ldesc); - rxcb->is_last_msdu = ath12k_dp_rx_h_last_msdu(ab, ldesc); - - /* MSDU spans over multiple buffers because the length of the MSDU - * exceeds DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE. So assume the data - * in the first buf is of length DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE. - */ - skb_put(first, DP_RX_BUFFER_SIZE); - skb_pull(first, buf_first_hdr_len); - - /* When an MSDU spread over multiple buffers MSDU_END - * tlvs are valid only in the last buffer. Copy those tlvs. - */ - ath12k_dp_rx_desc_end_tlv_copy(ab, rxcb->rx_desc, ldesc); - - space_extra = msdu_len - (buf_first_len + skb_tailroom(first)); - if (space_extra > 0 && - (pskb_expand_head(first, 0, space_extra, GFP_ATOMIC) < 0)) { - /* Free up all buffers of the MSDU */ - while ((skb = __skb_dequeue(msdu_list)) != NULL) { - rxcb = ATH12K_SKB_RXCB(skb); - if (!rxcb->is_continuation) { - dev_kfree_skb_any(skb); - break; - } - dev_kfree_skb_any(skb); - } - return -ENOMEM; - } - - rem_len = msdu_len - buf_first_len; - while ((skb = __skb_dequeue(msdu_list)) != NULL && rem_len > 0) { - rxcb = ATH12K_SKB_RXCB(skb); - is_continuation = rxcb->is_continuation; - if (is_continuation) - buf_len = DP_RX_BUFFER_SIZE - hal_rx_desc_sz; - else - buf_len = rem_len; - - if (buf_len > (DP_RX_BUFFER_SIZE - hal_rx_desc_sz)) { - WARN_ON_ONCE(1); - dev_kfree_skb_any(skb); - return -EINVAL; - } - - skb_put(skb, buf_len + hal_rx_desc_sz); - skb_pull(skb, hal_rx_desc_sz); - skb_copy_from_linear_data(skb, skb_put(first, buf_len), - buf_len); - dev_kfree_skb_any(skb); - - rem_len -= buf_len; - if (!is_continuation) - break; - } - - return 0; -} - -static struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, - struct sk_buff *first) +struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, + struct sk_buff *first) { struct sk_buff *skb; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(first); @@ -1872,13 +1785,6 @@ static struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_ return NULL; } -static void ath12k_dp_rx_h_csum_offload(struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info) -{ - msdu->ip_summed = (rx_info->ip_csum_fail || rx_info->l4_csum_fail) ? - CHECKSUM_NONE : CHECKSUM_UNNECESSARY; -} - int ath12k_dp_rx_crypto_mic_len(struct ath12k *ar, enum hal_encrypt_type enctype) { switch (enctype) { @@ -2197,84 +2103,6 @@ ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu, return peer; } -void ath12k_dp_rx_h_mpdu(struct ath12k *ar, - struct sk_buff *msdu, - struct hal_rx_desc *rx_desc, - struct ath12k_dp_rx_info *rx_info) -{ - struct ath12k_base *ab = ar->ab; - struct ath12k_skb_rxcb *rxcb; - enum hal_encrypt_type enctype; - bool is_decrypted = false; - struct ieee80211_hdr *hdr; - struct ath12k_peer *peer; - struct ieee80211_rx_status *rx_status = rx_info->rx_status; - u32 err_bitmap; - - /* PN for multicast packets will be checked in mac80211 */ - rxcb = ATH12K_SKB_RXCB(msdu); - rxcb->is_mcbc = rx_info->is_mcbc; - - if (rxcb->is_mcbc) - rxcb->peer_id = rx_info->peer_id; - - spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu, rx_info); - if (peer) { - /* resetting mcbc bit because mcbc packets are unicast - * packets only for AP as STA sends unicast packets. - */ - rxcb->is_mcbc = rxcb->is_mcbc && !peer->ucast_ra_only; - - if (rxcb->is_mcbc) - enctype = peer->sec_type_grp; - else - enctype = peer->sec_type; - } else { - enctype = HAL_ENCRYPT_TYPE_OPEN; - } - spin_unlock_bh(&ar->ab->base_lock); - - err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc); - if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap) - is_decrypted = ath12k_dp_rx_h_is_decrypted(ab, rx_desc); - - /* Clear per-MPDU flags while leaving per-PPDU flags intact */ - rx_status->flag &= ~(RX_FLAG_FAILED_FCS_CRC | - RX_FLAG_MMIC_ERROR | - RX_FLAG_DECRYPTED | - RX_FLAG_IV_STRIPPED | - RX_FLAG_MMIC_STRIPPED); - - if (err_bitmap & HAL_RX_MPDU_ERR_FCS) - rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - if (err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) - rx_status->flag |= RX_FLAG_MMIC_ERROR; - - if (is_decrypted) { - rx_status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_MMIC_STRIPPED; - - if (rx_info->is_mcbc) - rx_status->flag |= RX_FLAG_MIC_STRIPPED | - RX_FLAG_ICV_STRIPPED; - else - rx_status->flag |= RX_FLAG_IV_STRIPPED | - RX_FLAG_PN_VALIDATED; - } - - ath12k_dp_rx_h_csum_offload(msdu, rx_info); - ath12k_dp_rx_h_undecap(ar, msdu, rx_desc, - enctype, rx_status, is_decrypted); - - if (!is_decrypted || rx_info->is_mcbc) - return; - - if (rx_info->decap_type != DP_RX_DECAP_TYPE_ETHERNET2_DIX) { - hdr = (void *)msdu->data; - hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED); - } -} - static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info) { struct ieee80211_supported_band *sband; @@ -2533,140 +2361,9 @@ bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, return false; } -static int ath12k_dp_rx_process_msdu(struct ath12k *ar, - struct sk_buff *msdu, - struct sk_buff_head *msdu_list, - struct ath12k_dp_rx_info *rx_info) -{ - struct ath12k_base *ab = ar->ab; - struct hal_rx_desc *rx_desc, *lrx_desc; - struct ath12k_skb_rxcb *rxcb; - struct sk_buff *last_buf; - u8 l3_pad_bytes; - u16 msdu_len; - int ret; - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; - - last_buf = ath12k_dp_rx_get_msdu_last_buf(msdu_list, msdu); - if (!last_buf) { - ath12k_warn(ab, - "No valid Rx buffer to access MSDU_END tlv\n"); - ret = -EIO; - goto free_out; - } - - rx_desc = (struct hal_rx_desc *)msdu->data; - lrx_desc = (struct hal_rx_desc *)last_buf->data; - if (!ath12k_dp_rx_h_msdu_done(ab, lrx_desc)) { - ath12k_warn(ab, "msdu_done bit in msdu_end is not set\n"); - ret = -EIO; - goto free_out; - } - - rxcb = ATH12K_SKB_RXCB(msdu); - rxcb->rx_desc = rx_desc; - msdu_len = ath12k_dp_rx_h_msdu_len(ab, lrx_desc); - l3_pad_bytes = ath12k_dp_rx_h_l3pad(ab, lrx_desc); - - if (rxcb->is_frag) { - skb_pull(msdu, hal_rx_desc_sz); - } else if (!rxcb->is_continuation) { - if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { - ret = -EINVAL; - ath12k_warn(ab, "invalid msdu len %u\n", msdu_len); - ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", rx_desc, - sizeof(*rx_desc)); - goto free_out; - } - skb_put(msdu, hal_rx_desc_sz + l3_pad_bytes + msdu_len); - skb_pull(msdu, hal_rx_desc_sz + l3_pad_bytes); - } else { - ret = ath12k_dp_rx_msdu_coalesce(ar, msdu_list, - msdu, last_buf, - l3_pad_bytes, msdu_len); - if (ret) { - ath12k_warn(ab, - "failed to coalesce msdu rx buffer%d\n", ret); - goto free_out; - } - } - - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu))) { - ret = -EINVAL; - goto free_out; - } - - ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info); - ath12k_dp_rx_h_ppdu(ar, rx_info); - ath12k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_info); - - rx_info->rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; - - return 0; - -free_out: - return ret; -} - -static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab, - struct napi_struct *napi, - struct sk_buff_head *msdu_list, - int ring_id) -{ - struct ath12k_hw_group *ag = ab->ag; - struct ieee80211_rx_status rx_status = {}; - struct ath12k_skb_rxcb *rxcb; - struct sk_buff *msdu; - struct ath12k *ar; - struct ath12k_hw_link *hw_links = ag->hw_links; - struct ath12k_base *partner_ab; - struct ath12k_dp_rx_info rx_info; - u8 hw_link_id, pdev_id; - int ret; - - if (skb_queue_empty(msdu_list)) - return; - - rx_info.addr2_present = false; - rx_info.rx_status = &rx_status; - - rcu_read_lock(); - - while ((msdu = __skb_dequeue(msdu_list))) { - rxcb = ATH12K_SKB_RXCB(msdu); - hw_link_id = rxcb->hw_link_id; - partner_ab = ath12k_ag_to_ab(ag, - hw_links[hw_link_id].device_id); - pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, - hw_links[hw_link_id].pdev_idx); - ar = partner_ab->pdevs[pdev_id].ar; - if (!rcu_dereference(partner_ab->pdevs_active[pdev_id])) { - dev_kfree_skb_any(msdu); - continue; - } - - if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) { - dev_kfree_skb_any(msdu); - continue; - } - - ret = ath12k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_info); - if (ret) { - ath12k_dbg(ab, ATH12K_DBG_DATA, - "Unable to process msdu %d", ret); - dev_kfree_skb_any(msdu); - continue; - } - - ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info); - } - - rcu_read_unlock(); -} - -static u16 ath12k_dp_rx_get_peer_id(struct ath12k_base *ab, - enum ath12k_peer_metadata_version ver, - __le32 peer_metadata) +u16 ath12k_dp_rx_get_peer_id(struct ath12k_base *ab, + enum ath12k_peer_metadata_version ver, + __le32 peer_metadata) { switch (ver) { default: @@ -2687,166 +2384,6 @@ static u16 ath12k_dp_rx_get_peer_id(struct ath12k_base *ab, } } -int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id, - struct napi_struct *napi, int budget) -{ - struct ath12k_hw_group *ag = ab->ag; - struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; - struct ath12k_hw_link *hw_links = ag->hw_links; - int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; - struct ath12k_rx_desc_info *desc_info; - struct ath12k_dp *dp = &ab->dp; - struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; - struct hal_reo_dest_ring *desc; - struct ath12k_base *partner_ab; - struct sk_buff_head msdu_list; - struct ath12k_skb_rxcb *rxcb; - int total_msdu_reaped = 0; - u8 hw_link_id, device_id; - struct hal_srng *srng; - struct sk_buff *msdu; - bool done = false; - u64 desc_va; - - __skb_queue_head_init(&msdu_list); - - for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) - INIT_LIST_HEAD(&rx_desc_used_list[device_id]); - - srng = &ab->hal.srng_list[dp->reo_dst_ring[ring_id].ring_id]; - - spin_lock_bh(&srng->lock); - -try_again: - ath12k_hal_srng_access_begin(ab, srng); - - while ((desc = ath12k_hal_srng_dst_get_next_entry(ab, srng))) { - struct rx_mpdu_desc *mpdu_info; - struct rx_msdu_desc *msdu_info; - enum hal_reo_dest_ring_push_reason push_reason; - u32 cookie; - - cookie = le32_get_bits(desc->buf_addr_info.info1, - BUFFER_ADDR_INFO1_SW_COOKIE); - - hw_link_id = le32_get_bits(desc->info0, - HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); - - desc_va = ((u64)le32_to_cpu(desc->buf_va_hi) << 32 | - le32_to_cpu(desc->buf_va_lo)); - desc_info = (struct ath12k_rx_desc_info *)((unsigned long)desc_va); - - device_id = hw_links[hw_link_id].device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - if (unlikely(!partner_ab)) { - if (desc_info->skb) { - dev_kfree_skb_any(desc_info->skb); - desc_info->skb = NULL; - } - - continue; - } - - /* retry manual desc retrieval */ - if (!desc_info) { - desc_info = ath12k_dp_get_rx_desc(partner_ab, cookie); - if (!desc_info) { - ath12k_warn(partner_ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n", - cookie); - continue; - } - } - - if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) - ath12k_warn(ab, "Check HW CC implementation"); - - msdu = desc_info->skb; - desc_info->skb = NULL; - - list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]); - - rxcb = ATH12K_SKB_RXCB(msdu); - dma_unmap_single(partner_ab->dev, rxcb->paddr, - msdu->len + skb_tailroom(msdu), - DMA_FROM_DEVICE); - - num_buffs_reaped[device_id]++; - ab->device_stats.reo_rx[ring_id][ab->device_id]++; - - push_reason = le32_get_bits(desc->info0, - HAL_REO_DEST_RING_INFO0_PUSH_REASON); - if (push_reason != - HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) { - dev_kfree_skb_any(msdu); - ab->device_stats.hal_reo_error[ring_id]++; - continue; - } - - msdu_info = &desc->rx_msdu_info; - mpdu_info = &desc->rx_mpdu_info; - - rxcb->is_first_msdu = !!(le32_to_cpu(msdu_info->info0) & - RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU); - rxcb->is_last_msdu = !!(le32_to_cpu(msdu_info->info0) & - RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU); - rxcb->is_continuation = !!(le32_to_cpu(msdu_info->info0) & - RX_MSDU_DESC_INFO0_MSDU_CONTINUATION); - rxcb->hw_link_id = hw_link_id; - rxcb->peer_id = ath12k_dp_rx_get_peer_id(ab, dp->peer_metadata_ver, - mpdu_info->peer_meta_data); - rxcb->tid = le32_get_bits(mpdu_info->info0, - RX_MPDU_DESC_INFO0_TID); - - __skb_queue_tail(&msdu_list, msdu); - - if (!rxcb->is_continuation) { - total_msdu_reaped++; - done = true; - } else { - done = false; - } - - if (total_msdu_reaped >= budget) - break; - } - - /* Hw might have updated the head pointer after we cached it. - * In this case, even though there are entries in the ring we'll - * get rx_desc NULL. Give the read another try with updated cached - * head pointer so that we can reap complete MPDU in the current - * rx processing. - */ - if (!done && ath12k_hal_srng_dst_num_free(ab, srng, true)) { - ath12k_hal_srng_access_end(ab, srng); - goto try_again; - } - - ath12k_hal_srng_access_end(ab, srng); - - spin_unlock_bh(&srng->lock); - - if (!total_msdu_reaped) - goto exit; - - for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) { - if (!num_buffs_reaped[device_id]) - continue; - - partner_ab = ath12k_ag_to_ab(ag, device_id); - rx_ring = &partner_ab->dp.rx_refill_buf_ring; - - ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, - &rx_desc_used_list[device_id], - num_buffs_reaped[device_id]); - } - - ath12k_dp_rx_process_received_packets(ab, napi, &msdu_list, - ring_id); - -exit: - return total_msdu_reaped; -} - static void ath12k_dp_rx_frag_timer(struct timer_list *timer) { struct ath12k_dp_rx_tid *rx_tid = timer_container_of(rx_tid, timer, @@ -2904,9 +2441,9 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev return 0; } -static int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, - struct ieee80211_hdr *hdr, u8 *data, - size_t data_len, u8 *mic) +int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, + struct ieee80211_hdr *hdr, u8 *data, + size_t data_len, u8 *mic) { SHASH_DESC_ON_STACK(desc, tfm); u8 mic_hdr[16] = {}; @@ -2945,70 +2482,6 @@ static int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, return ret; } -int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer, - struct sk_buff *msdu) -{ - struct ath12k_base *ab = ar->ab; - struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; - struct ieee80211_rx_status *rxs = IEEE80211_SKB_RXCB(msdu); - struct ieee80211_key_conf *key_conf; - struct ieee80211_hdr *hdr; - struct ath12k_dp_rx_info rx_info; - u8 mic[IEEE80211_CCMP_MIC_LEN]; - int head_len, tail_len, ret; - size_t data_len; - u32 hdr_len, hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; - u8 *key, *data; - u8 key_idx; - - if (ath12k_dp_rx_h_enctype(ab, rx_desc) != HAL_ENCRYPT_TYPE_TKIP_MIC) - return 0; - - rx_info.addr2_present = false; - rx_info.rx_status = rxs; - - hdr = (struct ieee80211_hdr *)(msdu->data + hal_rx_desc_sz); - hdr_len = ieee80211_hdrlen(hdr->frame_control); - head_len = hdr_len + hal_rx_desc_sz + IEEE80211_TKIP_IV_LEN; - tail_len = IEEE80211_CCMP_MIC_LEN + IEEE80211_TKIP_ICV_LEN + FCS_LEN; - - if (!is_multicast_ether_addr(hdr->addr1)) - key_idx = peer->ucast_keyidx; - else - key_idx = peer->mcast_keyidx; - - key_conf = peer->keys[key_idx]; - - data = msdu->data + head_len; - data_len = msdu->len - head_len - tail_len; - key = &key_conf->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; - - ret = ath12k_dp_rx_h_michael_mic(peer->tfm_mmic, key, hdr, data, data_len, mic); - if (ret || memcmp(mic, data + data_len, IEEE80211_CCMP_MIC_LEN)) - goto mic_fail; - - return 0; - -mic_fail: - (ATH12K_SKB_RXCB(msdu))->is_first_msdu = true; - (ATH12K_SKB_RXCB(msdu))->is_last_msdu = true; - - ath12k_dp_rx_h_fetch_info(ab, rx_desc, &rx_info); - - rxs->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_MMIC_STRIPPED | - RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED; - skb_pull(msdu, hal_rx_desc_sz); - - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu))) - return -EINVAL; - - ath12k_dp_rx_h_ppdu(ar, &rx_info); - ath12k_dp_rx_h_undecap(ar, msdu, rx_desc, - HAL_ENCRYPT_TYPE_TKIP_MIC, rxs, true); - ieee80211_rx(ath12k_ar_to_hw(ar), msdu); - return -EINVAL; -} - void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu, enum hal_encrypt_type enctype, u32 flags) { diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 8249eed39a9b7..454e46b9d452a 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -6,6 +6,7 @@ #ifndef ATH12K_DP_RX_H #define ATH12K_DP_RX_H +#include #include "core.h" #include "wifi7/hal_rx_desc.h" #include "debug.h" @@ -367,20 +368,20 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, struct sk_buff *msdu); -void ath12k_dp_rx_h_mpdu(struct ath12k *ar, - struct sk_buff *msdu, - struct hal_rx_desc *rx_desc, - struct ath12k_dp_rx_info *rx_info); u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb); void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, struct sk_buff_head *frag_list, struct sk_buff *cur_frag); void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu, enum hal_encrypt_type enctype, u32 flags); -int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer, - struct sk_buff *msdu); void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, bool rel_link_desc); +int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, + struct ieee80211_hdr *hdr, u8 *data, + size_t data_len, u8 *mic); +u16 ath12k_dp_rx_get_peer_id(struct ath12k_base *ab, + enum ath12k_peer_metadata_version ver, + __le32 peer_metadata); int ath12k_dp_rx_ampdu_start(struct ath12k *ar, struct ieee80211_ampdu_params *params, u8 link_id); @@ -408,9 +409,6 @@ int ath12k_dp_rx_pdev_alloc(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab); void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab); -int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id, - struct napi_struct *napi, - int budget); int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, struct dp_rxdma_ring *rx_ring, struct list_head *used_list, @@ -445,4 +443,6 @@ int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info); +struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, + struct sk_buff *first); #endif /* ATH12K_DP_RX_H */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index c2b108a1005bd..b55cfb926571f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -8,6 +8,469 @@ #include "../dp_tx.h" #include "../peer.h" +static void ath12k_dp_rx_h_csum_offload(struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info) +{ + msdu->ip_summed = (rx_info->ip_csum_fail || rx_info->l4_csum_fail) ? + CHECKSUM_NONE : CHECKSUM_UNNECESSARY; +} + +static void ath12k_dp_rx_h_mpdu(struct ath12k *ar, + struct sk_buff *msdu, + struct hal_rx_desc *rx_desc, + struct ath12k_dp_rx_info *rx_info) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_skb_rxcb *rxcb; + enum hal_encrypt_type enctype; + bool is_decrypted = false; + struct ieee80211_hdr *hdr; + struct ath12k_peer *peer; + struct ieee80211_rx_status *rx_status = rx_info->rx_status; + u32 err_bitmap; + + /* PN for multicast packets will be checked in mac80211 */ + rxcb = ATH12K_SKB_RXCB(msdu); + rxcb->is_mcbc = rx_info->is_mcbc; + + if (rxcb->is_mcbc) + rxcb->peer_id = rx_info->peer_id; + + spin_lock_bh(&ar->ab->base_lock); + peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu, rx_info); + if (peer) { + /* resetting mcbc bit because mcbc packets are unicast + * packets only for AP as STA sends unicast packets. + */ + rxcb->is_mcbc = rxcb->is_mcbc && !peer->ucast_ra_only; + + if (rxcb->is_mcbc) + enctype = peer->sec_type_grp; + else + enctype = peer->sec_type; + } else { + enctype = HAL_ENCRYPT_TYPE_OPEN; + } + spin_unlock_bh(&ar->ab->base_lock); + + err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc); + if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap) + is_decrypted = ath12k_dp_rx_h_is_decrypted(ab, rx_desc); + + /* Clear per-MPDU flags while leaving per-PPDU flags intact */ + rx_status->flag &= ~(RX_FLAG_FAILED_FCS_CRC | + RX_FLAG_MMIC_ERROR | + RX_FLAG_DECRYPTED | + RX_FLAG_IV_STRIPPED | + RX_FLAG_MMIC_STRIPPED); + + if (err_bitmap & HAL_RX_MPDU_ERR_FCS) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + if (err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) + rx_status->flag |= RX_FLAG_MMIC_ERROR; + + if (is_decrypted) { + rx_status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_MMIC_STRIPPED; + + if (rx_info->is_mcbc) + rx_status->flag |= RX_FLAG_MIC_STRIPPED | + RX_FLAG_ICV_STRIPPED; + else + rx_status->flag |= RX_FLAG_IV_STRIPPED | + RX_FLAG_PN_VALIDATED; + } + + ath12k_dp_rx_h_csum_offload(msdu, rx_info); + ath12k_dp_rx_h_undecap(ar, msdu, rx_desc, + enctype, rx_status, is_decrypted); + + if (!is_decrypted || rx_info->is_mcbc) + return; + + if (rx_info->decap_type != DP_RX_DECAP_TYPE_ETHERNET2_DIX) { + hdr = (void *)msdu->data; + hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED); + } +} + +static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar, + struct sk_buff_head *msdu_list, + struct sk_buff *first, struct sk_buff *last, + u8 l3pad_bytes, int msdu_len) +{ + struct ath12k_base *ab = ar->ab; + struct sk_buff *skb; + struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(first); + int buf_first_hdr_len, buf_first_len; + struct hal_rx_desc *ldesc; + int space_extra, rem_len, buf_len; + u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + bool is_continuation; + + /* As the msdu is spread across multiple rx buffers, + * find the offset to the start of msdu for computing + * the length of the msdu in the first buffer. + */ + buf_first_hdr_len = hal_rx_desc_sz + l3pad_bytes; + buf_first_len = DP_RX_BUFFER_SIZE - buf_first_hdr_len; + + if (WARN_ON_ONCE(msdu_len <= buf_first_len)) { + skb_put(first, buf_first_hdr_len + msdu_len); + skb_pull(first, buf_first_hdr_len); + return 0; + } + + ldesc = (struct hal_rx_desc *)last->data; + rxcb->is_first_msdu = ath12k_dp_rx_h_first_msdu(ab, ldesc); + rxcb->is_last_msdu = ath12k_dp_rx_h_last_msdu(ab, ldesc); + + /* MSDU spans over multiple buffers because the length of the MSDU + * exceeds DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE. So assume the data + * in the first buf is of length DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE. + */ + skb_put(first, DP_RX_BUFFER_SIZE); + skb_pull(first, buf_first_hdr_len); + + /* When an MSDU spread over multiple buffers MSDU_END + * tlvs are valid only in the last buffer. Copy those tlvs. + */ + ath12k_dp_rx_desc_end_tlv_copy(ab, rxcb->rx_desc, ldesc); + + space_extra = msdu_len - (buf_first_len + skb_tailroom(first)); + if (space_extra > 0 && + (pskb_expand_head(first, 0, space_extra, GFP_ATOMIC) < 0)) { + /* Free up all buffers of the MSDU */ + while ((skb = __skb_dequeue(msdu_list)) != NULL) { + rxcb = ATH12K_SKB_RXCB(skb); + if (!rxcb->is_continuation) { + dev_kfree_skb_any(skb); + break; + } + dev_kfree_skb_any(skb); + } + return -ENOMEM; + } + + rem_len = msdu_len - buf_first_len; + while ((skb = __skb_dequeue(msdu_list)) != NULL && rem_len > 0) { + rxcb = ATH12K_SKB_RXCB(skb); + is_continuation = rxcb->is_continuation; + if (is_continuation) + buf_len = DP_RX_BUFFER_SIZE - hal_rx_desc_sz; + else + buf_len = rem_len; + + if (buf_len > (DP_RX_BUFFER_SIZE - hal_rx_desc_sz)) { + WARN_ON_ONCE(1); + dev_kfree_skb_any(skb); + return -EINVAL; + } + + skb_put(skb, buf_len + hal_rx_desc_sz); + skb_pull(skb, hal_rx_desc_sz); + skb_copy_from_linear_data(skb, skb_put(first, buf_len), + buf_len); + dev_kfree_skb_any(skb); + + rem_len -= buf_len; + if (!is_continuation) + break; + } + + return 0; +} + +static int ath12k_dp_rx_process_msdu(struct ath12k *ar, + struct sk_buff *msdu, + struct sk_buff_head *msdu_list, + struct ath12k_dp_rx_info *rx_info) +{ + struct ath12k_base *ab = ar->ab; + struct hal_rx_desc *rx_desc, *lrx_desc; + struct ath12k_skb_rxcb *rxcb; + struct sk_buff *last_buf; + u8 l3_pad_bytes; + u16 msdu_len; + int ret; + u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + + last_buf = ath12k_dp_rx_get_msdu_last_buf(msdu_list, msdu); + if (!last_buf) { + ath12k_warn(ab, + "No valid Rx buffer to access MSDU_END tlv\n"); + ret = -EIO; + goto free_out; + } + + rx_desc = (struct hal_rx_desc *)msdu->data; + lrx_desc = (struct hal_rx_desc *)last_buf->data; + if (!ath12k_dp_rx_h_msdu_done(ab, lrx_desc)) { + ath12k_warn(ab, "msdu_done bit in msdu_end is not set\n"); + ret = -EIO; + goto free_out; + } + + rxcb = ATH12K_SKB_RXCB(msdu); + rxcb->rx_desc = rx_desc; + msdu_len = ath12k_dp_rx_h_msdu_len(ab, lrx_desc); + l3_pad_bytes = ath12k_dp_rx_h_l3pad(ab, lrx_desc); + + if (rxcb->is_frag) { + skb_pull(msdu, hal_rx_desc_sz); + } else if (!rxcb->is_continuation) { + if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { + ret = -EINVAL; + ath12k_warn(ab, "invalid msdu len %u\n", msdu_len); + ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", rx_desc, + sizeof(*rx_desc)); + goto free_out; + } + skb_put(msdu, hal_rx_desc_sz + l3_pad_bytes + msdu_len); + skb_pull(msdu, hal_rx_desc_sz + l3_pad_bytes); + } else { + ret = ath12k_dp_rx_msdu_coalesce(ar, msdu_list, + msdu, last_buf, + l3_pad_bytes, msdu_len); + if (ret) { + ath12k_warn(ab, + "failed to coalesce msdu rx buffer%d\n", ret); + goto free_out; + } + } + + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu))) { + ret = -EINVAL; + goto free_out; + } + + ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info); + ath12k_dp_rx_h_ppdu(ar, rx_info); + ath12k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_info); + + rx_info->rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; + + return 0; + +free_out: + return ret; +} + +static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab, + struct napi_struct *napi, + struct sk_buff_head *msdu_list, + int ring_id) +{ + struct ath12k_hw_group *ag = ab->ag; + struct ieee80211_rx_status rx_status = {}; + struct ath12k_skb_rxcb *rxcb; + struct sk_buff *msdu; + struct ath12k *ar; + struct ath12k_hw_link *hw_links = ag->hw_links; + struct ath12k_base *partner_ab; + struct ath12k_dp_rx_info rx_info; + u8 hw_link_id, pdev_id; + int ret; + + if (skb_queue_empty(msdu_list)) + return; + + rx_info.addr2_present = false; + rx_info.rx_status = &rx_status; + + rcu_read_lock(); + + while ((msdu = __skb_dequeue(msdu_list))) { + rxcb = ATH12K_SKB_RXCB(msdu); + hw_link_id = rxcb->hw_link_id; + partner_ab = ath12k_ag_to_ab(ag, + hw_links[hw_link_id].device_id); + pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + hw_links[hw_link_id].pdev_idx); + ar = partner_ab->pdevs[pdev_id].ar; + if (!rcu_dereference(partner_ab->pdevs_active[pdev_id])) { + dev_kfree_skb_any(msdu); + continue; + } + + if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) { + dev_kfree_skb_any(msdu); + continue; + } + + ret = ath12k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_info); + if (ret) { + ath12k_dbg(ab, ATH12K_DBG_DATA, + "Unable to process msdu %d", ret); + dev_kfree_skb_any(msdu); + continue; + } + + ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info); + } + + rcu_read_unlock(); +} + +int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id, + struct napi_struct *napi, int budget) +{ + struct ath12k_hw_group *ag = ab->ag; + struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; + struct ath12k_hw_link *hw_links = ag->hw_links; + int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; + struct ath12k_rx_desc_info *desc_info; + struct ath12k_dp *dp = &ab->dp; + struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; + struct hal_reo_dest_ring *desc; + struct ath12k_base *partner_ab; + struct sk_buff_head msdu_list; + struct ath12k_skb_rxcb *rxcb; + int total_msdu_reaped = 0; + u8 hw_link_id, device_id; + struct hal_srng *srng; + struct sk_buff *msdu; + bool done = false; + u64 desc_va; + + __skb_queue_head_init(&msdu_list); + + for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) + INIT_LIST_HEAD(&rx_desc_used_list[device_id]); + + srng = &ab->hal.srng_list[dp->reo_dst_ring[ring_id].ring_id]; + + spin_lock_bh(&srng->lock); + +try_again: + ath12k_hal_srng_access_begin(ab, srng); + + while ((desc = ath12k_hal_srng_dst_get_next_entry(ab, srng))) { + struct rx_mpdu_desc *mpdu_info; + struct rx_msdu_desc *msdu_info; + enum hal_reo_dest_ring_push_reason push_reason; + u32 cookie; + + cookie = le32_get_bits(desc->buf_addr_info.info1, + BUFFER_ADDR_INFO1_SW_COOKIE); + + hw_link_id = le32_get_bits(desc->info0, + HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); + + desc_va = ((u64)le32_to_cpu(desc->buf_va_hi) << 32 | + le32_to_cpu(desc->buf_va_lo)); + desc_info = (struct ath12k_rx_desc_info *)((unsigned long)desc_va); + + device_id = hw_links[hw_link_id].device_id; + partner_ab = ath12k_ag_to_ab(ag, device_id); + if (unlikely(!partner_ab)) { + if (desc_info->skb) { + dev_kfree_skb_any(desc_info->skb); + desc_info->skb = NULL; + } + + continue; + } + + /* retry manual desc retrieval */ + if (!desc_info) { + desc_info = ath12k_dp_get_rx_desc(partner_ab, cookie); + if (!desc_info) { + ath12k_warn(partner_ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n", + cookie); + continue; + } + } + + if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) + ath12k_warn(ab, "Check HW CC implementation"); + + msdu = desc_info->skb; + desc_info->skb = NULL; + + list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]); + + rxcb = ATH12K_SKB_RXCB(msdu); + dma_unmap_single(partner_ab->dev, rxcb->paddr, + msdu->len + skb_tailroom(msdu), + DMA_FROM_DEVICE); + + num_buffs_reaped[device_id]++; + ab->device_stats.reo_rx[ring_id][ab->device_id]++; + + push_reason = le32_get_bits(desc->info0, + HAL_REO_DEST_RING_INFO0_PUSH_REASON); + if (push_reason != + HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) { + dev_kfree_skb_any(msdu); + ab->device_stats.hal_reo_error[ring_id]++; + continue; + } + + msdu_info = &desc->rx_msdu_info; + mpdu_info = &desc->rx_mpdu_info; + + rxcb->is_first_msdu = !!(le32_to_cpu(msdu_info->info0) & + RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU); + rxcb->is_last_msdu = !!(le32_to_cpu(msdu_info->info0) & + RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU); + rxcb->is_continuation = !!(le32_to_cpu(msdu_info->info0) & + RX_MSDU_DESC_INFO0_MSDU_CONTINUATION); + rxcb->hw_link_id = hw_link_id; + rxcb->peer_id = ath12k_dp_rx_get_peer_id(ab, dp->peer_metadata_ver, + mpdu_info->peer_meta_data); + rxcb->tid = le32_get_bits(mpdu_info->info0, + RX_MPDU_DESC_INFO0_TID); + + __skb_queue_tail(&msdu_list, msdu); + + if (!rxcb->is_continuation) { + total_msdu_reaped++; + done = true; + } else { + done = false; + } + + if (total_msdu_reaped >= budget) + break; + } + + /* Hw might have updated the head pointer after we cached it. + * In this case, even though there are entries in the ring we'll + * get rx_desc NULL. Give the read another try with updated cached + * head pointer so that we can reap complete MPDU in the current + * rx processing. + */ + if (!done && ath12k_hal_srng_dst_num_free(ab, srng, true)) { + ath12k_hal_srng_access_end(ab, srng); + goto try_again; + } + + ath12k_hal_srng_access_end(ab, srng); + + spin_unlock_bh(&srng->lock); + + if (!total_msdu_reaped) + goto exit; + + for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) { + if (!num_buffs_reaped[device_id]) + continue; + + partner_ab = ath12k_ag_to_ab(ag, device_id); + rx_ring = &partner_ab->dp.rx_refill_buf_ring; + + ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, + &rx_desc_used_list[device_id], + num_buffs_reaped[device_id]); + } + + ath12k_dp_rx_process_received_packets(ab, napi, &msdu_list, + ring_id); + +exit: + return total_msdu_reaped; +} + static bool ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, struct ath12k_dp_rx_tid *rx_tid) { @@ -188,6 +651,70 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, return ret; } +static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer, + struct sk_buff *msdu) +{ + struct ath12k_base *ab = ar->ab; + struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; + struct ieee80211_rx_status *rxs = IEEE80211_SKB_RXCB(msdu); + struct ieee80211_key_conf *key_conf; + struct ieee80211_hdr *hdr; + struct ath12k_dp_rx_info rx_info; + u8 mic[IEEE80211_CCMP_MIC_LEN]; + int head_len, tail_len, ret; + size_t data_len; + u32 hdr_len, hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + u8 *key, *data; + u8 key_idx; + + if (ath12k_dp_rx_h_enctype(ab, rx_desc) != HAL_ENCRYPT_TYPE_TKIP_MIC) + return 0; + + rx_info.addr2_present = false; + rx_info.rx_status = rxs; + + hdr = (struct ieee80211_hdr *)(msdu->data + hal_rx_desc_sz); + hdr_len = ieee80211_hdrlen(hdr->frame_control); + head_len = hdr_len + hal_rx_desc_sz + IEEE80211_TKIP_IV_LEN; + tail_len = IEEE80211_CCMP_MIC_LEN + IEEE80211_TKIP_ICV_LEN + FCS_LEN; + + if (!is_multicast_ether_addr(hdr->addr1)) + key_idx = peer->ucast_keyidx; + else + key_idx = peer->mcast_keyidx; + + key_conf = peer->keys[key_idx]; + + data = msdu->data + head_len; + data_len = msdu->len - head_len - tail_len; + key = &key_conf->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; + + ret = ath12k_dp_rx_h_michael_mic(peer->tfm_mmic, key, hdr, data, data_len, mic); + if (ret || memcmp(mic, data + data_len, IEEE80211_CCMP_MIC_LEN)) + goto mic_fail; + + return 0; + +mic_fail: + (ATH12K_SKB_RXCB(msdu))->is_first_msdu = true; + (ATH12K_SKB_RXCB(msdu))->is_last_msdu = true; + + ath12k_dp_rx_h_fetch_info(ab, rx_desc, &rx_info); + + rxs->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_MMIC_STRIPPED | + RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED; + skb_pull(msdu, hal_rx_desc_sz); + + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu))) + return -EINVAL; + + ath12k_dp_rx_h_ppdu(ar, &rx_info); + ath12k_dp_rx_h_undecap(ar, msdu, rx_desc, + HAL_ENCRYPT_TYPE_TKIP_MIC, rxs, true); + ieee80211_rx(ath12k_ar_to_hw(ar), msdu); + return -EINVAL; +} + static int ath12k_dp_rx_h_defrag(struct ath12k *ar, struct ath12k_peer *peer, struct ath12k_dp_rx_tid *rx_tid, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 9c2114c62ba2e..fa44e454cee6c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -13,6 +13,9 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, struct napi_struct *napi, int budget); int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, int budget); +int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id, + struct napi_struct *napi, + int budget); int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); #endif From fb798823882c687787f1b4ca52fd0f9891cf9bc4 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:44 +0530 Subject: [PATCH 024/140] wifi: ath12k: Move srng processing to wifi7 directory Move ath12k_dp_service_srng API and ath12k_dp_rx_process_reo_status to wifi7 directory. As srng processing is specific to architecture (wifi7 / wifi8), the API ath12k_dp_service_srng is being moved to wifi7 directory. The file wifi7/dp.c can be used to define wifi7-specifi functions that are common to both tx and rx. The API which is invoked as part of service srng, ath12k_dp_rx_process_reo_status is also moved to wifi7 directory, as the implementation is specific to HW due to the usage of wifi7 specific HAL macros. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-12-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 3 +- drivers/net/wireless/ath/ath12k/ahb.c | 3 +- drivers/net/wireless/ath/ath12k/dp.c | 124 ---------------- drivers/net/wireless/ath/ath12k/dp.h | 3 - drivers/net/wireless/ath/ath12k/dp_rx.c | 79 ---------- drivers/net/wireless/ath/ath12k/dp_rx.h | 1 - drivers/net/wireless/ath/ath12k/pci.c | 1 + drivers/net/wireless/ath/ath12k/wifi7/dp.c | 136 ++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp.h | 15 ++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 79 ++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 1 + 11 files changed, 236 insertions(+), 209 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp.c create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index d7628bb7af029..ed1f1dba3d3b9 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -24,7 +24,8 @@ ath12k-$(CONFIG_ATH12K_AHB) += ahb.o ath12k-y += wifi7/hal_tx.o \ wifi7/hal_rx.o \ - wifi7/dp_rx.o + wifi7/dp_rx.o \ + wifi7/dp.o obj-$(CONFIG_ATH12K) += wifi7/ diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index 9348b5aa08c67..8d14813365755 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include @@ -15,6 +15,7 @@ #include "ahb.h" #include "debug.h" #include "hif.h" +#include "wifi7/dp.h" #define ATH12K_IRQ_CE0_OFFSET 4 #define ATH12K_MAX_UPDS 1 diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 1faac4ab641c1..2826251602b6b 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -883,130 +883,6 @@ int ath12k_dp_link_desc_setup(struct ath12k_base *ab, return ret; } -int ath12k_dp_service_srng(struct ath12k_base *ab, - struct ath12k_ext_irq_grp *irq_grp, - int budget) -{ - struct napi_struct *napi = &irq_grp->napi; - int grp_id = irq_grp->grp_id; - int work_done = 0; - int i = 0, j; - int tot_work_done = 0; - enum dp_monitor_mode monitor_mode; - u8 ring_mask; - - if (ab->hw_params->ring_mask->tx[grp_id]) { - i = fls(ab->hw_params->ring_mask->tx[grp_id]) - 1; - ath12k_dp_tx_completion_handler(ab, i); - } - - if (ab->hw_params->ring_mask->rx_err[grp_id]) { - work_done = ath12k_dp_rx_process_err(ab, napi, budget); - budget -= work_done; - tot_work_done += work_done; - if (budget <= 0) - goto done; - } - - if (ab->hw_params->ring_mask->rx_wbm_rel[grp_id]) { - work_done = ath12k_dp_rx_process_wbm_err(ab, - napi, - budget); - budget -= work_done; - tot_work_done += work_done; - - if (budget <= 0) - goto done; - } - - if (ab->hw_params->ring_mask->rx[grp_id]) { - i = fls(ab->hw_params->ring_mask->rx[grp_id]) - 1; - work_done = ath12k_dp_rx_process(ab, i, napi, - budget); - budget -= work_done; - tot_work_done += work_done; - if (budget <= 0) - goto done; - } - - if (ab->hw_params->ring_mask->rx_mon_status[grp_id]) { - ring_mask = ab->hw_params->ring_mask->rx_mon_status[grp_id]; - for (i = 0; i < ab->num_radios; i++) { - for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { - int id = i * ab->hw_params->num_rxdma_per_pdev + j; - - if (ring_mask & BIT(id)) { - work_done = - ath12k_dp_mon_process_ring(ab, id, napi, budget, - 0); - budget -= work_done; - tot_work_done += work_done; - if (budget <= 0) - goto done; - } - } - } - } - - if (ab->hw_params->ring_mask->rx_mon_dest[grp_id]) { - monitor_mode = ATH12K_DP_RX_MONITOR_MODE; - ring_mask = ab->hw_params->ring_mask->rx_mon_dest[grp_id]; - for (i = 0; i < ab->num_radios; i++) { - for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { - int id = i * ab->hw_params->num_rxdma_per_pdev + j; - - if (ring_mask & BIT(id)) { - work_done = - ath12k_dp_mon_process_ring(ab, id, napi, budget, - monitor_mode); - budget -= work_done; - tot_work_done += work_done; - - if (budget <= 0) - goto done; - } - } - } - } - - if (ab->hw_params->ring_mask->tx_mon_dest[grp_id]) { - monitor_mode = ATH12K_DP_TX_MONITOR_MODE; - ring_mask = ab->hw_params->ring_mask->tx_mon_dest[grp_id]; - for (i = 0; i < ab->num_radios; i++) { - for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { - int id = i * ab->hw_params->num_rxdma_per_pdev + j; - - if (ring_mask & BIT(id)) { - work_done = - ath12k_dp_mon_process_ring(ab, id, napi, budget, - monitor_mode); - budget -= work_done; - tot_work_done += work_done; - - if (budget <= 0) - goto done; - } - } - } - } - - if (ab->hw_params->ring_mask->reo_status[grp_id]) - ath12k_dp_rx_process_reo_status(ab); - - if (ab->hw_params->ring_mask->host2rxdma[grp_id]) { - struct ath12k_dp *dp = &ab->dp; - struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; - LIST_HEAD(list); - - ath12k_dp_rx_bufs_replenish(ab, rx_ring, &list, 0); - } - - /* TODO: Implement handler for other interrupts */ - -done: - return tot_work_done; -} - void ath12k_dp_pdev_free(struct ath12k_base *ab) { int i; diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index e0c610f7ff885..cfffc51f87bf4 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -1940,9 +1940,6 @@ static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) memcpy(addr + 4, &addr_h16, ETH_ALEN - 4); } -int ath12k_dp_service_srng(struct ath12k_base *ab, - struct ath12k_ext_irq_grp *irq_grp, - int budget); int ath12k_dp_htt_connect(struct ath12k_dp *dp); void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif); void ath12k_dp_free(struct ath12k_base *ab); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 478d83ba82742..8564b18c6a447 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -2561,85 +2561,6 @@ u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb) return pn; } -void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab) -{ - struct ath12k_dp *dp = &ab->dp; - struct hal_tlv_64_hdr *hdr; - struct hal_srng *srng; - struct ath12k_dp_rx_reo_cmd *cmd, *tmp; - bool found = false; - u16 tag; - struct hal_reo_status reo_status; - - srng = &ab->hal.srng_list[dp->reo_status_ring.ring_id]; - - memset(&reo_status, 0, sizeof(reo_status)); - - spin_lock_bh(&srng->lock); - - ath12k_hal_srng_access_begin(ab, srng); - - while ((hdr = ath12k_hal_srng_dst_get_next_entry(ab, srng))) { - tag = le64_get_bits(hdr->tl, HAL_SRNG_TLV_HDR_TAG); - - switch (tag) { - case HAL_REO_GET_QUEUE_STATS_STATUS: - ath12k_hal_reo_status_queue_stats(ab, hdr, - &reo_status); - break; - case HAL_REO_FLUSH_QUEUE_STATUS: - ath12k_hal_reo_flush_queue_status(ab, hdr, - &reo_status); - break; - case HAL_REO_FLUSH_CACHE_STATUS: - ath12k_hal_reo_flush_cache_status(ab, hdr, - &reo_status); - break; - case HAL_REO_UNBLOCK_CACHE_STATUS: - ath12k_hal_reo_unblk_cache_status(ab, hdr, - &reo_status); - break; - case HAL_REO_FLUSH_TIMEOUT_LIST_STATUS: - ath12k_hal_reo_flush_timeout_list_status(ab, hdr, - &reo_status); - break; - case HAL_REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS: - ath12k_hal_reo_desc_thresh_reached_status(ab, hdr, - &reo_status); - break; - case HAL_REO_UPDATE_RX_REO_QUEUE_STATUS: - ath12k_hal_reo_update_rx_reo_queue_status(ab, hdr, - &reo_status); - break; - default: - ath12k_warn(ab, "Unknown reo status type %d\n", tag); - continue; - } - - spin_lock_bh(&dp->reo_cmd_lock); - list_for_each_entry_safe(cmd, tmp, &dp->reo_cmd_list, list) { - if (reo_status.uniform_hdr.cmd_num == cmd->cmd_num) { - found = true; - list_del(&cmd->list); - break; - } - } - spin_unlock_bh(&dp->reo_cmd_lock); - - if (found) { - cmd->handler(dp, (void *)&cmd->data, - reo_status.uniform_hdr.cmd_status); - kfree(cmd); - } - - found = false; - } - - ath12k_hal_srng_access_end(ab, srng); - - spin_unlock_bh(&srng->lock); -} - void ath12k_dp_rx_free(struct ath12k_base *ab) { struct ath12k_dp *dp = &ab->dp; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 454e46b9d452a..c1efc8c658db0 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -408,7 +408,6 @@ void ath12k_dp_rx_free(struct ath12k_base *ab); int ath12k_dp_rx_pdev_alloc(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab); -void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab); int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, struct dp_rxdma_ring *rx_ring, struct list_head *used_list, diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 1daccd5893a81..ee077c3f973c8 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -15,6 +15,7 @@ #include "hif.h" #include "mhi.h" #include "debug.h" +#include "wifi7/dp.h" #define ATH12K_PCI_BAR_NUM 0 #define ATH12K_PCI_DMA_MASK 36 diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c new file mode 100644 index 0000000000000..2e7b9bbd3d8ed --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#include "../core.h" +#include "../debug.h" +#include "../dp_rx.h" +#include "../dp_tx.h" +#include "../dp_mon.h" +#include "dp_rx.h" +#include "dp.h" + +int ath12k_dp_service_srng(struct ath12k_base *ab, + struct ath12k_ext_irq_grp *irq_grp, + int budget) +{ + struct napi_struct *napi = &irq_grp->napi; + int grp_id = irq_grp->grp_id; + int work_done = 0; + int i = 0, j; + int tot_work_done = 0; + enum dp_monitor_mode monitor_mode; + u8 ring_mask; + + if (ab->hw_params->ring_mask->tx[grp_id]) { + i = fls(ab->hw_params->ring_mask->tx[grp_id]) - 1; + ath12k_dp_tx_completion_handler(ab, i); + } + + if (ab->hw_params->ring_mask->rx_err[grp_id]) { + work_done = ath12k_dp_rx_process_err(ab, napi, budget); + budget -= work_done; + tot_work_done += work_done; + if (budget <= 0) + goto done; + } + + if (ab->hw_params->ring_mask->rx_wbm_rel[grp_id]) { + work_done = ath12k_dp_rx_process_wbm_err(ab, + napi, + budget); + budget -= work_done; + tot_work_done += work_done; + + if (budget <= 0) + goto done; + } + + if (ab->hw_params->ring_mask->rx[grp_id]) { + i = fls(ab->hw_params->ring_mask->rx[grp_id]) - 1; + work_done = ath12k_dp_rx_process(ab, i, napi, + budget); + budget -= work_done; + tot_work_done += work_done; + if (budget <= 0) + goto done; + } + + if (ab->hw_params->ring_mask->rx_mon_status[grp_id]) { + ring_mask = ab->hw_params->ring_mask->rx_mon_status[grp_id]; + for (i = 0; i < ab->num_radios; i++) { + for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { + int id = i * ab->hw_params->num_rxdma_per_pdev + j; + + if (ring_mask & BIT(id)) { + work_done = + ath12k_dp_mon_process_ring(ab, id, napi, budget, + 0); + budget -= work_done; + tot_work_done += work_done; + if (budget <= 0) + goto done; + } + } + } + } + + if (ab->hw_params->ring_mask->rx_mon_dest[grp_id]) { + monitor_mode = ATH12K_DP_RX_MONITOR_MODE; + ring_mask = ab->hw_params->ring_mask->rx_mon_dest[grp_id]; + for (i = 0; i < ab->num_radios; i++) { + for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { + int id = i * ab->hw_params->num_rxdma_per_pdev + j; + + if (ring_mask & BIT(id)) { + work_done = + ath12k_dp_mon_process_ring(ab, id, napi, budget, + monitor_mode); + budget -= work_done; + tot_work_done += work_done; + + if (budget <= 0) + goto done; + } + } + } + } + + if (ab->hw_params->ring_mask->tx_mon_dest[grp_id]) { + monitor_mode = ATH12K_DP_TX_MONITOR_MODE; + ring_mask = ab->hw_params->ring_mask->tx_mon_dest[grp_id]; + for (i = 0; i < ab->num_radios; i++) { + for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { + int id = i * ab->hw_params->num_rxdma_per_pdev + j; + + if (ring_mask & BIT(id)) { + work_done = + ath12k_dp_mon_process_ring(ab, id, napi, budget, + monitor_mode); + budget -= work_done; + tot_work_done += work_done; + + if (budget <= 0) + goto done; + } + } + } + } + + if (ab->hw_params->ring_mask->reo_status[grp_id]) + ath12k_dp_rx_process_reo_status(ab); + + if (ab->hw_params->ring_mask->host2rxdma[grp_id]) { + struct ath12k_dp *dp = &ab->dp; + struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; + LIST_HEAD(list); + + ath12k_dp_rx_bufs_replenish(ab, rx_ring, &list, 0); + } + + /* TODO: Implement handler for other interrupts */ + +done: + return tot_work_done; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.h b/drivers/net/wireless/ath/ath12k/wifi7/dp.h new file mode 100644 index 0000000000000..17255a5671d73 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_DP_WIFI7_H +#define ATH12K_DP_WIFI7_H + +#include "hw.h" + +int ath12k_dp_service_srng(struct ath12k_base *ab, + struct ath12k_ext_irq_grp *irq_grp, + int budget); +#endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index b55cfb926571f..cbc51a9a2c42b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -1642,3 +1642,82 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) return ret; } EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_wcn7850); + +void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab) +{ + struct ath12k_dp *dp = &ab->dp; + struct hal_tlv_64_hdr *hdr; + struct hal_srng *srng; + struct ath12k_dp_rx_reo_cmd *cmd, *tmp; + bool found = false; + u16 tag; + struct hal_reo_status reo_status; + + srng = &ab->hal.srng_list[dp->reo_status_ring.ring_id]; + + memset(&reo_status, 0, sizeof(reo_status)); + + spin_lock_bh(&srng->lock); + + ath12k_hal_srng_access_begin(ab, srng); + + while ((hdr = ath12k_hal_srng_dst_get_next_entry(ab, srng))) { + tag = le64_get_bits(hdr->tl, HAL_SRNG_TLV_HDR_TAG); + + switch (tag) { + case HAL_REO_GET_QUEUE_STATS_STATUS: + ath12k_hal_reo_status_queue_stats(ab, hdr, + &reo_status); + break; + case HAL_REO_FLUSH_QUEUE_STATUS: + ath12k_hal_reo_flush_queue_status(ab, hdr, + &reo_status); + break; + case HAL_REO_FLUSH_CACHE_STATUS: + ath12k_hal_reo_flush_cache_status(ab, hdr, + &reo_status); + break; + case HAL_REO_UNBLOCK_CACHE_STATUS: + ath12k_hal_reo_unblk_cache_status(ab, hdr, + &reo_status); + break; + case HAL_REO_FLUSH_TIMEOUT_LIST_STATUS: + ath12k_hal_reo_flush_timeout_list_status(ab, hdr, + &reo_status); + break; + case HAL_REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS: + ath12k_hal_reo_desc_thresh_reached_status(ab, hdr, + &reo_status); + break; + case HAL_REO_UPDATE_RX_REO_QUEUE_STATUS: + ath12k_hal_reo_update_rx_reo_queue_status(ab, hdr, + &reo_status); + break; + default: + ath12k_warn(ab, "Unknown reo status type %d\n", tag); + continue; + } + + spin_lock_bh(&dp->reo_cmd_lock); + list_for_each_entry_safe(cmd, tmp, &dp->reo_cmd_list, list) { + if (reo_status.uniform_hdr.cmd_num == cmd->cmd_num) { + found = true; + list_del(&cmd->list); + break; + } + } + spin_unlock_bh(&dp->reo_cmd_lock); + + if (found) { + cmd->handler(dp, (void *)&cmd->data, + reo_status.uniform_hdr.cmd_status); + kfree(cmd); + } + + found = false; + } + + ath12k_hal_srng_access_end(ab, srng); + + spin_unlock_bh(&srng->lock); +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index fa44e454cee6c..63176a53c1e76 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -16,6 +16,7 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id, struct napi_struct *napi, int budget); +void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); #endif From b94abfc6d61b20ec501bddcaafa195799a1d1ffc Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:45 +0530 Subject: [PATCH 025/140] wifi: ath12k: Separate arch specific part of RX APIs Below API have architecture specific HAL macros. ath12k_dp_rx_peer_pn_replay_config Separate architecture specific parts from these APIs to later move them to wifi7 directory. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-13-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 58 ++++++++++++++----------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 8564b18c6a447..c89ff56f04a15 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -1058,6 +1058,36 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, return ret; } +static void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, + struct ath12k_dp_rx_tid *rx_tid, + u32 cipher, enum set_key_cmd key_cmd) +{ + cmd->flag = HAL_REO_CMD_FLG_NEED_STATUS; + cmd->upd0 = HAL_REO_CMD_UPD0_PN | + HAL_REO_CMD_UPD0_PN_SIZE | + HAL_REO_CMD_UPD0_PN_VALID | + HAL_REO_CMD_UPD0_PN_CHECK | + HAL_REO_CMD_UPD0_SVLD; + + switch (cipher) { + case WLAN_CIPHER_SUITE_TKIP: + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_CCMP_256: + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_GCMP_256: + if (key_cmd == SET_KEY) { + cmd->upd1 |= HAL_REO_CMD_UPD1_PN_CHECK; + cmd->pn_size = 48; + } + break; + default: + break; + } + + cmd->addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); + cmd->addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); +} + int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, const u8 *peer_addr, enum set_key_cmd key_cmd, @@ -1079,28 +1109,6 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) return 0; - cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; - cmd.upd0 = HAL_REO_CMD_UPD0_PN | - HAL_REO_CMD_UPD0_PN_SIZE | - HAL_REO_CMD_UPD0_PN_VALID | - HAL_REO_CMD_UPD0_PN_CHECK | - HAL_REO_CMD_UPD0_SVLD; - - switch (key->cipher) { - case WLAN_CIPHER_SUITE_TKIP: - case WLAN_CIPHER_SUITE_CCMP: - case WLAN_CIPHER_SUITE_CCMP_256: - case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: - if (key_cmd == SET_KEY) { - cmd.upd1 |= HAL_REO_CMD_UPD1_PN_CHECK; - cmd.pn_size = 48; - } - break; - default: - break; - } - spin_lock_bh(&ab->base_lock); peer = ath12k_peer_find(ab, arvif->vdev_id, peer_addr); @@ -1116,10 +1124,8 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, if (!rx_tid->active) continue; - ath12k_dp_init_rx_tid_rxq(&rx_tid_rxq, rx_tid); - cmd.addr_lo = lower_32_bits(rx_tid_rxq.qbuf.paddr_aligned); - cmd.addr_hi = upper_32_bits(rx_tid_rxq.qbuf.paddr_aligned); - ret = ath12k_dp_reo_cmd_send(ab, &rx_tid_rxq, + ath12k_dp_setup_pn_check_reo_cmd(&cmd, rx_tid, key->cipher, key_cmd); + ret = ath12k_dp_reo_cmd_send(ab, rx_tid, HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, NULL); if (ret) { From 05470ea655c57d8a217684c9c9b438dd7bb71693 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:46 +0530 Subject: [PATCH 026/140] wifi: ath12k: Move arch specific REO functions to wifi7 directory Move arch specific REO functions to wifi7 directory. The moved APIs will be a part of dp_rx.c file inside wifi7 directory. wifi7/dp_rx.c file will continue to be part of ath12k.ko temporarily until the corresponding infra for movement to ath12k_wifi7.ko arrives in upcoming patches. Architecture specific APIs: ath12k_dp_setup_pn_check_reo_cmd ath12k_dp_rx_assign_reoq Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-14-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 107 +----------------- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 80 +++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 6 + 3 files changed, 87 insertions(+), 106 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index c89ff56f04a15..e54ed22773e1f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -13,6 +13,7 @@ #include "wifi7/hal_desc.h" #include "hw.h" #include "dp_rx.h" +#include "wifi7/dp_rx.h" #include "wifi7/hal_rx.h" #include "dp_tx.h" #include "peer.h" @@ -790,82 +791,6 @@ static int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, return 0; } -static int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, - struct ath12k_sta *ahsta, - struct ath12k_dp_rx_tid *rx_tid, - u16 ssn, enum hal_pn_type pn_type) -{ - u32 ba_win_sz = rx_tid->ba_win_sz; - struct ath12k_reoq_buf *buf; - void *vaddr, *vaddr_aligned; - dma_addr_t paddr_aligned; - u8 tid = rx_tid->tid; - u32 hw_desc_sz; - int ret; - - buf = &ahsta->reoq_bufs[tid]; - if (!buf->vaddr) { - /* TODO: Optimize the memory allocation for qos tid based on - * the actual BA window size in REO tid update path. - */ - if (tid == HAL_DESC_REO_NON_QOS_TID) - hw_desc_sz = ath12k_hal_reo_qdesc_size(ba_win_sz, tid); - else - hw_desc_sz = ath12k_hal_reo_qdesc_size(DP_BA_WIN_SZ_MAX, tid); - - vaddr = kzalloc(hw_desc_sz + HAL_LINK_DESC_ALIGN - 1, GFP_ATOMIC); - if (!vaddr) - return -ENOMEM; - - vaddr_aligned = PTR_ALIGN(vaddr, HAL_LINK_DESC_ALIGN); - - ath12k_hal_reo_qdesc_setup(vaddr_aligned, tid, ba_win_sz, - ssn, pn_type); - - paddr_aligned = dma_map_single(ab->dev, vaddr_aligned, hw_desc_sz, - DMA_BIDIRECTIONAL); - ret = dma_mapping_error(ab->dev, paddr_aligned); - if (ret) { - kfree(vaddr); - return ret; - } - - buf->vaddr = vaddr; - buf->paddr_aligned = paddr_aligned; - buf->size = hw_desc_sz; - } - - rx_tid->qbuf = *buf; - rx_tid->active = true; - - return 0; -} - -static int ath12k_dp_prepare_reo_update_elem(struct ath12k_dp *dp, - struct ath12k_peer *peer, - struct ath12k_dp_rx_tid *rx_tid) -{ - struct dp_reo_update_rx_queue_elem *elem; - - lockdep_assert_held(&dp->ab->base_lock); - - elem = kzalloc(sizeof(*elem), GFP_ATOMIC); - if (!elem) - return -ENOMEM; - - elem->peer_id = peer->peer_id; - elem->is_ml_peer = peer->mlo; - elem->ml_peer_id = peer->ml_id; - - ath12k_dp_init_rx_tid_rxq(&elem->rx_tid, rx_tid); - - spin_lock_bh(&dp->reo_rxq_flush_lock); - list_add_tail(&elem->list, &dp->reo_cmd_update_rx_queue_list); - spin_unlock_bh(&dp->reo_rxq_flush_lock); - - return 0; -} - int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id, u8 tid, u32 ba_win_sz, u16 ssn, enum hal_pn_type pn_type) @@ -1058,36 +983,6 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, return ret; } -static void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, - struct ath12k_dp_rx_tid *rx_tid, - u32 cipher, enum set_key_cmd key_cmd) -{ - cmd->flag = HAL_REO_CMD_FLG_NEED_STATUS; - cmd->upd0 = HAL_REO_CMD_UPD0_PN | - HAL_REO_CMD_UPD0_PN_SIZE | - HAL_REO_CMD_UPD0_PN_VALID | - HAL_REO_CMD_UPD0_PN_CHECK | - HAL_REO_CMD_UPD0_SVLD; - - switch (cipher) { - case WLAN_CIPHER_SUITE_TKIP: - case WLAN_CIPHER_SUITE_CCMP: - case WLAN_CIPHER_SUITE_CCMP_256: - case WLAN_CIPHER_SUITE_GCMP: - case WLAN_CIPHER_SUITE_GCMP_256: - if (key_cmd == SET_KEY) { - cmd->upd1 |= HAL_REO_CMD_UPD1_PN_CHECK; - cmd->pn_size = 48; - } - break; - default: - break; - } - - cmd->addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); - cmd->addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); -} - int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, const u8 *peer_addr, enum set_key_cmd key_cmd, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index cbc51a9a2c42b..bcdfa19a2e5f4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -8,6 +8,56 @@ #include "../dp_tx.h" #include "../peer.h" +int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, + struct ath12k_dp_rx_tid *rx_tid, + u16 ssn, enum hal_pn_type pn_type) +{ + u32 ba_win_sz = rx_tid->ba_win_sz; + struct ath12k_reoq_buf *buf; + void *vaddr, *vaddr_aligned; + dma_addr_t paddr_aligned; + u8 tid = rx_tid->tid; + u32 hw_desc_sz; + int ret; + + buf = &ahsta->reoq_bufs[tid]; + if (!buf->vaddr) { + /* TODO: Optimize the memory allocation for qos tid based on + * the actual BA window size in REO tid update path. + */ + if (tid == HAL_DESC_REO_NON_QOS_TID) + hw_desc_sz = ath12k_hal_reo_qdesc_size(ba_win_sz, tid); + else + hw_desc_sz = ath12k_hal_reo_qdesc_size(DP_BA_WIN_SZ_MAX, tid); + + vaddr = kzalloc(hw_desc_sz + HAL_LINK_DESC_ALIGN - 1, GFP_ATOMIC); + if (!vaddr) + return -ENOMEM; + + vaddr_aligned = PTR_ALIGN(vaddr, HAL_LINK_DESC_ALIGN); + + ath12k_hal_reo_qdesc_setup(vaddr_aligned, tid, ba_win_sz, + ssn, pn_type); + + paddr_aligned = dma_map_single(ab->dev, vaddr_aligned, hw_desc_sz, + DMA_BIDIRECTIONAL); + ret = dma_mapping_error(ab->dev, paddr_aligned); + if (ret) { + kfree(vaddr); + return ret; + } + + buf->vaddr = vaddr; + buf->paddr_aligned = paddr_aligned; + buf->size = hw_desc_sz; + } + + rx_tid->qbuf = *buf; + rx_tid->active = true; + + return 0; +} + static void ath12k_dp_rx_h_csum_offload(struct sk_buff *msdu, struct ath12k_dp_rx_info *rx_info) { @@ -1354,6 +1404,36 @@ static void ath12k_dp_rx_wbm_err(struct ath12k *ar, ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info); } +void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, + struct ath12k_dp_rx_tid *rx_tid, + u32 cipher, enum set_key_cmd key_cmd) +{ + cmd->flag = HAL_REO_CMD_FLG_NEED_STATUS; + cmd->upd0 = HAL_REO_CMD_UPD0_PN | + HAL_REO_CMD_UPD0_PN_SIZE | + HAL_REO_CMD_UPD0_PN_VALID | + HAL_REO_CMD_UPD0_PN_CHECK | + HAL_REO_CMD_UPD0_SVLD; + + switch (cipher) { + case WLAN_CIPHER_SUITE_TKIP: + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_CCMP_256: + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_GCMP_256: + if (key_cmd == SET_KEY) { + cmd->upd1 |= HAL_REO_CMD_UPD1_PN_CHECK; + cmd->pn_size = 48; + } + break; + default: + break; + } + + cmd->addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); + cmd->addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); +} + int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, struct napi_struct *napi, int budget) { diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 63176a53c1e76..3589db00c9064 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -19,4 +19,10 @@ int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id, void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); +void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, + struct ath12k_dp_rx_tid *rx_tid, + u32 cipher, enum set_key_cmd key_cmd); +int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, + struct ath12k_dp_rx_tid *rx_tid, + u16 ssn, enum hal_pn_type pn_type); #endif From efdaea79259644ab7e4a9a8f941e2a9610a8ff53 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:47 +0530 Subject: [PATCH 027/140] wifi: ath12k: Move arch specific rx tid and related functions to wifi7 directory Move arch specific Rx tid related functions to wifi7 directory. The moved APIs will be a part of dp_rx.c file inside wifi7 directory. wifi7/dp_rx.c file will continue to be part of ath12k.ko temporarily until the corresponding infra for movement to ath12k_wifi7.ko arrives in upcoming patches. Architecture specific APIs: ath12k_peer_rx_tid_qref_reset ath12k_dp_reo_cache_flush ath12k_dp_reo_cmd_send ath12k_peer_rx_tid_reo_update ath12k_dp_rx_link_desc_return ath12k_dp_rx_peer_tid_delete ath12k_peer_rx_tid_qref_setup Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-15-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 270 +----------------- drivers/net/wireless/ath/ath12k/dp_rx.h | 7 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 240 ++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 19 ++ 4 files changed, 267 insertions(+), 269 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index e54ed22773e1f..a66900541f7c3 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -394,8 +394,8 @@ void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab) spin_unlock_bh(&dp->reo_cmd_lock); } -static void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx, - enum hal_reo_cmd_status status) +void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status) { struct ath12k_dp_rx_tid_rxq *rx_tid = ctx; @@ -406,138 +406,8 @@ static void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx, ath12k_dp_rx_tid_cleanup(dp->ab, &rx_tid->qbuf); } -static int ath12k_dp_reo_cmd_send(struct ath12k_base *ab, - struct ath12k_dp_rx_tid_rxq *rx_tid, - enum hal_reo_cmd_type type, - struct ath12k_hal_reo_cmd *cmd, - void (*cb)(struct ath12k_dp *dp, void *ctx, - enum hal_reo_cmd_status status)) -{ - struct ath12k_dp *dp = &ab->dp; - struct ath12k_dp_rx_reo_cmd *dp_cmd; - struct hal_srng *cmd_ring; - int cmd_num; - - cmd_ring = &ab->hal.srng_list[dp->reo_cmd_ring.ring_id]; - cmd_num = ath12k_hal_reo_cmd_send(ab, cmd_ring, type, cmd); - - /* cmd_num should start from 1, during failure return the error code */ - if (cmd_num < 0) - return cmd_num; - - /* reo cmd ring descriptors has cmd_num starting from 1 */ - if (cmd_num == 0) - return -EINVAL; - - if (!cb) - return 0; - - /* Can this be optimized so that we keep the pending command list only - * for tid delete command to free up the resource on the command status - * indication? - */ - dp_cmd = kzalloc(sizeof(*dp_cmd), GFP_ATOMIC); - - if (!dp_cmd) - return -ENOMEM; - - memcpy(&dp_cmd->data, rx_tid, sizeof(*rx_tid)); - dp_cmd->cmd_num = cmd_num; - dp_cmd->handler = cb; - - spin_lock_bh(&dp->reo_cmd_lock); - list_add_tail(&dp_cmd->list, &dp->reo_cmd_list); - spin_unlock_bh(&dp->reo_cmd_lock); - - return 0; -} - -static int ath12k_dp_reo_cache_flush(struct ath12k_base *ab, - struct ath12k_dp_rx_tid_rxq *rx_tid) -{ - struct ath12k_hal_reo_cmd cmd = {}; - int ret; - - cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); - cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); - /* HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS - all pending MPDUs - *in the bitmap will be forwarded/flushed to REO output rings - */ - cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS | - HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS; - - /* For all QoS TIDs (except NON_QOS), the driver allocates a maximum - * window size of 1024. In such cases, the driver can issue a single - * 1KB descriptor flush command instead of sending multiple 128-byte - * flush commands for each QoS TID, improving efficiency. - */ - - if (rx_tid->tid != HAL_DESC_REO_NON_QOS_TID) - cmd.flag |= HAL_REO_CMD_FLG_FLUSH_QUEUE_1K_DESC; - - ret = ath12k_dp_reo_cmd_send(ab, rx_tid, - HAL_REO_CMD_FLUSH_CACHE, - &cmd, ath12k_dp_reo_cmd_free); - return ret; -} - -static void ath12k_peer_rx_tid_qref_reset(struct ath12k_base *ab, u16 peer_id, u16 tid) -{ - struct ath12k_reo_queue_ref *qref; - struct ath12k_dp *dp = &ab->dp; - bool ml_peer = false; - - if (!ab->hw_params->reoq_lut_support) - return; - - if (peer_id & ATH12K_PEER_ML_ID_VALID) { - peer_id &= ~ATH12K_PEER_ML_ID_VALID; - ml_peer = true; - } - - if (ml_peer) - qref = (struct ath12k_reo_queue_ref *)dp->ml_reoq_lut.vaddr + - (peer_id * (IEEE80211_NUM_TIDS + 1) + tid); - else - qref = (struct ath12k_reo_queue_ref *)dp->reoq_lut.vaddr + - (peer_id * (IEEE80211_NUM_TIDS + 1) + tid); - - qref->info0 = u32_encode_bits(0, BUFFER_ADDR_INFO0_ADDR); - qref->info1 = u32_encode_bits(0, BUFFER_ADDR_INFO1_ADDR) | - u32_encode_bits(tid, DP_REO_QREF_NUM); -} - -static void ath12k_dp_rx_process_reo_cmd_update_rx_queue_list(struct ath12k_dp *dp) -{ - struct ath12k_base *ab = dp->ab; - struct dp_reo_update_rx_queue_elem *elem, *tmp; - - spin_lock_bh(&dp->reo_rxq_flush_lock); - - list_for_each_entry_safe(elem, tmp, &dp->reo_cmd_update_rx_queue_list, list) { - if (elem->rx_tid.active) - continue; - - if (ath12k_dp_rx_tid_delete_handler(ab, &elem->rx_tid)) - break; - - ath12k_peer_rx_tid_qref_reset(ab, - elem->is_ml_peer ? elem->ml_peer_id : - elem->peer_id, - elem->rx_tid.tid); - - if (ab->hw_params->reoq_lut_support) - ath12k_hal_reo_shared_qaddr_cache_clear(ab); - - list_del(&elem->list); - kfree(elem); - } - - spin_unlock_bh(&dp->reo_rxq_flush_lock); -} - -static void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx, - enum hal_reo_cmd_status status) +void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status) { struct ath12k_base *ab = dp->ab; struct ath12k_dp_rx_tid_rxq *rx_tid = ctx; @@ -616,101 +486,6 @@ static int ath12k_dp_rx_tid_delete_handler(struct ath12k_base *ab, ath12k_dp_rx_tid_del_func); } -static void ath12k_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, - dma_addr_t paddr) -{ - struct ath12k_reo_queue_ref *qref; - struct ath12k_dp *dp = &ab->dp; - bool ml_peer = false; - - if (!ab->hw_params->reoq_lut_support) - return; - - if (peer_id & ATH12K_PEER_ML_ID_VALID) { - peer_id &= ~ATH12K_PEER_ML_ID_VALID; - ml_peer = true; - } - - if (ml_peer) - qref = (struct ath12k_reo_queue_ref *)dp->ml_reoq_lut.vaddr + - (peer_id * (IEEE80211_NUM_TIDS + 1) + tid); - else - qref = (struct ath12k_reo_queue_ref *)dp->reoq_lut.vaddr + - (peer_id * (IEEE80211_NUM_TIDS + 1) + tid); - - qref->info0 = u32_encode_bits(lower_32_bits(paddr), - BUFFER_ADDR_INFO0_ADDR); - qref->info1 = u32_encode_bits(upper_32_bits(paddr), - BUFFER_ADDR_INFO1_ADDR) | - u32_encode_bits(tid, DP_REO_QREF_NUM); - ath12k_hal_reo_shared_qaddr_cache_clear(ab); -} - -static void ath12k_dp_mark_tid_as_inactive(struct ath12k_dp *dp, int peer_id, u8 tid) -{ - struct dp_reo_update_rx_queue_elem *elem; - struct ath12k_dp_rx_tid_rxq *rx_tid; - - spin_lock_bh(&dp->reo_rxq_flush_lock); - list_for_each_entry(elem, &dp->reo_cmd_update_rx_queue_list, list) { - if (elem->peer_id == peer_id) { - rx_tid = &elem->rx_tid; - if (rx_tid->tid == tid) { - rx_tid->active = false; - break; - } - } - } - spin_unlock_bh(&dp->reo_rxq_flush_lock); -} - -void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar, - struct ath12k_peer *peer, u8 tid) -{ - struct ath12k_dp_rx_tid *rx_tid = &peer->rx_tid[tid]; - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; - - if (!rx_tid->active) - return; - - rx_tid->active = false; - - ath12k_dp_mark_tid_as_inactive(dp, peer->peer_id, tid); - ath12k_dp_rx_process_reo_cmd_update_rx_queue_list(dp); -} - -int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, - struct ath12k_buffer_addr *buf_addr_info, - enum hal_wbm_rel_bm_act action) -{ - struct hal_wbm_release_ring *desc; - struct ath12k_dp *dp = &ab->dp; - struct hal_srng *srng; - int ret = 0; - - srng = &ab->hal.srng_list[dp->wbm_desc_rel_ring.ring_id]; - - spin_lock_bh(&srng->lock); - - ath12k_hal_srng_access_begin(ab, srng); - - desc = ath12k_hal_srng_src_get_next_entry(ab, srng); - if (!desc) { - ret = -ENOBUFS; - goto exit; - } - - ath12k_hal_rx_msdu_link_desc_set(ab, desc, buf_addr_info, action); - -exit: - ath12k_hal_srng_access_end(ab, srng); - - spin_unlock_bh(&srng->lock); - - return ret; -} - void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, bool rel_link_desc) { @@ -754,43 +529,6 @@ void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_peer *peer) } } -static int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, - struct ath12k_peer *peer, - struct ath12k_dp_rx_tid *rx_tid, - u32 ba_win_sz, u16 ssn, - bool update_ssn) -{ - struct ath12k_hal_reo_cmd cmd = {}; - int ret; - struct ath12k_dp_rx_tid_rxq rx_tid_rxq; - - ath12k_dp_init_rx_tid_rxq(&rx_tid_rxq, rx_tid); - - cmd.addr_lo = lower_32_bits(rx_tid_rxq.qbuf.paddr_aligned); - cmd.addr_hi = upper_32_bits(rx_tid_rxq.qbuf.paddr_aligned); - cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; - cmd.upd0 = HAL_REO_CMD_UPD0_BA_WINDOW_SIZE; - cmd.ba_window_size = ba_win_sz; - - if (update_ssn) { - cmd.upd0 |= HAL_REO_CMD_UPD0_SSN; - cmd.upd2 = u32_encode_bits(ssn, HAL_REO_CMD_UPD2_SSN); - } - - ret = ath12k_dp_reo_cmd_send(ar->ab, &rx_tid_rxq, - HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, - NULL); - if (ret) { - ath12k_warn(ar->ab, "failed to update rx tid queue, tid %d (%d)\n", - rx_tid_rxq.tid, ret); - return ret; - } - - rx_tid->ba_win_sz = ba_win_sz; - - return 0; -} - int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id, u8 tid, u32 ba_win_sz, u16 ssn, enum hal_pn_type pn_type) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index c1efc8c658db0..fc1c4ac161c1a 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -436,12 +436,13 @@ u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); -int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, - struct ath12k_buffer_addr *buf_addr_info, - enum hal_wbm_rel_bm_act action); bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info); struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, struct sk_buff *first); +void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status); +void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status); #endif /* ATH12K_DP_RX_H */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index bcdfa19a2e5f4..d95e3c4daa5d5 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -8,6 +8,246 @@ #include "../dp_tx.h" #include "../peer.h" +void ath12k_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, + dma_addr_t paddr) +{ + struct ath12k_reo_queue_ref *qref; + struct ath12k_dp *dp = &ab->dp; + bool ml_peer = false; + + if (!ab->hw_params->reoq_lut_support) + return; + + if (peer_id & ATH12K_PEER_ML_ID_VALID) { + peer_id &= ~ATH12K_PEER_ML_ID_VALID; + ml_peer = true; + } + + if (ml_peer) + qref = (struct ath12k_reo_queue_ref *)dp->ml_reoq_lut.vaddr + + (peer_id * (IEEE80211_NUM_TIDS + 1) + tid); + else + qref = (struct ath12k_reo_queue_ref *)dp->reoq_lut.vaddr + + (peer_id * (IEEE80211_NUM_TIDS + 1) + tid); + + qref->info0 = u32_encode_bits(lower_32_bits(paddr), + BUFFER_ADDR_INFO0_ADDR); + qref->info1 = u32_encode_bits(upper_32_bits(paddr), + BUFFER_ADDR_INFO1_ADDR) | + u32_encode_bits(tid, DP_REO_QREF_NUM); + ath12k_hal_reo_shared_qaddr_cache_clear(ab); +} + +static void ath12k_peer_rx_tid_qref_reset(struct ath12k_base *ab, u16 peer_id, u16 tid) +{ + struct ath12k_reo_queue_ref *qref; + struct ath12k_dp *dp = &ab->dp; + bool ml_peer = false; + + if (!ab->hw_params->reoq_lut_support) + return; + + if (peer_id & ATH12K_PEER_ML_ID_VALID) { + peer_id &= ~ATH12K_PEER_ML_ID_VALID; + ml_peer = true; + } + + if (ml_peer) + qref = (struct ath12k_reo_queue_ref *)dp->ml_reoq_lut.vaddr + + (peer_id * (IEEE80211_NUM_TIDS + 1) + tid); + else + qref = (struct ath12k_reo_queue_ref *)dp->reoq_lut.vaddr + + (peer_id * (IEEE80211_NUM_TIDS + 1) + tid); + + qref->info0 = u32_encode_bits(0, BUFFER_ADDR_INFO0_ADDR); + qref->info1 = u32_encode_bits(0, BUFFER_ADDR_INFO1_ADDR) | + u32_encode_bits(tid, DP_REO_QREF_NUM); +} + +void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar, + struct ath12k_peer *peer, u8 tid) +{ + struct ath12k_hal_reo_cmd cmd = {}; + struct ath12k_dp_rx_tid *rx_tid = &peer->rx_tid[tid]; + int ret; + + if (!rx_tid->active) + return; + + cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; + cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); + cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); + cmd.upd0 = HAL_REO_CMD_UPD0_VLD; + ret = ath12k_dp_reo_cmd_send(ar->ab, rx_tid, + HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, + ath12k_dp_rx_tid_del_func); + if (ret) { + ath12k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n", + tid, ret); + dma_unmap_single(ar->ab->dev, rx_tid->qbuf.paddr_aligned, + rx_tid->qbuf.size, DMA_BIDIRECTIONAL); + kfree(rx_tid->qbuf.vaddr); + rx_tid->qbuf.vaddr = NULL; + } + + if (peer->mlo) + ath12k_peer_rx_tid_qref_reset(ar->ab, peer->ml_id, tid); + else + ath12k_peer_rx_tid_qref_reset(ar->ab, peer->peer_id, tid); + + rx_tid->active = false; +} + +int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, + struct ath12k_buffer_addr *buf_addr_info, + enum hal_wbm_rel_bm_act action) +{ + struct hal_wbm_release_ring *desc; + struct ath12k_dp *dp = &ab->dp; + struct hal_srng *srng; + int ret = 0; + + srng = &ab->hal.srng_list[dp->wbm_desc_rel_ring.ring_id]; + + spin_lock_bh(&srng->lock); + + ath12k_hal_srng_access_begin(ab, srng); + + desc = ath12k_hal_srng_src_get_next_entry(ab, srng); + if (!desc) { + ret = -ENOBUFS; + goto exit; + } + + ath12k_hal_rx_msdu_link_desc_set(ab, desc, buf_addr_info, action); + +exit: + ath12k_hal_srng_access_end(ab, srng); + + spin_unlock_bh(&srng->lock); + + return ret; +} + +int ath12k_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid, + enum hal_reo_cmd_type type, + struct ath12k_hal_reo_cmd *cmd, + void (*cb)(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status)) +{ + struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp_rx_reo_cmd *dp_cmd; + struct hal_srng *cmd_ring; + int cmd_num; + + cmd_ring = &ab->hal.srng_list[dp->reo_cmd_ring.ring_id]; + cmd_num = ath12k_hal_reo_cmd_send(ab, cmd_ring, type, cmd); + + /* cmd_num should start from 1, during failure return the error code */ + if (cmd_num < 0) + return cmd_num; + + /* reo cmd ring descriptors has cmd_num starting from 1 */ + if (cmd_num == 0) + return -EINVAL; + + if (!cb) + return 0; + + /* Can this be optimized so that we keep the pending command list only + * for tid delete command to free up the resource on the command status + * indication? + */ + dp_cmd = kzalloc(sizeof(*dp_cmd), GFP_ATOMIC); + + if (!dp_cmd) + return -ENOMEM; + + memcpy(&dp_cmd->data, rx_tid, sizeof(*rx_tid)); + dp_cmd->cmd_num = cmd_num; + dp_cmd->handler = cb; + + spin_lock_bh(&dp->reo_cmd_lock); + list_add_tail(&dp_cmd->list, &dp->reo_cmd_list); + spin_unlock_bh(&dp->reo_cmd_lock); + + return 0; +} + +int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, + struct ath12k_peer *peer, + struct ath12k_dp_rx_tid *rx_tid, + u32 ba_win_sz, u16 ssn, + bool update_ssn) +{ + struct ath12k_hal_reo_cmd cmd = {}; + int ret; + + cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); + cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); + cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; + cmd.upd0 = HAL_REO_CMD_UPD0_BA_WINDOW_SIZE; + cmd.ba_window_size = ba_win_sz; + + if (update_ssn) { + cmd.upd0 |= HAL_REO_CMD_UPD0_SSN; + cmd.upd2 = u32_encode_bits(ssn, HAL_REO_CMD_UPD2_SSN); + } + + ret = ath12k_dp_reo_cmd_send(ar->ab, rx_tid, + HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, + NULL); + if (ret) { + ath12k_warn(ar->ab, "failed to update rx tid queue, tid %d (%d)\n", + rx_tid->tid, ret); + return ret; + } + + rx_tid->ba_win_sz = ba_win_sz; + + return 0; +} + +void ath12k_dp_reo_cache_flush(struct ath12k_base *ab, + struct ath12k_dp_rx_tid *rx_tid) +{ + struct ath12k_hal_reo_cmd cmd = {}; + unsigned long tot_desc_sz, desc_sz; + int ret; + + tot_desc_sz = rx_tid->qbuf.size; + desc_sz = ath12k_hal_reo_qdesc_size(0, HAL_DESC_REO_NON_QOS_TID); + + while (tot_desc_sz > desc_sz) { + tot_desc_sz -= desc_sz; + cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned + tot_desc_sz); + cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); + ret = ath12k_dp_reo_cmd_send(ab, rx_tid, + HAL_REO_CMD_FLUSH_CACHE, &cmd, + NULL); + if (ret) + ath12k_warn(ab, + "failed to send HAL_REO_CMD_FLUSH_CACHE, tid %d (%d)\n", + rx_tid->tid, ret); + } + + memset(&cmd, 0, sizeof(cmd)); + cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); + cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); + cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; + ret = ath12k_dp_reo_cmd_send(ab, rx_tid, + HAL_REO_CMD_FLUSH_CACHE, + &cmd, ath12k_dp_reo_cmd_free); + if (ret) { + ath12k_err(ab, "failed to send HAL_REO_CMD_FLUSH_CACHE cmd, tid %d (%d)\n", + rx_tid->tid, ret); + dma_unmap_single(ab->dev, rx_tid->qbuf.paddr_aligned, rx_tid->qbuf.size, + DMA_BIDIRECTIONAL); + kfree(rx_tid->qbuf.vaddr); + rx_tid->qbuf.vaddr = NULL; + } +} + int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, struct ath12k_dp_rx_tid *rx_tid, u16 ssn, enum hal_pn_type pn_type) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 3589db00c9064..45b856aaaa124 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -25,4 +25,23 @@ void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, struct ath12k_dp_rx_tid *rx_tid, u16 ssn, enum hal_pn_type pn_type); +int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, + struct ath12k_buffer_addr *buf_addr_info, + enum hal_wbm_rel_bm_act action); +void ath12k_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, + dma_addr_t paddr); +void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar, + struct ath12k_peer *peer, u8 tid); +int ath12k_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid, + enum hal_reo_cmd_type type, + struct ath12k_hal_reo_cmd *cmd, + void (*cb)(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status)); +void ath12k_dp_reo_cache_flush(struct ath12k_base *ab, + struct ath12k_dp_rx_tid *rx_tid); +int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, + struct ath12k_peer *peer, + struct ath12k_dp_rx_tid *rx_tid, + u32 ba_win_sz, u16 ssn, + bool update_ssn); #endif From 4a9d15cdb5b70a73c7817482e0ae4a7452f61551 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:48 +0530 Subject: [PATCH 028/140] wifi: ath12k: Move arch specific tx APIs to wifi7 directory Move arch specific TX data path to wifi7 directory as part of Next Generation (NG) Driver Framework. Architecture specific APIs: ath12k_dp_tx_htt_tx_complete_buf ath12k_dp_tx_process_htt_tx_complete ath12k_dp_tx_update_txcompl ath12k_dp_tx_complete_msdu ath12k_dp_tx_status_parse ath12k_dp_tx_completion_handler The moved APIs will be a part of dp_tx.c file inside wifi7 directory. wifi7/dp_tx.c file will continue to be part of ath12k.ko temporarily until the corresponding infra for movement to ath12k_wifi7.ko arrives in upcoming patches. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-16-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/dp_tx.c | 564 +----------------- drivers/net/wireless/ath/ath12k/dp_tx.h | 18 +- drivers/net/wireless/ath/ath12k/mac.c | 1 + drivers/net/wireless/ath/ath12k/wifi7/dp.c | 1 + drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 545 +++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h | 11 + 7 files changed, 590 insertions(+), 551 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index ed1f1dba3d3b9..e72b52d5af6d6 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -25,6 +25,7 @@ ath12k-$(CONFIG_ATH12K_AHB) += ahb.o ath12k-y += wifi7/hal_tx.o \ wifi7/hal_rx.o \ wifi7/dp_rx.o \ + wifi7/dp_tx.o \ wifi7/dp.o obj-$(CONFIG_ATH12K) += wifi7/ diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c index abc84ca8467a2..f1649744c78b7 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/dp_tx.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 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. */ #include "core.h" @@ -12,7 +12,7 @@ #include "peer.h" #include "mac.h" -static enum hal_tcl_encap_type +enum hal_tcl_encap_type ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb) { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); @@ -26,7 +26,7 @@ ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb) return HAL_TCL_ENCAP_TYPE_NATIVE_WIFI; } -static void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb) +void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb) { struct ieee80211_hdr *hdr = (void *)skb->data; u8 *qos_ctl; @@ -43,7 +43,7 @@ static void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb) hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA); } -static u8 ath12k_dp_tx_get_tid(struct sk_buff *skb) +u8 ath12k_dp_tx_get_tid(struct sk_buff *skb) { struct ieee80211_hdr *hdr = (void *)skb->data; struct ath12k_skb_cb *cb = ATH12K_SKB_CB(skb); @@ -78,9 +78,9 @@ enum hal_encrypt_type ath12k_dp_tx_get_encrypt_type(u32 cipher) } } -static void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp, - struct ath12k_tx_desc_info *tx_desc, - u8 pool_id) +void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp, + struct ath12k_tx_desc_info *tx_desc, + u8 pool_id) { spin_lock_bh(&dp->tx_desc_lock[pool_id]); tx_desc->skb_ext_desc = NULL; @@ -88,8 +88,8 @@ static void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp, spin_unlock_bh(&dp->tx_desc_lock[pool_id]); } -static struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp, - u8 pool_id) +struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp, + u8 pool_id) { struct ath12k_tx_desc_info *desc; @@ -129,7 +129,7 @@ static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, #define HTT_META_DATA_ALIGNMENT 0x8 -static void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len) +void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len) { struct sk_buff *tail; void *metadata; @@ -182,8 +182,8 @@ static void ath12k_dp_tx_move_payload(struct sk_buff *skb, } } -static int ath12k_dp_tx_align_payload(struct ath12k_base *ab, - struct sk_buff **pskb) +int ath12k_dp_tx_align_payload(struct ath12k_base *ab, + struct sk_buff **pskb) { u32 iova_mask = ab->hw_params->iova_mask; unsigned long offset, delta1, delta2; @@ -539,9 +539,9 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, return ret; } -static void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, - struct dp_tx_ring *tx_ring, - struct ath12k_tx_desc_params *desc_params) +void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, + struct dp_tx_ring *tx_ring, + struct ath12k_tx_desc_params *desc_params) { struct ath12k *ar; struct sk_buff *msdu = desc_params->skb; @@ -564,540 +564,6 @@ static void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, wake_up(&ar->dp.tx_empty_waitq); } -static void -ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, - struct ath12k_tx_desc_params *desc_params, - struct dp_tx_ring *tx_ring, - struct ath12k_dp_htt_wbm_tx_status *ts, - u16 peer_id) -{ - struct ieee80211_tx_info *info; - struct ath12k_link_vif *arvif; - struct ath12k_skb_cb *skb_cb; - struct ieee80211_vif *vif; - struct ath12k_vif *ahvif; - struct ath12k *ar; - struct sk_buff *msdu = desc_params->skb; - s32 noise_floor; - struct ieee80211_tx_status status = {}; - struct ath12k_peer *peer; - - skb_cb = ATH12K_SKB_CB(msdu); - info = IEEE80211_SKB_CB(msdu); - - ar = skb_cb->ar; - ab->device_stats.tx_completed[tx_ring->tcl_data_ring_id]++; - - if (atomic_dec_and_test(&ar->dp.num_tx_pending)) - wake_up(&ar->dp.tx_empty_waitq); - - dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); - if (skb_cb->paddr_ext_desc) { - dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, - desc_params->skb_ext_desc->len, DMA_TO_DEVICE); - dev_kfree_skb_any(desc_params->skb_ext_desc); - } - - vif = skb_cb->vif; - if (vif) { - ahvif = ath12k_vif_to_ahvif(vif); - rcu_read_lock(); - arvif = rcu_dereference(ahvif->link[skb_cb->link_id]); - if (arvif) { - spin_lock_bh(&arvif->link_stats_lock); - arvif->link_stats.tx_completed++; - spin_unlock_bh(&arvif->link_stats_lock); - } - rcu_read_unlock(); - } - - memset(&info->status, 0, sizeof(info->status)); - - if (ts->acked) { - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { - info->flags |= IEEE80211_TX_STAT_ACK; - info->status.ack_signal = ts->ack_rssi; - - if (!test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, - ab->wmi_ab.svc_map)) { - spin_lock_bh(&ar->data_lock); - noise_floor = ath12k_pdev_get_noise_floor(ar); - spin_unlock_bh(&ar->data_lock); - - info->status.ack_signal += noise_floor; - } - - info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID; - } else { - info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; - } - } - rcu_read_lock(); - spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); - if (!peer || !peer->sta) { - ath12k_dbg(ab, ATH12K_DBG_DATA, - "dp_tx: failed to find the peer with peer_id %d\n", peer_id); - spin_unlock_bh(&ab->base_lock); - ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu); - goto exit; - } else { - status.sta = peer->sta; - } - spin_unlock_bh(&ab->base_lock); - - status.info = info; - status.skb = msdu; - ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status); -exit: - rcu_read_unlock(); -} - -static void -ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc, - struct dp_tx_ring *tx_ring, - struct ath12k_tx_desc_params *desc_params) -{ - struct htt_tx_wbm_completion *status_desc; - struct ath12k_dp_htt_wbm_tx_status ts = {}; - enum hal_wbm_htt_tx_comp_status wbm_status; - u16 peer_id; - - status_desc = desc; - - wbm_status = le32_get_bits(status_desc->info0, - HTT_TX_WBM_COMP_INFO0_STATUS); - ab->device_stats.fw_tx_status[wbm_status]++; - - switch (wbm_status) { - case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK: - ts.acked = (wbm_status == HAL_WBM_REL_HTT_TX_COMP_STATUS_OK); - ts.ack_rssi = le32_get_bits(status_desc->info2, - HTT_TX_WBM_COMP_INFO2_ACK_RSSI); - - peer_id = le32_get_bits(((struct hal_wbm_completion_ring_tx *)desc)-> - info3, HAL_WBM_COMPL_TX_INFO3_PEER_ID); - - ath12k_dp_tx_htt_tx_complete_buf(ab, desc_params, tx_ring, &ts, peer_id); - break; - case HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP: - case HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL: - case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ: - case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT: - case HAL_WBM_REL_HTT_TX_COMP_STATUS_VDEVID_MISMATCH: - ath12k_dp_tx_free_txbuf(ab, tx_ring, desc_params); - break; - case HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY: - /* This event is to be handled only when the driver decides to - * use WDS offload functionality. - */ - break; - default: - ath12k_warn(ab, "Unknown htt wbm tx status %d\n", wbm_status); - break; - } -} - -static void ath12k_dp_tx_update_txcompl(struct ath12k *ar, struct hal_tx_status *ts) -{ - struct ath12k_base *ab = ar->ab; - struct ath12k_peer *peer; - struct ieee80211_sta *sta; - struct ath12k_sta *ahsta; - struct ath12k_link_sta *arsta; - struct rate_info txrate = {}; - u16 rate, ru_tones; - u8 rate_idx = 0; - int ret; - - spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, ts->peer_id); - if (!peer || !peer->sta) { - ath12k_dbg(ab, ATH12K_DBG_DP_TX, - "failed to find the peer by id %u\n", ts->peer_id); - spin_unlock_bh(&ab->base_lock); - return; - } - sta = peer->sta; - ahsta = ath12k_sta_to_ahsta(sta); - arsta = &ahsta->deflink; - - /* This is to prefer choose the real NSS value arsta->last_txrate.nss, - * if it is invalid, then choose the NSS value while assoc. - */ - if (arsta->last_txrate.nss) - txrate.nss = arsta->last_txrate.nss; - else - txrate.nss = arsta->peer_nss; - spin_unlock_bh(&ab->base_lock); - - switch (ts->pkt_type) { - case HAL_TX_RATE_STATS_PKT_TYPE_11A: - case HAL_TX_RATE_STATS_PKT_TYPE_11B: - ret = ath12k_mac_hw_ratecode_to_legacy_rate(ts->mcs, - ts->pkt_type, - &rate_idx, - &rate); - if (ret < 0) { - ath12k_warn(ab, "Invalid tx legacy rate %d\n", ret); - return; - } - - txrate.legacy = rate; - break; - case HAL_TX_RATE_STATS_PKT_TYPE_11N: - if (ts->mcs > ATH12K_HT_MCS_MAX) { - ath12k_warn(ab, "Invalid HT mcs index %d\n", ts->mcs); - return; - } - - if (txrate.nss != 0) - txrate.mcs = ts->mcs + 8 * (txrate.nss - 1); - - txrate.flags = RATE_INFO_FLAGS_MCS; - - if (ts->sgi) - txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; - break; - case HAL_TX_RATE_STATS_PKT_TYPE_11AC: - if (ts->mcs > ATH12K_VHT_MCS_MAX) { - ath12k_warn(ab, "Invalid VHT mcs index %d\n", ts->mcs); - return; - } - - txrate.mcs = ts->mcs; - txrate.flags = RATE_INFO_FLAGS_VHT_MCS; - - if (ts->sgi) - txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; - break; - case HAL_TX_RATE_STATS_PKT_TYPE_11AX: - if (ts->mcs > ATH12K_HE_MCS_MAX) { - ath12k_warn(ab, "Invalid HE mcs index %d\n", ts->mcs); - return; - } - - txrate.mcs = ts->mcs; - txrate.flags = RATE_INFO_FLAGS_HE_MCS; - txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(ts->sgi); - break; - case HAL_TX_RATE_STATS_PKT_TYPE_11BE: - if (ts->mcs > ATH12K_EHT_MCS_MAX) { - ath12k_warn(ab, "Invalid EHT mcs index %d\n", ts->mcs); - return; - } - - txrate.mcs = ts->mcs; - txrate.flags = RATE_INFO_FLAGS_EHT_MCS; - txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(ts->sgi); - break; - default: - ath12k_warn(ab, "Invalid tx pkt type: %d\n", ts->pkt_type); - return; - } - - txrate.bw = ath12k_mac_bw_to_mac80211_bw(ts->bw); - - if (ts->ofdma && ts->pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11AX) { - txrate.bw = RATE_INFO_BW_HE_RU; - ru_tones = ath12k_mac_he_convert_tones_to_ru_tones(ts->tones); - txrate.he_ru_alloc = - ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones); - } - - if (ts->ofdma && ts->pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11BE) { - txrate.bw = RATE_INFO_BW_EHT_RU; - txrate.eht_ru_alloc = - ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(ts->tones); - } - - spin_lock_bh(&ab->base_lock); - arsta->txrate = txrate; - spin_unlock_bh(&ab->base_lock); -} - -static void ath12k_dp_tx_complete_msdu(struct ath12k *ar, - struct ath12k_tx_desc_params *desc_params, - struct hal_tx_status *ts, - int ring) -{ - struct ath12k_base *ab = ar->ab; - struct ath12k_hw *ah = ar->ah; - struct ieee80211_tx_info *info; - struct ath12k_link_vif *arvif; - struct ath12k_skb_cb *skb_cb; - struct ieee80211_vif *vif; - struct ath12k_vif *ahvif; - struct sk_buff *msdu = desc_params->skb; - s32 noise_floor; - struct ieee80211_tx_status status = {}; - struct ieee80211_rate_status status_rate = {}; - struct ath12k_peer *peer; - struct ath12k_link_sta *arsta; - struct ath12k_sta *ahsta; - struct rate_info rate; - - if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) { - /* Must not happen */ - return; - } - - skb_cb = ATH12K_SKB_CB(msdu); - ab->device_stats.tx_completed[ring]++; - - dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); - if (skb_cb->paddr_ext_desc) { - dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, - desc_params->skb_ext_desc->len, DMA_TO_DEVICE); - dev_kfree_skb_any(desc_params->skb_ext_desc); - } - - rcu_read_lock(); - - if (!rcu_dereference(ab->pdevs_active[ar->pdev_idx])) { - ieee80211_free_txskb(ah->hw, msdu); - goto exit; - } - - if (!skb_cb->vif) { - ieee80211_free_txskb(ah->hw, msdu); - goto exit; - } - - vif = skb_cb->vif; - if (vif) { - ahvif = ath12k_vif_to_ahvif(vif); - arvif = rcu_dereference(ahvif->link[skb_cb->link_id]); - if (arvif) { - spin_lock_bh(&arvif->link_stats_lock); - arvif->link_stats.tx_completed++; - spin_unlock_bh(&arvif->link_stats_lock); - } - } - - info = IEEE80211_SKB_CB(msdu); - memset(&info->status, 0, sizeof(info->status)); - - /* skip tx rate update from ieee80211_status*/ - info->status.rates[0].idx = -1; - - switch (ts->status) { - case HAL_WBM_TQM_REL_REASON_FRAME_ACKED: - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { - info->flags |= IEEE80211_TX_STAT_ACK; - info->status.ack_signal = ts->ack_rssi; - - if (!test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, - ab->wmi_ab.svc_map)) { - spin_lock_bh(&ar->data_lock); - noise_floor = ath12k_pdev_get_noise_floor(ar); - spin_unlock_bh(&ar->data_lock); - - info->status.ack_signal += noise_floor; - } - - info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID; - } - break; - case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_TX: - if (info->flags & IEEE80211_TX_CTL_NO_ACK) { - info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; - break; - } - fallthrough; - case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_MPDU: - case HAL_WBM_TQM_REL_REASON_DROP_THRESHOLD: - case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_AGED_FRAMES: - /* The failure status is due to internal firmware tx failure - * hence drop the frame; do not update the status of frame to - * the upper layer - */ - ieee80211_free_txskb(ah->hw, msdu); - goto exit; - default: - ath12k_dbg(ab, ATH12K_DBG_DP_TX, "tx frame is not acked status %d\n", - ts->status); - break; - } - - /* NOTE: Tx rate status reporting. Tx completion status does not have - * necessary information (for example nss) to build the tx rate. - * Might end up reporting it out-of-band from HTT stats. - */ - - ath12k_dp_tx_update_txcompl(ar, ts); - - spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, ts->peer_id); - if (!peer || !peer->sta) { - ath12k_err(ab, - "dp_tx: failed to find the peer with peer_id %d\n", - ts->peer_id); - spin_unlock_bh(&ab->base_lock); - ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu); - goto exit; - } - ahsta = ath12k_sta_to_ahsta(peer->sta); - arsta = &ahsta->deflink; - - spin_unlock_bh(&ab->base_lock); - - status.sta = peer->sta; - status.info = info; - status.skb = msdu; - rate = arsta->last_txrate; - - status_rate.rate_idx = rate; - status_rate.try_count = 1; - - status.rates = &status_rate; - status.n_rates = 1; - ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status); - -exit: - rcu_read_unlock(); -} - -static void ath12k_dp_tx_status_parse(struct ath12k_base *ab, - struct hal_wbm_completion_ring_tx *desc, - struct hal_tx_status *ts) -{ - u32 info0 = le32_to_cpu(desc->rate_stats.info0); - - ts->buf_rel_source = - le32_get_bits(desc->info0, HAL_WBM_COMPL_TX_INFO0_REL_SRC_MODULE); - if (ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_FW && - ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM) - return; - - if (ts->buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW) - return; - - ts->status = le32_get_bits(desc->info0, - HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON); - - ts->ppdu_id = le32_get_bits(desc->info1, - HAL_WBM_COMPL_TX_INFO1_TQM_STATUS_NUMBER); - - ts->peer_id = le32_get_bits(desc->info3, HAL_WBM_COMPL_TX_INFO3_PEER_ID); - - ts->ack_rssi = le32_get_bits(desc->info2, - HAL_WBM_COMPL_TX_INFO2_ACK_FRAME_RSSI); - - if (info0 & HAL_TX_RATE_STATS_INFO0_VALID) { - ts->pkt_type = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_PKT_TYPE); - ts->mcs = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_MCS); - ts->sgi = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_SGI); - ts->bw = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_BW); - ts->tones = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_TONES_IN_RU); - ts->ofdma = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_OFDMA_TX); - } -} - -void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) -{ - struct ath12k *ar; - struct ath12k_dp *dp = &ab->dp; - int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id; - struct hal_srng *status_ring = &ab->hal.srng_list[hal_ring_id]; - struct ath12k_tx_desc_info *tx_desc = NULL; - struct hal_tx_status ts = {}; - struct ath12k_tx_desc_params desc_params; - struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id]; - struct hal_wbm_release_ring *desc; - u8 pdev_id; - u64 desc_va; - enum hal_wbm_rel_src_module buf_rel_source; - enum hal_wbm_tqm_rel_reason rel_status; - - spin_lock_bh(&status_ring->lock); - - ath12k_hal_srng_access_begin(ab, status_ring); - - while (ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_head) != - tx_ring->tx_status_tail) { - desc = ath12k_hal_srng_dst_get_next_entry(ab, status_ring); - if (!desc) - break; - - memcpy(&tx_ring->tx_status[tx_ring->tx_status_head], - desc, sizeof(*desc)); - tx_ring->tx_status_head = - ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_head); - } - - if (ath12k_hal_srng_dst_peek(ab, status_ring) && - (ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_head) == - tx_ring->tx_status_tail)) { - /* TODO: Process pending tx_status messages when kfifo_is_full() */ - ath12k_warn(ab, "Unable to process some of the tx_status ring desc because status_fifo is full\n"); - } - - ath12k_hal_srng_access_end(ab, status_ring); - - spin_unlock_bh(&status_ring->lock); - - while (ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_tail) != - tx_ring->tx_status_head) { - struct hal_wbm_completion_ring_tx *tx_status; - u32 desc_id; - - tx_ring->tx_status_tail = - ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_tail); - tx_status = &tx_ring->tx_status[tx_ring->tx_status_tail]; - ath12k_dp_tx_status_parse(ab, tx_status, &ts); - - if (le32_get_bits(tx_status->info0, HAL_WBM_COMPL_TX_INFO0_CC_DONE)) { - /* HW done cookie conversion */ - desc_va = ((u64)le32_to_cpu(tx_status->buf_va_hi) << 32 | - le32_to_cpu(tx_status->buf_va_lo)); - tx_desc = (struct ath12k_tx_desc_info *)((unsigned long)desc_va); - } else { - /* SW does cookie conversion to VA */ - desc_id = le32_get_bits(tx_status->buf_va_hi, - BUFFER_ADDR_INFO1_SW_COOKIE); - - tx_desc = ath12k_dp_get_tx_desc(ab, desc_id); - } - if (!tx_desc) { - ath12k_warn(ab, "unable to retrieve tx_desc!"); - continue; - } - - desc_params.mac_id = tx_desc->mac_id; - desc_params.skb = tx_desc->skb; - desc_params.skb_ext_desc = tx_desc->skb_ext_desc; - - /* Find the HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE value */ - buf_rel_source = le32_get_bits(tx_status->info0, - HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE); - ab->device_stats.tx_wbm_rel_source[buf_rel_source]++; - - rel_status = le32_get_bits(tx_status->info0, - HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON); - ab->device_stats.tqm_rel_reason[rel_status]++; - - /* Release descriptor as soon as extracting necessary info - * to reduce contention - */ - ath12k_dp_tx_release_txbuf(dp, tx_desc, tx_desc->pool_id); - if (ts.buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW) { - ath12k_dp_tx_process_htt_tx_complete(ab, (void *)tx_status, - tx_ring, &desc_params); - continue; - } - - pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, desc_params.mac_id); - ar = ab->pdevs[pdev_id].ar; - - if (atomic_dec_and_test(&ar->dp.num_tx_pending)) - wake_up(&ar->dp.tx_empty_waitq); - - ath12k_dp_tx_complete_msdu(ar, &desc_params, &ts, - tx_ring->tcl_data_ring_id); - } -} - static int ath12k_dp_tx_get_ring_id_type(struct ath12k_base *ab, int mac_id, u32 ring_id, diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.h b/drivers/net/wireless/ath/ath12k/dp_tx.h index aa2f6397bc83d..67ab7b3f55eaf 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/dp_tx.h @@ -19,8 +19,6 @@ int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab); int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, bool is_mcast); -void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id); - int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask); int ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type, @@ -38,4 +36,20 @@ int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id, int tx_buf_size, struct htt_tx_ring_tlv_filter *htt_tlv_filter); int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset); + +enum hal_tcl_encap_type +ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb); +void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb); +u8 ath12k_dp_tx_get_tid(struct sk_buff *skb); +void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len); +int ath12k_dp_tx_align_payload(struct ath12k_base *ab, + struct sk_buff **pskb); +void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp, + struct ath12k_tx_desc_info *tx_desc, + u8 pool_id); +struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp, + u8 pool_id); +void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, + struct dp_tx_ring *tx_ring, + struct ath12k_tx_desc_params *desc_params); #endif diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index f7a2a544bef20..76d6e8c0c6ad6 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -14,6 +14,7 @@ #include "wmi.h" #include "hw.h" #include "dp_tx.h" +#include "wifi7/dp_tx.h" #include "dp_rx.h" #include "testmode.h" #include "peer.h" diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 2e7b9bbd3d8ed..afe791394e6b4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -10,6 +10,7 @@ #include "../dp_mon.h" #include "dp_rx.h" #include "dp.h" +#include "dp_tx.h" int ath12k_dp_service_srng(struct ath12k_base *ab, struct ath12k_ext_irq_grp *irq_grp, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c new file mode 100644 index 0000000000000..149e211aa225e --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -0,0 +1,545 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "../core.h" +#include "../debug.h" +#include "../dp_tx.h" +#include "../peer.h" +#include "dp_tx.h" + +static void +ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, + struct ath12k_tx_desc_params *desc_params, + struct dp_tx_ring *tx_ring, + struct ath12k_dp_htt_wbm_tx_status *ts, + u16 peer_id) +{ + struct ieee80211_tx_info *info; + struct ath12k_link_vif *arvif; + struct ath12k_skb_cb *skb_cb; + struct ieee80211_vif *vif; + struct ath12k_vif *ahvif; + struct ath12k *ar; + struct sk_buff *msdu = desc_params->skb; + s32 noise_floor; + struct ieee80211_tx_status status = {}; + struct ath12k_peer *peer; + + skb_cb = ATH12K_SKB_CB(msdu); + info = IEEE80211_SKB_CB(msdu); + + ar = skb_cb->ar; + ab->device_stats.tx_completed[tx_ring->tcl_data_ring_id]++; + + if (atomic_dec_and_test(&ar->dp.num_tx_pending)) + wake_up(&ar->dp.tx_empty_waitq); + + dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + if (skb_cb->paddr_ext_desc) { + dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, + desc_params->skb_ext_desc->len, DMA_TO_DEVICE); + dev_kfree_skb_any(desc_params->skb_ext_desc); + } + + vif = skb_cb->vif; + if (vif) { + ahvif = ath12k_vif_to_ahvif(vif); + rcu_read_lock(); + arvif = rcu_dereference(ahvif->link[skb_cb->link_id]); + if (arvif) { + spin_lock_bh(&arvif->link_stats_lock); + arvif->link_stats.tx_completed++; + spin_unlock_bh(&arvif->link_stats_lock); + } + rcu_read_unlock(); + } + + memset(&info->status, 0, sizeof(info->status)); + + if (ts->acked) { + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { + info->flags |= IEEE80211_TX_STAT_ACK; + info->status.ack_signal = ts->ack_rssi; + + if (!test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, + ab->wmi_ab.svc_map)) { + spin_lock_bh(&ar->data_lock); + noise_floor = ath12k_pdev_get_noise_floor(ar); + spin_unlock_bh(&ar->data_lock); + + info->status.ack_signal += noise_floor; + } + + info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID; + } else { + info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; + } + } + rcu_read_lock(); + spin_lock_bh(&ab->base_lock); + peer = ath12k_peer_find_by_id(ab, peer_id); + if (!peer || !peer->sta) { + ath12k_dbg(ab, ATH12K_DBG_DATA, + "dp_tx: failed to find the peer with peer_id %d\n", peer_id); + spin_unlock_bh(&ab->base_lock); + ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu); + goto exit; + } else { + status.sta = peer->sta; + } + spin_unlock_bh(&ab->base_lock); + + status.info = info; + status.skb = msdu; + ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status); +exit: + rcu_read_unlock(); +} + +static void +ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc, + struct dp_tx_ring *tx_ring, + struct ath12k_tx_desc_params *desc_params) +{ + struct htt_tx_wbm_completion *status_desc; + struct ath12k_dp_htt_wbm_tx_status ts = {}; + enum hal_wbm_htt_tx_comp_status wbm_status; + u16 peer_id; + + status_desc = desc; + + wbm_status = le32_get_bits(status_desc->info0, + HTT_TX_WBM_COMP_INFO0_STATUS); + ab->device_stats.fw_tx_status[wbm_status]++; + + switch (wbm_status) { + case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK: + ts.acked = (wbm_status == HAL_WBM_REL_HTT_TX_COMP_STATUS_OK); + ts.ack_rssi = le32_get_bits(status_desc->info2, + HTT_TX_WBM_COMP_INFO2_ACK_RSSI); + + peer_id = le32_get_bits(((struct hal_wbm_completion_ring_tx *)desc)-> + info3, HAL_WBM_COMPL_TX_INFO3_PEER_ID); + + ath12k_dp_tx_htt_tx_complete_buf(ab, desc_params, tx_ring, &ts, peer_id); + break; + case HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP: + case HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL: + case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ: + case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT: + case HAL_WBM_REL_HTT_TX_COMP_STATUS_VDEVID_MISMATCH: + ath12k_dp_tx_free_txbuf(ab, tx_ring, desc_params); + break; + case HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY: + /* This event is to be handled only when the driver decides to + * use WDS offload functionality. + */ + break; + default: + ath12k_warn(ab, "Unknown htt wbm tx status %d\n", wbm_status); + break; + } +} + +static void ath12k_dp_tx_update_txcompl(struct ath12k *ar, struct hal_tx_status *ts) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_peer *peer; + struct ieee80211_sta *sta; + struct ath12k_sta *ahsta; + struct ath12k_link_sta *arsta; + struct rate_info txrate = {}; + u16 rate, ru_tones; + u8 rate_idx = 0; + int ret; + + spin_lock_bh(&ab->base_lock); + peer = ath12k_peer_find_by_id(ab, ts->peer_id); + if (!peer || !peer->sta) { + ath12k_dbg(ab, ATH12K_DBG_DP_TX, + "failed to find the peer by id %u\n", ts->peer_id); + spin_unlock_bh(&ab->base_lock); + return; + } + sta = peer->sta; + ahsta = ath12k_sta_to_ahsta(sta); + arsta = &ahsta->deflink; + + /* This is to prefer choose the real NSS value arsta->last_txrate.nss, + * if it is invalid, then choose the NSS value while assoc. + */ + if (arsta->last_txrate.nss) + txrate.nss = arsta->last_txrate.nss; + else + txrate.nss = arsta->peer_nss; + spin_unlock_bh(&ab->base_lock); + + switch (ts->pkt_type) { + case HAL_TX_RATE_STATS_PKT_TYPE_11A: + case HAL_TX_RATE_STATS_PKT_TYPE_11B: + ret = ath12k_mac_hw_ratecode_to_legacy_rate(ts->mcs, + ts->pkt_type, + &rate_idx, + &rate); + if (ret < 0) { + ath12k_warn(ab, "Invalid tx legacy rate %d\n", ret); + return; + } + + txrate.legacy = rate; + break; + case HAL_TX_RATE_STATS_PKT_TYPE_11N: + if (ts->mcs > ATH12K_HT_MCS_MAX) { + ath12k_warn(ab, "Invalid HT mcs index %d\n", ts->mcs); + return; + } + + if (txrate.nss != 0) + txrate.mcs = ts->mcs + 8 * (txrate.nss - 1); + + txrate.flags = RATE_INFO_FLAGS_MCS; + + if (ts->sgi) + txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + break; + case HAL_TX_RATE_STATS_PKT_TYPE_11AC: + if (ts->mcs > ATH12K_VHT_MCS_MAX) { + ath12k_warn(ab, "Invalid VHT mcs index %d\n", ts->mcs); + return; + } + + txrate.mcs = ts->mcs; + txrate.flags = RATE_INFO_FLAGS_VHT_MCS; + + if (ts->sgi) + txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + break; + case HAL_TX_RATE_STATS_PKT_TYPE_11AX: + if (ts->mcs > ATH12K_HE_MCS_MAX) { + ath12k_warn(ab, "Invalid HE mcs index %d\n", ts->mcs); + return; + } + + txrate.mcs = ts->mcs; + txrate.flags = RATE_INFO_FLAGS_HE_MCS; + txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(ts->sgi); + break; + case HAL_TX_RATE_STATS_PKT_TYPE_11BE: + if (ts->mcs > ATH12K_EHT_MCS_MAX) { + ath12k_warn(ab, "Invalid EHT mcs index %d\n", ts->mcs); + return; + } + + txrate.mcs = ts->mcs; + txrate.flags = RATE_INFO_FLAGS_EHT_MCS; + txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(ts->sgi); + break; + default: + ath12k_warn(ab, "Invalid tx pkt type: %d\n", ts->pkt_type); + return; + } + + txrate.bw = ath12k_mac_bw_to_mac80211_bw(ts->bw); + + if (ts->ofdma && ts->pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11AX) { + txrate.bw = RATE_INFO_BW_HE_RU; + ru_tones = ath12k_mac_he_convert_tones_to_ru_tones(ts->tones); + txrate.he_ru_alloc = + ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones); + } + + if (ts->ofdma && ts->pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11BE) { + txrate.bw = RATE_INFO_BW_EHT_RU; + txrate.eht_ru_alloc = + ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(ts->tones); + } + + spin_lock_bh(&ab->base_lock); + arsta->txrate = txrate; + spin_unlock_bh(&ab->base_lock); +} + +static void ath12k_dp_tx_complete_msdu(struct ath12k *ar, + struct ath12k_tx_desc_params *desc_params, + struct hal_tx_status *ts, + int ring) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_hw *ah = ar->ah; + struct ieee80211_tx_info *info; + struct ath12k_link_vif *arvif; + struct ath12k_skb_cb *skb_cb; + struct ieee80211_vif *vif; + struct ath12k_vif *ahvif; + struct sk_buff *msdu = desc_params->skb; + s32 noise_floor; + struct ieee80211_tx_status status = {}; + struct ieee80211_rate_status status_rate = {}; + struct ath12k_peer *peer; + struct ath12k_link_sta *arsta; + struct ath12k_sta *ahsta; + struct rate_info rate; + + if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) { + /* Must not happen */ + return; + } + + skb_cb = ATH12K_SKB_CB(msdu); + ab->device_stats.tx_completed[ring]++; + + dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + if (skb_cb->paddr_ext_desc) { + dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, + desc_params->skb_ext_desc->len, DMA_TO_DEVICE); + dev_kfree_skb_any(desc_params->skb_ext_desc); + } + + rcu_read_lock(); + + if (!rcu_dereference(ab->pdevs_active[ar->pdev_idx])) { + ieee80211_free_txskb(ah->hw, msdu); + goto exit; + } + + if (!skb_cb->vif) { + ieee80211_free_txskb(ah->hw, msdu); + goto exit; + } + + vif = skb_cb->vif; + if (vif) { + ahvif = ath12k_vif_to_ahvif(vif); + arvif = rcu_dereference(ahvif->link[skb_cb->link_id]); + if (arvif) { + spin_lock_bh(&arvif->link_stats_lock); + arvif->link_stats.tx_completed++; + spin_unlock_bh(&arvif->link_stats_lock); + } + } + + info = IEEE80211_SKB_CB(msdu); + memset(&info->status, 0, sizeof(info->status)); + + /* skip tx rate update from ieee80211_status*/ + info->status.rates[0].idx = -1; + + switch (ts->status) { + case HAL_WBM_TQM_REL_REASON_FRAME_ACKED: + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { + info->flags |= IEEE80211_TX_STAT_ACK; + info->status.ack_signal = ts->ack_rssi; + + if (!test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, + ab->wmi_ab.svc_map)) { + spin_lock_bh(&ar->data_lock); + noise_floor = ath12k_pdev_get_noise_floor(ar); + spin_unlock_bh(&ar->data_lock); + + info->status.ack_signal += noise_floor; + } + + info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID; + } + break; + case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_TX: + if (info->flags & IEEE80211_TX_CTL_NO_ACK) { + info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; + break; + } + fallthrough; + case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_MPDU: + case HAL_WBM_TQM_REL_REASON_DROP_THRESHOLD: + case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_AGED_FRAMES: + /* The failure status is due to internal firmware tx failure + * hence drop the frame; do not update the status of frame to + * the upper layer + */ + ieee80211_free_txskb(ah->hw, msdu); + goto exit; + default: + ath12k_dbg(ab, ATH12K_DBG_DP_TX, "tx frame is not acked status %d\n", + ts->status); + break; + } + + /* NOTE: Tx rate status reporting. Tx completion status does not have + * necessary information (for example nss) to build the tx rate. + * Might end up reporting it out-of-band from HTT stats. + */ + + ath12k_dp_tx_update_txcompl(ar, ts); + + spin_lock_bh(&ab->base_lock); + peer = ath12k_peer_find_by_id(ab, ts->peer_id); + if (!peer || !peer->sta) { + ath12k_err(ab, + "dp_tx: failed to find the peer with peer_id %d\n", + ts->peer_id); + spin_unlock_bh(&ab->base_lock); + ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu); + goto exit; + } + ahsta = ath12k_sta_to_ahsta(peer->sta); + arsta = &ahsta->deflink; + + spin_unlock_bh(&ab->base_lock); + + status.sta = peer->sta; + status.info = info; + status.skb = msdu; + rate = arsta->last_txrate; + + status_rate.rate_idx = rate; + status_rate.try_count = 1; + + status.rates = &status_rate; + status.n_rates = 1; + ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status); + +exit: + rcu_read_unlock(); +} + +static void ath12k_dp_tx_status_parse(struct ath12k_base *ab, + struct hal_wbm_completion_ring_tx *desc, + struct hal_tx_status *ts) +{ + u32 info0 = le32_to_cpu(desc->rate_stats.info0); + + ts->buf_rel_source = + le32_get_bits(desc->info0, HAL_WBM_COMPL_TX_INFO0_REL_SRC_MODULE); + if (ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_FW && + ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM) + return; + + if (ts->buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW) + return; + + ts->status = le32_get_bits(desc->info0, + HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON); + + ts->ppdu_id = le32_get_bits(desc->info1, + HAL_WBM_COMPL_TX_INFO1_TQM_STATUS_NUMBER); + + ts->peer_id = le32_get_bits(desc->info3, HAL_WBM_COMPL_TX_INFO3_PEER_ID); + + ts->ack_rssi = le32_get_bits(desc->info2, + HAL_WBM_COMPL_TX_INFO2_ACK_FRAME_RSSI); + + if (info0 & HAL_TX_RATE_STATS_INFO0_VALID) { + ts->pkt_type = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_PKT_TYPE); + ts->mcs = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_MCS); + ts->sgi = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_SGI); + ts->bw = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_BW); + ts->tones = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_TONES_IN_RU); + ts->ofdma = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_OFDMA_TX); + } +} + +void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) +{ + struct ath12k *ar; + struct ath12k_dp *dp = &ab->dp; + int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id; + struct hal_srng *status_ring = &ab->hal.srng_list[hal_ring_id]; + struct ath12k_tx_desc_info *tx_desc = NULL; + struct hal_tx_status ts = {}; + struct ath12k_tx_desc_params desc_params; + struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id]; + struct hal_wbm_release_ring *desc; + u8 pdev_id; + u64 desc_va; + enum hal_wbm_rel_src_module buf_rel_source; + enum hal_wbm_tqm_rel_reason rel_status; + + spin_lock_bh(&status_ring->lock); + + ath12k_hal_srng_access_begin(ab, status_ring); + + while (ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_head) != + tx_ring->tx_status_tail) { + desc = ath12k_hal_srng_dst_get_next_entry(ab, status_ring); + if (!desc) + break; + + memcpy(&tx_ring->tx_status[tx_ring->tx_status_head], + desc, sizeof(*desc)); + tx_ring->tx_status_head = + ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_head); + } + + if (ath12k_hal_srng_dst_peek(ab, status_ring) && + (ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_head) == + tx_ring->tx_status_tail)) { + /* TODO: Process pending tx_status messages when kfifo_is_full() */ + ath12k_warn(ab, "Unable to process some of the tx_status ring desc because status_fifo is full\n"); + } + + ath12k_hal_srng_access_end(ab, status_ring); + + spin_unlock_bh(&status_ring->lock); + + while (ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_tail) != + tx_ring->tx_status_head) { + struct hal_wbm_completion_ring_tx *tx_status; + u32 desc_id; + + tx_ring->tx_status_tail = + ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_tail); + tx_status = &tx_ring->tx_status[tx_ring->tx_status_tail]; + ath12k_dp_tx_status_parse(ab, tx_status, &ts); + + if (le32_get_bits(tx_status->info0, HAL_WBM_COMPL_TX_INFO0_CC_DONE)) { + /* HW done cookie conversion */ + desc_va = ((u64)le32_to_cpu(tx_status->buf_va_hi) << 32 | + le32_to_cpu(tx_status->buf_va_lo)); + tx_desc = (struct ath12k_tx_desc_info *)((unsigned long)desc_va); + } else { + /* SW does cookie conversion to VA */ + desc_id = le32_get_bits(tx_status->buf_va_hi, + BUFFER_ADDR_INFO1_SW_COOKIE); + + tx_desc = ath12k_dp_get_tx_desc(ab, desc_id); + } + if (!tx_desc) { + ath12k_warn(ab, "unable to retrieve tx_desc!"); + continue; + } + + desc_params.mac_id = tx_desc->mac_id; + desc_params.skb = tx_desc->skb; + desc_params.skb_ext_desc = tx_desc->skb_ext_desc; + + /* Find the HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE value */ + buf_rel_source = le32_get_bits(tx_status->info0, + HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE); + ab->device_stats.tx_wbm_rel_source[buf_rel_source]++; + + rel_status = le32_get_bits(tx_status->info0, + HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON); + ab->device_stats.tqm_rel_reason[rel_status]++; + + /* Release descriptor as soon as extracting necessary info + * to reduce contention + */ + ath12k_dp_tx_release_txbuf(dp, tx_desc, tx_desc->pool_id); + if (ts.buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW) { + ath12k_dp_tx_process_htt_tx_complete(ab, (void *)tx_status, + tx_ring, &desc_params); + continue; + } + + pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, desc_params.mac_id); + ar = ab->pdevs[pdev_id].ar; + + if (atomic_dec_and_test(&ar->dp.num_tx_pending)) + wake_up(&ar->dp.tx_empty_waitq); + + ath12k_dp_tx_complete_msdu(ar, &desc_params, &ts, + tx_ring->tcl_data_ring_id); + } +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h new file mode 100644 index 0000000000000..4361beb996660 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_DP_TX_WIFI7_H +#define ATH12K_DP_TX_WIFI7_H + +void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id); +#endif From 790ef31b56610c21afce158bc0aa53c12b8e8b1b Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 28 Aug 2025 23:05:49 +0530 Subject: [PATCH 029/140] wifi: ath12k: Move ath12k_dp_tx and related APIs to wifi7 directory Move arch specific TX data path to wifi7 directory as part of Next Generation (NG) Driver Framework. Architecture specific APIs: ath12k_hal_tx_cmd_ext_desc_setup ath12k_dp_prepare_htt_metadata ath12k_dp_tx The moved APIs will be a part of dp_tx.c file inside wifi7 directory. wifi7/dp_tx.c file will continue to be part of ath12k.ko temporarily until the corresponding infra for movement to ath12k_wifi7.ko arrives in upcoming patches. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-17-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_tx.c | 363 ------------------ drivers/net/wireless/ath/ath12k/dp_tx.h | 3 - drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 363 ++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h | 3 + 4 files changed, 366 insertions(+), 366 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c index f1649744c78b7..c7b0fc22c1a79 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/dp_tx.c @@ -109,26 +109,6 @@ struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp, return desc; } -static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, - struct hal_tx_msdu_ext_desc *tcl_ext_cmd, - struct hal_tx_info *ti) -{ - tcl_ext_cmd->info0 = le32_encode_bits(ti->paddr, - HAL_TX_MSDU_EXT_INFO0_BUF_PTR_LO); - tcl_ext_cmd->info1 = le32_encode_bits(0x0, - HAL_TX_MSDU_EXT_INFO1_BUF_PTR_HI) | - le32_encode_bits(ti->data_len, - HAL_TX_MSDU_EXT_INFO1_BUF_LEN); - - tcl_ext_cmd->info1 |= le32_encode_bits(1, HAL_TX_MSDU_EXT_INFO1_EXTN_OVERRIDE) | - le32_encode_bits(ti->encap_type, - HAL_TX_MSDU_EXT_INFO1_ENCAP_TYPE) | - le32_encode_bits(ti->encrypt_type, - HAL_TX_MSDU_EXT_INFO1_ENCRYPT_TYPE); -} - -#define HTT_META_DATA_ALIGNMENT 0x8 - void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len) { struct sk_buff *tail; @@ -142,29 +122,6 @@ void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len) return metadata; } -/* Preparing HTT Metadata when utilized with ext MSDU */ -static int ath12k_dp_prepare_htt_metadata(struct sk_buff *skb) -{ - struct hal_tx_msdu_metadata *desc_ext; - u8 htt_desc_size; - /* Size rounded of multiple of 8 bytes */ - u8 htt_desc_size_aligned; - - htt_desc_size = sizeof(struct hal_tx_msdu_metadata); - htt_desc_size_aligned = ALIGN(htt_desc_size, HTT_META_DATA_ALIGNMENT); - - desc_ext = ath12k_dp_metadata_align_skb(skb, htt_desc_size_aligned); - if (!desc_ext) - return -ENOMEM; - - desc_ext->info0 = le32_encode_bits(1, HAL_TX_MSDU_METADATA_INFO0_ENCRYPT_FLAG) | - le32_encode_bits(0, HAL_TX_MSDU_METADATA_INFO0_ENCRYPT_TYPE) | - le32_encode_bits(1, - HAL_TX_MSDU_METADATA_INFO0_HOST_TX_DESC_POOL); - - return 0; -} - static void ath12k_dp_tx_move_payload(struct sk_buff *skb, unsigned long delta, bool head) @@ -219,326 +176,6 @@ int ath12k_dp_tx_align_payload(struct ath12k_base *ab, return ret; } -int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, - struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, - bool is_mcast) -{ - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; - struct hal_tx_info ti = {}; - struct ath12k_tx_desc_info *tx_desc; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb); - struct hal_tcl_data_cmd *hal_tcl_desc; - struct hal_tx_msdu_ext_desc *msg; - struct sk_buff *skb_ext_desc = NULL; - struct hal_srng *tcl_ring; - struct ieee80211_hdr *hdr = (void *)skb->data; - struct ath12k_vif *ahvif = arvif->ahvif; - struct dp_tx_ring *tx_ring; - u8 pool_id; - u8 hal_ring_id; - int ret; - u8 ring_selector, ring_map = 0; - bool tcl_ring_retry; - bool msdu_ext_desc = false; - bool add_htt_metadata = false; - u32 iova_mask = ab->hw_params->iova_mask; - bool is_diff_encap = false; - bool is_null_frame = false; - - if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags)) - return -ESHUTDOWN; - - if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && - !ieee80211_is_data(hdr->frame_control)) - return -EOPNOTSUPP; - - pool_id = skb_get_queue_mapping(skb) & (ATH12K_HW_MAX_QUEUES - 1); - - /* Let the default ring selection be based on current processor - * number, where one of the 3 tcl rings are selected based on - * the smp_processor_id(). In case that ring - * is full/busy, we resort to other available rings. - * If all rings are full, we drop the packet. - * TODO: Add throttling logic when all rings are full - */ - ring_selector = ab->hw_params->hw_ops->get_ring_selector(skb); - -tcl_ring_sel: - tcl_ring_retry = false; - ti.ring_id = ring_selector % ab->hw_params->max_tx_ring; - - ring_map |= BIT(ti.ring_id); - ti.rbm_id = ab->hw_params->hal_ops->tcl_to_wbm_rbm_map[ti.ring_id].rbm_id; - - tx_ring = &dp->tx_ring[ti.ring_id]; - - tx_desc = ath12k_dp_tx_assign_buffer(dp, pool_id); - if (!tx_desc) - return -ENOMEM; - - ti.bank_id = arvif->bank_id; - ti.meta_data_flags = arvif->tcl_metadata; - - if (ahvif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW && - test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) { - if (skb_cb->flags & ATH12K_SKB_CIPHER_SET) { - ti.encrypt_type = - ath12k_dp_tx_get_encrypt_type(skb_cb->cipher); - - if (ieee80211_has_protected(hdr->frame_control)) - skb_put(skb, IEEE80211_CCMP_MIC_LEN); - } else { - ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN; - } - - msdu_ext_desc = true; - } - - if (gsn_valid) { - /* Reset and Initialize meta_data_flags with Global Sequence - * Number (GSN) info. - */ - ti.meta_data_flags = - u32_encode_bits(HTT_TCL_META_DATA_TYPE_GLOBAL_SEQ_NUM, - HTT_TCL_META_DATA_TYPE) | - u32_encode_bits(mcbc_gsn, HTT_TCL_META_DATA_GLOBAL_SEQ_NUM); - } - - ti.encap_type = ath12k_dp_tx_get_encap_type(ab, skb); - ti.addr_search_flags = arvif->hal_addr_search_flags; - ti.search_type = arvif->search_type; - ti.type = HAL_TCL_DESC_TYPE_BUFFER; - ti.pkt_offset = 0; - ti.lmac_id = ar->lmac_id; - - ti.vdev_id = arvif->vdev_id; - if (gsn_valid) - ti.vdev_id += HTT_TX_MLO_MCAST_HOST_REINJECT_BASE_VDEV_ID; - - ti.bss_ast_hash = arvif->ast_hash; - ti.bss_ast_idx = arvif->ast_idx; - ti.dscp_tid_tbl_idx = 0; - - if (skb->ip_summed == CHECKSUM_PARTIAL && - ti.encap_type != HAL_TCL_ENCAP_TYPE_RAW) { - ti.flags0 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_IP4_CKSUM_EN) | - u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_UDP4_CKSUM_EN) | - u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_UDP6_CKSUM_EN) | - u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TCP4_CKSUM_EN) | - u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TCP6_CKSUM_EN); - } - - ti.flags1 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO3_TID_OVERWRITE); - - ti.tid = ath12k_dp_tx_get_tid(skb); - - switch (ti.encap_type) { - case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI: - is_null_frame = ieee80211_is_nullfunc(hdr->frame_control); - if (ahvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) { - if (skb->protocol == cpu_to_be16(ETH_P_PAE) || is_null_frame) - is_diff_encap = true; - - /* Firmware expects msdu ext descriptor for nwifi/raw packets - * received in ETH mode. Without this, observed tx fail for - * Multicast packets in ETH mode. - */ - msdu_ext_desc = true; - } else { - ath12k_dp_tx_encap_nwifi(skb); - } - break; - case HAL_TCL_ENCAP_TYPE_RAW: - if (!test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) { - ret = -EINVAL; - goto fail_remove_tx_buf; - } - break; - case HAL_TCL_ENCAP_TYPE_ETHERNET: - /* no need to encap */ - break; - case HAL_TCL_ENCAP_TYPE_802_3: - default: - /* TODO: Take care of other encap modes as well */ - ret = -EINVAL; - atomic_inc(&ab->device_stats.tx_err.misc_fail); - goto fail_remove_tx_buf; - } - - if (iova_mask && - (unsigned long)skb->data & iova_mask) { - ret = ath12k_dp_tx_align_payload(ab, &skb); - if (ret) { - ath12k_warn(ab, "failed to align TX buffer %d\n", ret); - /* don't bail out, give original buffer - * a chance even unaligned. - */ - goto map; - } - - /* hdr is pointing to a wrong place after alignment, - * so refresh it for later use. - */ - hdr = (void *)skb->data; - } -map: - ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE); - if (dma_mapping_error(ab->dev, ti.paddr)) { - atomic_inc(&ab->device_stats.tx_err.misc_fail); - ath12k_warn(ab, "failed to DMA map data Tx buffer\n"); - ret = -ENOMEM; - goto fail_remove_tx_buf; - } - - if ((!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && - !(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) && - !(skb_cb->flags & ATH12K_SKB_CIPHER_SET) && - ieee80211_has_protected(hdr->frame_control)) || - is_diff_encap) { - /* Firmware is not expecting meta data for qos null - * nwifi packet received in ETH encap mode. - */ - if (is_null_frame && msdu_ext_desc) - goto skip_htt_meta; - - /* Add metadata for sw encrypted vlan group traffic - * and EAPOL nwifi packet received in ETH encap mode. - */ - add_htt_metadata = true; - msdu_ext_desc = true; - ti.meta_data_flags |= HTT_TCL_META_DATA_VALID_HTT; -skip_htt_meta: - ti.flags0 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TO_FW); - ti.encap_type = HAL_TCL_ENCAP_TYPE_RAW; - ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN; - } - - tx_desc->skb = skb; - tx_desc->mac_id = ar->pdev_idx; - ti.desc_id = tx_desc->desc_id; - ti.data_len = skb->len; - skb_cb->paddr = ti.paddr; - skb_cb->vif = ahvif->vif; - skb_cb->ar = ar; - - if (msdu_ext_desc) { - skb_ext_desc = dev_alloc_skb(sizeof(struct hal_tx_msdu_ext_desc)); - if (!skb_ext_desc) { - ret = -ENOMEM; - goto fail_unmap_dma; - } - - skb_put(skb_ext_desc, sizeof(struct hal_tx_msdu_ext_desc)); - memset(skb_ext_desc->data, 0, skb_ext_desc->len); - - msg = (struct hal_tx_msdu_ext_desc *)skb_ext_desc->data; - ath12k_hal_tx_cmd_ext_desc_setup(ab, msg, &ti); - - if (add_htt_metadata) { - ret = ath12k_dp_prepare_htt_metadata(skb_ext_desc); - if (ret < 0) { - ath12k_dbg(ab, ATH12K_DBG_DP_TX, - "Failed to add HTT meta data, dropping packet\n"); - goto fail_free_ext_skb; - } - } - - ti.paddr = dma_map_single(ab->dev, skb_ext_desc->data, - skb_ext_desc->len, DMA_TO_DEVICE); - ret = dma_mapping_error(ab->dev, ti.paddr); - if (ret) - goto fail_free_ext_skb; - - ti.data_len = skb_ext_desc->len; - ti.type = HAL_TCL_DESC_TYPE_EXT_DESC; - - skb_cb->paddr_ext_desc = ti.paddr; - tx_desc->skb_ext_desc = skb_ext_desc; - } - - hal_ring_id = tx_ring->tcl_data_ring.ring_id; - tcl_ring = &ab->hal.srng_list[hal_ring_id]; - - spin_lock_bh(&tcl_ring->lock); - - ath12k_hal_srng_access_begin(ab, tcl_ring); - - hal_tcl_desc = ath12k_hal_srng_src_get_next_entry(ab, tcl_ring); - if (!hal_tcl_desc) { - /* NOTE: It is highly unlikely we'll be running out of tcl_ring - * desc because the desc is directly enqueued onto hw queue. - */ - ath12k_hal_srng_access_end(ab, tcl_ring); - ab->device_stats.tx_err.desc_na[ti.ring_id]++; - spin_unlock_bh(&tcl_ring->lock); - ret = -ENOMEM; - - /* Checking for available tcl descriptors in another ring in - * case of failure due to full tcl ring now, is better than - * checking this ring earlier for each pkt tx. - * Restart ring selection if some rings are not checked yet. - */ - if (ring_map != (BIT(ab->hw_params->max_tx_ring) - 1) && - ab->hw_params->tcl_ring_retry) { - tcl_ring_retry = true; - ring_selector++; - } - - goto fail_unmap_dma_ext; - } - - spin_lock_bh(&arvif->link_stats_lock); - arvif->link_stats.tx_encap_type[ti.encap_type]++; - arvif->link_stats.tx_encrypt_type[ti.encrypt_type]++; - arvif->link_stats.tx_desc_type[ti.type]++; - - if (is_mcast) - arvif->link_stats.tx_bcast_mcast++; - else - arvif->link_stats.tx_enqueued++; - spin_unlock_bh(&arvif->link_stats_lock); - - ab->device_stats.tx_enqueued[ti.ring_id]++; - - ath12k_hal_tx_cmd_desc_setup(ab, hal_tcl_desc, &ti); - - ath12k_hal_srng_access_end(ab, tcl_ring); - - spin_unlock_bh(&tcl_ring->lock); - - ath12k_dbg_dump(ab, ATH12K_DBG_DP_TX, NULL, "dp tx msdu: ", - skb->data, skb->len); - - atomic_inc(&ar->dp.num_tx_pending); - - return 0; - -fail_unmap_dma_ext: - if (skb_cb->paddr_ext_desc) - dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, - skb_ext_desc->len, - DMA_TO_DEVICE); -fail_free_ext_skb: - kfree_skb(skb_ext_desc); - -fail_unmap_dma: - dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE); - -fail_remove_tx_buf: - ath12k_dp_tx_release_txbuf(dp, tx_desc, pool_id); - - spin_lock_bh(&arvif->link_stats_lock); - arvif->link_stats.tx_dropped++; - spin_unlock_bh(&arvif->link_stats_lock); - - if (tcl_ring_retry) - goto tcl_ring_sel; - - return ret; -} - void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, struct dp_tx_ring *tx_ring, struct ath12k_tx_desc_params *desc_params) diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.h b/drivers/net/wireless/ath/ath12k/dp_tx.h index 67ab7b3f55eaf..8405a0baf95b6 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/dp_tx.h @@ -16,9 +16,6 @@ struct ath12k_dp_htt_wbm_tx_status { }; int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab); -int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, - struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, - bool is_mcast); int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask); int ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 149e211aa225e..49d219a195c5e 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -10,6 +10,369 @@ #include "../peer.h" #include "dp_tx.h" +static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, + struct hal_tx_msdu_ext_desc *tcl_ext_cmd, + struct hal_tx_info *ti) +{ + tcl_ext_cmd->info0 = le32_encode_bits(ti->paddr, + HAL_TX_MSDU_EXT_INFO0_BUF_PTR_LO); + tcl_ext_cmd->info1 = le32_encode_bits(0x0, + HAL_TX_MSDU_EXT_INFO1_BUF_PTR_HI) | + le32_encode_bits(ti->data_len, + HAL_TX_MSDU_EXT_INFO1_BUF_LEN); + + tcl_ext_cmd->info1 |= le32_encode_bits(1, HAL_TX_MSDU_EXT_INFO1_EXTN_OVERRIDE) | + le32_encode_bits(ti->encap_type, + HAL_TX_MSDU_EXT_INFO1_ENCAP_TYPE) | + le32_encode_bits(ti->encrypt_type, + HAL_TX_MSDU_EXT_INFO1_ENCRYPT_TYPE); +} + +#define HTT_META_DATA_ALIGNMENT 0x8 + +/* Preparing HTT Metadata when utilized with ext MSDU */ +static int ath12k_dp_prepare_htt_metadata(struct sk_buff *skb) +{ + struct hal_tx_msdu_metadata *desc_ext; + u8 htt_desc_size; + /* Size rounded of multiple of 8 bytes */ + u8 htt_desc_size_aligned; + + htt_desc_size = sizeof(struct hal_tx_msdu_metadata); + htt_desc_size_aligned = ALIGN(htt_desc_size, HTT_META_DATA_ALIGNMENT); + + desc_ext = ath12k_dp_metadata_align_skb(skb, htt_desc_size_aligned); + if (!desc_ext) + return -ENOMEM; + + desc_ext->info0 = le32_encode_bits(1, HAL_TX_MSDU_METADATA_INFO0_ENCRYPT_FLAG) | + le32_encode_bits(0, HAL_TX_MSDU_METADATA_INFO0_ENCRYPT_TYPE) | + le32_encode_bits(1, + HAL_TX_MSDU_METADATA_INFO0_HOST_TX_DESC_POOL); + + return 0; +} + +int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, + struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, + bool is_mcast) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = &ab->dp; + struct hal_tx_info ti = {}; + struct ath12k_tx_desc_info *tx_desc; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb); + struct hal_tcl_data_cmd *hal_tcl_desc; + struct hal_tx_msdu_ext_desc *msg; + struct sk_buff *skb_ext_desc = NULL; + struct hal_srng *tcl_ring; + struct ieee80211_hdr *hdr = (void *)skb->data; + struct ath12k_vif *ahvif = arvif->ahvif; + struct dp_tx_ring *tx_ring; + u8 pool_id; + u8 hal_ring_id; + int ret; + u8 ring_selector, ring_map = 0; + bool tcl_ring_retry; + bool msdu_ext_desc = false; + bool add_htt_metadata = false; + u32 iova_mask = ab->hw_params->iova_mask; + bool is_diff_encap = false; + bool is_null_frame = false; + + if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags)) + return -ESHUTDOWN; + + if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && + !ieee80211_is_data(hdr->frame_control)) + return -EOPNOTSUPP; + + pool_id = skb_get_queue_mapping(skb) & (ATH12K_HW_MAX_QUEUES - 1); + + /* Let the default ring selection be based on current processor + * number, where one of the 3 tcl rings are selected based on + * the smp_processor_id(). In case that ring + * is full/busy, we resort to other available rings. + * If all rings are full, we drop the packet. + * TODO: Add throttling logic when all rings are full + */ + ring_selector = ab->hw_params->hw_ops->get_ring_selector(skb); + +tcl_ring_sel: + tcl_ring_retry = false; + ti.ring_id = ring_selector % ab->hw_params->max_tx_ring; + + ring_map |= BIT(ti.ring_id); + ti.rbm_id = ab->hw_params->hal_ops->tcl_to_wbm_rbm_map[ti.ring_id].rbm_id; + + tx_ring = &dp->tx_ring[ti.ring_id]; + + tx_desc = ath12k_dp_tx_assign_buffer(dp, pool_id); + if (!tx_desc) + return -ENOMEM; + + ti.bank_id = arvif->bank_id; + ti.meta_data_flags = arvif->tcl_metadata; + + if (ahvif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW && + test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) { + if (skb_cb->flags & ATH12K_SKB_CIPHER_SET) { + ti.encrypt_type = + ath12k_dp_tx_get_encrypt_type(skb_cb->cipher); + + if (ieee80211_has_protected(hdr->frame_control)) + skb_put(skb, IEEE80211_CCMP_MIC_LEN); + } else { + ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN; + } + + msdu_ext_desc = true; + } + + if (gsn_valid) { + /* Reset and Initialize meta_data_flags with Global Sequence + * Number (GSN) info. + */ + ti.meta_data_flags = + u32_encode_bits(HTT_TCL_META_DATA_TYPE_GLOBAL_SEQ_NUM, + HTT_TCL_META_DATA_TYPE) | + u32_encode_bits(mcbc_gsn, HTT_TCL_META_DATA_GLOBAL_SEQ_NUM); + } + + ti.encap_type = ath12k_dp_tx_get_encap_type(ab, skb); + ti.addr_search_flags = arvif->hal_addr_search_flags; + ti.search_type = arvif->search_type; + ti.type = HAL_TCL_DESC_TYPE_BUFFER; + ti.pkt_offset = 0; + ti.lmac_id = ar->lmac_id; + + ti.vdev_id = arvif->vdev_id; + if (gsn_valid) + ti.vdev_id += HTT_TX_MLO_MCAST_HOST_REINJECT_BASE_VDEV_ID; + + ti.bss_ast_hash = arvif->ast_hash; + ti.bss_ast_idx = arvif->ast_idx; + ti.dscp_tid_tbl_idx = 0; + + if (skb->ip_summed == CHECKSUM_PARTIAL && + ti.encap_type != HAL_TCL_ENCAP_TYPE_RAW) { + ti.flags0 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_IP4_CKSUM_EN) | + u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_UDP4_CKSUM_EN) | + u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_UDP6_CKSUM_EN) | + u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TCP4_CKSUM_EN) | + u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TCP6_CKSUM_EN); + } + + ti.flags1 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO3_TID_OVERWRITE); + + ti.tid = ath12k_dp_tx_get_tid(skb); + + switch (ti.encap_type) { + case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI: + is_null_frame = ieee80211_is_nullfunc(hdr->frame_control); + if (ahvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) { + if (skb->protocol == cpu_to_be16(ETH_P_PAE) || is_null_frame) + is_diff_encap = true; + + /* Firmware expects msdu ext descriptor for nwifi/raw packets + * received in ETH mode. Without this, observed tx fail for + * Multicast packets in ETH mode. + */ + msdu_ext_desc = true; + } else { + ath12k_dp_tx_encap_nwifi(skb); + } + break; + case HAL_TCL_ENCAP_TYPE_RAW: + if (!test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) { + ret = -EINVAL; + goto fail_remove_tx_buf; + } + break; + case HAL_TCL_ENCAP_TYPE_ETHERNET: + /* no need to encap */ + break; + case HAL_TCL_ENCAP_TYPE_802_3: + default: + /* TODO: Take care of other encap modes as well */ + ret = -EINVAL; + atomic_inc(&ab->device_stats.tx_err.misc_fail); + goto fail_remove_tx_buf; + } + + if (iova_mask && + (unsigned long)skb->data & iova_mask) { + ret = ath12k_dp_tx_align_payload(ab, &skb); + if (ret) { + ath12k_warn(ab, "failed to align TX buffer %d\n", ret); + /* don't bail out, give original buffer + * a chance even unaligned. + */ + goto map; + } + + /* hdr is pointing to a wrong place after alignment, + * so refresh it for later use. + */ + hdr = (void *)skb->data; + } +map: + ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE); + if (dma_mapping_error(ab->dev, ti.paddr)) { + atomic_inc(&ab->device_stats.tx_err.misc_fail); + ath12k_warn(ab, "failed to DMA map data Tx buffer\n"); + ret = -ENOMEM; + goto fail_remove_tx_buf; + } + + if ((!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && + !(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) && + !(skb_cb->flags & ATH12K_SKB_CIPHER_SET) && + ieee80211_has_protected(hdr->frame_control)) || + is_diff_encap) { + /* Firmware is not expecting meta data for qos null + * nwifi packet received in ETH encap mode. + */ + if (is_null_frame && msdu_ext_desc) + goto skip_htt_meta; + + /* Add metadata for sw encrypted vlan group traffic + * and EAPOL nwifi packet received in ETH encap mode. + */ + add_htt_metadata = true; + msdu_ext_desc = true; + ti.meta_data_flags |= HTT_TCL_META_DATA_VALID_HTT; +skip_htt_meta: + ti.flags0 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TO_FW); + ti.encap_type = HAL_TCL_ENCAP_TYPE_RAW; + ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN; + } + + tx_desc->skb = skb; + tx_desc->mac_id = ar->pdev_idx; + ti.desc_id = tx_desc->desc_id; + ti.data_len = skb->len; + skb_cb->paddr = ti.paddr; + skb_cb->vif = ahvif->vif; + skb_cb->ar = ar; + + if (msdu_ext_desc) { + skb_ext_desc = dev_alloc_skb(sizeof(struct hal_tx_msdu_ext_desc)); + if (!skb_ext_desc) { + ret = -ENOMEM; + goto fail_unmap_dma; + } + + skb_put(skb_ext_desc, sizeof(struct hal_tx_msdu_ext_desc)); + memset(skb_ext_desc->data, 0, skb_ext_desc->len); + + msg = (struct hal_tx_msdu_ext_desc *)skb_ext_desc->data; + ath12k_hal_tx_cmd_ext_desc_setup(ab, msg, &ti); + + if (add_htt_metadata) { + ret = ath12k_dp_prepare_htt_metadata(skb_ext_desc); + if (ret < 0) { + ath12k_dbg(ab, ATH12K_DBG_DP_TX, + "Failed to add HTT meta data, dropping packet\n"); + goto fail_free_ext_skb; + } + } + + ti.paddr = dma_map_single(ab->dev, skb_ext_desc->data, + skb_ext_desc->len, DMA_TO_DEVICE); + ret = dma_mapping_error(ab->dev, ti.paddr); + if (ret) + goto fail_free_ext_skb; + + ti.data_len = skb_ext_desc->len; + ti.type = HAL_TCL_DESC_TYPE_EXT_DESC; + + skb_cb->paddr_ext_desc = ti.paddr; + tx_desc->skb_ext_desc = skb_ext_desc; + } + + hal_ring_id = tx_ring->tcl_data_ring.ring_id; + tcl_ring = &ab->hal.srng_list[hal_ring_id]; + + spin_lock_bh(&tcl_ring->lock); + + ath12k_hal_srng_access_begin(ab, tcl_ring); + + hal_tcl_desc = ath12k_hal_srng_src_get_next_entry(ab, tcl_ring); + if (!hal_tcl_desc) { + /* NOTE: It is highly unlikely we'll be running out of tcl_ring + * desc because the desc is directly enqueued onto hw queue. + */ + ath12k_hal_srng_access_end(ab, tcl_ring); + ab->device_stats.tx_err.desc_na[ti.ring_id]++; + spin_unlock_bh(&tcl_ring->lock); + ret = -ENOMEM; + + /* Checking for available tcl descriptors in another ring in + * case of failure due to full tcl ring now, is better than + * checking this ring earlier for each pkt tx. + * Restart ring selection if some rings are not checked yet. + */ + if (ring_map != (BIT(ab->hw_params->max_tx_ring) - 1) && + ab->hw_params->tcl_ring_retry) { + tcl_ring_retry = true; + ring_selector++; + } + + goto fail_unmap_dma_ext; + } + + spin_lock_bh(&arvif->link_stats_lock); + arvif->link_stats.tx_encap_type[ti.encap_type]++; + arvif->link_stats.tx_encrypt_type[ti.encrypt_type]++; + arvif->link_stats.tx_desc_type[ti.type]++; + + if (is_mcast) + arvif->link_stats.tx_bcast_mcast++; + else + arvif->link_stats.tx_enqueued++; + spin_unlock_bh(&arvif->link_stats_lock); + + ab->device_stats.tx_enqueued[ti.ring_id]++; + + ath12k_hal_tx_cmd_desc_setup(ab, hal_tcl_desc, &ti); + + ath12k_hal_srng_access_end(ab, tcl_ring); + + spin_unlock_bh(&tcl_ring->lock); + + ath12k_dbg_dump(ab, ATH12K_DBG_DP_TX, NULL, "dp tx msdu: ", + skb->data, skb->len); + + atomic_inc(&ar->dp.num_tx_pending); + + return 0; + +fail_unmap_dma_ext: + if (skb_cb->paddr_ext_desc) + dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, + skb_ext_desc->len, + DMA_TO_DEVICE); +fail_free_ext_skb: + kfree_skb(skb_ext_desc); + +fail_unmap_dma: + dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE); + +fail_remove_tx_buf: + ath12k_dp_tx_release_txbuf(dp, tx_desc, pool_id); + + spin_lock_bh(&arvif->link_stats_lock); + arvif->link_stats.tx_dropped++; + spin_unlock_bh(&arvif->link_stats_lock); + + if (tcl_ring_retry) + goto tcl_ring_sel; + + return ret; +} + static void ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, struct ath12k_tx_desc_params *desc_params, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h index 4361beb996660..42faf664f8f8b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h @@ -7,5 +7,8 @@ #ifndef ATH12K_DP_TX_WIFI7_H #define ATH12K_DP_TX_WIFI7_H +int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, + struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, + bool is_mcast); void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id); #endif From e985ee10060c01d784092ef2008c0211f5a3c266 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Thu, 28 Aug 2025 23:05:50 +0530 Subject: [PATCH 030/140] wifi: ath12k: Move HTT code in dp.h to newly introduced files WLAN Host driver interacts with the Firmware and vice versa using Host-To-Target (HTT) interface. HTT interface code is spread across multiple files (ex dp_tx.c, dp_rx.c, dp.h etc) and this interface is independent of the underlying architecture Tx and Rx. Relocate HTT specific code from dp.h to newly introduced file dp_htt.h for HTT interface. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-18-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- .../wireless/ath/ath12k/debugfs_htt_stats.h | 4 +- drivers/net/wireless/ath/ath12k/dp.h | 1506 +--------------- drivers/net/wireless/ath/ath12k/dp_htt.h | 1517 +++++++++++++++++ 3 files changed, 1521 insertions(+), 1506 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/dp_htt.h diff --git a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h index 9bd3a632b002d..8008658371aae 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h +++ b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h @@ -1,12 +1,14 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 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 DEBUG_HTT_STATS_H #define DEBUG_HTT_STATS_H +#include "dp_htt.h" + #define ATH12K_HTT_STATS_BUF_SIZE (1024 * 512) #define ATH12K_HTT_STATS_COOKIE_LSB GENMASK_ULL(31, 0) #define ATH12K_HTT_STATS_COOKIE_MSB GENMASK_ULL(63, 32) diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index cfffc51f87bf4..9c860cc8d7d98 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -10,6 +10,7 @@ #include "wifi7/hal_desc.h" #include "wifi7/hal_rx.h" #include "hw.h" +#include "dp_htt.h" #define MAX_RXDMA_PER_PDEV 2 @@ -429,1511 +430,6 @@ struct ath12k_dp { struct ath12k_reo_q_addr_lut ml_reoq_lut; }; -/* HTT definitions */ -#define HTT_TAG_TCL_METADATA_VERSION 5 - -#define HTT_TCL_META_DATA_TYPE GENMASK(1, 0) -#define HTT_TCL_META_DATA_VALID_HTT BIT(2) - -/* vdev meta data */ -#define HTT_TCL_META_DATA_VDEV_ID GENMASK(10, 3) -#define HTT_TCL_META_DATA_PDEV_ID GENMASK(12, 11) -#define HTT_TCL_META_DATA_HOST_INSPECTED_MISSION BIT(13) - -/* peer meta data */ -#define HTT_TCL_META_DATA_PEER_ID GENMASK(15, 3) - -/* Global sequence number */ -#define HTT_TCL_META_DATA_TYPE_GLOBAL_SEQ_NUM 3 -#define HTT_TCL_META_DATA_GLOBAL_SEQ_HOST_INSPECTED BIT(2) -#define HTT_TCL_META_DATA_GLOBAL_SEQ_NUM GENMASK(14, 3) -#define HTT_TX_MLO_MCAST_HOST_REINJECT_BASE_VDEV_ID 128 - -/* HTT tx completion is overlaid in wbm_release_ring */ -#define HTT_TX_WBM_COMP_INFO0_STATUS GENMASK(16, 13) -#define HTT_TX_WBM_COMP_INFO1_REINJECT_REASON GENMASK(3, 0) -#define HTT_TX_WBM_COMP_INFO1_EXCEPTION_FRAME BIT(4) - -#define HTT_TX_WBM_COMP_INFO2_ACK_RSSI GENMASK(31, 24) - -struct htt_tx_wbm_completion { - __le32 rsvd0[2]; - __le32 info0; - __le32 info1; - __le32 info2; - __le32 info3; - __le32 info4; - __le32 rsvd1; - -} __packed; - -enum htt_h2t_msg_type { - HTT_H2T_MSG_TYPE_VERSION_REQ = 0, - HTT_H2T_MSG_TYPE_SRING_SETUP = 0xb, - HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG = 0xc, - HTT_H2T_MSG_TYPE_EXT_STATS_CFG = 0x10, - HTT_H2T_MSG_TYPE_PPDU_STATS_CFG = 0x11, - HTT_H2T_MSG_TYPE_VDEV_TXRX_STATS_CFG = 0x1a, - HTT_H2T_MSG_TYPE_TX_MONITOR_CFG = 0x1b, -}; - -#define HTT_VER_REQ_INFO_MSG_ID GENMASK(7, 0) -#define HTT_OPTION_TCL_METADATA_VER_V1 1 -#define HTT_OPTION_TCL_METADATA_VER_V2 2 -#define HTT_OPTION_TAG GENMASK(7, 0) -#define HTT_OPTION_LEN GENMASK(15, 8) -#define HTT_OPTION_VALUE GENMASK(31, 16) -#define HTT_TCL_METADATA_VER_SZ 4 - -struct htt_ver_req_cmd { - __le32 ver_reg_info; - __le32 tcl_metadata_version; -} __packed; - -enum htt_srng_ring_type { - HTT_HW_TO_SW_RING, - HTT_SW_TO_HW_RING, - HTT_SW_TO_SW_RING, -}; - -enum htt_srng_ring_id { - HTT_RXDMA_HOST_BUF_RING, - HTT_RXDMA_MONITOR_STATUS_RING, - HTT_RXDMA_MONITOR_BUF_RING, - HTT_RXDMA_MONITOR_DESC_RING, - HTT_RXDMA_MONITOR_DEST_RING, - HTT_HOST1_TO_FW_RXBUF_RING, - HTT_HOST2_TO_FW_RXBUF_RING, - HTT_RXDMA_NON_MONITOR_DEST_RING, - HTT_RXDMA_HOST_BUF_RING2, - HTT_TX_MON_HOST2MON_BUF_RING, - HTT_TX_MON_MON2HOST_DEST_RING, - HTT_RX_MON_HOST2MON_BUF_RING, - HTT_RX_MON_MON2HOST_DEST_RING, -}; - -/* host -> target HTT_SRING_SETUP message - * - * After target is booted up, Host can send SRING setup message for - * each host facing LMAC SRING. Target setups up HW registers based - * on setup message and confirms back to Host if response_required is set. - * Host should wait for confirmation message before sending new SRING - * setup message - * - * The message would appear as follows: - * - * |31 24|23 20|19|18 16|15|14 8|7 0| - * |--------------- +-----------------+----------------+------------------| - * | ring_type | ring_id | pdev_id | msg_type | - * |----------------------------------------------------------------------| - * | ring_base_addr_lo | - * |----------------------------------------------------------------------| - * | ring_base_addr_hi | - * |----------------------------------------------------------------------| - * |ring_misc_cfg_flag|ring_entry_size| ring_size | - * |----------------------------------------------------------------------| - * | ring_head_offset32_remote_addr_lo | - * |----------------------------------------------------------------------| - * | ring_head_offset32_remote_addr_hi | - * |----------------------------------------------------------------------| - * | ring_tail_offset32_remote_addr_lo | - * |----------------------------------------------------------------------| - * | ring_tail_offset32_remote_addr_hi | - * |----------------------------------------------------------------------| - * | ring_msi_addr_lo | - * |----------------------------------------------------------------------| - * | ring_msi_addr_hi | - * |----------------------------------------------------------------------| - * | ring_msi_data | - * |----------------------------------------------------------------------| - * | intr_timer_th |IM| intr_batch_counter_th | - * |----------------------------------------------------------------------| - * | reserved |RR|PTCF| intr_low_threshold | - * |----------------------------------------------------------------------| - * Where - * IM = sw_intr_mode - * RR = response_required - * PTCF = prefetch_timer_cfg - * - * The message is interpreted as follows: - * dword0 - b'0:7 - msg_type: This will be set to - * HTT_H2T_MSG_TYPE_SRING_SETUP - * b'8:15 - pdev_id: - * 0 (for rings at SOC/UMAC level), - * 1/2/3 mac id (for rings at LMAC level) - * b'16:23 - ring_id: identify which ring is to setup, - * more details can be got from enum htt_srng_ring_id - * b'24:31 - ring_type: identify type of host rings, - * more details can be got from enum htt_srng_ring_type - * dword1 - b'0:31 - ring_base_addr_lo: Lower 32bits of ring base address - * dword2 - b'0:31 - ring_base_addr_hi: Upper 32bits of ring base address - * dword3 - b'0:15 - ring_size: size of the ring in unit of 4-bytes words - * b'16:23 - ring_entry_size: Size of each entry in 4-byte word units - * b'24:31 - ring_misc_cfg_flag: Valid only for HW_TO_SW_RING and - * SW_TO_HW_RING. - * Refer to HTT_SRING_SETUP_RING_MISC_CFG_RING defs. - * dword4 - b'0:31 - ring_head_off32_remote_addr_lo: - * Lower 32 bits of memory address of the remote variable - * storing the 4-byte word offset that identifies the head - * element within the ring. - * (The head offset variable has type u32.) - * Valid for HW_TO_SW and SW_TO_SW rings. - * dword5 - b'0:31 - ring_head_off32_remote_addr_hi: - * Upper 32 bits of memory address of the remote variable - * storing the 4-byte word offset that identifies the head - * element within the ring. - * (The head offset variable has type u32.) - * Valid for HW_TO_SW and SW_TO_SW rings. - * dword6 - b'0:31 - ring_tail_off32_remote_addr_lo: - * Lower 32 bits of memory address of the remote variable - * storing the 4-byte word offset that identifies the tail - * element within the ring. - * (The tail offset variable has type u32.) - * Valid for HW_TO_SW and SW_TO_SW rings. - * dword7 - b'0:31 - ring_tail_off32_remote_addr_hi: - * Upper 32 bits of memory address of the remote variable - * storing the 4-byte word offset that identifies the tail - * element within the ring. - * (The tail offset variable has type u32.) - * Valid for HW_TO_SW and SW_TO_SW rings. - * dword8 - b'0:31 - ring_msi_addr_lo: Lower 32bits of MSI cfg address - * valid only for HW_TO_SW_RING and SW_TO_HW_RING - * dword9 - b'0:31 - ring_msi_addr_hi: Upper 32bits of MSI cfg address - * valid only for HW_TO_SW_RING and SW_TO_HW_RING - * dword10 - b'0:31 - ring_msi_data: MSI data - * Refer to HTT_SRING_SETUP_RING_MSC_CFG_xxx defs - * valid only for HW_TO_SW_RING and SW_TO_HW_RING - * dword11 - b'0:14 - intr_batch_counter_th: - * batch counter threshold is in units of 4-byte words. - * HW internally maintains and increments batch count. - * (see SRING spec for detail description). - * When batch count reaches threshold value, an interrupt - * is generated by HW. - * b'15 - sw_intr_mode: - * This configuration shall be static. - * Only programmed at power up. - * 0: generate pulse style sw interrupts - * 1: generate level style sw interrupts - * b'16:31 - intr_timer_th: - * The timer init value when timer is idle or is - * initialized to start downcounting. - * In 8us units (to cover a range of 0 to 524 ms) - * dword12 - b'0:15 - intr_low_threshold: - * Used only by Consumer ring to generate ring_sw_int_p. - * Ring entries low threshold water mark, that is used - * in combination with the interrupt timer as well as - * the clearing of the level interrupt. - * b'16:18 - prefetch_timer_cfg: - * Used only by Consumer ring to set timer mode to - * support Application prefetch handling. - * The external tail offset/pointer will be updated - * at following intervals: - * 3'b000: (Prefetch feature disabled; used only for debug) - * 3'b001: 1 usec - * 3'b010: 4 usec - * 3'b011: 8 usec (default) - * 3'b100: 16 usec - * Others: Reserved - * b'19 - response_required: - * Host needs HTT_T2H_MSG_TYPE_SRING_SETUP_DONE as response - * b'20:31 - reserved: reserved for future use - */ - -#define HTT_SRNG_SETUP_CMD_INFO0_MSG_TYPE GENMASK(7, 0) -#define HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID GENMASK(15, 8) -#define HTT_SRNG_SETUP_CMD_INFO0_RING_ID GENMASK(23, 16) -#define HTT_SRNG_SETUP_CMD_INFO0_RING_TYPE GENMASK(31, 24) - -#define HTT_SRNG_SETUP_CMD_INFO1_RING_SIZE GENMASK(15, 0) -#define HTT_SRNG_SETUP_CMD_INFO1_RING_ENTRY_SIZE GENMASK(23, 16) -#define HTT_SRNG_SETUP_CMD_INFO1_RING_LOOP_CNT_DIS BIT(25) -#define HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_MSI_SWAP BIT(27) -#define HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_HOST_FW_SWAP BIT(28) -#define HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_TLV_SWAP BIT(29) - -#define HTT_SRNG_SETUP_CMD_INTR_INFO_BATCH_COUNTER_THRESH GENMASK(14, 0) -#define HTT_SRNG_SETUP_CMD_INTR_INFO_SW_INTR_MODE BIT(15) -#define HTT_SRNG_SETUP_CMD_INTR_INFO_INTR_TIMER_THRESH GENMASK(31, 16) - -#define HTT_SRNG_SETUP_CMD_INFO2_INTR_LOW_THRESH GENMASK(15, 0) -#define HTT_SRNG_SETUP_CMD_INFO2_PRE_FETCH_TIMER_CFG GENMASK(18, 16) -#define HTT_SRNG_SETUP_CMD_INFO2_RESPONSE_REQUIRED BIT(19) - -struct htt_srng_setup_cmd { - __le32 info0; - __le32 ring_base_addr_lo; - __le32 ring_base_addr_hi; - __le32 info1; - __le32 ring_head_off32_remote_addr_lo; - __le32 ring_head_off32_remote_addr_hi; - __le32 ring_tail_off32_remote_addr_lo; - __le32 ring_tail_off32_remote_addr_hi; - __le32 ring_msi_addr_lo; - __le32 ring_msi_addr_hi; - __le32 msi_data; - __le32 intr_info; - __le32 info2; -} __packed; - -/* host -> target FW PPDU_STATS config message - * - * @details - * The following field definitions describe the format of the HTT host - * to target FW for PPDU_STATS_CFG msg. - * The message allows the host to configure the PPDU_STATS_IND messages - * produced by the target. - * - * |31 24|23 16|15 8|7 0| - * |-----------------------------------------------------------| - * | REQ bit mask | pdev_mask | msg type | - * |-----------------------------------------------------------| - * Header fields: - * - MSG_TYPE - * Bits 7:0 - * Purpose: identifies this is a req to configure ppdu_stats_ind from target - * Value: 0x11 - * - PDEV_MASK - * Bits 8:15 - * Purpose: identifies which pdevs this PPDU stats configuration applies to - * Value: This is a overloaded field, refer to usage and interpretation of - * PDEV in interface document. - * Bit 8 : Reserved for SOC stats - * Bit 9 - 15 : Indicates PDEV_MASK in DBDC - * Indicates MACID_MASK in DBS - * - REQ_TLV_BIT_MASK - * Bits 16:31 - * Purpose: each set bit indicates the corresponding PPDU stats TLV type - * needs to be included in the target's PPDU_STATS_IND messages. - * Value: refer htt_ppdu_stats_tlv_tag_t << 30 bits - * Refer to PKT_TYPE_ENABLE_FLAG0_xxx_MGMT_xxx defs - * dword3 - b'0:31 - packet_type_enable_flags_1: - * Enable MGMT packet from 0b1010 to 0b1111 - * bits from low to high: FP, MD, MO - 3 bits - * Refer to PKT_TYPE_ENABLE_FLAG1_xxx_MGMT_xxx defs - * dword4 - b'0:31 - packet_type_enable_flags_2: - * Enable CTRL packet from 0b0000 to 0b1001 - * bits from low to high: FP, MD, MO - 3 bits - * Refer to PKT_TYPE_ENABLE_FLAG2_xxx_CTRL_xxx defs - * dword5 - b'0:31 - packet_type_enable_flags_3: - * Enable CTRL packet from 0b1010 to 0b1111, - * MCAST_DATA, UCAST_DATA, NULL_DATA - * bits from low to high: FP, MD, MO - 3 bits - * Refer to PKT_TYPE_ENABLE_FLAG3_xxx_CTRL_xxx defs - * dword6 - b'0:31 - tlv_filter_in_flags: - * Filter in Attention/MPDU/PPDU/Header/User tlvs - * Refer to CFG_TLV_FILTER_IN_FLAG defs - */ - -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID GENMASK(15, 8) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_RING_ID GENMASK(23, 16) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_SS BIT(24) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS BIT(25) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_OFFSET_VALID BIT(26) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_DROP_THRES_VAL BIT(27) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_EN_RXMON BIT(28) - -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE GENMASK(15, 0) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT GENMASK(18, 16) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL GENMASK(21, 19) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA GENMASK(24, 22) - -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_DROP_THRESHOLD GENMASK(9, 0) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_MGMT_TYPE BIT(17) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_CTRL_TYPE BIT(18) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_DATA_TYPE BIT(19) - -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO3_EN_TLV_PKT_OFFSET BIT(0) -#define HTT_RX_RING_SELECTION_CFG_CMD_INFO3_PKT_TLV_OFFSET GENMASK(14, 1) - -#define HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET GENMASK(15, 0) -#define HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET GENMASK(31, 16) -#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET GENMASK(15, 0) -#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET GENMASK(31, 16) -#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET GENMASK(15, 0) -#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET GENMASK(31, 16) -#define HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET GENMASK(15, 0) - -#define HTT_RX_RING_SELECTION_CFG_WORD_MASK_COMPACT_SET BIT(23) -#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_MASK GENMASK(15, 0) -#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_MASK GENMASK(18, 16) -#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_MASK GENMASK(16, 0) - -enum htt_rx_filter_tlv_flags { - HTT_RX_FILTER_TLV_FLAGS_MPDU_START = BIT(0), - HTT_RX_FILTER_TLV_FLAGS_MSDU_START = BIT(1), - HTT_RX_FILTER_TLV_FLAGS_RX_PACKET = BIT(2), - HTT_RX_FILTER_TLV_FLAGS_MSDU_END = BIT(3), - HTT_RX_FILTER_TLV_FLAGS_MPDU_END = BIT(4), - HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER = BIT(5), - HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER = BIT(6), - HTT_RX_FILTER_TLV_FLAGS_ATTENTION = BIT(7), - HTT_RX_FILTER_TLV_FLAGS_PPDU_START = BIT(8), - HTT_RX_FILTER_TLV_FLAGS_PPDU_END = BIT(9), - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS = BIT(10), - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT = BIT(11), - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE = BIT(12), - HTT_RX_FILTER_TLV_FLAGS_PPDU_START_USER_INFO = BIT(13), -}; - -enum htt_rx_mgmt_pkt_filter_tlv_flags0 { - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ = BIT(0), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ = BIT(1), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ = BIT(2), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP = BIT(3), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP = BIT(4), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP = BIT(5), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ = BIT(6), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ = BIT(7), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ = BIT(8), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP = BIT(9), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP = BIT(10), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP = BIT(11), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ = BIT(12), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ = BIT(13), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ = BIT(14), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP = BIT(15), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP = BIT(16), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP = BIT(17), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV = BIT(18), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV = BIT(19), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV = BIT(20), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7 = BIT(21), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7 = BIT(22), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7 = BIT(23), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON = BIT(24), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON = BIT(25), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON = BIT(26), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM = BIT(27), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM = BIT(28), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM = BIT(29), -}; - -enum htt_rx_mgmt_pkt_filter_tlv_flags1 { - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC = BIT(0), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC = BIT(1), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC = BIT(2), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH = BIT(3), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH = BIT(4), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH = BIT(5), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH = BIT(6), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH = BIT(7), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH = BIT(8), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION = BIT(9), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION = BIT(10), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION = BIT(11), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK = BIT(12), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK = BIT(13), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK = BIT(14), - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15 = BIT(15), - HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15 = BIT(16), - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15 = BIT(17), -}; - -enum htt_rx_ctrl_pkt_filter_tlv_flags2 { - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 = BIT(0), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 = BIT(1), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 = BIT(2), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 = BIT(3), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 = BIT(4), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 = BIT(5), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER = BIT(6), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER = BIT(7), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER = BIT(8), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 = BIT(9), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 = BIT(10), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 = BIT(11), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL = BIT(12), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL = BIT(13), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL = BIT(14), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP = BIT(15), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP = BIT(16), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP = BIT(17), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT = BIT(18), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT = BIT(19), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT = BIT(20), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER = BIT(21), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER = BIT(22), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER = BIT(23), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR = BIT(24), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BAR = BIT(25), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BAR = BIT(26), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BA = BIT(27), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BA = BIT(28), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BA = BIT(29), -}; - -enum htt_rx_ctrl_pkt_filter_tlv_flags3 { - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL = BIT(0), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL = BIT(1), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL = BIT(2), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_RTS = BIT(3), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_RTS = BIT(4), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_RTS = BIT(5), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CTS = BIT(6), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CTS = BIT(7), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CTS = BIT(8), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_ACK = BIT(9), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_ACK = BIT(10), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_ACK = BIT(11), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND = BIT(12), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND = BIT(13), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND = BIT(14), - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK = BIT(15), - HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK = BIT(16), - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK = BIT(17), -}; - -enum htt_rx_data_pkt_filter_tlv_flasg3 { - HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST = BIT(18), - HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_MCAST = BIT(19), - HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_MCAST = BIT(20), - HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST = BIT(21), - HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_UCAST = BIT(22), - HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_UCAST = BIT(23), - HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA = BIT(24), - HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA = BIT(25), - HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA = BIT(26), -}; - -#define HTT_RX_FP_MGMT_FILTER_FLAGS0 \ - (HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM) - -#define HTT_RX_MD_MGMT_FILTER_FLAGS0 \ - (HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM) - -#define HTT_RX_MO_MGMT_FILTER_FLAGS0 \ - (HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM) - -#define HTT_RX_FP_MGMT_FILTER_FLAGS1 (HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION \ - | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK) - -#define HTT_RX_MD_MGMT_FILTER_FLAGS1 (HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION \ - | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK) - -#define HTT_RX_MO_MGMT_FILTER_FLAGS1 (HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION \ - | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK) - -#define HTT_RX_FP_CTRL_FILTER_FLASG2 (HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER \ - | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR \ - | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BA) - -#define HTT_RX_MD_CTRL_FILTER_FLASG2 (HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER \ - | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BAR \ - | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BA) - -#define HTT_RX_MO_CTRL_FILTER_FLASG2 (HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER \ - | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BAR \ - | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BA) - -#define HTT_RX_FP_CTRL_FILTER_FLASG3 (HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL \ - | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_RTS \ - | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CTS \ - | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_ACK \ - | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND \ - | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK) - -#define HTT_RX_MD_CTRL_FILTER_FLASG3 (HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL \ - | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_RTS \ - | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CTS \ - | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_ACK \ - | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND \ - | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK) - -#define HTT_RX_MO_CTRL_FILTER_FLASG3 (HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL \ - | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_RTS \ - | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CTS \ - | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_ACK \ - | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND \ - | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK) - -#define HTT_RX_FP_DATA_FILTER_FLASG3 (HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST \ - | HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST \ - | HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA) - -#define HTT_RX_MD_DATA_FILTER_FLASG3 (HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_MCAST \ - | HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_UCAST \ - | HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA) - -#define HTT_RX_MO_DATA_FILTER_FLASG3 (HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_MCAST \ - | HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_UCAST \ - | HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA) - -#define HTT_RX_MON_FP_MGMT_FILTER_FLAGS0 \ - (HTT_RX_FP_MGMT_FILTER_FLAGS0 | \ - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7) - -#define HTT_RX_MON_MO_MGMT_FILTER_FLAGS0 \ - (HTT_RX_MO_MGMT_FILTER_FLAGS0 | \ - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7) - -#define HTT_RX_MON_FP_MGMT_FILTER_FLAGS1 \ - (HTT_RX_FP_MGMT_FILTER_FLAGS1 | \ - HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15) - -#define HTT_RX_MON_MO_MGMT_FILTER_FLAGS1 \ - (HTT_RX_MO_MGMT_FILTER_FLAGS1 | \ - HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15) - -#define HTT_RX_MON_FP_CTRL_FILTER_FLASG2 \ - (HTT_RX_FP_CTRL_FILTER_FLASG2 | \ - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 | \ - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 | \ - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER | \ - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 | \ - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL | \ - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP | \ - HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT) - -#define HTT_RX_MON_MO_CTRL_FILTER_FLASG2 \ - (HTT_RX_MO_CTRL_FILTER_FLASG2 | \ - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 | \ - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 | \ - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER | \ - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 | \ - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL | \ - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP | \ - HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT) - -#define HTT_RX_MON_FP_CTRL_FILTER_FLASG3 HTT_RX_FP_CTRL_FILTER_FLASG3 - -#define HTT_RX_MON_MO_CTRL_FILTER_FLASG3 HTT_RX_MO_CTRL_FILTER_FLASG3 - -#define HTT_RX_MON_FP_DATA_FILTER_FLASG3 HTT_RX_FP_DATA_FILTER_FLASG3 - -#define HTT_RX_MON_MO_DATA_FILTER_FLASG3 HTT_RX_MO_DATA_FILTER_FLASG3 - -#define HTT_RX_MON_FILTER_TLV_FLAGS \ - (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE) - -#define HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING \ - (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE) - -#define HTT_RX_MON_FILTER_TLV_FLAGS_MON_BUF_RING \ - (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \ - HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \ - HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \ - HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER | \ - HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \ - HTT_RX_FILTER_TLV_FLAGS_ATTENTION) - -#define HTT_RX_MON_FILTER_TLV_FLAGS_MON_DEST_RING \ - (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \ - HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \ - HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \ - HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER | \ - HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \ - HTT_RX_FILTER_TLV_FLAGS_PPDU_START_USER_INFO) - -/* msdu start. mpdu end, attention, rx hdr tlv's are not subscribed */ -#define HTT_RX_TLV_FLAGS_RXDMA_RING \ - (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ - HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \ - HTT_RX_FILTER_TLV_FLAGS_MSDU_END) - -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID GENMASK(15, 8) - -struct htt_rx_ring_selection_cfg_cmd { - __le32 info0; - __le32 info1; - __le32 pkt_type_en_flags0; - __le32 pkt_type_en_flags1; - __le32 pkt_type_en_flags2; - __le32 pkt_type_en_flags3; - __le32 rx_filter_tlv; - __le32 rx_packet_offset; - __le32 rx_mpdu_offset; - __le32 rx_msdu_offset; - __le32 rx_attn_offset; - __le32 info2; - __le32 reserved[2]; - __le32 rx_mpdu_start_end_mask; - __le32 rx_msdu_end_word_mask; - __le32 info3; -} __packed; - -#define HTT_RX_RING_TLV_DROP_THRESHOLD_VALUE 32 -#define HTT_RX_RING_DEFAULT_DMA_LENGTH 0x7 -#define HTT_RX_RING_PKT_TLV_OFFSET 0x1 - -struct htt_rx_ring_tlv_filter { - u32 rx_filter; /* see htt_rx_filter_tlv_flags */ - u32 pkt_filter_flags0; /* MGMT */ - u32 pkt_filter_flags1; /* MGMT */ - u32 pkt_filter_flags2; /* CTRL */ - u32 pkt_filter_flags3; /* DATA */ - bool offset_valid; - u16 rx_packet_offset; - u16 rx_header_offset; - u16 rx_mpdu_end_offset; - u16 rx_mpdu_start_offset; - u16 rx_msdu_end_offset; - u16 rx_msdu_start_offset; - u16 rx_attn_offset; - u16 rx_mpdu_start_wmask; - u16 rx_mpdu_end_wmask; - u32 rx_msdu_end_wmask; - u32 conf_len_ctrl; - u32 conf_len_mgmt; - u32 conf_len_data; - u16 rx_drop_threshold; - bool enable_log_mgmt_type; - bool enable_log_ctrl_type; - bool enable_log_data_type; - bool enable_rx_tlv_offset; - u16 rx_tlv_offset; - bool drop_threshold_valid; - bool rxmon_disable; -}; - -#define HTT_STATS_FRAME_CTRL_TYPE_MGMT 0x0 -#define HTT_STATS_FRAME_CTRL_TYPE_CTRL 0x1 -#define HTT_STATS_FRAME_CTRL_TYPE_DATA 0x2 -#define HTT_STATS_FRAME_CTRL_TYPE_RESV 0x3 - -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID GENMASK(15, 8) -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_RING_ID GENMASK(23, 16) -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_SS BIT(24) -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PS BIT(25) - -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_RING_BUFF_SIZE GENMASK(15, 0) -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE GENMASK(18, 16) -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT GENMASK(21, 19) -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL GENMASK(24, 22) -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA GENMASK(27, 25) - -#define HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG GENMASK(2, 0) - -struct htt_tx_ring_selection_cfg_cmd { - __le32 info0; - __le32 info1; - __le32 info2; - __le32 tlv_filter_mask_in0; - __le32 tlv_filter_mask_in1; - __le32 tlv_filter_mask_in2; - __le32 tlv_filter_mask_in3; - __le32 reserved[3]; -} __packed; - -#define HTT_TX_RING_TLV_FILTER_MGMT_DMA_LEN GENMASK(3, 0) -#define HTT_TX_RING_TLV_FILTER_CTRL_DMA_LEN GENMASK(7, 4) -#define HTT_TX_RING_TLV_FILTER_DATA_DMA_LEN GENMASK(11, 8) - -#define HTT_TX_MON_FILTER_HYBRID_MODE \ - (HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_START_STATUS | \ - HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_END_STATUS | \ - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START | \ - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_END | \ - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PPDU | \ - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_PPDU | \ - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_ACK_OR_BA | \ - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_1K_BA | \ - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PROT | \ - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_PROT | \ - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_RESPONSE | \ - HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO | \ - HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO_PART2) - -struct htt_tx_ring_tlv_filter { - u32 tx_mon_downstream_tlv_flags; - u32 tx_mon_upstream_tlv_flags0; - u32 tx_mon_upstream_tlv_flags1; - u32 tx_mon_upstream_tlv_flags2; - bool tx_mon_mgmt_filter; - bool tx_mon_data_filter; - bool tx_mon_ctrl_filter; - u16 tx_mon_pkt_dma_len; -} __packed; - -enum htt_tx_mon_upstream_tlv_flags0 { - HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_START_STATUS = BIT(1), - HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_END_STATUS = BIT(2), - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START = BIT(3), - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_END = BIT(4), - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PPDU = BIT(5), - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_PPDU = BIT(6), - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_ACK_OR_BA = BIT(7), - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_1K_BA = BIT(8), - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PROT = BIT(9), - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_PROT = BIT(10), - HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_RESPONSE = BIT(11), - HTT_TX_FILTER_TLV_FLAGS0_RX_FRAME_BITMAP_ACK = BIT(12), - HTT_TX_FILTER_TLV_FLAGS0_RX_FRAME_1K_BITMAP_ACK = BIT(13), - HTT_TX_FILTER_TLV_FLAGS0_COEX_TX_STATUS = BIT(14), - HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO = BIT(15), - HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO_PART2 = BIT(16), -}; - -#define HTT_TX_FILTER_TLV_FLAGS2_TXPCU_PHYTX_OTHER_TRANSMIT_INFO32 BIT(11) - -/* HTT message target->host */ - -enum htt_t2h_msg_type { - HTT_T2H_MSG_TYPE_VERSION_CONF, - HTT_T2H_MSG_TYPE_PEER_MAP = 0x3, - HTT_T2H_MSG_TYPE_PEER_UNMAP = 0x4, - HTT_T2H_MSG_TYPE_RX_ADDBA = 0x5, - HTT_T2H_MSG_TYPE_PKTLOG = 0x8, - HTT_T2H_MSG_TYPE_SEC_IND = 0xb, - HTT_T2H_MSG_TYPE_PEER_MAP2 = 0x1e, - HTT_T2H_MSG_TYPE_PEER_UNMAP2 = 0x1f, - HTT_T2H_MSG_TYPE_PPDU_STATS_IND = 0x1d, - HTT_T2H_MSG_TYPE_EXT_STATS_CONF = 0x1c, - HTT_T2H_MSG_TYPE_BKPRESSURE_EVENT_IND = 0x24, - HTT_T2H_MSG_TYPE_MLO_TIMESTAMP_OFFSET_IND = 0x28, - HTT_T2H_MSG_TYPE_PEER_MAP3 = 0x2b, - HTT_T2H_MSG_TYPE_VDEV_TXRX_STATS_PERIODIC_IND = 0x2c, -}; - -#define HTT_TARGET_VERSION_MAJOR 3 - -#define HTT_T2H_MSG_TYPE GENMASK(7, 0) -#define HTT_T2H_VERSION_CONF_MINOR GENMASK(15, 8) -#define HTT_T2H_VERSION_CONF_MAJOR GENMASK(23, 16) - -struct htt_t2h_version_conf_msg { - __le32 version; -} __packed; - -#define HTT_T2H_PEER_MAP_INFO_VDEV_ID GENMASK(15, 8) -#define HTT_T2H_PEER_MAP_INFO_PEER_ID GENMASK(31, 16) -#define HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16 GENMASK(15, 0) -#define HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID GENMASK(31, 16) -#define HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL GENMASK(15, 0) -#define HTT_T2H_PEER_MAP3_INFO2_HW_PEER_ID GENMASK(15, 0) -#define HTT_T2H_PEER_MAP3_INFO2_AST_HASH_VAL GENMASK(31, 16) -#define HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M BIT(16) -#define HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_S 16 - -struct htt_t2h_peer_map_event { - __le32 info; - __le32 mac_addr_l32; - __le32 info1; - __le32 info2; -} __packed; - -#define HTT_T2H_PEER_UNMAP_INFO_VDEV_ID HTT_T2H_PEER_MAP_INFO_VDEV_ID -#define HTT_T2H_PEER_UNMAP_INFO_PEER_ID HTT_T2H_PEER_MAP_INFO_PEER_ID -#define HTT_T2H_PEER_UNMAP_INFO1_MAC_ADDR_H16 \ - HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16 -#define HTT_T2H_PEER_MAP_INFO1_NEXT_HOP_M HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M -#define HTT_T2H_PEER_MAP_INFO1_NEXT_HOP_S HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_S - -struct htt_t2h_peer_unmap_event { - __le32 info; - __le32 mac_addr_l32; - __le32 info1; -} __packed; - -struct htt_resp_msg { - union { - struct htt_t2h_version_conf_msg version_msg; - struct htt_t2h_peer_map_event peer_map_ev; - struct htt_t2h_peer_unmap_event peer_unmap_ev; - }; -} __packed; - -#define HTT_VDEV_GET_STATS_U64(msg_l32, msg_u32)\ - (((u64)__le32_to_cpu(msg_u32) << 32) | (__le32_to_cpu(msg_l32))) -#define HTT_T2H_VDEV_STATS_PERIODIC_MSG_TYPE GENMASK(7, 0) -#define HTT_T2H_VDEV_STATS_PERIODIC_PDEV_ID GENMASK(15, 8) -#define HTT_T2H_VDEV_STATS_PERIODIC_NUM_VDEV GENMASK(23, 16) -#define HTT_T2H_VDEV_STATS_PERIODIC_PAYLOAD_BYTES GENMASK(15, 0) -#define HTT_VDEV_TXRX_STATS_COMMON_TLV 0 -#define HTT_VDEV_TXRX_STATS_HW_STATS_TLV 1 - -struct htt_t2h_vdev_txrx_stats_ind { - __le32 vdev_id; - __le32 rx_msdu_byte_cnt_lo; - __le32 rx_msdu_byte_cnt_hi; - __le32 rx_msdu_cnt_lo; - __le32 rx_msdu_cnt_hi; - __le32 tx_msdu_byte_cnt_lo; - __le32 tx_msdu_byte_cnt_hi; - __le32 tx_msdu_cnt_lo; - __le32 tx_msdu_cnt_hi; - __le32 tx_retry_cnt_lo; - __le32 tx_retry_cnt_hi; - __le32 tx_retry_byte_cnt_lo; - __le32 tx_retry_byte_cnt_hi; - __le32 tx_drop_cnt_lo; - __le32 tx_drop_cnt_hi; - __le32 tx_drop_byte_cnt_lo; - __le32 tx_drop_byte_cnt_hi; - __le32 msdu_ttl_cnt_lo; - __le32 msdu_ttl_cnt_hi; - __le32 msdu_ttl_byte_cnt_lo; - __le32 msdu_ttl_byte_cnt_hi; -} __packed; - -struct htt_t2h_vdev_common_stats_tlv { - __le32 soc_drop_count_lo; - __le32 soc_drop_count_hi; -} __packed; - -/* ppdu stats - * - * @details - * The following field definitions describe the format of the HTT target - * to host ppdu stats indication message. - * - * - * |31 16|15 12|11 10|9 8|7 0 | - * |----------------------------------------------------------------------| - * | payload_size | rsvd |pdev_id|mac_id | msg type | - * |----------------------------------------------------------------------| - * | ppdu_id | - * |----------------------------------------------------------------------| - * | Timestamp in us | - * |----------------------------------------------------------------------| - * | reserved | - * |----------------------------------------------------------------------| - * | type-specific stats info | - * | (see htt_ppdu_stats.h) | - * |----------------------------------------------------------------------| - * Header fields: - * - MSG_TYPE - * Bits 7:0 - * Purpose: Identifies this is a PPDU STATS indication - * message. - * Value: 0x1d - * - mac_id - * Bits 9:8 - * Purpose: mac_id of this ppdu_id - * Value: 0-3 - * - pdev_id - * Bits 11:10 - * Purpose: pdev_id of this ppdu_id - * Value: 0-3 - * 0 (for rings at SOC level), - * 1/2/3 PDEV -> 0/1/2 - * - payload_size - * Bits 31:16 - * Purpose: total tlv size - * Value: payload_size in bytes - */ - -#define HTT_T2H_PPDU_STATS_INFO_PDEV_ID GENMASK(11, 10) -#define HTT_T2H_PPDU_STATS_INFO_PAYLOAD_SIZE GENMASK(31, 16) - -struct ath12k_htt_ppdu_stats_msg { - __le32 info; - __le32 ppdu_id; - __le32 timestamp; - __le32 rsvd; - u8 data[]; -} __packed; - -struct htt_tlv { - __le32 header; - u8 value[]; -} __packed; - -#define HTT_TLV_TAG GENMASK(11, 0) -#define HTT_TLV_LEN GENMASK(23, 12) - -enum HTT_PPDU_STATS_BW { - HTT_PPDU_STATS_BANDWIDTH_5MHZ = 0, - HTT_PPDU_STATS_BANDWIDTH_10MHZ = 1, - HTT_PPDU_STATS_BANDWIDTH_20MHZ = 2, - HTT_PPDU_STATS_BANDWIDTH_40MHZ = 3, - HTT_PPDU_STATS_BANDWIDTH_80MHZ = 4, - HTT_PPDU_STATS_BANDWIDTH_160MHZ = 5, /* includes 80+80 */ - HTT_PPDU_STATS_BANDWIDTH_DYN = 6, -}; - -#define HTT_PPDU_STATS_CMN_FLAGS_FRAME_TYPE_M GENMASK(7, 0) -#define HTT_PPDU_STATS_CMN_FLAGS_QUEUE_TYPE_M GENMASK(15, 8) -/* bw - HTT_PPDU_STATS_BW */ -#define HTT_PPDU_STATS_CMN_FLAGS_BW_M GENMASK(19, 16) - -struct htt_ppdu_stats_common { - __le32 ppdu_id; - __le16 sched_cmdid; - u8 ring_id; - u8 num_users; - __le32 flags; /* %HTT_PPDU_STATS_COMMON_FLAGS_*/ - __le32 chain_mask; - __le32 fes_duration_us; /* frame exchange sequence */ - __le32 ppdu_sch_eval_start_tstmp_us; - __le32 ppdu_sch_end_tstmp_us; - __le32 ppdu_start_tstmp_us; - /* BIT [15 : 0] - phy mode (WLAN_PHY_MODE) with which ppdu was transmitted - * BIT [31 : 16] - bandwidth (in MHz) with which ppdu was transmitted - */ - __le16 phy_mode; - __le16 bw_mhz; -} __packed; - -enum htt_ppdu_stats_gi { - HTT_PPDU_STATS_SGI_0_8_US, - HTT_PPDU_STATS_SGI_0_4_US, - HTT_PPDU_STATS_SGI_1_6_US, - HTT_PPDU_STATS_SGI_3_2_US, -}; - -#define HTT_PPDU_STATS_USER_RATE_INFO0_USER_POS_M GENMASK(3, 0) -#define HTT_PPDU_STATS_USER_RATE_INFO0_MU_GROUP_ID_M GENMASK(11, 4) - -enum HTT_PPDU_STATS_PPDU_TYPE { - HTT_PPDU_STATS_PPDU_TYPE_SU, - HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO, - HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA, - HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA, - HTT_PPDU_STATS_PPDU_TYPE_UL_TRIG, - HTT_PPDU_STATS_PPDU_TYPE_BURST_BCN, - HTT_PPDU_STATS_PPDU_TYPE_UL_BSR_RESP, - HTT_PPDU_STATS_PPDU_TYPE_UL_BSR_TRIG, - HTT_PPDU_STATS_PPDU_TYPE_UL_RESP, - HTT_PPDU_STATS_PPDU_TYPE_MAX -}; - -#define HTT_PPDU_STATS_USER_RATE_INFO1_RESP_TYPE_VALD_M BIT(0) -#define HTT_PPDU_STATS_USER_RATE_INFO1_PPDU_TYPE_M GENMASK(5, 1) - -#define HTT_PPDU_STATS_USER_RATE_FLAGS_LTF_SIZE_M GENMASK(1, 0) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_STBC_M BIT(2) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_HE_RE_M BIT(3) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_TXBF_M GENMASK(7, 4) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_BW_M GENMASK(11, 8) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_NSS_M GENMASK(15, 12) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_MCS_M GENMASK(19, 16) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_PREAMBLE_M GENMASK(23, 20) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_GI_M GENMASK(27, 24) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_DCM_M BIT(28) -#define HTT_PPDU_STATS_USER_RATE_FLAGS_LDPC_M BIT(29) - -#define HTT_USR_RATE_PPDU_TYPE(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_INFO1_PPDU_TYPE_M) -#define HTT_USR_RATE_PREAMBLE(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_PREAMBLE_M) -#define HTT_USR_RATE_BW(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_BW_M) -#define HTT_USR_RATE_NSS(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_NSS_M) -#define HTT_USR_RATE_MCS(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_MCS_M) -#define HTT_USR_RATE_GI(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_GI_M) -#define HTT_USR_RATE_DCM(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_DCM_M) - -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_LTF_SIZE_M GENMASK(1, 0) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_STBC_M BIT(2) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_HE_RE_M BIT(3) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_TXBF_M GENMASK(7, 4) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_BW_M GENMASK(11, 8) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_NSS_M GENMASK(15, 12) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_MCS_M GENMASK(19, 16) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_PREAMBLE_M GENMASK(23, 20) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_GI_M GENMASK(27, 24) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_DCM_M BIT(28) -#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_LDPC_M BIT(29) - -struct htt_ppdu_stats_user_rate { - u8 tid_num; - u8 reserved0; - __le16 sw_peer_id; - __le32 info0; /* %HTT_PPDU_STATS_USER_RATE_INFO0_*/ - __le16 ru_end; - __le16 ru_start; - __le16 resp_ru_end; - __le16 resp_ru_start; - __le32 info1; /* %HTT_PPDU_STATS_USER_RATE_INFO1_ */ - __le32 rate_flags; /* %HTT_PPDU_STATS_USER_RATE_FLAGS_ */ - /* Note: resp_rate_info is only valid for if resp_type is UL */ - __le32 resp_rate_flags; /* %HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_ */ -} __packed; - -#define HTT_PPDU_STATS_TX_INFO_FLAGS_RATECODE_M GENMASK(7, 0) -#define HTT_PPDU_STATS_TX_INFO_FLAGS_IS_AMPDU_M BIT(8) -#define HTT_PPDU_STATS_TX_INFO_FLAGS_BA_ACK_FAILED_M GENMASK(10, 9) -#define HTT_PPDU_STATS_TX_INFO_FLAGS_BW_M GENMASK(13, 11) -#define HTT_PPDU_STATS_TX_INFO_FLAGS_SGI_M BIT(14) -#define HTT_PPDU_STATS_TX_INFO_FLAGS_PEERID_M GENMASK(31, 16) - -#define HTT_TX_INFO_IS_AMSDU(_flags) \ - u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_IS_AMPDU_M) -#define HTT_TX_INFO_BA_ACK_FAILED(_flags) \ - u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_BA_ACK_FAILED_M) -#define HTT_TX_INFO_RATECODE(_flags) \ - u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_RATECODE_M) -#define HTT_TX_INFO_PEERID(_flags) \ - u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_PEERID_M) - -enum htt_ppdu_stats_usr_compln_status { - HTT_PPDU_STATS_USER_STATUS_OK, - HTT_PPDU_STATS_USER_STATUS_FILTERED, - HTT_PPDU_STATS_USER_STATUS_RESP_TIMEOUT, - HTT_PPDU_STATS_USER_STATUS_RESP_MISMATCH, - HTT_PPDU_STATS_USER_STATUS_ABORT, -}; - -#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_LONG_RETRY_M GENMASK(3, 0) -#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_SHORT_RETRY_M GENMASK(7, 4) -#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_IS_AMPDU_M BIT(8) -#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_RESP_TYPE_M GENMASK(12, 9) - -#define HTT_USR_CMPLTN_IS_AMPDU(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_IS_AMPDU_M) -#define HTT_USR_CMPLTN_LONG_RETRY(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_LONG_RETRY_M) -#define HTT_USR_CMPLTN_SHORT_RETRY(_val) \ - le32_get_bits(_val, HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_SHORT_RETRY_M) - -struct htt_ppdu_stats_usr_cmpltn_cmn { - u8 status; - u8 tid_num; - __le16 sw_peer_id; - /* RSSI value of last ack packet (units = dB above noise floor) */ - __le32 ack_rssi; - __le16 mpdu_tried; - __le16 mpdu_success; - __le32 flags; /* %HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_LONG_RETRIES*/ -} __packed; - -#define HTT_PPDU_STATS_ACK_BA_INFO_NUM_MPDU_M GENMASK(8, 0) -#define HTT_PPDU_STATS_ACK_BA_INFO_NUM_MSDU_M GENMASK(24, 9) -#define HTT_PPDU_STATS_ACK_BA_INFO_TID_NUM GENMASK(31, 25) - -#define HTT_PPDU_STATS_NON_QOS_TID 16 - -struct htt_ppdu_stats_usr_cmpltn_ack_ba_status { - __le32 ppdu_id; - __le16 sw_peer_id; - __le16 reserved0; - __le32 info; /* %HTT_PPDU_STATS_USR_CMPLTN_CMN_INFO_ */ - __le16 current_seq; - __le16 start_seq; - __le32 success_bytes; -} __packed; - -struct htt_ppdu_user_stats { - u16 peer_id; - u16 delay_ba; - u32 tlv_flags; - bool is_valid_peer_id; - struct htt_ppdu_stats_user_rate rate; - struct htt_ppdu_stats_usr_cmpltn_cmn cmpltn_cmn; - struct htt_ppdu_stats_usr_cmpltn_ack_ba_status ack_ba; -}; - -#define HTT_PPDU_STATS_MAX_USERS 8 -#define HTT_PPDU_DESC_MAX_DEPTH 16 - -struct htt_ppdu_stats { - struct htt_ppdu_stats_common common; - struct htt_ppdu_user_stats user_stats[HTT_PPDU_STATS_MAX_USERS]; -}; - -struct htt_ppdu_stats_info { - u32 tlv_bitmap; - u32 ppdu_id; - u32 frame_type; - u32 frame_ctrl; - u32 delay_ba; - u32 bar_num_users; - struct htt_ppdu_stats ppdu_stats; - struct list_head list; -}; - -/* @brief target -> host MLO offset indiciation message - * - * @details - * The following field definitions describe the format of the HTT target - * to host mlo offset indication message. - * - * - * |31 29|28 |26|25 22|21 16|15 13|12 10 |9 8|7 0| - * |---------------------------------------------------------------------| - * | rsvd1 | mac_freq |chip_id |pdev_id|msgtype| - * |---------------------------------------------------------------------| - * | sync_timestamp_lo_us | - * |---------------------------------------------------------------------| - * | sync_timestamp_hi_us | - * |---------------------------------------------------------------------| - * | mlo_offset_lo | - * |---------------------------------------------------------------------| - * | mlo_offset_hi | - * |---------------------------------------------------------------------| - * | mlo_offset_clcks | - * |---------------------------------------------------------------------| - * | rsvd2 | mlo_comp_clks |mlo_comp_us | - * |---------------------------------------------------------------------| - * | rsvd3 |mlo_comp_timer | - * |---------------------------------------------------------------------| - * Header fields - * - MSG_TYPE - * Bits 7:0 - * Purpose: Identifies this is a MLO offset indication msg - * - PDEV_ID - * Bits 9:8 - * Purpose: Pdev of this MLO offset - * - CHIP_ID - * Bits 12:10 - * Purpose: chip_id of this MLO offset - * - MAC_FREQ - * Bits 28:13 - * - SYNC_TIMESTAMP_LO_US - * Purpose: clock frequency of the mac HW block in MHz - * Bits: 31:0 - * Purpose: lower 32 bits of the WLAN global time stamp at which - * last sync interrupt was received - * - SYNC_TIMESTAMP_HI_US - * Bits: 31:0 - * Purpose: upper 32 bits of WLAN global time stamp at which - * last sync interrupt was received - * - MLO_OFFSET_LO - * Bits: 31:0 - * Purpose: lower 32 bits of the MLO offset in us - * - MLO_OFFSET_HI - * Bits: 31:0 - * Purpose: upper 32 bits of the MLO offset in us - * - MLO_COMP_US - * Bits: 15:0 - * Purpose: MLO time stamp compensation applied in us - * - MLO_COMP_CLCKS - * Bits: 25:16 - * Purpose: MLO time stamp compensation applied in clock ticks - * - MLO_COMP_TIMER - * Bits: 21:0 - * Purpose: Periodic timer at which compensation is applied - */ - -#define HTT_T2H_MLO_OFFSET_INFO_MSG_TYPE GENMASK(7, 0) -#define HTT_T2H_MLO_OFFSET_INFO_PDEV_ID GENMASK(9, 8) - -struct ath12k_htt_mlo_offset_msg { - __le32 info; - __le32 sync_timestamp_lo_us; - __le32 sync_timestamp_hi_us; - __le32 mlo_offset_hi; - __le32 mlo_offset_lo; - __le32 mlo_offset_clks; - __le32 mlo_comp_clks; - __le32 mlo_comp_timer; -} __packed; - -/* @brief host -> target FW extended statistics retrieve - * - * @details - * The following field definitions describe the format of the HTT host - * to target FW extended stats retrieve message. - * The message specifies the type of stats the host wants to retrieve. - * - * |31 24|23 16|15 8|7 0| - * |-----------------------------------------------------------| - * | reserved | stats type | pdev_mask | msg type | - * |-----------------------------------------------------------| - * | config param [0] | - * |-----------------------------------------------------------| - * | config param [1] | - * |-----------------------------------------------------------| - * | config param [2] | - * |-----------------------------------------------------------| - * | config param [3] | - * |-----------------------------------------------------------| - * | reserved | - * |-----------------------------------------------------------| - * | cookie LSBs | - * |-----------------------------------------------------------| - * | cookie MSBs | - * |-----------------------------------------------------------| - * Header fields: - * - MSG_TYPE - * Bits 7:0 - * Purpose: identifies this is a extended stats upload request message - * Value: 0x10 - * - PDEV_MASK - * Bits 8:15 - * Purpose: identifies the mask of PDEVs to retrieve stats from - * Value: This is a overloaded field, refer to usage and interpretation of - * PDEV in interface document. - * Bit 8 : Reserved for SOC stats - * Bit 9 - 15 : Indicates PDEV_MASK in DBDC - * Indicates MACID_MASK in DBS - * - STATS_TYPE - * Bits 23:16 - * Purpose: identifies which FW statistics to upload - * Value: Defined by htt_dbg_ext_stats_type (see htt_stats.h) - * - Reserved - * Bits 31:24 - * - CONFIG_PARAM [0] - * Bits 31:0 - * Purpose: give an opaque configuration value to the specified stats type - * Value: stats-type specific configuration value - * Refer to htt_stats.h for interpretation for each stats sub_type - * - CONFIG_PARAM [1] - * Bits 31:0 - * Purpose: give an opaque configuration value to the specified stats type - * Value: stats-type specific configuration value - * Refer to htt_stats.h for interpretation for each stats sub_type - * - CONFIG_PARAM [2] - * Bits 31:0 - * Purpose: give an opaque configuration value to the specified stats type - * Value: stats-type specific configuration value - * Refer to htt_stats.h for interpretation for each stats sub_type - * - CONFIG_PARAM [3] - * Bits 31:0 - * Purpose: give an opaque configuration value to the specified stats type - * Value: stats-type specific configuration value - * Refer to htt_stats.h for interpretation for each stats sub_type - * - Reserved [31:0] for future use. - * - COOKIE_LSBS - * Bits 31:0 - * Purpose: Provide a mechanism to match a target->host stats confirmation - * message with its preceding host->target stats request message. - * Value: LSBs of the opaque cookie specified by the host-side requestor - * - COOKIE_MSBS - * Bits 31:0 - * Purpose: Provide a mechanism to match a target->host stats confirmation - * message with its preceding host->target stats request message. - * Value: MSBs of the opaque cookie specified by the host-side requestor - */ - -struct htt_ext_stats_cfg_hdr { - u8 msg_type; - u8 pdev_mask; - u8 stats_type; - u8 reserved; -} __packed; - -struct htt_ext_stats_cfg_cmd { - struct htt_ext_stats_cfg_hdr hdr; - __le32 cfg_param0; - __le32 cfg_param1; - __le32 cfg_param2; - __le32 cfg_param3; - __le32 reserved; - __le32 cookie_lsb; - __le32 cookie_msb; -} __packed; - -/* htt stats config default params */ -#define HTT_STAT_DEFAULT_RESET_START_OFFSET 0 -#define HTT_STAT_DEFAULT_CFG0_ALL_HWQS 0xffffffff -#define HTT_STAT_DEFAULT_CFG0_ALL_TXQS 0xffffffff -#define HTT_STAT_DEFAULT_CFG0_ALL_CMDQS 0xffff -#define HTT_STAT_DEFAULT_CFG0_ALL_RINGS 0xffff -#define HTT_STAT_DEFAULT_CFG0_ACTIVE_PEERS 0xff -#define HTT_STAT_DEFAULT_CFG0_CCA_CUMULATIVE 0x00 -#define HTT_STAT_DEFAULT_CFG0_ACTIVE_VDEVS 0x00 - -/* HTT_DBG_EXT_STATS_PEER_INFO - * PARAMS: - * @config_param0: - * [Bit0] - [0] for sw_peer_id, [1] for mac_addr based request - * [Bit15 : Bit 1] htt_peer_stats_req_mode_t - * [Bit31 : Bit16] sw_peer_id - * @config_param1: - * peer_stats_req_type_mask:32 (enum htt_peer_stats_tlv_enum) - * 0 bit htt_peer_stats_cmn_tlv - * 1 bit htt_peer_details_tlv - * 2 bit htt_tx_peer_rate_stats_tlv - * 3 bit htt_rx_peer_rate_stats_tlv - * 4 bit htt_tx_tid_stats_tlv/htt_tx_tid_stats_v1_tlv - * 5 bit htt_rx_tid_stats_tlv - * 6 bit htt_msdu_flow_stats_tlv - * @config_param2: [Bit31 : Bit0] mac_addr31to0 - * @config_param3: [Bit15 : Bit0] mac_addr47to32 - * [Bit31 : Bit16] reserved - */ -#define HTT_STAT_PEER_INFO_MAC_ADDR BIT(0) -#define HTT_STAT_DEFAULT_PEER_REQ_TYPE 0x7f - -/* Used to set different configs to the specified stats type.*/ -struct htt_ext_stats_cfg_params { - u32 cfg0; - u32 cfg1; - u32 cfg2; - u32 cfg3; -}; - -enum vdev_stats_offload_timer_duration { - ATH12K_STATS_TIMER_DUR_500MS = 1, - ATH12K_STATS_TIMER_DUR_1SEC = 2, - ATH12K_STATS_TIMER_DUR_2SEC = 3, -}; - -#define ATH12K_HTT_MAC_ADDR_L32_0 GENMASK(7, 0) -#define ATH12K_HTT_MAC_ADDR_L32_1 GENMASK(15, 8) -#define ATH12K_HTT_MAC_ADDR_L32_2 GENMASK(23, 16) -#define ATH12K_HTT_MAC_ADDR_L32_3 GENMASK(31, 24) -#define ATH12K_HTT_MAC_ADDR_H16_0 GENMASK(7, 0) -#define ATH12K_HTT_MAC_ADDR_H16_1 GENMASK(15, 8) - -struct htt_mac_addr { - __le32 mac_addr_l32; - __le32 mac_addr_h16; -} __packed; - static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) { memcpy(addr, &addr_l32, 4); diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.h b/drivers/net/wireless/ath/ath12k/dp_htt.h new file mode 100644 index 0000000000000..ce9064628d343 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/dp_htt.h @@ -0,0 +1,1517 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_DP_HTT_H +#define ATH12K_DP_HTT_H + +struct ath12k_dp; + +/* HTT definitions */ +#define HTT_TAG_TCL_METADATA_VERSION 5 + +#define HTT_TCL_META_DATA_TYPE GENMASK(1, 0) +#define HTT_TCL_META_DATA_VALID_HTT BIT(2) + +/* vdev meta data */ +#define HTT_TCL_META_DATA_VDEV_ID GENMASK(10, 3) +#define HTT_TCL_META_DATA_PDEV_ID GENMASK(12, 11) +#define HTT_TCL_META_DATA_HOST_INSPECTED_MISSION BIT(13) + +/* peer meta data */ +#define HTT_TCL_META_DATA_PEER_ID GENMASK(15, 3) + +/* Global sequence number */ +#define HTT_TCL_META_DATA_TYPE_GLOBAL_SEQ_NUM 3 +#define HTT_TCL_META_DATA_GLOBAL_SEQ_HOST_INSPECTED BIT(2) +#define HTT_TCL_META_DATA_GLOBAL_SEQ_NUM GENMASK(14, 3) +#define HTT_TX_MLO_MCAST_HOST_REINJECT_BASE_VDEV_ID 128 + +/* HTT tx completion is overlaid in wbm_release_ring */ +#define HTT_TX_WBM_COMP_INFO0_STATUS GENMASK(16, 13) +#define HTT_TX_WBM_COMP_INFO1_REINJECT_REASON GENMASK(3, 0) +#define HTT_TX_WBM_COMP_INFO1_EXCEPTION_FRAME BIT(4) + +#define HTT_TX_WBM_COMP_INFO2_ACK_RSSI GENMASK(31, 24) + +struct htt_tx_wbm_completion { + __le32 rsvd0[2]; + __le32 info0; + __le32 info1; + __le32 info2; + __le32 info3; + __le32 info4; + __le32 rsvd1; + +} __packed; + +enum htt_h2t_msg_type { + HTT_H2T_MSG_TYPE_VERSION_REQ = 0, + HTT_H2T_MSG_TYPE_SRING_SETUP = 0xb, + HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG = 0xc, + HTT_H2T_MSG_TYPE_EXT_STATS_CFG = 0x10, + HTT_H2T_MSG_TYPE_PPDU_STATS_CFG = 0x11, + HTT_H2T_MSG_TYPE_VDEV_TXRX_STATS_CFG = 0x1a, + HTT_H2T_MSG_TYPE_TX_MONITOR_CFG = 0x1b, +}; + +#define HTT_VER_REQ_INFO_MSG_ID GENMASK(7, 0) +#define HTT_OPTION_TCL_METADATA_VER_V1 1 +#define HTT_OPTION_TCL_METADATA_VER_V2 2 +#define HTT_OPTION_TAG GENMASK(7, 0) +#define HTT_OPTION_LEN GENMASK(15, 8) +#define HTT_OPTION_VALUE GENMASK(31, 16) +#define HTT_TCL_METADATA_VER_SZ 4 + +struct htt_ver_req_cmd { + __le32 ver_reg_info; + __le32 tcl_metadata_version; +} __packed; + +enum htt_srng_ring_type { + HTT_HW_TO_SW_RING, + HTT_SW_TO_HW_RING, + HTT_SW_TO_SW_RING, +}; + +enum htt_srng_ring_id { + HTT_RXDMA_HOST_BUF_RING, + HTT_RXDMA_MONITOR_STATUS_RING, + HTT_RXDMA_MONITOR_BUF_RING, + HTT_RXDMA_MONITOR_DESC_RING, + HTT_RXDMA_MONITOR_DEST_RING, + HTT_HOST1_TO_FW_RXBUF_RING, + HTT_HOST2_TO_FW_RXBUF_RING, + HTT_RXDMA_NON_MONITOR_DEST_RING, + HTT_RXDMA_HOST_BUF_RING2, + HTT_TX_MON_HOST2MON_BUF_RING, + HTT_TX_MON_MON2HOST_DEST_RING, + HTT_RX_MON_HOST2MON_BUF_RING, + HTT_RX_MON_MON2HOST_DEST_RING, +}; + +/* host -> target HTT_SRING_SETUP message + * + * After target is booted up, Host can send SRING setup message for + * each host facing LMAC SRING. Target setups up HW registers based + * on setup message and confirms back to Host if response_required is set. + * Host should wait for confirmation message before sending new SRING + * setup message + * + * The message would appear as follows: + * + * |31 24|23 20|19|18 16|15|14 8|7 0| + * |--------------- +-----------------+----------------+------------------| + * | ring_type | ring_id | pdev_id | msg_type | + * |----------------------------------------------------------------------| + * | ring_base_addr_lo | + * |----------------------------------------------------------------------| + * | ring_base_addr_hi | + * |----------------------------------------------------------------------| + * |ring_misc_cfg_flag|ring_entry_size| ring_size | + * |----------------------------------------------------------------------| + * | ring_head_offset32_remote_addr_lo | + * |----------------------------------------------------------------------| + * | ring_head_offset32_remote_addr_hi | + * |----------------------------------------------------------------------| + * | ring_tail_offset32_remote_addr_lo | + * |----------------------------------------------------------------------| + * | ring_tail_offset32_remote_addr_hi | + * |----------------------------------------------------------------------| + * | ring_msi_addr_lo | + * |----------------------------------------------------------------------| + * | ring_msi_addr_hi | + * |----------------------------------------------------------------------| + * | ring_msi_data | + * |----------------------------------------------------------------------| + * | intr_timer_th |IM| intr_batch_counter_th | + * |----------------------------------------------------------------------| + * | reserved |RR|PTCF| intr_low_threshold | + * |----------------------------------------------------------------------| + * Where + * IM = sw_intr_mode + * RR = response_required + * PTCF = prefetch_timer_cfg + * + * The message is interpreted as follows: + * dword0 - b'0:7 - msg_type: This will be set to + * HTT_H2T_MSG_TYPE_SRING_SETUP + * b'8:15 - pdev_id: + * 0 (for rings at SOC/UMAC level), + * 1/2/3 mac id (for rings at LMAC level) + * b'16:23 - ring_id: identify which ring is to setup, + * more details can be got from enum htt_srng_ring_id + * b'24:31 - ring_type: identify type of host rings, + * more details can be got from enum htt_srng_ring_type + * dword1 - b'0:31 - ring_base_addr_lo: Lower 32bits of ring base address + * dword2 - b'0:31 - ring_base_addr_hi: Upper 32bits of ring base address + * dword3 - b'0:15 - ring_size: size of the ring in unit of 4-bytes words + * b'16:23 - ring_entry_size: Size of each entry in 4-byte word units + * b'24:31 - ring_misc_cfg_flag: Valid only for HW_TO_SW_RING and + * SW_TO_HW_RING. + * Refer to HTT_SRING_SETUP_RING_MISC_CFG_RING defs. + * dword4 - b'0:31 - ring_head_off32_remote_addr_lo: + * Lower 32 bits of memory address of the remote variable + * storing the 4-byte word offset that identifies the head + * element within the ring. + * (The head offset variable has type u32.) + * Valid for HW_TO_SW and SW_TO_SW rings. + * dword5 - b'0:31 - ring_head_off32_remote_addr_hi: + * Upper 32 bits of memory address of the remote variable + * storing the 4-byte word offset that identifies the head + * element within the ring. + * (The head offset variable has type u32.) + * Valid for HW_TO_SW and SW_TO_SW rings. + * dword6 - b'0:31 - ring_tail_off32_remote_addr_lo: + * Lower 32 bits of memory address of the remote variable + * storing the 4-byte word offset that identifies the tail + * element within the ring. + * (The tail offset variable has type u32.) + * Valid for HW_TO_SW and SW_TO_SW rings. + * dword7 - b'0:31 - ring_tail_off32_remote_addr_hi: + * Upper 32 bits of memory address of the remote variable + * storing the 4-byte word offset that identifies the tail + * element within the ring. + * (The tail offset variable has type u32.) + * Valid for HW_TO_SW and SW_TO_SW rings. + * dword8 - b'0:31 - ring_msi_addr_lo: Lower 32bits of MSI cfg address + * valid only for HW_TO_SW_RING and SW_TO_HW_RING + * dword9 - b'0:31 - ring_msi_addr_hi: Upper 32bits of MSI cfg address + * valid only for HW_TO_SW_RING and SW_TO_HW_RING + * dword10 - b'0:31 - ring_msi_data: MSI data + * Refer to HTT_SRING_SETUP_RING_MSC_CFG_xxx defs + * valid only for HW_TO_SW_RING and SW_TO_HW_RING + * dword11 - b'0:14 - intr_batch_counter_th: + * batch counter threshold is in units of 4-byte words. + * HW internally maintains and increments batch count. + * (see SRING spec for detail description). + * When batch count reaches threshold value, an interrupt + * is generated by HW. + * b'15 - sw_intr_mode: + * This configuration shall be static. + * Only programmed at power up. + * 0: generate pulse style sw interrupts + * 1: generate level style sw interrupts + * b'16:31 - intr_timer_th: + * The timer init value when timer is idle or is + * initialized to start downcounting. + * In 8us units (to cover a range of 0 to 524 ms) + * dword12 - b'0:15 - intr_low_threshold: + * Used only by Consumer ring to generate ring_sw_int_p. + * Ring entries low threshold water mark, that is used + * in combination with the interrupt timer as well as + * the clearing of the level interrupt. + * b'16:18 - prefetch_timer_cfg: + * Used only by Consumer ring to set timer mode to + * support Application prefetch handling. + * The external tail offset/pointer will be updated + * at following intervals: + * 3'b000: (Prefetch feature disabled; used only for debug) + * 3'b001: 1 usec + * 3'b010: 4 usec + * 3'b011: 8 usec (default) + * 3'b100: 16 usec + * Others: Reserved + * b'19 - response_required: + * Host needs HTT_T2H_MSG_TYPE_SRING_SETUP_DONE as response + * b'20:31 - reserved: reserved for future use + */ + +#define HTT_SRNG_SETUP_CMD_INFO0_MSG_TYPE GENMASK(7, 0) +#define HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID GENMASK(15, 8) +#define HTT_SRNG_SETUP_CMD_INFO0_RING_ID GENMASK(23, 16) +#define HTT_SRNG_SETUP_CMD_INFO0_RING_TYPE GENMASK(31, 24) + +#define HTT_SRNG_SETUP_CMD_INFO1_RING_SIZE GENMASK(15, 0) +#define HTT_SRNG_SETUP_CMD_INFO1_RING_ENTRY_SIZE GENMASK(23, 16) +#define HTT_SRNG_SETUP_CMD_INFO1_RING_LOOP_CNT_DIS BIT(25) +#define HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_MSI_SWAP BIT(27) +#define HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_HOST_FW_SWAP BIT(28) +#define HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_TLV_SWAP BIT(29) + +#define HTT_SRNG_SETUP_CMD_INTR_INFO_BATCH_COUNTER_THRESH GENMASK(14, 0) +#define HTT_SRNG_SETUP_CMD_INTR_INFO_SW_INTR_MODE BIT(15) +#define HTT_SRNG_SETUP_CMD_INTR_INFO_INTR_TIMER_THRESH GENMASK(31, 16) + +#define HTT_SRNG_SETUP_CMD_INFO2_INTR_LOW_THRESH GENMASK(15, 0) +#define HTT_SRNG_SETUP_CMD_INFO2_PRE_FETCH_TIMER_CFG GENMASK(18, 16) +#define HTT_SRNG_SETUP_CMD_INFO2_RESPONSE_REQUIRED BIT(19) + +struct htt_srng_setup_cmd { + __le32 info0; + __le32 ring_base_addr_lo; + __le32 ring_base_addr_hi; + __le32 info1; + __le32 ring_head_off32_remote_addr_lo; + __le32 ring_head_off32_remote_addr_hi; + __le32 ring_tail_off32_remote_addr_lo; + __le32 ring_tail_off32_remote_addr_hi; + __le32 ring_msi_addr_lo; + __le32 ring_msi_addr_hi; + __le32 msi_data; + __le32 intr_info; + __le32 info2; +} __packed; + +/* host -> target FW PPDU_STATS config message + * + * @details + * The following field definitions describe the format of the HTT host + * to target FW for PPDU_STATS_CFG msg. + * The message allows the host to configure the PPDU_STATS_IND messages + * produced by the target. + * + * |31 24|23 16|15 8|7 0| + * |-----------------------------------------------------------| + * | REQ bit mask | pdev_mask | msg type | + * |-----------------------------------------------------------| + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this is a req to configure ppdu_stats_ind from target + * Value: 0x11 + * - PDEV_MASK + * Bits 8:15 + * Purpose: identifies which pdevs this PPDU stats configuration applies to + * Value: This is a overloaded field, refer to usage and interpretation of + * PDEV in interface document. + * Bit 8 : Reserved for SOC stats + * Bit 9 - 15 : Indicates PDEV_MASK in DBDC + * Indicates MACID_MASK in DBS + * - REQ_TLV_BIT_MASK + * Bits 16:31 + * Purpose: each set bit indicates the corresponding PPDU stats TLV type + * needs to be included in the target's PPDU_STATS_IND messages. + * Value: refer htt_ppdu_stats_tlv_tag_t << 30 bits + * Refer to PKT_TYPE_ENABLE_FLAG0_xxx_MGMT_xxx defs + * dword3 - b'0:31 - packet_type_enable_flags_1: + * Enable MGMT packet from 0b1010 to 0b1111 + * bits from low to high: FP, MD, MO - 3 bits + * Refer to PKT_TYPE_ENABLE_FLAG1_xxx_MGMT_xxx defs + * dword4 - b'0:31 - packet_type_enable_flags_2: + * Enable CTRL packet from 0b0000 to 0b1001 + * bits from low to high: FP, MD, MO - 3 bits + * Refer to PKT_TYPE_ENABLE_FLAG2_xxx_CTRL_xxx defs + * dword5 - b'0:31 - packet_type_enable_flags_3: + * Enable CTRL packet from 0b1010 to 0b1111, + * MCAST_DATA, UCAST_DATA, NULL_DATA + * bits from low to high: FP, MD, MO - 3 bits + * Refer to PKT_TYPE_ENABLE_FLAG3_xxx_CTRL_xxx defs + * dword6 - b'0:31 - tlv_filter_in_flags: + * Filter in Attention/MPDU/PPDU/Header/User tlvs + * Refer to CFG_TLV_FILTER_IN_FLAG defs + */ + +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID GENMASK(15, 8) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_RING_ID GENMASK(23, 16) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_SS BIT(24) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS BIT(25) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_OFFSET_VALID BIT(26) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_DROP_THRES_VAL BIT(27) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_EN_RXMON BIT(28) + +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE GENMASK(15, 0) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT GENMASK(18, 16) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL GENMASK(21, 19) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA GENMASK(24, 22) + +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_DROP_THRESHOLD GENMASK(9, 0) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_MGMT_TYPE BIT(17) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_CTRL_TYPE BIT(18) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_DATA_TYPE BIT(19) + +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO3_EN_TLV_PKT_OFFSET BIT(0) +#define HTT_RX_RING_SELECTION_CFG_CMD_INFO3_PKT_TLV_OFFSET GENMASK(14, 1) + +#define HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET GENMASK(15, 0) +#define HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET GENMASK(31, 16) +#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET GENMASK(15, 0) +#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET GENMASK(31, 16) +#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET GENMASK(15, 0) +#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET GENMASK(31, 16) +#define HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET GENMASK(15, 0) + +#define HTT_RX_RING_SELECTION_CFG_WORD_MASK_COMPACT_SET BIT(23) +#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_MASK GENMASK(15, 0) +#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_MASK GENMASK(18, 16) +#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_MASK GENMASK(16, 0) + +enum htt_rx_filter_tlv_flags { + HTT_RX_FILTER_TLV_FLAGS_MPDU_START = BIT(0), + HTT_RX_FILTER_TLV_FLAGS_MSDU_START = BIT(1), + HTT_RX_FILTER_TLV_FLAGS_RX_PACKET = BIT(2), + HTT_RX_FILTER_TLV_FLAGS_MSDU_END = BIT(3), + HTT_RX_FILTER_TLV_FLAGS_MPDU_END = BIT(4), + HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER = BIT(5), + HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER = BIT(6), + HTT_RX_FILTER_TLV_FLAGS_ATTENTION = BIT(7), + HTT_RX_FILTER_TLV_FLAGS_PPDU_START = BIT(8), + HTT_RX_FILTER_TLV_FLAGS_PPDU_END = BIT(9), + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS = BIT(10), + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT = BIT(11), + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE = BIT(12), + HTT_RX_FILTER_TLV_FLAGS_PPDU_START_USER_INFO = BIT(13), +}; + +enum htt_rx_mgmt_pkt_filter_tlv_flags0 { + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ = BIT(0), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ = BIT(1), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ = BIT(2), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP = BIT(3), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP = BIT(4), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP = BIT(5), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ = BIT(6), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ = BIT(7), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ = BIT(8), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP = BIT(9), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP = BIT(10), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP = BIT(11), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ = BIT(12), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ = BIT(13), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ = BIT(14), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP = BIT(15), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP = BIT(16), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP = BIT(17), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV = BIT(18), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV = BIT(19), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV = BIT(20), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7 = BIT(21), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7 = BIT(22), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7 = BIT(23), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON = BIT(24), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON = BIT(25), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON = BIT(26), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM = BIT(27), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM = BIT(28), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM = BIT(29), +}; + +enum htt_rx_mgmt_pkt_filter_tlv_flags1 { + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC = BIT(0), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC = BIT(1), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC = BIT(2), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH = BIT(3), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH = BIT(4), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH = BIT(5), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH = BIT(6), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH = BIT(7), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH = BIT(8), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION = BIT(9), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION = BIT(10), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION = BIT(11), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK = BIT(12), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK = BIT(13), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK = BIT(14), + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15 = BIT(15), + HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15 = BIT(16), + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15 = BIT(17), +}; + +enum htt_rx_ctrl_pkt_filter_tlv_flags2 { + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 = BIT(0), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 = BIT(1), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 = BIT(2), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 = BIT(3), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 = BIT(4), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 = BIT(5), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER = BIT(6), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER = BIT(7), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER = BIT(8), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 = BIT(9), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 = BIT(10), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 = BIT(11), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL = BIT(12), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL = BIT(13), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL = BIT(14), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP = BIT(15), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP = BIT(16), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP = BIT(17), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT = BIT(18), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT = BIT(19), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT = BIT(20), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER = BIT(21), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER = BIT(22), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER = BIT(23), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR = BIT(24), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BAR = BIT(25), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BAR = BIT(26), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BA = BIT(27), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BA = BIT(28), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BA = BIT(29), +}; + +enum htt_rx_ctrl_pkt_filter_tlv_flags3 { + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL = BIT(0), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL = BIT(1), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL = BIT(2), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_RTS = BIT(3), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_RTS = BIT(4), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_RTS = BIT(5), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CTS = BIT(6), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CTS = BIT(7), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CTS = BIT(8), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_ACK = BIT(9), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_ACK = BIT(10), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_ACK = BIT(11), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND = BIT(12), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND = BIT(13), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND = BIT(14), + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK = BIT(15), + HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK = BIT(16), + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK = BIT(17), +}; + +enum htt_rx_data_pkt_filter_tlv_flasg3 { + HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST = BIT(18), + HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_MCAST = BIT(19), + HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_MCAST = BIT(20), + HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST = BIT(21), + HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_UCAST = BIT(22), + HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_UCAST = BIT(23), + HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA = BIT(24), + HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA = BIT(25), + HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA = BIT(26), +}; + +#define HTT_RX_FP_MGMT_FILTER_FLAGS0 \ + (HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM) + +#define HTT_RX_MD_MGMT_FILTER_FLAGS0 \ + (HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM) + +#define HTT_RX_MO_MGMT_FILTER_FLAGS0 \ + (HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM) + +#define HTT_RX_FP_MGMT_FILTER_FLAGS1 (HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION \ + | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK) + +#define HTT_RX_MD_MGMT_FILTER_FLAGS1 (HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION \ + | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK) + +#define HTT_RX_MO_MGMT_FILTER_FLAGS1 (HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION \ + | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK) + +#define HTT_RX_FP_CTRL_FILTER_FLASG2 (HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER \ + | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR \ + | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BA) + +#define HTT_RX_MD_CTRL_FILTER_FLASG2 (HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER \ + | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BAR \ + | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BA) + +#define HTT_RX_MO_CTRL_FILTER_FLASG2 (HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER \ + | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BAR \ + | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BA) + +#define HTT_RX_FP_CTRL_FILTER_FLASG3 (HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL \ + | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_RTS \ + | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CTS \ + | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_ACK \ + | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND \ + | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK) + +#define HTT_RX_MD_CTRL_FILTER_FLASG3 (HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL \ + | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_RTS \ + | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CTS \ + | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_ACK \ + | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND \ + | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK) + +#define HTT_RX_MO_CTRL_FILTER_FLASG3 (HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL \ + | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_RTS \ + | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CTS \ + | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_ACK \ + | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND \ + | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK) + +#define HTT_RX_FP_DATA_FILTER_FLASG3 (HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST \ + | HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST \ + | HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA) + +#define HTT_RX_MD_DATA_FILTER_FLASG3 (HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_MCAST \ + | HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_UCAST \ + | HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA) + +#define HTT_RX_MO_DATA_FILTER_FLASG3 (HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_MCAST \ + | HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_UCAST \ + | HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA) + +#define HTT_RX_MON_FP_MGMT_FILTER_FLAGS0 \ + (HTT_RX_FP_MGMT_FILTER_FLAGS0 | \ + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7) + +#define HTT_RX_MON_MO_MGMT_FILTER_FLAGS0 \ + (HTT_RX_MO_MGMT_FILTER_FLAGS0 | \ + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7) + +#define HTT_RX_MON_FP_MGMT_FILTER_FLAGS1 \ + (HTT_RX_FP_MGMT_FILTER_FLAGS1 | \ + HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15) + +#define HTT_RX_MON_MO_MGMT_FILTER_FLAGS1 \ + (HTT_RX_MO_MGMT_FILTER_FLAGS1 | \ + HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15) + +#define HTT_RX_MON_FP_CTRL_FILTER_FLASG2 \ + (HTT_RX_FP_CTRL_FILTER_FLASG2 | \ + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 | \ + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 | \ + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER | \ + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 | \ + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL | \ + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP | \ + HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT) + +#define HTT_RX_MON_MO_CTRL_FILTER_FLASG2 \ + (HTT_RX_MO_CTRL_FILTER_FLASG2 | \ + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 | \ + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 | \ + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER | \ + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 | \ + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL | \ + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP | \ + HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT) + +#define HTT_RX_MON_FP_CTRL_FILTER_FLASG3 HTT_RX_FP_CTRL_FILTER_FLASG3 + +#define HTT_RX_MON_MO_CTRL_FILTER_FLASG3 HTT_RX_MO_CTRL_FILTER_FLASG3 + +#define HTT_RX_MON_FP_DATA_FILTER_FLASG3 HTT_RX_FP_DATA_FILTER_FLASG3 + +#define HTT_RX_MON_MO_DATA_FILTER_FLASG3 HTT_RX_MO_DATA_FILTER_FLASG3 + +#define HTT_RX_MON_FILTER_TLV_FLAGS \ + (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE) + +#define HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING \ + (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE) + +#define HTT_RX_MON_FILTER_TLV_FLAGS_MON_BUF_RING \ + (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \ + HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \ + HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \ + HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER | \ + HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \ + HTT_RX_FILTER_TLV_FLAGS_ATTENTION) + +#define HTT_RX_MON_FILTER_TLV_FLAGS_MON_DEST_RING \ + (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \ + HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \ + HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \ + HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER | \ + HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \ + HTT_RX_FILTER_TLV_FLAGS_PPDU_START_USER_INFO) + +/* msdu start. mpdu end, attention, rx hdr tlv's are not subscribed */ +#define HTT_RX_TLV_FLAGS_RXDMA_RING \ + (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \ + HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \ + HTT_RX_FILTER_TLV_FLAGS_MSDU_END) + +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID GENMASK(15, 8) + +struct htt_rx_ring_selection_cfg_cmd { + __le32 info0; + __le32 info1; + __le32 pkt_type_en_flags0; + __le32 pkt_type_en_flags1; + __le32 pkt_type_en_flags2; + __le32 pkt_type_en_flags3; + __le32 rx_filter_tlv; + __le32 rx_packet_offset; + __le32 rx_mpdu_offset; + __le32 rx_msdu_offset; + __le32 rx_attn_offset; + __le32 info2; + __le32 reserved[2]; + __le32 rx_mpdu_start_end_mask; + __le32 rx_msdu_end_word_mask; + __le32 info3; +} __packed; + +#define HTT_RX_RING_TLV_DROP_THRESHOLD_VALUE 32 +#define HTT_RX_RING_DEFAULT_DMA_LENGTH 0x7 +#define HTT_RX_RING_PKT_TLV_OFFSET 0x1 + +struct htt_rx_ring_tlv_filter { + u32 rx_filter; /* see htt_rx_filter_tlv_flags */ + u32 pkt_filter_flags0; /* MGMT */ + u32 pkt_filter_flags1; /* MGMT */ + u32 pkt_filter_flags2; /* CTRL */ + u32 pkt_filter_flags3; /* DATA */ + bool offset_valid; + u16 rx_packet_offset; + u16 rx_header_offset; + u16 rx_mpdu_end_offset; + u16 rx_mpdu_start_offset; + u16 rx_msdu_end_offset; + u16 rx_msdu_start_offset; + u16 rx_attn_offset; + u16 rx_mpdu_start_wmask; + u16 rx_mpdu_end_wmask; + u32 rx_msdu_end_wmask; + u32 conf_len_ctrl; + u32 conf_len_mgmt; + u32 conf_len_data; + u16 rx_drop_threshold; + bool enable_log_mgmt_type; + bool enable_log_ctrl_type; + bool enable_log_data_type; + bool enable_rx_tlv_offset; + u16 rx_tlv_offset; + bool drop_threshold_valid; + bool rxmon_disable; +}; + +#define HTT_STATS_FRAME_CTRL_TYPE_MGMT 0x0 +#define HTT_STATS_FRAME_CTRL_TYPE_CTRL 0x1 +#define HTT_STATS_FRAME_CTRL_TYPE_DATA 0x2 +#define HTT_STATS_FRAME_CTRL_TYPE_RESV 0x3 + +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID GENMASK(15, 8) +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_RING_ID GENMASK(23, 16) +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_SS BIT(24) +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PS BIT(25) + +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_RING_BUFF_SIZE GENMASK(15, 0) +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE GENMASK(18, 16) +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT GENMASK(21, 19) +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL GENMASK(24, 22) +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA GENMASK(27, 25) + +#define HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG GENMASK(2, 0) + +struct htt_tx_ring_selection_cfg_cmd { + __le32 info0; + __le32 info1; + __le32 info2; + __le32 tlv_filter_mask_in0; + __le32 tlv_filter_mask_in1; + __le32 tlv_filter_mask_in2; + __le32 tlv_filter_mask_in3; + __le32 reserved[3]; +} __packed; + +#define HTT_TX_RING_TLV_FILTER_MGMT_DMA_LEN GENMASK(3, 0) +#define HTT_TX_RING_TLV_FILTER_CTRL_DMA_LEN GENMASK(7, 4) +#define HTT_TX_RING_TLV_FILTER_DATA_DMA_LEN GENMASK(11, 8) + +#define HTT_TX_MON_FILTER_HYBRID_MODE \ + (HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_START_STATUS | \ + HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_END_STATUS | \ + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START | \ + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_END | \ + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PPDU | \ + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_PPDU | \ + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_ACK_OR_BA | \ + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_1K_BA | \ + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PROT | \ + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_PROT | \ + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_RESPONSE | \ + HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO | \ + HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO_PART2) + +struct htt_tx_ring_tlv_filter { + u32 tx_mon_downstream_tlv_flags; + u32 tx_mon_upstream_tlv_flags0; + u32 tx_mon_upstream_tlv_flags1; + u32 tx_mon_upstream_tlv_flags2; + bool tx_mon_mgmt_filter; + bool tx_mon_data_filter; + bool tx_mon_ctrl_filter; + u16 tx_mon_pkt_dma_len; +} __packed; + +enum htt_tx_mon_upstream_tlv_flags0 { + HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_START_STATUS = BIT(1), + HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_END_STATUS = BIT(2), + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START = BIT(3), + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_END = BIT(4), + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PPDU = BIT(5), + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_PPDU = BIT(6), + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_ACK_OR_BA = BIT(7), + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_1K_BA = BIT(8), + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PROT = BIT(9), + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_PROT = BIT(10), + HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_RESPONSE = BIT(11), + HTT_TX_FILTER_TLV_FLAGS0_RX_FRAME_BITMAP_ACK = BIT(12), + HTT_TX_FILTER_TLV_FLAGS0_RX_FRAME_1K_BITMAP_ACK = BIT(13), + HTT_TX_FILTER_TLV_FLAGS0_COEX_TX_STATUS = BIT(14), + HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO = BIT(15), + HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO_PART2 = BIT(16), +}; + +#define HTT_TX_FILTER_TLV_FLAGS2_TXPCU_PHYTX_OTHER_TRANSMIT_INFO32 BIT(11) + +/* HTT message target->host */ + +enum htt_t2h_msg_type { + HTT_T2H_MSG_TYPE_VERSION_CONF, + HTT_T2H_MSG_TYPE_PEER_MAP = 0x3, + HTT_T2H_MSG_TYPE_PEER_UNMAP = 0x4, + HTT_T2H_MSG_TYPE_RX_ADDBA = 0x5, + HTT_T2H_MSG_TYPE_PKTLOG = 0x8, + HTT_T2H_MSG_TYPE_SEC_IND = 0xb, + HTT_T2H_MSG_TYPE_PEER_MAP2 = 0x1e, + HTT_T2H_MSG_TYPE_PEER_UNMAP2 = 0x1f, + HTT_T2H_MSG_TYPE_PPDU_STATS_IND = 0x1d, + HTT_T2H_MSG_TYPE_EXT_STATS_CONF = 0x1c, + HTT_T2H_MSG_TYPE_BKPRESSURE_EVENT_IND = 0x24, + HTT_T2H_MSG_TYPE_MLO_TIMESTAMP_OFFSET_IND = 0x28, + HTT_T2H_MSG_TYPE_PEER_MAP3 = 0x2b, + HTT_T2H_MSG_TYPE_VDEV_TXRX_STATS_PERIODIC_IND = 0x2c, +}; + +#define HTT_TARGET_VERSION_MAJOR 3 + +#define HTT_T2H_MSG_TYPE GENMASK(7, 0) +#define HTT_T2H_VERSION_CONF_MINOR GENMASK(15, 8) +#define HTT_T2H_VERSION_CONF_MAJOR GENMASK(23, 16) + +struct htt_t2h_version_conf_msg { + __le32 version; +} __packed; + +#define HTT_T2H_PEER_MAP_INFO_VDEV_ID GENMASK(15, 8) +#define HTT_T2H_PEER_MAP_INFO_PEER_ID GENMASK(31, 16) +#define HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16 GENMASK(15, 0) +#define HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID GENMASK(31, 16) +#define HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL GENMASK(15, 0) +#define HTT_T2H_PEER_MAP3_INFO2_HW_PEER_ID GENMASK(15, 0) +#define HTT_T2H_PEER_MAP3_INFO2_AST_HASH_VAL GENMASK(31, 16) +#define HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M BIT(16) +#define HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_S 16 + +struct htt_t2h_peer_map_event { + __le32 info; + __le32 mac_addr_l32; + __le32 info1; + __le32 info2; +} __packed; + +#define HTT_T2H_PEER_UNMAP_INFO_VDEV_ID HTT_T2H_PEER_MAP_INFO_VDEV_ID +#define HTT_T2H_PEER_UNMAP_INFO_PEER_ID HTT_T2H_PEER_MAP_INFO_PEER_ID +#define HTT_T2H_PEER_UNMAP_INFO1_MAC_ADDR_H16 \ + HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16 +#define HTT_T2H_PEER_MAP_INFO1_NEXT_HOP_M HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M +#define HTT_T2H_PEER_MAP_INFO1_NEXT_HOP_S HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_S + +struct htt_t2h_peer_unmap_event { + __le32 info; + __le32 mac_addr_l32; + __le32 info1; +} __packed; + +struct htt_resp_msg { + union { + struct htt_t2h_version_conf_msg version_msg; + struct htt_t2h_peer_map_event peer_map_ev; + struct htt_t2h_peer_unmap_event peer_unmap_ev; + }; +} __packed; + +#define HTT_VDEV_GET_STATS_U64(msg_l32, msg_u32)\ + (((u64)__le32_to_cpu(msg_u32) << 32) | (__le32_to_cpu(msg_l32))) +#define HTT_T2H_VDEV_STATS_PERIODIC_MSG_TYPE GENMASK(7, 0) +#define HTT_T2H_VDEV_STATS_PERIODIC_PDEV_ID GENMASK(15, 8) +#define HTT_T2H_VDEV_STATS_PERIODIC_NUM_VDEV GENMASK(23, 16) +#define HTT_T2H_VDEV_STATS_PERIODIC_PAYLOAD_BYTES GENMASK(15, 0) +#define HTT_VDEV_TXRX_STATS_COMMON_TLV 0 +#define HTT_VDEV_TXRX_STATS_HW_STATS_TLV 1 + +struct htt_t2h_vdev_txrx_stats_ind { + __le32 vdev_id; + __le32 rx_msdu_byte_cnt_lo; + __le32 rx_msdu_byte_cnt_hi; + __le32 rx_msdu_cnt_lo; + __le32 rx_msdu_cnt_hi; + __le32 tx_msdu_byte_cnt_lo; + __le32 tx_msdu_byte_cnt_hi; + __le32 tx_msdu_cnt_lo; + __le32 tx_msdu_cnt_hi; + __le32 tx_retry_cnt_lo; + __le32 tx_retry_cnt_hi; + __le32 tx_retry_byte_cnt_lo; + __le32 tx_retry_byte_cnt_hi; + __le32 tx_drop_cnt_lo; + __le32 tx_drop_cnt_hi; + __le32 tx_drop_byte_cnt_lo; + __le32 tx_drop_byte_cnt_hi; + __le32 msdu_ttl_cnt_lo; + __le32 msdu_ttl_cnt_hi; + __le32 msdu_ttl_byte_cnt_lo; + __le32 msdu_ttl_byte_cnt_hi; +} __packed; + +struct htt_t2h_vdev_common_stats_tlv { + __le32 soc_drop_count_lo; + __le32 soc_drop_count_hi; +} __packed; + +/* ppdu stats + * + * @details + * The following field definitions describe the format of the HTT target + * to host ppdu stats indication message. + * + * + * |31 16|15 12|11 10|9 8|7 0 | + * |----------------------------------------------------------------------| + * | payload_size | rsvd |pdev_id|mac_id | msg type | + * |----------------------------------------------------------------------| + * | ppdu_id | + * |----------------------------------------------------------------------| + * | Timestamp in us | + * |----------------------------------------------------------------------| + * | reserved | + * |----------------------------------------------------------------------| + * | type-specific stats info | + * | (see htt_ppdu_stats.h) | + * |----------------------------------------------------------------------| + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: Identifies this is a PPDU STATS indication + * message. + * Value: 0x1d + * - mac_id + * Bits 9:8 + * Purpose: mac_id of this ppdu_id + * Value: 0-3 + * - pdev_id + * Bits 11:10 + * Purpose: pdev_id of this ppdu_id + * Value: 0-3 + * 0 (for rings at SOC level), + * 1/2/3 PDEV -> 0/1/2 + * - payload_size + * Bits 31:16 + * Purpose: total tlv size + * Value: payload_size in bytes + */ + +#define HTT_T2H_PPDU_STATS_INFO_PDEV_ID GENMASK(11, 10) +#define HTT_T2H_PPDU_STATS_INFO_PAYLOAD_SIZE GENMASK(31, 16) + +struct ath12k_htt_ppdu_stats_msg { + __le32 info; + __le32 ppdu_id; + __le32 timestamp; + __le32 rsvd; + u8 data[]; +} __packed; + +struct htt_tlv { + __le32 header; + u8 value[]; +} __packed; + +#define HTT_TLV_TAG GENMASK(11, 0) +#define HTT_TLV_LEN GENMASK(23, 12) + +enum HTT_PPDU_STATS_BW { + HTT_PPDU_STATS_BANDWIDTH_5MHZ = 0, + HTT_PPDU_STATS_BANDWIDTH_10MHZ = 1, + HTT_PPDU_STATS_BANDWIDTH_20MHZ = 2, + HTT_PPDU_STATS_BANDWIDTH_40MHZ = 3, + HTT_PPDU_STATS_BANDWIDTH_80MHZ = 4, + HTT_PPDU_STATS_BANDWIDTH_160MHZ = 5, /* includes 80+80 */ + HTT_PPDU_STATS_BANDWIDTH_DYN = 6, +}; + +#define HTT_PPDU_STATS_CMN_FLAGS_FRAME_TYPE_M GENMASK(7, 0) +#define HTT_PPDU_STATS_CMN_FLAGS_QUEUE_TYPE_M GENMASK(15, 8) +/* bw - HTT_PPDU_STATS_BW */ +#define HTT_PPDU_STATS_CMN_FLAGS_BW_M GENMASK(19, 16) + +struct htt_ppdu_stats_common { + __le32 ppdu_id; + __le16 sched_cmdid; + u8 ring_id; + u8 num_users; + __le32 flags; /* %HTT_PPDU_STATS_COMMON_FLAGS_*/ + __le32 chain_mask; + __le32 fes_duration_us; /* frame exchange sequence */ + __le32 ppdu_sch_eval_start_tstmp_us; + __le32 ppdu_sch_end_tstmp_us; + __le32 ppdu_start_tstmp_us; + /* BIT [15 : 0] - phy mode (WLAN_PHY_MODE) with which ppdu was transmitted + * BIT [31 : 16] - bandwidth (in MHz) with which ppdu was transmitted + */ + __le16 phy_mode; + __le16 bw_mhz; +} __packed; + +enum htt_ppdu_stats_gi { + HTT_PPDU_STATS_SGI_0_8_US, + HTT_PPDU_STATS_SGI_0_4_US, + HTT_PPDU_STATS_SGI_1_6_US, + HTT_PPDU_STATS_SGI_3_2_US, +}; + +#define HTT_PPDU_STATS_USER_RATE_INFO0_USER_POS_M GENMASK(3, 0) +#define HTT_PPDU_STATS_USER_RATE_INFO0_MU_GROUP_ID_M GENMASK(11, 4) + +enum HTT_PPDU_STATS_PPDU_TYPE { + HTT_PPDU_STATS_PPDU_TYPE_SU, + HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO, + HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA, + HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA, + HTT_PPDU_STATS_PPDU_TYPE_UL_TRIG, + HTT_PPDU_STATS_PPDU_TYPE_BURST_BCN, + HTT_PPDU_STATS_PPDU_TYPE_UL_BSR_RESP, + HTT_PPDU_STATS_PPDU_TYPE_UL_BSR_TRIG, + HTT_PPDU_STATS_PPDU_TYPE_UL_RESP, + HTT_PPDU_STATS_PPDU_TYPE_MAX +}; + +#define HTT_PPDU_STATS_USER_RATE_INFO1_RESP_TYPE_VALD_M BIT(0) +#define HTT_PPDU_STATS_USER_RATE_INFO1_PPDU_TYPE_M GENMASK(5, 1) + +#define HTT_PPDU_STATS_USER_RATE_FLAGS_LTF_SIZE_M GENMASK(1, 0) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_STBC_M BIT(2) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_HE_RE_M BIT(3) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_TXBF_M GENMASK(7, 4) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_BW_M GENMASK(11, 8) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_NSS_M GENMASK(15, 12) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_MCS_M GENMASK(19, 16) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_PREAMBLE_M GENMASK(23, 20) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_GI_M GENMASK(27, 24) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_DCM_M BIT(28) +#define HTT_PPDU_STATS_USER_RATE_FLAGS_LDPC_M BIT(29) + +#define HTT_USR_RATE_PPDU_TYPE(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_INFO1_PPDU_TYPE_M) +#define HTT_USR_RATE_PREAMBLE(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_PREAMBLE_M) +#define HTT_USR_RATE_BW(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_BW_M) +#define HTT_USR_RATE_NSS(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_NSS_M) +#define HTT_USR_RATE_MCS(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_MCS_M) +#define HTT_USR_RATE_GI(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_GI_M) +#define HTT_USR_RATE_DCM(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_DCM_M) + +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_LTF_SIZE_M GENMASK(1, 0) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_STBC_M BIT(2) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_HE_RE_M BIT(3) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_TXBF_M GENMASK(7, 4) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_BW_M GENMASK(11, 8) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_NSS_M GENMASK(15, 12) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_MCS_M GENMASK(19, 16) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_PREAMBLE_M GENMASK(23, 20) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_GI_M GENMASK(27, 24) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_DCM_M BIT(28) +#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_LDPC_M BIT(29) + +struct htt_ppdu_stats_user_rate { + u8 tid_num; + u8 reserved0; + __le16 sw_peer_id; + __le32 info0; /* %HTT_PPDU_STATS_USER_RATE_INFO0_*/ + __le16 ru_end; + __le16 ru_start; + __le16 resp_ru_end; + __le16 resp_ru_start; + __le32 info1; /* %HTT_PPDU_STATS_USER_RATE_INFO1_ */ + __le32 rate_flags; /* %HTT_PPDU_STATS_USER_RATE_FLAGS_ */ + /* Note: resp_rate_info is only valid for if resp_type is UL */ + __le32 resp_rate_flags; /* %HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_ */ +} __packed; + +#define HTT_PPDU_STATS_TX_INFO_FLAGS_RATECODE_M GENMASK(7, 0) +#define HTT_PPDU_STATS_TX_INFO_FLAGS_IS_AMPDU_M BIT(8) +#define HTT_PPDU_STATS_TX_INFO_FLAGS_BA_ACK_FAILED_M GENMASK(10, 9) +#define HTT_PPDU_STATS_TX_INFO_FLAGS_BW_M GENMASK(13, 11) +#define HTT_PPDU_STATS_TX_INFO_FLAGS_SGI_M BIT(14) +#define HTT_PPDU_STATS_TX_INFO_FLAGS_PEERID_M GENMASK(31, 16) + +#define HTT_TX_INFO_IS_AMSDU(_flags) \ + u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_IS_AMPDU_M) +#define HTT_TX_INFO_BA_ACK_FAILED(_flags) \ + u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_BA_ACK_FAILED_M) +#define HTT_TX_INFO_RATECODE(_flags) \ + u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_RATECODE_M) +#define HTT_TX_INFO_PEERID(_flags) \ + u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_PEERID_M) + +enum htt_ppdu_stats_usr_compln_status { + HTT_PPDU_STATS_USER_STATUS_OK, + HTT_PPDU_STATS_USER_STATUS_FILTERED, + HTT_PPDU_STATS_USER_STATUS_RESP_TIMEOUT, + HTT_PPDU_STATS_USER_STATUS_RESP_MISMATCH, + HTT_PPDU_STATS_USER_STATUS_ABORT, +}; + +#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_LONG_RETRY_M GENMASK(3, 0) +#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_SHORT_RETRY_M GENMASK(7, 4) +#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_IS_AMPDU_M BIT(8) +#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_RESP_TYPE_M GENMASK(12, 9) + +#define HTT_USR_CMPLTN_IS_AMPDU(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_IS_AMPDU_M) +#define HTT_USR_CMPLTN_LONG_RETRY(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_LONG_RETRY_M) +#define HTT_USR_CMPLTN_SHORT_RETRY(_val) \ + le32_get_bits(_val, HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_SHORT_RETRY_M) + +struct htt_ppdu_stats_usr_cmpltn_cmn { + u8 status; + u8 tid_num; + __le16 sw_peer_id; + /* RSSI value of last ack packet (units = dB above noise floor) */ + __le32 ack_rssi; + __le16 mpdu_tried; + __le16 mpdu_success; + __le32 flags; /* %HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_LONG_RETRIES*/ +} __packed; + +#define HTT_PPDU_STATS_ACK_BA_INFO_NUM_MPDU_M GENMASK(8, 0) +#define HTT_PPDU_STATS_ACK_BA_INFO_NUM_MSDU_M GENMASK(24, 9) +#define HTT_PPDU_STATS_ACK_BA_INFO_TID_NUM GENMASK(31, 25) + +#define HTT_PPDU_STATS_NON_QOS_TID 16 + +struct htt_ppdu_stats_usr_cmpltn_ack_ba_status { + __le32 ppdu_id; + __le16 sw_peer_id; + __le16 reserved0; + __le32 info; /* %HTT_PPDU_STATS_USR_CMPLTN_CMN_INFO_ */ + __le16 current_seq; + __le16 start_seq; + __le32 success_bytes; +} __packed; + +struct htt_ppdu_user_stats { + u16 peer_id; + u16 delay_ba; + u32 tlv_flags; + bool is_valid_peer_id; + struct htt_ppdu_stats_user_rate rate; + struct htt_ppdu_stats_usr_cmpltn_cmn cmpltn_cmn; + struct htt_ppdu_stats_usr_cmpltn_ack_ba_status ack_ba; +}; + +#define HTT_PPDU_STATS_MAX_USERS 8 +#define HTT_PPDU_DESC_MAX_DEPTH 16 + +struct htt_ppdu_stats { + struct htt_ppdu_stats_common common; + struct htt_ppdu_user_stats user_stats[HTT_PPDU_STATS_MAX_USERS]; +}; + +struct htt_ppdu_stats_info { + u32 tlv_bitmap; + u32 ppdu_id; + u32 frame_type; + u32 frame_ctrl; + u32 delay_ba; + u32 bar_num_users; + struct htt_ppdu_stats ppdu_stats; + struct list_head list; +}; + +/* @brief target -> host MLO offset indiciation message + * + * @details + * The following field definitions describe the format of the HTT target + * to host mlo offset indication message. + * + * + * |31 29|28 |26|25 22|21 16|15 13|12 10 |9 8|7 0| + * |---------------------------------------------------------------------| + * | rsvd1 | mac_freq |chip_id |pdev_id|msgtype| + * |---------------------------------------------------------------------| + * | sync_timestamp_lo_us | + * |---------------------------------------------------------------------| + * | sync_timestamp_hi_us | + * |---------------------------------------------------------------------| + * | mlo_offset_lo | + * |---------------------------------------------------------------------| + * | mlo_offset_hi | + * |---------------------------------------------------------------------| + * | mlo_offset_clcks | + * |---------------------------------------------------------------------| + * | rsvd2 | mlo_comp_clks |mlo_comp_us | + * |---------------------------------------------------------------------| + * | rsvd3 |mlo_comp_timer | + * |---------------------------------------------------------------------| + * Header fields + * - MSG_TYPE + * Bits 7:0 + * Purpose: Identifies this is a MLO offset indication msg + * - PDEV_ID + * Bits 9:8 + * Purpose: Pdev of this MLO offset + * - CHIP_ID + * Bits 12:10 + * Purpose: chip_id of this MLO offset + * - MAC_FREQ + * Bits 28:13 + * - SYNC_TIMESTAMP_LO_US + * Purpose: clock frequency of the mac HW block in MHz + * Bits: 31:0 + * Purpose: lower 32 bits of the WLAN global time stamp at which + * last sync interrupt was received + * - SYNC_TIMESTAMP_HI_US + * Bits: 31:0 + * Purpose: upper 32 bits of WLAN global time stamp at which + * last sync interrupt was received + * - MLO_OFFSET_LO + * Bits: 31:0 + * Purpose: lower 32 bits of the MLO offset in us + * - MLO_OFFSET_HI + * Bits: 31:0 + * Purpose: upper 32 bits of the MLO offset in us + * - MLO_COMP_US + * Bits: 15:0 + * Purpose: MLO time stamp compensation applied in us + * - MLO_COMP_CLCKS + * Bits: 25:16 + * Purpose: MLO time stamp compensation applied in clock ticks + * - MLO_COMP_TIMER + * Bits: 21:0 + * Purpose: Periodic timer at which compensation is applied + */ + +#define HTT_T2H_MLO_OFFSET_INFO_MSG_TYPE GENMASK(7, 0) +#define HTT_T2H_MLO_OFFSET_INFO_PDEV_ID GENMASK(9, 8) + +struct ath12k_htt_mlo_offset_msg { + __le32 info; + __le32 sync_timestamp_lo_us; + __le32 sync_timestamp_hi_us; + __le32 mlo_offset_hi; + __le32 mlo_offset_lo; + __le32 mlo_offset_clks; + __le32 mlo_comp_clks; + __le32 mlo_comp_timer; +} __packed; + +/* @brief host -> target FW extended statistics retrieve + * + * @details + * The following field definitions describe the format of the HTT host + * to target FW extended stats retrieve message. + * The message specifies the type of stats the host wants to retrieve. + * + * |31 24|23 16|15 8|7 0| + * |-----------------------------------------------------------| + * | reserved | stats type | pdev_mask | msg type | + * |-----------------------------------------------------------| + * | config param [0] | + * |-----------------------------------------------------------| + * | config param [1] | + * |-----------------------------------------------------------| + * | config param [2] | + * |-----------------------------------------------------------| + * | config param [3] | + * |-----------------------------------------------------------| + * | reserved | + * |-----------------------------------------------------------| + * | cookie LSBs | + * |-----------------------------------------------------------| + * | cookie MSBs | + * |-----------------------------------------------------------| + * Header fields: + * - MSG_TYPE + * Bits 7:0 + * Purpose: identifies this is a extended stats upload request message + * Value: 0x10 + * - PDEV_MASK + * Bits 8:15 + * Purpose: identifies the mask of PDEVs to retrieve stats from + * Value: This is a overloaded field, refer to usage and interpretation of + * PDEV in interface document. + * Bit 8 : Reserved for SOC stats + * Bit 9 - 15 : Indicates PDEV_MASK in DBDC + * Indicates MACID_MASK in DBS + * - STATS_TYPE + * Bits 23:16 + * Purpose: identifies which FW statistics to upload + * Value: Defined by htt_dbg_ext_stats_type (see htt_stats.h) + * - Reserved + * Bits 31:24 + * - CONFIG_PARAM [0] + * Bits 31:0 + * Purpose: give an opaque configuration value to the specified stats type + * Value: stats-type specific configuration value + * Refer to htt_stats.h for interpretation for each stats sub_type + * - CONFIG_PARAM [1] + * Bits 31:0 + * Purpose: give an opaque configuration value to the specified stats type + * Value: stats-type specific configuration value + * Refer to htt_stats.h for interpretation for each stats sub_type + * - CONFIG_PARAM [2] + * Bits 31:0 + * Purpose: give an opaque configuration value to the specified stats type + * Value: stats-type specific configuration value + * Refer to htt_stats.h for interpretation for each stats sub_type + * - CONFIG_PARAM [3] + * Bits 31:0 + * Purpose: give an opaque configuration value to the specified stats type + * Value: stats-type specific configuration value + * Refer to htt_stats.h for interpretation for each stats sub_type + * - Reserved [31:0] for future use. + * - COOKIE_LSBS + * Bits 31:0 + * Purpose: Provide a mechanism to match a target->host stats confirmation + * message with its preceding host->target stats request message. + * Value: LSBs of the opaque cookie specified by the host-side requestor + * - COOKIE_MSBS + * Bits 31:0 + * Purpose: Provide a mechanism to match a target->host stats confirmation + * message with its preceding host->target stats request message. + * Value: MSBs of the opaque cookie specified by the host-side requestor + */ + +struct htt_ext_stats_cfg_hdr { + u8 msg_type; + u8 pdev_mask; + u8 stats_type; + u8 reserved; +} __packed; + +struct htt_ext_stats_cfg_cmd { + struct htt_ext_stats_cfg_hdr hdr; + __le32 cfg_param0; + __le32 cfg_param1; + __le32 cfg_param2; + __le32 cfg_param3; + __le32 reserved; + __le32 cookie_lsb; + __le32 cookie_msb; +} __packed; + +/* htt stats config default params */ +#define HTT_STAT_DEFAULT_RESET_START_OFFSET 0 +#define HTT_STAT_DEFAULT_CFG0_ALL_HWQS 0xffffffff +#define HTT_STAT_DEFAULT_CFG0_ALL_TXQS 0xffffffff +#define HTT_STAT_DEFAULT_CFG0_ALL_CMDQS 0xffff +#define HTT_STAT_DEFAULT_CFG0_ALL_RINGS 0xffff +#define HTT_STAT_DEFAULT_CFG0_ACTIVE_PEERS 0xff +#define HTT_STAT_DEFAULT_CFG0_CCA_CUMULATIVE 0x00 +#define HTT_STAT_DEFAULT_CFG0_ACTIVE_VDEVS 0x00 + +/* HTT_DBG_EXT_STATS_PEER_INFO + * PARAMS: + * @config_param0: + * [Bit0] - [0] for sw_peer_id, [1] for mac_addr based request + * [Bit15 : Bit 1] htt_peer_stats_req_mode_t + * [Bit31 : Bit16] sw_peer_id + * @config_param1: + * peer_stats_req_type_mask:32 (enum htt_peer_stats_tlv_enum) + * 0 bit htt_peer_stats_cmn_tlv + * 1 bit htt_peer_details_tlv + * 2 bit htt_tx_peer_rate_stats_tlv + * 3 bit htt_rx_peer_rate_stats_tlv + * 4 bit htt_tx_tid_stats_tlv/htt_tx_tid_stats_v1_tlv + * 5 bit htt_rx_tid_stats_tlv + * 6 bit htt_msdu_flow_stats_tlv + * @config_param2: [Bit31 : Bit0] mac_addr31to0 + * @config_param3: [Bit15 : Bit0] mac_addr47to32 + * [Bit31 : Bit16] reserved + */ +#define HTT_STAT_PEER_INFO_MAC_ADDR BIT(0) +#define HTT_STAT_DEFAULT_PEER_REQ_TYPE 0x7f + +/* Used to set different configs to the specified stats type.*/ +struct htt_ext_stats_cfg_params { + u32 cfg0; + u32 cfg1; + u32 cfg2; + u32 cfg3; +}; + +enum vdev_stats_offload_timer_duration { + ATH12K_STATS_TIMER_DUR_500MS = 1, + ATH12K_STATS_TIMER_DUR_1SEC = 2, + ATH12K_STATS_TIMER_DUR_2SEC = 3, +}; + +#define ATH12K_HTT_MAC_ADDR_L32_0 GENMASK(7, 0) +#define ATH12K_HTT_MAC_ADDR_L32_1 GENMASK(15, 8) +#define ATH12K_HTT_MAC_ADDR_L32_2 GENMASK(23, 16) +#define ATH12K_HTT_MAC_ADDR_L32_3 GENMASK(31, 24) +#define ATH12K_HTT_MAC_ADDR_H16_0 GENMASK(7, 0) +#define ATH12K_HTT_MAC_ADDR_H16_1 GENMASK(15, 8) + +struct htt_mac_addr { + __le32 mac_addr_l32; + __le32 mac_addr_h16; +} __packed; + +#endif From ec98794e806c7ddaa8b225626acb9f532c1f4a61 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Thu, 28 Aug 2025 23:05:51 +0530 Subject: [PATCH 031/140] wifi: ath12k: Move HTT Rx specific code to newly introduced files WLAN Host driver interacts with the Firmware and vice versa using Host-To-Target (HTT) interface. HTT interface code is spread across multiple files (ex dp_tx.c, dp_rx.c etc) and this interface is independent of the underlying architecture Tx and Rx. Relocate HTT specific code from dp_rx.c to newly introduced file dp_htt.c for HTT interface. This new file is compiled as part of the common module ath12k.ko. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-19-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/dp_htt.c | 644 +++++++++++++++++++++++ drivers/net/wireless/ath/ath12k/dp_htt.h | 6 + drivers/net/wireless/ath/ath12k/dp_rx.c | 633 ---------------------- drivers/net/wireless/ath/ath12k/dp_rx.h | 6 - 5 files changed, 651 insertions(+), 639 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/dp_htt.c diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index e72b52d5af6d6..70d4daa48c902 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -10,6 +10,7 @@ ath12k-y += core.o \ dp.o \ dp_tx.o \ dp_rx.o \ + dp_htt.o \ debug.o \ ce.o \ peer.o \ diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c new file mode 100644 index 0000000000000..00847d579b958 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -0,0 +1,644 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "core.h" +#include "peer.h" +#include "htc.h" +#include "dp_htt.h" +#include "debugfs_htt_stats.h" + +static int ath12k_get_ppdu_user_index(struct htt_ppdu_stats *ppdu_stats, + u16 peer_id) +{ + int i; + + for (i = 0; i < HTT_PPDU_STATS_MAX_USERS - 1; i++) { + if (ppdu_stats->user_stats[i].is_valid_peer_id) { + if (peer_id == ppdu_stats->user_stats[i].peer_id) + return i; + } else { + return i; + } + } + + return -EINVAL; +} + +static int ath12k_htt_tlv_ppdu_stats_parse(struct ath12k_base *ab, + u16 tag, u16 len, const void *ptr, + void *data) +{ + const struct htt_ppdu_stats_usr_cmpltn_ack_ba_status *ba_status; + const struct htt_ppdu_stats_usr_cmpltn_cmn *cmplt_cmn; + const struct htt_ppdu_stats_user_rate *user_rate; + struct htt_ppdu_stats_info *ppdu_info; + struct htt_ppdu_user_stats *user_stats; + int cur_user; + u16 peer_id; + + ppdu_info = data; + + switch (tag) { + case HTT_PPDU_STATS_TAG_COMMON: + if (len < sizeof(struct htt_ppdu_stats_common)) { + ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n", + len, tag); + return -EINVAL; + } + memcpy(&ppdu_info->ppdu_stats.common, ptr, + sizeof(struct htt_ppdu_stats_common)); + break; + case HTT_PPDU_STATS_TAG_USR_RATE: + if (len < sizeof(struct htt_ppdu_stats_user_rate)) { + ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n", + len, tag); + return -EINVAL; + } + user_rate = ptr; + peer_id = le16_to_cpu(user_rate->sw_peer_id); + cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats, + peer_id); + if (cur_user < 0) + return -EINVAL; + user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user]; + user_stats->peer_id = peer_id; + user_stats->is_valid_peer_id = true; + memcpy(&user_stats->rate, ptr, + sizeof(struct htt_ppdu_stats_user_rate)); + user_stats->tlv_flags |= BIT(tag); + break; + case HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON: + if (len < sizeof(struct htt_ppdu_stats_usr_cmpltn_cmn)) { + ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n", + len, tag); + return -EINVAL; + } + + cmplt_cmn = ptr; + peer_id = le16_to_cpu(cmplt_cmn->sw_peer_id); + cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats, + peer_id); + if (cur_user < 0) + return -EINVAL; + user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user]; + user_stats->peer_id = peer_id; + user_stats->is_valid_peer_id = true; + memcpy(&user_stats->cmpltn_cmn, ptr, + sizeof(struct htt_ppdu_stats_usr_cmpltn_cmn)); + user_stats->tlv_flags |= BIT(tag); + break; + case HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS: + if (len < + sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status)) { + ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n", + len, tag); + return -EINVAL; + } + + ba_status = ptr; + peer_id = le16_to_cpu(ba_status->sw_peer_id); + cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats, + peer_id); + if (cur_user < 0) + return -EINVAL; + user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user]; + user_stats->peer_id = peer_id; + user_stats->is_valid_peer_id = true; + memcpy(&user_stats->ack_ba, ptr, + sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status)); + user_stats->tlv_flags |= BIT(tag); + break; + } + return 0; +} + +int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len, + int (*iter)(struct ath12k_base *ar, u16 tag, u16 len, + const void *ptr, void *data), + void *data) +{ + const struct htt_tlv *tlv; + const void *begin = ptr; + u16 tlv_tag, tlv_len; + int ret = -EINVAL; + + while (len > 0) { + if (len < sizeof(*tlv)) { + ath12k_err(ab, "htt tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n", + ptr - begin, len, sizeof(*tlv)); + return -EINVAL; + } + tlv = (struct htt_tlv *)ptr; + tlv_tag = le32_get_bits(tlv->header, HTT_TLV_TAG); + tlv_len = le32_get_bits(tlv->header, HTT_TLV_LEN); + ptr += sizeof(*tlv); + len -= sizeof(*tlv); + + if (tlv_len > len) { + ath12k_err(ab, "htt tlv parse failure of tag %u at byte %zd (%zu bytes left, %u expected)\n", + tlv_tag, ptr - begin, len, tlv_len); + return -EINVAL; + } + ret = iter(ab, tlv_tag, tlv_len, ptr, data); + if (ret == -ENOMEM) + return ret; + + ptr += tlv_len; + len -= tlv_len; + } + return 0; +} + +static void +ath12k_update_per_peer_tx_stats(struct ath12k *ar, + struct htt_ppdu_stats *ppdu_stats, u8 user) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_peer *peer; + struct ath12k_link_sta *arsta; + struct htt_ppdu_stats_user_rate *user_rate; + struct ath12k_per_peer_tx_stats *peer_stats = &ar->peer_tx_stats; + struct htt_ppdu_user_stats *usr_stats = &ppdu_stats->user_stats[user]; + struct htt_ppdu_stats_common *common = &ppdu_stats->common; + int ret; + u8 flags, mcs, nss, bw, sgi, dcm, ppdu_type, rate_idx = 0; + u32 v, succ_bytes = 0; + u16 tones, rate = 0, succ_pkts = 0; + u32 tx_duration = 0; + u8 tid = HTT_PPDU_STATS_NON_QOS_TID; + u16 tx_retry_failed = 0, tx_retry_count = 0; + bool is_ampdu = false, is_ofdma; + + if (!(usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_RATE))) + return; + + if (usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON)) { + is_ampdu = + HTT_USR_CMPLTN_IS_AMPDU(usr_stats->cmpltn_cmn.flags); + tx_retry_failed = + __le16_to_cpu(usr_stats->cmpltn_cmn.mpdu_tried) - + __le16_to_cpu(usr_stats->cmpltn_cmn.mpdu_success); + tx_retry_count = + HTT_USR_CMPLTN_LONG_RETRY(usr_stats->cmpltn_cmn.flags) + + HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags); + } + + if (usr_stats->tlv_flags & + BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS)) { + succ_bytes = le32_to_cpu(usr_stats->ack_ba.success_bytes); + succ_pkts = le32_get_bits(usr_stats->ack_ba.info, + HTT_PPDU_STATS_ACK_BA_INFO_NUM_MSDU_M); + tid = le32_get_bits(usr_stats->ack_ba.info, + HTT_PPDU_STATS_ACK_BA_INFO_TID_NUM); + } + + if (common->fes_duration_us) + tx_duration = le32_to_cpu(common->fes_duration_us); + + user_rate = &usr_stats->rate; + flags = HTT_USR_RATE_PREAMBLE(user_rate->rate_flags); + bw = HTT_USR_RATE_BW(user_rate->rate_flags) - 2; + nss = HTT_USR_RATE_NSS(user_rate->rate_flags) + 1; + mcs = HTT_USR_RATE_MCS(user_rate->rate_flags); + sgi = HTT_USR_RATE_GI(user_rate->rate_flags); + dcm = HTT_USR_RATE_DCM(user_rate->rate_flags); + + ppdu_type = HTT_USR_RATE_PPDU_TYPE(user_rate->info1); + is_ofdma = (ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA) || + (ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA); + + /* Note: If host configured fixed rates and in some other special + * cases, the broadcast/management frames are sent in different rates. + * Firmware rate's control to be skipped for this? + */ + + if (flags == WMI_RATE_PREAMBLE_HE && mcs > ATH12K_HE_MCS_MAX) { + ath12k_warn(ab, "Invalid HE mcs %d peer stats", mcs); + return; + } + + if (flags == WMI_RATE_PREAMBLE_VHT && mcs > ATH12K_VHT_MCS_MAX) { + ath12k_warn(ab, "Invalid VHT mcs %d peer stats", mcs); + return; + } + + if (flags == WMI_RATE_PREAMBLE_HT && (mcs > ATH12K_HT_MCS_MAX || nss < 1)) { + ath12k_warn(ab, "Invalid HT mcs %d nss %d peer stats", + mcs, nss); + return; + } + + if (flags == WMI_RATE_PREAMBLE_CCK || flags == WMI_RATE_PREAMBLE_OFDM) { + ret = ath12k_mac_hw_ratecode_to_legacy_rate(mcs, + flags, + &rate_idx, + &rate); + if (ret < 0) + return; + } + + rcu_read_lock(); + spin_lock_bh(&ab->base_lock); + peer = ath12k_peer_find_by_id(ab, usr_stats->peer_id); + + if (!peer || !peer->sta) { + spin_unlock_bh(&ab->base_lock); + rcu_read_unlock(); + return; + } + + arsta = ath12k_peer_get_link_sta(ab, peer); + if (!arsta) { + spin_unlock_bh(&ab->base_lock); + rcu_read_unlock(); + return; + } + + memset(&arsta->txrate, 0, sizeof(arsta->txrate)); + + arsta->txrate.bw = ath12k_mac_bw_to_mac80211_bw(bw); + + switch (flags) { + case WMI_RATE_PREAMBLE_OFDM: + arsta->txrate.legacy = rate; + break; + case WMI_RATE_PREAMBLE_CCK: + arsta->txrate.legacy = rate; + break; + case WMI_RATE_PREAMBLE_HT: + arsta->txrate.mcs = mcs + 8 * (nss - 1); + arsta->txrate.flags = RATE_INFO_FLAGS_MCS; + if (sgi) + arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + break; + case WMI_RATE_PREAMBLE_VHT: + arsta->txrate.mcs = mcs; + arsta->txrate.flags = RATE_INFO_FLAGS_VHT_MCS; + if (sgi) + arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + break; + case WMI_RATE_PREAMBLE_HE: + arsta->txrate.mcs = mcs; + arsta->txrate.flags = RATE_INFO_FLAGS_HE_MCS; + arsta->txrate.he_dcm = dcm; + arsta->txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi); + tones = le16_to_cpu(user_rate->ru_end) - + le16_to_cpu(user_rate->ru_start) + 1; + v = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(tones); + arsta->txrate.he_ru_alloc = v; + if (is_ofdma) + arsta->txrate.bw = RATE_INFO_BW_HE_RU; + break; + case WMI_RATE_PREAMBLE_EHT: + arsta->txrate.mcs = mcs; + arsta->txrate.flags = RATE_INFO_FLAGS_EHT_MCS; + arsta->txrate.he_dcm = dcm; + arsta->txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(sgi); + tones = le16_to_cpu(user_rate->ru_end) - + le16_to_cpu(user_rate->ru_start) + 1; + v = ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(tones); + arsta->txrate.eht_ru_alloc = v; + if (is_ofdma) + arsta->txrate.bw = RATE_INFO_BW_EHT_RU; + break; + } + + arsta->tx_retry_failed += tx_retry_failed; + arsta->tx_retry_count += tx_retry_count; + arsta->txrate.nss = nss; + arsta->tx_duration += tx_duration; + memcpy(&arsta->last_txrate, &arsta->txrate, sizeof(struct rate_info)); + + /* PPDU stats reported for mgmt packet doesn't have valid tx bytes. + * So skip peer stats update for mgmt packets. + */ + if (tid < HTT_PPDU_STATS_NON_QOS_TID) { + memset(peer_stats, 0, sizeof(*peer_stats)); + peer_stats->succ_pkts = succ_pkts; + peer_stats->succ_bytes = succ_bytes; + peer_stats->is_ampdu = is_ampdu; + peer_stats->duration = tx_duration; + peer_stats->ba_fails = + HTT_USR_CMPLTN_LONG_RETRY(usr_stats->cmpltn_cmn.flags) + + HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags); + } + + spin_unlock_bh(&ab->base_lock); + rcu_read_unlock(); +} + +static void ath12k_htt_update_ppdu_stats(struct ath12k *ar, + struct htt_ppdu_stats *ppdu_stats) +{ + u8 user; + + for (user = 0; user < HTT_PPDU_STATS_MAX_USERS - 1; user++) + ath12k_update_per_peer_tx_stats(ar, ppdu_stats, user); +} + +static +struct htt_ppdu_stats_info *ath12k_dp_htt_get_ppdu_desc(struct ath12k *ar, + u32 ppdu_id) +{ + struct htt_ppdu_stats_info *ppdu_info; + + lockdep_assert_held(&ar->data_lock); + if (!list_empty(&ar->ppdu_stats_info)) { + list_for_each_entry(ppdu_info, &ar->ppdu_stats_info, list) { + if (ppdu_info->ppdu_id == ppdu_id) + return ppdu_info; + } + + if (ar->ppdu_stat_list_depth > HTT_PPDU_DESC_MAX_DEPTH) { + ppdu_info = list_first_entry(&ar->ppdu_stats_info, + typeof(*ppdu_info), list); + list_del(&ppdu_info->list); + ar->ppdu_stat_list_depth--; + ath12k_htt_update_ppdu_stats(ar, &ppdu_info->ppdu_stats); + kfree(ppdu_info); + } + } + + ppdu_info = kzalloc(sizeof(*ppdu_info), GFP_ATOMIC); + if (!ppdu_info) + return NULL; + + list_add_tail(&ppdu_info->list, &ar->ppdu_stats_info); + ar->ppdu_stat_list_depth++; + + return ppdu_info; +} + +static void ath12k_copy_to_delay_stats(struct ath12k_peer *peer, + struct htt_ppdu_user_stats *usr_stats) +{ + peer->ppdu_stats_delayba.sw_peer_id = le16_to_cpu(usr_stats->rate.sw_peer_id); + peer->ppdu_stats_delayba.info0 = le32_to_cpu(usr_stats->rate.info0); + peer->ppdu_stats_delayba.ru_end = le16_to_cpu(usr_stats->rate.ru_end); + peer->ppdu_stats_delayba.ru_start = le16_to_cpu(usr_stats->rate.ru_start); + peer->ppdu_stats_delayba.info1 = le32_to_cpu(usr_stats->rate.info1); + peer->ppdu_stats_delayba.rate_flags = le32_to_cpu(usr_stats->rate.rate_flags); + peer->ppdu_stats_delayba.resp_rate_flags = + le32_to_cpu(usr_stats->rate.resp_rate_flags); + + peer->delayba_flag = true; +} + +static void ath12k_copy_to_bar(struct ath12k_peer *peer, + struct htt_ppdu_user_stats *usr_stats) +{ + usr_stats->rate.sw_peer_id = cpu_to_le16(peer->ppdu_stats_delayba.sw_peer_id); + usr_stats->rate.info0 = cpu_to_le32(peer->ppdu_stats_delayba.info0); + usr_stats->rate.ru_end = cpu_to_le16(peer->ppdu_stats_delayba.ru_end); + usr_stats->rate.ru_start = cpu_to_le16(peer->ppdu_stats_delayba.ru_start); + usr_stats->rate.info1 = cpu_to_le32(peer->ppdu_stats_delayba.info1); + usr_stats->rate.rate_flags = cpu_to_le32(peer->ppdu_stats_delayba.rate_flags); + usr_stats->rate.resp_rate_flags = + cpu_to_le32(peer->ppdu_stats_delayba.resp_rate_flags); + + peer->delayba_flag = false; +} + +static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, + struct sk_buff *skb) +{ + struct ath12k_htt_ppdu_stats_msg *msg; + struct htt_ppdu_stats_info *ppdu_info; + struct ath12k_peer *peer = NULL; + struct htt_ppdu_user_stats *usr_stats = NULL; + u32 peer_id = 0; + struct ath12k *ar; + int ret, i; + u8 pdev_id; + u32 ppdu_id, len; + + msg = (struct ath12k_htt_ppdu_stats_msg *)skb->data; + len = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PAYLOAD_SIZE); + if (len > (skb->len - struct_size(msg, data, 0))) { + ath12k_warn(ab, + "HTT PPDU STATS event has unexpected payload size %u, should be smaller than %u\n", + len, skb->len); + return -EINVAL; + } + + pdev_id = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PDEV_ID); + ppdu_id = le32_to_cpu(msg->ppdu_id); + + rcu_read_lock(); + ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id); + if (!ar) { + ret = -EINVAL; + goto exit; + } + + spin_lock_bh(&ar->data_lock); + ppdu_info = ath12k_dp_htt_get_ppdu_desc(ar, ppdu_id); + if (!ppdu_info) { + spin_unlock_bh(&ar->data_lock); + ret = -EINVAL; + goto exit; + } + + ppdu_info->ppdu_id = ppdu_id; + ret = ath12k_dp_htt_tlv_iter(ab, msg->data, len, + ath12k_htt_tlv_ppdu_stats_parse, + (void *)ppdu_info); + if (ret) { + spin_unlock_bh(&ar->data_lock); + ath12k_warn(ab, "Failed to parse tlv %d\n", ret); + goto exit; + } + + if (ppdu_info->ppdu_stats.common.num_users >= HTT_PPDU_STATS_MAX_USERS) { + spin_unlock_bh(&ar->data_lock); + ath12k_warn(ab, + "HTT PPDU STATS event has unexpected num_users %u, should be smaller than %u\n", + ppdu_info->ppdu_stats.common.num_users, + HTT_PPDU_STATS_MAX_USERS); + ret = -EINVAL; + goto exit; + } + + /* back up data rate tlv for all peers */ + if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_DATA && + (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON)) && + ppdu_info->delay_ba) { + for (i = 0; i < ppdu_info->ppdu_stats.common.num_users; i++) { + peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; + spin_lock_bh(&ab->base_lock); + peer = ath12k_peer_find_by_id(ab, peer_id); + if (!peer) { + spin_unlock_bh(&ab->base_lock); + continue; + } + + usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; + if (usr_stats->delay_ba) + ath12k_copy_to_delay_stats(peer, usr_stats); + spin_unlock_bh(&ab->base_lock); + } + } + + /* restore all peers' data rate tlv to mu-bar tlv */ + if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_BAR && + (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON))) { + for (i = 0; i < ppdu_info->bar_num_users; i++) { + peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; + spin_lock_bh(&ab->base_lock); + peer = ath12k_peer_find_by_id(ab, peer_id); + if (!peer) { + spin_unlock_bh(&ab->base_lock); + continue; + } + + usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; + if (peer->delayba_flag) + ath12k_copy_to_bar(peer, usr_stats); + spin_unlock_bh(&ab->base_lock); + } + } + + spin_unlock_bh(&ar->data_lock); + +exit: + rcu_read_unlock(); + + return ret; +} + +static void ath12k_htt_mlo_offset_event_handler(struct ath12k_base *ab, + struct sk_buff *skb) +{ + struct ath12k_htt_mlo_offset_msg *msg; + struct ath12k_pdev *pdev; + struct ath12k *ar; + u8 pdev_id; + + msg = (struct ath12k_htt_mlo_offset_msg *)skb->data; + pdev_id = u32_get_bits(__le32_to_cpu(msg->info), + HTT_T2H_MLO_OFFSET_INFO_PDEV_ID); + + rcu_read_lock(); + ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id); + if (!ar) { + /* It is possible that the ar is not yet active (started). + * The above function will only look for the active pdev + * and hence %NULL return is possible. Just silently + * discard this message + */ + goto exit; + } + + spin_lock_bh(&ar->data_lock); + pdev = ar->pdev; + + pdev->timestamp.info = __le32_to_cpu(msg->info); + pdev->timestamp.sync_timestamp_lo_us = __le32_to_cpu(msg->sync_timestamp_lo_us); + pdev->timestamp.sync_timestamp_hi_us = __le32_to_cpu(msg->sync_timestamp_hi_us); + pdev->timestamp.mlo_offset_lo = __le32_to_cpu(msg->mlo_offset_lo); + pdev->timestamp.mlo_offset_hi = __le32_to_cpu(msg->mlo_offset_hi); + pdev->timestamp.mlo_offset_clks = __le32_to_cpu(msg->mlo_offset_clks); + pdev->timestamp.mlo_comp_clks = __le32_to_cpu(msg->mlo_comp_clks); + pdev->timestamp.mlo_comp_timer = __le32_to_cpu(msg->mlo_comp_timer); + + spin_unlock_bh(&ar->data_lock); +exit: + rcu_read_unlock(); +} + +void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, + struct sk_buff *skb) +{ + struct ath12k_dp *dp = &ab->dp; + struct htt_resp_msg *resp = (struct htt_resp_msg *)skb->data; + enum htt_t2h_msg_type type; + u16 peer_id; + u8 vdev_id; + u8 mac_addr[ETH_ALEN]; + u16 peer_mac_h16; + u16 ast_hash = 0; + u16 hw_peer_id; + + type = le32_get_bits(resp->version_msg.version, HTT_T2H_MSG_TYPE); + + ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt rx msg type :0x%0x\n", type); + + switch (type) { + case HTT_T2H_MSG_TYPE_VERSION_CONF: + dp->htt_tgt_ver_major = le32_get_bits(resp->version_msg.version, + HTT_T2H_VERSION_CONF_MAJOR); + dp->htt_tgt_ver_minor = le32_get_bits(resp->version_msg.version, + HTT_T2H_VERSION_CONF_MINOR); + complete(&dp->htt_tgt_version_received); + break; + /* TODO: remove unused peer map versions after testing */ + case HTT_T2H_MSG_TYPE_PEER_MAP: + vdev_id = le32_get_bits(resp->peer_map_ev.info, + HTT_T2H_PEER_MAP_INFO_VDEV_ID); + peer_id = le32_get_bits(resp->peer_map_ev.info, + HTT_T2H_PEER_MAP_INFO_PEER_ID); + peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1, + HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16); + ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32), + peer_mac_h16, mac_addr); + ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, 0, 0); + break; + case HTT_T2H_MSG_TYPE_PEER_MAP2: + vdev_id = le32_get_bits(resp->peer_map_ev.info, + HTT_T2H_PEER_MAP_INFO_VDEV_ID); + peer_id = le32_get_bits(resp->peer_map_ev.info, + HTT_T2H_PEER_MAP_INFO_PEER_ID); + peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1, + HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16); + ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32), + peer_mac_h16, mac_addr); + ast_hash = le32_get_bits(resp->peer_map_ev.info2, + HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL); + hw_peer_id = le32_get_bits(resp->peer_map_ev.info1, + HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID); + ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash, + hw_peer_id); + break; + case HTT_T2H_MSG_TYPE_PEER_MAP3: + vdev_id = le32_get_bits(resp->peer_map_ev.info, + HTT_T2H_PEER_MAP_INFO_VDEV_ID); + peer_id = le32_get_bits(resp->peer_map_ev.info, + HTT_T2H_PEER_MAP_INFO_PEER_ID); + peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1, + HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16); + ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32), + peer_mac_h16, mac_addr); + ast_hash = le32_get_bits(resp->peer_map_ev.info2, + HTT_T2H_PEER_MAP3_INFO2_AST_HASH_VAL); + hw_peer_id = le32_get_bits(resp->peer_map_ev.info2, + HTT_T2H_PEER_MAP3_INFO2_HW_PEER_ID); + ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash, + hw_peer_id); + break; + case HTT_T2H_MSG_TYPE_PEER_UNMAP: + case HTT_T2H_MSG_TYPE_PEER_UNMAP2: + peer_id = le32_get_bits(resp->peer_unmap_ev.info, + HTT_T2H_PEER_UNMAP_INFO_PEER_ID); + ath12k_peer_unmap_event(ab, peer_id); + break; + case HTT_T2H_MSG_TYPE_PPDU_STATS_IND: + ath12k_htt_pull_ppdu_stats(ab, skb); + break; + case HTT_T2H_MSG_TYPE_EXT_STATS_CONF: + ath12k_debugfs_htt_ext_stats_handler(ab, skb); + break; + case HTT_T2H_MSG_TYPE_MLO_TIMESTAMP_OFFSET_IND: + ath12k_htt_mlo_offset_event_handler(ab, skb); + break; + default: + ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt event %d not handled\n", + type); + break; + } + + dev_kfree_skb_any(skb); +} +EXPORT_SYMBOL(ath12k_dp_htt_htc_t2h_msg_handler); diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.h b/drivers/net/wireless/ath/ath12k/dp_htt.h index ce9064628d343..9ae3a750f6081 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.h +++ b/drivers/net/wireless/ath/ath12k/dp_htt.h @@ -1514,4 +1514,10 @@ struct htt_mac_addr { __le32 mac_addr_h16; } __packed; +int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len, + int (*iter)(struct ath12k_base *ar, u16 tag, u16 len, + const void *ptr, void *data), + void *data); +void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, + struct sk_buff *skb); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index a66900541f7c3..6505a37f02e9d 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -773,639 +773,6 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, return ret; } -static int ath12k_get_ppdu_user_index(struct htt_ppdu_stats *ppdu_stats, - u16 peer_id) -{ - int i; - - for (i = 0; i < HTT_PPDU_STATS_MAX_USERS - 1; i++) { - if (ppdu_stats->user_stats[i].is_valid_peer_id) { - if (peer_id == ppdu_stats->user_stats[i].peer_id) - return i; - } else { - return i; - } - } - - return -EINVAL; -} - -static int ath12k_htt_tlv_ppdu_stats_parse(struct ath12k_base *ab, - u16 tag, u16 len, const void *ptr, - void *data) -{ - const struct htt_ppdu_stats_usr_cmpltn_ack_ba_status *ba_status; - const struct htt_ppdu_stats_usr_cmpltn_cmn *cmplt_cmn; - const struct htt_ppdu_stats_user_rate *user_rate; - struct htt_ppdu_stats_info *ppdu_info; - struct htt_ppdu_user_stats *user_stats; - int cur_user; - u16 peer_id; - - ppdu_info = data; - - switch (tag) { - case HTT_PPDU_STATS_TAG_COMMON: - if (len < sizeof(struct htt_ppdu_stats_common)) { - ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n", - len, tag); - return -EINVAL; - } - memcpy(&ppdu_info->ppdu_stats.common, ptr, - sizeof(struct htt_ppdu_stats_common)); - break; - case HTT_PPDU_STATS_TAG_USR_RATE: - if (len < sizeof(struct htt_ppdu_stats_user_rate)) { - ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n", - len, tag); - return -EINVAL; - } - user_rate = ptr; - peer_id = le16_to_cpu(user_rate->sw_peer_id); - cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats, - peer_id); - if (cur_user < 0) - return -EINVAL; - user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user]; - user_stats->peer_id = peer_id; - user_stats->is_valid_peer_id = true; - memcpy(&user_stats->rate, ptr, - sizeof(struct htt_ppdu_stats_user_rate)); - user_stats->tlv_flags |= BIT(tag); - break; - case HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON: - if (len < sizeof(struct htt_ppdu_stats_usr_cmpltn_cmn)) { - ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n", - len, tag); - return -EINVAL; - } - - cmplt_cmn = ptr; - peer_id = le16_to_cpu(cmplt_cmn->sw_peer_id); - cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats, - peer_id); - if (cur_user < 0) - return -EINVAL; - user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user]; - user_stats->peer_id = peer_id; - user_stats->is_valid_peer_id = true; - memcpy(&user_stats->cmpltn_cmn, ptr, - sizeof(struct htt_ppdu_stats_usr_cmpltn_cmn)); - user_stats->tlv_flags |= BIT(tag); - break; - case HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS: - if (len < - sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status)) { - ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n", - len, tag); - return -EINVAL; - } - - ba_status = ptr; - peer_id = le16_to_cpu(ba_status->sw_peer_id); - cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats, - peer_id); - if (cur_user < 0) - return -EINVAL; - user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user]; - user_stats->peer_id = peer_id; - user_stats->is_valid_peer_id = true; - memcpy(&user_stats->ack_ba, ptr, - sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status)); - user_stats->tlv_flags |= BIT(tag); - break; - } - return 0; -} - -int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len, - int (*iter)(struct ath12k_base *ar, u16 tag, u16 len, - const void *ptr, void *data), - void *data) -{ - const struct htt_tlv *tlv; - const void *begin = ptr; - u16 tlv_tag, tlv_len; - int ret = -EINVAL; - - while (len > 0) { - if (len < sizeof(*tlv)) { - ath12k_err(ab, "htt tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n", - ptr - begin, len, sizeof(*tlv)); - return -EINVAL; - } - tlv = (struct htt_tlv *)ptr; - tlv_tag = le32_get_bits(tlv->header, HTT_TLV_TAG); - tlv_len = le32_get_bits(tlv->header, HTT_TLV_LEN); - ptr += sizeof(*tlv); - len -= sizeof(*tlv); - - if (tlv_len > len) { - ath12k_err(ab, "htt tlv parse failure of tag %u at byte %zd (%zu bytes left, %u expected)\n", - tlv_tag, ptr - begin, len, tlv_len); - return -EINVAL; - } - ret = iter(ab, tlv_tag, tlv_len, ptr, data); - if (ret == -ENOMEM) - return ret; - - ptr += tlv_len; - len -= tlv_len; - } - return 0; -} - -static void -ath12k_update_per_peer_tx_stats(struct ath12k *ar, - struct htt_ppdu_stats *ppdu_stats, u8 user) -{ - struct ath12k_base *ab = ar->ab; - struct ath12k_peer *peer; - struct ath12k_link_sta *arsta; - struct htt_ppdu_stats_user_rate *user_rate; - struct ath12k_per_peer_tx_stats *peer_stats = &ar->peer_tx_stats; - struct htt_ppdu_user_stats *usr_stats = &ppdu_stats->user_stats[user]; - struct htt_ppdu_stats_common *common = &ppdu_stats->common; - int ret; - u8 flags, mcs, nss, bw, sgi, dcm, ppdu_type, rate_idx = 0; - u32 v, succ_bytes = 0; - u16 tones, rate = 0, succ_pkts = 0; - u32 tx_duration = 0; - u8 tid = HTT_PPDU_STATS_NON_QOS_TID; - u16 tx_retry_failed = 0, tx_retry_count = 0; - bool is_ampdu = false, is_ofdma; - - if (!(usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_RATE))) - return; - - if (usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON)) { - is_ampdu = - HTT_USR_CMPLTN_IS_AMPDU(usr_stats->cmpltn_cmn.flags); - tx_retry_failed = - __le16_to_cpu(usr_stats->cmpltn_cmn.mpdu_tried) - - __le16_to_cpu(usr_stats->cmpltn_cmn.mpdu_success); - tx_retry_count = - HTT_USR_CMPLTN_LONG_RETRY(usr_stats->cmpltn_cmn.flags) + - HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags); - } - - if (usr_stats->tlv_flags & - BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS)) { - succ_bytes = le32_to_cpu(usr_stats->ack_ba.success_bytes); - succ_pkts = le32_get_bits(usr_stats->ack_ba.info, - HTT_PPDU_STATS_ACK_BA_INFO_NUM_MSDU_M); - tid = le32_get_bits(usr_stats->ack_ba.info, - HTT_PPDU_STATS_ACK_BA_INFO_TID_NUM); - } - - if (common->fes_duration_us) - tx_duration = le32_to_cpu(common->fes_duration_us); - - user_rate = &usr_stats->rate; - flags = HTT_USR_RATE_PREAMBLE(user_rate->rate_flags); - bw = HTT_USR_RATE_BW(user_rate->rate_flags) - 2; - nss = HTT_USR_RATE_NSS(user_rate->rate_flags) + 1; - mcs = HTT_USR_RATE_MCS(user_rate->rate_flags); - sgi = HTT_USR_RATE_GI(user_rate->rate_flags); - dcm = HTT_USR_RATE_DCM(user_rate->rate_flags); - - ppdu_type = HTT_USR_RATE_PPDU_TYPE(user_rate->info1); - is_ofdma = (ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA) || - (ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA); - - /* Note: If host configured fixed rates and in some other special - * cases, the broadcast/management frames are sent in different rates. - * Firmware rate's control to be skipped for this? - */ - - if (flags == WMI_RATE_PREAMBLE_HE && mcs > ATH12K_HE_MCS_MAX) { - ath12k_warn(ab, "Invalid HE mcs %d peer stats", mcs); - return; - } - - if (flags == WMI_RATE_PREAMBLE_VHT && mcs > ATH12K_VHT_MCS_MAX) { - ath12k_warn(ab, "Invalid VHT mcs %d peer stats", mcs); - return; - } - - if (flags == WMI_RATE_PREAMBLE_HT && (mcs > ATH12K_HT_MCS_MAX || nss < 1)) { - ath12k_warn(ab, "Invalid HT mcs %d nss %d peer stats", - mcs, nss); - return; - } - - if (flags == WMI_RATE_PREAMBLE_CCK || flags == WMI_RATE_PREAMBLE_OFDM) { - ret = ath12k_mac_hw_ratecode_to_legacy_rate(mcs, - flags, - &rate_idx, - &rate); - if (ret < 0) - return; - } - - rcu_read_lock(); - spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, usr_stats->peer_id); - - if (!peer || !peer->sta) { - spin_unlock_bh(&ab->base_lock); - rcu_read_unlock(); - return; - } - - arsta = ath12k_peer_get_link_sta(ab, peer); - if (!arsta) { - spin_unlock_bh(&ab->base_lock); - rcu_read_unlock(); - return; - } - - memset(&arsta->txrate, 0, sizeof(arsta->txrate)); - - arsta->txrate.bw = ath12k_mac_bw_to_mac80211_bw(bw); - - switch (flags) { - case WMI_RATE_PREAMBLE_OFDM: - arsta->txrate.legacy = rate; - break; - case WMI_RATE_PREAMBLE_CCK: - arsta->txrate.legacy = rate; - break; - case WMI_RATE_PREAMBLE_HT: - arsta->txrate.mcs = mcs + 8 * (nss - 1); - arsta->txrate.flags = RATE_INFO_FLAGS_MCS; - if (sgi) - arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; - break; - case WMI_RATE_PREAMBLE_VHT: - arsta->txrate.mcs = mcs; - arsta->txrate.flags = RATE_INFO_FLAGS_VHT_MCS; - if (sgi) - arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; - break; - case WMI_RATE_PREAMBLE_HE: - arsta->txrate.mcs = mcs; - arsta->txrate.flags = RATE_INFO_FLAGS_HE_MCS; - arsta->txrate.he_dcm = dcm; - arsta->txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi); - tones = le16_to_cpu(user_rate->ru_end) - - le16_to_cpu(user_rate->ru_start) + 1; - v = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(tones); - arsta->txrate.he_ru_alloc = v; - if (is_ofdma) - arsta->txrate.bw = RATE_INFO_BW_HE_RU; - break; - case WMI_RATE_PREAMBLE_EHT: - arsta->txrate.mcs = mcs; - arsta->txrate.flags = RATE_INFO_FLAGS_EHT_MCS; - arsta->txrate.he_dcm = dcm; - arsta->txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(sgi); - tones = le16_to_cpu(user_rate->ru_end) - - le16_to_cpu(user_rate->ru_start) + 1; - v = ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(tones); - arsta->txrate.eht_ru_alloc = v; - if (is_ofdma) - arsta->txrate.bw = RATE_INFO_BW_EHT_RU; - break; - } - - arsta->tx_retry_failed += tx_retry_failed; - arsta->tx_retry_count += tx_retry_count; - arsta->txrate.nss = nss; - arsta->tx_duration += tx_duration; - memcpy(&arsta->last_txrate, &arsta->txrate, sizeof(struct rate_info)); - - /* PPDU stats reported for mgmt packet doesn't have valid tx bytes. - * So skip peer stats update for mgmt packets. - */ - if (tid < HTT_PPDU_STATS_NON_QOS_TID) { - memset(peer_stats, 0, sizeof(*peer_stats)); - peer_stats->succ_pkts = succ_pkts; - peer_stats->succ_bytes = succ_bytes; - peer_stats->is_ampdu = is_ampdu; - peer_stats->duration = tx_duration; - peer_stats->ba_fails = - HTT_USR_CMPLTN_LONG_RETRY(usr_stats->cmpltn_cmn.flags) + - HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags); - } - - spin_unlock_bh(&ab->base_lock); - rcu_read_unlock(); -} - -static void ath12k_htt_update_ppdu_stats(struct ath12k *ar, - struct htt_ppdu_stats *ppdu_stats) -{ - u8 user; - - for (user = 0; user < HTT_PPDU_STATS_MAX_USERS - 1; user++) - ath12k_update_per_peer_tx_stats(ar, ppdu_stats, user); -} - -static -struct htt_ppdu_stats_info *ath12k_dp_htt_get_ppdu_desc(struct ath12k *ar, - u32 ppdu_id) -{ - struct htt_ppdu_stats_info *ppdu_info; - - lockdep_assert_held(&ar->data_lock); - if (!list_empty(&ar->ppdu_stats_info)) { - list_for_each_entry(ppdu_info, &ar->ppdu_stats_info, list) { - if (ppdu_info->ppdu_id == ppdu_id) - return ppdu_info; - } - - if (ar->ppdu_stat_list_depth > HTT_PPDU_DESC_MAX_DEPTH) { - ppdu_info = list_first_entry(&ar->ppdu_stats_info, - typeof(*ppdu_info), list); - list_del(&ppdu_info->list); - ar->ppdu_stat_list_depth--; - ath12k_htt_update_ppdu_stats(ar, &ppdu_info->ppdu_stats); - kfree(ppdu_info); - } - } - - ppdu_info = kzalloc(sizeof(*ppdu_info), GFP_ATOMIC); - if (!ppdu_info) - return NULL; - - list_add_tail(&ppdu_info->list, &ar->ppdu_stats_info); - ar->ppdu_stat_list_depth++; - - return ppdu_info; -} - -static void ath12k_copy_to_delay_stats(struct ath12k_peer *peer, - struct htt_ppdu_user_stats *usr_stats) -{ - peer->ppdu_stats_delayba.sw_peer_id = le16_to_cpu(usr_stats->rate.sw_peer_id); - peer->ppdu_stats_delayba.info0 = le32_to_cpu(usr_stats->rate.info0); - peer->ppdu_stats_delayba.ru_end = le16_to_cpu(usr_stats->rate.ru_end); - peer->ppdu_stats_delayba.ru_start = le16_to_cpu(usr_stats->rate.ru_start); - peer->ppdu_stats_delayba.info1 = le32_to_cpu(usr_stats->rate.info1); - peer->ppdu_stats_delayba.rate_flags = le32_to_cpu(usr_stats->rate.rate_flags); - peer->ppdu_stats_delayba.resp_rate_flags = - le32_to_cpu(usr_stats->rate.resp_rate_flags); - - peer->delayba_flag = true; -} - -static void ath12k_copy_to_bar(struct ath12k_peer *peer, - struct htt_ppdu_user_stats *usr_stats) -{ - usr_stats->rate.sw_peer_id = cpu_to_le16(peer->ppdu_stats_delayba.sw_peer_id); - usr_stats->rate.info0 = cpu_to_le32(peer->ppdu_stats_delayba.info0); - usr_stats->rate.ru_end = cpu_to_le16(peer->ppdu_stats_delayba.ru_end); - usr_stats->rate.ru_start = cpu_to_le16(peer->ppdu_stats_delayba.ru_start); - usr_stats->rate.info1 = cpu_to_le32(peer->ppdu_stats_delayba.info1); - usr_stats->rate.rate_flags = cpu_to_le32(peer->ppdu_stats_delayba.rate_flags); - usr_stats->rate.resp_rate_flags = - cpu_to_le32(peer->ppdu_stats_delayba.resp_rate_flags); - - peer->delayba_flag = false; -} - -static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, - struct sk_buff *skb) -{ - struct ath12k_htt_ppdu_stats_msg *msg; - struct htt_ppdu_stats_info *ppdu_info; - struct ath12k_peer *peer = NULL; - struct htt_ppdu_user_stats *usr_stats = NULL; - u32 peer_id = 0; - struct ath12k *ar; - int ret, i; - u8 pdev_id; - u32 ppdu_id, len; - - msg = (struct ath12k_htt_ppdu_stats_msg *)skb->data; - len = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PAYLOAD_SIZE); - if (len > (skb->len - struct_size(msg, data, 0))) { - ath12k_warn(ab, - "HTT PPDU STATS event has unexpected payload size %u, should be smaller than %u\n", - len, skb->len); - return -EINVAL; - } - - pdev_id = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PDEV_ID); - ppdu_id = le32_to_cpu(msg->ppdu_id); - - rcu_read_lock(); - ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id); - if (!ar) { - ret = -EINVAL; - goto exit; - } - - spin_lock_bh(&ar->data_lock); - ppdu_info = ath12k_dp_htt_get_ppdu_desc(ar, ppdu_id); - if (!ppdu_info) { - spin_unlock_bh(&ar->data_lock); - ret = -EINVAL; - goto exit; - } - - ppdu_info->ppdu_id = ppdu_id; - ret = ath12k_dp_htt_tlv_iter(ab, msg->data, len, - ath12k_htt_tlv_ppdu_stats_parse, - (void *)ppdu_info); - if (ret) { - spin_unlock_bh(&ar->data_lock); - ath12k_warn(ab, "Failed to parse tlv %d\n", ret); - goto exit; - } - - if (ppdu_info->ppdu_stats.common.num_users >= HTT_PPDU_STATS_MAX_USERS) { - spin_unlock_bh(&ar->data_lock); - ath12k_warn(ab, - "HTT PPDU STATS event has unexpected num_users %u, should be smaller than %u\n", - ppdu_info->ppdu_stats.common.num_users, - HTT_PPDU_STATS_MAX_USERS); - ret = -EINVAL; - goto exit; - } - - /* back up data rate tlv for all peers */ - if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_DATA && - (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON)) && - ppdu_info->delay_ba) { - for (i = 0; i < ppdu_info->ppdu_stats.common.num_users; i++) { - peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; - spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); - if (!peer) { - spin_unlock_bh(&ab->base_lock); - continue; - } - - usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; - if (usr_stats->delay_ba) - ath12k_copy_to_delay_stats(peer, usr_stats); - spin_unlock_bh(&ab->base_lock); - } - } - - /* restore all peers' data rate tlv to mu-bar tlv */ - if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_BAR && - (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON))) { - for (i = 0; i < ppdu_info->bar_num_users; i++) { - peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; - spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); - if (!peer) { - spin_unlock_bh(&ab->base_lock); - continue; - } - - usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; - if (peer->delayba_flag) - ath12k_copy_to_bar(peer, usr_stats); - spin_unlock_bh(&ab->base_lock); - } - } - - spin_unlock_bh(&ar->data_lock); - -exit: - rcu_read_unlock(); - - return ret; -} - -static void ath12k_htt_mlo_offset_event_handler(struct ath12k_base *ab, - struct sk_buff *skb) -{ - struct ath12k_htt_mlo_offset_msg *msg; - struct ath12k_pdev *pdev; - struct ath12k *ar; - u8 pdev_id; - - msg = (struct ath12k_htt_mlo_offset_msg *)skb->data; - pdev_id = u32_get_bits(__le32_to_cpu(msg->info), - HTT_T2H_MLO_OFFSET_INFO_PDEV_ID); - - rcu_read_lock(); - ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id); - if (!ar) { - /* It is possible that the ar is not yet active (started). - * The above function will only look for the active pdev - * and hence %NULL return is possible. Just silently - * discard this message - */ - goto exit; - } - - spin_lock_bh(&ar->data_lock); - pdev = ar->pdev; - - pdev->timestamp.info = __le32_to_cpu(msg->info); - pdev->timestamp.sync_timestamp_lo_us = __le32_to_cpu(msg->sync_timestamp_lo_us); - pdev->timestamp.sync_timestamp_hi_us = __le32_to_cpu(msg->sync_timestamp_hi_us); - pdev->timestamp.mlo_offset_lo = __le32_to_cpu(msg->mlo_offset_lo); - pdev->timestamp.mlo_offset_hi = __le32_to_cpu(msg->mlo_offset_hi); - pdev->timestamp.mlo_offset_clks = __le32_to_cpu(msg->mlo_offset_clks); - pdev->timestamp.mlo_comp_clks = __le32_to_cpu(msg->mlo_comp_clks); - pdev->timestamp.mlo_comp_timer = __le32_to_cpu(msg->mlo_comp_timer); - - spin_unlock_bh(&ar->data_lock); -exit: - rcu_read_unlock(); -} - -void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, - struct sk_buff *skb) -{ - struct ath12k_dp *dp = &ab->dp; - struct htt_resp_msg *resp = (struct htt_resp_msg *)skb->data; - enum htt_t2h_msg_type type; - u16 peer_id; - u8 vdev_id; - u8 mac_addr[ETH_ALEN]; - u16 peer_mac_h16; - u16 ast_hash = 0; - u16 hw_peer_id; - - type = le32_get_bits(resp->version_msg.version, HTT_T2H_MSG_TYPE); - - ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt rx msg type :0x%0x\n", type); - - switch (type) { - case HTT_T2H_MSG_TYPE_VERSION_CONF: - dp->htt_tgt_ver_major = le32_get_bits(resp->version_msg.version, - HTT_T2H_VERSION_CONF_MAJOR); - dp->htt_tgt_ver_minor = le32_get_bits(resp->version_msg.version, - HTT_T2H_VERSION_CONF_MINOR); - complete(&dp->htt_tgt_version_received); - break; - /* TODO: remove unused peer map versions after testing */ - case HTT_T2H_MSG_TYPE_PEER_MAP: - vdev_id = le32_get_bits(resp->peer_map_ev.info, - HTT_T2H_PEER_MAP_INFO_VDEV_ID); - peer_id = le32_get_bits(resp->peer_map_ev.info, - HTT_T2H_PEER_MAP_INFO_PEER_ID); - peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1, - HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16); - ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32), - peer_mac_h16, mac_addr); - ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, 0, 0); - break; - case HTT_T2H_MSG_TYPE_PEER_MAP2: - vdev_id = le32_get_bits(resp->peer_map_ev.info, - HTT_T2H_PEER_MAP_INFO_VDEV_ID); - peer_id = le32_get_bits(resp->peer_map_ev.info, - HTT_T2H_PEER_MAP_INFO_PEER_ID); - peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1, - HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16); - ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32), - peer_mac_h16, mac_addr); - ast_hash = le32_get_bits(resp->peer_map_ev.info2, - HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL); - hw_peer_id = le32_get_bits(resp->peer_map_ev.info1, - HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID); - ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash, - hw_peer_id); - break; - case HTT_T2H_MSG_TYPE_PEER_MAP3: - vdev_id = le32_get_bits(resp->peer_map_ev.info, - HTT_T2H_PEER_MAP_INFO_VDEV_ID); - peer_id = le32_get_bits(resp->peer_map_ev.info, - HTT_T2H_PEER_MAP_INFO_PEER_ID); - peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1, - HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16); - ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32), - peer_mac_h16, mac_addr); - ast_hash = le32_get_bits(resp->peer_map_ev.info2, - HTT_T2H_PEER_MAP3_INFO2_AST_HASH_VAL); - hw_peer_id = le32_get_bits(resp->peer_map_ev.info2, - HTT_T2H_PEER_MAP3_INFO2_HW_PEER_ID); - ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash, - hw_peer_id); - break; - case HTT_T2H_MSG_TYPE_PEER_UNMAP: - case HTT_T2H_MSG_TYPE_PEER_UNMAP2: - peer_id = le32_get_bits(resp->peer_unmap_ev.info, - HTT_T2H_PEER_UNMAP_INFO_PEER_ID); - ath12k_peer_unmap_event(ab, peer_id); - break; - case HTT_T2H_MSG_TYPE_PPDU_STATS_IND: - ath12k_htt_pull_ppdu_stats(ab, skb); - break; - case HTT_T2H_MSG_TYPE_EXT_STATS_CONF: - ath12k_debugfs_htt_ext_stats_handler(ab, skb); - break; - case HTT_T2H_MSG_TYPE_MLO_TIMESTAMP_OFFSET_IND: - ath12k_htt_mlo_offset_event_handler(ab, skb); - break; - default: - ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt event %d not handled\n", - type); - break; - } - - dev_kfree_skb_any(skb); -} -EXPORT_SYMBOL(ath12k_dp_htt_htc_t2h_msg_handler); - struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, struct sk_buff *first) { diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index fc1c4ac161c1a..a6b6fea4c5e2e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -398,8 +398,6 @@ void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar, int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id, u8 tid, u32 ba_win_sz, u16 ssn, enum hal_pn_type pn_type); -void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, - struct sk_buff *skb); int ath12k_dp_rx_pdev_reo_setup(struct ath12k_base *ab); void ath12k_dp_rx_pdev_reo_cleanup(struct ath12k_base *ab); int ath12k_dp_rx_htt_setup(struct ath12k_base *ab); @@ -424,10 +422,6 @@ u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, struct hal_rx_desc *desc); u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, struct hal_rx_desc *desc); -int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len, - int (*iter)(struct ath12k_base *ar, u16 tag, u16 len, - const void *ptr, void *data), - void *data); void ath12k_dp_rx_h_fetch_info(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, struct ath12k_dp_rx_info *rx_info); From 3848c4a9c9c5c42b2e0f9e04ec8590d70056502d Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Thu, 28 Aug 2025 23:05:52 +0530 Subject: [PATCH 032/140] wifi: ath12k: Move HTT Tx specific code to newly introduced files WLAN Host driver interacts with the Firmware and vice versa using Host-To-Target (HTT) interface. Relocate HTT specific code from dp_tx.c to dp_htt.c introduced for HTT interface. These code is compiled as part of the common module ath12k.ko. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-20-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.h | 2 - drivers/net/wireless/ath/ath12k/dp_htt.c | 683 +++++++++++++++++++++++ drivers/net/wireless/ath/ath12k/dp_htt.h | 24 +- drivers/net/wireless/ath/ath12k/dp_tx.c | 682 ---------------------- drivers/net/wireless/ath/ath12k/dp_tx.h | 18 - 5 files changed, 705 insertions(+), 704 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 9c860cc8d7d98..852b35ff1ecd4 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -445,8 +445,6 @@ void ath12k_dp_partner_cc_init(struct ath12k_base *ab); int ath12k_dp_pdev_alloc(struct ath12k_base *ab); void ath12k_dp_pdev_pre_alloc(struct ath12k *ar); void ath12k_dp_pdev_free(struct ath12k_base *ab); -int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id, - int mac_id, enum hal_ring_type ring_type); int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr); void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr); void ath12k_dp_srng_cleanup(struct ath12k_base *ab, struct dp_srng *ring); diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index 00847d579b958..45aa8ae86a14c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -9,6 +9,7 @@ #include "htc.h" #include "dp_htt.h" #include "debugfs_htt_stats.h" +#include "debugfs.h" static int ath12k_get_ppdu_user_index(struct htt_ppdu_stats *ppdu_stats, u16 peer_id) @@ -642,3 +643,685 @@ void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, dev_kfree_skb_any(skb); } EXPORT_SYMBOL(ath12k_dp_htt_htc_t2h_msg_handler); + +static int +ath12k_dp_tx_get_ring_id_type(struct ath12k_base *ab, + int mac_id, u32 ring_id, + enum hal_ring_type ring_type, + enum htt_srng_ring_type *htt_ring_type, + enum htt_srng_ring_id *htt_ring_id) +{ + int ret = 0; + + switch (ring_type) { + case HAL_RXDMA_BUF: + /* for some targets, host fills rx buffer to fw and fw fills to + * rxbuf ring for each rxdma + */ + if (!ab->hw_params->rx_mac_buf_ring) { + if (!(ring_id == HAL_SRNG_SW2RXDMA_BUF0 || + ring_id == HAL_SRNG_SW2RXDMA_BUF1)) { + ret = -EINVAL; + } + *htt_ring_id = HTT_RXDMA_HOST_BUF_RING; + *htt_ring_type = HTT_SW_TO_HW_RING; + } else { + if (ring_id == HAL_SRNG_SW2RXDMA_BUF0) { + *htt_ring_id = HTT_HOST1_TO_FW_RXBUF_RING; + *htt_ring_type = HTT_SW_TO_SW_RING; + } else { + *htt_ring_id = HTT_RXDMA_HOST_BUF_RING; + *htt_ring_type = HTT_SW_TO_HW_RING; + } + } + break; + case HAL_RXDMA_DST: + *htt_ring_id = HTT_RXDMA_NON_MONITOR_DEST_RING; + *htt_ring_type = HTT_HW_TO_SW_RING; + break; + case HAL_RXDMA_MONITOR_BUF: + *htt_ring_id = HTT_RX_MON_HOST2MON_BUF_RING; + *htt_ring_type = HTT_SW_TO_HW_RING; + break; + case HAL_RXDMA_MONITOR_STATUS: + *htt_ring_id = HTT_RXDMA_MONITOR_STATUS_RING; + *htt_ring_type = HTT_SW_TO_HW_RING; + break; + case HAL_RXDMA_MONITOR_DST: + *htt_ring_id = HTT_RX_MON_MON2HOST_DEST_RING; + *htt_ring_type = HTT_HW_TO_SW_RING; + break; + case HAL_RXDMA_MONITOR_DESC: + *htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING; + *htt_ring_type = HTT_SW_TO_HW_RING; + break; + default: + ath12k_warn(ab, "Unsupported ring type in DP :%d\n", ring_type); + ret = -EINVAL; + } + return ret; +} + +int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id, + int mac_id, enum hal_ring_type ring_type) +{ + struct htt_srng_setup_cmd *cmd; + struct hal_srng *srng = &ab->hal.srng_list[ring_id]; + struct hal_srng_params params; + struct sk_buff *skb; + u32 ring_entry_sz; + int len = sizeof(*cmd); + dma_addr_t hp_addr, tp_addr; + enum htt_srng_ring_type htt_ring_type; + enum htt_srng_ring_id htt_ring_id; + int ret; + + skb = ath12k_htc_alloc_skb(ab, len); + if (!skb) + return -ENOMEM; + + memset(¶ms, 0, sizeof(params)); + ath12k_hal_srng_get_params(ab, srng, ¶ms); + + hp_addr = ath12k_hal_srng_get_hp_addr(ab, srng); + tp_addr = ath12k_hal_srng_get_tp_addr(ab, srng); + + ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id, + ring_type, &htt_ring_type, + &htt_ring_id); + if (ret) + goto err_free; + + skb_put(skb, len); + cmd = (struct htt_srng_setup_cmd *)skb->data; + cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_SRING_SETUP, + HTT_SRNG_SETUP_CMD_INFO0_MSG_TYPE); + if (htt_ring_type == HTT_SW_TO_HW_RING || + htt_ring_type == HTT_HW_TO_SW_RING) + cmd->info0 |= le32_encode_bits(DP_SW2HW_MACID(mac_id), + HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID); + else + cmd->info0 |= le32_encode_bits(mac_id, + HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID); + cmd->info0 |= le32_encode_bits(htt_ring_type, + HTT_SRNG_SETUP_CMD_INFO0_RING_TYPE); + cmd->info0 |= le32_encode_bits(htt_ring_id, + HTT_SRNG_SETUP_CMD_INFO0_RING_ID); + + cmd->ring_base_addr_lo = cpu_to_le32(params.ring_base_paddr & + HAL_ADDR_LSB_REG_MASK); + + cmd->ring_base_addr_hi = cpu_to_le32((u64)params.ring_base_paddr >> + HAL_ADDR_MSB_REG_SHIFT); + + ret = ath12k_hal_srng_get_entrysize(ab, ring_type); + if (ret < 0) + goto err_free; + + ring_entry_sz = ret; + + ring_entry_sz >>= 2; + cmd->info1 = le32_encode_bits(ring_entry_sz, + HTT_SRNG_SETUP_CMD_INFO1_RING_ENTRY_SIZE); + cmd->info1 |= le32_encode_bits(params.num_entries * ring_entry_sz, + HTT_SRNG_SETUP_CMD_INFO1_RING_SIZE); + cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP), + HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_MSI_SWAP); + cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP), + HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_TLV_SWAP); + cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_RING_PTR_SWAP), + HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_HOST_FW_SWAP); + if (htt_ring_type == HTT_SW_TO_HW_RING) + cmd->info1 |= cpu_to_le32(HTT_SRNG_SETUP_CMD_INFO1_RING_LOOP_CNT_DIS); + + cmd->ring_head_off32_remote_addr_lo = cpu_to_le32(lower_32_bits(hp_addr)); + cmd->ring_head_off32_remote_addr_hi = cpu_to_le32(upper_32_bits(hp_addr)); + + cmd->ring_tail_off32_remote_addr_lo = cpu_to_le32(lower_32_bits(tp_addr)); + cmd->ring_tail_off32_remote_addr_hi = cpu_to_le32(upper_32_bits(tp_addr)); + + cmd->ring_msi_addr_lo = cpu_to_le32(lower_32_bits(params.msi_addr)); + cmd->ring_msi_addr_hi = cpu_to_le32(upper_32_bits(params.msi_addr)); + cmd->msi_data = cpu_to_le32(params.msi_data); + + cmd->intr_info = + le32_encode_bits(params.intr_batch_cntr_thres_entries * ring_entry_sz, + HTT_SRNG_SETUP_CMD_INTR_INFO_BATCH_COUNTER_THRESH); + cmd->intr_info |= + le32_encode_bits(params.intr_timer_thres_us >> 3, + HTT_SRNG_SETUP_CMD_INTR_INFO_INTR_TIMER_THRESH); + + cmd->info2 = 0; + if (params.flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) { + cmd->info2 = le32_encode_bits(params.low_threshold, + HTT_SRNG_SETUP_CMD_INFO2_INTR_LOW_THRESH); + } + + ath12k_dbg(ab, ATH12K_DBG_HAL, + "%s msi_addr_lo:0x%x, msi_addr_hi:0x%x, msi_data:0x%x\n", + __func__, cmd->ring_msi_addr_lo, cmd->ring_msi_addr_hi, + cmd->msi_data); + + ath12k_dbg(ab, ATH12K_DBG_HAL, + "ring_id:%d, ring_type:%d, intr_info:0x%x, flags:0x%x\n", + ring_id, ring_type, cmd->intr_info, cmd->info2); + + ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); + if (ret) + goto err_free; + + return 0; + +err_free: + dev_kfree_skb_any(skb); + + return ret; +} + +#define HTT_TARGET_VERSION_TIMEOUT_HZ (3 * HZ) + +int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab) +{ + struct ath12k_dp *dp = &ab->dp; + struct sk_buff *skb; + struct htt_ver_req_cmd *cmd; + int len = sizeof(*cmd); + u32 metadata_version; + int ret; + + init_completion(&dp->htt_tgt_version_received); + + skb = ath12k_htc_alloc_skb(ab, len); + if (!skb) + return -ENOMEM; + + skb_put(skb, len); + cmd = (struct htt_ver_req_cmd *)skb->data; + cmd->ver_reg_info = le32_encode_bits(HTT_H2T_MSG_TYPE_VERSION_REQ, + HTT_OPTION_TAG); + metadata_version = ath12k_ftm_mode ? HTT_OPTION_TCL_METADATA_VER_V1 : + HTT_OPTION_TCL_METADATA_VER_V2; + + cmd->tcl_metadata_version = le32_encode_bits(HTT_TAG_TCL_METADATA_VERSION, + HTT_OPTION_TAG) | + le32_encode_bits(HTT_TCL_METADATA_VER_SZ, + HTT_OPTION_LEN) | + le32_encode_bits(metadata_version, + HTT_OPTION_VALUE); + + ret = ath12k_htc_send(&ab->htc, dp->eid, skb); + if (ret) { + dev_kfree_skb_any(skb); + return ret; + } + + ret = wait_for_completion_timeout(&dp->htt_tgt_version_received, + HTT_TARGET_VERSION_TIMEOUT_HZ); + if (ret == 0) { + ath12k_warn(ab, "htt target version request timed out\n"); + return -ETIMEDOUT; + } + + if (dp->htt_tgt_ver_major != HTT_TARGET_VERSION_MAJOR) { + ath12k_err(ab, "unsupported htt major version %d supported version is %d\n", + dp->htt_tgt_ver_major, HTT_TARGET_VERSION_MAJOR); + return -EOPNOTSUPP; + } + + return 0; +} + +int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = &ab->dp; + struct sk_buff *skb; + struct htt_ppdu_stats_cfg_cmd *cmd; + int len = sizeof(*cmd); + u8 pdev_mask; + int ret; + int i; + + for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { + skb = ath12k_htc_alloc_skb(ab, len); + if (!skb) + return -ENOMEM; + + skb_put(skb, len); + cmd = (struct htt_ppdu_stats_cfg_cmd *)skb->data; + cmd->msg = le32_encode_bits(HTT_H2T_MSG_TYPE_PPDU_STATS_CFG, + HTT_PPDU_STATS_CFG_MSG_TYPE); + + pdev_mask = 1 << (i + ar->pdev_idx); + cmd->msg |= le32_encode_bits(pdev_mask, HTT_PPDU_STATS_CFG_PDEV_ID); + cmd->msg |= le32_encode_bits(mask, HTT_PPDU_STATS_CFG_TLV_TYPE_BITMASK); + + ret = ath12k_htc_send(&ab->htc, dp->eid, skb); + if (ret) { + dev_kfree_skb_any(skb); + return ret; + } + } + + return 0; +} + +int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id, + int mac_id, enum hal_ring_type ring_type, + int rx_buf_size, + struct htt_rx_ring_tlv_filter *tlv_filter) +{ + struct htt_rx_ring_selection_cfg_cmd *cmd; + struct hal_srng *srng = &ab->hal.srng_list[ring_id]; + struct hal_srng_params params; + struct sk_buff *skb; + int len = sizeof(*cmd); + enum htt_srng_ring_type htt_ring_type; + enum htt_srng_ring_id htt_ring_id; + int ret; + + skb = ath12k_htc_alloc_skb(ab, len); + if (!skb) + return -ENOMEM; + + memset(¶ms, 0, sizeof(params)); + ath12k_hal_srng_get_params(ab, srng, ¶ms); + + ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id, + ring_type, &htt_ring_type, + &htt_ring_id); + if (ret) + goto err_free; + + skb_put(skb, len); + cmd = (struct htt_rx_ring_selection_cfg_cmd *)skb->data; + cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG, + HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE); + if (htt_ring_type == HTT_SW_TO_HW_RING || + htt_ring_type == HTT_HW_TO_SW_RING) + cmd->info0 |= + le32_encode_bits(DP_SW2HW_MACID(mac_id), + HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID); + else + cmd->info0 |= + le32_encode_bits(mac_id, + HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID); + cmd->info0 |= le32_encode_bits(htt_ring_id, + HTT_RX_RING_SELECTION_CFG_CMD_INFO0_RING_ID); + cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP), + HTT_RX_RING_SELECTION_CFG_CMD_INFO0_SS); + cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP), + HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS); + cmd->info0 |= le32_encode_bits(tlv_filter->offset_valid, + HTT_RX_RING_SELECTION_CFG_CMD_INFO0_OFFSET_VALID); + cmd->info0 |= + le32_encode_bits(tlv_filter->drop_threshold_valid, + HTT_RX_RING_SELECTION_CFG_CMD_INFO0_DROP_THRES_VAL); + cmd->info0 |= le32_encode_bits(!tlv_filter->rxmon_disable, + HTT_RX_RING_SELECTION_CFG_CMD_INFO0_EN_RXMON); + + cmd->info1 = le32_encode_bits(rx_buf_size, + HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE); + cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_mgmt, + HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT); + cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_ctrl, + HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL); + cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_data, + HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA); + cmd->pkt_type_en_flags0 = cpu_to_le32(tlv_filter->pkt_filter_flags0); + cmd->pkt_type_en_flags1 = cpu_to_le32(tlv_filter->pkt_filter_flags1); + cmd->pkt_type_en_flags2 = cpu_to_le32(tlv_filter->pkt_filter_flags2); + cmd->pkt_type_en_flags3 = cpu_to_le32(tlv_filter->pkt_filter_flags3); + cmd->rx_filter_tlv = cpu_to_le32(tlv_filter->rx_filter); + + cmd->info2 = le32_encode_bits(tlv_filter->rx_drop_threshold, + HTT_RX_RING_SELECTION_CFG_CMD_INFO2_DROP_THRESHOLD); + cmd->info2 |= + le32_encode_bits(tlv_filter->enable_log_mgmt_type, + HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_MGMT_TYPE); + cmd->info2 |= + le32_encode_bits(tlv_filter->enable_log_ctrl_type, + HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_CTRL_TYPE); + cmd->info2 |= + le32_encode_bits(tlv_filter->enable_log_data_type, + HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_DATA_TYPE); + + cmd->info3 = + le32_encode_bits(tlv_filter->enable_rx_tlv_offset, + HTT_RX_RING_SELECTION_CFG_CMD_INFO3_EN_TLV_PKT_OFFSET); + cmd->info3 |= + le32_encode_bits(tlv_filter->rx_tlv_offset, + HTT_RX_RING_SELECTION_CFG_CMD_INFO3_PKT_TLV_OFFSET); + + if (tlv_filter->offset_valid) { + cmd->rx_packet_offset = + le32_encode_bits(tlv_filter->rx_packet_offset, + HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET); + + cmd->rx_packet_offset |= + le32_encode_bits(tlv_filter->rx_header_offset, + HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET); + + cmd->rx_mpdu_offset = + le32_encode_bits(tlv_filter->rx_mpdu_end_offset, + HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET); + + cmd->rx_mpdu_offset |= + le32_encode_bits(tlv_filter->rx_mpdu_start_offset, + HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET); + + cmd->rx_msdu_offset = + le32_encode_bits(tlv_filter->rx_msdu_end_offset, + HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET); + + cmd->rx_msdu_offset |= + le32_encode_bits(tlv_filter->rx_msdu_start_offset, + HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET); + + cmd->rx_attn_offset = + le32_encode_bits(tlv_filter->rx_attn_offset, + HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET); + } + + if (tlv_filter->rx_mpdu_start_wmask > 0 && + tlv_filter->rx_msdu_end_wmask > 0) { + cmd->info2 |= + le32_encode_bits(true, + HTT_RX_RING_SELECTION_CFG_WORD_MASK_COMPACT_SET); + cmd->rx_mpdu_start_end_mask = + le32_encode_bits(tlv_filter->rx_mpdu_start_wmask, + HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_MASK); + /* mpdu_end is not used for any hardwares so far + * please assign it in future if any chip is + * using through hal ops + */ + cmd->rx_mpdu_start_end_mask |= + le32_encode_bits(tlv_filter->rx_mpdu_end_wmask, + HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_MASK); + cmd->rx_msdu_end_word_mask = + le32_encode_bits(tlv_filter->rx_msdu_end_wmask, + HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_MASK); + } + + ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); + if (ret) + goto err_free; + + return 0; + +err_free: + dev_kfree_skb_any(skb); + + return ret; +} + +int +ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type, + struct htt_ext_stats_cfg_params *cfg_params, + u64 cookie) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = &ab->dp; + struct sk_buff *skb; + struct htt_ext_stats_cfg_cmd *cmd; + int len = sizeof(*cmd); + int ret; + u32 pdev_id; + + skb = ath12k_htc_alloc_skb(ab, len); + if (!skb) + return -ENOMEM; + + skb_put(skb, len); + + cmd = (struct htt_ext_stats_cfg_cmd *)skb->data; + memset(cmd, 0, sizeof(*cmd)); + cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_EXT_STATS_CFG; + + pdev_id = ath12k_mac_get_target_pdev_id(ar); + cmd->hdr.pdev_mask = 1 << pdev_id; + + cmd->hdr.stats_type = type; + cmd->cfg_param0 = cpu_to_le32(cfg_params->cfg0); + cmd->cfg_param1 = cpu_to_le32(cfg_params->cfg1); + cmd->cfg_param2 = cpu_to_le32(cfg_params->cfg2); + cmd->cfg_param3 = cpu_to_le32(cfg_params->cfg3); + cmd->cookie_lsb = cpu_to_le32(lower_32_bits(cookie)); + cmd->cookie_msb = cpu_to_le32(upper_32_bits(cookie)); + + ret = ath12k_htc_send(&ab->htc, dp->eid, skb); + if (ret) { + ath12k_warn(ab, "failed to send htt type stats request: %d", + ret); + dev_kfree_skb_any(skb); + return ret; + } + + return 0; +} + +int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset) +{ + struct ath12k_base *ab = ar->ab; + int ret; + + ret = ath12k_dp_tx_htt_rx_monitor_mode_ring_config(ar, reset); + if (ret) { + ath12k_err(ab, "failed to setup rx monitor filter %d\n", ret); + return ret; + } + + return 0; +} + +int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset) +{ + struct ath12k_base *ab = ar->ab; + struct htt_rx_ring_tlv_filter tlv_filter = {}; + int ret, ring_id, i; + + tlv_filter.offset_valid = false; + + if (!reset) { + tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_DEST_RING; + + tlv_filter.drop_threshold_valid = true; + tlv_filter.rx_drop_threshold = HTT_RX_RING_TLV_DROP_THRESHOLD_VALUE; + + tlv_filter.enable_log_mgmt_type = true; + tlv_filter.enable_log_ctrl_type = true; + tlv_filter.enable_log_data_type = true; + + tlv_filter.conf_len_ctrl = HTT_RX_RING_DEFAULT_DMA_LENGTH; + tlv_filter.conf_len_mgmt = HTT_RX_RING_DEFAULT_DMA_LENGTH; + tlv_filter.conf_len_data = HTT_RX_RING_DEFAULT_DMA_LENGTH; + + tlv_filter.enable_rx_tlv_offset = true; + tlv_filter.rx_tlv_offset = HTT_RX_RING_PKT_TLV_OFFSET; + + tlv_filter.pkt_filter_flags0 = + HTT_RX_MON_FP_MGMT_FILTER_FLAGS0 | + HTT_RX_MON_MO_MGMT_FILTER_FLAGS0; + tlv_filter.pkt_filter_flags1 = + HTT_RX_MON_FP_MGMT_FILTER_FLAGS1 | + HTT_RX_MON_MO_MGMT_FILTER_FLAGS1; + tlv_filter.pkt_filter_flags2 = + HTT_RX_MON_FP_CTRL_FILTER_FLASG2 | + HTT_RX_MON_MO_CTRL_FILTER_FLASG2; + tlv_filter.pkt_filter_flags3 = + HTT_RX_MON_FP_CTRL_FILTER_FLASG3 | + HTT_RX_MON_MO_CTRL_FILTER_FLASG3 | + HTT_RX_MON_FP_DATA_FILTER_FLASG3 | + HTT_RX_MON_MO_DATA_FILTER_FLASG3; + } else { + tlv_filter = ath12k_mac_mon_status_filter_default; + + if (ath12k_debugfs_is_extd_rx_stats_enabled(ar)) + tlv_filter.rx_filter = ath12k_debugfs_rx_filter(ar); + } + + if (ab->hw_params->rxdma1_enable) { + for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { + ring_id = ar->dp.rxdma_mon_dst_ring[i].ring_id; + ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, + ar->dp.mac_id + i, + HAL_RXDMA_MONITOR_DST, + DP_RXDMA_REFILL_RING_SIZE, + &tlv_filter); + if (ret) { + ath12k_err(ab, + "failed to setup filter for monitor buf %d\n", + ret); + return ret; + } + } + return 0; + } + + if (!reset) { + for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { + ring_id = ab->dp.rx_mac_buf_ring[i].ring_id; + ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, + i, + HAL_RXDMA_BUF, + DP_RXDMA_REFILL_RING_SIZE, + &tlv_filter); + if (ret) { + ath12k_err(ab, + "failed to setup filter for mon rx buf %d\n", + ret); + return ret; + } + } + } + + for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { + ring_id = ab->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; + if (!reset) { + tlv_filter.rx_filter = + HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING; + } + + ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, + i, + HAL_RXDMA_MONITOR_STATUS, + RX_MON_STATUS_BUF_SIZE, + &tlv_filter); + if (ret) { + ath12k_err(ab, + "failed to setup filter for mon status buf %d\n", + ret); + return ret; + } + } + + return 0; +} + +int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id, + int mac_id, enum hal_ring_type ring_type, + int tx_buf_size, + struct htt_tx_ring_tlv_filter *htt_tlv_filter) +{ + struct htt_tx_ring_selection_cfg_cmd *cmd; + struct hal_srng *srng = &ab->hal.srng_list[ring_id]; + struct hal_srng_params params; + struct sk_buff *skb; + int len = sizeof(*cmd); + enum htt_srng_ring_type htt_ring_type; + enum htt_srng_ring_id htt_ring_id; + int ret; + + skb = ath12k_htc_alloc_skb(ab, len); + if (!skb) + return -ENOMEM; + + memset(¶ms, 0, sizeof(params)); + ath12k_hal_srng_get_params(ab, srng, ¶ms); + + ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id, + ring_type, &htt_ring_type, + &htt_ring_id); + + if (ret) + goto err_free; + + skb_put(skb, len); + cmd = (struct htt_tx_ring_selection_cfg_cmd *)skb->data; + cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_TX_MONITOR_CFG, + HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE); + if (htt_ring_type == HTT_SW_TO_HW_RING || + htt_ring_type == HTT_HW_TO_SW_RING) + cmd->info0 |= + le32_encode_bits(DP_SW2HW_MACID(mac_id), + HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID); + else + cmd->info0 |= + le32_encode_bits(mac_id, + HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID); + cmd->info0 |= le32_encode_bits(htt_ring_id, + HTT_TX_RING_SELECTION_CFG_CMD_INFO0_RING_ID); + cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP), + HTT_TX_RING_SELECTION_CFG_CMD_INFO0_SS); + cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP), + HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PS); + + cmd->info1 |= + le32_encode_bits(tx_buf_size, + HTT_TX_RING_SELECTION_CFG_CMD_INFO1_RING_BUFF_SIZE); + + if (htt_tlv_filter->tx_mon_mgmt_filter) { + cmd->info1 |= + le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_MGMT, + HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE); + cmd->info1 |= + le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len, + HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT); + cmd->info2 |= + le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_MGMT, + HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG); + } + + if (htt_tlv_filter->tx_mon_data_filter) { + cmd->info1 |= + le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_CTRL, + HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE); + cmd->info1 |= + le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len, + HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL); + cmd->info2 |= + le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_CTRL, + HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG); + } + + if (htt_tlv_filter->tx_mon_ctrl_filter) { + cmd->info1 |= + le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_DATA, + HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE); + cmd->info1 |= + le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len, + HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA); + cmd->info2 |= + le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_DATA, + HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG); + } + + cmd->tlv_filter_mask_in0 = + cpu_to_le32(htt_tlv_filter->tx_mon_downstream_tlv_flags); + cmd->tlv_filter_mask_in1 = + cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags0); + cmd->tlv_filter_mask_in2 = + cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags1); + cmd->tlv_filter_mask_in3 = + cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags2); + + ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); + if (ret) + goto err_free; + + return 0; + +err_free: + dev_kfree_skb_any(skb); + return ret; +} diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.h b/drivers/net/wireless/ath/ath12k/dp_htt.h index 9ae3a750f6081..b13af1c69253d 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.h +++ b/drivers/net/wireless/ath/ath12k/dp_htt.h @@ -1514,10 +1514,30 @@ struct htt_mac_addr { __le32 mac_addr_h16; } __packed; +int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id, + int mac_id, enum hal_ring_type ring_type); + +void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, + struct sk_buff *skb); int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len, int (*iter)(struct ath12k_base *ar, u16 tag, u16 len, const void *ptr, void *data), void *data); -void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, - struct sk_buff *skb); +int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab); +int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask); +int +ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type, + struct htt_ext_stats_cfg_params *cfg_params, + u64 cookie); +int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset); + +int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id, + int mac_id, enum hal_ring_type ring_type, + int rx_buf_size, + struct htt_rx_ring_tlv_filter *tlv_filter); +int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id, + int mac_id, enum hal_ring_type ring_type, + int tx_buf_size, + struct htt_tx_ring_tlv_filter *htt_tlv_filter); +int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c index c7b0fc22c1a79..8d5e10781377e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/dp_tx.c @@ -200,685 +200,3 @@ void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, if (atomic_dec_and_test(&ar->dp.num_tx_pending)) wake_up(&ar->dp.tx_empty_waitq); } - -static int -ath12k_dp_tx_get_ring_id_type(struct ath12k_base *ab, - int mac_id, u32 ring_id, - enum hal_ring_type ring_type, - enum htt_srng_ring_type *htt_ring_type, - enum htt_srng_ring_id *htt_ring_id) -{ - int ret = 0; - - switch (ring_type) { - case HAL_RXDMA_BUF: - /* for some targets, host fills rx buffer to fw and fw fills to - * rxbuf ring for each rxdma - */ - if (!ab->hw_params->rx_mac_buf_ring) { - if (!(ring_id == HAL_SRNG_SW2RXDMA_BUF0 || - ring_id == HAL_SRNG_SW2RXDMA_BUF1)) { - ret = -EINVAL; - } - *htt_ring_id = HTT_RXDMA_HOST_BUF_RING; - *htt_ring_type = HTT_SW_TO_HW_RING; - } else { - if (ring_id == HAL_SRNG_SW2RXDMA_BUF0) { - *htt_ring_id = HTT_HOST1_TO_FW_RXBUF_RING; - *htt_ring_type = HTT_SW_TO_SW_RING; - } else { - *htt_ring_id = HTT_RXDMA_HOST_BUF_RING; - *htt_ring_type = HTT_SW_TO_HW_RING; - } - } - break; - case HAL_RXDMA_DST: - *htt_ring_id = HTT_RXDMA_NON_MONITOR_DEST_RING; - *htt_ring_type = HTT_HW_TO_SW_RING; - break; - case HAL_RXDMA_MONITOR_BUF: - *htt_ring_id = HTT_RX_MON_HOST2MON_BUF_RING; - *htt_ring_type = HTT_SW_TO_HW_RING; - break; - case HAL_RXDMA_MONITOR_STATUS: - *htt_ring_id = HTT_RXDMA_MONITOR_STATUS_RING; - *htt_ring_type = HTT_SW_TO_HW_RING; - break; - case HAL_RXDMA_MONITOR_DST: - *htt_ring_id = HTT_RX_MON_MON2HOST_DEST_RING; - *htt_ring_type = HTT_HW_TO_SW_RING; - break; - case HAL_RXDMA_MONITOR_DESC: - *htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING; - *htt_ring_type = HTT_SW_TO_HW_RING; - break; - default: - ath12k_warn(ab, "Unsupported ring type in DP :%d\n", ring_type); - ret = -EINVAL; - } - return ret; -} - -int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id, - int mac_id, enum hal_ring_type ring_type) -{ - struct htt_srng_setup_cmd *cmd; - struct hal_srng *srng = &ab->hal.srng_list[ring_id]; - struct hal_srng_params params; - struct sk_buff *skb; - u32 ring_entry_sz; - int len = sizeof(*cmd); - dma_addr_t hp_addr, tp_addr; - enum htt_srng_ring_type htt_ring_type; - enum htt_srng_ring_id htt_ring_id; - int ret; - - skb = ath12k_htc_alloc_skb(ab, len); - if (!skb) - return -ENOMEM; - - memset(¶ms, 0, sizeof(params)); - ath12k_hal_srng_get_params(ab, srng, ¶ms); - - hp_addr = ath12k_hal_srng_get_hp_addr(ab, srng); - tp_addr = ath12k_hal_srng_get_tp_addr(ab, srng); - - ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id, - ring_type, &htt_ring_type, - &htt_ring_id); - if (ret) - goto err_free; - - skb_put(skb, len); - cmd = (struct htt_srng_setup_cmd *)skb->data; - cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_SRING_SETUP, - HTT_SRNG_SETUP_CMD_INFO0_MSG_TYPE); - if (htt_ring_type == HTT_SW_TO_HW_RING || - htt_ring_type == HTT_HW_TO_SW_RING) - cmd->info0 |= le32_encode_bits(DP_SW2HW_MACID(mac_id), - HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID); - else - cmd->info0 |= le32_encode_bits(mac_id, - HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID); - cmd->info0 |= le32_encode_bits(htt_ring_type, - HTT_SRNG_SETUP_CMD_INFO0_RING_TYPE); - cmd->info0 |= le32_encode_bits(htt_ring_id, - HTT_SRNG_SETUP_CMD_INFO0_RING_ID); - - cmd->ring_base_addr_lo = cpu_to_le32(params.ring_base_paddr & - HAL_ADDR_LSB_REG_MASK); - - cmd->ring_base_addr_hi = cpu_to_le32((u64)params.ring_base_paddr >> - HAL_ADDR_MSB_REG_SHIFT); - - ret = ath12k_hal_srng_get_entrysize(ab, ring_type); - if (ret < 0) - goto err_free; - - ring_entry_sz = ret; - - ring_entry_sz >>= 2; - cmd->info1 = le32_encode_bits(ring_entry_sz, - HTT_SRNG_SETUP_CMD_INFO1_RING_ENTRY_SIZE); - cmd->info1 |= le32_encode_bits(params.num_entries * ring_entry_sz, - HTT_SRNG_SETUP_CMD_INFO1_RING_SIZE); - cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP), - HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_MSI_SWAP); - cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP), - HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_TLV_SWAP); - cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_RING_PTR_SWAP), - HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_HOST_FW_SWAP); - if (htt_ring_type == HTT_SW_TO_HW_RING) - cmd->info1 |= cpu_to_le32(HTT_SRNG_SETUP_CMD_INFO1_RING_LOOP_CNT_DIS); - - cmd->ring_head_off32_remote_addr_lo = cpu_to_le32(lower_32_bits(hp_addr)); - cmd->ring_head_off32_remote_addr_hi = cpu_to_le32(upper_32_bits(hp_addr)); - - cmd->ring_tail_off32_remote_addr_lo = cpu_to_le32(lower_32_bits(tp_addr)); - cmd->ring_tail_off32_remote_addr_hi = cpu_to_le32(upper_32_bits(tp_addr)); - - cmd->ring_msi_addr_lo = cpu_to_le32(lower_32_bits(params.msi_addr)); - cmd->ring_msi_addr_hi = cpu_to_le32(upper_32_bits(params.msi_addr)); - cmd->msi_data = cpu_to_le32(params.msi_data); - - cmd->intr_info = - le32_encode_bits(params.intr_batch_cntr_thres_entries * ring_entry_sz, - HTT_SRNG_SETUP_CMD_INTR_INFO_BATCH_COUNTER_THRESH); - cmd->intr_info |= - le32_encode_bits(params.intr_timer_thres_us >> 3, - HTT_SRNG_SETUP_CMD_INTR_INFO_INTR_TIMER_THRESH); - - cmd->info2 = 0; - if (params.flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) { - cmd->info2 = le32_encode_bits(params.low_threshold, - HTT_SRNG_SETUP_CMD_INFO2_INTR_LOW_THRESH); - } - - ath12k_dbg(ab, ATH12K_DBG_HAL, - "%s msi_addr_lo:0x%x, msi_addr_hi:0x%x, msi_data:0x%x\n", - __func__, cmd->ring_msi_addr_lo, cmd->ring_msi_addr_hi, - cmd->msi_data); - - ath12k_dbg(ab, ATH12K_DBG_HAL, - "ring_id:%d, ring_type:%d, intr_info:0x%x, flags:0x%x\n", - ring_id, ring_type, cmd->intr_info, cmd->info2); - - ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); - if (ret) - goto err_free; - - return 0; - -err_free: - dev_kfree_skb_any(skb); - - return ret; -} - -#define HTT_TARGET_VERSION_TIMEOUT_HZ (3 * HZ) - -int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab) -{ - struct ath12k_dp *dp = &ab->dp; - struct sk_buff *skb; - struct htt_ver_req_cmd *cmd; - int len = sizeof(*cmd); - u32 metadata_version; - int ret; - - init_completion(&dp->htt_tgt_version_received); - - skb = ath12k_htc_alloc_skb(ab, len); - if (!skb) - return -ENOMEM; - - skb_put(skb, len); - cmd = (struct htt_ver_req_cmd *)skb->data; - cmd->ver_reg_info = le32_encode_bits(HTT_H2T_MSG_TYPE_VERSION_REQ, - HTT_OPTION_TAG); - metadata_version = ath12k_ftm_mode ? HTT_OPTION_TCL_METADATA_VER_V1 : - HTT_OPTION_TCL_METADATA_VER_V2; - - cmd->tcl_metadata_version = le32_encode_bits(HTT_TAG_TCL_METADATA_VERSION, - HTT_OPTION_TAG) | - le32_encode_bits(HTT_TCL_METADATA_VER_SZ, - HTT_OPTION_LEN) | - le32_encode_bits(metadata_version, - HTT_OPTION_VALUE); - - ret = ath12k_htc_send(&ab->htc, dp->eid, skb); - if (ret) { - dev_kfree_skb_any(skb); - return ret; - } - - ret = wait_for_completion_timeout(&dp->htt_tgt_version_received, - HTT_TARGET_VERSION_TIMEOUT_HZ); - if (ret == 0) { - ath12k_warn(ab, "htt target version request timed out\n"); - return -ETIMEDOUT; - } - - if (dp->htt_tgt_ver_major != HTT_TARGET_VERSION_MAJOR) { - ath12k_err(ab, "unsupported htt major version %d supported version is %d\n", - dp->htt_tgt_ver_major, HTT_TARGET_VERSION_MAJOR); - return -EOPNOTSUPP; - } - - return 0; -} - -int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask) -{ - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; - struct sk_buff *skb; - struct htt_ppdu_stats_cfg_cmd *cmd; - int len = sizeof(*cmd); - u8 pdev_mask; - int ret; - int i; - - for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { - skb = ath12k_htc_alloc_skb(ab, len); - if (!skb) - return -ENOMEM; - - skb_put(skb, len); - cmd = (struct htt_ppdu_stats_cfg_cmd *)skb->data; - cmd->msg = le32_encode_bits(HTT_H2T_MSG_TYPE_PPDU_STATS_CFG, - HTT_PPDU_STATS_CFG_MSG_TYPE); - - pdev_mask = 1 << (i + ar->pdev_idx); - cmd->msg |= le32_encode_bits(pdev_mask, HTT_PPDU_STATS_CFG_PDEV_ID); - cmd->msg |= le32_encode_bits(mask, HTT_PPDU_STATS_CFG_TLV_TYPE_BITMASK); - - ret = ath12k_htc_send(&ab->htc, dp->eid, skb); - if (ret) { - dev_kfree_skb_any(skb); - return ret; - } - } - - return 0; -} - -int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id, - int mac_id, enum hal_ring_type ring_type, - int rx_buf_size, - struct htt_rx_ring_tlv_filter *tlv_filter) -{ - struct htt_rx_ring_selection_cfg_cmd *cmd; - struct hal_srng *srng = &ab->hal.srng_list[ring_id]; - struct hal_srng_params params; - struct sk_buff *skb; - int len = sizeof(*cmd); - enum htt_srng_ring_type htt_ring_type; - enum htt_srng_ring_id htt_ring_id; - int ret; - - skb = ath12k_htc_alloc_skb(ab, len); - if (!skb) - return -ENOMEM; - - memset(¶ms, 0, sizeof(params)); - ath12k_hal_srng_get_params(ab, srng, ¶ms); - - ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id, - ring_type, &htt_ring_type, - &htt_ring_id); - if (ret) - goto err_free; - - skb_put(skb, len); - cmd = (struct htt_rx_ring_selection_cfg_cmd *)skb->data; - cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG, - HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE); - if (htt_ring_type == HTT_SW_TO_HW_RING || - htt_ring_type == HTT_HW_TO_SW_RING) - cmd->info0 |= - le32_encode_bits(DP_SW2HW_MACID(mac_id), - HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID); - else - cmd->info0 |= - le32_encode_bits(mac_id, - HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID); - cmd->info0 |= le32_encode_bits(htt_ring_id, - HTT_RX_RING_SELECTION_CFG_CMD_INFO0_RING_ID); - cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP), - HTT_RX_RING_SELECTION_CFG_CMD_INFO0_SS); - cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP), - HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS); - cmd->info0 |= le32_encode_bits(tlv_filter->offset_valid, - HTT_RX_RING_SELECTION_CFG_CMD_INFO0_OFFSET_VALID); - cmd->info0 |= - le32_encode_bits(tlv_filter->drop_threshold_valid, - HTT_RX_RING_SELECTION_CFG_CMD_INFO0_DROP_THRES_VAL); - cmd->info0 |= le32_encode_bits(!tlv_filter->rxmon_disable, - HTT_RX_RING_SELECTION_CFG_CMD_INFO0_EN_RXMON); - - cmd->info1 = le32_encode_bits(rx_buf_size, - HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE); - cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_mgmt, - HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT); - cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_ctrl, - HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL); - cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_data, - HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA); - cmd->pkt_type_en_flags0 = cpu_to_le32(tlv_filter->pkt_filter_flags0); - cmd->pkt_type_en_flags1 = cpu_to_le32(tlv_filter->pkt_filter_flags1); - cmd->pkt_type_en_flags2 = cpu_to_le32(tlv_filter->pkt_filter_flags2); - cmd->pkt_type_en_flags3 = cpu_to_le32(tlv_filter->pkt_filter_flags3); - cmd->rx_filter_tlv = cpu_to_le32(tlv_filter->rx_filter); - - cmd->info2 = le32_encode_bits(tlv_filter->rx_drop_threshold, - HTT_RX_RING_SELECTION_CFG_CMD_INFO2_DROP_THRESHOLD); - cmd->info2 |= - le32_encode_bits(tlv_filter->enable_log_mgmt_type, - HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_MGMT_TYPE); - cmd->info2 |= - le32_encode_bits(tlv_filter->enable_log_ctrl_type, - HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_CTRL_TYPE); - cmd->info2 |= - le32_encode_bits(tlv_filter->enable_log_data_type, - HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_DATA_TYPE); - - cmd->info3 = - le32_encode_bits(tlv_filter->enable_rx_tlv_offset, - HTT_RX_RING_SELECTION_CFG_CMD_INFO3_EN_TLV_PKT_OFFSET); - cmd->info3 |= - le32_encode_bits(tlv_filter->rx_tlv_offset, - HTT_RX_RING_SELECTION_CFG_CMD_INFO3_PKT_TLV_OFFSET); - - if (tlv_filter->offset_valid) { - cmd->rx_packet_offset = - le32_encode_bits(tlv_filter->rx_packet_offset, - HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET); - - cmd->rx_packet_offset |= - le32_encode_bits(tlv_filter->rx_header_offset, - HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET); - - cmd->rx_mpdu_offset = - le32_encode_bits(tlv_filter->rx_mpdu_end_offset, - HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET); - - cmd->rx_mpdu_offset |= - le32_encode_bits(tlv_filter->rx_mpdu_start_offset, - HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET); - - cmd->rx_msdu_offset = - le32_encode_bits(tlv_filter->rx_msdu_end_offset, - HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET); - - cmd->rx_msdu_offset |= - le32_encode_bits(tlv_filter->rx_msdu_start_offset, - HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET); - - cmd->rx_attn_offset = - le32_encode_bits(tlv_filter->rx_attn_offset, - HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET); - } - - if (tlv_filter->rx_mpdu_start_wmask > 0 && - tlv_filter->rx_msdu_end_wmask > 0) { - cmd->info2 |= - le32_encode_bits(true, - HTT_RX_RING_SELECTION_CFG_WORD_MASK_COMPACT_SET); - cmd->rx_mpdu_start_end_mask = - le32_encode_bits(tlv_filter->rx_mpdu_start_wmask, - HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_MASK); - /* mpdu_end is not used for any hardwares so far - * please assign it in future if any chip is - * using through hal ops - */ - cmd->rx_mpdu_start_end_mask |= - le32_encode_bits(tlv_filter->rx_mpdu_end_wmask, - HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_MASK); - cmd->rx_msdu_end_word_mask = - le32_encode_bits(tlv_filter->rx_msdu_end_wmask, - HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_MASK); - } - - ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); - if (ret) - goto err_free; - - return 0; - -err_free: - dev_kfree_skb_any(skb); - - return ret; -} - -int -ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type, - struct htt_ext_stats_cfg_params *cfg_params, - u64 cookie) -{ - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; - struct sk_buff *skb; - struct htt_ext_stats_cfg_cmd *cmd; - int len = sizeof(*cmd); - int ret; - u32 pdev_id; - - skb = ath12k_htc_alloc_skb(ab, len); - if (!skb) - return -ENOMEM; - - skb_put(skb, len); - - cmd = (struct htt_ext_stats_cfg_cmd *)skb->data; - memset(cmd, 0, sizeof(*cmd)); - cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_EXT_STATS_CFG; - - pdev_id = ath12k_mac_get_target_pdev_id(ar); - cmd->hdr.pdev_mask = 1 << pdev_id; - - cmd->hdr.stats_type = type; - cmd->cfg_param0 = cpu_to_le32(cfg_params->cfg0); - cmd->cfg_param1 = cpu_to_le32(cfg_params->cfg1); - cmd->cfg_param2 = cpu_to_le32(cfg_params->cfg2); - cmd->cfg_param3 = cpu_to_le32(cfg_params->cfg3); - cmd->cookie_lsb = cpu_to_le32(lower_32_bits(cookie)); - cmd->cookie_msb = cpu_to_le32(upper_32_bits(cookie)); - - ret = ath12k_htc_send(&ab->htc, dp->eid, skb); - if (ret) { - ath12k_warn(ab, "failed to send htt type stats request: %d", - ret); - dev_kfree_skb_any(skb); - return ret; - } - - return 0; -} - -int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset) -{ - struct ath12k_base *ab = ar->ab; - int ret; - - ret = ath12k_dp_tx_htt_rx_monitor_mode_ring_config(ar, reset); - if (ret) { - ath12k_err(ab, "failed to setup rx monitor filter %d\n", ret); - return ret; - } - - return 0; -} - -int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset) -{ - struct ath12k_base *ab = ar->ab; - struct htt_rx_ring_tlv_filter tlv_filter = {}; - int ret, ring_id, i; - - tlv_filter.offset_valid = false; - - if (!reset) { - tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_DEST_RING; - - tlv_filter.drop_threshold_valid = true; - tlv_filter.rx_drop_threshold = HTT_RX_RING_TLV_DROP_THRESHOLD_VALUE; - - tlv_filter.enable_log_mgmt_type = true; - tlv_filter.enable_log_ctrl_type = true; - tlv_filter.enable_log_data_type = true; - - tlv_filter.conf_len_ctrl = HTT_RX_RING_DEFAULT_DMA_LENGTH; - tlv_filter.conf_len_mgmt = HTT_RX_RING_DEFAULT_DMA_LENGTH; - tlv_filter.conf_len_data = HTT_RX_RING_DEFAULT_DMA_LENGTH; - - tlv_filter.enable_rx_tlv_offset = true; - tlv_filter.rx_tlv_offset = HTT_RX_RING_PKT_TLV_OFFSET; - - tlv_filter.pkt_filter_flags0 = - HTT_RX_MON_FP_MGMT_FILTER_FLAGS0 | - HTT_RX_MON_MO_MGMT_FILTER_FLAGS0; - tlv_filter.pkt_filter_flags1 = - HTT_RX_MON_FP_MGMT_FILTER_FLAGS1 | - HTT_RX_MON_MO_MGMT_FILTER_FLAGS1; - tlv_filter.pkt_filter_flags2 = - HTT_RX_MON_FP_CTRL_FILTER_FLASG2 | - HTT_RX_MON_MO_CTRL_FILTER_FLASG2; - tlv_filter.pkt_filter_flags3 = - HTT_RX_MON_FP_CTRL_FILTER_FLASG3 | - HTT_RX_MON_MO_CTRL_FILTER_FLASG3 | - HTT_RX_MON_FP_DATA_FILTER_FLASG3 | - HTT_RX_MON_MO_DATA_FILTER_FLASG3; - } else { - tlv_filter = ath12k_mac_mon_status_filter_default; - - if (ath12k_debugfs_is_extd_rx_stats_enabled(ar)) - tlv_filter.rx_filter = ath12k_debugfs_rx_filter(ar); - } - - if (ab->hw_params->rxdma1_enable) { - for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { - ring_id = ar->dp.rxdma_mon_dst_ring[i].ring_id; - ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, - ar->dp.mac_id + i, - HAL_RXDMA_MONITOR_DST, - DP_RXDMA_REFILL_RING_SIZE, - &tlv_filter); - if (ret) { - ath12k_err(ab, - "failed to setup filter for monitor buf %d\n", - ret); - return ret; - } - } - return 0; - } - - if (!reset) { - for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { - ring_id = ab->dp.rx_mac_buf_ring[i].ring_id; - ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, - i, - HAL_RXDMA_BUF, - DP_RXDMA_REFILL_RING_SIZE, - &tlv_filter); - if (ret) { - ath12k_err(ab, - "failed to setup filter for mon rx buf %d\n", - ret); - return ret; - } - } - } - - for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { - ring_id = ab->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; - if (!reset) { - tlv_filter.rx_filter = - HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING; - } - - ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, - i, - HAL_RXDMA_MONITOR_STATUS, - RX_MON_STATUS_BUF_SIZE, - &tlv_filter); - if (ret) { - ath12k_err(ab, - "failed to setup filter for mon status buf %d\n", - ret); - return ret; - } - } - - return 0; -} - -int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id, - int mac_id, enum hal_ring_type ring_type, - int tx_buf_size, - struct htt_tx_ring_tlv_filter *htt_tlv_filter) -{ - struct htt_tx_ring_selection_cfg_cmd *cmd; - struct hal_srng *srng = &ab->hal.srng_list[ring_id]; - struct hal_srng_params params; - struct sk_buff *skb; - int len = sizeof(*cmd); - enum htt_srng_ring_type htt_ring_type; - enum htt_srng_ring_id htt_ring_id; - int ret; - - skb = ath12k_htc_alloc_skb(ab, len); - if (!skb) - return -ENOMEM; - - memset(¶ms, 0, sizeof(params)); - ath12k_hal_srng_get_params(ab, srng, ¶ms); - - ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id, - ring_type, &htt_ring_type, - &htt_ring_id); - - if (ret) - goto err_free; - - skb_put(skb, len); - cmd = (struct htt_tx_ring_selection_cfg_cmd *)skb->data; - cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_TX_MONITOR_CFG, - HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE); - if (htt_ring_type == HTT_SW_TO_HW_RING || - htt_ring_type == HTT_HW_TO_SW_RING) - cmd->info0 |= - le32_encode_bits(DP_SW2HW_MACID(mac_id), - HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID); - else - cmd->info0 |= - le32_encode_bits(mac_id, - HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID); - cmd->info0 |= le32_encode_bits(htt_ring_id, - HTT_TX_RING_SELECTION_CFG_CMD_INFO0_RING_ID); - cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP), - HTT_TX_RING_SELECTION_CFG_CMD_INFO0_SS); - cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP), - HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PS); - - cmd->info1 |= - le32_encode_bits(tx_buf_size, - HTT_TX_RING_SELECTION_CFG_CMD_INFO1_RING_BUFF_SIZE); - - if (htt_tlv_filter->tx_mon_mgmt_filter) { - cmd->info1 |= - le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_MGMT, - HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE); - cmd->info1 |= - le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len, - HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT); - cmd->info2 |= - le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_MGMT, - HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG); - } - - if (htt_tlv_filter->tx_mon_data_filter) { - cmd->info1 |= - le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_CTRL, - HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE); - cmd->info1 |= - le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len, - HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL); - cmd->info2 |= - le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_CTRL, - HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG); - } - - if (htt_tlv_filter->tx_mon_ctrl_filter) { - cmd->info1 |= - le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_DATA, - HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE); - cmd->info1 |= - le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len, - HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA); - cmd->info2 |= - le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_DATA, - HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG); - } - - cmd->tlv_filter_mask_in0 = - cpu_to_le32(htt_tlv_filter->tx_mon_downstream_tlv_flags); - cmd->tlv_filter_mask_in1 = - cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags0); - cmd->tlv_filter_mask_in2 = - cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags1); - cmd->tlv_filter_mask_in3 = - cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags2); - - ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); - if (ret) - goto err_free; - - return 0; - -err_free: - dev_kfree_skb_any(skb); - return ret; -} diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.h b/drivers/net/wireless/ath/ath12k/dp_tx.h index 8405a0baf95b6..5b8fe280c32ae 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/dp_tx.h @@ -15,25 +15,7 @@ struct ath12k_dp_htt_wbm_tx_status { s8 ack_rssi; }; -int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab); -int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask); -int -ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type, - struct htt_ext_stats_cfg_params *cfg_params, - u64 cookie); -int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset); - -int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id, - int mac_id, enum hal_ring_type ring_type, - int rx_buf_size, - struct htt_rx_ring_tlv_filter *tlv_filter); void ath12k_dp_tx_put_bank_profile(struct ath12k_dp *dp, u8 bank_id); -int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id, - int mac_id, enum hal_ring_type ring_type, - int tx_buf_size, - struct htt_tx_ring_tlv_filter *htt_tlv_filter); -int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset); - enum hal_tcl_encap_type ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb); void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb); From ca402e7a4013b074cfbb4af4917d315eb3a1529d Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Thu, 28 Aug 2025 23:05:53 +0530 Subject: [PATCH 033/140] wifi: ath12k: Move HTT specific code from dp.c to newly introduced files WLAN Host driver interacts with the Firmware and vice versa using Host-To-Target (HTT) interface. Relocate HTT specific code from dp.c to newly introduced file dp_htt.c for HTT interface. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250828173553.3341351-21-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 29 ---------------------- drivers/net/wireless/ath/ath12k/dp.h | 1 - drivers/net/wireless/ath/ath12k/dp_htt.c | 31 ++++++++++++++++++++++-- drivers/net/wireless/ath/ath12k/dp_htt.h | 3 +++ 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 2826251602b6b..b4f287fb46441 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -19,12 +19,6 @@ enum ath12k_dp_desc_type { ATH12K_DP_RX_DESC, }; -static void ath12k_dp_htt_htc_tx_complete(struct ath12k_base *ab, - struct sk_buff *skb) -{ - dev_kfree_skb_any(skb); -} - void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr) { struct ath12k_base *ab = ar->ab; @@ -957,29 +951,6 @@ int ath12k_dp_pdev_alloc(struct ath12k_base *ab) return ret; } -int ath12k_dp_htt_connect(struct ath12k_dp *dp) -{ - struct ath12k_htc_svc_conn_req conn_req = {}; - struct ath12k_htc_svc_conn_resp conn_resp = {}; - int status; - - conn_req.ep_ops.ep_tx_complete = ath12k_dp_htt_htc_tx_complete; - conn_req.ep_ops.ep_rx_complete = ath12k_dp_htt_htc_t2h_msg_handler; - - /* connect to control service */ - conn_req.service_id = ATH12K_HTC_SVC_ID_HTT_DATA_MSG; - - status = ath12k_htc_connect_service(&dp->ab->htc, &conn_req, - &conn_resp); - - if (status) - return status; - - dp->eid = conn_resp.eid; - - return 0; -} - static void ath12k_dp_update_vdev_search(struct ath12k_link_vif *arvif) { switch (arvif->ahvif->vdev_type) { diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 852b35ff1ecd4..9b82e1cf74dc3 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -436,7 +436,6 @@ static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) memcpy(addr + 4, &addr_h16, ETH_ALEN - 4); } -int ath12k_dp_htt_connect(struct ath12k_dp *dp); void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif); void ath12k_dp_free(struct ath12k_base *ab); int ath12k_dp_alloc(struct ath12k_base *ab); diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index 45aa8ae86a14c..6ab5b2d8aac94 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -11,6 +11,35 @@ #include "debugfs_htt_stats.h" #include "debugfs.h" +static void ath12k_dp_htt_htc_tx_complete(struct ath12k_base *ab, + struct sk_buff *skb) +{ + dev_kfree_skb_any(skb); +} + +int ath12k_dp_htt_connect(struct ath12k_dp *dp) +{ + struct ath12k_htc_svc_conn_req conn_req = {}; + struct ath12k_htc_svc_conn_resp conn_resp = {}; + int status; + + conn_req.ep_ops.ep_tx_complete = ath12k_dp_htt_htc_tx_complete; + conn_req.ep_ops.ep_rx_complete = ath12k_dp_htt_htc_t2h_msg_handler; + + /* connect to control service */ + conn_req.service_id = ATH12K_HTC_SVC_ID_HTT_DATA_MSG; + + status = ath12k_htc_connect_service(&dp->ab->htc, &conn_req, + &conn_resp); + + if (status) + return status; + + dp->eid = conn_resp.eid; + + return 0; +} + static int ath12k_get_ppdu_user_index(struct htt_ppdu_stats *ppdu_stats, u16 peer_id) { @@ -818,8 +847,6 @@ int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id, return ret; } -#define HTT_TARGET_VERSION_TIMEOUT_HZ (3 * HZ) - int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab) { struct ath12k_dp *dp = &ab->dp; diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.h b/drivers/net/wireless/ath/ath12k/dp_htt.h index b13af1c69253d..6020e632f74ec 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.h +++ b/drivers/net/wireless/ath/ath12k/dp_htt.h @@ -36,6 +36,8 @@ struct ath12k_dp; #define HTT_TX_WBM_COMP_INFO2_ACK_RSSI GENMASK(31, 24) +#define HTT_TARGET_VERSION_TIMEOUT_HZ (3 * HZ) + struct htt_tx_wbm_completion { __le32 rsvd0[2]; __le32 info0; @@ -1514,6 +1516,7 @@ struct htt_mac_addr { __le32 mac_addr_h16; } __packed; +int ath12k_dp_htt_connect(struct ath12k_dp *dp); int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id, int mac_id, enum hal_ring_type ring_type); From 9c46745f33e0054d0cca5b1e32e33c20cf7c99de Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Wed, 10 Sep 2025 23:44:07 +0530 Subject: [PATCH 034/140] wifi: ath12k: Remove non-compact TLV support from QCN Set compact TLV ops as the default ops by registering them in hal_rx_ops by default for QCN, and remove non-compact TLV ops and the corresponding hal APIs for QCN. Please note that compact TLVs have been supported by the firmware since the beginning of Wi-Fi 7, so backward compatibility has been maintained. These changes are specific to QCN as WCN only support non-compact TLVs. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250910181414.2062280-2-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 20 +- drivers/net/wireless/ath/ath12k/dp.h | 1 - drivers/net/wireless/ath/ath12k/hal.c | 339 +----------------- drivers/net/wireless/ath/ath12k/hal.h | 2 - drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 16 +- .../wireless/ath/ath12k/wifi7/hal_rx_desc.h | 7 - drivers/net/wireless/ath/ath12k/wifi7/pci.c | 2 +- 7 files changed, 11 insertions(+), 376 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index b4f287fb46441..4c6caa8905fdd 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -895,27 +895,9 @@ void ath12k_dp_pdev_pre_alloc(struct ath12k *ar) /* TODO: Add any RXDMA setup required per pdev */ } -bool ath12k_dp_wmask_compaction_rx_tlv_supported(struct ath12k_base *ab) -{ - if (test_bit(WMI_TLV_SERVICE_WMSK_COMPACTION_RX_TLVS, ab->wmi_ab.svc_map) && - ab->hw_params->hal_ops->rxdma_ring_wmask_rx_mpdu_start && - ab->hw_params->hal_ops->rxdma_ring_wmask_rx_msdu_end && - ab->hw_params->hal_ops->get_hal_rx_compact_ops) { - return true; - } - return false; -} - void ath12k_dp_hal_rx_desc_init(struct ath12k_base *ab) { - if (ath12k_dp_wmask_compaction_rx_tlv_supported(ab)) { - /* RX TLVS compaction is supported, hence change the hal_rx_ops - * to compact hal_rx_ops. - */ - ab->hal_rx_ops = ab->hw_params->hal_ops->get_hal_rx_compact_ops(); - } - ab->hal.hal_desc_sz = - ab->hal_rx_ops->rx_desc_get_desc_size(); + ab->hal.hal_desc_sz = ab->hal_rx_ops->rx_desc_get_desc_size(); } int ath12k_dp_pdev_alloc(struct ath12k_base *ab) diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 9b82e1cf74dc3..5c8e6089f9e94 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -461,6 +461,5 @@ struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_base *ab, u32 cookie); struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_base *ab, u32 desc_id); -bool ath12k_dp_wmask_compaction_rx_tlv_supported(struct ath12k_base *ab); void ath12k_dp_hal_rx_desc_init(struct ath12k_base *ab); #endif diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 144c26586b794..980f17791c1aa 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -294,230 +294,6 @@ static unsigned int ath12k_hal_reo1_ring_misc_offset(struct ath12k_base *ab) return HAL_REO1_RING_MISC(ab) - HAL_REO1_RING_BASE_LSB(ab); } -static bool ath12k_hw_qcn9274_rx_desc_get_first_msdu(struct hal_rx_desc *desc) -{ - return !!le16_get_bits(desc->u.qcn9274.msdu_end.info5, - RX_MSDU_END_INFO5_FIRST_MSDU); -} - -static bool ath12k_hw_qcn9274_rx_desc_get_last_msdu(struct hal_rx_desc *desc) -{ - return !!le16_get_bits(desc->u.qcn9274.msdu_end.info5, - RX_MSDU_END_INFO5_LAST_MSDU); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc) -{ - return le16_get_bits(desc->u.qcn9274.msdu_end.info5, - RX_MSDU_END_INFO5_L3_HDR_PADDING); -} - -static bool ath12k_hw_qcn9274_rx_desc_encrypt_valid(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274.mpdu_start.info4, - RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); -} - -static u32 ath12k_hw_qcn9274_rx_desc_get_encrypt_type(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.mpdu_start.info2, - RX_MPDU_START_INFO2_ENC_TYPE); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_decap_type(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.msdu_end.info11, - RX_MSDU_END_INFO11_DECAP_FORMAT); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.msdu_end.info11, - RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); -} - -static bool ath12k_hw_qcn9274_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274.mpdu_start.info4, - RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); -} - -static bool ath12k_hw_qcn9274_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274.mpdu_start.info4, - RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); -} - -static u16 ath12k_hw_qcn9274_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.mpdu_start.info4, - RX_MPDU_START_INFO4_MPDU_SEQ_NUM); -} - -static u16 ath12k_hw_qcn9274_rx_desc_get_msdu_len(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.msdu_end.info10, - RX_MSDU_END_INFO10_MSDU_LENGTH); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.msdu_end.info12, - RX_MSDU_END_INFO12_SGI); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.msdu_end.info12, - RX_MSDU_END_INFO12_RATE_MCS); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.msdu_end.info12, - RX_MSDU_END_INFO12_RECV_BW); -} - -static u32 ath12k_hw_qcn9274_rx_desc_get_msdu_freq(struct hal_rx_desc *desc) -{ - return __le32_to_cpu(desc->u.qcn9274.msdu_end.phy_meta_data); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.msdu_end.info12, - RX_MSDU_END_INFO12_PKT_TYPE); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_nss(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274.msdu_end.info12, - RX_MSDU_END_INFO12_MIMO_SS_BITMAP); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc) -{ - return le16_get_bits(desc->u.qcn9274.msdu_end.info5, - RX_MSDU_END_INFO5_TID); -} - -static u16 ath12k_hw_qcn9274_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc) -{ - return __le16_to_cpu(desc->u.qcn9274.mpdu_start.sw_peer_id); -} - -static void ath12k_hw_qcn9274_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, - struct hal_rx_desc *ldesc) -{ - memcpy(&fdesc->u.qcn9274.msdu_end, &ldesc->u.qcn9274.msdu_end, - sizeof(struct rx_msdu_end_qcn9274)); -} - -static u32 ath12k_hw_qcn9274_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc) -{ - return __le16_to_cpu(desc->u.qcn9274.mpdu_start.phy_ppdu_id); -} - -static void ath12k_hw_qcn9274_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) -{ - u32 info = __le32_to_cpu(desc->u.qcn9274.msdu_end.info10); - - info &= ~RX_MSDU_END_INFO10_MSDU_LENGTH; - info |= u32_encode_bits(len, RX_MSDU_END_INFO10_MSDU_LENGTH); - - desc->u.qcn9274.msdu_end.info10 = __cpu_to_le32(info); -} - -static u8 *ath12k_hw_qcn9274_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) -{ - return &desc->u.qcn9274.msdu_payload[0]; -} - -static u32 ath12k_hw_qcn9274_rx_desc_get_mpdu_start_offset(void) -{ - return offsetof(struct hal_rx_desc_qcn9274, mpdu_start); -} - -static u32 ath12k_hw_qcn9274_rx_desc_get_msdu_end_offset(void) -{ - return offsetof(struct hal_rx_desc_qcn9274, msdu_end); -} - -static bool ath12k_hw_qcn9274_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) -{ - return __le32_to_cpu(desc->u.qcn9274.mpdu_start.info4) & - RX_MPDU_START_INFO4_MAC_ADDR2_VALID; -} - -static u8 *ath12k_hw_qcn9274_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) -{ - return desc->u.qcn9274.mpdu_start.addr2; -} - -static bool ath12k_hw_qcn9274_rx_desc_is_da_mcbc(struct hal_rx_desc *desc) -{ - return __le16_to_cpu(desc->u.qcn9274.msdu_end.info5) & - RX_MSDU_END_INFO5_DA_IS_MCBC; -} - -static void ath12k_hw_qcn9274_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, - struct ieee80211_hdr *hdr) -{ - hdr->frame_control = desc->u.qcn9274.mpdu_start.frame_ctrl; - hdr->duration_id = desc->u.qcn9274.mpdu_start.duration; - ether_addr_copy(hdr->addr1, desc->u.qcn9274.mpdu_start.addr1); - ether_addr_copy(hdr->addr2, desc->u.qcn9274.mpdu_start.addr2); - ether_addr_copy(hdr->addr3, desc->u.qcn9274.mpdu_start.addr3); - if (__le32_to_cpu(desc->u.qcn9274.mpdu_start.info4) & - RX_MPDU_START_INFO4_MAC_ADDR4_VALID) { - ether_addr_copy(hdr->addr4, desc->u.qcn9274.mpdu_start.addr4); - } - hdr->seq_ctrl = desc->u.qcn9274.mpdu_start.seq_ctrl; -} - -static void ath12k_hw_qcn9274_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, - u8 *crypto_hdr, - enum hal_encrypt_type enctype) -{ - unsigned int key_id; - - switch (enctype) { - case HAL_ENCRYPT_TYPE_OPEN: - return; - case HAL_ENCRYPT_TYPE_TKIP_NO_MIC: - case HAL_ENCRYPT_TYPE_TKIP_MIC: - crypto_hdr[0] = - HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274.mpdu_start.pn[0]); - crypto_hdr[1] = 0; - crypto_hdr[2] = - HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274.mpdu_start.pn[0]); - break; - case HAL_ENCRYPT_TYPE_CCMP_128: - case HAL_ENCRYPT_TYPE_CCMP_256: - case HAL_ENCRYPT_TYPE_GCMP_128: - case HAL_ENCRYPT_TYPE_AES_GCMP_256: - crypto_hdr[0] = - HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274.mpdu_start.pn[0]); - crypto_hdr[1] = - HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274.mpdu_start.pn[0]); - crypto_hdr[2] = 0; - break; - case HAL_ENCRYPT_TYPE_WEP_40: - case HAL_ENCRYPT_TYPE_WEP_104: - case HAL_ENCRYPT_TYPE_WEP_128: - case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4: - case HAL_ENCRYPT_TYPE_WAPI: - return; - } - key_id = le32_get_bits(desc->u.qcn9274.mpdu_start.info5, - RX_MPDU_START_INFO5_KEY_ID); - crypto_hdr[3] = 0x20 | (key_id << 6); - crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.qcn9274.mpdu_start.pn[0]); - crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.qcn9274.mpdu_start.pn[0]); - crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274.mpdu_start.pn[1]); - crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274.mpdu_start.pn[1]); -} - static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) { struct ath12k_hal *hal = &ab->hal; @@ -638,116 +414,6 @@ static u32 ath12k_hal_qcn9274_rx_msdu_end_wmask_get(void) return QCN9274_MSDU_END_WMASK; } -static const struct hal_rx_ops *ath12k_hal_qcn9274_get_hal_rx_compact_ops(void) -{ - return &hal_rx_qcn9274_compact_ops; -} - -static bool ath12k_hw_qcn9274_dp_rx_h_msdu_done(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274.msdu_end.info14, - RX_MSDU_END_INFO14_MSDU_DONE); -} - -static bool ath12k_hw_qcn9274_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274.msdu_end.info13, - RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); -} - -static bool ath12k_hw_qcn9274_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274.msdu_end.info13, - RX_MSDU_END_INFO13_IP_CKSUM_FAIL); -} - -static bool ath12k_hw_qcn9274_dp_rx_h_is_decrypted(struct hal_rx_desc *desc) -{ - return (le32_get_bits(desc->u.qcn9274.msdu_end.info14, - RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == - RX_DESC_DECRYPT_STATUS_CODE_OK); -} - -static u32 ath12k_hw_qcn9274_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) -{ - u32 info = __le32_to_cpu(desc->u.qcn9274.msdu_end.info13); - u32 errmap = 0; - - if (info & RX_MSDU_END_INFO13_FCS_ERR) - errmap |= HAL_RX_MPDU_ERR_FCS; - - if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) - errmap |= HAL_RX_MPDU_ERR_DECRYPT; - - if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) - errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; - - if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) - errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; - - if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) - errmap |= HAL_RX_MPDU_ERR_OVERFLOW; - - if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) - errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; - - if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) - errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; - - return errmap; -} - -static u32 ath12k_hw_qcn9274_get_rx_desc_size(void) -{ - return sizeof(struct hal_rx_desc_qcn9274); -} - -static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) -{ - return 0; -} - -const struct hal_rx_ops hal_rx_qcn9274_ops = { - .rx_desc_get_first_msdu = ath12k_hw_qcn9274_rx_desc_get_first_msdu, - .rx_desc_get_last_msdu = ath12k_hw_qcn9274_rx_desc_get_last_msdu, - .rx_desc_get_l3_pad_bytes = ath12k_hw_qcn9274_rx_desc_get_l3_pad_bytes, - .rx_desc_encrypt_valid = ath12k_hw_qcn9274_rx_desc_encrypt_valid, - .rx_desc_get_encrypt_type = ath12k_hw_qcn9274_rx_desc_get_encrypt_type, - .rx_desc_get_decap_type = ath12k_hw_qcn9274_rx_desc_get_decap_type, - .rx_desc_get_mesh_ctl = ath12k_hw_qcn9274_rx_desc_get_mesh_ctl, - .rx_desc_get_mpdu_seq_ctl_vld = ath12k_hw_qcn9274_rx_desc_get_mpdu_seq_ctl_vld, - .rx_desc_get_mpdu_fc_valid = ath12k_hw_qcn9274_rx_desc_get_mpdu_fc_valid, - .rx_desc_get_mpdu_start_seq_no = ath12k_hw_qcn9274_rx_desc_get_mpdu_start_seq_no, - .rx_desc_get_msdu_len = ath12k_hw_qcn9274_rx_desc_get_msdu_len, - .rx_desc_get_msdu_sgi = ath12k_hw_qcn9274_rx_desc_get_msdu_sgi, - .rx_desc_get_msdu_rate_mcs = ath12k_hw_qcn9274_rx_desc_get_msdu_rate_mcs, - .rx_desc_get_msdu_rx_bw = ath12k_hw_qcn9274_rx_desc_get_msdu_rx_bw, - .rx_desc_get_msdu_freq = ath12k_hw_qcn9274_rx_desc_get_msdu_freq, - .rx_desc_get_msdu_pkt_type = ath12k_hw_qcn9274_rx_desc_get_msdu_pkt_type, - .rx_desc_get_msdu_nss = ath12k_hw_qcn9274_rx_desc_get_msdu_nss, - .rx_desc_get_mpdu_tid = ath12k_hw_qcn9274_rx_desc_get_mpdu_tid, - .rx_desc_get_mpdu_peer_id = ath12k_hw_qcn9274_rx_desc_get_mpdu_peer_id, - .rx_desc_copy_end_tlv = ath12k_hw_qcn9274_rx_desc_copy_end_tlv, - .rx_desc_get_mpdu_ppdu_id = ath12k_hw_qcn9274_rx_desc_get_mpdu_ppdu_id, - .rx_desc_set_msdu_len = ath12k_hw_qcn9274_rx_desc_set_msdu_len, - .rx_desc_get_msdu_payload = ath12k_hw_qcn9274_rx_desc_get_msdu_payload, - .rx_desc_get_mpdu_start_offset = ath12k_hw_qcn9274_rx_desc_get_mpdu_start_offset, - .rx_desc_get_msdu_end_offset = ath12k_hw_qcn9274_rx_desc_get_msdu_end_offset, - .rx_desc_mac_addr2_valid = ath12k_hw_qcn9274_rx_desc_mac_addr2_valid, - .rx_desc_mpdu_start_addr2 = ath12k_hw_qcn9274_rx_desc_mpdu_start_addr2, - .rx_desc_is_da_mcbc = ath12k_hw_qcn9274_rx_desc_is_da_mcbc, - .rx_desc_get_dot11_hdr = ath12k_hw_qcn9274_rx_desc_get_dot11_hdr, - .rx_desc_get_crypto_header = ath12k_hw_qcn9274_rx_desc_get_crypto_hdr, - .dp_rx_h_msdu_done = ath12k_hw_qcn9274_dp_rx_h_msdu_done, - .dp_rx_h_l4_cksum_fail = ath12k_hw_qcn9274_dp_rx_h_l4_cksum_fail, - .dp_rx_h_ip_cksum_fail = ath12k_hw_qcn9274_dp_rx_h_ip_cksum_fail, - .dp_rx_h_is_decrypted = ath12k_hw_qcn9274_dp_rx_h_is_decrypted, - .dp_rx_h_mpdu_err = ath12k_hw_qcn9274_dp_rx_h_mpdu_err, - .rx_desc_get_desc_size = ath12k_hw_qcn9274_get_rx_desc_size, - .rx_desc_get_msdu_src_link_id = ath12k_hw_qcn9274_rx_desc_get_msdu_src_link, -}; -EXPORT_SYMBOL(hal_rx_qcn9274_ops); - static bool ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu(struct hal_rx_desc *desc) { return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, @@ -786,7 +452,7 @@ static u8 ath12k_hw_qcn9274_compact_rx_desc_get_decap_type(struct hal_rx_desc *d static u8 ath12k_hw_qcn9274_compact_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) { - return le32_get_bits(desc->u.qcn9274.msdu_end.info11, + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); } @@ -1086,13 +752,13 @@ const struct hal_rx_ops hal_rx_qcn9274_compact_ops = { .rx_desc_get_msdu_src_link_id = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_src_link, }; +EXPORT_SYMBOL(hal_rx_qcn9274_compact_ops); const struct hal_ops hal_qcn9274_ops = { .create_srng_config = ath12k_hal_srng_create_config_qcn9274, .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, .rxdma_ring_wmask_rx_mpdu_start = ath12k_hal_qcn9274_rx_mpdu_start_wmask_get, .rxdma_ring_wmask_rx_msdu_end = ath12k_hal_qcn9274_rx_msdu_end_wmask_get, - .get_hal_rx_compact_ops = ath12k_hal_qcn9274_get_hal_rx_compact_ops, }; EXPORT_SYMBOL(hal_qcn9274_ops); @@ -1561,7 +1227,6 @@ const struct hal_ops hal_wcn7850_ops = { .tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map, .rxdma_ring_wmask_rx_mpdu_start = NULL, .rxdma_ring_wmask_rx_msdu_end = NULL, - .get_hal_rx_compact_ops = NULL, }; EXPORT_SYMBOL(hal_wcn7850_ops); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 4b512fd3adc41..2e086909ce25e 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1600,14 +1600,12 @@ struct hal_ops { int (*create_srng_config)(struct ath12k_base *ab); u16 (*rxdma_ring_wmask_rx_mpdu_start)(void); u32 (*rxdma_ring_wmask_rx_msdu_end)(void); - const struct hal_rx_ops *(*get_hal_rx_compact_ops)(void); const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; }; extern const struct hal_ops hal_qcn9274_ops; extern const struct hal_ops hal_wcn7850_ops; -extern const struct hal_rx_ops hal_rx_qcn9274_ops; extern const struct hal_rx_ops hal_rx_qcn9274_compact_ops; extern const struct hal_rx_ops hal_rx_wcn7850_ops; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index d95e3c4daa5d5..2105d9e949768 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -1901,15 +1901,13 @@ int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab) tlv_filter.rx_msdu_end_offset = ab->hal_rx_ops->rx_desc_get_msdu_end_offset(); - if (ath12k_dp_wmask_compaction_rx_tlv_supported(ab)) { - tlv_filter.rx_mpdu_start_wmask = - ab->hw_params->hal_ops->rxdma_ring_wmask_rx_mpdu_start(); - tlv_filter.rx_msdu_end_wmask = - ab->hw_params->hal_ops->rxdma_ring_wmask_rx_msdu_end(); - ath12k_dbg(ab, ATH12K_DBG_DATA, - "Configuring compact tlv masks rx_mpdu_start_wmask 0x%x rx_msdu_end_wmask 0x%x\n", - tlv_filter.rx_mpdu_start_wmask, tlv_filter.rx_msdu_end_wmask); - } + tlv_filter.rx_mpdu_start_wmask = + ab->hw_params->hal_ops->rxdma_ring_wmask_rx_mpdu_start(); + tlv_filter.rx_msdu_end_wmask = + ab->hw_params->hal_ops->rxdma_ring_wmask_rx_msdu_end(); + ath12k_dbg(ab, ATH12K_DBG_DATA, + "Configuring compact tlv masks rx_mpdu_start_wmask 0x%x rx_msdu_end_wmask 0x%x\n", + tlv_filter.rx_mpdu_start_wmask, tlv_filter.rx_msdu_end_wmask); ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, 0, HAL_RXDMA_BUF, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h index 60f165a176e0f..cc5e1d336376a 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h @@ -1454,12 +1454,6 @@ struct rx_msdu_end_qcn9274_compact { * */ -struct hal_rx_desc_qcn9274 { - struct rx_msdu_end_qcn9274 msdu_end; - struct rx_mpdu_start_qcn9274 mpdu_start; - u8 msdu_payload[]; -} __packed; - struct hal_rx_desc_qcn9274_compact { struct rx_msdu_end_qcn9274_compact msdu_end; struct rx_mpdu_start_qcn9274_compact mpdu_start; @@ -1489,7 +1483,6 @@ struct hal_rx_desc_wcn7850 { struct hal_rx_desc { union { - struct hal_rx_desc_qcn9274 qcn9274; struct hal_rx_desc_qcn9274_compact qcn9274_compact; struct hal_rx_desc_wcn7850 wcn7850; } u; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/pci.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c index 9b1acf6c7aa31..abdb3b8ff658c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/pci.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -101,7 +101,7 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; ab->static_window_map = true; ab_pci->pci_ops = &ath12k_wifi7_pci_ops_qcn9274; - ab->hal_rx_ops = &hal_rx_qcn9274_ops; + ab->hal_rx_ops = &hal_rx_qcn9274_compact_ops; ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major, &soc_hw_version_minor); ab->target_mem_mode = ath12k_core_get_memory_mode(ab); From 6a3137f3617fa2017f9282ea4cbbc43e20f521be Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Wed, 10 Sep 2025 23:44:08 +0530 Subject: [PATCH 035/140] wifi: ath12k: Move the hal APIs to hardware specific files Move the hal APIs from the existing common hal files to hardware specific hal files. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250910181414.2062280-3-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 4 +- drivers/net/wireless/ath/ath12k/hal.c | 600 +----------------- .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 307 +++++++++ .../wireless/ath/ath12k/wifi7/hal_qcn9274.h | 58 ++ .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 302 +++++++++ .../wireless/ath/ath12k/wifi7/hal_wcn7850.h | 55 ++ 6 files changed, 727 insertions(+), 599 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index 70d4daa48c902..e148444021633 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -27,7 +27,9 @@ ath12k-y += wifi7/hal_tx.o \ wifi7/hal_rx.o \ wifi7/dp_rx.o \ wifi7/dp_tx.o \ - wifi7/dp.o + wifi7/dp.o \ + wifi7/hal_qcn9274.o \ + wifi7/hal_wcn7850.o obj-$(CONFIG_ATH12K) += wifi7/ diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 980f17791c1aa..77024c99d0bf0 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -9,6 +9,8 @@ #include "debug.h" #include "wifi7/hal_desc.h" #include "hif.h" +#include "wifi7/hal_qcn9274.h" +#include "wifi7/hal_wcn7850.h" static const struct hal_srng_config hw_srng_config_template[] = { /* TODO: max_rings can populated by querying HW capabilities */ @@ -404,310 +406,6 @@ static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) return 0; } -static u16 ath12k_hal_qcn9274_rx_mpdu_start_wmask_get(void) -{ - return QCN9274_MPDU_START_WMASK; -} - -static u32 ath12k_hal_qcn9274_rx_msdu_end_wmask_get(void) -{ - return QCN9274_MSDU_END_WMASK; -} - -static bool ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu(struct hal_rx_desc *desc) -{ - return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, - RX_MSDU_END_INFO5_FIRST_MSDU); -} - -static bool ath12k_hw_qcn9274_compact_rx_desc_get_last_msdu(struct hal_rx_desc *desc) -{ - return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, - RX_MSDU_END_INFO5_LAST_MSDU); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc) -{ - return le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, - RX_MSDU_END_INFO5_L3_HDR_PADDING); -} - -static bool ath12k_hw_qcn9274_compact_rx_desc_encrypt_valid(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, - RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); -} - -static u32 ath12k_hw_qcn9274_compact_rx_desc_get_encrypt_type(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info2, - RX_MPDU_START_INFO2_ENC_TYPE); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_decap_type(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, - RX_MSDU_END_INFO11_DECAP_FORMAT); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, - RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); -} - -static bool -ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, - RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); -} - -static bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, - RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); -} - -static u16 -ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, - RX_MPDU_START_INFO4_MPDU_SEQ_NUM); -} - -static u16 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_len(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info10, - RX_MSDU_END_INFO10_MSDU_LENGTH); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, - RX_MSDU_END_INFO12_SGI); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, - RX_MSDU_END_INFO12_RATE_MCS); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, - RX_MSDU_END_INFO12_RECV_BW); -} - -static u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_freq(struct hal_rx_desc *desc) -{ - return __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.phy_meta_data); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, - RX_MSDU_END_INFO12_PKT_TYPE); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_nss(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, - RX_MSDU_END_INFO12_MIMO_SS_BITMAP); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc) -{ - return le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, - RX_MSDU_END_INFO5_TID); -} - -static u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc) -{ - return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.sw_peer_id); -} - -static void ath12k_hw_qcn9274_compact_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, - struct hal_rx_desc *ldesc) -{ - fdesc->u.qcn9274_compact.msdu_end = ldesc->u.qcn9274_compact.msdu_end; -} - -static u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc) -{ - return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.phy_ppdu_id); -} - -static void -ath12k_hw_qcn9274_compact_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) -{ - u32 info = __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.info10); - - info = u32_replace_bits(info, len, RX_MSDU_END_INFO10_MSDU_LENGTH); - desc->u.qcn9274_compact.msdu_end.info10 = __cpu_to_le32(info); -} - -static u8 *ath12k_hw_qcn9274_compact_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) -{ - return &desc->u.qcn9274_compact.msdu_payload[0]; -} - -static u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_offset(void) -{ - return offsetof(struct hal_rx_desc_qcn9274_compact, mpdu_start); -} - -static u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_end_offset(void) -{ - return offsetof(struct hal_rx_desc_qcn9274_compact, msdu_end); -} - -static bool ath12k_hw_qcn9274_compact_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) -{ - return __le32_to_cpu(desc->u.qcn9274_compact.mpdu_start.info4) & - RX_MPDU_START_INFO4_MAC_ADDR2_VALID; -} - -static u8 *ath12k_hw_qcn9274_compact_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) -{ - return desc->u.qcn9274_compact.mpdu_start.addr2; -} - -static bool ath12k_hw_qcn9274_compact_rx_desc_is_da_mcbc(struct hal_rx_desc *desc) -{ - return __le16_to_cpu(desc->u.qcn9274_compact.msdu_end.info5) & - RX_MSDU_END_INFO5_DA_IS_MCBC; -} - -static void ath12k_hw_qcn9274_compact_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, - struct ieee80211_hdr *hdr) -{ - hdr->frame_control = desc->u.qcn9274_compact.mpdu_start.frame_ctrl; - hdr->duration_id = desc->u.qcn9274_compact.mpdu_start.duration; - ether_addr_copy(hdr->addr1, desc->u.qcn9274_compact.mpdu_start.addr1); - ether_addr_copy(hdr->addr2, desc->u.qcn9274_compact.mpdu_start.addr2); - ether_addr_copy(hdr->addr3, desc->u.qcn9274_compact.mpdu_start.addr3); - if (__le32_to_cpu(desc->u.qcn9274_compact.mpdu_start.info4) & - RX_MPDU_START_INFO4_MAC_ADDR4_VALID) { - ether_addr_copy(hdr->addr4, desc->u.qcn9274_compact.mpdu_start.addr4); - } - hdr->seq_ctrl = desc->u.qcn9274_compact.mpdu_start.seq_ctrl; -} - -static void -ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, - u8 *crypto_hdr, - enum hal_encrypt_type enctype) -{ - unsigned int key_id; - - switch (enctype) { - case HAL_ENCRYPT_TYPE_OPEN: - return; - case HAL_ENCRYPT_TYPE_TKIP_NO_MIC: - case HAL_ENCRYPT_TYPE_TKIP_MIC: - crypto_hdr[0] = - HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[0]); - crypto_hdr[1] = 0; - crypto_hdr[2] = - HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274_compact.mpdu_start.pn[0]); - break; - case HAL_ENCRYPT_TYPE_CCMP_128: - case HAL_ENCRYPT_TYPE_CCMP_256: - case HAL_ENCRYPT_TYPE_GCMP_128: - case HAL_ENCRYPT_TYPE_AES_GCMP_256: - crypto_hdr[0] = - HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274_compact.mpdu_start.pn[0]); - crypto_hdr[1] = - HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[0]); - crypto_hdr[2] = 0; - break; - case HAL_ENCRYPT_TYPE_WEP_40: - case HAL_ENCRYPT_TYPE_WEP_104: - case HAL_ENCRYPT_TYPE_WEP_128: - case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4: - case HAL_ENCRYPT_TYPE_WAPI: - return; - } - key_id = le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info5, - RX_MPDU_START_INFO5_KEY_ID); - crypto_hdr[3] = 0x20 | (key_id << 6); - crypto_hdr[4] = - HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.qcn9274_compact.mpdu_start.pn[0]); - crypto_hdr[5] = - HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.qcn9274_compact.mpdu_start.pn[0]); - crypto_hdr[6] = - HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274_compact.mpdu_start.pn[1]); - crypto_hdr[7] = - HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[1]); -} - -static bool ath12k_hw_qcn9274_compact_dp_rx_h_msdu_done(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14, - RX_MSDU_END_INFO14_MSDU_DONE); -} - -static bool ath12k_hw_qcn9274_compact_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info13, - RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); -} - -static bool ath12k_hw_qcn9274_compact_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info13, - RX_MSDU_END_INFO13_IP_CKSUM_FAIL); -} - -static bool ath12k_hw_qcn9274_compact_dp_rx_h_is_decrypted(struct hal_rx_desc *desc) -{ - return (le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14, - RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == - RX_DESC_DECRYPT_STATUS_CODE_OK); -} - -static u32 ath12k_hw_qcn9274_compact_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) -{ - u32 info = __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.info13); - u32 errmap = 0; - - if (info & RX_MSDU_END_INFO13_FCS_ERR) - errmap |= HAL_RX_MPDU_ERR_FCS; - - if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) - errmap |= HAL_RX_MPDU_ERR_DECRYPT; - - if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) - errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; - - if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) - errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; - - if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) - errmap |= HAL_RX_MPDU_ERR_OVERFLOW; - - if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) - errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; - - if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) - errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; - - return errmap; -} - -static u32 ath12k_hw_qcn9274_compact_get_rx_desc_size(void) -{ - return sizeof(struct hal_rx_desc_qcn9274_compact); -} - -static u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) -{ - return le64_get_bits(desc->u.qcn9274_compact.msdu_end.msdu_end_tag, - RX_MSDU_END_64_TLV_SRC_LINK_ID); -} - const struct hal_rx_ops hal_rx_qcn9274_compact_ops = { .rx_desc_get_first_msdu = ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu, .rx_desc_get_last_msdu = ath12k_hw_qcn9274_compact_rx_desc_get_last_msdu, @@ -762,236 +460,6 @@ const struct hal_ops hal_qcn9274_ops = { }; EXPORT_SYMBOL(hal_qcn9274_ops); -static bool ath12k_hw_wcn7850_rx_desc_get_first_msdu(struct hal_rx_desc *desc) -{ - return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5, - RX_MSDU_END_INFO5_FIRST_MSDU); -} - -static bool ath12k_hw_wcn7850_rx_desc_get_last_msdu(struct hal_rx_desc *desc) -{ - return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5, - RX_MSDU_END_INFO5_LAST_MSDU); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc) -{ - return le16_get_bits(desc->u.wcn7850.msdu_end.info5, - RX_MSDU_END_INFO5_L3_HDR_PADDING); -} - -static bool ath12k_hw_wcn7850_rx_desc_encrypt_valid(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, - RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); -} - -static u32 ath12k_hw_wcn7850_rx_desc_get_encrypt_type(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.mpdu_start.info2, - RX_MPDU_START_INFO2_ENC_TYPE); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_decap_type(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.msdu_end.info11, - RX_MSDU_END_INFO11_DECAP_FORMAT); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.msdu_end.info11, - RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); -} - -static bool ath12k_hw_wcn7850_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, - RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); -} - -static bool ath12k_hw_wcn7850_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, - RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); -} - -static u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.mpdu_start.info4, - RX_MPDU_START_INFO4_MPDU_SEQ_NUM); -} - -static u16 ath12k_hw_wcn7850_rx_desc_get_msdu_len(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.msdu_end.info10, - RX_MSDU_END_INFO10_MSDU_LENGTH); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.msdu_end.info12, - RX_MSDU_END_INFO12_SGI); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.msdu_end.info12, - RX_MSDU_END_INFO12_RATE_MCS); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.msdu_end.info12, - RX_MSDU_END_INFO12_RECV_BW); -} - -static u32 ath12k_hw_wcn7850_rx_desc_get_msdu_freq(struct hal_rx_desc *desc) -{ - return __le32_to_cpu(desc->u.wcn7850.msdu_end.phy_meta_data); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.msdu_end.info12, - RX_MSDU_END_INFO12_PKT_TYPE); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_nss(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.msdu_end.info12, - RX_MSDU_END_INFO12_MIMO_SS_BITMAP); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc) -{ - return le32_get_bits(desc->u.wcn7850.mpdu_start.info2, - RX_MPDU_START_INFO2_TID); -} - -static u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc) -{ - return __le16_to_cpu(desc->u.wcn7850.mpdu_start.sw_peer_id); -} - -static void ath12k_hw_wcn7850_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, - struct hal_rx_desc *ldesc) -{ - memcpy(&fdesc->u.wcn7850.msdu_end, &ldesc->u.wcn7850.msdu_end, - sizeof(struct rx_msdu_end_qcn9274)); -} - -static u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag(struct hal_rx_desc *desc) -{ - return le64_get_bits(desc->u.wcn7850.mpdu_start_tag, - HAL_TLV_HDR_TAG); -} - -static u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc) -{ - return __le16_to_cpu(desc->u.wcn7850.mpdu_start.phy_ppdu_id); -} - -static void ath12k_hw_wcn7850_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) -{ - u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info10); - - info &= ~RX_MSDU_END_INFO10_MSDU_LENGTH; - info |= u32_encode_bits(len, RX_MSDU_END_INFO10_MSDU_LENGTH); - - desc->u.wcn7850.msdu_end.info10 = __cpu_to_le32(info); -} - -static u8 *ath12k_hw_wcn7850_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) -{ - return &desc->u.wcn7850.msdu_payload[0]; -} - -static u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_offset(void) -{ - return offsetof(struct hal_rx_desc_wcn7850, mpdu_start_tag); -} - -static u32 ath12k_hw_wcn7850_rx_desc_get_msdu_end_offset(void) -{ - return offsetof(struct hal_rx_desc_wcn7850, msdu_end_tag); -} - -static bool ath12k_hw_wcn7850_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) -{ - return __le32_to_cpu(desc->u.wcn7850.mpdu_start.info4) & - RX_MPDU_START_INFO4_MAC_ADDR2_VALID; -} - -static u8 *ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) -{ - return desc->u.wcn7850.mpdu_start.addr2; -} - -static bool ath12k_hw_wcn7850_rx_desc_is_da_mcbc(struct hal_rx_desc *desc) -{ - return __le32_to_cpu(desc->u.wcn7850.msdu_end.info13) & - RX_MSDU_END_INFO13_MCAST_BCAST; -} - -static void ath12k_hw_wcn7850_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, - struct ieee80211_hdr *hdr) -{ - hdr->frame_control = desc->u.wcn7850.mpdu_start.frame_ctrl; - hdr->duration_id = desc->u.wcn7850.mpdu_start.duration; - ether_addr_copy(hdr->addr1, desc->u.wcn7850.mpdu_start.addr1); - ether_addr_copy(hdr->addr2, desc->u.wcn7850.mpdu_start.addr2); - ether_addr_copy(hdr->addr3, desc->u.wcn7850.mpdu_start.addr3); - if (__le32_to_cpu(desc->u.wcn7850.mpdu_start.info4) & - RX_MPDU_START_INFO4_MAC_ADDR4_VALID) { - ether_addr_copy(hdr->addr4, desc->u.wcn7850.mpdu_start.addr4); - } - hdr->seq_ctrl = desc->u.wcn7850.mpdu_start.seq_ctrl; -} - -static void ath12k_hw_wcn7850_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, - u8 *crypto_hdr, - enum hal_encrypt_type enctype) -{ - unsigned int key_id; - - switch (enctype) { - case HAL_ENCRYPT_TYPE_OPEN: - return; - case HAL_ENCRYPT_TYPE_TKIP_NO_MIC: - case HAL_ENCRYPT_TYPE_TKIP_MIC: - crypto_hdr[0] = - HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[0]); - crypto_hdr[1] = 0; - crypto_hdr[2] = - HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[0]); - break; - case HAL_ENCRYPT_TYPE_CCMP_128: - case HAL_ENCRYPT_TYPE_CCMP_256: - case HAL_ENCRYPT_TYPE_GCMP_128: - case HAL_ENCRYPT_TYPE_AES_GCMP_256: - crypto_hdr[0] = - HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[0]); - crypto_hdr[1] = - HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[0]); - crypto_hdr[2] = 0; - break; - case HAL_ENCRYPT_TYPE_WEP_40: - case HAL_ENCRYPT_TYPE_WEP_104: - case HAL_ENCRYPT_TYPE_WEP_128: - case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4: - case HAL_ENCRYPT_TYPE_WAPI: - return; - } - key_id = u32_get_bits(__le32_to_cpu(desc->u.wcn7850.mpdu_start.info5), - RX_MPDU_START_INFO5_KEY_ID); - crypto_hdr[3] = 0x20 | (key_id << 6); - crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.wcn7850.mpdu_start.pn[0]); - crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.wcn7850.mpdu_start.pn[0]); - crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[1]); - crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[1]); -} - static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) { struct ath12k_hal *hal = &ab->hal; @@ -1116,70 +584,6 @@ static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) return 0; } -static bool ath12k_hw_wcn7850_dp_rx_h_msdu_done(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.wcn7850.msdu_end.info14, - RX_MSDU_END_INFO14_MSDU_DONE); -} - -static bool ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13, - RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); -} - -static bool ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc) -{ - return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13, - RX_MSDU_END_INFO13_IP_CKSUM_FAIL); -} - -static bool ath12k_hw_wcn7850_dp_rx_h_is_decrypted(struct hal_rx_desc *desc) -{ - return (le32_get_bits(desc->u.wcn7850.msdu_end.info14, - RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == - RX_DESC_DECRYPT_STATUS_CODE_OK); -} - -static u32 ath12k_hw_wcn7850_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) -{ - u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info13); - u32 errmap = 0; - - if (info & RX_MSDU_END_INFO13_FCS_ERR) - errmap |= HAL_RX_MPDU_ERR_FCS; - - if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) - errmap |= HAL_RX_MPDU_ERR_DECRYPT; - - if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) - errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; - - if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) - errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; - - if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) - errmap |= HAL_RX_MPDU_ERR_OVERFLOW; - - if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) - errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; - - if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) - errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; - - return errmap; -} - -static u32 ath12k_hw_wcn7850_get_rx_desc_size(void) -{ - return sizeof(struct hal_rx_desc_wcn7850); -} - -static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) -{ - return 0; -} - const struct hal_rx_ops hal_rx_wcn7850_ops = { .rx_desc_get_first_msdu = ath12k_hw_wcn7850_rx_desc_get_first_msdu, .rx_desc_get_last_msdu = ath12k_hw_wcn7850_rx_desc_get_last_msdu, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c new file mode 100644 index 0000000000000..bd114e82d55be --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -0,0 +1,307 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#include "hal_desc.h" +#include "hal_qcn9274.h" + +bool ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu(struct hal_rx_desc *desc) +{ + return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, + RX_MSDU_END_INFO5_FIRST_MSDU); +} + +bool ath12k_hw_qcn9274_compact_rx_desc_get_last_msdu(struct hal_rx_desc *desc) +{ + return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, + RX_MSDU_END_INFO5_LAST_MSDU); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc) +{ + return le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, + RX_MSDU_END_INFO5_L3_HDR_PADDING); +} + +bool ath12k_hw_qcn9274_compact_rx_desc_encrypt_valid(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, + RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); +} + +u32 ath12k_hw_qcn9274_compact_rx_desc_get_encrypt_type(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info2, + RX_MPDU_START_INFO2_ENC_TYPE); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_decap_type(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, + RX_MSDU_END_INFO11_DECAP_FORMAT); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, + RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); +} + +bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, + RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); +} + +bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, + RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); +} + +u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, + RX_MPDU_START_INFO4_MPDU_SEQ_NUM); +} + +u16 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_len(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info10, + RX_MSDU_END_INFO10_MSDU_LENGTH); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, + RX_MSDU_END_INFO12_SGI); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, + RX_MSDU_END_INFO12_RATE_MCS); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, + RX_MSDU_END_INFO12_RECV_BW); +} + +u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_freq(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.phy_meta_data); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, + RX_MSDU_END_INFO12_PKT_TYPE); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_nss(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, + RX_MSDU_END_INFO12_MIMO_SS_BITMAP); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc) +{ + return le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, + RX_MSDU_END_INFO5_TID); +} + +u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.sw_peer_id); +} + +void ath12k_hw_qcn9274_compact_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc) +{ + fdesc->u.qcn9274_compact.msdu_end = ldesc->u.qcn9274_compact.msdu_end; +} + +u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.phy_ppdu_id); +} + +void ath12k_hw_qcn9274_compact_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) +{ + u32 info = __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.info10); + + info = u32_replace_bits(info, len, RX_MSDU_END_INFO10_MSDU_LENGTH); + desc->u.qcn9274_compact.msdu_end.info10 = __cpu_to_le32(info); +} + +u8 *ath12k_hw_qcn9274_compact_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) +{ + return &desc->u.qcn9274_compact.msdu_payload[0]; +} + +u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_offset(void) +{ + return offsetof(struct hal_rx_desc_qcn9274_compact, mpdu_start); +} + +u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_end_offset(void) +{ + return offsetof(struct hal_rx_desc_qcn9274_compact, msdu_end); +} + +bool ath12k_hw_qcn9274_compact_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.qcn9274_compact.mpdu_start.info4) & + RX_MPDU_START_INFO4_MAC_ADDR2_VALID; +} + +u8 *ath12k_hw_qcn9274_compact_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) +{ + return desc->u.qcn9274_compact.mpdu_start.addr2; +} + +bool ath12k_hw_qcn9274_compact_rx_desc_is_da_mcbc(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->u.qcn9274_compact.msdu_end.info5) & + RX_MSDU_END_INFO5_DA_IS_MCBC; +} + +bool ath12k_hw_qcn9274_compact_dp_rx_h_msdu_done(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14, + RX_MSDU_END_INFO14_MSDU_DONE); +} + +bool ath12k_hw_qcn9274_compact_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info13, + RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); +} + +bool ath12k_hw_qcn9274_compact_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info13, + RX_MSDU_END_INFO13_IP_CKSUM_FAIL); +} + +bool ath12k_hw_qcn9274_compact_dp_rx_h_is_decrypted(struct hal_rx_desc *desc) +{ + return (le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14, + RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == + RX_DESC_DECRYPT_STATUS_CODE_OK); +} + +u32 ath12k_hw_qcn9274_compact_get_rx_desc_size(void) +{ + return sizeof(struct hal_rx_desc_qcn9274_compact); +} + +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) +{ + return le64_get_bits(desc->u.qcn9274_compact.msdu_end.msdu_end_tag, + RX_MSDU_END_64_TLV_SRC_LINK_ID); +} + +u16 ath12k_hal_qcn9274_rx_mpdu_start_wmask_get(void) +{ + return QCN9274_MPDU_START_WMASK; +} + +u32 ath12k_hal_qcn9274_rx_msdu_end_wmask_get(void) +{ + return QCN9274_MSDU_END_WMASK; +} + +u32 ath12k_hw_qcn9274_compact_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) +{ + u32 info = __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.info13); + u32 errmap = 0; + + if (info & RX_MSDU_END_INFO13_FCS_ERR) + errmap |= HAL_RX_MPDU_ERR_FCS; + + if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) + errmap |= HAL_RX_MPDU_ERR_DECRYPT; + + if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) + errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; + + if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) + errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; + + if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) + errmap |= HAL_RX_MPDU_ERR_OVERFLOW; + + if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) + errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; + + if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) + errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; + + return errmap; +} + +void ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype) +{ + unsigned int key_id; + + switch (enctype) { + case HAL_ENCRYPT_TYPE_OPEN: + return; + case HAL_ENCRYPT_TYPE_TKIP_NO_MIC: + case HAL_ENCRYPT_TYPE_TKIP_MIC: + crypto_hdr[0] = + HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[0]); + crypto_hdr[1] = 0; + crypto_hdr[2] = + HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274_compact.mpdu_start.pn[0]); + break; + case HAL_ENCRYPT_TYPE_CCMP_128: + case HAL_ENCRYPT_TYPE_CCMP_256: + case HAL_ENCRYPT_TYPE_GCMP_128: + case HAL_ENCRYPT_TYPE_AES_GCMP_256: + crypto_hdr[0] = + HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274_compact.mpdu_start.pn[0]); + crypto_hdr[1] = + HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[0]); + crypto_hdr[2] = 0; + break; + case HAL_ENCRYPT_TYPE_WEP_40: + case HAL_ENCRYPT_TYPE_WEP_104: + case HAL_ENCRYPT_TYPE_WEP_128: + case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4: + case HAL_ENCRYPT_TYPE_WAPI: + return; + } + key_id = le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info5, + RX_MPDU_START_INFO5_KEY_ID); + crypto_hdr[3] = 0x20 | (key_id << 6); + crypto_hdr[4] = + HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.qcn9274_compact.mpdu_start.pn[0]); + crypto_hdr[5] = + HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.qcn9274_compact.mpdu_start.pn[0]); + crypto_hdr[6] = + HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274_compact.mpdu_start.pn[1]); + crypto_hdr[7] = + HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[1]); +} + +void ath12k_hw_qcn9274_compact_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr) +{ + hdr->frame_control = desc->u.qcn9274_compact.mpdu_start.frame_ctrl; + hdr->duration_id = desc->u.qcn9274_compact.mpdu_start.duration; + ether_addr_copy(hdr->addr1, desc->u.qcn9274_compact.mpdu_start.addr1); + ether_addr_copy(hdr->addr2, desc->u.qcn9274_compact.mpdu_start.addr2); + ether_addr_copy(hdr->addr3, desc->u.qcn9274_compact.mpdu_start.addr3); + if (__le32_to_cpu(desc->u.qcn9274_compact.mpdu_start.info4) & + RX_MPDU_START_INFO4_MAC_ADDR4_VALID) { + ether_addr_copy(hdr->addr4, desc->u.qcn9274_compact.mpdu_start.addr4); + } + hdr->seq_ctrl = desc->u.qcn9274_compact.mpdu_start.seq_ctrl; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h new file mode 100644 index 0000000000000..d066e5bc00dbc --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear*/ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_HAL_QCN9274_H +#define ATH12K_HAL_QCN9274_H + +#include +#include +#include "../hal.h" +#include "hal_rx.h" + +bool ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu(struct hal_rx_desc *desc); +bool ath12k_hw_qcn9274_compact_rx_desc_get_last_msdu(struct hal_rx_desc *desc); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc); +bool ath12k_hw_qcn9274_compact_rx_desc_encrypt_valid(struct hal_rx_desc *desc); +u32 ath12k_hw_qcn9274_compact_rx_desc_get_encrypt_type(struct hal_rx_desc *desc); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_decap_type(struct hal_rx_desc *desc); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc); +bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc); +bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc); +u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc); +u16 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_len(struct hal_rx_desc *desc); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc); +u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_freq(struct hal_rx_desc *desc); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_nss(struct hal_rx_desc *desc); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc); +u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc); +void ath12k_hw_qcn9274_compact_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc); +u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc); +void ath12k_hw_qcn9274_compact_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len); +u8 *ath12k_hw_qcn9274_compact_rx_desc_get_msdu_payload(struct hal_rx_desc *desc); +u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_offset(void); +u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_end_offset(void); +bool ath12k_hw_qcn9274_compact_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc); +u8 *ath12k_hw_qcn9274_compact_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc); +bool ath12k_hw_qcn9274_compact_rx_desc_is_da_mcbc(struct hal_rx_desc *desc); +bool ath12k_hw_qcn9274_compact_dp_rx_h_msdu_done(struct hal_rx_desc *desc); +bool ath12k_hw_qcn9274_compact_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc); +bool ath12k_hw_qcn9274_compact_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc); +bool ath12k_hw_qcn9274_compact_dp_rx_h_is_decrypted(struct hal_rx_desc *desc); +u32 ath12k_hw_qcn9274_compact_get_rx_desc_size(void); +u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc); +u16 ath12k_hal_qcn9274_rx_mpdu_start_wmask_get(void); +u32 ath12k_hal_qcn9274_rx_msdu_end_wmask_get(void); +u32 ath12k_hw_qcn9274_compact_dp_rx_h_mpdu_err(struct hal_rx_desc *desc); +void ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype); +void ath12k_hw_qcn9274_compact_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr); +#endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c new file mode 100644 index 0000000000000..1e23665aabc91 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -0,0 +1,302 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "hal_desc.h" +#include "hal_wcn7850.h" + +bool ath12k_hw_wcn7850_rx_desc_get_first_msdu(struct hal_rx_desc *desc) +{ + return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5, + RX_MSDU_END_INFO5_FIRST_MSDU); +} + +bool ath12k_hw_wcn7850_rx_desc_get_last_msdu(struct hal_rx_desc *desc) +{ + return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5, + RX_MSDU_END_INFO5_LAST_MSDU); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc) +{ + return le16_get_bits(desc->u.wcn7850.msdu_end.info5, + RX_MSDU_END_INFO5_L3_HDR_PADDING); +} + +bool ath12k_hw_wcn7850_rx_desc_encrypt_valid(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, + RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); +} + +u32 ath12k_hw_wcn7850_rx_desc_get_encrypt_type(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.mpdu_start.info2, + RX_MPDU_START_INFO2_ENC_TYPE); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_decap_type(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.msdu_end.info11, + RX_MSDU_END_INFO11_DECAP_FORMAT); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.msdu_end.info11, + RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); +} + +bool ath12k_hw_wcn7850_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, + RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); +} + +bool ath12k_hw_wcn7850_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, + RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); +} + +u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.mpdu_start.info4, + RX_MPDU_START_INFO4_MPDU_SEQ_NUM); +} + +u16 ath12k_hw_wcn7850_rx_desc_get_msdu_len(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.msdu_end.info10, + RX_MSDU_END_INFO10_MSDU_LENGTH); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.msdu_end.info12, + RX_MSDU_END_INFO12_SGI); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.msdu_end.info12, + RX_MSDU_END_INFO12_RATE_MCS); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.msdu_end.info12, + RX_MSDU_END_INFO12_RECV_BW); +} + +u32 ath12k_hw_wcn7850_rx_desc_get_msdu_freq(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.wcn7850.msdu_end.phy_meta_data); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.msdu_end.info12, + RX_MSDU_END_INFO12_PKT_TYPE); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_nss(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.msdu_end.info12, + RX_MSDU_END_INFO12_MIMO_SS_BITMAP); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.wcn7850.mpdu_start.info2, + RX_MPDU_START_INFO2_TID); +} + +u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->u.wcn7850.mpdu_start.sw_peer_id); +} + +void ath12k_hw_wcn7850_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc) +{ + memcpy(&fdesc->u.wcn7850.msdu_end, &ldesc->u.wcn7850.msdu_end, + sizeof(struct rx_msdu_end_qcn9274)); +} + +u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag(struct hal_rx_desc *desc) +{ + return le64_get_bits(desc->u.wcn7850.mpdu_start_tag, + HAL_TLV_HDR_TAG); +} + +u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->u.wcn7850.mpdu_start.phy_ppdu_id); +} + +void ath12k_hw_wcn7850_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) +{ + u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info10); + + info &= ~RX_MSDU_END_INFO10_MSDU_LENGTH; + info |= u32_encode_bits(len, RX_MSDU_END_INFO10_MSDU_LENGTH); + + desc->u.wcn7850.msdu_end.info10 = __cpu_to_le32(info); +} + +u8 *ath12k_hw_wcn7850_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) +{ + return &desc->u.wcn7850.msdu_payload[0]; +} + +u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_offset(void) +{ + return offsetof(struct hal_rx_desc_wcn7850, mpdu_start_tag); +} + +u32 ath12k_hw_wcn7850_rx_desc_get_msdu_end_offset(void) +{ + return offsetof(struct hal_rx_desc_wcn7850, msdu_end_tag); +} + +bool ath12k_hw_wcn7850_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.wcn7850.mpdu_start.info4) & + RX_MPDU_START_INFO4_MAC_ADDR2_VALID; +} + +u8 *ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) +{ + return desc->u.wcn7850.mpdu_start.addr2; +} + +bool ath12k_hw_wcn7850_rx_desc_is_da_mcbc(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.wcn7850.msdu_end.info13) & + RX_MSDU_END_INFO13_MCAST_BCAST; +} + +bool ath12k_hw_wcn7850_dp_rx_h_msdu_done(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.wcn7850.msdu_end.info14, + RX_MSDU_END_INFO14_MSDU_DONE); +} + +bool ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13, + RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); +} + +bool ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13, + RX_MSDU_END_INFO13_IP_CKSUM_FAIL); +} + +bool ath12k_hw_wcn7850_dp_rx_h_is_decrypted(struct hal_rx_desc *desc) +{ + return (le32_get_bits(desc->u.wcn7850.msdu_end.info14, + RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == + RX_DESC_DECRYPT_STATUS_CODE_OK); +} + +u32 ath12k_hw_wcn7850_get_rx_desc_size(void) +{ + return sizeof(struct hal_rx_desc_wcn7850); +} + +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) +{ + return 0; +} + +u32 ath12k_hw_wcn7850_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) +{ + u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info13); + u32 errmap = 0; + + if (info & RX_MSDU_END_INFO13_FCS_ERR) + errmap |= HAL_RX_MPDU_ERR_FCS; + + if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) + errmap |= HAL_RX_MPDU_ERR_DECRYPT; + + if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) + errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; + + if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) + errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; + + if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) + errmap |= HAL_RX_MPDU_ERR_OVERFLOW; + + if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) + errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; + + if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) + errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; + + return errmap; +} + +void ath12k_hw_wcn7850_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype) +{ + unsigned int key_id; + + switch (enctype) { + case HAL_ENCRYPT_TYPE_OPEN: + return; + case HAL_ENCRYPT_TYPE_TKIP_NO_MIC: + case HAL_ENCRYPT_TYPE_TKIP_MIC: + crypto_hdr[0] = + HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[0]); + crypto_hdr[1] = 0; + crypto_hdr[2] = + HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[0]); + break; + case HAL_ENCRYPT_TYPE_CCMP_128: + case HAL_ENCRYPT_TYPE_CCMP_256: + case HAL_ENCRYPT_TYPE_GCMP_128: + case HAL_ENCRYPT_TYPE_AES_GCMP_256: + crypto_hdr[0] = + HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[0]); + crypto_hdr[1] = + HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[0]); + crypto_hdr[2] = 0; + break; + case HAL_ENCRYPT_TYPE_WEP_40: + case HAL_ENCRYPT_TYPE_WEP_104: + case HAL_ENCRYPT_TYPE_WEP_128: + case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4: + case HAL_ENCRYPT_TYPE_WAPI: + return; + } + key_id = u32_get_bits(__le32_to_cpu(desc->u.wcn7850.mpdu_start.info5), + RX_MPDU_START_INFO5_KEY_ID); + crypto_hdr[3] = 0x20 | (key_id << 6); + crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.wcn7850.mpdu_start.pn[0]); + crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.wcn7850.mpdu_start.pn[0]); + crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[1]); + crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[1]); +} + +void ath12k_hw_wcn7850_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr) +{ + hdr->frame_control = desc->u.wcn7850.mpdu_start.frame_ctrl; + hdr->duration_id = desc->u.wcn7850.mpdu_start.duration; + ether_addr_copy(hdr->addr1, desc->u.wcn7850.mpdu_start.addr1); + ether_addr_copy(hdr->addr2, desc->u.wcn7850.mpdu_start.addr2); + ether_addr_copy(hdr->addr3, desc->u.wcn7850.mpdu_start.addr3); + if (__le32_to_cpu(desc->u.wcn7850.mpdu_start.info4) & + RX_MPDU_START_INFO4_MAC_ADDR4_VALID) { + ether_addr_copy(hdr->addr4, desc->u.wcn7850.mpdu_start.addr4); + } + hdr->seq_ctrl = desc->u.wcn7850.mpdu_start.seq_ctrl; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h new file mode 100644 index 0000000000000..a5395a0053834 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_HAL_WCN7850_H +#define ATH12K_HAL_WCN7850_H + +#include "../hal.h" +#include "hal_rx.h" + +bool ath12k_hw_wcn7850_rx_desc_get_first_msdu(struct hal_rx_desc *desc); +bool ath12k_hw_wcn7850_rx_desc_get_last_msdu(struct hal_rx_desc *desc); +u8 ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc); +bool ath12k_hw_wcn7850_rx_desc_encrypt_valid(struct hal_rx_desc *desc); +u32 ath12k_hw_wcn7850_rx_desc_get_encrypt_type(struct hal_rx_desc *desc); +u8 ath12k_hw_wcn7850_rx_desc_get_decap_type(struct hal_rx_desc *desc); +u8 ath12k_hw_wcn7850_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc); +bool ath12k_hw_wcn7850_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc); +bool ath12k_hw_wcn7850_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc); +u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc); +u16 ath12k_hw_wcn7850_rx_desc_get_msdu_len(struct hal_rx_desc *desc); +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc); +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc); +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc); +u32 ath12k_hw_wcn7850_rx_desc_get_msdu_freq(struct hal_rx_desc *desc); +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc); +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_nss(struct hal_rx_desc *desc); +u8 ath12k_hw_wcn7850_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc); +u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc); +void ath12k_hw_wcn7850_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc); +u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag(struct hal_rx_desc *desc); +u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc); +void ath12k_hw_wcn7850_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len); +u8 *ath12k_hw_wcn7850_rx_desc_get_msdu_payload(struct hal_rx_desc *desc); +u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_offset(void); +u32 ath12k_hw_wcn7850_rx_desc_get_msdu_end_offset(void); +bool ath12k_hw_wcn7850_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc); +u8 *ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc); +bool ath12k_hw_wcn7850_rx_desc_is_da_mcbc(struct hal_rx_desc *desc); +bool ath12k_hw_wcn7850_dp_rx_h_msdu_done(struct hal_rx_desc *desc); +bool ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc); +bool ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc); +bool ath12k_hw_wcn7850_dp_rx_h_is_decrypted(struct hal_rx_desc *desc); +u32 ath12k_hw_wcn7850_get_rx_desc_size(void); +u8 ath12k_hw_wcn7850_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc); +u32 ath12k_hw_wcn7850_dp_rx_h_mpdu_err(struct hal_rx_desc *desc); +void ath12k_hw_wcn7850_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype); +void ath12k_hw_wcn7850_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr); +#endif From 18714f76ba25a9163836d57b6b8cbb36110a86a0 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Wed, 10 Sep 2025 23:44:09 +0530 Subject: [PATCH 036/140] wifi: ath12k: unify HAL ops naming across chips Rename HAL ops to follow a consistent hal ops format: ath12k_hal_rx_xxxx_. Remove "compact" references as non-compacts variant is no longer used. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250910181414.2062280-4-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.c | 154 +++++++++--------- .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 86 +++++----- .../wireless/ath/ath12k/wifi7/hal_qcn9274.h | 86 +++++----- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 84 +++++----- .../wireless/ath/ath12k/wifi7/hal_wcn7850.h | 84 +++++----- 5 files changed, 247 insertions(+), 247 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 77024c99d0bf0..1fba023d0859d 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -407,56 +407,56 @@ static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) } const struct hal_rx_ops hal_rx_qcn9274_compact_ops = { - .rx_desc_get_first_msdu = ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu, - .rx_desc_get_last_msdu = ath12k_hw_qcn9274_compact_rx_desc_get_last_msdu, - .rx_desc_get_l3_pad_bytes = ath12k_hw_qcn9274_compact_rx_desc_get_l3_pad_bytes, - .rx_desc_encrypt_valid = ath12k_hw_qcn9274_compact_rx_desc_encrypt_valid, - .rx_desc_get_encrypt_type = ath12k_hw_qcn9274_compact_rx_desc_get_encrypt_type, - .rx_desc_get_decap_type = ath12k_hw_qcn9274_compact_rx_desc_get_decap_type, - .rx_desc_get_mesh_ctl = ath12k_hw_qcn9274_compact_rx_desc_get_mesh_ctl, + .rx_desc_get_first_msdu = ath12k_hal_rx_desc_get_first_msdu_qcn9274, + .rx_desc_get_last_msdu = ath12k_hal_rx_desc_get_last_msdu_qcn9274, + .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274, + .rx_desc_encrypt_valid = ath12k_hal_rx_desc_encrypt_valid_qcn9274, + .rx_desc_get_encrypt_type = ath12k_hal_rx_desc_get_encrypt_type_qcn9274, + .rx_desc_get_decap_type = ath12k_hal_rx_desc_get_decap_type_qcn9274, + .rx_desc_get_mesh_ctl = ath12k_hal_rx_desc_get_mesh_ctl_qcn9274, .rx_desc_get_mpdu_seq_ctl_vld = - ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_seq_ctl_vld, - .rx_desc_get_mpdu_fc_valid = ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_fc_valid, + ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcn9274, + .rx_desc_get_mpdu_fc_valid = ath12k_hal_rx_desc_get_mpdu_fc_valid_qcn9274, .rx_desc_get_mpdu_start_seq_no = - ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_seq_no, - .rx_desc_get_msdu_len = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_len, - .rx_desc_get_msdu_sgi = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_sgi, - .rx_desc_get_msdu_rate_mcs = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rate_mcs, - .rx_desc_get_msdu_rx_bw = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rx_bw, - .rx_desc_get_msdu_freq = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_freq, - .rx_desc_get_msdu_pkt_type = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_pkt_type, - .rx_desc_get_msdu_nss = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_nss, - .rx_desc_get_mpdu_tid = ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_tid, - .rx_desc_get_mpdu_peer_id = ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_peer_id, - .rx_desc_copy_end_tlv = ath12k_hw_qcn9274_compact_rx_desc_copy_end_tlv, - .rx_desc_get_mpdu_ppdu_id = ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_ppdu_id, - .rx_desc_set_msdu_len = ath12k_hw_qcn9274_compact_rx_desc_set_msdu_len, - .rx_desc_get_msdu_payload = ath12k_hw_qcn9274_compact_rx_desc_get_msdu_payload, + ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcn9274, + .rx_desc_get_msdu_len = ath12k_hal_rx_desc_get_msdu_len_qcn9274, + .rx_desc_get_msdu_sgi = ath12k_hal_rx_desc_get_msdu_sgi_qcn9274, + .rx_desc_get_msdu_rate_mcs = ath12k_hal_rx_desc_get_msdu_rate_mcs_qcn9274, + .rx_desc_get_msdu_rx_bw = ath12k_hal_rx_desc_get_msdu_rx_bw_qcn9274, + .rx_desc_get_msdu_freq = ath12k_hal_rx_desc_get_msdu_freq_qcn9274, + .rx_desc_get_msdu_pkt_type = ath12k_hal_rx_desc_get_msdu_pkt_type_qcn9274, + .rx_desc_get_msdu_nss = ath12k_hal_rx_desc_get_msdu_nss_qcn9274, + .rx_desc_get_mpdu_tid = ath12k_hal_rx_desc_get_mpdu_tid_qcn9274, + .rx_desc_get_mpdu_peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_qcn9274, + .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcn9274, + .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, + .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcn9274, + .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, .rx_desc_get_mpdu_start_offset = - ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_offset, + ath12k_hal_rx_desc_get_mpdu_start_offset_qcn9274, .rx_desc_get_msdu_end_offset = - ath12k_hw_qcn9274_compact_rx_desc_get_msdu_end_offset, - .rx_desc_mac_addr2_valid = ath12k_hw_qcn9274_compact_rx_desc_mac_addr2_valid, - .rx_desc_mpdu_start_addr2 = ath12k_hw_qcn9274_compact_rx_desc_mpdu_start_addr2, - .rx_desc_is_da_mcbc = ath12k_hw_qcn9274_compact_rx_desc_is_da_mcbc, - .rx_desc_get_dot11_hdr = ath12k_hw_qcn9274_compact_rx_desc_get_dot11_hdr, - .rx_desc_get_crypto_header = ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr, - .dp_rx_h_msdu_done = ath12k_hw_qcn9274_compact_dp_rx_h_msdu_done, - .dp_rx_h_l4_cksum_fail = ath12k_hw_qcn9274_compact_dp_rx_h_l4_cksum_fail, - .dp_rx_h_ip_cksum_fail = ath12k_hw_qcn9274_compact_dp_rx_h_ip_cksum_fail, - .dp_rx_h_is_decrypted = ath12k_hw_qcn9274_compact_dp_rx_h_is_decrypted, - .dp_rx_h_mpdu_err = ath12k_hw_qcn9274_compact_dp_rx_h_mpdu_err, - .rx_desc_get_desc_size = ath12k_hw_qcn9274_compact_get_rx_desc_size, + ath12k_hal_rx_desc_get_msdu_end_offset_qcn9274, + .rx_desc_mac_addr2_valid = ath12k_hal_rx_desc_mac_addr2_valid_qcn9274, + .rx_desc_mpdu_start_addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_qcn9274, + .rx_desc_is_da_mcbc = ath12k_hal_rx_desc_is_da_mcbc_qcn9274, + .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_qcn9274, + .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcn9274, + .dp_rx_h_msdu_done = ath12k_hal_rx_h_msdu_done_qcn9274, + .dp_rx_h_l4_cksum_fail = ath12k_hal_rx_h_l4_cksum_fail_qcn9274, + .dp_rx_h_ip_cksum_fail = ath12k_hal_rx_h_ip_cksum_fail_qcn9274, + .dp_rx_h_is_decrypted = ath12k_hal_rx_h_is_decrypted_qcn9274, + .dp_rx_h_mpdu_err = ath12k_hal_rx_h_mpdu_err_qcn9274, + .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_qcn9274, .rx_desc_get_msdu_src_link_id = - ath12k_hw_qcn9274_compact_rx_desc_get_msdu_src_link, + ath12k_hal_rx_desc_get_msdu_src_link_qcn9274, }; EXPORT_SYMBOL(hal_rx_qcn9274_compact_ops); const struct hal_ops hal_qcn9274_ops = { .create_srng_config = ath12k_hal_srng_create_config_qcn9274, .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, - .rxdma_ring_wmask_rx_mpdu_start = ath12k_hal_qcn9274_rx_mpdu_start_wmask_get, - .rxdma_ring_wmask_rx_msdu_end = ath12k_hal_qcn9274_rx_msdu_end_wmask_get, + .rxdma_ring_wmask_rx_mpdu_start = ath12k_hal_rx_mpdu_start_wmask_get_qcn9274, + .rxdma_ring_wmask_rx_msdu_end = ath12k_hal_rx_msdu_end_wmask_get_qcn9274, }; EXPORT_SYMBOL(hal_qcn9274_ops); @@ -585,44 +585,44 @@ static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) } const struct hal_rx_ops hal_rx_wcn7850_ops = { - .rx_desc_get_first_msdu = ath12k_hw_wcn7850_rx_desc_get_first_msdu, - .rx_desc_get_last_msdu = ath12k_hw_wcn7850_rx_desc_get_last_msdu, - .rx_desc_get_l3_pad_bytes = ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes, - .rx_desc_encrypt_valid = ath12k_hw_wcn7850_rx_desc_encrypt_valid, - .rx_desc_get_encrypt_type = ath12k_hw_wcn7850_rx_desc_get_encrypt_type, - .rx_desc_get_decap_type = ath12k_hw_wcn7850_rx_desc_get_decap_type, - .rx_desc_get_mesh_ctl = ath12k_hw_wcn7850_rx_desc_get_mesh_ctl, - .rx_desc_get_mpdu_seq_ctl_vld = ath12k_hw_wcn7850_rx_desc_get_mpdu_seq_ctl_vld, - .rx_desc_get_mpdu_fc_valid = ath12k_hw_wcn7850_rx_desc_get_mpdu_fc_valid, - .rx_desc_get_mpdu_start_seq_no = ath12k_hw_wcn7850_rx_desc_get_mpdu_start_seq_no, - .rx_desc_get_msdu_len = ath12k_hw_wcn7850_rx_desc_get_msdu_len, - .rx_desc_get_msdu_sgi = ath12k_hw_wcn7850_rx_desc_get_msdu_sgi, - .rx_desc_get_msdu_rate_mcs = ath12k_hw_wcn7850_rx_desc_get_msdu_rate_mcs, - .rx_desc_get_msdu_rx_bw = ath12k_hw_wcn7850_rx_desc_get_msdu_rx_bw, - .rx_desc_get_msdu_freq = ath12k_hw_wcn7850_rx_desc_get_msdu_freq, - .rx_desc_get_msdu_pkt_type = ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type, - .rx_desc_get_msdu_nss = ath12k_hw_wcn7850_rx_desc_get_msdu_nss, - .rx_desc_get_mpdu_tid = ath12k_hw_wcn7850_rx_desc_get_mpdu_tid, - .rx_desc_get_mpdu_peer_id = ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id, - .rx_desc_copy_end_tlv = ath12k_hw_wcn7850_rx_desc_copy_end_tlv, - .rx_desc_get_mpdu_start_tag = ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag, - .rx_desc_get_mpdu_ppdu_id = ath12k_hw_wcn7850_rx_desc_get_mpdu_ppdu_id, - .rx_desc_set_msdu_len = ath12k_hw_wcn7850_rx_desc_set_msdu_len, - .rx_desc_get_msdu_payload = ath12k_hw_wcn7850_rx_desc_get_msdu_payload, - .rx_desc_get_mpdu_start_offset = ath12k_hw_wcn7850_rx_desc_get_mpdu_start_offset, - .rx_desc_get_msdu_end_offset = ath12k_hw_wcn7850_rx_desc_get_msdu_end_offset, - .rx_desc_mac_addr2_valid = ath12k_hw_wcn7850_rx_desc_mac_addr2_valid, - .rx_desc_mpdu_start_addr2 = ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2, - .rx_desc_is_da_mcbc = ath12k_hw_wcn7850_rx_desc_is_da_mcbc, - .rx_desc_get_dot11_hdr = ath12k_hw_wcn7850_rx_desc_get_dot11_hdr, - .rx_desc_get_crypto_header = ath12k_hw_wcn7850_rx_desc_get_crypto_hdr, - .dp_rx_h_msdu_done = ath12k_hw_wcn7850_dp_rx_h_msdu_done, - .dp_rx_h_l4_cksum_fail = ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail, - .dp_rx_h_ip_cksum_fail = ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail, - .dp_rx_h_is_decrypted = ath12k_hw_wcn7850_dp_rx_h_is_decrypted, - .dp_rx_h_mpdu_err = ath12k_hw_wcn7850_dp_rx_h_mpdu_err, - .rx_desc_get_desc_size = ath12k_hw_wcn7850_get_rx_desc_size, - .rx_desc_get_msdu_src_link_id = ath12k_hw_wcn7850_rx_desc_get_msdu_src_link, + .rx_desc_get_first_msdu = ath12k_hal_rx_desc_get_first_msdu_wcn7850, + .rx_desc_get_last_msdu = ath12k_hal_rx_desc_get_last_msdu_wcn7850, + .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850, + .rx_desc_encrypt_valid = ath12k_hal_rx_desc_encrypt_valid_wcn7850, + .rx_desc_get_encrypt_type = ath12k_hal_rx_desc_get_encrypt_type_wcn7850, + .rx_desc_get_decap_type = ath12k_hal_rx_desc_get_decap_type_wcn7850, + .rx_desc_get_mesh_ctl = ath12k_hal_rx_desc_get_mesh_ctl_wcn7850, + .rx_desc_get_mpdu_seq_ctl_vld = ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_wcn7850, + .rx_desc_get_mpdu_fc_valid = ath12k_hal_rx_desc_get_mpdu_fc_valid_wcn7850, + .rx_desc_get_mpdu_start_seq_no = ath12k_hal_rx_desc_get_mpdu_start_seq_no_wcn7850, + .rx_desc_get_msdu_len = ath12k_hal_rx_desc_get_msdu_len_wcn7850, + .rx_desc_get_msdu_sgi = ath12k_hal_rx_desc_get_msdu_sgi_wcn7850, + .rx_desc_get_msdu_rate_mcs = ath12k_hal_rx_desc_get_msdu_rate_mcs_wcn7850, + .rx_desc_get_msdu_rx_bw = ath12k_hal_rx_desc_get_msdu_rx_bw_wcn7850, + .rx_desc_get_msdu_freq = ath12k_hal_rx_desc_get_msdu_freq_wcn7850, + .rx_desc_get_msdu_pkt_type = ath12k_hal_rx_desc_get_msdu_pkt_type_wcn7850, + .rx_desc_get_msdu_nss = ath12k_hal_rx_desc_get_msdu_nss_wcn7850, + .rx_desc_get_mpdu_tid = ath12k_hal_rx_desc_get_mpdu_tid_wcn7850, + .rx_desc_get_mpdu_peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_wcn7850, + .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_wcn7850, + .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, + .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, + .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_wcn7850, + .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, + .rx_desc_get_mpdu_start_offset = ath12k_hal_rx_desc_get_mpdu_start_offset_wcn7850, + .rx_desc_get_msdu_end_offset = ath12k_hal_rx_desc_get_msdu_end_offset_wcn7850, + .rx_desc_mac_addr2_valid = ath12k_hal_rx_desc_mac_addr2_valid_wcn7850, + .rx_desc_mpdu_start_addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_wcn7850, + .rx_desc_is_da_mcbc = ath12k_hal_rx_desc_is_da_mcbc_wcn7850, + .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_wcn7850, + .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_wcn7850, + .dp_rx_h_msdu_done = ath12k_hal_rx_h_msdu_done_wcn7850, + .dp_rx_h_l4_cksum_fail = ath12k_hal_rx_h_l4_cksum_fail_wcn7850, + .dp_rx_h_ip_cksum_fail = ath12k_hal_rx_h_ip_cksum_fail_wcn7850, + .dp_rx_h_is_decrypted = ath12k_hal_rx_h_is_decrypted_wcn7850, + .dp_rx_h_mpdu_err = ath12k_hal_rx_h_mpdu_err_wcn7850, + .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_wcn7850, + .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_wcn7850, }; EXPORT_SYMBOL(hal_rx_wcn7850_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index bd114e82d55be..bf09a40c91d9d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -6,130 +6,130 @@ #include "hal_desc.h" #include "hal_qcn9274.h" -bool ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_get_first_msdu_qcn9274(struct hal_rx_desc *desc) { return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, RX_MSDU_END_INFO5_FIRST_MSDU); } -bool ath12k_hw_qcn9274_compact_rx_desc_get_last_msdu(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_get_last_msdu_qcn9274(struct hal_rx_desc *desc) { return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, RX_MSDU_END_INFO5_LAST_MSDU); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274(struct hal_rx_desc *desc) { return le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, RX_MSDU_END_INFO5_L3_HDR_PADDING); } -bool ath12k_hw_qcn9274_compact_rx_desc_encrypt_valid(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_encrypt_valid_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); } -u32 ath12k_hw_qcn9274_compact_rx_desc_get_encrypt_type(struct hal_rx_desc *desc) +u32 ath12k_hal_rx_desc_get_encrypt_type_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info2, RX_MPDU_START_INFO2_ENC_TYPE); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_decap_type(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_decap_type_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, RX_MSDU_END_INFO11_DECAP_FORMAT); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_mesh_ctl_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); } -bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); } -bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_get_mpdu_fc_valid_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); } -u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc) +u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_SEQ_NUM); } -u16 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_len(struct hal_rx_desc *desc) +u16 ath12k_hal_rx_desc_get_msdu_len_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info10, RX_MSDU_END_INFO10_MSDU_LENGTH); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_sgi_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_SGI); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_RATE_MCS); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_rx_bw_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_RECV_BW); } -u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_freq(struct hal_rx_desc *desc) +u32 ath12k_hal_rx_desc_get_msdu_freq_qcn9274(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.phy_meta_data); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_pkt_type_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_PKT_TYPE); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_nss(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_nss_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_MIMO_SS_BITMAP); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_mpdu_tid_qcn9274(struct hal_rx_desc *desc) { return le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, RX_MSDU_END_INFO5_TID); } -u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc) +u16 ath12k_hal_rx_desc_get_mpdu_peer_id_qcn9274(struct hal_rx_desc *desc) { return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.sw_peer_id); } -void ath12k_hw_qcn9274_compact_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, - struct hal_rx_desc *ldesc) +void ath12k_hal_rx_desc_copy_end_tlv_qcn9274(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc) { fdesc->u.qcn9274_compact.msdu_end = ldesc->u.qcn9274_compact.msdu_end; } -u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc) +u32 ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274(struct hal_rx_desc *desc) { return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.phy_ppdu_id); } -void ath12k_hw_qcn9274_compact_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) +void ath12k_hal_rx_desc_set_msdu_len_qcn9274(struct hal_rx_desc *desc, u16 len) { u32 info = __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.info10); @@ -137,85 +137,85 @@ void ath12k_hw_qcn9274_compact_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u1 desc->u.qcn9274_compact.msdu_end.info10 = __cpu_to_le32(info); } -u8 *ath12k_hw_qcn9274_compact_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) +u8 *ath12k_hal_rx_desc_get_msdu_payload_qcn9274(struct hal_rx_desc *desc) { return &desc->u.qcn9274_compact.msdu_payload[0]; } -u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_offset(void) +u32 ath12k_hal_rx_desc_get_mpdu_start_offset_qcn9274(void) { return offsetof(struct hal_rx_desc_qcn9274_compact, mpdu_start); } -u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_end_offset(void) +u32 ath12k_hal_rx_desc_get_msdu_end_offset_qcn9274(void) { return offsetof(struct hal_rx_desc_qcn9274_compact, msdu_end); } -bool ath12k_hw_qcn9274_compact_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_mac_addr2_valid_qcn9274(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.qcn9274_compact.mpdu_start.info4) & RX_MPDU_START_INFO4_MAC_ADDR2_VALID; } -u8 *ath12k_hw_qcn9274_compact_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) +u8 *ath12k_hal_rx_desc_mpdu_start_addr2_qcn9274(struct hal_rx_desc *desc) { return desc->u.qcn9274_compact.mpdu_start.addr2; } -bool ath12k_hw_qcn9274_compact_rx_desc_is_da_mcbc(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_is_da_mcbc_qcn9274(struct hal_rx_desc *desc) { return __le16_to_cpu(desc->u.qcn9274_compact.msdu_end.info5) & RX_MSDU_END_INFO5_DA_IS_MCBC; } -bool ath12k_hw_qcn9274_compact_dp_rx_h_msdu_done(struct hal_rx_desc *desc) +bool ath12k_hal_rx_h_msdu_done_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14, RX_MSDU_END_INFO14_MSDU_DONE); } -bool ath12k_hw_qcn9274_compact_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc) +bool ath12k_hal_rx_h_l4_cksum_fail_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info13, RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); } -bool ath12k_hw_qcn9274_compact_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc) +bool ath12k_hal_rx_h_ip_cksum_fail_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info13, RX_MSDU_END_INFO13_IP_CKSUM_FAIL); } -bool ath12k_hw_qcn9274_compact_dp_rx_h_is_decrypted(struct hal_rx_desc *desc) +bool ath12k_hal_rx_h_is_decrypted_qcn9274(struct hal_rx_desc *desc) { return (le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14, RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == RX_DESC_DECRYPT_STATUS_CODE_OK); } -u32 ath12k_hw_qcn9274_compact_get_rx_desc_size(void) +u32 ath12k_hal_get_rx_desc_size_qcn9274(void) { return sizeof(struct hal_rx_desc_qcn9274_compact); } -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_src_link_qcn9274(struct hal_rx_desc *desc) { return le64_get_bits(desc->u.qcn9274_compact.msdu_end.msdu_end_tag, RX_MSDU_END_64_TLV_SRC_LINK_ID); } -u16 ath12k_hal_qcn9274_rx_mpdu_start_wmask_get(void) +u16 ath12k_hal_rx_mpdu_start_wmask_get_qcn9274(void) { return QCN9274_MPDU_START_WMASK; } -u32 ath12k_hal_qcn9274_rx_msdu_end_wmask_get(void) +u32 ath12k_hal_rx_msdu_end_wmask_get_qcn9274(void) { return QCN9274_MSDU_END_WMASK; } -u32 ath12k_hw_qcn9274_compact_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) +u32 ath12k_hal_rx_h_mpdu_err_qcn9274(struct hal_rx_desc *desc) { u32 info = __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.info13); u32 errmap = 0; @@ -244,9 +244,9 @@ u32 ath12k_hw_qcn9274_compact_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) return errmap; } -void ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, - u8 *crypto_hdr, - enum hal_encrypt_type enctype) +void ath12k_hal_rx_desc_get_crypto_hdr_qcn9274(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype) { unsigned int key_id; @@ -291,8 +291,8 @@ void ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274_compact.mpdu_start.pn[1]); } -void ath12k_hw_qcn9274_compact_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, - struct ieee80211_hdr *hdr) +void ath12k_hal_rx_desc_get_dot11_hdr_qcn9274(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr) { hdr->frame_control = desc->u.qcn9274_compact.mpdu_start.frame_ctrl; hdr->duration_id = desc->u.qcn9274_compact.mpdu_start.duration; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h index d066e5bc00dbc..562156bbd726d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h @@ -12,47 +12,47 @@ #include "../hal.h" #include "hal_rx.h" -bool ath12k_hw_qcn9274_compact_rx_desc_get_first_msdu(struct hal_rx_desc *desc); -bool ath12k_hw_qcn9274_compact_rx_desc_get_last_msdu(struct hal_rx_desc *desc); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc); -bool ath12k_hw_qcn9274_compact_rx_desc_encrypt_valid(struct hal_rx_desc *desc); -u32 ath12k_hw_qcn9274_compact_rx_desc_get_encrypt_type(struct hal_rx_desc *desc); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_decap_type(struct hal_rx_desc *desc); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc); -bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc); -bool ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc); -u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc); -u16 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_len(struct hal_rx_desc *desc); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc); -u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_freq(struct hal_rx_desc *desc); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_nss(struct hal_rx_desc *desc); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc); -u16 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc); -void ath12k_hw_qcn9274_compact_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, - struct hal_rx_desc *ldesc); -u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc); -void ath12k_hw_qcn9274_compact_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len); -u8 *ath12k_hw_qcn9274_compact_rx_desc_get_msdu_payload(struct hal_rx_desc *desc); -u32 ath12k_hw_qcn9274_compact_rx_desc_get_mpdu_start_offset(void); -u32 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_end_offset(void); -bool ath12k_hw_qcn9274_compact_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc); -u8 *ath12k_hw_qcn9274_compact_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc); -bool ath12k_hw_qcn9274_compact_rx_desc_is_da_mcbc(struct hal_rx_desc *desc); -bool ath12k_hw_qcn9274_compact_dp_rx_h_msdu_done(struct hal_rx_desc *desc); -bool ath12k_hw_qcn9274_compact_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc); -bool ath12k_hw_qcn9274_compact_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc); -bool ath12k_hw_qcn9274_compact_dp_rx_h_is_decrypted(struct hal_rx_desc *desc); -u32 ath12k_hw_qcn9274_compact_get_rx_desc_size(void); -u8 ath12k_hw_qcn9274_compact_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc); -u16 ath12k_hal_qcn9274_rx_mpdu_start_wmask_get(void); -u32 ath12k_hal_qcn9274_rx_msdu_end_wmask_get(void); -u32 ath12k_hw_qcn9274_compact_dp_rx_h_mpdu_err(struct hal_rx_desc *desc); -void ath12k_hw_qcn9274_compact_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, - u8 *crypto_hdr, - enum hal_encrypt_type enctype); -void ath12k_hw_qcn9274_compact_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, - struct ieee80211_hdr *hdr); +bool ath12k_hal_rx_desc_get_first_msdu_qcn9274(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_get_last_msdu_qcn9274(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_encrypt_valid_qcn9274(struct hal_rx_desc *desc); +u32 ath12k_hal_rx_desc_get_encrypt_type_qcn9274(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_decap_type_qcn9274(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_mesh_ctl_qcn9274(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcn9274(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_get_mpdu_fc_valid_qcn9274(struct hal_rx_desc *desc); +u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcn9274(struct hal_rx_desc *desc); +u16 ath12k_hal_rx_desc_get_msdu_len_qcn9274(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_sgi_qcn9274(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_qcn9274(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_rx_bw_qcn9274(struct hal_rx_desc *desc); +u32 ath12k_hal_rx_desc_get_msdu_freq_qcn9274(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_pkt_type_qcn9274(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_nss_qcn9274(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_mpdu_tid_qcn9274(struct hal_rx_desc *desc); +u16 ath12k_hal_rx_desc_get_mpdu_peer_id_qcn9274(struct hal_rx_desc *desc); +void ath12k_hal_rx_desc_copy_end_tlv_qcn9274(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc); +u32 ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274(struct hal_rx_desc *desc); +void ath12k_hal_rx_desc_set_msdu_len_qcn9274(struct hal_rx_desc *desc, u16 len); +u8 *ath12k_hal_rx_desc_get_msdu_payload_qcn9274(struct hal_rx_desc *desc); +u32 ath12k_hal_rx_desc_get_mpdu_start_offset_qcn9274(void); +u32 ath12k_hal_rx_desc_get_msdu_end_offset_qcn9274(void); +bool ath12k_hal_rx_desc_mac_addr2_valid_qcn9274(struct hal_rx_desc *desc); +u8 *ath12k_hal_rx_desc_mpdu_start_addr2_qcn9274(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_is_da_mcbc_qcn9274(struct hal_rx_desc *desc); +bool ath12k_hal_rx_h_msdu_done_qcn9274(struct hal_rx_desc *desc); +bool ath12k_hal_rx_h_l4_cksum_fail_qcn9274(struct hal_rx_desc *desc); +bool ath12k_hal_rx_h_ip_cksum_fail_qcn9274(struct hal_rx_desc *desc); +bool ath12k_hal_rx_h_is_decrypted_qcn9274(struct hal_rx_desc *desc); +u32 ath12k_hal_get_rx_desc_size_qcn9274(void); +u8 ath12k_hal_rx_desc_get_msdu_src_link_qcn9274(struct hal_rx_desc *desc); +u16 ath12k_hal_rx_mpdu_start_wmask_get_qcn9274(void); +u32 ath12k_hal_rx_msdu_end_wmask_get_qcn9274(void); +u32 ath12k_hal_rx_h_mpdu_err_qcn9274(struct hal_rx_desc *desc); +void ath12k_hal_rx_desc_get_crypto_hdr_qcn9274(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype); +void ath12k_hal_rx_desc_get_dot11_hdr_qcn9274(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 1e23665aabc91..11b03452494c5 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -7,137 +7,137 @@ #include "hal_desc.h" #include "hal_wcn7850.h" -bool ath12k_hw_wcn7850_rx_desc_get_first_msdu(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_get_first_msdu_wcn7850(struct hal_rx_desc *desc) { return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5, RX_MSDU_END_INFO5_FIRST_MSDU); } -bool ath12k_hw_wcn7850_rx_desc_get_last_msdu(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_get_last_msdu_wcn7850(struct hal_rx_desc *desc) { return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5, RX_MSDU_END_INFO5_LAST_MSDU); } -u8 ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850(struct hal_rx_desc *desc) { return le16_get_bits(desc->u.wcn7850.msdu_end.info5, RX_MSDU_END_INFO5_L3_HDR_PADDING); } -bool ath12k_hw_wcn7850_rx_desc_encrypt_valid(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_encrypt_valid_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); } -u32 ath12k_hw_wcn7850_rx_desc_get_encrypt_type(struct hal_rx_desc *desc) +u32 ath12k_hal_rx_desc_get_encrypt_type_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.mpdu_start.info2, RX_MPDU_START_INFO2_ENC_TYPE); } -u8 ath12k_hw_wcn7850_rx_desc_get_decap_type(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_decap_type_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info11, RX_MSDU_END_INFO11_DECAP_FORMAT); } -u8 ath12k_hw_wcn7850_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_mesh_ctl_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info11, RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); } -bool ath12k_hw_wcn7850_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); } -bool ath12k_hw_wcn7850_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_get_mpdu_fc_valid_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); } -u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc) +u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_SEQ_NUM); } -u16 ath12k_hw_wcn7850_rx_desc_get_msdu_len(struct hal_rx_desc *desc) +u16 ath12k_hal_rx_desc_get_msdu_len_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info10, RX_MSDU_END_INFO10_MSDU_LENGTH); } -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_sgi_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_SGI); } -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_RATE_MCS); } -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_rx_bw_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_RECV_BW); } -u32 ath12k_hw_wcn7850_rx_desc_get_msdu_freq(struct hal_rx_desc *desc) +u32 ath12k_hal_rx_desc_get_msdu_freq_wcn7850(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.wcn7850.msdu_end.phy_meta_data); } -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_pkt_type_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_PKT_TYPE); } -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_nss(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_nss_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_MIMO_SS_BITMAP); } -u8 ath12k_hw_wcn7850_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_mpdu_tid_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.mpdu_start.info2, RX_MPDU_START_INFO2_TID); } -u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc) +u16 ath12k_hal_rx_desc_get_mpdu_peer_id_wcn7850(struct hal_rx_desc *desc) { return __le16_to_cpu(desc->u.wcn7850.mpdu_start.sw_peer_id); } -void ath12k_hw_wcn7850_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, - struct hal_rx_desc *ldesc) +void ath12k_hal_rx_desc_copy_end_tlv_wcn7850(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc) { memcpy(&fdesc->u.wcn7850.msdu_end, &ldesc->u.wcn7850.msdu_end, sizeof(struct rx_msdu_end_qcn9274)); } -u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag(struct hal_rx_desc *desc) +u32 ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850(struct hal_rx_desc *desc) { return le64_get_bits(desc->u.wcn7850.mpdu_start_tag, HAL_TLV_HDR_TAG); } -u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc) +u32 ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850(struct hal_rx_desc *desc) { return __le16_to_cpu(desc->u.wcn7850.mpdu_start.phy_ppdu_id); } -void ath12k_hw_wcn7850_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) +void ath12k_hal_rx_desc_set_msdu_len_wcn7850(struct hal_rx_desc *desc, u16 len) { u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info10); @@ -147,74 +147,74 @@ void ath12k_hw_wcn7850_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) desc->u.wcn7850.msdu_end.info10 = __cpu_to_le32(info); } -u8 *ath12k_hw_wcn7850_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) +u8 *ath12k_hal_rx_desc_get_msdu_payload_wcn7850(struct hal_rx_desc *desc) { return &desc->u.wcn7850.msdu_payload[0]; } -u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_offset(void) +u32 ath12k_hal_rx_desc_get_mpdu_start_offset_wcn7850(void) { return offsetof(struct hal_rx_desc_wcn7850, mpdu_start_tag); } -u32 ath12k_hw_wcn7850_rx_desc_get_msdu_end_offset(void) +u32 ath12k_hal_rx_desc_get_msdu_end_offset_wcn7850(void) { return offsetof(struct hal_rx_desc_wcn7850, msdu_end_tag); } -bool ath12k_hw_wcn7850_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_mac_addr2_valid_wcn7850(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.wcn7850.mpdu_start.info4) & RX_MPDU_START_INFO4_MAC_ADDR2_VALID; } -u8 *ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) +u8 *ath12k_hal_rx_desc_mpdu_start_addr2_wcn7850(struct hal_rx_desc *desc) { return desc->u.wcn7850.mpdu_start.addr2; } -bool ath12k_hw_wcn7850_rx_desc_is_da_mcbc(struct hal_rx_desc *desc) +bool ath12k_hal_rx_desc_is_da_mcbc_wcn7850(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.wcn7850.msdu_end.info13) & RX_MSDU_END_INFO13_MCAST_BCAST; } -bool ath12k_hw_wcn7850_dp_rx_h_msdu_done(struct hal_rx_desc *desc) +bool ath12k_hal_rx_h_msdu_done_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.msdu_end.info14, RX_MSDU_END_INFO14_MSDU_DONE); } -bool ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc) +bool ath12k_hal_rx_h_l4_cksum_fail_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13, RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); } -bool ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc) +bool ath12k_hal_rx_h_ip_cksum_fail_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13, RX_MSDU_END_INFO13_IP_CKSUM_FAIL); } -bool ath12k_hw_wcn7850_dp_rx_h_is_decrypted(struct hal_rx_desc *desc) +bool ath12k_hal_rx_h_is_decrypted_wcn7850(struct hal_rx_desc *desc) { return (le32_get_bits(desc->u.wcn7850.msdu_end.info14, RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == RX_DESC_DECRYPT_STATUS_CODE_OK); } -u32 ath12k_hw_wcn7850_get_rx_desc_size(void) +u32 ath12k_hal_get_rx_desc_size_wcn7850(void) { return sizeof(struct hal_rx_desc_wcn7850); } -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc) +u8 ath12k_hal_rx_desc_get_msdu_src_link_wcn7850(struct hal_rx_desc *desc) { return 0; } -u32 ath12k_hw_wcn7850_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) +u32 ath12k_hal_rx_h_mpdu_err_wcn7850(struct hal_rx_desc *desc) { u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info13); u32 errmap = 0; @@ -243,9 +243,9 @@ u32 ath12k_hw_wcn7850_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) return errmap; } -void ath12k_hw_wcn7850_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, - u8 *crypto_hdr, - enum hal_encrypt_type enctype) +void ath12k_hal_rx_desc_get_crypto_hdr_wcn7850(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype) { unsigned int key_id; @@ -286,8 +286,8 @@ void ath12k_hw_wcn7850_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[1]); } -void ath12k_hw_wcn7850_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, - struct ieee80211_hdr *hdr) +void ath12k_hal_rx_desc_get_dot11_hdr_wcn7850(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr) { hdr->frame_control = desc->u.wcn7850.mpdu_start.frame_ctrl; hdr->duration_id = desc->u.wcn7850.mpdu_start.duration; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h index a5395a0053834..c9a6b7ffb6078 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -10,46 +10,46 @@ #include "../hal.h" #include "hal_rx.h" -bool ath12k_hw_wcn7850_rx_desc_get_first_msdu(struct hal_rx_desc *desc); -bool ath12k_hw_wcn7850_rx_desc_get_last_msdu(struct hal_rx_desc *desc); -u8 ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc); -bool ath12k_hw_wcn7850_rx_desc_encrypt_valid(struct hal_rx_desc *desc); -u32 ath12k_hw_wcn7850_rx_desc_get_encrypt_type(struct hal_rx_desc *desc); -u8 ath12k_hw_wcn7850_rx_desc_get_decap_type(struct hal_rx_desc *desc); -u8 ath12k_hw_wcn7850_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc); -bool ath12k_hw_wcn7850_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc); -bool ath12k_hw_wcn7850_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc); -u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc); -u16 ath12k_hw_wcn7850_rx_desc_get_msdu_len(struct hal_rx_desc *desc); -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc); -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc); -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc); -u32 ath12k_hw_wcn7850_rx_desc_get_msdu_freq(struct hal_rx_desc *desc); -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc); -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_nss(struct hal_rx_desc *desc); -u8 ath12k_hw_wcn7850_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc); -u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc); -void ath12k_hw_wcn7850_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, - struct hal_rx_desc *ldesc); -u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag(struct hal_rx_desc *desc); -u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc); -void ath12k_hw_wcn7850_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len); -u8 *ath12k_hw_wcn7850_rx_desc_get_msdu_payload(struct hal_rx_desc *desc); -u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_offset(void); -u32 ath12k_hw_wcn7850_rx_desc_get_msdu_end_offset(void); -bool ath12k_hw_wcn7850_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc); -u8 *ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc); -bool ath12k_hw_wcn7850_rx_desc_is_da_mcbc(struct hal_rx_desc *desc); -bool ath12k_hw_wcn7850_dp_rx_h_msdu_done(struct hal_rx_desc *desc); -bool ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc); -bool ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc); -bool ath12k_hw_wcn7850_dp_rx_h_is_decrypted(struct hal_rx_desc *desc); -u32 ath12k_hw_wcn7850_get_rx_desc_size(void); -u8 ath12k_hw_wcn7850_rx_desc_get_msdu_src_link(struct hal_rx_desc *desc); -u32 ath12k_hw_wcn7850_dp_rx_h_mpdu_err(struct hal_rx_desc *desc); -void ath12k_hw_wcn7850_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, - u8 *crypto_hdr, - enum hal_encrypt_type enctype); -void ath12k_hw_wcn7850_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, - struct ieee80211_hdr *hdr); +bool ath12k_hal_rx_desc_get_first_msdu_wcn7850(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_get_last_msdu_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_encrypt_valid_wcn7850(struct hal_rx_desc *desc); +u32 ath12k_hal_rx_desc_get_encrypt_type_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_decap_type_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_mesh_ctl_wcn7850(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_wcn7850(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_get_mpdu_fc_valid_wcn7850(struct hal_rx_desc *desc); +u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_wcn7850(struct hal_rx_desc *desc); +u16 ath12k_hal_rx_desc_get_msdu_len_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_sgi_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_rx_bw_wcn7850(struct hal_rx_desc *desc); +u32 ath12k_hal_rx_desc_get_msdu_freq_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_pkt_type_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_msdu_nss_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_desc_get_mpdu_tid_wcn7850(struct hal_rx_desc *desc); +u16 ath12k_hal_rx_desc_get_mpdu_peer_id_wcn7850(struct hal_rx_desc *desc); +void ath12k_hal_rx_desc_copy_end_tlv_wcn7850(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc); +u32 ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850(struct hal_rx_desc *desc); +u32 ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850(struct hal_rx_desc *desc); +void ath12k_hal_rx_desc_set_msdu_len_wcn7850(struct hal_rx_desc *desc, u16 len); +u8 *ath12k_hal_rx_desc_get_msdu_payload_wcn7850(struct hal_rx_desc *desc); +u32 ath12k_hal_rx_desc_get_mpdu_start_offset_wcn7850(void); +u32 ath12k_hal_rx_desc_get_msdu_end_offset_wcn7850(void); +bool ath12k_hal_rx_desc_mac_addr2_valid_wcn7850(struct hal_rx_desc *desc); +u8 *ath12k_hal_rx_desc_mpdu_start_addr2_wcn7850(struct hal_rx_desc *desc); +bool ath12k_hal_rx_desc_is_da_mcbc_wcn7850(struct hal_rx_desc *desc); +bool ath12k_hal_rx_h_msdu_done_wcn7850(struct hal_rx_desc *desc); +bool ath12k_hal_rx_h_l4_cksum_fail_wcn7850(struct hal_rx_desc *desc); +bool ath12k_hal_rx_h_ip_cksum_fail_wcn7850(struct hal_rx_desc *desc); +bool ath12k_hal_rx_h_is_decrypted_wcn7850(struct hal_rx_desc *desc); +u32 ath12k_hal_get_rx_desc_size_wcn7850(void); +u8 ath12k_hal_rx_desc_get_msdu_src_link_wcn7850(struct hal_rx_desc *desc); +u32 ath12k_hal_rx_h_mpdu_err_wcn7850(struct hal_rx_desc *desc); +void ath12k_hal_rx_desc_get_crypto_hdr_wcn7850(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype); +void ath12k_hal_rx_desc_get_dot11_hdr_wcn7850(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr); #endif From 340866967e20c4927d762e039053cb514815ceeb Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Wed, 10 Sep 2025 23:44:10 +0530 Subject: [PATCH 037/140] wifi: ath12k: Replace ops with direct calls for rxdma ring mask Replace following ops with direct function calls rxdma_ring_wmask_rx_mpdu_start rxdma_ring_wmask_rx_msdu_end rx_desc_get_mpdu_start_offset rx_desc_get_msdu_end_offset Remove redundant ops entries following the switch to direct function calls. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250910181414.2062280-5-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.c | 10 ---------- drivers/net/wireless/ath/ath12k/hal.h | 4 ---- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 16 ++++++++-------- 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 1fba023d0859d..329c458d1fe25 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -432,10 +432,6 @@ const struct hal_rx_ops hal_rx_qcn9274_compact_ops = { .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcn9274, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, - .rx_desc_get_mpdu_start_offset = - ath12k_hal_rx_desc_get_mpdu_start_offset_qcn9274, - .rx_desc_get_msdu_end_offset = - ath12k_hal_rx_desc_get_msdu_end_offset_qcn9274, .rx_desc_mac_addr2_valid = ath12k_hal_rx_desc_mac_addr2_valid_qcn9274, .rx_desc_mpdu_start_addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_qcn9274, .rx_desc_is_da_mcbc = ath12k_hal_rx_desc_is_da_mcbc_qcn9274, @@ -455,8 +451,6 @@ EXPORT_SYMBOL(hal_rx_qcn9274_compact_ops); const struct hal_ops hal_qcn9274_ops = { .create_srng_config = ath12k_hal_srng_create_config_qcn9274, .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, - .rxdma_ring_wmask_rx_mpdu_start = ath12k_hal_rx_mpdu_start_wmask_get_qcn9274, - .rxdma_ring_wmask_rx_msdu_end = ath12k_hal_rx_msdu_end_wmask_get_qcn9274, }; EXPORT_SYMBOL(hal_qcn9274_ops); @@ -609,8 +603,6 @@ const struct hal_rx_ops hal_rx_wcn7850_ops = { .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_wcn7850, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, - .rx_desc_get_mpdu_start_offset = ath12k_hal_rx_desc_get_mpdu_start_offset_wcn7850, - .rx_desc_get_msdu_end_offset = ath12k_hal_rx_desc_get_msdu_end_offset_wcn7850, .rx_desc_mac_addr2_valid = ath12k_hal_rx_desc_mac_addr2_valid_wcn7850, .rx_desc_mpdu_start_addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_wcn7850, .rx_desc_is_da_mcbc = ath12k_hal_rx_desc_is_da_mcbc_wcn7850, @@ -629,8 +621,6 @@ EXPORT_SYMBOL(hal_rx_wcn7850_ops); const struct hal_ops hal_wcn7850_ops = { .create_srng_config = ath12k_hal_srng_create_config_wcn7850, .tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map, - .rxdma_ring_wmask_rx_mpdu_start = NULL, - .rxdma_ring_wmask_rx_msdu_end = NULL, }; EXPORT_SYMBOL(hal_wcn7850_ops); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 2e086909ce25e..7e61d073b98d3 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1577,8 +1577,6 @@ struct hal_rx_ops { void (*rx_desc_set_msdu_len)(struct hal_rx_desc *desc, u16 len); struct rx_attention *(*rx_desc_get_attention)(struct hal_rx_desc *desc); u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc); - u32 (*rx_desc_get_mpdu_start_offset)(void); - u32 (*rx_desc_get_msdu_end_offset)(void); bool (*rx_desc_mac_addr2_valid)(struct hal_rx_desc *desc); u8* (*rx_desc_mpdu_start_addr2)(struct hal_rx_desc *desc); bool (*rx_desc_is_da_mcbc)(struct hal_rx_desc *desc); @@ -1598,8 +1596,6 @@ struct hal_rx_ops { struct hal_ops { int (*create_srng_config)(struct ath12k_base *ab); - u16 (*rxdma_ring_wmask_rx_mpdu_start)(void); - u32 (*rxdma_ring_wmask_rx_msdu_end)(void); const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; }; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 2105d9e949768..99ff560384520 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -7,6 +7,8 @@ #include "dp_rx.h" #include "../dp_tx.h" #include "../peer.h" +#include "hal_qcn9274.h" +#include "hal_wcn7850.h" void ath12k_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, dma_addr_t paddr) @@ -1897,14 +1899,12 @@ int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab) tlv_filter.rx_packet_offset = hal_rx_desc_sz; tlv_filter.rx_mpdu_start_offset = - ab->hal_rx_ops->rx_desc_get_mpdu_start_offset(); + ath12k_hal_rx_desc_get_mpdu_start_offset_qcn9274(); tlv_filter.rx_msdu_end_offset = - ab->hal_rx_ops->rx_desc_get_msdu_end_offset(); + ath12k_hal_rx_desc_get_msdu_end_offset_qcn9274(); - tlv_filter.rx_mpdu_start_wmask = - ab->hw_params->hal_ops->rxdma_ring_wmask_rx_mpdu_start(); - tlv_filter.rx_msdu_end_wmask = - ab->hw_params->hal_ops->rxdma_ring_wmask_rx_msdu_end(); + tlv_filter.rx_mpdu_start_wmask = ath12k_hal_rx_mpdu_start_wmask_get_qcn9274(); + tlv_filter.rx_msdu_end_wmask = ath12k_hal_rx_msdu_end_wmask_get_qcn9274(); ath12k_dbg(ab, ATH12K_DBG_DATA, "Configuring compact tlv masks rx_mpdu_start_wmask 0x%x rx_msdu_end_wmask 0x%x\n", tlv_filter.rx_mpdu_start_wmask, tlv_filter.rx_msdu_end_wmask); @@ -1940,9 +1940,9 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) tlv_filter.rx_header_offset = offsetof(struct hal_rx_desc_wcn7850, pkt_hdr_tlv); tlv_filter.rx_mpdu_start_offset = - ab->hal_rx_ops->rx_desc_get_mpdu_start_offset(); + ath12k_hal_rx_desc_get_mpdu_start_offset_wcn7850(); tlv_filter.rx_msdu_end_offset = - ab->hal_rx_ops->rx_desc_get_msdu_end_offset(); + ath12k_hal_rx_desc_get_msdu_end_offset_wcn7850(); /* TODO: Selectively subscribe to required qwords within msdu_end * and mpdu_start and setup the mask in below msg From 219599a8e1c003ec4a0c321a6942d0a409da19e9 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Wed, 10 Sep 2025 23:44:11 +0530 Subject: [PATCH 038/140] wifi: ath12k: Move hal_rx_ops callbacks to hal_ops Move the following callbacks from hal_rx_ops to hal_ops for use in non-performance-critical paths: rx_desc_set_msdu_len rx_desc_get_dot11_hdr rx_desc_get_crypto_header rx_desc_copy_end_tlv rx_desc_get_msdu_src_link_id rx_desc_get_desc_size hal_rx_ops currently includes callbacks used in both critical and non-critical Rx paths. To reduce function pointer indirection in hot path, performance-critical ops will be consolidated into a single extraction API in a follow-up patch. Begin cleanup by migrating non-performance-critical callbacks from hal_rx_ops to hal_ops. Once the extraction API is in place, remove hal_rx_ops entirely to simplify the HAL interface. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250910181414.2062280-6-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 2 +- drivers/net/wireless/ath/ath12k/dp_rx.h | 10 +++++----- drivers/net/wireless/ath/ath12k/hal.c | 25 ++++++++++++------------- drivers/net/wireless/ath/ath12k/hal.h | 20 ++++++++++---------- 4 files changed, 28 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 4c6caa8905fdd..4cc4006b18bbc 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -897,7 +897,7 @@ void ath12k_dp_pdev_pre_alloc(struct ath12k *ar) void ath12k_dp_hal_rx_desc_init(struct ath12k_base *ab) { - ab->hal.hal_desc_sz = ab->hal_rx_ops->rx_desc_get_desc_size(); + ab->hal.hal_desc_sz = ab->hw_params->hal_ops->rx_desc_get_desc_size(); } int ath12k_dp_pdev_alloc(struct ath12k_base *ab) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index a6b6fea4c5e2e..0b92a996f68f8 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -283,14 +283,14 @@ static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab, struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc) { - ab->hal_rx_ops->rx_desc_copy_end_tlv(fdesc, ldesc); + ab->hw_params->hal_ops->rx_desc_copy_end_tlv(fdesc, ldesc); } static inline void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab, struct hal_rx_desc *desc, u16 len) { - ab->hal_rx_ops->rx_desc_set_msdu_len(desc, len); + ab->hw_params->hal_ops->rx_desc_set_msdu_len(desc, len); } static inline u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, @@ -332,7 +332,7 @@ static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab, struct hal_rx_desc *desc, struct ieee80211_hdr *hdr) { - ab->hal_rx_ops->rx_desc_get_dot11_hdr(desc, hdr); + ab->hw_params->hal_ops->rx_desc_get_dot11_hdr(desc, hdr); } static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, @@ -340,13 +340,13 @@ static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, u8 *crypto_hdr, enum hal_encrypt_type enctype) { - ab->hal_rx_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); + ab->hw_params->hal_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); } static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab, struct hal_rx_desc *desc) { - return ab->hal_rx_ops->rx_desc_get_msdu_src_link_id(desc); + return ab->hw_params->hal_ops->rx_desc_get_msdu_src_link_id(desc); } static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 329c458d1fe25..60a4e5766f513 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -428,29 +428,28 @@ const struct hal_rx_ops hal_rx_qcn9274_compact_ops = { .rx_desc_get_msdu_nss = ath12k_hal_rx_desc_get_msdu_nss_qcn9274, .rx_desc_get_mpdu_tid = ath12k_hal_rx_desc_get_mpdu_tid_qcn9274, .rx_desc_get_mpdu_peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_qcn9274, - .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcn9274, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, - .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcn9274, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, .rx_desc_mac_addr2_valid = ath12k_hal_rx_desc_mac_addr2_valid_qcn9274, .rx_desc_mpdu_start_addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_qcn9274, .rx_desc_is_da_mcbc = ath12k_hal_rx_desc_is_da_mcbc_qcn9274, - .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_qcn9274, - .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcn9274, .dp_rx_h_msdu_done = ath12k_hal_rx_h_msdu_done_qcn9274, .dp_rx_h_l4_cksum_fail = ath12k_hal_rx_h_l4_cksum_fail_qcn9274, .dp_rx_h_ip_cksum_fail = ath12k_hal_rx_h_ip_cksum_fail_qcn9274, .dp_rx_h_is_decrypted = ath12k_hal_rx_h_is_decrypted_qcn9274, .dp_rx_h_mpdu_err = ath12k_hal_rx_h_mpdu_err_qcn9274, - .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_qcn9274, - .rx_desc_get_msdu_src_link_id = - ath12k_hal_rx_desc_get_msdu_src_link_qcn9274, }; EXPORT_SYMBOL(hal_rx_qcn9274_compact_ops); const struct hal_ops hal_qcn9274_ops = { .create_srng_config = ath12k_hal_srng_create_config_qcn9274, .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, + .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcn9274, + .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_qcn9274, + .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcn9274, + .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcn9274, + .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_qcn9274, + .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_qcn9274, }; EXPORT_SYMBOL(hal_qcn9274_ops); @@ -598,29 +597,29 @@ const struct hal_rx_ops hal_rx_wcn7850_ops = { .rx_desc_get_msdu_nss = ath12k_hal_rx_desc_get_msdu_nss_wcn7850, .rx_desc_get_mpdu_tid = ath12k_hal_rx_desc_get_mpdu_tid_wcn7850, .rx_desc_get_mpdu_peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_wcn7850, - .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_wcn7850, .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, - .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_wcn7850, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, .rx_desc_mac_addr2_valid = ath12k_hal_rx_desc_mac_addr2_valid_wcn7850, .rx_desc_mpdu_start_addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_wcn7850, .rx_desc_is_da_mcbc = ath12k_hal_rx_desc_is_da_mcbc_wcn7850, - .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_wcn7850, - .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_wcn7850, .dp_rx_h_msdu_done = ath12k_hal_rx_h_msdu_done_wcn7850, .dp_rx_h_l4_cksum_fail = ath12k_hal_rx_h_l4_cksum_fail_wcn7850, .dp_rx_h_ip_cksum_fail = ath12k_hal_rx_h_ip_cksum_fail_wcn7850, .dp_rx_h_is_decrypted = ath12k_hal_rx_h_is_decrypted_wcn7850, .dp_rx_h_mpdu_err = ath12k_hal_rx_h_mpdu_err_wcn7850, - .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_wcn7850, - .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_wcn7850, }; EXPORT_SYMBOL(hal_rx_wcn7850_ops); const struct hal_ops hal_wcn7850_ops = { .create_srng_config = ath12k_hal_srng_create_config_wcn7850, .tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map, + .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_wcn7850, + .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_wcn7850, + .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_wcn7850, + .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_wcn7850, + .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_wcn7850, + .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_wcn7850, }; EXPORT_SYMBOL(hal_wcn7850_ops); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 7e61d073b98d3..79d3eba6e7959 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1570,33 +1570,33 @@ struct hal_rx_ops { u8 (*rx_desc_get_msdu_nss)(struct hal_rx_desc *desc); u8 (*rx_desc_get_mpdu_tid)(struct hal_rx_desc *desc); u16 (*rx_desc_get_mpdu_peer_id)(struct hal_rx_desc *desc); - void (*rx_desc_copy_end_tlv)(struct hal_rx_desc *fdesc, - struct hal_rx_desc *ldesc); u32 (*rx_desc_get_mpdu_start_tag)(struct hal_rx_desc *desc); u32 (*rx_desc_get_mpdu_ppdu_id)(struct hal_rx_desc *desc); - void (*rx_desc_set_msdu_len)(struct hal_rx_desc *desc, u16 len); struct rx_attention *(*rx_desc_get_attention)(struct hal_rx_desc *desc); u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc); bool (*rx_desc_mac_addr2_valid)(struct hal_rx_desc *desc); u8* (*rx_desc_mpdu_start_addr2)(struct hal_rx_desc *desc); bool (*rx_desc_is_da_mcbc)(struct hal_rx_desc *desc); - void (*rx_desc_get_dot11_hdr)(struct hal_rx_desc *desc, - struct ieee80211_hdr *hdr); - void (*rx_desc_get_crypto_header)(struct hal_rx_desc *desc, - u8 *crypto_hdr, - enum hal_encrypt_type enctype); bool (*dp_rx_h_msdu_done)(struct hal_rx_desc *desc); bool (*dp_rx_h_l4_cksum_fail)(struct hal_rx_desc *desc); bool (*dp_rx_h_ip_cksum_fail)(struct hal_rx_desc *desc); bool (*dp_rx_h_is_decrypted)(struct hal_rx_desc *desc); u32 (*dp_rx_h_mpdu_err)(struct hal_rx_desc *desc); - u32 (*rx_desc_get_desc_size)(void); - u8 (*rx_desc_get_msdu_src_link_id)(struct hal_rx_desc *desc); }; struct hal_ops { int (*create_srng_config)(struct ath12k_base *ab); const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; + void (*rx_desc_set_msdu_len)(struct hal_rx_desc *desc, u16 len); + void (*rx_desc_get_dot11_hdr)(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr); + void (*rx_desc_get_crypto_header)(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype); + void (*rx_desc_copy_end_tlv)(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc); + u8 (*rx_desc_get_msdu_src_link_id)(struct hal_rx_desc *desc); + u32 (*rx_desc_get_desc_size)(void); }; extern const struct hal_ops hal_qcn9274_ops; From b8860f5ec2aca7018c477fc4746d1b45dfcb8b62 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Wed, 10 Sep 2025 23:44:12 +0530 Subject: [PATCH 039/140] wifi: ath12k: Add new infra for the rx path The existing usage of rx_ops to reach the hal APIs at multiple place uses function pointer indirections. In order to avoid multiple function pointer indirections, add an API to extract the required hal parameters in the rx path right at the beginning and store them in a structure which is then leveraged by rest of the rx path. rx_desc_get_first_msdu rx_desc_get_last_msdu rx_desc_encrypt_valid rx_desc_get_encrypt_type rx_desc_get_decap_type rx_desc_get_mesh_ctl rx_desc_get_mpdu_seq_ctl_vld rx_desc_get_mpdu_fc_valid rx_desc_get_mpdu_start_seq_no rx_desc_get_msdu_len rx_desc_get_msdu_sgi rx_desc_get_msdu_rate_mcs rx_desc_get_msdu_rx_bw rx_desc_get_msdu_freq rx_desc_get_msdu_pkt_type rx_desc_get_msdu_nss rx_desc_get_mpdu_tid rx_desc_get_mpdu_peer_id rx_desc_mac_addr2_valid rx_desc_mpdu_start_addr2 rx_desc_is_da_mcbc dp_rx_h_msdu_done dp_rx_h_l4_cksum_fail dp_rx_h_ip_cksum_fail dp_rx_h_is_decrypted dp_rx_h_mpdu_err Remove following unused HAL rx ops rx_desc_get_hdr_status rx_desc_get_attention Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250910181414.2062280-7-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.c | 1 + drivers/net/wireless/ath/ath12k/dp_mon.c | 5 + drivers/net/wireless/ath/ath12k/dp_rx.c | 85 +++----- drivers/net/wireless/ath/ath12k/dp_rx.h | 188 +----------------- drivers/net/wireless/ath/ath12k/hal.c | 56 +----- drivers/net/wireless/ath/ath12k/hal.h | 61 +++--- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 163 +++++++-------- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 8 + .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 64 +++++- .../wireless/ath/ath12k/wifi7/hal_qcn9274.h | 29 +-- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 64 +++++- .../wireless/ath/ath12k/wifi7/hal_wcn7850.h | 29 +-- 12 files changed, 290 insertions(+), 463 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 301d1337ab8bd..ca38f1f133708 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -15,6 +15,7 @@ #include "core.h" #include "dp_tx.h" #include "dp_rx.h" +#include "wifi7/dp_rx.h" #include "debug.h" #include "debugfs.h" #include "fw.h" diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 803de9ca3e51a..bb98257c8d427 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -6,6 +6,7 @@ #include "dp_mon.h" #include "debug.h" +#include "wifi7/hal_qcn9274.h" #include "wifi7/dp_rx.h" #include "dp_tx.h" #include "peer.h" @@ -2292,8 +2293,10 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct struct ieee80211_sta *pubsta = NULL; struct ath12k_peer *peer; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); + struct hal_rx_desc_data rx_info; bool is_mcbc = rxcb->is_mcbc; bool is_eapol_tkip = rxcb->is_eapol; + struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; status->link_valid = 0; @@ -2304,6 +2307,8 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct status->flag |= RX_FLAG_RADIOTAP_HE; } + ath12k_wifi7_dp_extract_rx_desc_data(ar->ab, &rx_info, rx_desc, rx_desc); + spin_lock_bh(&ar->ab->base_lock); peer = ath12k_peer_find_by_id(ar->ab, ppduinfo->peer_id); if (peer && peer->sta) { diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 6505a37f02e9d..c0e41a0a29f35 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -873,9 +873,8 @@ static int ath12k_dp_rx_crypto_icv_len(struct ath12k *ar, static void ath12k_dp_rx_h_undecap_nwifi(struct ath12k *ar, struct sk_buff *msdu, enum hal_encrypt_type enctype, - struct ieee80211_rx_status *status) + struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); u8 decap_hdr[DP_MAX_NWIFI_HDR_LEN]; struct ieee80211_hdr *hdr; @@ -896,7 +895,7 @@ static void ath12k_dp_rx_h_undecap_nwifi(struct ath12k *ar, qos_ctl = rxcb->tid; - if (ath12k_dp_rx_h_mesh_ctl_present(ab, rxcb->rx_desc)) + if (rx_info->mesh_ctrl_present) qos_ctl |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT; /* TODO: Add other QoS ctl fields when required */ @@ -905,7 +904,7 @@ static void ath12k_dp_rx_h_undecap_nwifi(struct ath12k *ar, memcpy(decap_hdr, hdr, hdr_len); /* Rebuild crypto header for mac80211 use */ - if (!(status->flag & RX_FLAG_IV_STRIPPED)) { + if (!(rx_info->rx_status->flag & RX_FLAG_IV_STRIPPED)) { crypto_hdr = skb_push(msdu, ath12k_dp_rx_crypto_param_len(ar, enctype)); ath12k_dp_rx_desc_get_crypto_header(ar->ab, rxcb->rx_desc, crypto_hdr, @@ -979,21 +978,20 @@ static void ath12k_dp_rx_h_undecap_raw(struct ath12k *ar, struct sk_buff *msdu, static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k *ar, struct sk_buff *msdu, struct ath12k_skb_rxcb *rxcb, - struct ieee80211_rx_status *status, - enum hal_encrypt_type enctype) + enum hal_encrypt_type enctype, + struct hal_rx_desc_data *rx_info) { struct hal_rx_desc *rx_desc = rxcb->rx_desc; struct ath12k_base *ab = ar->ab; size_t hdr_len, crypto_len; struct ieee80211_hdr hdr; __le16 qos_ctl; - u8 *crypto_hdr, mesh_ctrl; + u8 *crypto_hdr; ath12k_dp_rx_desc_get_dot11_hdr(ab, rx_desc, &hdr); hdr_len = ieee80211_hdrlen(hdr.frame_control); - mesh_ctrl = ath12k_dp_rx_h_mesh_ctl_present(ab, rx_desc); - if (!(status->flag & RX_FLAG_IV_STRIPPED)) { + if (!(rx_info->rx_status->flag & RX_FLAG_IV_STRIPPED)) { crypto_len = ath12k_dp_rx_crypto_param_len(ar, enctype); crypto_hdr = skb_push(msdu, crypto_len); ath12k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype); @@ -1003,14 +1001,14 @@ static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k *ar, memcpy(msdu->data, &hdr, min(hdr_len, sizeof(hdr))); if (rxcb->is_mcbc) - status->flag &= ~RX_FLAG_PN_VALIDATED; + rx_info->rx_status->flag &= ~RX_FLAG_PN_VALIDATED; /* Add QOS header */ if (ieee80211_is_data_qos(hdr.frame_control)) { struct ieee80211_hdr *qos_ptr = (struct ieee80211_hdr *)msdu->data; qos_ctl = cpu_to_le16(rxcb->tid & IEEE80211_QOS_CTL_TID_MASK); - if (mesh_ctrl) + if (rx_info->mesh_ctrl_present) qos_ctl |= cpu_to_le16(IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT); memcpy(ieee80211_get_qos_ctl(qos_ptr), &qos_ctl, IEEE80211_QOS_CTL_LEN); @@ -1020,7 +1018,7 @@ static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k *ar, static void ath12k_dp_rx_h_undecap_eth(struct ath12k *ar, struct sk_buff *msdu, enum hal_encrypt_type enctype, - struct ieee80211_rx_status *status) + struct hal_rx_desc_data *rx_info) { struct ieee80211_hdr *hdr; struct ethhdr *eth; @@ -1036,7 +1034,7 @@ static void ath12k_dp_rx_h_undecap_eth(struct ath12k *ar, skb_pull(msdu, sizeof(*eth)); memcpy(skb_push(msdu, sizeof(rfc)), &rfc, sizeof(rfc)); - ath12k_get_dot11_hdr_from_rx_desc(ar, msdu, rxcb, status, enctype); + ath12k_get_dot11_hdr_from_rx_desc(ar, msdu, rxcb, enctype, rx_info); /* original 802.11 header has a different DA and in * case of 4addr it may also have different SA @@ -1049,21 +1047,17 @@ static void ath12k_dp_rx_h_undecap_eth(struct ath12k *ar, void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, struct hal_rx_desc *rx_desc, enum hal_encrypt_type enctype, - struct ieee80211_rx_status *status, - bool decrypted) + bool decrypted, + struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; - u8 decap; struct ethhdr *ehdr; - decap = ath12k_dp_rx_h_decap_type(ab, rx_desc); - - switch (decap) { + switch (rx_info->decap_type) { case DP_RX_DECAP_TYPE_NATIVE_WIFI: - ath12k_dp_rx_h_undecap_nwifi(ar, msdu, enctype, status); + ath12k_dp_rx_h_undecap_nwifi(ar, msdu, enctype, rx_info); break; case DP_RX_DECAP_TYPE_RAW: - ath12k_dp_rx_h_undecap_raw(ar, msdu, enctype, status, + ath12k_dp_rx_h_undecap_raw(ar, msdu, enctype, rx_info->rx_status, decrypted); break; case DP_RX_DECAP_TYPE_ETHERNET2_DIX: @@ -1072,7 +1066,7 @@ void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, /* mac80211 allows fast path only for authorized STA */ if (ehdr->h_proto == cpu_to_be16(ETH_P_PAE)) { ATH12K_SKB_RXCB(msdu)->is_eapol = true; - ath12k_dp_rx_h_undecap_eth(ar, msdu, enctype, status); + ath12k_dp_rx_h_undecap_eth(ar, msdu, enctype, rx_info); break; } @@ -1080,7 +1074,7 @@ void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, * remove eth header and add 802.11 header. */ if (ATH12K_SKB_RXCB(msdu)->is_mcbc && decrypted) - ath12k_dp_rx_h_undecap_eth(ar, msdu, enctype, status); + ath12k_dp_rx_h_undecap_eth(ar, msdu, enctype, rx_info); break; case DP_RX_DECAP_TYPE_8023: /* TODO: Handle undecap for these formats */ @@ -1090,7 +1084,7 @@ void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, struct ath12k_peer * ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info) + struct hal_rx_desc_data *rx_info) { struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); struct ath12k_peer *peer = NULL; @@ -1109,7 +1103,7 @@ ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu, return peer; } -static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info) +static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct hal_rx_desc_data *rx_info) { struct ieee80211_supported_band *sband; struct ieee80211_rx_status *rx_status = rx_info->rx_status; @@ -1186,33 +1180,7 @@ static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct ath12k_dp_rx_info *rx_ } } -void ath12k_dp_rx_h_fetch_info(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, - struct ath12k_dp_rx_info *rx_info) -{ - rx_info->ip_csum_fail = ath12k_dp_rx_h_ip_cksum_fail(ab, rx_desc); - rx_info->l4_csum_fail = ath12k_dp_rx_h_l4_cksum_fail(ab, rx_desc); - rx_info->is_mcbc = ath12k_dp_rx_h_is_da_mcbc(ab, rx_desc); - rx_info->decap_type = ath12k_dp_rx_h_decap_type(ab, rx_desc); - rx_info->pkt_type = ath12k_dp_rx_h_pkt_type(ab, rx_desc); - rx_info->sgi = ath12k_dp_rx_h_sgi(ab, rx_desc); - rx_info->rate_mcs = ath12k_dp_rx_h_rate_mcs(ab, rx_desc); - rx_info->bw = ath12k_dp_rx_h_rx_bw(ab, rx_desc); - rx_info->nss = ath12k_dp_rx_h_nss(ab, rx_desc); - rx_info->tid = ath12k_dp_rx_h_tid(ab, rx_desc); - rx_info->peer_id = ath12k_dp_rx_h_peer_id(ab, rx_desc); - rx_info->phy_meta_data = ath12k_dp_rx_h_freq(ab, rx_desc); - - if (ath12k_dp_rxdesc_mac_addr2_valid(ab, rx_desc)) { - ether_addr_copy(rx_info->addr2, - ath12k_dp_rxdesc_get_mpdu_start_addr2(ab, rx_desc)); - rx_info->addr2_present = true; - } - - ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "rx_desc: ", - rx_desc, sizeof(*rx_desc)); -} - -void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info) +void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc_data *rx_info) { struct ieee80211_rx_status *rx_status = rx_info->rx_status; u8 channel_num; @@ -1274,7 +1242,7 @@ void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info) void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info) + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; struct ieee80211_rx_status *rx_status; @@ -1305,7 +1273,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, peer ? peer->addr : NULL, rxcb->tid, is_mcbc ? "mcast" : "ucast", - ath12k_dp_rx_h_seq_no(ab, rxcb->rx_desc), + rx_info->seq_no, (status->encoding == RX_ENC_LEGACY) ? "legacy" : "", (status->encoding == RX_ENC_HT) ? "ht" : "", (status->encoding == RX_ENC_VHT) ? "vht" : "", @@ -1346,14 +1314,13 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, - struct sk_buff *msdu) + struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info) { struct ieee80211_hdr *hdr; - u8 decap_type; u32 hdr_len; - decap_type = ath12k_dp_rx_h_decap_type(ab, rx_desc); - if (decap_type != DP_RX_DECAP_TYPE_NATIVE_WIFI) + if (rx_info->decap_type != DP_RX_DECAP_TYPE_NATIVE_WIFI) return true; hdr = (struct ieee80211_hdr *)msdu->data; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 0b92a996f68f8..38d9b11eff762 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -80,24 +80,6 @@ struct ath12k_dp_rx_rfc1042_hdr { __be16 snap_type; } __packed; -struct ath12k_dp_rx_info { - struct ieee80211_rx_status *rx_status; - u32 phy_meta_data; - u16 peer_id; - u8 decap_type; - u8 pkt_type; - u8 sgi; - u8 rate_mcs; - u8 bw; - u8 nss; - u8 addr2[ETH_ALEN]; - u8 tid; - bool ip_csum_fail; - bool l4_csum_fail; - bool is_mcbc; - bool addr2_present; -}; - static inline u32 ath12k_he_gi_to_nl80211_he_gi(u8 sgi) { u32 ret = 0; @@ -120,39 +102,6 @@ static inline u32 ath12k_he_gi_to_nl80211_he_gi(u8 sgi) return ret; } -static inline enum hal_encrypt_type ath12k_dp_rx_h_enctype(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - if (!ab->hal_rx_ops->rx_desc_encrypt_valid(desc)) - return HAL_ENCRYPT_TYPE_OPEN; - - return ab->hal_rx_ops->rx_desc_get_encrypt_type(desc); -} - -static inline u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_decap_type(desc); -} - -static inline u8 ath12k_dp_rx_h_mesh_ctl_present(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mesh_ctl(desc); -} - -static inline bool ath12k_dp_rx_h_seq_ctrl_valid(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_seq_ctl_vld(desc); -} - -static inline bool ath12k_dp_rx_h_fc_valid(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_fc_valid(desc); -} - static inline bool ath12k_dp_rx_h_more_frags(struct ath12k_base *ab, struct sk_buff *skb) { @@ -171,114 +120,12 @@ static inline u16 ath12k_dp_rx_h_frag_no(struct ath12k_base *ab, return le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; } -static inline u16 ath12k_dp_rx_h_seq_no(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_start_seq_no(desc); -} - -static inline bool ath12k_dp_rx_h_msdu_done(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_msdu_done(desc); -} - -static inline bool ath12k_dp_rx_h_l4_cksum_fail(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_l4_cksum_fail(desc); -} - -static inline bool ath12k_dp_rx_h_ip_cksum_fail(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_ip_cksum_fail(desc); -} - -static inline bool ath12k_dp_rx_h_is_decrypted(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_is_decrypted(desc); -} - -static inline u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->dp_rx_h_mpdu_err(desc); -} - -static inline u16 ath12k_dp_rx_h_msdu_len(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_len(desc); -} - -static inline u8 ath12k_dp_rx_h_sgi(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_sgi(desc); -} - -static inline u8 ath12k_dp_rx_h_rate_mcs(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_rate_mcs(desc); -} - -static inline u8 ath12k_dp_rx_h_rx_bw(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_rx_bw(desc); -} - -static inline u32 ath12k_dp_rx_h_freq(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_freq(desc); -} - -static inline u8 ath12k_dp_rx_h_pkt_type(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_msdu_pkt_type(desc); -} - -static inline u8 ath12k_dp_rx_h_nss(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return hweight8(ab->hal_rx_ops->rx_desc_get_msdu_nss(desc)); -} - -static inline u8 ath12k_dp_rx_h_tid(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_tid(desc); -} - -static inline u16 ath12k_dp_rx_h_peer_id(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_mpdu_peer_id(desc); -} - static inline u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, struct hal_rx_desc *desc) { return ab->hal_rx_ops->rx_desc_get_l3_pad_bytes(desc); } -static inline bool ath12k_dp_rx_h_first_msdu(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_first_msdu(desc); -} - -static inline bool ath12k_dp_rx_h_last_msdu(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_get_last_msdu(desc); -} - static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab, struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc) @@ -309,25 +156,6 @@ static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, return tlv_tag == HAL_RX_MPDU_START; } -static inline bool ath12k_dp_rx_h_is_da_mcbc(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return (ath12k_dp_rx_h_first_msdu(ab, desc) && - ab->hal_rx_ops->rx_desc_is_da_mcbc(desc)); -} - -static inline bool ath12k_dp_rxdesc_mac_addr2_valid(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_mac_addr2_valid(desc); -} - -static inline u8 *ath12k_dp_rxdesc_get_mpdu_start_addr2(struct ath12k_base *ab, - struct hal_rx_desc *desc) -{ - return ab->hal_rx_ops->rx_desc_mpdu_start_addr2(desc); -} - static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab, struct hal_rx_desc *desc, struct ieee80211_hdr *hdr) @@ -360,14 +188,15 @@ static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, struct hal_rx_desc *rx_desc, enum hal_encrypt_type enctype, - struct ieee80211_rx_status *status, - bool decrypted); + bool decrypted, + struct hal_rx_desc_data *rx_info); void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info); + struct hal_rx_desc_data *rx_info); bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, - struct sk_buff *msdu); + struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info); u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb); void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, struct sk_buff_head *frag_list, @@ -417,14 +246,11 @@ u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, struct hal_rx_desc *desc); struct ath12k_peer * ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info); + struct hal_rx_desc_data *rx_info); u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, struct hal_rx_desc *desc); u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, struct hal_rx_desc *desc); -void ath12k_dp_rx_h_fetch_info(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, - struct ath12k_dp_rx_info *rx_info); - int ath12k_dp_rx_crypto_mic_len(struct ath12k *ar, enum hal_encrypt_type enctype); u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); @@ -432,7 +258,7 @@ bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); -void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info); +void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc_data *rx_info); struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, struct sk_buff *first); void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx, diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 60a4e5766f513..db6294ba6771b 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -407,37 +407,9 @@ static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) } const struct hal_rx_ops hal_rx_qcn9274_compact_ops = { - .rx_desc_get_first_msdu = ath12k_hal_rx_desc_get_first_msdu_qcn9274, - .rx_desc_get_last_msdu = ath12k_hal_rx_desc_get_last_msdu_qcn9274, .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274, - .rx_desc_encrypt_valid = ath12k_hal_rx_desc_encrypt_valid_qcn9274, - .rx_desc_get_encrypt_type = ath12k_hal_rx_desc_get_encrypt_type_qcn9274, - .rx_desc_get_decap_type = ath12k_hal_rx_desc_get_decap_type_qcn9274, - .rx_desc_get_mesh_ctl = ath12k_hal_rx_desc_get_mesh_ctl_qcn9274, - .rx_desc_get_mpdu_seq_ctl_vld = - ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcn9274, - .rx_desc_get_mpdu_fc_valid = ath12k_hal_rx_desc_get_mpdu_fc_valid_qcn9274, - .rx_desc_get_mpdu_start_seq_no = - ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcn9274, - .rx_desc_get_msdu_len = ath12k_hal_rx_desc_get_msdu_len_qcn9274, - .rx_desc_get_msdu_sgi = ath12k_hal_rx_desc_get_msdu_sgi_qcn9274, - .rx_desc_get_msdu_rate_mcs = ath12k_hal_rx_desc_get_msdu_rate_mcs_qcn9274, - .rx_desc_get_msdu_rx_bw = ath12k_hal_rx_desc_get_msdu_rx_bw_qcn9274, - .rx_desc_get_msdu_freq = ath12k_hal_rx_desc_get_msdu_freq_qcn9274, - .rx_desc_get_msdu_pkt_type = ath12k_hal_rx_desc_get_msdu_pkt_type_qcn9274, - .rx_desc_get_msdu_nss = ath12k_hal_rx_desc_get_msdu_nss_qcn9274, - .rx_desc_get_mpdu_tid = ath12k_hal_rx_desc_get_mpdu_tid_qcn9274, - .rx_desc_get_mpdu_peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_qcn9274, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, - .rx_desc_mac_addr2_valid = ath12k_hal_rx_desc_mac_addr2_valid_qcn9274, - .rx_desc_mpdu_start_addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_qcn9274, - .rx_desc_is_da_mcbc = ath12k_hal_rx_desc_is_da_mcbc_qcn9274, - .dp_rx_h_msdu_done = ath12k_hal_rx_h_msdu_done_qcn9274, - .dp_rx_h_l4_cksum_fail = ath12k_hal_rx_h_l4_cksum_fail_qcn9274, - .dp_rx_h_ip_cksum_fail = ath12k_hal_rx_h_ip_cksum_fail_qcn9274, - .dp_rx_h_is_decrypted = ath12k_hal_rx_h_is_decrypted_qcn9274, - .dp_rx_h_mpdu_err = ath12k_hal_rx_h_mpdu_err_qcn9274, }; EXPORT_SYMBOL(hal_rx_qcn9274_compact_ops); @@ -449,6 +421,7 @@ const struct hal_ops hal_qcn9274_ops = { .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcn9274, .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcn9274, .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_qcn9274, + .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_qcn9274, .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_qcn9274, }; EXPORT_SYMBOL(hal_qcn9274_ops); @@ -578,36 +551,10 @@ static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) } const struct hal_rx_ops hal_rx_wcn7850_ops = { - .rx_desc_get_first_msdu = ath12k_hal_rx_desc_get_first_msdu_wcn7850, - .rx_desc_get_last_msdu = ath12k_hal_rx_desc_get_last_msdu_wcn7850, .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850, - .rx_desc_encrypt_valid = ath12k_hal_rx_desc_encrypt_valid_wcn7850, - .rx_desc_get_encrypt_type = ath12k_hal_rx_desc_get_encrypt_type_wcn7850, - .rx_desc_get_decap_type = ath12k_hal_rx_desc_get_decap_type_wcn7850, - .rx_desc_get_mesh_ctl = ath12k_hal_rx_desc_get_mesh_ctl_wcn7850, - .rx_desc_get_mpdu_seq_ctl_vld = ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_wcn7850, - .rx_desc_get_mpdu_fc_valid = ath12k_hal_rx_desc_get_mpdu_fc_valid_wcn7850, - .rx_desc_get_mpdu_start_seq_no = ath12k_hal_rx_desc_get_mpdu_start_seq_no_wcn7850, - .rx_desc_get_msdu_len = ath12k_hal_rx_desc_get_msdu_len_wcn7850, - .rx_desc_get_msdu_sgi = ath12k_hal_rx_desc_get_msdu_sgi_wcn7850, - .rx_desc_get_msdu_rate_mcs = ath12k_hal_rx_desc_get_msdu_rate_mcs_wcn7850, - .rx_desc_get_msdu_rx_bw = ath12k_hal_rx_desc_get_msdu_rx_bw_wcn7850, - .rx_desc_get_msdu_freq = ath12k_hal_rx_desc_get_msdu_freq_wcn7850, - .rx_desc_get_msdu_pkt_type = ath12k_hal_rx_desc_get_msdu_pkt_type_wcn7850, - .rx_desc_get_msdu_nss = ath12k_hal_rx_desc_get_msdu_nss_wcn7850, - .rx_desc_get_mpdu_tid = ath12k_hal_rx_desc_get_mpdu_tid_wcn7850, - .rx_desc_get_mpdu_peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_wcn7850, .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, - .rx_desc_mac_addr2_valid = ath12k_hal_rx_desc_mac_addr2_valid_wcn7850, - .rx_desc_mpdu_start_addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_wcn7850, - .rx_desc_is_da_mcbc = ath12k_hal_rx_desc_is_da_mcbc_wcn7850, - .dp_rx_h_msdu_done = ath12k_hal_rx_h_msdu_done_wcn7850, - .dp_rx_h_l4_cksum_fail = ath12k_hal_rx_h_l4_cksum_fail_wcn7850, - .dp_rx_h_ip_cksum_fail = ath12k_hal_rx_h_ip_cksum_fail_wcn7850, - .dp_rx_h_is_decrypted = ath12k_hal_rx_h_is_decrypted_wcn7850, - .dp_rx_h_mpdu_err = ath12k_hal_rx_h_mpdu_err_wcn7850, }; EXPORT_SYMBOL(hal_rx_wcn7850_ops); @@ -619,6 +566,7 @@ const struct hal_ops hal_wcn7850_ops = { .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_wcn7850, .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_wcn7850, .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_wcn7850, + .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_wcn7850, .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_wcn7850, }; EXPORT_SYMBOL(hal_wcn7850_ops); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 79d3eba6e7959..38f07f5a72000 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1022,6 +1022,36 @@ struct hal_rx_mon_ppdu_info { struct hal_rx_tlv_aggr_info tlv_aggr; }; +struct hal_rx_desc_data { + struct ieee80211_rx_status *rx_status; + u32 phy_meta_data; + u32 err_bitmap; + u32 enctype; + u32 msdu_done:1, + is_decrypted:1, + ip_csum_fail:1, + l4_csum_fail:1, + is_first_msdu:1, + is_last_msdu:1, + mesh_ctrl_present:1, + addr2_present:1, + is_mcbc:1, + seq_ctl_valid:1, + fc_valid:1; + u16 msdu_len; + u16 peer_id; + u16 seq_no; + u8 *addr2; + u8 pkt_type; + u8 l3_pad_bytes; + u8 decap_type; + u8 bw; + u8 rate_mcs; + u8 nss; + u8 sgi; + u8 tid; +}; + /* srng flags */ #define HAL_SRNG_FLAGS_MSI_SWAP 0x00000008 #define HAL_SRNG_FLAGS_RING_PTR_SWAP 0x00000010 @@ -1550,38 +1580,10 @@ enum nl80211_he_ru_alloc ath12k_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones) } struct hal_rx_ops { - bool (*rx_desc_get_first_msdu)(struct hal_rx_desc *desc); - bool (*rx_desc_get_last_msdu)(struct hal_rx_desc *desc); u8 (*rx_desc_get_l3_pad_bytes)(struct hal_rx_desc *desc); - u8 *(*rx_desc_get_hdr_status)(struct hal_rx_desc *desc); - bool (*rx_desc_encrypt_valid)(struct hal_rx_desc *desc); - u32 (*rx_desc_get_encrypt_type)(struct hal_rx_desc *desc); - u8 (*rx_desc_get_decap_type)(struct hal_rx_desc *desc); - u8 (*rx_desc_get_mesh_ctl)(struct hal_rx_desc *desc); - bool (*rx_desc_get_mpdu_seq_ctl_vld)(struct hal_rx_desc *desc); - bool (*rx_desc_get_mpdu_fc_valid)(struct hal_rx_desc *desc); - u16 (*rx_desc_get_mpdu_start_seq_no)(struct hal_rx_desc *desc); - u16 (*rx_desc_get_msdu_len)(struct hal_rx_desc *desc); - u8 (*rx_desc_get_msdu_sgi)(struct hal_rx_desc *desc); - u8 (*rx_desc_get_msdu_rate_mcs)(struct hal_rx_desc *desc); - u8 (*rx_desc_get_msdu_rx_bw)(struct hal_rx_desc *desc); - u32 (*rx_desc_get_msdu_freq)(struct hal_rx_desc *desc); - u8 (*rx_desc_get_msdu_pkt_type)(struct hal_rx_desc *desc); - u8 (*rx_desc_get_msdu_nss)(struct hal_rx_desc *desc); - u8 (*rx_desc_get_mpdu_tid)(struct hal_rx_desc *desc); - u16 (*rx_desc_get_mpdu_peer_id)(struct hal_rx_desc *desc); u32 (*rx_desc_get_mpdu_start_tag)(struct hal_rx_desc *desc); u32 (*rx_desc_get_mpdu_ppdu_id)(struct hal_rx_desc *desc); - struct rx_attention *(*rx_desc_get_attention)(struct hal_rx_desc *desc); u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc); - bool (*rx_desc_mac_addr2_valid)(struct hal_rx_desc *desc); - u8* (*rx_desc_mpdu_start_addr2)(struct hal_rx_desc *desc); - bool (*rx_desc_is_da_mcbc)(struct hal_rx_desc *desc); - bool (*dp_rx_h_msdu_done)(struct hal_rx_desc *desc); - bool (*dp_rx_h_l4_cksum_fail)(struct hal_rx_desc *desc); - bool (*dp_rx_h_ip_cksum_fail)(struct hal_rx_desc *desc); - bool (*dp_rx_h_is_decrypted)(struct hal_rx_desc *desc); - u32 (*dp_rx_h_mpdu_err)(struct hal_rx_desc *desc); }; struct hal_ops { @@ -1596,6 +1598,9 @@ struct hal_ops { void (*rx_desc_copy_end_tlv)(struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc); u8 (*rx_desc_get_msdu_src_link_id)(struct hal_rx_desc *desc); + void (*extract_rx_desc_data)(struct hal_rx_desc_data *rx_desc_data, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc *ldesc); u32 (*rx_desc_get_desc_size)(void); }; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 99ff560384520..f19c5612bb7c0 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -301,7 +301,7 @@ int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, } static void ath12k_dp_rx_h_csum_offload(struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info) + struct hal_rx_desc_data *rx_info) { msdu->ip_summed = (rx_info->ip_csum_fail || rx_info->l4_csum_fail) ? CHECKSUM_NONE : CHECKSUM_UNNECESSARY; @@ -310,16 +310,15 @@ static void ath12k_dp_rx_h_csum_offload(struct sk_buff *msdu, static void ath12k_dp_rx_h_mpdu(struct ath12k *ar, struct sk_buff *msdu, struct hal_rx_desc *rx_desc, - struct ath12k_dp_rx_info *rx_info) + struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; struct ath12k_skb_rxcb *rxcb; enum hal_encrypt_type enctype; bool is_decrypted = false; struct ieee80211_hdr *hdr; struct ath12k_peer *peer; struct ieee80211_rx_status *rx_status = rx_info->rx_status; - u32 err_bitmap; + u32 err_bitmap = rx_info->err_bitmap; /* PN for multicast packets will be checked in mac80211 */ rxcb = ATH12K_SKB_RXCB(msdu); @@ -345,9 +344,8 @@ static void ath12k_dp_rx_h_mpdu(struct ath12k *ar, } spin_unlock_bh(&ar->ab->base_lock); - err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc); if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap) - is_decrypted = ath12k_dp_rx_h_is_decrypted(ab, rx_desc); + is_decrypted = rx_info->is_decrypted; /* Clear per-MPDU flags while leaving per-PPDU flags intact */ rx_status->flag &= ~(RX_FLAG_FAILED_FCS_CRC | @@ -374,7 +372,7 @@ static void ath12k_dp_rx_h_mpdu(struct ath12k *ar, ath12k_dp_rx_h_csum_offload(msdu, rx_info); ath12k_dp_rx_h_undecap(ar, msdu, rx_desc, - enctype, rx_status, is_decrypted); + enctype, is_decrypted, rx_info); if (!is_decrypted || rx_info->is_mcbc) return; @@ -388,7 +386,8 @@ static void ath12k_dp_rx_h_mpdu(struct ath12k *ar, static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar, struct sk_buff_head *msdu_list, struct sk_buff *first, struct sk_buff *last, - u8 l3pad_bytes, int msdu_len) + u8 l3pad_bytes, int msdu_len, + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; struct sk_buff *skb; @@ -413,8 +412,8 @@ static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar, } ldesc = (struct hal_rx_desc *)last->data; - rxcb->is_first_msdu = ath12k_dp_rx_h_first_msdu(ab, ldesc); - rxcb->is_last_msdu = ath12k_dp_rx_h_last_msdu(ab, ldesc); + rxcb->is_first_msdu = rx_info->is_first_msdu; + rxcb->is_last_msdu = rx_info->is_last_msdu; /* MSDU spans over multiple buffers because the length of the MSDU * exceeds DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE. So assume the data @@ -475,7 +474,7 @@ static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar, static int ath12k_dp_rx_process_msdu(struct ath12k *ar, struct sk_buff *msdu, struct sk_buff_head *msdu_list, - struct ath12k_dp_rx_info *rx_info) + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; struct hal_rx_desc *rx_desc, *lrx_desc; @@ -496,7 +495,9 @@ static int ath12k_dp_rx_process_msdu(struct ath12k *ar, rx_desc = (struct hal_rx_desc *)msdu->data; lrx_desc = (struct hal_rx_desc *)last_buf->data; - if (!ath12k_dp_rx_h_msdu_done(ab, lrx_desc)) { + + ath12k_wifi7_dp_extract_rx_desc_data(ab, rx_info, rx_desc, lrx_desc); + if (!rx_info->msdu_done) { ath12k_warn(ab, "msdu_done bit in msdu_end is not set\n"); ret = -EIO; goto free_out; @@ -504,8 +505,8 @@ static int ath12k_dp_rx_process_msdu(struct ath12k *ar, rxcb = ATH12K_SKB_RXCB(msdu); rxcb->rx_desc = rx_desc; - msdu_len = ath12k_dp_rx_h_msdu_len(ab, lrx_desc); - l3_pad_bytes = ath12k_dp_rx_h_l3pad(ab, lrx_desc); + msdu_len = rx_info->msdu_len; + l3_pad_bytes = rx_info->l3_pad_bytes; if (rxcb->is_frag) { skb_pull(msdu, hal_rx_desc_sz); @@ -522,7 +523,8 @@ static int ath12k_dp_rx_process_msdu(struct ath12k *ar, } else { ret = ath12k_dp_rx_msdu_coalesce(ar, msdu_list, msdu, last_buf, - l3_pad_bytes, msdu_len); + l3_pad_bytes, msdu_len, + rx_info); if (ret) { ath12k_warn(ab, "failed to coalesce msdu rx buffer%d\n", ret); @@ -530,12 +532,12 @@ static int ath12k_dp_rx_process_msdu(struct ath12k *ar, } } - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu))) { + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu, + rx_info))) { ret = -EINVAL; goto free_out; } - ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info); ath12k_dp_rx_h_ppdu(ar, rx_info); ath12k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_info); @@ -559,7 +561,7 @@ static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab, struct ath12k *ar; struct ath12k_hw_link *hw_links = ag->hw_links; struct ath12k_base *partner_ab; - struct ath12k_dp_rx_info rx_info; + struct hal_rx_desc_data rx_info; u8 hw_link_id, pdev_id; int ret; @@ -764,19 +766,16 @@ int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id, } static bool -ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, struct ath12k_dp_rx_tid *rx_tid) +ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, + struct ath12k_dp_rx_tid *rx_tid, + enum hal_encrypt_type encrypt_type) { - struct ath12k_base *ab = ar->ab; - enum hal_encrypt_type encrypt_type; struct sk_buff *first_frag, *skb; - struct hal_rx_desc *desc; u64 last_pn; u64 cur_pn; first_frag = skb_peek(&rx_tid->rx_frags); - desc = (struct hal_rx_desc *)first_frag->data; - encrypt_type = ath12k_dp_rx_h_enctype(ab, desc); if (encrypt_type != HAL_ENCRYPT_TYPE_CCMP_128 && encrypt_type != HAL_ENCRYPT_TYPE_CCMP_256 && encrypt_type != HAL_ENCRYPT_TYPE_GCMP_128 && @@ -943,27 +942,29 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, return ret; } -static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer, - struct sk_buff *msdu) +static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, + struct ath12k_peer *peer, + enum hal_encrypt_type enctype, + struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; struct ieee80211_rx_status *rxs = IEEE80211_SKB_RXCB(msdu); struct ieee80211_key_conf *key_conf; struct ieee80211_hdr *hdr; - struct ath12k_dp_rx_info rx_info; u8 mic[IEEE80211_CCMP_MIC_LEN]; int head_len, tail_len, ret; size_t data_len; - u32 hdr_len, hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + u32 hdr_len, hal_rx_desc_sz = ab->hal.hal_desc_sz; u8 *key, *data; u8 key_idx; - if (ath12k_dp_rx_h_enctype(ab, rx_desc) != HAL_ENCRYPT_TYPE_TKIP_MIC) + if (enctype != HAL_ENCRYPT_TYPE_TKIP_MIC) return 0; - rx_info.addr2_present = false; - rx_info.rx_status = rxs; + rx_info->addr2_present = false; + rx_info->rx_status = rxs; hdr = (struct ieee80211_hdr *)(msdu->data + hal_rx_desc_sz); hdr_len = ieee80211_hdrlen(hdr->frame_control); @@ -991,18 +992,19 @@ static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer (ATH12K_SKB_RXCB(msdu))->is_first_msdu = true; (ATH12K_SKB_RXCB(msdu))->is_last_msdu = true; - ath12k_dp_rx_h_fetch_info(ab, rx_desc, &rx_info); + ath12k_wifi7_dp_extract_rx_desc_data(ab, rx_info, rx_desc, rx_desc); rxs->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_MMIC_STRIPPED | RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED; skb_pull(msdu, hal_rx_desc_sz); - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu))) + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu, + rx_info))) return -EINVAL; - ath12k_dp_rx_h_ppdu(ar, &rx_info); + ath12k_dp_rx_h_ppdu(ar, rx_info); ath12k_dp_rx_h_undecap(ar, msdu, rx_desc, - HAL_ENCRYPT_TYPE_TKIP_MIC, rxs, true); + HAL_ENCRYPT_TYPE_TKIP_MIC, true, rx_info); ieee80211_rx(ath12k_ar_to_hw(ar), msdu); return -EINVAL; } @@ -1010,13 +1012,12 @@ static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer static int ath12k_dp_rx_h_defrag(struct ath12k *ar, struct ath12k_peer *peer, struct ath12k_dp_rx_tid *rx_tid, - struct sk_buff **defrag_skb) + struct sk_buff **defrag_skb, + enum hal_encrypt_type enctype, + struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; - struct hal_rx_desc *rx_desc; struct sk_buff *skb, *first_frag, *last_frag; struct ieee80211_hdr *hdr; - enum hal_encrypt_type enctype; bool is_decrypted = false; int msdu_len = 0; int extra_space; @@ -1027,13 +1028,10 @@ static int ath12k_dp_rx_h_defrag(struct ath12k *ar, skb_queue_walk(&rx_tid->rx_frags, skb) { flags = 0; - rx_desc = (struct hal_rx_desc *)skb->data; hdr = (struct ieee80211_hdr *)(skb->data + hal_rx_desc_sz); - enctype = ath12k_dp_rx_h_enctype(ab, rx_desc); if (enctype != HAL_ENCRYPT_TYPE_OPEN) - is_decrypted = ath12k_dp_rx_h_is_decrypted(ab, - rx_desc); + is_decrypted = rx_info->is_decrypted; if (is_decrypted) { if (skb != first_frag) @@ -1069,7 +1067,7 @@ static int ath12k_dp_rx_h_defrag(struct ath12k *ar, hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); ATH12K_SKB_RXCB(first_frag)->is_frag = 1; - if (ath12k_dp_rx_h_verify_tkip_mic(ar, peer, first_frag)) + if (ath12k_dp_rx_h_verify_tkip_mic(ar, peer, enctype, first_frag, rx_info)) first_frag = NULL; *defrag_skb = first_frag; @@ -1078,28 +1076,25 @@ static int ath12k_dp_rx_h_defrag(struct ath12k *ar, static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, struct sk_buff *msdu, - struct hal_reo_dest_ring *ring_desc) + struct hal_reo_dest_ring *ring_desc, + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; - struct hal_rx_desc *rx_desc; struct ath12k_peer *peer; struct ath12k_dp_rx_tid *rx_tid; struct sk_buff *defrag_skb = NULL; - u32 peer_id; + u32 peer_id = rx_info->peer_id; u16 seqno, frag_no; - u8 tid; + u8 tid = rx_info->tid; int ret = 0; bool more_frags; + enum hal_encrypt_type enctype = rx_info->enctype; - rx_desc = (struct hal_rx_desc *)msdu->data; - peer_id = ath12k_dp_rx_h_peer_id(ab, rx_desc); - tid = ath12k_dp_rx_h_tid(ab, rx_desc); - seqno = ath12k_dp_rx_h_seq_no(ab, rx_desc); frag_no = ath12k_dp_rx_h_frag_no(ab, msdu); more_frags = ath12k_dp_rx_h_more_frags(ab, msdu); + seqno = rx_info->seq_no; - if (!ath12k_dp_rx_h_seq_ctrl_valid(ab, rx_desc) || - !ath12k_dp_rx_h_fc_valid(ab, rx_desc) || + if (!rx_info->seq_ctl_valid || !rx_info->fc_valid || tid > IEEE80211_NUM_TIDS) return -EINVAL; @@ -1179,10 +1174,11 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, if (!peer) goto err_frags_cleanup; - if (!ath12k_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid)) + if (!ath12k_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid, enctype)) goto err_frags_cleanup; - if (ath12k_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb)) + if (ath12k_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb, + enctype, rx_info)) goto err_frags_cleanup; if (!defrag_skb) @@ -1210,6 +1206,7 @@ ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc, struct ath12k_base *ab = ar->ab; struct sk_buff *msdu; struct ath12k_skb_rxcb *rxcb; + struct hal_rx_desc_data rx_info; struct hal_rx_desc *rx_desc; u16 msdu_len; u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; @@ -1260,7 +1257,9 @@ ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc, } rx_desc = (struct hal_rx_desc *)msdu->data; - msdu_len = ath12k_dp_rx_h_msdu_len(ar->ab, rx_desc); + ath12k_wifi7_dp_extract_rx_desc_data(ab, &rx_info, rx_desc, rx_desc); + + msdu_len = rx_info.msdu_len; if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { ath12k_warn(ar->ab, "invalid msdu leng %u", msdu_len); ath12k_dbg_dump(ar->ab, ATH12K_DBG_DATA, NULL, "", rx_desc, @@ -1271,7 +1270,7 @@ ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc, skb_put(msdu, hal_rx_desc_sz + msdu_len); - if (ath12k_dp_rx_frag_h_mpdu(ar, msdu, desc)) { + if (ath12k_dp_rx_frag_h_mpdu(ar, msdu, desc, &rx_info)) { dev_kfree_skb_any(msdu); ath12k_dp_rx_link_desc_return(ar->ab, &desc->buf_addr_info, HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); @@ -1439,18 +1438,16 @@ static void ath12k_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, } static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info, + struct hal_rx_desc_data *rx_info, struct sk_buff_head *msdu_list) { struct ath12k_base *ab = ar->ab; - u16 msdu_len; + u16 msdu_len = rx_info->msdu_len; struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; - u8 l3pad_bytes; + u8 l3pad_bytes = rx_info->l3_pad_bytes; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; - msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc); - if (!rxcb->is_frag && ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE)) { /* First buffer will be freed by the caller, so deduct it's length */ msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - hal_rx_desc_sz); @@ -1465,7 +1462,7 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, if (rxcb->is_continuation) return -EINVAL; - if (!ath12k_dp_rx_h_msdu_done(ab, desc)) { + if (!rx_info->msdu_done) { ath12k_warn(ar->ab, "msdu_done bit not set in null_q_des processing\n"); __skb_queue_purge(msdu_list); @@ -1484,18 +1481,15 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, if (rxcb->is_frag) { skb_pull(msdu, hal_rx_desc_sz); } else { - l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc); - if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) return -EINVAL; skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); } - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu))) + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu, rx_info))) return -EINVAL; - ath12k_dp_rx_h_fetch_info(ab, desc, rx_info); ath12k_dp_rx_h_ppdu(ar, rx_info); ath12k_dp_rx_h_mpdu(ar, msdu, desc, rx_info); @@ -1509,20 +1503,17 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, } static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info) + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; - u16 msdu_len; + u16 msdu_len = rx_info->msdu_len; struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; - u8 l3pad_bytes; + u8 l3pad_bytes = rx_info->l3_pad_bytes; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; - rxcb->is_first_msdu = ath12k_dp_rx_h_first_msdu(ab, desc); - rxcb->is_last_msdu = ath12k_dp_rx_h_last_msdu(ab, desc); - - l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc); - msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc); + rxcb->is_first_msdu = rx_info->is_first_msdu; + rxcb->is_last_msdu = rx_info->is_last_msdu; if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) { ath12k_dbg(ab, ATH12K_DBG_DATA, @@ -1535,7 +1526,7 @@ static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu))) + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu, rx_info))) return true; ath12k_dp_rx_h_ppdu(ar, rx_info); @@ -1544,27 +1535,22 @@ static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, RX_FLAG_DECRYPTED); ath12k_dp_rx_h_undecap(ar, msdu, desc, - HAL_ENCRYPT_TYPE_TKIP_MIC, rx_info->rx_status, false); + HAL_ENCRYPT_TYPE_TKIP_MIC, false, rx_info); return false; } static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info) + struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); - struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; bool drop = false; - u32 err_bitmap; ar->ab->device_stats.rxdma_error[rxcb->err_code]++; switch (rxcb->err_code) { case HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR: case HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR: - err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc); - if (err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) { - ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info); + if (rx_info->err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) { drop = ath12k_dp_rx_h_tkip_mic_err(ar, msdu, rx_info); break; } @@ -1581,7 +1567,7 @@ static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, } static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu, - struct ath12k_dp_rx_info *rx_info, + struct hal_rx_desc_data *rx_info, struct sk_buff_head *msdu_list) { struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); @@ -1616,14 +1602,17 @@ static void ath12k_dp_rx_wbm_err(struct ath12k *ar, struct sk_buff *msdu, struct sk_buff_head *msdu_list) { + struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); struct ieee80211_rx_status rxs = {}; - struct ath12k_dp_rx_info rx_info; + struct hal_rx_desc_data rx_info; bool drop = true; rx_info.addr2_present = false; rx_info.rx_status = &rxs; + ath12k_wifi7_dp_extract_rx_desc_data(ar->ab, &rx_info, rx_desc, rx_desc); + switch (rxcb->err_rel_src) { case HAL_WBM_REL_SRC_MODULE_REO: drop = ath12k_dp_rx_h_reo_err(ar, msdu, &rx_info, msdu_list); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 45b856aaaa124..f258472bc1fc6 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -44,4 +44,12 @@ int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, struct ath12k_dp_rx_tid *rx_tid, u32 ba_win_sz, u16 ssn, bool update_ssn); +static inline +void ath12k_wifi7_dp_extract_rx_desc_data(struct ath12k_base *ab, + struct hal_rx_desc_data *rx_info, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc *ldesc) +{ + ab->hw_params->hal_ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); +} #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index bf09a40c91d9d..2e84c830d9b2b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -6,12 +6,14 @@ #include "hal_desc.h" #include "hal_qcn9274.h" +static inline bool ath12k_hal_rx_desc_get_first_msdu_qcn9274(struct hal_rx_desc *desc) { return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, RX_MSDU_END_INFO5_FIRST_MSDU); } +static inline bool ath12k_hal_rx_desc_get_last_msdu_qcn9274(struct hal_rx_desc *desc) { return !!le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, @@ -24,95 +26,114 @@ u8 ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274(struct hal_rx_desc *desc) RX_MSDU_END_INFO5_L3_HDR_PADDING); } +static inline bool ath12k_hal_rx_desc_encrypt_valid_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); } +static inline u32 ath12k_hal_rx_desc_get_encrypt_type_qcn9274(struct hal_rx_desc *desc) { + if (!ath12k_hal_rx_desc_encrypt_valid_qcn9274(desc)) + return HAL_ENCRYPT_TYPE_OPEN; + return le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info2, RX_MPDU_START_INFO2_ENC_TYPE); } +static inline u8 ath12k_hal_rx_desc_get_decap_type_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, RX_MSDU_END_INFO11_DECAP_FORMAT); } +static inline u8 ath12k_hal_rx_desc_get_mesh_ctl_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info11, RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); } +static inline bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); } +static inline bool ath12k_hal_rx_desc_get_mpdu_fc_valid_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); } +static inline u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_SEQ_NUM); } +static inline u16 ath12k_hal_rx_desc_get_msdu_len_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info10, RX_MSDU_END_INFO10_MSDU_LENGTH); } +static inline u8 ath12k_hal_rx_desc_get_msdu_sgi_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_SGI); } +static inline u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_RATE_MCS); } +static inline u8 ath12k_hal_rx_desc_get_msdu_rx_bw_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_RECV_BW); } +static inline u32 ath12k_hal_rx_desc_get_msdu_freq_qcn9274(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.phy_meta_data); } +static inline u8 ath12k_hal_rx_desc_get_msdu_pkt_type_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_PKT_TYPE); } +static inline u8 ath12k_hal_rx_desc_get_msdu_nss_qcn9274(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.qcn9274_compact.msdu_end.info12, RX_MSDU_END_INFO12_MIMO_SS_BITMAP); } +static inline u8 ath12k_hal_rx_desc_get_mpdu_tid_qcn9274(struct hal_rx_desc *desc) { return le16_get_bits(desc->u.qcn9274_compact.msdu_end.info5, RX_MSDU_END_INFO5_TID); } +static inline u16 ath12k_hal_rx_desc_get_mpdu_peer_id_qcn9274(struct hal_rx_desc *desc) { return __le16_to_cpu(desc->u.qcn9274_compact.mpdu_start.sw_peer_id); @@ -152,41 +173,48 @@ u32 ath12k_hal_rx_desc_get_msdu_end_offset_qcn9274(void) return offsetof(struct hal_rx_desc_qcn9274_compact, msdu_end); } +static inline bool ath12k_hal_rx_desc_mac_addr2_valid_qcn9274(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.qcn9274_compact.mpdu_start.info4) & RX_MPDU_START_INFO4_MAC_ADDR2_VALID; } +static inline u8 *ath12k_hal_rx_desc_mpdu_start_addr2_qcn9274(struct hal_rx_desc *desc) { return desc->u.qcn9274_compact.mpdu_start.addr2; } +static inline bool ath12k_hal_rx_desc_is_da_mcbc_qcn9274(struct hal_rx_desc *desc) { return __le16_to_cpu(desc->u.qcn9274_compact.msdu_end.info5) & RX_MSDU_END_INFO5_DA_IS_MCBC; } +static inline bool ath12k_hal_rx_h_msdu_done_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14, RX_MSDU_END_INFO14_MSDU_DONE); } +static inline bool ath12k_hal_rx_h_l4_cksum_fail_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info13, RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); } +static inline bool ath12k_hal_rx_h_ip_cksum_fail_qcn9274(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.qcn9274_compact.msdu_end.info13, RX_MSDU_END_INFO13_IP_CKSUM_FAIL); } +static inline bool ath12k_hal_rx_h_is_decrypted_qcn9274(struct hal_rx_desc *desc) { return (le32_get_bits(desc->u.qcn9274_compact.msdu_end.info14, @@ -215,7 +243,7 @@ u32 ath12k_hal_rx_msdu_end_wmask_get_qcn9274(void) return QCN9274_MSDU_END_WMASK; } -u32 ath12k_hal_rx_h_mpdu_err_qcn9274(struct hal_rx_desc *desc) +static u32 ath12k_hal_rx_h_mpdu_err_qcn9274(struct hal_rx_desc *desc) { u32 info = __le32_to_cpu(desc->u.qcn9274_compact.msdu_end.info13); u32 errmap = 0; @@ -305,3 +333,37 @@ void ath12k_hal_rx_desc_get_dot11_hdr_qcn9274(struct hal_rx_desc *desc, } hdr->seq_ctrl = desc->u.qcn9274_compact.mpdu_start.seq_ctrl; } + +void ath12k_hal_extract_rx_desc_data_qcn9274(struct hal_rx_desc_data *rx_desc_data, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc *ldesc) +{ + rx_desc_data->is_first_msdu = ath12k_hal_rx_desc_get_first_msdu_qcn9274(ldesc); + rx_desc_data->is_last_msdu = ath12k_hal_rx_desc_get_last_msdu_qcn9274(ldesc); + rx_desc_data->l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274(ldesc); + rx_desc_data->enctype = ath12k_hal_rx_desc_get_encrypt_type_qcn9274(rx_desc); + rx_desc_data->decap_type = ath12k_hal_rx_desc_get_decap_type_qcn9274(rx_desc); + rx_desc_data->mesh_ctrl_present = + ath12k_hal_rx_desc_get_mesh_ctl_qcn9274(rx_desc); + rx_desc_data->seq_ctl_valid = + ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcn9274(rx_desc); + rx_desc_data->fc_valid = ath12k_hal_rx_desc_get_mpdu_fc_valid_qcn9274(rx_desc); + rx_desc_data->seq_no = ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcn9274(rx_desc); + rx_desc_data->msdu_len = ath12k_hal_rx_desc_get_msdu_len_qcn9274(ldesc); + rx_desc_data->sgi = ath12k_hal_rx_desc_get_msdu_sgi_qcn9274(rx_desc); + rx_desc_data->rate_mcs = ath12k_hal_rx_desc_get_msdu_rate_mcs_qcn9274(rx_desc); + rx_desc_data->bw = ath12k_hal_rx_desc_get_msdu_rx_bw_qcn9274(rx_desc); + rx_desc_data->phy_meta_data = ath12k_hal_rx_desc_get_msdu_freq_qcn9274(rx_desc); + rx_desc_data->pkt_type = ath12k_hal_rx_desc_get_msdu_pkt_type_qcn9274(rx_desc); + rx_desc_data->nss = hweight8(ath12k_hal_rx_desc_get_msdu_nss_qcn9274(rx_desc)); + rx_desc_data->tid = ath12k_hal_rx_desc_get_mpdu_tid_qcn9274(rx_desc); + rx_desc_data->peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_qcn9274(rx_desc); + rx_desc_data->addr2_present = ath12k_hal_rx_desc_mac_addr2_valid_qcn9274(rx_desc); + rx_desc_data->addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_qcn9274(rx_desc); + rx_desc_data->is_mcbc = ath12k_hal_rx_desc_is_da_mcbc_qcn9274(rx_desc); + rx_desc_data->msdu_done = ath12k_hal_rx_h_msdu_done_qcn9274(ldesc); + rx_desc_data->l4_csum_fail = ath12k_hal_rx_h_l4_cksum_fail_qcn9274(rx_desc); + rx_desc_data->ip_csum_fail = ath12k_hal_rx_h_ip_cksum_fail_qcn9274(rx_desc); + rx_desc_data->is_decrypted = ath12k_hal_rx_h_is_decrypted_qcn9274(rx_desc); + rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_qcn9274(rx_desc); +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h index 562156bbd726d..9a918824e093f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h @@ -12,25 +12,7 @@ #include "../hal.h" #include "hal_rx.h" -bool ath12k_hal_rx_desc_get_first_msdu_qcn9274(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_get_last_msdu_qcn9274(struct hal_rx_desc *desc); u8 ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_encrypt_valid_qcn9274(struct hal_rx_desc *desc); -u32 ath12k_hal_rx_desc_get_encrypt_type_qcn9274(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_decap_type_qcn9274(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_mesh_ctl_qcn9274(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcn9274(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_get_mpdu_fc_valid_qcn9274(struct hal_rx_desc *desc); -u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcn9274(struct hal_rx_desc *desc); -u16 ath12k_hal_rx_desc_get_msdu_len_qcn9274(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_sgi_qcn9274(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_qcn9274(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_rx_bw_qcn9274(struct hal_rx_desc *desc); -u32 ath12k_hal_rx_desc_get_msdu_freq_qcn9274(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_pkt_type_qcn9274(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_nss_qcn9274(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_mpdu_tid_qcn9274(struct hal_rx_desc *desc); -u16 ath12k_hal_rx_desc_get_mpdu_peer_id_qcn9274(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_copy_end_tlv_qcn9274(struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc); u32 ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274(struct hal_rx_desc *desc); @@ -38,21 +20,16 @@ void ath12k_hal_rx_desc_set_msdu_len_qcn9274(struct hal_rx_desc *desc, u16 len); u8 *ath12k_hal_rx_desc_get_msdu_payload_qcn9274(struct hal_rx_desc *desc); u32 ath12k_hal_rx_desc_get_mpdu_start_offset_qcn9274(void); u32 ath12k_hal_rx_desc_get_msdu_end_offset_qcn9274(void); -bool ath12k_hal_rx_desc_mac_addr2_valid_qcn9274(struct hal_rx_desc *desc); -u8 *ath12k_hal_rx_desc_mpdu_start_addr2_qcn9274(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_is_da_mcbc_qcn9274(struct hal_rx_desc *desc); -bool ath12k_hal_rx_h_msdu_done_qcn9274(struct hal_rx_desc *desc); -bool ath12k_hal_rx_h_l4_cksum_fail_qcn9274(struct hal_rx_desc *desc); -bool ath12k_hal_rx_h_ip_cksum_fail_qcn9274(struct hal_rx_desc *desc); -bool ath12k_hal_rx_h_is_decrypted_qcn9274(struct hal_rx_desc *desc); u32 ath12k_hal_get_rx_desc_size_qcn9274(void); u8 ath12k_hal_rx_desc_get_msdu_src_link_qcn9274(struct hal_rx_desc *desc); u16 ath12k_hal_rx_mpdu_start_wmask_get_qcn9274(void); u32 ath12k_hal_rx_msdu_end_wmask_get_qcn9274(void); -u32 ath12k_hal_rx_h_mpdu_err_qcn9274(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_get_crypto_hdr_qcn9274(struct hal_rx_desc *desc, u8 *crypto_hdr, enum hal_encrypt_type enctype); void ath12k_hal_rx_desc_get_dot11_hdr_qcn9274(struct hal_rx_desc *desc, struct ieee80211_hdr *hdr); +void ath12k_hal_extract_rx_desc_data_qcn9274(struct hal_rx_desc_data *rx_desc_data, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc *ldesc); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 11b03452494c5..0fa1d9fad2e19 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -7,12 +7,14 @@ #include "hal_desc.h" #include "hal_wcn7850.h" +static inline bool ath12k_hal_rx_desc_get_first_msdu_wcn7850(struct hal_rx_desc *desc) { return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5, RX_MSDU_END_INFO5_FIRST_MSDU); } +static inline bool ath12k_hal_rx_desc_get_last_msdu_wcn7850(struct hal_rx_desc *desc) { return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5, @@ -25,95 +27,114 @@ u8 ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850(struct hal_rx_desc *desc) RX_MSDU_END_INFO5_L3_HDR_PADDING); } +static inline bool ath12k_hal_rx_desc_encrypt_valid_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); } +static inline u32 ath12k_hal_rx_desc_get_encrypt_type_wcn7850(struct hal_rx_desc *desc) { + if (!ath12k_hal_rx_desc_encrypt_valid_wcn7850(desc)) + return HAL_ENCRYPT_TYPE_OPEN; + return le32_get_bits(desc->u.wcn7850.mpdu_start.info2, RX_MPDU_START_INFO2_ENC_TYPE); } +static inline u8 ath12k_hal_rx_desc_get_decap_type_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info11, RX_MSDU_END_INFO11_DECAP_FORMAT); } +static inline u8 ath12k_hal_rx_desc_get_mesh_ctl_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info11, RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); } +static inline bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); } +static inline bool ath12k_hal_rx_desc_get_mpdu_fc_valid_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); } +static inline u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.mpdu_start.info4, RX_MPDU_START_INFO4_MPDU_SEQ_NUM); } +static inline u16 ath12k_hal_rx_desc_get_msdu_len_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info10, RX_MSDU_END_INFO10_MSDU_LENGTH); } +static inline u8 ath12k_hal_rx_desc_get_msdu_sgi_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_SGI); } +static inline u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_RATE_MCS); } +static inline u8 ath12k_hal_rx_desc_get_msdu_rx_bw_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_RECV_BW); } +static inline u32 ath12k_hal_rx_desc_get_msdu_freq_wcn7850(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.wcn7850.msdu_end.phy_meta_data); } +static inline u8 ath12k_hal_rx_desc_get_msdu_pkt_type_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_PKT_TYPE); } +static inline u8 ath12k_hal_rx_desc_get_msdu_nss_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.msdu_end.info12, RX_MSDU_END_INFO12_MIMO_SS_BITMAP); } +static inline u8 ath12k_hal_rx_desc_get_mpdu_tid_wcn7850(struct hal_rx_desc *desc) { return le32_get_bits(desc->u.wcn7850.mpdu_start.info2, RX_MPDU_START_INFO2_TID); } +static inline u16 ath12k_hal_rx_desc_get_mpdu_peer_id_wcn7850(struct hal_rx_desc *desc) { return __le16_to_cpu(desc->u.wcn7850.mpdu_start.sw_peer_id); @@ -162,41 +183,48 @@ u32 ath12k_hal_rx_desc_get_msdu_end_offset_wcn7850(void) return offsetof(struct hal_rx_desc_wcn7850, msdu_end_tag); } +static inline bool ath12k_hal_rx_desc_mac_addr2_valid_wcn7850(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.wcn7850.mpdu_start.info4) & RX_MPDU_START_INFO4_MAC_ADDR2_VALID; } +static inline u8 *ath12k_hal_rx_desc_mpdu_start_addr2_wcn7850(struct hal_rx_desc *desc) { return desc->u.wcn7850.mpdu_start.addr2; } +static inline bool ath12k_hal_rx_desc_is_da_mcbc_wcn7850(struct hal_rx_desc *desc) { return __le32_to_cpu(desc->u.wcn7850.msdu_end.info13) & RX_MSDU_END_INFO13_MCAST_BCAST; } +static inline bool ath12k_hal_rx_h_msdu_done_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.msdu_end.info14, RX_MSDU_END_INFO14_MSDU_DONE); } +static inline bool ath12k_hal_rx_h_l4_cksum_fail_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13, RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); } +static inline bool ath12k_hal_rx_h_ip_cksum_fail_wcn7850(struct hal_rx_desc *desc) { return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13, RX_MSDU_END_INFO13_IP_CKSUM_FAIL); } +static inline bool ath12k_hal_rx_h_is_decrypted_wcn7850(struct hal_rx_desc *desc) { return (le32_get_bits(desc->u.wcn7850.msdu_end.info14, @@ -214,7 +242,7 @@ u8 ath12k_hal_rx_desc_get_msdu_src_link_wcn7850(struct hal_rx_desc *desc) return 0; } -u32 ath12k_hal_rx_h_mpdu_err_wcn7850(struct hal_rx_desc *desc) +static u32 ath12k_hal_rx_h_mpdu_err_wcn7850(struct hal_rx_desc *desc) { u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info13); u32 errmap = 0; @@ -300,3 +328,37 @@ void ath12k_hal_rx_desc_get_dot11_hdr_wcn7850(struct hal_rx_desc *desc, } hdr->seq_ctrl = desc->u.wcn7850.mpdu_start.seq_ctrl; } + +void ath12k_hal_extract_rx_desc_data_wcn7850(struct hal_rx_desc_data *rx_desc_data, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc *ldesc) +{ + rx_desc_data->is_first_msdu = ath12k_hal_rx_desc_get_first_msdu_wcn7850(ldesc); + rx_desc_data->is_last_msdu = ath12k_hal_rx_desc_get_last_msdu_wcn7850(ldesc); + rx_desc_data->l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850(ldesc); + rx_desc_data->enctype = ath12k_hal_rx_desc_get_encrypt_type_wcn7850(rx_desc); + rx_desc_data->decap_type = ath12k_hal_rx_desc_get_decap_type_wcn7850(rx_desc); + rx_desc_data->mesh_ctrl_present = + ath12k_hal_rx_desc_get_mesh_ctl_wcn7850(rx_desc); + rx_desc_data->seq_ctl_valid = + ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_wcn7850(rx_desc); + rx_desc_data->fc_valid = ath12k_hal_rx_desc_get_mpdu_fc_valid_wcn7850(rx_desc); + rx_desc_data->seq_no = ath12k_hal_rx_desc_get_mpdu_start_seq_no_wcn7850(rx_desc); + rx_desc_data->msdu_len = ath12k_hal_rx_desc_get_msdu_len_wcn7850(ldesc); + rx_desc_data->sgi = ath12k_hal_rx_desc_get_msdu_sgi_wcn7850(rx_desc); + rx_desc_data->rate_mcs = ath12k_hal_rx_desc_get_msdu_rate_mcs_wcn7850(rx_desc); + rx_desc_data->bw = ath12k_hal_rx_desc_get_msdu_rx_bw_wcn7850(rx_desc); + rx_desc_data->phy_meta_data = ath12k_hal_rx_desc_get_msdu_freq_wcn7850(rx_desc); + rx_desc_data->pkt_type = ath12k_hal_rx_desc_get_msdu_pkt_type_wcn7850(rx_desc); + rx_desc_data->nss = hweight8(ath12k_hal_rx_desc_get_msdu_nss_wcn7850(rx_desc)); + rx_desc_data->tid = ath12k_hal_rx_desc_get_mpdu_tid_wcn7850(rx_desc); + rx_desc_data->peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_wcn7850(rx_desc); + rx_desc_data->addr2_present = ath12k_hal_rx_desc_mac_addr2_valid_wcn7850(rx_desc); + rx_desc_data->addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_wcn7850(rx_desc); + rx_desc_data->is_mcbc = ath12k_hal_rx_desc_is_da_mcbc_wcn7850(rx_desc); + rx_desc_data->msdu_done = ath12k_hal_rx_h_msdu_done_wcn7850(ldesc); + rx_desc_data->l4_csum_fail = ath12k_hal_rx_h_l4_cksum_fail_wcn7850(rx_desc); + rx_desc_data->ip_csum_fail = ath12k_hal_rx_h_ip_cksum_fail_wcn7850(rx_desc); + rx_desc_data->is_decrypted = ath12k_hal_rx_h_is_decrypted_wcn7850(rx_desc); + rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_wcn7850(rx_desc); +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h index c9a6b7ffb6078..a90978b2a4543 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -10,25 +10,7 @@ #include "../hal.h" #include "hal_rx.h" -bool ath12k_hal_rx_desc_get_first_msdu_wcn7850(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_get_last_msdu_wcn7850(struct hal_rx_desc *desc); u8 ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_encrypt_valid_wcn7850(struct hal_rx_desc *desc); -u32 ath12k_hal_rx_desc_get_encrypt_type_wcn7850(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_decap_type_wcn7850(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_mesh_ctl_wcn7850(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_wcn7850(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_get_mpdu_fc_valid_wcn7850(struct hal_rx_desc *desc); -u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_wcn7850(struct hal_rx_desc *desc); -u16 ath12k_hal_rx_desc_get_msdu_len_wcn7850(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_sgi_wcn7850(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_wcn7850(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_rx_bw_wcn7850(struct hal_rx_desc *desc); -u32 ath12k_hal_rx_desc_get_msdu_freq_wcn7850(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_pkt_type_wcn7850(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_msdu_nss_wcn7850(struct hal_rx_desc *desc); -u8 ath12k_hal_rx_desc_get_mpdu_tid_wcn7850(struct hal_rx_desc *desc); -u16 ath12k_hal_rx_desc_get_mpdu_peer_id_wcn7850(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_copy_end_tlv_wcn7850(struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc); u32 ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850(struct hal_rx_desc *desc); @@ -37,19 +19,14 @@ void ath12k_hal_rx_desc_set_msdu_len_wcn7850(struct hal_rx_desc *desc, u16 len); u8 *ath12k_hal_rx_desc_get_msdu_payload_wcn7850(struct hal_rx_desc *desc); u32 ath12k_hal_rx_desc_get_mpdu_start_offset_wcn7850(void); u32 ath12k_hal_rx_desc_get_msdu_end_offset_wcn7850(void); -bool ath12k_hal_rx_desc_mac_addr2_valid_wcn7850(struct hal_rx_desc *desc); -u8 *ath12k_hal_rx_desc_mpdu_start_addr2_wcn7850(struct hal_rx_desc *desc); -bool ath12k_hal_rx_desc_is_da_mcbc_wcn7850(struct hal_rx_desc *desc); -bool ath12k_hal_rx_h_msdu_done_wcn7850(struct hal_rx_desc *desc); -bool ath12k_hal_rx_h_l4_cksum_fail_wcn7850(struct hal_rx_desc *desc); -bool ath12k_hal_rx_h_ip_cksum_fail_wcn7850(struct hal_rx_desc *desc); -bool ath12k_hal_rx_h_is_decrypted_wcn7850(struct hal_rx_desc *desc); u32 ath12k_hal_get_rx_desc_size_wcn7850(void); u8 ath12k_hal_rx_desc_get_msdu_src_link_wcn7850(struct hal_rx_desc *desc); -u32 ath12k_hal_rx_h_mpdu_err_wcn7850(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_get_crypto_hdr_wcn7850(struct hal_rx_desc *desc, u8 *crypto_hdr, enum hal_encrypt_type enctype); void ath12k_hal_rx_desc_get_dot11_hdr_wcn7850(struct hal_rx_desc *desc, struct ieee80211_hdr *hdr); +void ath12k_hal_extract_rx_desc_data_wcn7850(struct hal_rx_desc_data *rx_desc_data, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc *ldesc); #endif From c1510186a71ab3ace4167aec3d30986575f13e8a Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Wed, 10 Sep 2025 23:44:13 +0530 Subject: [PATCH 040/140] wifi: ath12k: Remove hal_rx_ops and merge into hal_ops Move following ops from hal_rx_ops to hal_ops to simplify the HAL interface. rx_desc_get_l3_pad_bytes rx_desc_get_mpdu_start_tag rx_desc_get_mpdu_ppdu_id rx_desc_get_msdu_payload Remove the hal_rx_ops as they become unused with this change. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250910181414.2062280-8-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 2 -- drivers/net/wireless/ath/ath12k/dp_mon.c | 2 +- drivers/net/wireless/ath/ath12k/dp_rx.h | 6 +++--- drivers/net/wireless/ath/ath12k/hal.c | 22 +++++++-------------- drivers/net/wireless/ath/ath12k/hal.h | 14 ++++--------- drivers/net/wireless/ath/ath12k/wifi7/pci.c | 2 -- 6 files changed, 15 insertions(+), 33 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 7eaf098ccc8f5..985616950b0d7 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1203,8 +1203,6 @@ struct ath12k_base { bool fw_features_valid; } fw; - const struct hal_rx_ops *hal_rx_ops; - struct completion restart_completed; #ifdef CONFIG_ACPI diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index bb98257c8d427..a292658a78c24 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2076,7 +2076,7 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar, rx_desc = (struct hal_rx_desc *)head_msdu->data; hdr_desc = - ab->hal_rx_ops->rx_desc_get_msdu_payload(rx_desc); + ab->hw_params->hal_ops->rx_desc_get_msdu_payload(rx_desc); /* Base size */ wh = (struct ieee80211_hdr_3addr *)hdr_desc; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 38d9b11eff762..1a8802c37443b 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -123,7 +123,7 @@ static inline u16 ath12k_dp_rx_h_frag_no(struct ath12k_base *ab, static inline u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, struct hal_rx_desc *desc) { - return ab->hal_rx_ops->rx_desc_get_l3_pad_bytes(desc); + return ab->hw_params->hal_ops->rx_desc_get_l3_pad_bytes(desc); } static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab, @@ -143,7 +143,7 @@ static inline void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab, static inline u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc) { - return ab->hal_rx_ops->rx_desc_get_mpdu_ppdu_id(rx_desc); + return ab->hw_params->hal_ops->rx_desc_get_mpdu_ppdu_id(rx_desc); } static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, @@ -151,7 +151,7 @@ static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, { u32 tlv_tag; - tlv_tag = ab->hal_rx_ops->rx_desc_get_mpdu_start_tag(rx_desc); + tlv_tag = ab->hw_params->hal_ops->rx_desc_get_mpdu_start_tag(rx_desc); return tlv_tag == HAL_RX_MPDU_START; } diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index db6294ba6771b..a14a7d8dc69f2 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -406,13 +406,6 @@ static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) return 0; } -const struct hal_rx_ops hal_rx_qcn9274_compact_ops = { - .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274, - .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, - .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, -}; -EXPORT_SYMBOL(hal_rx_qcn9274_compact_ops); - const struct hal_ops hal_qcn9274_ops = { .create_srng_config = ath12k_hal_srng_create_config_qcn9274, .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, @@ -423,6 +416,9 @@ const struct hal_ops hal_qcn9274_ops = { .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_qcn9274, .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_qcn9274, .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_qcn9274, + .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274, + .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, + .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, }; EXPORT_SYMBOL(hal_qcn9274_ops); @@ -550,14 +546,6 @@ static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) return 0; } -const struct hal_rx_ops hal_rx_wcn7850_ops = { - .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850, - .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, - .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, - .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, -}; -EXPORT_SYMBOL(hal_rx_wcn7850_ops); - const struct hal_ops hal_wcn7850_ops = { .create_srng_config = ath12k_hal_srng_create_config_wcn7850, .tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map, @@ -568,6 +556,10 @@ const struct hal_ops hal_wcn7850_ops = { .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_wcn7850, .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_wcn7850, .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_wcn7850, + .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850, + .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, + .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, + .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, }; EXPORT_SYMBOL(hal_wcn7850_ops); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 38f07f5a72000..81ceb296cb91c 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1579,13 +1579,6 @@ enum nl80211_he_ru_alloc ath12k_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones) return ret; } -struct hal_rx_ops { - u8 (*rx_desc_get_l3_pad_bytes)(struct hal_rx_desc *desc); - u32 (*rx_desc_get_mpdu_start_tag)(struct hal_rx_desc *desc); - u32 (*rx_desc_get_mpdu_ppdu_id)(struct hal_rx_desc *desc); - u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc); -}; - struct hal_ops { int (*create_srng_config)(struct ath12k_base *ab); const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; @@ -1602,14 +1595,15 @@ struct hal_ops { struct hal_rx_desc *rx_desc, struct hal_rx_desc *ldesc); u32 (*rx_desc_get_desc_size)(void); + u32 (*rx_desc_get_mpdu_start_tag)(struct hal_rx_desc *desc); + u32 (*rx_desc_get_mpdu_ppdu_id)(struct hal_rx_desc *desc); + u8 (*rx_desc_get_l3_pad_bytes)(struct hal_rx_desc *desc); + u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc); }; extern const struct hal_ops hal_qcn9274_ops; extern const struct hal_ops hal_wcn7850_ops; -extern const struct hal_rx_ops hal_rx_qcn9274_compact_ops; -extern const struct hal_rx_ops hal_rx_wcn7850_ops; - u32 ath12k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); void ath12k_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, int tid, u32 ba_window_size, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/pci.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c index abdb3b8ff658c..ba8c19c24ae6a 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/pci.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -101,7 +101,6 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; ab->static_window_map = true; ab_pci->pci_ops = &ath12k_wifi7_pci_ops_qcn9274; - ab->hal_rx_ops = &hal_rx_qcn9274_compact_ops; ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major, &soc_hw_version_minor); ab->target_mem_mode = ath12k_core_get_memory_mode(ab); @@ -124,7 +123,6 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; ab->static_window_map = false; ab_pci->pci_ops = &ath12k_wifi7_pci_ops_wcn7850; - ab->hal_rx_ops = &hal_rx_wcn7850_ops; ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major, &soc_hw_version_minor); ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT; From a481732c32457c4abb379c3203d5aeecd4ba05e5 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Wed, 10 Sep 2025 23:44:14 +0530 Subject: [PATCH 041/140] wifi: ath12k: Change the API prefixes to ath12k_wifi7 in tx/rx Change the API prefixes to ath12k_wifi7_ from ath12k_ in all the tx and rx related files within wifi7 directory. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250910181414.2062280-9-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ahb.c | 2 +- drivers/net/wireless/ath/ath12k/dbring.c | 5 +- drivers/net/wireless/ath/ath12k/dp.c | 11 +- drivers/net/wireless/ath/ath12k/dp_mon.c | 28 +- drivers/net/wireless/ath/ath12k/dp_rx.c | 47 ++- drivers/net/wireless/ath/ath12k/hal.h | 15 +- drivers/net/wireless/ath/ath12k/mac.c | 6 +- drivers/net/wireless/ath/ath12k/pci.c | 2 +- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 19 +- drivers/net/wireless/ath/ath12k/wifi7/dp.h | 5 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 372 +++++++++--------- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 66 ++-- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 49 +-- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h | 8 +- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 167 ++++---- .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 82 ++-- .../net/wireless/ath/ath12k/wifi7/hal_tx.c | 13 +- .../net/wireless/ath/ath12k/wifi7/hal_tx.h | 18 +- 18 files changed, 483 insertions(+), 432 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index 8d14813365755..f49f117b90754 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -527,7 +527,7 @@ static int ath12k_ahb_ext_grp_napi_poll(struct napi_struct *napi, int budget) struct ath12k_base *ab = irq_grp->ab; int work_done; - work_done = ath12k_dp_service_srng(ab, irq_grp, budget); + work_done = ath12k_wifi7_dp_service_srng(ab, irq_grp, budget); if (work_done < budget) { napi_complete_done(napi, work_done); ath12k_ahb_ext_grp_enable(irq_grp); diff --git a/drivers/net/wireless/ath/ath12k/dbring.c b/drivers/net/wireless/ath/ath12k/dbring.c index 6604dacea2ae5..093298f8acabd 100644 --- a/drivers/net/wireless/ath/ath12k/dbring.c +++ b/drivers/net/wireless/ath/ath12k/dbring.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2019-2021 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. */ @@ -55,7 +54,7 @@ static int ath12k_dbring_bufs_replenish(struct ath12k *ar, cookie = u32_encode_bits(ar->pdev_idx, DP_RXDMA_BUF_COOKIE_PDEV_ID) | u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID); - ath12k_hal_rx_buf_addr_info_set(desc, paddr, cookie, 0); + ath12k_wifi7_hal_rx_buf_addr_info_set(desc, paddr, cookie, 0); ath12k_hal_srng_access_end(ab, srng); @@ -298,7 +297,7 @@ int ath12k_dbring_buffer_release_event(struct ath12k_base *ab, num_buff_reaped++; - ath12k_hal_rx_buf_addr_info_get(&desc, &paddr, &cookie, &rbm); + ath12k_wifi7_hal_rx_buf_addr_info_get(&desc, &paddr, &cookie, &rbm); buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 4cc4006b18bbc..296d7b17c15bd 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -96,7 +96,7 @@ int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr) } for (tid--; tid >= 0; tid--) - ath12k_dp_rx_peer_tid_delete(ar, peer, tid); + ath12k_wifi7_dp_rx_peer_tid_delete(ar, peer, tid); spin_unlock_bh(&ab->base_lock); @@ -418,7 +418,8 @@ static int ath12k_dp_tx_get_bank_profile(struct ath12k_base *ab, spin_unlock_bh(&dp->tx_bank_lock); if (configure_register) - ath12k_hal_tx_configure_bank_register(ab, bank_config, bank_id); + ath12k_wifi7_hal_tx_configure_bank_register(ab, bank_config, + bank_id); ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt tcl bank_id %d input 0x%x match 0x%x num_users %u", bank_id, bank_config, dp->bank_profiles[bank_id].bank_config, @@ -554,7 +555,7 @@ static int ath12k_dp_srng_common_setup(struct ath12k_base *ab) } srng = &ab->hal.srng_list[dp->reo_cmd_ring.ring_id]; - ath12k_hal_reo_init_cmd_ring(ab, srng); + ath12k_wifi7_hal_reo_init_cmd_ring(ab, srng); ret = ath12k_dp_srng_setup(ab, &dp->reo_status_ring, HAL_REO_STATUS, 0, 0, DP_REO_STATUS_RING_SIZE); @@ -578,7 +579,7 @@ static int ath12k_dp_srng_common_setup(struct ath12k_base *ab) HAL_HASH_ROUTING_RING_SW3 << 24 | HAL_HASH_ROUTING_RING_SW4 << 28; - ath12k_hal_reo_hw_setup(ab, ring_hash_map); + ath12k_wifi7_hal_reo_hw_setup(ab, ring_hash_map); return 0; @@ -1637,7 +1638,7 @@ int ath12k_dp_alloc(struct ath12k_base *ab) } for (i = 0; i < HAL_DSCP_TID_MAP_TBL_NUM_ENTRIES_MAX; i++) - ath12k_hal_tx_set_dscp_tid_map(ab, i); + ath12k_wifi7_hal_tx_set_dscp_tid_map(ab, i); ret = ath12k_dp_rx_alloc(ab); if (ret) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index a292658a78c24..9085bf8d3dee1 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -1843,7 +1843,7 @@ ath12k_dp_rx_mon_buf_done(struct ath12k_base *ab, struct hal_srng *srng, if (!status_desc) return DP_MON_STATUS_NO_DMA; - ath12k_hal_rx_buf_addr_info_get(status_desc, &paddr, &cookie, &rbm); + ath12k_wifi7_hal_rx_buf_addr_info_get(status_desc, &paddr, &cookie, &rbm); buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); @@ -1895,7 +1895,7 @@ void ath12k_dp_mon_next_link_desc_get(struct hal_rx_msdu_link *msdu_link, buf_addr_info = &msdu_link->buf_addr_info; - ath12k_hal_rx_buf_addr_info_get(buf_addr_info, paddr, sw_cookie, rbm); + ath12k_wifi7_hal_rx_buf_addr_info_get(buf_addr_info, paddr, sw_cookie, rbm); *pp_buf_addr_info = buf_addr_info; } @@ -2761,7 +2761,7 @@ int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, num_remain--; - ath12k_hal_rx_buf_addr_info_set(desc, paddr, cookie, mgr); + ath12k_wifi7_hal_rx_buf_addr_info_set(desc, paddr, cookie, mgr); } ath12k_hal_srng_access_end(ab, srng); @@ -3980,8 +3980,8 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, pmon->buf_state = DP_MON_STATUS_REPLINISH; break; } - ath12k_hal_rx_buf_addr_info_get(rx_mon_status_desc, &paddr, - &cookie, &rbm); + ath12k_wifi7_hal_rx_buf_addr_info_get(rx_mon_status_desc, &paddr, + &cookie, &rbm); if (paddr) { buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); @@ -4062,12 +4062,12 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, move_next: skb = ath12k_dp_rx_alloc_mon_status_buf(ab, rx_ring, &buf_id); + hal_params = ab->hw_params->hal_params; if (!skb) { ath12k_warn(ab, "failed to alloc buffer for status ring\n"); - hal_params = ab->hw_params->hal_params; - ath12k_hal_rx_buf_addr_info_set(rx_mon_status_desc, 0, 0, - hal_params->rx_buf_rbm); + ath12k_wifi7_hal_rx_buf_addr_info_set(rx_mon_status_desc, 0, 0, + hal_params->rx_buf_rbm); num_buffs_reaped++; break; } @@ -4076,9 +4076,9 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, cookie = u32_encode_bits(mac_id, DP_RXDMA_BUF_COOKIE_PDEV_ID) | u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID); - ath12k_hal_rx_buf_addr_info_set(rx_mon_status_desc, rxcb->paddr, - cookie, - ab->hw_params->hal_params->rx_buf_rbm); + ath12k_wifi7_hal_rx_buf_addr_info_set(rx_mon_status_desc, rxcb->paddr, + cookie, + hal_params->rx_buf_rbm); ath12k_hal_srng_src_get_next_entry(ab, srng); num_buffs_reaped++; } @@ -4247,14 +4247,14 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, list_add_tail(&desc_info->list, used_list); } - ath12k_hal_rx_buf_addr_info_set(&buf_info, paddr, sw_cookie, rbm); + ath12k_wifi7_hal_rx_buf_addr_info_set(&buf_info, paddr, sw_cookie, rbm); ath12k_dp_mon_next_link_desc_get(msdu_link_desc, &paddr, &sw_cookie, &rbm, &p_buf_addr_info); - ath12k_dp_rx_link_desc_return(ar->ab, &buf_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + ath12k_wifi7_dp_rx_link_desc_return(ar->ab, &buf_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); p_last_buf_addr_info = p_buf_addr_info; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index c0e41a0a29f35..c420bf0016aaa 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -145,7 +145,7 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, num_remain--; - ath12k_hal_rx_buf_addr_info_set(desc, paddr, cookie, mgr); + ath12k_wifi7_hal_rx_buf_addr_info_set(desc, paddr, cookie, mgr); } goto out; @@ -459,6 +459,19 @@ void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx, list_del(&elem->list); dp->reo_cmd_cache_flush_count--; + + /* Unlock the reo_cmd_lock before using ath12k_dp_reo_cmd_send() + * within ath12k_wifi7_dp_reo_cache_flush. + * The reo_cmd_cache_flush_list is used in only two contexts, + * one is in this function called from napi and the other in + * ath12k_dp_free during core destroy. + * Before dp_free, the irqs would be disabled and would wait to + * synchronize. Hence there wouldn’t be any race against add or + * delete to this list. Hence unlock-lock is safe here. + */ + spin_unlock_bh(&dp->reo_cmd_lock); + + ath12k_wifi7_dp_reo_cache_flush(ab, &elem->data); kfree(elem); } } @@ -497,8 +510,9 @@ void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, if (rx_tid->dst_ring_desc) { if (rel_link_desc) { buf_addr_info = &rx_tid->dst_ring_desc->buf_addr_info; - ath12k_dp_rx_link_desc_return(ab, buf_addr_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + ath12k_wifi7_dp_rx_link_desc_return + (ab, buf_addr_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); } kfree(rx_tid->dst_ring_desc); rx_tid->dst_ring_desc = NULL; @@ -520,7 +534,7 @@ void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_peer *peer) for (i = 0; i <= IEEE80211_NUM_TIDS; i++) { rx_tid = &peer->rx_tid[i]; - ath12k_dp_rx_peer_tid_delete(ar, peer, i); + ath12k_wifi7_dp_rx_peer_tid_delete(ar, peer, i); ath12k_dp_rx_frags_cleanup(rx_tid, true); spin_unlock_bh(&ar->ab->base_lock); @@ -573,8 +587,8 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ rx_tid = &peer->rx_tid[tid]; /* Update the tid queue if it is already setup */ if (rx_tid->active) { - ret = ath12k_peer_rx_tid_reo_update(ar, peer, rx_tid, - ba_win_sz, ssn, true); + ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, rx_tid, + ba_win_sz, ssn, true); spin_unlock_bh(&ab->base_lock); if (ret) { ath12k_warn(ab, "failed to update reo for rx tid %d\n", tid); @@ -602,7 +616,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ rx_tid->ba_win_sz = ba_win_sz; ahsta = ath12k_sta_to_ahsta(peer->sta); - ret = ath12k_dp_rx_assign_reoq(ab, ahsta, rx_tid, ssn, pn_type); + ret = ath12k_wifi7_dp_rx_assign_reoq(ab, ahsta, rx_tid, ssn, pn_type); if (ret) { spin_unlock_bh(&ab->base_lock); ath12k_warn(ab, "failed to assign reoq buf for rx tid %u\n", tid); @@ -628,11 +642,11 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ * and tid with qaddr. */ if (peer->mlo) - ath12k_peer_rx_tid_qref_setup(ab, peer->ml_id, tid, - paddr_aligned); + ath12k_wifi7_peer_rx_tid_qref_setup(ab, peer->ml_id, tid, + paddr_aligned); else - ath12k_peer_rx_tid_qref_setup(ab, peer->peer_id, tid, - paddr_aligned); + ath12k_wifi7_peer_rx_tid_qref_setup(ab, peer->peer_id, tid, + paddr_aligned); spin_unlock_bh(&ab->base_lock); } else { @@ -710,7 +724,7 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, return 0; } - ret = ath12k_peer_rx_tid_reo_update(ar, peer, peer->rx_tid, 1, 0, false); + ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, peer->rx_tid, 1, 0, false); spin_unlock_bh(&ab->base_lock); if (ret) { ath12k_warn(ab, "failed to update reo for rx tid %d: %d\n", @@ -757,10 +771,11 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, if (!rx_tid->active) continue; - ath12k_dp_setup_pn_check_reo_cmd(&cmd, rx_tid, key->cipher, key_cmd); - ret = ath12k_dp_reo_cmd_send(ab, rx_tid, - HAL_REO_CMD_UPDATE_RX_QUEUE, - &cmd, NULL); + ath12k_wifi7_dp_setup_pn_check_reo_cmd(&cmd, rx_tid, key->cipher, + key_cmd); + ret = ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid, + HAL_REO_CMD_UPDATE_RX_QUEUE, + &cmd, NULL); if (ret) { ath12k_warn(ab, "failed to configure rx tid %d queue of peer %pM for pn replay detection %d\n", tid, peer_addr, ret); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 81ceb296cb91c..8d539b72d6677 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1604,13 +1604,14 @@ struct hal_ops { extern const struct hal_ops hal_qcn9274_ops; extern const struct hal_ops hal_wcn7850_ops; -u32 ath12k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); -void ath12k_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, - int tid, u32 ba_window_size, - u32 start_seq, enum hal_pn_type type); -void ath12k_hal_reo_init_cmd_ring(struct ath12k_base *ab, - struct hal_srng *srng); -void ath12k_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); +u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); +void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, + int tid, u32 ba_window_size, + u32 start_seq, enum hal_pn_type type); +void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, + struct hal_srng *srng); +void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); + void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, struct hal_wbm_idle_scatter_list *sbuf, u32 nsbufs, u32 tot_link_desc, diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 76d6e8c0c6ad6..5ed10d75e5e42 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -9223,7 +9223,7 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw, if (!vif->valid_links || !is_mcast || is_dvlan || (skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) || test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags)) { - ret = ath12k_dp_tx(ar, arvif, skb, false, 0, is_mcast); + ret = ath12k_wifi7_dp_tx(ar, arvif, skb, false, 0, is_mcast); if (unlikely(ret)) { ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret); ieee80211_free_txskb(ar->ah->hw, skb); @@ -9284,8 +9284,8 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw, spin_unlock_bh(&tmp_ar->ab->base_lock); skip_peer_find: - ret = ath12k_dp_tx(tmp_ar, tmp_arvif, - msdu_copied, true, mcbc_gsn, is_mcast); + ret = ath12k_wifi7_dp_tx(tmp_ar, tmp_arvif, + msdu_copied, true, mcbc_gsn, is_mcast); if (unlikely(ret)) { if (ret == -ENOMEM) { /* Drops are expected during heavy multicast diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index ee077c3f973c8..257c5bc3c0f16 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -500,7 +500,7 @@ static int ath12k_pci_ext_grp_napi_poll(struct napi_struct *napi, int budget) int work_done; int i; - work_done = ath12k_dp_service_srng(ab, irq_grp, budget); + work_done = ath12k_wifi7_dp_service_srng(ab, irq_grp, budget); if (work_done < budget) { napi_complete_done(napi, work_done); for (i = 0; i < irq_grp->num_irq; i++) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index afe791394e6b4..05c278467cb32 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -12,9 +12,9 @@ #include "dp.h" #include "dp_tx.h" -int ath12k_dp_service_srng(struct ath12k_base *ab, - struct ath12k_ext_irq_grp *irq_grp, - int budget) +int ath12k_wifi7_dp_service_srng(struct ath12k_base *ab, + struct ath12k_ext_irq_grp *irq_grp, + int budget) { struct napi_struct *napi = &irq_grp->napi; int grp_id = irq_grp->grp_id; @@ -26,11 +26,11 @@ int ath12k_dp_service_srng(struct ath12k_base *ab, if (ab->hw_params->ring_mask->tx[grp_id]) { i = fls(ab->hw_params->ring_mask->tx[grp_id]) - 1; - ath12k_dp_tx_completion_handler(ab, i); + ath12k_wifi7_dp_tx_completion_handler(ab, i); } if (ab->hw_params->ring_mask->rx_err[grp_id]) { - work_done = ath12k_dp_rx_process_err(ab, napi, budget); + work_done = ath12k_wifi7_dp_rx_process_err(ab, napi, budget); budget -= work_done; tot_work_done += work_done; if (budget <= 0) @@ -38,9 +38,7 @@ int ath12k_dp_service_srng(struct ath12k_base *ab, } if (ab->hw_params->ring_mask->rx_wbm_rel[grp_id]) { - work_done = ath12k_dp_rx_process_wbm_err(ab, - napi, - budget); + work_done = ath12k_wifi7_dp_rx_process_wbm_err(ab, napi, budget); budget -= work_done; tot_work_done += work_done; @@ -50,8 +48,7 @@ int ath12k_dp_service_srng(struct ath12k_base *ab, if (ab->hw_params->ring_mask->rx[grp_id]) { i = fls(ab->hw_params->ring_mask->rx[grp_id]) - 1; - work_done = ath12k_dp_rx_process(ab, i, napi, - budget); + work_done = ath12k_wifi7_dp_rx_process(ab, i, napi, budget); budget -= work_done; tot_work_done += work_done; if (budget <= 0) @@ -120,7 +117,7 @@ int ath12k_dp_service_srng(struct ath12k_base *ab, } if (ab->hw_params->ring_mask->reo_status[grp_id]) - ath12k_dp_rx_process_reo_status(ab); + ath12k_wifi7_dp_rx_process_reo_status(ab); if (ab->hw_params->ring_mask->host2rxdma[grp_id]) { struct ath12k_dp *dp = &ab->dp; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.h b/drivers/net/wireless/ath/ath12k/wifi7/dp.h index 17255a5671d73..9332b9401bbf7 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.h @@ -9,7 +9,6 @@ #include "hw.h" -int ath12k_dp_service_srng(struct ath12k_base *ab, - struct ath12k_ext_irq_grp *irq_grp, - int budget); +int ath12k_wifi7_dp_service_srng(struct ath12k_base *ab, + struct ath12k_ext_irq_grp *irq_grp, int budget); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index f19c5612bb7c0..76bfa33120f3a 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -10,8 +10,8 @@ #include "hal_qcn9274.h" #include "hal_wcn7850.h" -void ath12k_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, - dma_addr_t paddr) +void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, + dma_addr_t paddr) { struct ath12k_reo_queue_ref *qref; struct ath12k_dp *dp = &ab->dp; @@ -40,7 +40,8 @@ void ath12k_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, ath12k_hal_reo_shared_qaddr_cache_clear(ab); } -static void ath12k_peer_rx_tid_qref_reset(struct ath12k_base *ab, u16 peer_id, u16 tid) +static void ath12k_wifi7_peer_rx_tid_qref_reset(struct ath12k_base *ab, + u16 peer_id, u16 tid) { struct ath12k_reo_queue_ref *qref; struct ath12k_dp *dp = &ab->dp; @@ -66,8 +67,8 @@ static void ath12k_peer_rx_tid_qref_reset(struct ath12k_base *ab, u16 peer_id, u u32_encode_bits(tid, DP_REO_QREF_NUM); } -void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar, - struct ath12k_peer *peer, u8 tid) +void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k *ar, + struct ath12k_peer *peer, u8 tid) { struct ath12k_hal_reo_cmd cmd = {}; struct ath12k_dp_rx_tid *rx_tid = &peer->rx_tid[tid]; @@ -80,9 +81,9 @@ void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar, cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); cmd.upd0 = HAL_REO_CMD_UPD0_VLD; - ret = ath12k_dp_reo_cmd_send(ar->ab, rx_tid, - HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, - ath12k_dp_rx_tid_del_func); + ret = ath12k_wifi7_dp_reo_cmd_send(ar->ab, rx_tid, + HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, + ath12k_dp_rx_tid_del_func); if (ret) { ath12k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n", tid, ret); @@ -93,16 +94,16 @@ void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar, } if (peer->mlo) - ath12k_peer_rx_tid_qref_reset(ar->ab, peer->ml_id, tid); + ath12k_wifi7_peer_rx_tid_qref_reset(ar->ab, peer->ml_id, tid); else - ath12k_peer_rx_tid_qref_reset(ar->ab, peer->peer_id, tid); + ath12k_wifi7_peer_rx_tid_qref_reset(ar->ab, peer->peer_id, tid); rx_tid->active = false; } -int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, - struct ath12k_buffer_addr *buf_addr_info, - enum hal_wbm_rel_bm_act action) +int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, + struct ath12k_buffer_addr *buf_addr_info, + enum hal_wbm_rel_bm_act action) { struct hal_wbm_release_ring *desc; struct ath12k_dp *dp = &ab->dp; @@ -121,7 +122,7 @@ int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, goto exit; } - ath12k_hal_rx_msdu_link_desc_set(ab, desc, buf_addr_info, action); + ath12k_wifi7_hal_rx_msdu_link_desc_set(ab, desc, buf_addr_info, action); exit: ath12k_hal_srng_access_end(ab, srng); @@ -131,11 +132,12 @@ int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, return ret; } -int ath12k_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid, - enum hal_reo_cmd_type type, - struct ath12k_hal_reo_cmd *cmd, - void (*cb)(struct ath12k_dp *dp, void *ctx, - enum hal_reo_cmd_status status)) +int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, + struct ath12k_dp_rx_tid *rx_tid, + enum hal_reo_cmd_type type, + struct ath12k_hal_reo_cmd *cmd, + void (*cb)(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status)) { struct ath12k_dp *dp = &ab->dp; struct ath12k_dp_rx_reo_cmd *dp_cmd; @@ -143,7 +145,7 @@ int ath12k_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_t int cmd_num; cmd_ring = &ab->hal.srng_list[dp->reo_cmd_ring.ring_id]; - cmd_num = ath12k_hal_reo_cmd_send(ab, cmd_ring, type, cmd); + cmd_num = ath12k_wifi7_hal_reo_cmd_send(ab, cmd_ring, type, cmd); /* cmd_num should start from 1, during failure return the error code */ if (cmd_num < 0) @@ -176,11 +178,11 @@ int ath12k_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_t return 0; } -int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, - struct ath12k_peer *peer, - struct ath12k_dp_rx_tid *rx_tid, - u32 ba_win_sz, u16 ssn, - bool update_ssn) +int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k *ar, + struct ath12k_peer *peer, + struct ath12k_dp_rx_tid *rx_tid, + u32 ba_win_sz, u16 ssn, + bool update_ssn) { struct ath12k_hal_reo_cmd cmd = {}; int ret; @@ -196,9 +198,9 @@ int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, cmd.upd2 = u32_encode_bits(ssn, HAL_REO_CMD_UPD2_SSN); } - ret = ath12k_dp_reo_cmd_send(ar->ab, rx_tid, - HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, - NULL); + ret = ath12k_wifi7_dp_reo_cmd_send(ar->ab, rx_tid, + HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, + NULL); if (ret) { ath12k_warn(ar->ab, "failed to update rx tid queue, tid %d (%d)\n", rx_tid->tid, ret); @@ -210,23 +212,23 @@ int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, return 0; } -void ath12k_dp_reo_cache_flush(struct ath12k_base *ab, - struct ath12k_dp_rx_tid *rx_tid) +void ath12k_wifi7_dp_reo_cache_flush(struct ath12k_base *ab, + struct ath12k_dp_rx_tid *rx_tid) { struct ath12k_hal_reo_cmd cmd = {}; unsigned long tot_desc_sz, desc_sz; int ret; tot_desc_sz = rx_tid->qbuf.size; - desc_sz = ath12k_hal_reo_qdesc_size(0, HAL_DESC_REO_NON_QOS_TID); + desc_sz = ath12k_wifi7_hal_reo_qdesc_size(0, HAL_DESC_REO_NON_QOS_TID); while (tot_desc_sz > desc_sz) { tot_desc_sz -= desc_sz; cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned + tot_desc_sz); cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); - ret = ath12k_dp_reo_cmd_send(ab, rx_tid, - HAL_REO_CMD_FLUSH_CACHE, &cmd, - NULL); + ret = ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid, + HAL_REO_CMD_FLUSH_CACHE, &cmd, + NULL); if (ret) ath12k_warn(ab, "failed to send HAL_REO_CMD_FLUSH_CACHE, tid %d (%d)\n", @@ -237,9 +239,9 @@ void ath12k_dp_reo_cache_flush(struct ath12k_base *ab, cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; - ret = ath12k_dp_reo_cmd_send(ab, rx_tid, - HAL_REO_CMD_FLUSH_CACHE, - &cmd, ath12k_dp_reo_cmd_free); + ret = ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid, + HAL_REO_CMD_FLUSH_CACHE, + &cmd, ath12k_dp_reo_cmd_free); if (ret) { ath12k_err(ab, "failed to send HAL_REO_CMD_FLUSH_CACHE cmd, tid %d (%d)\n", rx_tid->tid, ret); @@ -250,9 +252,9 @@ void ath12k_dp_reo_cache_flush(struct ath12k_base *ab, } } -int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, - struct ath12k_dp_rx_tid *rx_tid, - u16 ssn, enum hal_pn_type pn_type) +int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, + struct ath12k_dp_rx_tid *rx_tid, + u16 ssn, enum hal_pn_type pn_type) { u32 ba_win_sz = rx_tid->ba_win_sz; struct ath12k_reoq_buf *buf; @@ -268,9 +270,10 @@ int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, * the actual BA window size in REO tid update path. */ if (tid == HAL_DESC_REO_NON_QOS_TID) - hw_desc_sz = ath12k_hal_reo_qdesc_size(ba_win_sz, tid); + hw_desc_sz = ath12k_wifi7_hal_reo_qdesc_size(ba_win_sz, tid); else - hw_desc_sz = ath12k_hal_reo_qdesc_size(DP_BA_WIN_SZ_MAX, tid); + hw_desc_sz = ath12k_wifi7_hal_reo_qdesc_size(DP_BA_WIN_SZ_MAX, + tid); vaddr = kzalloc(hw_desc_sz + HAL_LINK_DESC_ALIGN - 1, GFP_ATOMIC); if (!vaddr) @@ -278,8 +281,8 @@ int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, vaddr_aligned = PTR_ALIGN(vaddr, HAL_LINK_DESC_ALIGN); - ath12k_hal_reo_qdesc_setup(vaddr_aligned, tid, ba_win_sz, - ssn, pn_type); + ath12k_wifi7_hal_reo_qdesc_setup(vaddr_aligned, tid, ba_win_sz, + ssn, pn_type); paddr_aligned = dma_map_single(ab->dev, vaddr_aligned, hw_desc_sz, DMA_BIDIRECTIONAL); @@ -300,17 +303,17 @@ int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, return 0; } -static void ath12k_dp_rx_h_csum_offload(struct sk_buff *msdu, - struct hal_rx_desc_data *rx_info) +static void ath12k_wifi7_dp_rx_h_csum_offload(struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info) { msdu->ip_summed = (rx_info->ip_csum_fail || rx_info->l4_csum_fail) ? CHECKSUM_NONE : CHECKSUM_UNNECESSARY; } -static void ath12k_dp_rx_h_mpdu(struct ath12k *ar, - struct sk_buff *msdu, - struct hal_rx_desc *rx_desc, - struct hal_rx_desc_data *rx_info) +static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k *ar, + struct sk_buff *msdu, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc_data *rx_info) { struct ath12k_skb_rxcb *rxcb; enum hal_encrypt_type enctype; @@ -364,13 +367,13 @@ static void ath12k_dp_rx_h_mpdu(struct ath12k *ar, if (rx_info->is_mcbc) rx_status->flag |= RX_FLAG_MIC_STRIPPED | - RX_FLAG_ICV_STRIPPED; + RX_FLAG_ICV_STRIPPED; else rx_status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_PN_VALIDATED; } - ath12k_dp_rx_h_csum_offload(msdu, rx_info); + ath12k_wifi7_dp_rx_h_csum_offload(msdu, rx_info); ath12k_dp_rx_h_undecap(ar, msdu, rx_desc, enctype, is_decrypted, rx_info); @@ -383,11 +386,11 @@ static void ath12k_dp_rx_h_mpdu(struct ath12k *ar, } } -static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar, - struct sk_buff_head *msdu_list, - struct sk_buff *first, struct sk_buff *last, - u8 l3pad_bytes, int msdu_len, - struct hal_rx_desc_data *rx_info) +static int ath12k_wifi7_dp_rx_msdu_coalesce(struct ath12k *ar, + struct sk_buff_head *msdu_list, + struct sk_buff *first, struct sk_buff *last, + u8 l3pad_bytes, int msdu_len, + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; struct sk_buff *skb; @@ -471,10 +474,10 @@ static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar, return 0; } -static int ath12k_dp_rx_process_msdu(struct ath12k *ar, - struct sk_buff *msdu, - struct sk_buff_head *msdu_list, - struct hal_rx_desc_data *rx_info) +static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k *ar, + struct sk_buff *msdu, + struct sk_buff_head *msdu_list, + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; struct hal_rx_desc *rx_desc, *lrx_desc; @@ -521,10 +524,10 @@ static int ath12k_dp_rx_process_msdu(struct ath12k *ar, skb_put(msdu, hal_rx_desc_sz + l3_pad_bytes + msdu_len); skb_pull(msdu, hal_rx_desc_sz + l3_pad_bytes); } else { - ret = ath12k_dp_rx_msdu_coalesce(ar, msdu_list, - msdu, last_buf, - l3_pad_bytes, msdu_len, - rx_info); + ret = ath12k_wifi7_dp_rx_msdu_coalesce(ar, msdu_list, + msdu, last_buf, + l3_pad_bytes, msdu_len, + rx_info); if (ret) { ath12k_warn(ab, "failed to coalesce msdu rx buffer%d\n", ret); @@ -539,7 +542,7 @@ static int ath12k_dp_rx_process_msdu(struct ath12k *ar, } ath12k_dp_rx_h_ppdu(ar, rx_info); - ath12k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_info); + ath12k_wifi7_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_info); rx_info->rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; @@ -549,10 +552,11 @@ static int ath12k_dp_rx_process_msdu(struct ath12k *ar, return ret; } -static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab, - struct napi_struct *napi, - struct sk_buff_head *msdu_list, - int ring_id) +static void +ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, + struct napi_struct *napi, + struct sk_buff_head *msdu_list, + int ring_id) { struct ath12k_hw_group *ag = ab->ag; struct ieee80211_rx_status rx_status = {}; @@ -591,7 +595,7 @@ static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab, continue; } - ret = ath12k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_info); + ret = ath12k_wifi7_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_info); if (ret) { ath12k_dbg(ab, ATH12K_DBG_DATA, "Unable to process msdu %d", ret); @@ -605,8 +609,8 @@ static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab, rcu_read_unlock(); } -int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id, - struct napi_struct *napi, int budget) +int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, + struct napi_struct *napi, int budget) { struct ath12k_hw_group *ag = ab->ag; struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; @@ -758,17 +762,17 @@ int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id, num_buffs_reaped[device_id]); } - ath12k_dp_rx_process_received_packets(ab, napi, &msdu_list, - ring_id); + ath12k_wifi7_dp_rx_process_received_packets(ab, napi, &msdu_list, + ring_id); exit: return total_msdu_reaped; } static bool -ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, - struct ath12k_dp_rx_tid *rx_tid, - enum hal_encrypt_type encrypt_type) +ath12k_wifi7_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, + struct ath12k_dp_rx_tid *rx_tid, + enum hal_encrypt_type encrypt_type) { struct sk_buff *first_frag, *skb; u64 last_pn; @@ -795,9 +799,9 @@ ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, return true; } -static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, - struct ath12k_dp_rx_tid *rx_tid, - struct sk_buff *defrag_skb) +static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, + struct ath12k_dp_rx_tid *rx_tid, + struct sk_buff *defrag_skb) { struct ath12k_base *ab = ar->ab; struct ath12k_dp *dp = &ab->dp; @@ -820,8 +824,8 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, link_desc_banks = dp->link_desc_banks; reo_dest_ring = rx_tid->dst_ring_desc; - ath12k_hal_rx_reo_ent_paddr_get(ab, &reo_dest_ring->buf_addr_info, - &link_paddr, &cookie); + ath12k_wifi7_hal_rx_reo_ent_paddr_get(ab, &reo_dest_ring->buf_addr_info, + &link_paddr, &cookie); desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK); msdu_link = (struct hal_rx_msdu_link *)(link_desc_banks[desc_bank].vaddr + @@ -870,9 +874,9 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, ATH12K_SKB_RXCB(defrag_skb)->paddr = buf_paddr; - ath12k_hal_rx_buf_addr_info_set(&msdu0->buf_addr_info, buf_paddr, - desc_info->cookie, - HAL_RX_BUF_RBM_SW3_BM); + ath12k_wifi7_hal_rx_buf_addr_info_set(&msdu0->buf_addr_info, buf_paddr, + desc_info->cookie, + HAL_RX_BUF_RBM_SW3_BM); /* Fill mpdu details into reo entrance ring */ srng = &ab->hal.srng_list[dp->reo_reinject_ring.ring_id]; @@ -889,9 +893,8 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, } memset(reo_ent_ring, 0, sizeof(*reo_ent_ring)); - ath12k_hal_rx_buf_addr_info_set(&reo_ent_ring->buf_addr_info, link_paddr, - cookie, - idle_link_rbm); + ath12k_wifi7_hal_rx_buf_addr_info_set(&reo_ent_ring->buf_addr_info, link_paddr, + cookie, idle_link_rbm); mpdu_info = u32_encode_bits(1, RX_MPDU_DESC_INFO0_MSDU_COUNT) | u32_encode_bits(0, RX_MPDU_DESC_INFO0_FRAG_FLAG) | @@ -942,11 +945,11 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, return ret; } -static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, - struct ath12k_peer *peer, - enum hal_encrypt_type enctype, - struct sk_buff *msdu, - struct hal_rx_desc_data *rx_info) +static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k *ar, + struct ath12k_peer *peer, + enum hal_encrypt_type enctype, + struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; @@ -982,7 +985,8 @@ static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, data_len = msdu->len - head_len - tail_len; key = &key_conf->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; - ret = ath12k_dp_rx_h_michael_mic(peer->tfm_mmic, key, hdr, data, data_len, mic); + ret = ath12k_dp_rx_h_michael_mic(peer->tfm_mmic, key, hdr, data, + data_len, mic); if (ret || memcmp(mic, data + data_len, IEEE80211_CCMP_MIC_LEN)) goto mic_fail; @@ -1009,12 +1013,12 @@ static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, return -EINVAL; } -static int ath12k_dp_rx_h_defrag(struct ath12k *ar, - struct ath12k_peer *peer, - struct ath12k_dp_rx_tid *rx_tid, - struct sk_buff **defrag_skb, - enum hal_encrypt_type enctype, - struct hal_rx_desc_data *rx_info) +static int ath12k_wifi7_dp_rx_h_defrag(struct ath12k *ar, + struct ath12k_peer *peer, + struct ath12k_dp_rx_tid *rx_tid, + struct sk_buff **defrag_skb, + enum hal_encrypt_type enctype, + struct hal_rx_desc_data *rx_info) { struct sk_buff *skb, *first_frag, *last_frag; struct ieee80211_hdr *hdr; @@ -1038,7 +1042,7 @@ static int ath12k_dp_rx_h_defrag(struct ath12k *ar, flags |= RX_FLAG_IV_STRIPPED; if (skb != last_frag) flags |= RX_FLAG_ICV_STRIPPED | - RX_FLAG_MIC_STRIPPED; + RX_FLAG_MIC_STRIPPED; } /* RX fragments are always raw packets */ @@ -1067,17 +1071,17 @@ static int ath12k_dp_rx_h_defrag(struct ath12k *ar, hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); ATH12K_SKB_RXCB(first_frag)->is_frag = 1; - if (ath12k_dp_rx_h_verify_tkip_mic(ar, peer, enctype, first_frag, rx_info)) + if (ath12k_wifi7_dp_rx_h_verify_tkip_mic(ar, peer, enctype, first_frag, rx_info)) first_frag = NULL; *defrag_skb = first_frag; return 0; } -static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, - struct sk_buff *msdu, - struct hal_reo_dest_ring *ring_desc, - struct hal_rx_desc_data *rx_info) +static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k *ar, + struct sk_buff *msdu, + struct hal_reo_dest_ring *ring_desc, + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; struct ath12k_peer *peer; @@ -1155,8 +1159,8 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, goto out_unlock; } } else { - ath12k_dp_rx_link_desc_return(ab, &ring_desc->buf_addr_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + ath12k_wifi7_dp_rx_link_desc_return(ab, &ring_desc->buf_addr_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); } if (!rx_tid->last_frag_no || @@ -1174,17 +1178,17 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, if (!peer) goto err_frags_cleanup; - if (!ath12k_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid, enctype)) + if (!ath12k_wifi7_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid, enctype)) goto err_frags_cleanup; - if (ath12k_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb, - enctype, rx_info)) + if (ath12k_wifi7_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb, + enctype, rx_info)) goto err_frags_cleanup; if (!defrag_skb) goto err_frags_cleanup; - if (ath12k_dp_rx_h_defrag_reo_reinject(ar, rx_tid, defrag_skb)) + if (ath12k_wifi7_dp_rx_h_defrag_reo_reinject(ar, rx_tid, defrag_skb)) goto err_frags_cleanup; ath12k_dp_rx_frags_cleanup(rx_tid, false); @@ -1199,9 +1203,10 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, } static int -ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc, - struct list_head *used_list, - bool drop, u32 cookie) +ath12k_wifi7_dp_process_rx_err_buf(struct ath12k *ar, + struct hal_reo_dest_ring *desc, + struct list_head *used_list, + bool drop, u32 cookie) { struct ath12k_base *ab = ar->ab; struct sk_buff *msdu; @@ -1270,18 +1275,18 @@ ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc, skb_put(msdu, hal_rx_desc_sz + msdu_len); - if (ath12k_dp_rx_frag_h_mpdu(ar, msdu, desc, &rx_info)) { + if (ath12k_wifi7_dp_rx_frag_h_mpdu(ar, msdu, desc, &rx_info)) { dev_kfree_skb_any(msdu); - ath12k_dp_rx_link_desc_return(ar->ab, &desc->buf_addr_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + ath12k_wifi7_dp_rx_link_desc_return(ar->ab, &desc->buf_addr_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); } exit: rcu_read_unlock(); return 0; } -int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, - int budget) +int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, + int budget) { struct ath12k_hw_group *ag = ab->ag; struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; @@ -1304,6 +1309,8 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, bool is_frag; bool drop; int pdev_id; + struct list_head *used_list; + enum hal_wbm_rel_bm_act act; tot_n_bufs_reaped = 0; quota = budget; @@ -1324,8 +1331,8 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, drop = false; ab->device_stats.err_ring_pkts++; - ret = ath12k_hal_desc_reo_parse_err(ab, reo_desc, &paddr, - &desc_bank); + ret = ath12k_wifi7_hal_desc_reo_parse_err(ab, reo_desc, &paddr, + &desc_bank); if (ret) { ath12k_warn(ab, "failed to parse error reo desc %d\n", ret); @@ -1344,16 +1351,17 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, link_desc_banks = partner_ab->dp.link_desc_banks; link_desc_va = link_desc_banks[desc_bank].vaddr + (paddr - link_desc_banks[desc_bank].paddr); - ath12k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies, - &rbm); + ath12k_wifi7_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, + msdu_cookies, &rbm); if (rbm != partner_ab->dp.idle_link_rbm && rbm != HAL_RX_BUF_RBM_SW3_BM && rbm != partner_ab->hw_params->hal_params->rx_buf_rbm) { + act = HAL_WBM_REL_BM_ACT_REL_MSDU; ab->device_stats.invalid_rbm++; ath12k_warn(ab, "invalid return buffer manager %d\n", rbm); - ath12k_dp_rx_link_desc_return(partner_ab, - &reo_desc->buf_addr_info, - HAL_WBM_REL_BM_ACT_REL_MSDU); + ath12k_wifi7_dp_rx_link_desc_return(partner_ab, + &reo_desc->buf_addr_info, + act); continue; } @@ -1368,18 +1376,21 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, if (!is_frag || num_msdus > 1 || partner_ab->device_id != ab->device_id) { drop = true; + act = HAL_WBM_REL_BM_ACT_PUT_IN_IDLE; /* Return the link desc back to wbm idle list */ - ath12k_dp_rx_link_desc_return(partner_ab, - &reo_desc->buf_addr_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + ath12k_wifi7_dp_rx_link_desc_return(partner_ab, + &reo_desc->buf_addr_info, + act); } for (i = 0; i < num_msdus; i++) { - if (!ath12k_dp_process_rx_err_buf(ar, reo_desc, - &rx_desc_used_list[device_id], - drop, - msdu_cookies[i])) { + used_list = &rx_desc_used_list[device_id]; + + if (!ath12k_wifi7_dp_process_rx_err_buf(ar, reo_desc, + used_list, + drop, + msdu_cookies[i])) { num_buffs_reaped[device_id]++; tot_n_bufs_reaped++; } @@ -1413,9 +1424,9 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, return tot_n_bufs_reaped; } -static void ath12k_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, - int msdu_len, - struct sk_buff_head *msdu_list) +static void +ath12k_wifi7_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, int msdu_len, + struct sk_buff_head *msdu_list) { struct sk_buff *skb, *tmp; struct ath12k_skb_rxcb *rxcb; @@ -1437,9 +1448,9 @@ static void ath12k_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, } } -static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, - struct hal_rx_desc_data *rx_info, - struct sk_buff_head *msdu_list) +static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info, + struct sk_buff_head *msdu_list) { struct ath12k_base *ab = ar->ab; u16 msdu_len = rx_info->msdu_len; @@ -1451,7 +1462,7 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, if (!rxcb->is_frag && ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE)) { /* First buffer will be freed by the caller, so deduct it's length */ msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - hal_rx_desc_sz); - ath12k_dp_rx_null_q_desc_sg_drop(ar, msdu_len, msdu_list); + ath12k_wifi7_dp_rx_null_q_desc_sg_drop(ar, msdu_len, msdu_list); return -EINVAL; } @@ -1491,7 +1502,7 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, return -EINVAL; ath12k_dp_rx_h_ppdu(ar, rx_info); - ath12k_dp_rx_h_mpdu(ar, msdu, desc, rx_info); + ath12k_wifi7_dp_rx_h_mpdu(ar, msdu, desc, rx_info); rxcb->tid = rx_info->tid; @@ -1502,8 +1513,8 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, return 0; } -static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, - struct hal_rx_desc_data *rx_info) +static bool ath12k_wifi7_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info) { struct ath12k_base *ab = ar->ab; u16 msdu_len = rx_info->msdu_len; @@ -1539,8 +1550,8 @@ static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, return false; } -static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, - struct hal_rx_desc_data *rx_info) +static bool ath12k_wifi7_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info) { struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); bool drop = false; @@ -1551,7 +1562,7 @@ static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, case HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR: case HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR: if (rx_info->err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) { - drop = ath12k_dp_rx_h_tkip_mic_err(ar, msdu, rx_info); + drop = ath12k_wifi7_dp_rx_h_tkip_mic_err(ar, msdu, rx_info); break; } fallthrough; @@ -1566,9 +1577,9 @@ static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, return drop; } -static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu, - struct hal_rx_desc_data *rx_info, - struct sk_buff_head *msdu_list) +static bool ath12k_wifi7_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info, + struct sk_buff_head *msdu_list) { struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); bool drop = false; @@ -1577,7 +1588,7 @@ static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu, switch (rxcb->err_code) { case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO: - if (ath12k_dp_rx_h_null_q_desc(ar, msdu, rx_info, msdu_list)) + if (ath12k_wifi7_dp_rx_h_null_q_desc(ar, msdu, rx_info, msdu_list)) drop = true; break; case HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED: @@ -1597,10 +1608,10 @@ static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu, return drop; } -static void ath12k_dp_rx_wbm_err(struct ath12k *ar, - struct napi_struct *napi, - struct sk_buff *msdu, - struct sk_buff_head *msdu_list) +static void ath12k_wifi7_dp_rx_wbm_err(struct ath12k *ar, + struct napi_struct *napi, + struct sk_buff *msdu, + struct sk_buff_head *msdu_list) { struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); @@ -1615,10 +1626,10 @@ static void ath12k_dp_rx_wbm_err(struct ath12k *ar, switch (rxcb->err_rel_src) { case HAL_WBM_REL_SRC_MODULE_REO: - drop = ath12k_dp_rx_h_reo_err(ar, msdu, &rx_info, msdu_list); + drop = ath12k_wifi7_dp_rx_h_reo_err(ar, msdu, &rx_info, msdu_list); break; case HAL_WBM_REL_SRC_MODULE_RXDMA: - drop = ath12k_dp_rx_h_rxdma_err(ar, msdu, &rx_info); + drop = ath12k_wifi7_dp_rx_h_rxdma_err(ar, msdu, &rx_info); break; default: /* msdu will get freed */ @@ -1635,9 +1646,9 @@ static void ath12k_dp_rx_wbm_err(struct ath12k *ar, ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info); } -void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, - struct ath12k_dp_rx_tid *rx_tid, - u32 cipher, enum set_key_cmd key_cmd) +void ath12k_wifi7_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, + struct ath12k_dp_rx_tid *rx_tid, + u32 cipher, enum set_key_cmd key_cmd) { cmd->flag = HAL_REO_CMD_FLG_NEED_STATUS; cmd->upd0 = HAL_REO_CMD_UPD0_PN | @@ -1665,8 +1676,8 @@ void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, cmd->addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); } -int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, - struct napi_struct *napi, int budget) +int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, + struct napi_struct *napi, int budget) { struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; struct ath12k_hw_group *ag = ab->ag; @@ -1705,7 +1716,8 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, if (!rx_desc) break; - ret = ath12k_hal_wbm_desc_parse_err(ab, rx_desc, &err_info); + ret = ath12k_wifi7_hal_wbm_desc_parse_err(ab, rx_desc, + &err_info); if (ret) { ath12k_warn(ab, "failed to parse rx error in wbm_rel ring desc %d\n", @@ -1862,7 +1874,7 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, device_stats->rx_wbm_rel_source[rxcb->err_rel_src][device_id]++; } - ath12k_dp_rx_wbm_err(ar, napi, msdu, &msdu_list); + ath12k_wifi7_dp_rx_wbm_err(ar, napi, msdu, &msdu_list); } rcu_read_unlock(); done: @@ -1950,7 +1962,7 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) } EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_wcn7850); -void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab) +void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_base *ab) { struct ath12k_dp *dp = &ab->dp; struct hal_tlv_64_hdr *hdr; @@ -1973,32 +1985,32 @@ void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab) switch (tag) { case HAL_REO_GET_QUEUE_STATS_STATUS: - ath12k_hal_reo_status_queue_stats(ab, hdr, - &reo_status); + ath12k_wifi7_hal_reo_status_queue_stats(ab, hdr, + &reo_status); break; case HAL_REO_FLUSH_QUEUE_STATUS: - ath12k_hal_reo_flush_queue_status(ab, hdr, - &reo_status); + ath12k_wifi7_hal_reo_flush_queue_status(ab, hdr, + &reo_status); break; case HAL_REO_FLUSH_CACHE_STATUS: - ath12k_hal_reo_flush_cache_status(ab, hdr, - &reo_status); + ath12k_wifi7_hal_reo_flush_cache_status(ab, hdr, + &reo_status); break; case HAL_REO_UNBLOCK_CACHE_STATUS: - ath12k_hal_reo_unblk_cache_status(ab, hdr, - &reo_status); + ath12k_wifi7_hal_reo_unblk_cache_status(ab, hdr, + &reo_status); break; case HAL_REO_FLUSH_TIMEOUT_LIST_STATUS: - ath12k_hal_reo_flush_timeout_list_status(ab, hdr, - &reo_status); + ath12k_wifi7_hal_reo_flush_timeout_list_status(ab, hdr, + &reo_status); break; case HAL_REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS: - ath12k_hal_reo_desc_thresh_reached_status(ab, hdr, - &reo_status); + ath12k_wifi7_hal_reo_desc_thresh_reached_status(ab, hdr, + &reo_status); break; case HAL_REO_UPDATE_RX_REO_QUEUE_STATUS: - ath12k_hal_reo_update_rx_reo_queue_status(ab, hdr, - &reo_status); + ath12k_wifi7_hal_reo_update_rx_reo_queue_status(ab, hdr, + &reo_status); break; default: ath12k_warn(ab, "Unknown reo status type %d\n", tag); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index f258472bc1fc6..35709dfccbcf3 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -9,41 +9,41 @@ #include "../core.h" #include "../dp_rx.h" -int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, - struct napi_struct *napi, int budget); -int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, - int budget); -int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id, - struct napi_struct *napi, - int budget); -void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab); +int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, + struct napi_struct *napi, int budget); +int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, + int budget); +int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int mac_id, + struct napi_struct *napi, + int budget); +void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); -void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, - struct ath12k_dp_rx_tid *rx_tid, - u32 cipher, enum set_key_cmd key_cmd); -int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, - struct ath12k_dp_rx_tid *rx_tid, - u16 ssn, enum hal_pn_type pn_type); -int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab, - struct ath12k_buffer_addr *buf_addr_info, - enum hal_wbm_rel_bm_act action); -void ath12k_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, - dma_addr_t paddr); -void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar, - struct ath12k_peer *peer, u8 tid); -int ath12k_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid, - enum hal_reo_cmd_type type, - struct ath12k_hal_reo_cmd *cmd, - void (*cb)(struct ath12k_dp *dp, void *ctx, - enum hal_reo_cmd_status status)); -void ath12k_dp_reo_cache_flush(struct ath12k_base *ab, - struct ath12k_dp_rx_tid *rx_tid); -int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, - struct ath12k_peer *peer, - struct ath12k_dp_rx_tid *rx_tid, - u32 ba_win_sz, u16 ssn, - bool update_ssn); +void ath12k_wifi7_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, + struct ath12k_dp_rx_tid *rx_tid, + u32 cipher, enum set_key_cmd key_cmd); +int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, + struct ath12k_dp_rx_tid *rx_tid, + u16 ssn, enum hal_pn_type pn_type); +int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, + struct ath12k_buffer_addr *buf_addr_info, + enum hal_wbm_rel_bm_act action); +void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, + dma_addr_t paddr); +void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k *ar, + struct ath12k_peer *peer, u8 tid); +int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid, + enum hal_reo_cmd_type type, + struct ath12k_hal_reo_cmd *cmd, + void (*cb)(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status)); +void ath12k_wifi7_dp_reo_cache_flush(struct ath12k_base *ab, + struct ath12k_dp_rx_tid *rx_tid); +int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k *ar, + struct ath12k_peer *peer, + struct ath12k_dp_rx_tid *rx_tid, + u32 ba_win_sz, u16 ssn, + bool update_ssn); static inline void ath12k_wifi7_dp_extract_rx_desc_data(struct ath12k_base *ab, struct hal_rx_desc_data *rx_info, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 49d219a195c5e..b3928c3d007df 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -10,9 +10,10 @@ #include "../peer.h" #include "dp_tx.h" -static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, - struct hal_tx_msdu_ext_desc *tcl_ext_cmd, - struct hal_tx_info *ti) +static void +ath12k_wifi7_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, + struct hal_tx_msdu_ext_desc *tcl_ext_cmd, + struct hal_tx_info *ti) { tcl_ext_cmd->info0 = le32_encode_bits(ti->paddr, HAL_TX_MSDU_EXT_INFO0_BUF_PTR_LO); @@ -31,7 +32,7 @@ static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, #define HTT_META_DATA_ALIGNMENT 0x8 /* Preparing HTT Metadata when utilized with ext MSDU */ -static int ath12k_dp_prepare_htt_metadata(struct sk_buff *skb) +static int ath12k_wifi7_dp_prepare_htt_metadata(struct sk_buff *skb) { struct hal_tx_msdu_metadata *desc_ext; u8 htt_desc_size; @@ -53,9 +54,9 @@ static int ath12k_dp_prepare_htt_metadata(struct sk_buff *skb) return 0; } -int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, - struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, - bool is_mcast) +int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, + struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, + bool is_mcast) { struct ath12k_base *ab = ar->ab; struct ath12k_dp *dp = &ab->dp; @@ -268,10 +269,10 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, memset(skb_ext_desc->data, 0, skb_ext_desc->len); msg = (struct hal_tx_msdu_ext_desc *)skb_ext_desc->data; - ath12k_hal_tx_cmd_ext_desc_setup(ab, msg, &ti); + ath12k_wifi7_hal_tx_cmd_ext_desc_setup(ab, msg, &ti); if (add_htt_metadata) { - ret = ath12k_dp_prepare_htt_metadata(skb_ext_desc); + ret = ath12k_wifi7_dp_prepare_htt_metadata(skb_ext_desc); if (ret < 0) { ath12k_dbg(ab, ATH12K_DBG_DP_TX, "Failed to add HTT meta data, dropping packet\n"); @@ -336,7 +337,7 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, ab->device_stats.tx_enqueued[ti.ring_id]++; - ath12k_hal_tx_cmd_desc_setup(ab, hal_tcl_desc, &ti); + ath12k_wifi7_hal_tx_cmd_desc_setup(ab, hal_tcl_desc, &ti); ath12k_hal_srng_access_end(ab, tcl_ring); @@ -507,7 +508,8 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc, } } -static void ath12k_dp_tx_update_txcompl(struct ath12k *ar, struct hal_tx_status *ts) +static void +ath12k_wifi7_dp_tx_update_txcompl(struct ath12k *ar, struct hal_tx_status *ts) { struct ath12k_base *ab = ar->ab; struct ath12k_peer *peer; @@ -625,10 +627,10 @@ static void ath12k_dp_tx_update_txcompl(struct ath12k *ar, struct hal_tx_status spin_unlock_bh(&ab->base_lock); } -static void ath12k_dp_tx_complete_msdu(struct ath12k *ar, - struct ath12k_tx_desc_params *desc_params, - struct hal_tx_status *ts, - int ring) +static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k *ar, + struct ath12k_tx_desc_params *desc_params, + struct hal_tx_status *ts, + int ring) { struct ath12k_base *ab = ar->ab; struct ath12k_hw *ah = ar->ah; @@ -734,7 +736,7 @@ static void ath12k_dp_tx_complete_msdu(struct ath12k *ar, * Might end up reporting it out-of-band from HTT stats. */ - ath12k_dp_tx_update_txcompl(ar, ts); + ath12k_wifi7_dp_tx_update_txcompl(ar, ts); spin_lock_bh(&ab->base_lock); peer = ath12k_peer_find_by_id(ab, ts->peer_id); @@ -767,9 +769,10 @@ static void ath12k_dp_tx_complete_msdu(struct ath12k *ar, rcu_read_unlock(); } -static void ath12k_dp_tx_status_parse(struct ath12k_base *ab, - struct hal_wbm_completion_ring_tx *desc, - struct hal_tx_status *ts) +static void +ath12k_wifi7_dp_tx_status_parse(struct ath12k_base *ab, + struct hal_wbm_completion_ring_tx *desc, + struct hal_tx_status *ts) { u32 info0 = le32_to_cpu(desc->rate_stats.info0); @@ -803,7 +806,7 @@ static void ath12k_dp_tx_status_parse(struct ath12k_base *ab, } } -void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) +void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) { struct ath12k *ar; struct ath12k_dp *dp = &ab->dp; @@ -854,7 +857,7 @@ void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) tx_ring->tx_status_tail = ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_tail); tx_status = &tx_ring->tx_status[tx_ring->tx_status_tail]; - ath12k_dp_tx_status_parse(ab, tx_status, &ts); + ath12k_wifi7_dp_tx_status_parse(ab, tx_status, &ts); if (le32_get_bits(tx_status->info0, HAL_WBM_COMPL_TX_INFO0_CC_DONE)) { /* HW done cookie conversion */ @@ -902,7 +905,7 @@ void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) if (atomic_dec_and_test(&ar->dp.num_tx_pending)) wake_up(&ar->dp.tx_empty_waitq); - ath12k_dp_tx_complete_msdu(ar, &desc_params, &ts, - tx_ring->tcl_data_ring_id); + ath12k_wifi7_dp_tx_complete_msdu(ar, &desc_params, &ts, + tx_ring->tcl_data_ring_id); } } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h index 42faf664f8f8b..061c4de4d4e62 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h @@ -7,8 +7,8 @@ #ifndef ATH12K_DP_TX_WIFI7_H #define ATH12K_DP_TX_WIFI7_H -int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, - struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, - bool is_mcast); -void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id); +int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, + struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, + bool is_mcast); +void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index e539f3b1eeafc..7da840e3dac85 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -11,8 +11,9 @@ #include "hal_rx.h" #include "hal_desc.h" -static void ath12k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, - u8 owner, u8 buffer_type, u32 magic) +static +void ath12k_wifi7_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, + u8 owner, u8 buffer_type, u32 magic) { hdr->info0 = le32_encode_bits(owner, HAL_DESC_HDR_INFO0_OWNER) | le32_encode_bits(buffer_type, HAL_DESC_HDR_INFO0_BUF_TYPE); @@ -21,8 +22,8 @@ static void ath12k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, hdr->info0 |= le32_encode_bits(magic, HAL_DESC_HDR_INFO0_DBG_RESERVED); } -static int ath12k_hal_reo_cmd_queue_stats(struct hal_tlv_64_hdr *tlv, - struct ath12k_hal_reo_cmd *cmd) +static int ath12k_wifi7_hal_reo_cmd_queue_stats(struct hal_tlv_64_hdr *tlv, + struct ath12k_hal_reo_cmd *cmd) { struct hal_reo_get_queue_stats *desc; @@ -45,9 +46,9 @@ static int ath12k_hal_reo_cmd_queue_stats(struct hal_tlv_64_hdr *tlv, return le32_get_bits(desc->cmd.info0, HAL_REO_CMD_HDR_INFO0_CMD_NUMBER); } -static int ath12k_hal_reo_cmd_flush_cache(struct ath12k_hal *hal, - struct hal_tlv_64_hdr *tlv, - struct ath12k_hal_reo_cmd *cmd) +static int ath12k_wifi7_hal_reo_cmd_flush_cache(struct ath12k_hal *hal, + struct hal_tlv_64_hdr *tlv, + struct ath12k_hal_reo_cmd *cmd) { struct hal_reo_flush_cache *desc; u8 avail_slot = ffz(hal->avail_blk_resource); @@ -95,8 +96,9 @@ static int ath12k_hal_reo_cmd_flush_cache(struct ath12k_hal *hal, return le32_get_bits(desc->cmd.info0, HAL_REO_CMD_HDR_INFO0_CMD_NUMBER); } -static int ath12k_hal_reo_cmd_update_rx_queue(struct hal_tlv_64_hdr *tlv, - struct ath12k_hal_reo_cmd *cmd) +static int +ath12k_wifi7_hal_reo_cmd_update_rx_queue(struct hal_tlv_64_hdr *tlv, + struct ath12k_hal_reo_cmd *cmd) { struct hal_reo_update_rx_queue *desc; @@ -220,9 +222,9 @@ static int ath12k_hal_reo_cmd_update_rx_queue(struct hal_tlv_64_hdr *tlv, return le32_get_bits(desc->cmd.info0, HAL_REO_CMD_HDR_INFO0_CMD_NUMBER); } -int ath12k_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, - enum hal_reo_cmd_type type, - struct ath12k_hal_reo_cmd *cmd) +int ath12k_wifi7_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, + enum hal_reo_cmd_type type, + struct ath12k_hal_reo_cmd *cmd) { struct hal_tlv_64_hdr *reo_desc; int ret; @@ -238,13 +240,14 @@ int ath12k_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, switch (type) { case HAL_REO_CMD_GET_QUEUE_STATS: - ret = ath12k_hal_reo_cmd_queue_stats(reo_desc, cmd); + ret = ath12k_wifi7_hal_reo_cmd_queue_stats(reo_desc, cmd); break; case HAL_REO_CMD_FLUSH_CACHE: - ret = ath12k_hal_reo_cmd_flush_cache(&ab->hal, reo_desc, cmd); + ret = ath12k_wifi7_hal_reo_cmd_flush_cache(&ab->hal, reo_desc, + cmd); break; case HAL_REO_CMD_UPDATE_RX_QUEUE: - ret = ath12k_hal_reo_cmd_update_rx_queue(reo_desc, cmd); + ret = ath12k_wifi7_hal_reo_cmd_update_rx_queue(reo_desc, cmd); break; case HAL_REO_CMD_FLUSH_QUEUE: case HAL_REO_CMD_UNBLOCK_CACHE: @@ -265,8 +268,9 @@ int ath12k_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, return ret; } -void ath12k_hal_rx_buf_addr_info_set(struct ath12k_buffer_addr *binfo, - dma_addr_t paddr, u32 cookie, u8 manager) +void ath12k_wifi7_hal_rx_buf_addr_info_set(struct ath12k_buffer_addr *binfo, + dma_addr_t paddr, u32 cookie, + u8 manager) { u32 paddr_lo, paddr_hi; @@ -278,9 +282,9 @@ void ath12k_hal_rx_buf_addr_info_set(struct ath12k_buffer_addr *binfo, le32_encode_bits(manager, BUFFER_ADDR_INFO1_RET_BUF_MGR); } -void ath12k_hal_rx_buf_addr_info_get(struct ath12k_buffer_addr *binfo, - dma_addr_t *paddr, - u32 *cookie, u8 *rbm) +void ath12k_wifi7_hal_rx_buf_addr_info_get(struct ath12k_buffer_addr *binfo, + dma_addr_t *paddr, + u32 *cookie, u8 *rbm) { *paddr = (((u64)le32_get_bits(binfo->info1, BUFFER_ADDR_INFO1_ADDR)) << 32) | le32_get_bits(binfo->info0, BUFFER_ADDR_INFO0_ADDR); @@ -288,9 +292,10 @@ void ath12k_hal_rx_buf_addr_info_get(struct ath12k_buffer_addr *binfo, *rbm = le32_get_bits(binfo->info1, BUFFER_ADDR_INFO1_RET_BUF_MGR); } -void ath12k_hal_rx_msdu_link_info_get(struct hal_rx_msdu_link *link, u32 *num_msdus, - u32 *msdu_cookies, - enum hal_rx_buf_return_buf_manager *rbm) +void +ath12k_wifi7_hal_rx_msdu_link_info_get(struct hal_rx_msdu_link *link, + u32 *num_msdus, u32 *msdu_cookies, + enum hal_rx_buf_return_buf_manager *rbm) { struct hal_rx_msdu_details *msdu; u32 val; @@ -317,9 +322,9 @@ void ath12k_hal_rx_msdu_link_info_get(struct hal_rx_msdu_link *link, u32 *num_ms } } -int ath12k_hal_desc_reo_parse_err(struct ath12k_base *ab, - struct hal_reo_dest_ring *desc, - dma_addr_t *paddr, u32 *desc_bank) +int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_base *ab, + struct hal_reo_dest_ring *desc, + dma_addr_t *paddr, u32 *desc_bank) { enum hal_reo_dest_ring_push_reason push_reason; enum hal_reo_dest_ring_error_code err_code; @@ -338,14 +343,21 @@ int ath12k_hal_desc_reo_parse_err(struct ath12k_base *ab, return -EINVAL; } - ath12k_hal_rx_reo_ent_paddr_get(ab, &desc->buf_addr_info, paddr, &cookie); + val = le32_get_bits(desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE); + if (val != HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC) { + ath12k_warn(ab, "expected buffer type link_desc"); + return -EINVAL; + } + + ath12k_wifi7_hal_rx_reo_ent_paddr_get(ab, &desc->buf_addr_info, paddr, + &cookie); *desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK); return 0; } -int ath12k_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, - struct hal_rx_wbm_rel_info *rel_info) +int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, + struct hal_rx_wbm_rel_info *rel_info) { struct hal_wbm_release_ring *wbm_desc = desc; struct hal_wbm_release_ring_cc_rx *wbm_cc_desc = desc; @@ -432,9 +444,9 @@ int ath12k_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, return 0; } -void ath12k_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab, - struct ath12k_buffer_addr *buff_addr, - dma_addr_t *paddr, u32 *cookie) +void ath12k_wifi7_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab, + struct ath12k_buffer_addr *buff_addr, + dma_addr_t *paddr, u32 *cookie) { *paddr = ((u64)(le32_get_bits(buff_addr->info1, BUFFER_ADDR_INFO1_ADDR)) << 32) | @@ -523,10 +535,11 @@ void ath12k_hal_rx_msdu_list_get(struct ath12k *ar, *num_msdus = i; } -void ath12k_hal_rx_msdu_link_desc_set(struct ath12k_base *ab, - struct hal_wbm_release_ring *desc, - struct ath12k_buffer_addr *buf_addr_info, - enum hal_wbm_rel_bm_act action) +void +ath12k_wifi7_hal_rx_msdu_link_desc_set(struct ath12k_base *ab, + struct hal_wbm_release_ring *desc, + struct ath12k_buffer_addr *buf_addr_info, + enum hal_wbm_rel_bm_act action) { desc->buf_addr_info = *buf_addr_info; desc->info0 |= le32_encode_bits(HAL_WBM_REL_SRC_MODULE_SW, @@ -536,8 +549,9 @@ void ath12k_hal_rx_msdu_link_desc_set(struct ath12k_base *ab, HAL_WBM_RELEASE_INFO0_DESC_TYPE); } -void ath12k_hal_reo_status_queue_stats(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status) +void ath12k_wifi7_hal_reo_status_queue_stats(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status) { struct hal_reo_get_queue_stats_status *desc = (struct hal_reo_get_queue_stats_status *)tlv->value; @@ -599,8 +613,9 @@ void ath12k_hal_reo_status_queue_stats(struct ath12k_base *ab, struct hal_tlv_64 HAL_REO_GET_QUEUE_STATS_STATUS_INFO5_LOOPING_CNT)); } -void ath12k_hal_reo_flush_queue_status(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status) +void ath12k_wifi7_hal_reo_flush_queue_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status) { struct hal_reo_flush_queue_status *desc = (struct hal_reo_flush_queue_status *)tlv->value; @@ -616,8 +631,10 @@ void ath12k_hal_reo_flush_queue_status(struct ath12k_base *ab, struct hal_tlv_64 HAL_REO_FLUSH_QUEUE_INFO0_ERR_DETECTED); } -void ath12k_hal_reo_flush_cache_status(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status) +void +ath12k_wifi7_hal_reo_flush_cache_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status) { struct ath12k_hal *hal = &ab->hal; struct hal_reo_flush_cache_status *desc = @@ -657,8 +674,9 @@ void ath12k_hal_reo_flush_cache_status(struct ath12k_base *ab, struct hal_tlv_64 HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_COUNT); } -void ath12k_hal_reo_unblk_cache_status(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status) +void ath12k_wifi7_hal_reo_unblk_cache_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status) { struct ath12k_hal *hal = &ab->hal; struct hal_reo_unblock_cache_status *desc = @@ -684,9 +702,10 @@ void ath12k_hal_reo_unblk_cache_status(struct ath12k_base *ab, struct hal_tlv_64 hal->avail_blk_resource &= ~BIT(hal->current_blk_index); } -void ath12k_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status) +void +ath12k_wifi7_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status) { struct hal_reo_flush_timeout_list_status *desc = (struct hal_reo_flush_timeout_list_status *)tlv->value; @@ -713,9 +732,10 @@ void ath12k_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, HAL_REO_FLUSH_TIMEOUT_STATUS_INFO1_FWD_BUF_COUNT); } -void ath12k_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status) +void +ath12k_wifi7_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status) { struct hal_reo_desc_thresh_reached_status *desc = (struct hal_reo_desc_thresh_reached_status *)tlv->value; @@ -748,9 +768,9 @@ void ath12k_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, HAL_REO_DESC_THRESH_STATUS_INFO4_LINK_DESC_COUNTER_SUM); } -void ath12k_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status) +void ath12k_wifi7_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status) { struct hal_reo_status_hdr *desc = (struct hal_reo_status_hdr *)tlv->value; @@ -763,7 +783,7 @@ void ath12k_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab, HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS); } -u32 ath12k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid) +u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid) { u32 num_ext_desc, num_1k_desc = 0; @@ -789,15 +809,15 @@ u32 ath12k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid) (num_1k_desc * sizeof(struct hal_rx_reo_queue_1k)); } -void ath12k_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, - int tid, u32 ba_window_size, - u32 start_seq, enum hal_pn_type type) +void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, + int tid, u32 ba_window_size, + u32 start_seq, enum hal_pn_type type) { struct hal_rx_reo_queue_ext *ext_desc; - ath12k_hal_reo_set_desc_hdr(&qdesc->desc_hdr, HAL_DESC_REO_OWNED, - HAL_DESC_REO_QUEUE_DESC, - REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_0); + ath12k_wifi7_hal_reo_set_desc_hdr(&qdesc->desc_hdr, HAL_DESC_REO_OWNED, + HAL_DESC_REO_QUEUE_DESC, + REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_0); qdesc->rx_queue_num = le32_encode_bits(tid, HAL_RX_REO_QUEUE_RX_QUEUE_NUMBER); @@ -855,21 +875,24 @@ void ath12k_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, * queue descriptor in Rx peer entry as part of dp_rx_tid_update. */ memset(ext_desc, 0, 3 * sizeof(*ext_desc)); - ath12k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED, - HAL_DESC_REO_QUEUE_EXT_DESC, - REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_1); + ath12k_wifi7_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, + HAL_DESC_REO_OWNED, + HAL_DESC_REO_QUEUE_EXT_DESC, + REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_1); ext_desc++; - ath12k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED, - HAL_DESC_REO_QUEUE_EXT_DESC, - REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2); + ath12k_wifi7_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, + HAL_DESC_REO_OWNED, + HAL_DESC_REO_QUEUE_EXT_DESC, + REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2); ext_desc++; - ath12k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED, - HAL_DESC_REO_QUEUE_EXT_DESC, - REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3); + ath12k_wifi7_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, + HAL_DESC_REO_OWNED, + HAL_DESC_REO_QUEUE_EXT_DESC, + REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3); } -void ath12k_hal_reo_init_cmd_ring(struct ath12k_base *ab, - struct hal_srng *srng) +void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, + struct hal_srng *srng) { struct hal_srng_params params; struct hal_tlv_64_hdr *tlv; @@ -893,7 +916,7 @@ void ath12k_hal_reo_init_cmd_ring(struct ath12k_base *ab, } } -void ath12k_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) +void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) { u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; u32 val; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index d8d9d469c6704..458282343ff30 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -822,47 +822,47 @@ enum hal_mon_reception_type { #define HAL_RU_PER80(ru_per80, num_80mhz, ru_idx_per80mhz) \ (HAL_RU(ru_per80, num_80mhz, ru_idx_per80mhz)) -void ath12k_hal_reo_status_queue_stats(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status); -void ath12k_hal_reo_flush_queue_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status); -void ath12k_hal_reo_flush_cache_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status); -void ath12k_hal_reo_unblk_cache_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status); -void ath12k_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status); -void ath12k_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status); -void ath12k_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status); -void ath12k_hal_rx_msdu_link_info_get(struct hal_rx_msdu_link *link, u32 *num_msdus, - u32 *msdu_cookies, - enum hal_rx_buf_return_buf_manager *rbm); -void ath12k_hal_rx_msdu_link_desc_set(struct ath12k_base *ab, - struct hal_wbm_release_ring *desc, - struct ath12k_buffer_addr *buf_addr_info, - enum hal_wbm_rel_bm_act action); -void ath12k_hal_rx_buf_addr_info_set(struct ath12k_buffer_addr *binfo, - dma_addr_t paddr, u32 cookie, u8 manager); -void ath12k_hal_rx_buf_addr_info_get(struct ath12k_buffer_addr *binfo, - dma_addr_t *paddr, - u32 *cookie, u8 *rbm); -int ath12k_hal_desc_reo_parse_err(struct ath12k_base *ab, - struct hal_reo_dest_ring *desc, - dma_addr_t *paddr, u32 *desc_bank); -int ath12k_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, - struct hal_rx_wbm_rel_info *rel_info); -void ath12k_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab, - struct ath12k_buffer_addr *buff_addr, - dma_addr_t *paddr, u32 *cookie); +void ath12k_wifi7_hal_reo_status_queue_stats(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status); +void ath12k_wifi7_hal_reo_flush_queue_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status); +void ath12k_wifi7_hal_reo_flush_cache_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status); +void ath12k_wifi7_hal_reo_unblk_cache_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status); +void ath12k_wifi7_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status); +void ath12k_wifi7_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status); +void ath12k_wifi7_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab, + struct hal_tlv_64_hdr *tlv, + struct hal_reo_status *status); +void ath12k_wifi7_hal_rx_msdu_link_info_get(struct hal_rx_msdu_link *link, u32 *num_msdus, + u32 *msdu_cookies, + enum hal_rx_buf_return_buf_manager *rbm); +void ath12k_wifi7_hal_rx_msdu_link_desc_set(struct ath12k_base *ab, + struct hal_wbm_release_ring *desc, + struct ath12k_buffer_addr *buf_addr_info, + enum hal_wbm_rel_bm_act action); +void ath12k_wifi7_hal_rx_buf_addr_info_set(struct ath12k_buffer_addr *binfo, + dma_addr_t paddr, u32 cookie, u8 manager); +void ath12k_wifi7_hal_rx_buf_addr_info_get(struct ath12k_buffer_addr *binfo, + dma_addr_t *paddr, + u32 *cookie, u8 *rbm); +int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_base *ab, + struct hal_reo_dest_ring *desc, + dma_addr_t *paddr, u32 *desc_bank); +int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, + struct hal_rx_wbm_rel_info *rel_info); +void ath12k_wifi7_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab, + struct ath12k_buffer_addr *buff_addr, + dma_addr_t *paddr, u32 *cookie); void ath12k_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr, u32 *sw_cookie, struct ath12k_buffer_addr **pp_buf_addr, u8 *rbm, u32 *msdu_cnt); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c index 3a7d3163b1a56..027e02141ec2c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c @@ -29,9 +29,9 @@ static inline u8 dscp2tid(u8 dscp) return dscp >> 3; } -void ath12k_hal_tx_cmd_desc_setup(struct ath12k_base *ab, - struct hal_tcl_data_cmd *tcl_cmd, - struct hal_tx_info *ti) +void ath12k_wifi7_hal_tx_cmd_desc_setup(struct ath12k_base *ab, + struct hal_tcl_data_cmd *tcl_cmd, + struct hal_tx_info *ti) { tcl_cmd->buf_addr_info.info0 = le32_encode_bits(ti->paddr, BUFFER_ADDR_INFO0_ADDR); @@ -66,7 +66,7 @@ void ath12k_hal_tx_cmd_desc_setup(struct ath12k_base *ab, tcl_cmd->info5 = 0; } -void ath12k_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id) +void ath12k_wifi7_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id) { u32 ctrl_reg_val; u32 addr; @@ -137,8 +137,9 @@ void ath12k_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id) ctrl_reg_val); } -void ath12k_hal_tx_configure_bank_register(struct ath12k_base *ab, u32 bank_config, - u8 bank_id) +void ath12k_wifi7_hal_tx_configure_bank_register(struct ath12k_base *ab, + u32 bank_config, + u8 bank_id) { ath12k_hif_write32(ab, HAL_TCL_SW_CONFIG_BANK_ADDR + 4 * bank_id, bank_config); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h index 412fe1ba22dcc..d0f6a174f347c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h @@ -181,13 +181,13 @@ struct hal_tx_fes_status_end { /* STA mode will have MCAST_PKT_CTRL instead of DSCP_TID_MAP bitfield */ #define HAL_TX_BANK_CONFIG_DSCP_TIP_MAP_ID GENMASK(22, 17) -void ath12k_hal_tx_cmd_desc_setup(struct ath12k_base *ab, - struct hal_tcl_data_cmd *tcl_cmd, - struct hal_tx_info *ti); -void ath12k_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id); -int ath12k_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, - enum hal_reo_cmd_type type, - struct ath12k_hal_reo_cmd *cmd); -void ath12k_hal_tx_configure_bank_register(struct ath12k_base *ab, u32 bank_config, - u8 bank_id); +void ath12k_wifi7_hal_tx_cmd_desc_setup(struct ath12k_base *ab, + struct hal_tcl_data_cmd *tcl_cmd, + struct hal_tx_info *ti); +void ath12k_wifi7_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id); +int ath12k_wifi7_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, + enum hal_reo_cmd_type type, + struct ath12k_hal_reo_cmd *cmd); +void ath12k_wifi7_hal_tx_configure_bank_register(struct ath12k_base *ab, + u32 bank_config, u8 bank_id); #endif From 817e79f44c5d997be4ec4a5db4004cb0981649e9 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Tue, 30 Sep 2025 18:40:00 +0530 Subject: [PATCH 042/140] wifi: ath12k: Convert ath12k_dp member in ath12k_base to pointer Currently, the Data Path (DP) specific device object (ath12k_dp) is embedded directly within the ath12k_base structure. The DP object cannot be extended with architecture-specific fields within a contiguous memory block with this design. To address this, convert ath12k_dp into a dynamically allocated object and store it as a pointer in ath12k_base. This change allows allocation and initialization of ath12k_dp based on the underlying hardware architecture. Architecture-specific fields can now be maintained as private data within a contiguous memory block of ath12k_dp. This patch (and the forthcoming patches) are intended to serve the purpose of refactoring different DP objects for the Next Generation ath12k driver. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250930131005.2884253-2-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.c | 2 +- drivers/net/wireless/ath/ath12k/core.h | 12 +++- drivers/net/wireless/ath/ath12k/dp.c | 58 +++++++++++-------- drivers/net/wireless/ath/ath12k/dp_htt.c | 22 ++++--- drivers/net/wireless/ath/ath12k/dp_mon.c | 15 +++-- drivers/net/wireless/ath/ath12k/dp_rx.c | 20 +++---- drivers/net/wireless/ath/ath12k/mac.c | 4 +- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 2 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 40 ++++++++----- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 4 +- drivers/net/wireless/ath/ath12k/wmi.c | 3 +- 11 files changed, 110 insertions(+), 72 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index ca38f1f133708..4b9a49eaa3396 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -896,7 +896,7 @@ static int ath12k_core_start(struct ath12k_base *ab) goto err_hif_stop; } - ret = ath12k_dp_htt_connect(&ab->dp); + ret = ath12k_dp_htt_connect(ath12k_ab_to_dp(ab)); if (ret) { ath12k_err(ab, "failed to connect to HTT: %d\n", ret); goto err_hif_stop; diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 985616950b0d7..28bf34e420195 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1060,7 +1060,7 @@ struct ath12k_base { struct ath12k_htc htc; - struct ath12k_dp dp; + struct ath12k_dp *dp; void __iomem *mem; unsigned long mem_len; @@ -1521,4 +1521,14 @@ static inline s32 ath12k_pdev_get_noise_floor(struct ath12k *ar) return ar->rssi_info.noise_floor; } +/* The @ab->dp NULL check or assertion is intentionally omitted because + * @ab->dp is guaranteed to be non-NULL after a successful probe and + * remains valid until teardown. Invoking this before allocation or + * after teardown is considered invalid usage. + */ +static inline struct ath12k_dp *ath12k_ab_to_dp(struct ath12k_base *ab) +{ + return ab->dp; +} + #endif /* _CORE_H_ */ diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 296d7b17c15bd..5a76bc58dab8d 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -437,7 +437,7 @@ void ath12k_dp_tx_put_bank_profile(struct ath12k_dp *dp, u8 bank_id) static void ath12k_dp_deinit_bank_profiles(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); kfree(dp->bank_profiles); dp->bank_profiles = NULL; @@ -445,7 +445,7 @@ static void ath12k_dp_deinit_bank_profiles(struct ath12k_base *ab) static int ath12k_dp_init_bank_profiles(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); u32 num_tcl_banks = ab->hw_params->num_tcl_banks; int i; @@ -468,7 +468,7 @@ static int ath12k_dp_init_bank_profiles(struct ath12k_base *ab) static void ath12k_dp_srng_common_cleanup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int i; ath12k_dp_srng_cleanup(ab, &dp->reo_status_ring); @@ -485,7 +485,7 @@ static void ath12k_dp_srng_common_cleanup(struct ath12k_base *ab) static int ath12k_dp_srng_common_setup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); const struct ath12k_hal_tcl_to_wbm_rbm_map *map; struct hal_srng *srng; int i, ret, tx_comp_ring_num; @@ -591,7 +591,7 @@ static int ath12k_dp_srng_common_setup(struct ath12k_base *ab) static void ath12k_dp_scatter_idle_link_desc_cleanup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct hal_wbm_idle_scatter_list *slist = dp->scatter_list; int i; @@ -611,7 +611,7 @@ static int ath12k_dp_scatter_idle_link_desc_setup(struct ath12k_base *ab, u32 n_link_desc, u32 last_bank_sz) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct dp_link_desc_bank *link_desc_banks = dp->link_desc_banks; struct hal_wbm_idle_scatter_list *slist = dp->scatter_list; u32 n_entries_per_buf; @@ -705,7 +705,7 @@ static int ath12k_dp_link_desc_bank_alloc(struct ath12k_base *ab, int n_link_desc_bank, int last_bank_sz) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int i; int ret = 0; int desc_sz = DP_LINK_DESC_ALLOC_SIZE_THRESH; @@ -753,7 +753,7 @@ void ath12k_dp_link_desc_cleanup(struct ath12k_base *ab, static int ath12k_wbm_idle_ring_setup(struct ath12k_base *ab, u32 *n_link_desc) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); u32 n_mpdu_link_desc, n_mpdu_queue_desc; u32 n_tx_msdu_link_desc, n_rx_msdu_link_desc; int ret = 0; @@ -792,6 +792,7 @@ int ath12k_dp_link_desc_setup(struct ath12k_base *ab, u32 ring_type, struct hal_srng *srng, u32 n_link_desc) { + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); u32 tot_mem_sz; u32 n_link_desc_bank, last_bank_sz; u32 entry_sz, align_bytes, n_entries; @@ -799,7 +800,7 @@ int ath12k_dp_link_desc_setup(struct ath12k_base *ab, u32 paddr; int i, ret; u32 cookie; - enum hal_rx_buf_return_buf_manager rbm = ab->dp.idle_link_rbm; + enum hal_rx_buf_return_buf_manager rbm = dp->idle_link_rbm; tot_mem_sz = n_link_desc * HAL_LINK_DESC_SIZE; tot_mem_sz += HAL_LINK_DESC_ALIGN; @@ -967,7 +968,7 @@ void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif) ath12k_dp_update_vdev_search(arvif); arvif->vdev_id_check_en = true; - arvif->bank_id = ath12k_dp_tx_get_bank_profile(ab, arvif, &ab->dp); + arvif->bank_id = ath12k_dp_tx_get_bank_profile(ab, arvif, ath12k_ab_to_dp(ab)); /* TODO: error path for bank id failure */ if (arvif->bank_id == DP_INVALID_BANK_ID) { @@ -980,7 +981,7 @@ static void ath12k_dp_cc_cleanup(struct ath12k_base *ab) { struct ath12k_rx_desc_info *desc_info; struct ath12k_tx_desc_info *tx_desc_info, *tmp1; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_skb_cb *skb_cb; struct sk_buff *skb; struct ath12k *ar; @@ -1103,7 +1104,7 @@ static void ath12k_dp_cc_cleanup(struct ath12k_base *ab) static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); if (!ab->hw_params->reoq_lut_support) return; @@ -1131,7 +1132,7 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab) void ath12k_dp_free(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int i; if (!dp->ab) @@ -1154,7 +1155,8 @@ void ath12k_dp_free(struct ath12k_base *ab) ath12k_dp_rx_free(ab); /* Deinit any SOC level resource */ - dp->ab = NULL; + kfree(ab->dp); + ab->dp = NULL; } void ath12k_dp_cc_config(struct ath12k_base *ab) @@ -1218,7 +1220,7 @@ static u32 ath12k_dp_cc_cookie_gen(u16 ppt_idx, u16 spt_idx) static inline void *ath12k_dp_cc_get_desc_addr_ptr(struct ath12k_base *ab, u16 ppt_idx, u16 spt_idx) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); return dp->spt_info[ppt_idx].vaddr + spt_idx; } @@ -1226,7 +1228,7 @@ static inline void *ath12k_dp_cc_get_desc_addr_ptr(struct ath12k_base *ab, struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_base *ab, u32 cookie) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_rx_desc_info **desc_addr_ptr; u16 start_ppt_idx, end_ppt_idx, ppt_idx, spt_idx; @@ -1272,7 +1274,7 @@ struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_base *ab, static int ath12k_dp_cc_desc_init(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_rx_desc_info *rx_descs, **rx_desc_addr; struct ath12k_tx_desc_info *tx_descs, **tx_desc_addr; u32 num_rx_spt_pages = ATH12K_NUM_RX_SPT_PAGES(ab); @@ -1401,7 +1403,7 @@ void ath12k_dp_partner_cc_init(struct ath12k_base *ab) if (ag->ab[i] == ab) continue; - ath12k_dp_cmem_init(ab, &ag->ab[i]->dp, ATH12K_DP_RX_DESC); + ath12k_dp_cmem_init(ab, ath12k_ab_to_dp(ag->ab[i]), ATH12K_DP_RX_DESC); } } @@ -1412,7 +1414,7 @@ static u32 ath12k_dp_get_num_spt_pages(struct ath12k_base *ab) static int ath12k_dp_cc_init(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int i, ret = 0; INIT_LIST_HEAD(&dp->rx_desc_free_list); @@ -1498,7 +1500,7 @@ static int ath12k_dp_alloc_reoq_lut(struct ath12k_base *ab, static int ath12k_dp_reoq_lut_setup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); u32 val; int ret; @@ -1564,13 +1566,19 @@ ath12k_dp_get_idle_link_rbm(struct ath12k_base *ab) int ath12k_dp_alloc(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp; struct hal_srng *srng = NULL; size_t size = 0; u32 n_link_desc = 0; int ret; int i; + /* TODO: align dp later if cache alignment becomes a bottleneck */ + dp = kzalloc(sizeof(*dp), GFP_KERNEL); + if (!dp) + return -ENOMEM; + + ab->dp = dp; dp->ab = ab; INIT_LIST_HEAD(&dp->reo_cmd_list); @@ -1585,7 +1593,7 @@ int ath12k_dp_alloc(struct ath12k_base *ab) ret = ath12k_wbm_idle_ring_setup(ab, &n_link_desc); if (ret) { ath12k_warn(ab, "failed to setup wbm_idle_ring: %d\n", ret); - return ret; + goto fail_dp_free; } srng = &ab->hal.srng_list[dp->wbm_idle_ring.ring_id]; @@ -1594,7 +1602,7 @@ int ath12k_dp_alloc(struct ath12k_base *ab) HAL_WBM_IDLE_LINK, srng, n_link_desc); if (ret) { ath12k_warn(ab, "failed to setup link desc: %d\n", ret); - return ret; + goto fail_dp_free; } ret = ath12k_dp_cc_init(ab); @@ -1667,5 +1675,9 @@ int ath12k_dp_alloc(struct ath12k_base *ab) ath12k_dp_link_desc_cleanup(ab, dp->link_desc_banks, HAL_WBM_IDLE_LINK, &dp->wbm_idle_ring); +fail_dp_free: + kfree(ab->dp); + ab->dp = NULL; + return ret; } diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index 6ab5b2d8aac94..267220f43fd2c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -582,7 +582,7 @@ static void ath12k_htt_mlo_offset_event_handler(struct ath12k_base *ab, void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, struct sk_buff *skb) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct htt_resp_msg *resp = (struct htt_resp_msg *)skb->data; enum htt_t2h_msg_type type; u16 peer_id; @@ -734,6 +734,7 @@ ath12k_dp_tx_get_ring_id_type(struct ath12k_base *ab, int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id, int mac_id, enum hal_ring_type ring_type) { + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct htt_srng_setup_cmd *cmd; struct hal_srng *srng = &ab->hal.srng_list[ring_id]; struct hal_srng_params params; @@ -835,7 +836,7 @@ int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id, "ring_id:%d, ring_type:%d, intr_info:0x%x, flags:0x%x\n", ring_id, ring_type, cmd->intr_info, cmd->info2); - ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); + ret = ath12k_htc_send(&ab->htc, dp->eid, skb); if (ret) goto err_free; @@ -849,7 +850,7 @@ int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id, int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct sk_buff *skb; struct htt_ver_req_cmd *cmd; int len = sizeof(*cmd); @@ -901,7 +902,7 @@ int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab) int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask) { struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct sk_buff *skb; struct htt_ppdu_stats_cfg_cmd *cmd; int len = sizeof(*cmd); @@ -938,6 +939,7 @@ int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id, int rx_buf_size, struct htt_rx_ring_tlv_filter *tlv_filter) { + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct htt_rx_ring_selection_cfg_cmd *cmd; struct hal_srng *srng = &ab->hal.srng_list[ring_id]; struct hal_srng_params params; @@ -1070,7 +1072,7 @@ int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id, HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_MASK); } - ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); + ret = ath12k_htc_send(&ab->htc, dp->eid, skb); if (ret) goto err_free; @@ -1088,7 +1090,7 @@ ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type, u64 cookie) { struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct sk_buff *skb; struct htt_ext_stats_cfg_cmd *cmd; int len = sizeof(*cmd); @@ -1144,6 +1146,7 @@ int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset) int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset) { struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct htt_rx_ring_tlv_filter tlv_filter = {}; int ret, ring_id, i; @@ -1207,7 +1210,7 @@ int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset) if (!reset) { for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { - ring_id = ab->dp.rx_mac_buf_ring[i].ring_id; + ring_id = dp->rx_mac_buf_ring[i].ring_id; ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, i, HAL_RXDMA_BUF, @@ -1223,7 +1226,7 @@ int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset) } for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { - ring_id = ab->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; + ring_id = dp->rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; if (!reset) { tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING; @@ -1250,6 +1253,7 @@ int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id, int tx_buf_size, struct htt_tx_ring_tlv_filter *htt_tlv_filter) { + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct htt_tx_ring_selection_cfg_cmd *cmd; struct hal_srng *srng = &ab->hal.srng_list[ring_id]; struct hal_srng_params params; @@ -1342,7 +1346,7 @@ int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id, cmd->tlv_filter_mask_in3 = cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags2); - ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb); + ret = ath12k_htc_send(&ab->htc, dp->eid, skb); if (ret) goto err_free; diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 9085bf8d3dee1..c853c96ab220c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2470,7 +2470,8 @@ ath12k_dp_mon_parse_status_buf(struct ath12k *ar, const struct dp_mon_packet_info *packet_info) { struct ath12k_base *ab = ar->ab; - struct dp_rxdma_mon_ring *buf_ring = &ab->dp.rxdma_mon_buf_ring; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct dp_rxdma_mon_ring *buf_ring = &dp->rxdma_mon_buf_ring; struct sk_buff *msdu; int buf_id; u32 offset; @@ -3782,7 +3783,7 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget, struct ath12k_pdev_dp *pdev_dp = &ar->dp; struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&pdev_dp->mon_data; struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct hal_mon_dest_desc *mon_dst_desc; struct sk_buff *skb; struct ath12k_skb_rxcb *rxcb; @@ -3962,7 +3963,7 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, u8 rbm; ar = ab->pdevs[ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id)].ar; - dp = &ab->dp; + dp = ath12k_ab_to_dp(ab); pmon = &ar->dp.mon_data; srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, mac_id); rx_ring = &dp->rx_mon_status_refill_ring[srng_id]; @@ -4096,6 +4097,8 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, u32 *npackets, u32 *ppdu_id) { struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_buffer_addr *p_buf_addr_info, *p_last_buf_addr_info; u32 msdu_ppdu_id = 0, msdu_cnt = 0, total_len = 0, frag_len = 0; u32 rx_buf_size, rx_pkt_offset, sw_cookie; @@ -4147,8 +4150,8 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, desc_bank = u32_get_bits(sw_cookie, DP_LINK_DESC_BANK_MASK); msdu_link_desc = - ar->ab->dp.link_desc_banks[desc_bank].vaddr + - (paddr - ar->ab->dp.link_desc_banks[desc_bank].paddr); + dp->link_desc_banks[desc_bank].vaddr + + (paddr - dp->link_desc_banks[desc_bank].paddr); ath12k_hal_rx_msdu_list_get(ar, msdu_link_desc, &msdu_list, &num_msdus); @@ -4286,8 +4289,8 @@ static void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, struct ath12k_pdev_mon_stats *rx_mon_stats; u32 ppdu_id, rx_bufs_used = 0, ring_id; u32 mpdu_rx_bufs_used, npackets = 0; - struct ath12k_dp *dp = &ar->ab->dp; struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); void *ring_entry, *mon_dst_srng; struct dp_mon_mpdu *tmp_mpdu; LIST_HEAD(rx_desc_used_list); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index c420bf0016aaa..f6d7b5f974b1f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -76,7 +76,7 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, int num_remain; u32 cookie; dma_addr_t paddr; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_rx_desc_info *rx_desc; enum hal_rx_buf_return_buf_manager mgr = ab->hw_params->hal_params->rx_buf_rbm; @@ -191,7 +191,7 @@ static int ath12k_dp_rxdma_mon_buf_ring_free(struct ath12k_base *ab, static int ath12k_dp_rxdma_buf_free(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int i; ath12k_dp_rxdma_mon_buf_ring_free(ab, &dp->rxdma_mon_buf_ring); @@ -241,7 +241,7 @@ static int ath12k_dp_rxdma_ring_buf_setup(struct ath12k_base *ab, static int ath12k_dp_rxdma_buf_setup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct dp_rxdma_mon_ring *mon_ring; int ret, i; @@ -288,7 +288,7 @@ static void ath12k_dp_rx_pdev_srng_free(struct ath12k *ar) void ath12k_dp_rx_pdev_reo_cleanup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int i; for (i = 0; i < DP_REO_DST_RING_MAX; i++) @@ -297,7 +297,7 @@ void ath12k_dp_rx_pdev_reo_cleanup(struct ath12k_base *ab) int ath12k_dp_rx_pdev_reo_setup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int ret; int i; @@ -364,7 +364,7 @@ static void ath12k_dp_rx_tid_cleanup(struct ath12k_base *ab, void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_dp_rx_reo_cmd *cmd, *tmp; struct ath12k_dp_rx_reo_cache_flush_elem *cmd_cache, *tmp_cache; struct dp_reo_update_rx_queue_elem *cmd_queue, *tmp_queue; @@ -548,7 +548,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ enum hal_pn_type pn_type) { struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_peer *peer; struct ath12k_sta *ahsta; struct ath12k_dp_rx_tid *rx_tid; @@ -1551,7 +1551,7 @@ u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb) void ath12k_dp_rx_free(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct dp_srng *srng; int i; @@ -1583,7 +1583,7 @@ void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int mac_id) int ath12k_dp_rx_htt_setup(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); u32 ring_id; int i, ret; @@ -1655,7 +1655,7 @@ int ath12k_dp_rx_htt_setup(struct ath12k_base *ab) int ath12k_dp_rx_alloc(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct dp_srng *srng; int i, ret; diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 5ed10d75e5e42..cb7f491eaba97 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -10526,8 +10526,8 @@ static int ath12k_mac_vdev_delete(struct ath12k *ar, struct ath12k_link_vif *arv idr_for_each(&ar->txmgmt_idr, ath12k_mac_vif_txmgmt_idr_remove, vif); - ath12k_mac_vif_unref(&ab->dp, vif); - ath12k_dp_tx_put_bank_profile(&ab->dp, arvif->bank_id); + ath12k_mac_vif_unref(ath12k_ab_to_dp(ab), vif); + ath12k_dp_tx_put_bank_profile(ath12k_ab_to_dp(ab), arvif->bank_id); /* Recalc txpower for remaining vdev */ ath12k_mac_txpower_recalc(ar); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 05c278467cb32..4310f06163c93 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -120,7 +120,7 @@ int ath12k_wifi7_dp_service_srng(struct ath12k_base *ab, ath12k_wifi7_dp_rx_process_reo_status(ab); if (ab->hw_params->ring_mask->host2rxdma[grp_id]) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; LIST_HEAD(list); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 76bfa33120f3a..6353c2f1f709e 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -14,7 +14,7 @@ void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u1 dma_addr_t paddr) { struct ath12k_reo_queue_ref *qref; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); bool ml_peer = false; if (!ab->hw_params->reoq_lut_support) @@ -44,7 +44,7 @@ static void ath12k_wifi7_peer_rx_tid_qref_reset(struct ath12k_base *ab, u16 peer_id, u16 tid) { struct ath12k_reo_queue_ref *qref; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); bool ml_peer = false; if (!ab->hw_params->reoq_lut_support) @@ -106,7 +106,7 @@ int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, enum hal_wbm_rel_bm_act action) { struct hal_wbm_release_ring *desc; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct hal_srng *srng; int ret = 0; @@ -139,7 +139,7 @@ int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, void (*cb)(struct ath12k_dp *dp, void *ctx, enum hal_reo_cmd_status status)) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_dp_rx_reo_cmd *dp_cmd; struct hal_srng *cmd_ring; int cmd_num; @@ -617,9 +617,10 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, struct ath12k_hw_link *hw_links = ag->hw_links; int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; struct ath12k_rx_desc_info *desc_info; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; struct hal_reo_dest_ring *desc; + struct ath12k_dp *partner_dp; struct ath12k_base *partner_ab; struct sk_buff_head msdu_list; struct ath12k_skb_rxcb *rxcb; @@ -755,7 +756,8 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, continue; partner_ab = ath12k_ag_to_ab(ag, device_id); - rx_ring = &partner_ab->dp.rx_refill_buf_ring; + partner_dp = ath12k_ab_to_dp(partner_ab); + rx_ring = &partner_dp->rx_refill_buf_ring; ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, &rx_desc_used_list[device_id], @@ -804,7 +806,7 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, struct sk_buff *defrag_skb) { struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)defrag_skb->data; struct hal_reo_entrance_ring *reo_ent_ring; struct hal_reo_dest_ring *reo_dest_ring; @@ -1289,6 +1291,8 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n int budget) { struct ath12k_hw_group *ag = ab->ag; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_dp *partner_dp; struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; u32 msdu_cookies[HAL_NUM_RX_MSDUS_PER_LINK_DESC]; int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; @@ -1318,7 +1322,7 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) INIT_LIST_HEAD(&rx_desc_used_list[device_id]); - reo_except = &ab->dp.reo_except_ring; + reo_except = &dp->reo_except_ring; srng = &ab->hal.srng_list[reo_except->ring_id]; @@ -1343,17 +1347,18 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); device_id = hw_links[hw_link_id].device_id; partner_ab = ath12k_ag_to_ab(ag, device_id); + partner_dp = ath12k_ab_to_dp(partner_ab); pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, hw_links[hw_link_id].pdev_idx); ar = partner_ab->pdevs[pdev_id].ar; - link_desc_banks = partner_ab->dp.link_desc_banks; + link_desc_banks = partner_dp->link_desc_banks; link_desc_va = link_desc_banks[desc_bank].vaddr + (paddr - link_desc_banks[desc_bank].paddr); ath12k_wifi7_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies, &rbm); - if (rbm != partner_ab->dp.idle_link_rbm && + if (rbm != partner_dp->idle_link_rbm && rbm != HAL_RX_BUF_RBM_SW3_BM && rbm != partner_ab->hw_params->hal_params->rx_buf_rbm) { act = HAL_WBM_REL_BM_ACT_REL_MSDU; @@ -1414,7 +1419,8 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n continue; partner_ab = ath12k_ag_to_ab(ag, device_id); - rx_ring = &partner_ab->dp.rx_refill_buf_ring; + partner_dp = ath12k_ab_to_dp(partner_ab); + rx_ring = &partner_dp->rx_refill_buf_ring; ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, &rx_desc_used_list[device_id], @@ -1682,7 +1688,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; struct ath12k_hw_group *ag = ab->ag; struct ath12k *ar; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_dp *partner_dp; struct dp_rxdma_ring *rx_ring; struct hal_rx_wbm_rel_info err_info; struct hal_srng *srng; @@ -1833,7 +1840,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, continue; partner_ab = ath12k_ag_to_ab(ag, device_id); - rx_ring = &partner_ab->dp.rx_refill_buf_ring; + partner_dp = ath12k_ab_to_dp(partner_ab); + rx_ring = &partner_dp->rx_refill_buf_ring; ath12k_dp_rx_bufs_replenish(ab, rx_ring, &rx_desc_used_list[device_id], @@ -1883,7 +1891,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct htt_rx_ring_tlv_filter tlv_filter = {}; u32 ring_id; int ret; @@ -1921,7 +1929,7 @@ EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_qcn9274); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct htt_rx_ring_tlv_filter tlv_filter = {}; u32 ring_id; int ret = 0; @@ -1964,7 +1972,7 @@ EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_wcn7850); void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_base *ab) { - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct hal_tlv_64_hdr *hdr; struct hal_srng *srng; struct ath12k_dp_rx_reo_cmd *cmd, *tmp; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index b3928c3d007df..6a5d6f5259515 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -59,7 +59,7 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, bool is_mcast) { struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct hal_tx_info ti = {}; struct ath12k_tx_desc_info *tx_desc; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -809,7 +809,7 @@ ath12k_wifi7_dp_tx_status_parse(struct ath12k_base *ab, void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) { struct ath12k *ar; - struct ath12k_dp *dp = &ab->dp; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id; struct hal_srng *status_ring = &ab->hal.srng_list[hal_ring_id]; struct ath12k_tx_desc_info *tx_desc = NULL; diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index e87f1f8b95b94..a8a6159f8ee53 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -4120,6 +4120,7 @@ int ath12k_wmi_set_hw_mode(struct ath12k_base *ab, int ath12k_wmi_cmd_init(struct ath12k_base *ab) { + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_wmi_base *wmi_ab = &ab->wmi_ab; struct ath12k_wmi_init_cmd_arg arg = {}; @@ -4140,7 +4141,7 @@ int ath12k_wmi_cmd_init(struct ath12k_base *ab) arg.num_band_to_mac = ab->num_radios; ath12k_fill_band_to_mac_param(ab, arg.band_to_mac); - ab->dp.peer_metadata_ver = arg.res_cfg.peer_metadata_ver; + dp->peer_metadata_ver = arg.res_cfg.peer_metadata_ver; return ath12k_init_cmd_send(&wmi_ab->wmi[0], &arg); } From 94e4942e3c2ce20f4d15bc63a5b111696d01fe71 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Tue, 30 Sep 2025 18:40:01 +0530 Subject: [PATCH 043/140] wifi: ath12k: Support arch-specific DP device allocation Add arch_init() and arch_deinit() ops to the PCI and AHB family ops to support allocation and cleanup of architecture-specific fields in ath12k_base. Define shared ath12k_wifi7_arch_init() and ath12k_wifi7_arch_deinit() functions to handle DP device allocation and cleanup for Wi-Fi 7 across both PCI and AHB. Introduce a new header file wifi7/core.h to declare functions defined in wifi7/core.c. Currently, DP device allocation and cleanup are handled via arch_init() and arch_deinit(), which can be extended to support additional architecture-specific initialization in the future. Define common ath12k_wifi7_arch_init() and ath12k_wifi7_arch_deinit() functions to handle allocation and cleanup for Wi-Fi 7. Add a new header file wifi7/core.h to declare common Wi-Fi 7 functions. Add ath12k_wifi7_dp_device_alloc() and ath12k_wifi7_dp_device_free() to handle allocation and deallocation of the DP device object for Wi-Fi 7. Add ath12k_dp_cmn_device_init() and ath12k_dp_cmn_device_deinit() to initialize and deinitialize common DP device fields. Introduce a new header file dp_cmn.h to declare these functions, which can also be used to expose new common DP functions that need to be invoked from non-DP code. Rename existing DP allocation and cleanup functions to ath12k_dp_setup() and ath12k_dp_cleanup() to better reflect their purpose in the updated design. Replicate device-related fields such as device and hw_params in the DP device object to align with the new design, which limits per packet data path object usage to DP specific objects. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250930131005.2884253-3-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ahb.c | 19 ++++++++-- drivers/net/wireless/ath/ath12k/ahb.h | 4 ++- drivers/net/wireless/ath/ath12k/core.c | 13 +++---- drivers/net/wireless/ath/ath12k/dp.c | 38 +++++++++++--------- drivers/net/wireless/ath/ath12k/dp.h | 4 +-- drivers/net/wireless/ath/ath12k/dp_cmn.h | 12 +++++++ drivers/net/wireless/ath/ath12k/pci.c | 20 +++++++++-- drivers/net/wireless/ath/ath12k/pci.h | 4 ++- drivers/net/wireless/ath/ath12k/wifi7/ahb.c | 4 +++ drivers/net/wireless/ath/ath12k/wifi7/core.c | 24 +++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/core.h | 11 ++++++ drivers/net/wireless/ath/ath12k/wifi7/dp.c | 25 +++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp.h | 7 ++++ drivers/net/wireless/ath/ath12k/wifi7/pci.c | 4 +++ 14 files changed, 159 insertions(+), 30 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/dp_cmn.h create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/core.h diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index f49f117b90754..5c95bdd36d6aa 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -1088,14 +1088,26 @@ static int ath12k_ahb_probe(struct platform_device *pdev) goto err_rproc_deconfigure; } + /* Invoke arch_init here so that arch-specific init operations + * can utilize already initialized ab fields, such as HAL SRNGs. + */ + ret = ab_ahb->device_family_ops->arch_init(ab); + if (ret) { + ath12k_err(ab, "AHB arch_init failed %d\n", ret); + goto err_rproc_deconfigure; + } + ret = ath12k_core_init(ab); if (ret) { ath12k_err(ab, "failed to init core: %d\n", ret); - goto err_rproc_deconfigure; + goto err_deinit_arch; } return 0; +err_deinit_arch: + ab_ahb->device_family_ops->arch_deinit(ab); + err_rproc_deconfigure: ath12k_ahb_deconfigure_rproc(ab); @@ -1134,11 +1146,13 @@ static void ath12k_ahb_remove_prepare(struct ath12k_base *ab) static void ath12k_ahb_free_resources(struct ath12k_base *ab) { struct platform_device *pdev = ab->pdev; + struct ath12k_ahb *ab_ahb = ath12k_ab_to_ahb(ab); ath12k_hal_srng_deinit(ab); ath12k_ce_free_pipes(ab); ath12k_ahb_resource_deinit(ab); ath12k_ahb_deconfigure_rproc(ab); + ab_ahb->device_family_ops->arch_deinit(ab); ath12k_core_free(ab); platform_set_drvdata(pdev, NULL); } @@ -1167,7 +1181,8 @@ int ath12k_ahb_register_driver(const enum ath12k_device_family device_id, if (device_id >= ATH12K_DEVICE_FAMILY_MAX) return -EINVAL; - if (!driver || !driver->ops.probe) + if (!driver || !driver->ops.probe || + !driver->ops.arch_init || !driver->ops.arch_deinit) return -EINVAL; if (ath12k_ahb_family_drivers[device_id]) { diff --git a/drivers/net/wireless/ath/ath12k/ahb.h b/drivers/net/wireless/ath/ath12k/ahb.h index fce02e3af5fb4..8a040d03d27a3 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.h +++ b/drivers/net/wireless/ath/ath12k/ahb.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2025, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_AHB_H #define ATH12K_AHB_H @@ -46,6 +46,8 @@ struct ath12k_base; struct ath12k_ahb_device_family_ops { int (*probe)(struct platform_device *pdev); + int (*arch_init)(struct ath12k_base *ab); + void (*arch_deinit)(struct ath12k_base *ab); }; struct ath12k_ahb { diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 4b9a49eaa3396..c92990bae2ddf 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -22,6 +22,7 @@ #include "hif.h" #include "pci.h" #include "wow.h" +#include "dp_cmn.h" unsigned int ath12k_debug_mask; module_param_named(debug_mask, ath12k_debug_mask, uint, 0644); @@ -711,7 +712,7 @@ static void ath12k_core_stop(struct ath12k_base *ab) ath12k_dp_rx_pdev_reo_cleanup(ab); ath12k_hif_stop(ab); ath12k_wmi_detach(ab); - ath12k_dp_free(ab); + ath12k_dp_cmn_device_deinit(ath12k_ab_to_dp(ab)); /* De-Init of components as needed */ } @@ -1289,7 +1290,7 @@ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab) goto err_firmware_stop; } - ret = ath12k_dp_alloc(ab); + ret = ath12k_dp_cmn_device_init(ath12k_ab_to_dp(ab)); if (ret) { ath12k_err(ab, "failed to init DP: %d\n", ret); goto err_firmware_stop; @@ -1301,7 +1302,7 @@ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab) ret = ath12k_core_start(ab); if (ret) { ath12k_err(ab, "failed to start core: %d\n", ret); - goto err_dp_free; + goto err_deinit; } mutex_unlock(&ab->core_lock); @@ -1334,8 +1335,8 @@ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab) mutex_unlock(&ag->mutex); goto exit; -err_dp_free: - ath12k_dp_free(ab); +err_deinit: + ath12k_dp_cmn_device_deinit(ath12k_ab_to_dp(ab)); mutex_unlock(&ab->core_lock); mutex_unlock(&ag->mutex); @@ -1357,7 +1358,7 @@ static int ath12k_core_reconfigure_on_crash(struct ath12k_base *ab) ath12k_dp_rx_pdev_reo_cleanup(ab); mutex_unlock(&ab->core_lock); - ath12k_dp_free(ab); + ath12k_dp_cmn_device_deinit(ath12k_ab_to_dp(ab)); ath12k_hal_srng_deinit(ab); total_vdev = ab->num_radios * TARGET_NUM_VDEVS(ab); ab->free_vdev_map = (1LL << total_vdev) - 1; diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 5a76bc58dab8d..9d9665ce5019f 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -13,6 +13,7 @@ #include "wifi7/dp_rx.h" #include "peer.h" #include "dp_mon.h" +#include "dp_cmn.h" enum ath12k_dp_desc_type { ATH12K_DP_TX_DESC, @@ -1130,7 +1131,7 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab) } } -void ath12k_dp_free(struct ath12k_base *ab) +static void ath12k_dp_cleanup(struct ath12k_base *ab) { struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int i; @@ -1155,8 +1156,6 @@ void ath12k_dp_free(struct ath12k_base *ab) ath12k_dp_rx_free(ab); /* Deinit any SOC level resource */ - kfree(ab->dp); - ab->dp = NULL; } void ath12k_dp_cc_config(struct ath12k_base *ab) @@ -1564,7 +1563,7 @@ ath12k_dp_get_idle_link_rbm(struct ath12k_base *ab) } } -int ath12k_dp_alloc(struct ath12k_base *ab) +static int ath12k_dp_setup(struct ath12k_base *ab) { struct ath12k_dp *dp; struct hal_srng *srng = NULL; @@ -1573,12 +1572,7 @@ int ath12k_dp_alloc(struct ath12k_base *ab) int ret; int i; - /* TODO: align dp later if cache alignment becomes a bottleneck */ - dp = kzalloc(sizeof(*dp), GFP_KERNEL); - if (!dp) - return -ENOMEM; - - ab->dp = dp; + dp = ath12k_ab_to_dp(ab); dp->ab = ab; INIT_LIST_HEAD(&dp->reo_cmd_list); @@ -1593,7 +1587,7 @@ int ath12k_dp_alloc(struct ath12k_base *ab) ret = ath12k_wbm_idle_ring_setup(ab, &n_link_desc); if (ret) { ath12k_warn(ab, "failed to setup wbm_idle_ring: %d\n", ret); - goto fail_dp_free; + return ret; } srng = &ab->hal.srng_list[dp->wbm_idle_ring.ring_id]; @@ -1602,7 +1596,7 @@ int ath12k_dp_alloc(struct ath12k_base *ab) HAL_WBM_IDLE_LINK, srng, n_link_desc); if (ret) { ath12k_warn(ab, "failed to setup link desc: %d\n", ret); - goto fail_dp_free; + return ret; } ret = ath12k_dp_cc_init(ab); @@ -1675,9 +1669,21 @@ int ath12k_dp_alloc(struct ath12k_base *ab) ath12k_dp_link_desc_cleanup(ab, dp->link_desc_banks, HAL_WBM_IDLE_LINK, &dp->wbm_idle_ring); -fail_dp_free: - kfree(ab->dp); - ab->dp = NULL; - return ret; } + +void ath12k_dp_cmn_device_deinit(struct ath12k_dp *dp) +{ + ath12k_dp_cleanup(dp->ab); +} + +int ath12k_dp_cmn_device_init(struct ath12k_dp *dp) +{ + int ret; + + ret = ath12k_dp_setup(dp->ab); + if (ret) + return ret; + + return 0; +} diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 5c8e6089f9e94..938a7ebfe55f4 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -428,6 +428,8 @@ struct ath12k_dp { struct dp_rxdma_mon_ring rx_mon_status_refill_ring[MAX_RXDMA_PER_PDEV]; struct ath12k_reo_q_addr_lut reoq_lut; struct ath12k_reo_q_addr_lut ml_reoq_lut; + const struct ath12k_hw_params *hw_params; + struct device *dev; }; static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) @@ -437,8 +439,6 @@ static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) } void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif); -void ath12k_dp_free(struct ath12k_base *ab); -int ath12k_dp_alloc(struct ath12k_base *ab); void ath12k_dp_cc_config(struct ath12k_base *ab); void ath12k_dp_partner_cc_init(struct ath12k_base *ab); int ath12k_dp_pdev_alloc(struct ath12k_base *ab); diff --git a/drivers/net/wireless/ath/ath12k/dp_cmn.h b/drivers/net/wireless/ath/ath12k/dp_cmn.h new file mode 100644 index 0000000000000..acc0782ad3096 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/dp_cmn.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_DP_CMN_H +#define ATH12K_DP_CMN_H + +void ath12k_dp_cmn_device_deinit(struct ath12k_dp *dp); +int ath12k_dp_cmn_device_init(struct ath12k_dp *dp); + +#endif diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 257c5bc3c0f16..12a8c2f55a4cf 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -1638,13 +1638,25 @@ static int ath12k_pci_probe(struct pci_dev *pdev, goto err_free_irq; } + /* Invoke arch_init here so that arch-specific init operations + * can utilize already initialized ab fields, such as HAL SRNGs. + */ + ret = ab_pci->device_family_ops->arch_init(ab); + if (ret) { + ath12k_err(ab, "PCI arch_init failed %d\n", ret); + goto err_pci_msi_free; + } + ret = ath12k_core_init(ab); if (ret) { ath12k_err(ab, "failed to init core: %d\n", ret); - goto err_free_irq; + goto err_deinit_arch; } return 0; +err_deinit_arch: + ab_pci->device_family_ops->arch_deinit(ab); + err_free_irq: /* __free_irq() expects the caller to have cleared the affinity hint */ ath12k_pci_set_irq_affinity_hint(ab_pci, NULL); @@ -1703,6 +1715,9 @@ static void ath12k_pci_remove(struct pci_dev *pdev) ath12k_hal_srng_deinit(ab); ath12k_ce_free_pipes(ab); + + ab_pci->device_family_ops->arch_deinit(ab); + ath12k_core_free(ab); } @@ -1799,7 +1814,8 @@ int ath12k_pci_register_driver(const enum ath12k_device_family device_id, if (device_id >= ATH12K_DEVICE_FAMILY_MAX) return -EINVAL; - if (!driver || !driver->ops.probe) + if (!driver || !driver->ops.probe || + !driver->ops.arch_init || !driver->ops.arch_deinit) return -EINVAL; if (ath12k_pci_family_drivers[device_id]) { diff --git a/drivers/net/wireless/ath/ath12k/pci.h b/drivers/net/wireless/ath/ath12k/pci.h index 5af33e5deacfd..2c19bb42f0f70 100644 --- a/drivers/net/wireless/ath/ath12k/pci.h +++ b/drivers/net/wireless/ath/ath12k/pci.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2019-2021 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 ATH12K_PCI_H #define ATH12K_PCI_H @@ -97,6 +97,8 @@ struct ath12k_pci_ops { struct ath12k_pci_device_family_ops { int (*probe)(struct pci_dev *pdev, const struct pci_device_id *pci_dev); + int (*arch_init)(struct ath12k_base *ab); + void (*arch_deinit)(struct ath12k_base *ab); }; struct ath12k_pci_reg_base { diff --git a/drivers/net/wireless/ath/ath12k/wifi7/ahb.c b/drivers/net/wireless/ath/ath12k/wifi7/ahb.c index 803e13207bc06..a6c5f7689edd1 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/ahb.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/ahb.c @@ -12,6 +12,8 @@ #include "../debug.h" #include "../hif.h" #include "hw.h" +#include "dp.h" +#include "core.h" static const struct of_device_id ath12k_wifi7_ahb_of_match[] = { { .compatible = "qcom,ipq5332-wifi", @@ -57,6 +59,8 @@ static struct ath12k_ahb_driver ath12k_wifi7_ahb_driver = { .name = "ath12k_wifi7_ahb", .id_table = ath12k_wifi7_ahb_of_match, .ops.probe = ath12k_wifi7_ahb_probe, + .ops.arch_init = ath12k_wifi7_arch_init, + .ops.arch_deinit = ath12k_wifi7_arch_deinit, }; int ath12k_wifi7_ahb_init(void) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/core.c b/drivers/net/wireless/ath/ath12k/wifi7/core.c index eb882e56e5ec2..a02c57acf1374 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/core.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/core.c @@ -9,9 +9,33 @@ #include "../pci.h" #include "pci.h" #include "ahb.h" +#include "core.h" +#include "dp.h" +#include "../debug.h" static int ahb_err, pci_err; +int ath12k_wifi7_arch_init(struct ath12k_base *ab) +{ + struct ath12k_dp *dp; + + dp = ath12k_wifi7_dp_device_alloc(ab); + if (!dp) { + ath12k_err(ab, "dp alloc failed"); + return -EINVAL; + } + + ab->dp = dp; + + return 0; +} + +void ath12k_wifi7_arch_deinit(struct ath12k_base *ab) +{ + ath12k_wifi7_dp_device_free(ab->dp); + ab->dp = NULL; +} + static int ath12k_wifi7_init(void) { ahb_err = ath12k_wifi7_ahb_init(); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/core.h b/drivers/net/wireless/ath/ath12k/wifi7/core.h new file mode 100644 index 0000000000000..7e9689d2ddd73 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/core.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#ifndef ATH12K_CORE_WIFI7_H +#define ATH12K_CORE_WIFI7_H + +int ath12k_wifi7_arch_init(struct ath12k_base *ab); +void ath12k_wifi7_arch_deinit(struct ath12k_base *ab); + +#endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 4310f06163c93..adc3480b282b3 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -8,6 +8,7 @@ #include "../dp_rx.h" #include "../dp_tx.h" #include "../dp_mon.h" +#include "../dp_cmn.h" #include "dp_rx.h" #include "dp.h" #include "dp_tx.h" @@ -132,3 +133,27 @@ int ath12k_wifi7_dp_service_srng(struct ath12k_base *ab, done: return tot_work_done; } + +/* TODO: remove export once this file is built with wifi7 ko */ +struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab) +{ + struct ath12k_dp *dp; + + /* TODO: align dp later if cache alignment becomes a bottleneck */ + dp = kzalloc(sizeof(*dp), GFP_KERNEL); + if (!dp) + return NULL; + + dp->ab = ab; + dp->dev = ab->dev; + dp->hw_params = ab->hw_params; + + return dp; +} +EXPORT_SYMBOL(ath12k_wifi7_dp_device_alloc); + +void ath12k_wifi7_dp_device_free(struct ath12k_dp *dp) +{ + kfree(dp); +} +EXPORT_SYMBOL(ath12k_wifi7_dp_device_free); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.h b/drivers/net/wireless/ath/ath12k/wifi7/dp.h index 9332b9401bbf7..2300fda657865 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.h @@ -7,8 +7,15 @@ #ifndef ATH12K_DP_WIFI7_H #define ATH12K_DP_WIFI7_H +#include "../dp_cmn.h" #include "hw.h" +struct ath12k_base; +struct ath12k_dp; + int ath12k_wifi7_dp_service_srng(struct ath12k_base *ab, struct ath12k_ext_irq_grp *irq_grp, int budget); +struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab); +void ath12k_wifi7_dp_device_free(struct ath12k_dp *dp); + #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/pci.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c index ba8c19c24ae6a..f6dfdcf95025a 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/pci.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -13,6 +13,8 @@ #include "../mhi.h" #include "hw.h" #include "../hal.h" +#include "dp.h" +#include "core.h" #define QCN9274_DEVICE_ID 0x1109 #define WCN7850_DEVICE_ID 0x1107 @@ -163,6 +165,8 @@ static struct ath12k_pci_driver ath12k_wifi7_pci_driver = { .id_table = ath12k_wifi7_pci_id_table, .ops.probe = ath12k_wifi7_pci_probe, .reg_base = &ath12k_wifi7_reg_base, + .ops.arch_init = ath12k_wifi7_arch_init, + .ops.arch_deinit = ath12k_wifi7_arch_deinit, }; int ath12k_wifi7_pci_init(void) From 6c2441190932a61170cfbd0b301e2efb3e7feb7f Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Tue, 30 Sep 2025 18:40:02 +0530 Subject: [PATCH 044/140] wifi: ath12k: Rearrange DP fields in ath12k_hw_group struct Introduce the ath12k_dp_hw_group struct within ath12k_hw_group to encapsulate all Data Path fields, providing a baseline for future extensions. Add this struct to the top of ath12k_hw_group to allow optimal usage of cache lines for data path fields, as it is accessed in multiple tight loops in the per-packet path. Add cmn_def.h to define common macros shared between DP and other modules. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250930131005.2884253-4-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/cmn_defs.h | 13 +++++ drivers/net/wireless/ath/ath12k/core.c | 4 ++ drivers/net/wireless/ath/ath12k/core.h | 9 ++- drivers/net/wireless/ath/ath12k/dp.c | 24 ++++++++ drivers/net/wireless/ath/ath12k/dp.h | 10 ++++ drivers/net/wireless/ath/ath12k/dp_cmn.h | 12 ++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 58 +++++++++++-------- drivers/net/wireless/ath/ath12k/wmi.h | 3 +- 8 files changed, 104 insertions(+), 29 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/cmn_defs.h diff --git a/drivers/net/wireless/ath/ath12k/cmn_defs.h b/drivers/net/wireless/ath/ath12k/cmn_defs.h new file mode 100644 index 0000000000000..e1f1f50341ff0 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/cmn_defs.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_CMN_DEFS_H +#define ATH12K_CMN_DEFS_H + +#define MAX_RADIOS 2 +#define ATH12K_MAX_DEVICES 3 +#define ATH12K_GROUP_MAX_RADIO (ATH12K_MAX_DEVICES * MAX_RADIOS) + +#endif diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index c92990bae2ddf..c82c0746a3494 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -1992,6 +1992,8 @@ static struct ath12k_hw_group *ath12k_core_hw_group_assign(struct ath12k_base *a ag->ab[ab->device_id] = ab; ab->ag = ag; + ath12k_dp_cmn_hw_group_assign(ath12k_ab_to_dp(ab), ag); + ath12k_dbg(ab, ATH12K_DBG_BOOT, "wsi group-id %d num-devices %d index %d", ag->id, ag->num_devices, wsi->index); @@ -2019,6 +2021,8 @@ void ath12k_core_hw_group_unassign(struct ath12k_base *ab) return; } + ath12k_dp_cmn_hw_group_unassign(ath12k_ab_to_dp(ab), ag); + ag->ab[device_id] = NULL; ab->ag = NULL; ab->device_id = ATH12K_INVALID_DEVICE_ID; diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 28bf34e420195..0c84347901901 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -34,6 +34,7 @@ #include "wow.h" #include "debugfs_htt_stats.h" #include "coredump.h" +#include "cmn_defs.h" #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) @@ -64,8 +65,6 @@ #define ATH12K_RECONFIGURE_TIMEOUT_HZ (10 * HZ) #define ATH12K_RECOVER_START_TIMEOUT_HZ (20 * HZ) -#define ATH12K_MAX_DEVICES 3 -#define ATH12K_GROUP_MAX_RADIO (ATH12K_MAX_DEVICES * MAX_RADIOS) #define ATH12K_INVALID_GROUP_ID 0xFF #define ATH12K_INVALID_DEVICE_ID 0xFF @@ -987,6 +986,11 @@ struct ath12k_hw_link { * wiphy, protected with struct ath12k_hw_group::mutex. */ struct ath12k_hw_group { + /* Keep dp_hw_grp as the first member to allow efficient + * usage of cache lines for DP fields + */ + struct ath12k_dp_hw_group dp_hw_grp; + struct ath12k_hw_link hw_links[ATH12K_GROUP_MAX_RADIO]; struct list_head list; u8 id; u8 num_devices; @@ -1009,7 +1013,6 @@ struct ath12k_hw_group { bool mlo_capable; struct device_node *wsi_node[ATH12K_MAX_DEVICES]; struct ath12k_mlo_memory mlo_mem; - struct ath12k_hw_link hw_links[ATH12K_GROUP_MAX_RADIO]; bool hw_link_id_init_done; }; diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 9d9665ce5019f..1e14f3a70904c 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1687,3 +1687,27 @@ int ath12k_dp_cmn_device_init(struct ath12k_dp *dp) return 0; } + +void ath12k_dp_cmn_hw_group_unassign(struct ath12k_dp *dp, + struct ath12k_hw_group *ag) +{ + struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; + + lockdep_assert_held(&ag->mutex); + + dp_hw_grp->dp[dp->device_id] = NULL; + + dp->ag = NULL; + dp->device_id = ATH12K_INVALID_DEVICE_ID; +} + +void ath12k_dp_cmn_hw_group_assign(struct ath12k_dp *dp, + struct ath12k_hw_group *ag) +{ + struct ath12k_base *ab = dp->ab; + struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; + + dp->ag = ag; + dp->device_id = ab->device_id; + dp_hw_grp->dp[dp->device_id] = dp; +} diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 938a7ebfe55f4..84f40a6612d31 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -11,6 +11,7 @@ #include "wifi7/hal_rx.h" #include "hw.h" #include "dp_htt.h" +#include "dp_cmn.h" #define MAX_RXDMA_PER_PDEV 2 @@ -430,6 +431,9 @@ struct ath12k_dp { struct ath12k_reo_q_addr_lut ml_reoq_lut; const struct ath12k_hw_params *hw_params; struct device *dev; + + struct ath12k_hw_group *ag; + u8 device_id; }; static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) @@ -438,6 +442,12 @@ static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) memcpy(addr + 4, &addr_h16, ETH_ALEN - 4); } +static inline struct ath12k_dp * +ath12k_dp_hw_grp_to_dp(struct ath12k_dp_hw_group *dp_hw_grp, u8 device_id) +{ + return dp_hw_grp->dp[device_id]; +} + void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif); void ath12k_dp_cc_config(struct ath12k_base *ab); void ath12k_dp_partner_cc_init(struct ath12k_base *ab); diff --git a/drivers/net/wireless/ath/ath12k/dp_cmn.h b/drivers/net/wireless/ath/ath12k/dp_cmn.h index acc0782ad3096..70c92f6d33d6f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_cmn.h +++ b/drivers/net/wireless/ath/ath12k/dp_cmn.h @@ -6,7 +6,19 @@ #ifndef ATH12K_DP_CMN_H #define ATH12K_DP_CMN_H +#include "cmn_defs.h" + +struct ath12k_hw_group; + +struct ath12k_dp_hw_group { + struct ath12k_dp *dp[ATH12K_MAX_DEVICES]; +}; + void ath12k_dp_cmn_device_deinit(struct ath12k_dp *dp); int ath12k_dp_cmn_device_init(struct ath12k_dp *dp); +void ath12k_dp_cmn_hw_group_unassign(struct ath12k_dp *dp, + struct ath12k_hw_group *ag); +void ath12k_dp_cmn_hw_group_assign(struct ath12k_dp *dp, + struct ath12k_hw_group *ag); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 6353c2f1f709e..04c64b9046938 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -558,7 +558,9 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, struct sk_buff_head *msdu_list, int ring_id) { - struct ath12k_hw_group *ag = ab->ag; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_hw_group *ag = dp->ag; + struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct ieee80211_rx_status rx_status = {}; struct ath12k_skb_rxcb *rxcb; struct sk_buff *msdu; @@ -566,6 +568,7 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, struct ath12k_hw_link *hw_links = ag->hw_links; struct ath12k_base *partner_ab; struct hal_rx_desc_data rx_info; + struct ath12k_dp *partner_dp; u8 hw_link_id, pdev_id; int ret; @@ -580,10 +583,11 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, while ((msdu = __skb_dequeue(msdu_list))) { rxcb = ATH12K_SKB_RXCB(msdu); hw_link_id = rxcb->hw_link_id; - partner_ab = ath12k_ag_to_ab(ag, - hw_links[hw_link_id].device_id); - pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, + hw_links[hw_link_id].device_id); + pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params, hw_links[hw_link_id].pdev_idx); + partner_ab = partner_dp->ab; ar = partner_ab->pdevs[pdev_id].ar; if (!rcu_dereference(partner_ab->pdevs_active[pdev_id])) { dev_kfree_skb_any(msdu); @@ -612,12 +616,13 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, struct napi_struct *napi, int budget) { - struct ath12k_hw_group *ag = ab->ag; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_hw_group *ag = dp->ag; + struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; struct ath12k_hw_link *hw_links = ag->hw_links; int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; struct ath12k_rx_desc_info *desc_info; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; struct hal_reo_dest_ring *desc; struct ath12k_dp *partner_dp; @@ -660,8 +665,8 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, desc_info = (struct ath12k_rx_desc_info *)((unsigned long)desc_va); device_id = hw_links[hw_link_id].device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - if (unlikely(!partner_ab)) { + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + if (unlikely(!partner_dp)) { if (desc_info->skb) { dev_kfree_skb_any(desc_info->skb); desc_info->skb = NULL; @@ -669,6 +674,7 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, continue; } + partner_ab = partner_dp->ab; /* retry manual desc retrieval */ if (!desc_info) { @@ -755,8 +761,8 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, if (!num_buffs_reaped[device_id]) continue; - partner_ab = ath12k_ag_to_ab(ag, device_id); - partner_dp = ath12k_ab_to_dp(partner_ab); + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + partner_ab = partner_dp->ab; rx_ring = &partner_dp->rx_refill_buf_ring; ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, @@ -1290,8 +1296,9 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k *ar, int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, int budget) { - struct ath12k_hw_group *ag = ab->ag; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_hw_group *ag = dp->ag; + struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct ath12k_dp *partner_dp; struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; u32 msdu_cookies[HAL_NUM_RX_MSDUS_PER_LINK_DESC]; @@ -1346,8 +1353,8 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n hw_link_id = le32_get_bits(reo_desc->info0, HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); device_id = hw_links[hw_link_id].device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - partner_dp = ath12k_ab_to_dp(partner_ab); + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + partner_ab = partner_dp->ab; pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, hw_links[hw_link_id].pdev_idx); @@ -1418,8 +1425,8 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n if (!num_buffs_reaped[device_id]) continue; - partner_ab = ath12k_ag_to_ab(ag, device_id); - partner_dp = ath12k_ab_to_dp(partner_ab); + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + partner_ab = partner_dp->ab; rx_ring = &partner_dp->rx_refill_buf_ring; ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, @@ -1686,9 +1693,10 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, struct napi_struct *napi, int budget) { struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; - struct ath12k_hw_group *ag = ab->ag; struct ath12k *ar; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_hw_group *ag = dp->ag; + struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct ath12k_dp *partner_dp; struct dp_rxdma_ring *rx_ring; struct hal_rx_wbm_rel_info err_info; @@ -1751,8 +1759,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, desc_info->skb = NULL; device_id = desc_info->device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - if (unlikely(!partner_ab)) { + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + if (unlikely(!partner_dp)) { dev_kfree_skb_any(msdu); /* In any case continuation bit is set @@ -1762,10 +1770,12 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, continue; } + partner_ab = partner_dp->ab; + list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]); rxcb = ATH12K_SKB_RXCB(msdu); - dma_unmap_single(partner_ab->dev, rxcb->paddr, + dma_unmap_single(partner_dp->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), DMA_FROM_DEVICE); @@ -1839,8 +1849,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, if (!num_buffs_reaped[device_id]) continue; - partner_ab = ath12k_ag_to_ab(ag, device_id); - partner_dp = ath12k_ab_to_dp(partner_ab); + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); rx_ring = &partner_dp->rx_refill_buf_ring; ath12k_dp_rx_bufs_replenish(ab, rx_ring, @@ -1854,8 +1863,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, hw_link_id = rxcb->hw_link_id; device_id = hw_links[hw_link_id].device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - if (unlikely(!partner_ab)) { + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + if (unlikely(!partner_dp)) { ath12k_dbg(ab, ATH12K_DBG_DATA, "Unable to process WBM error msdu due to invalid hw link id %d device id %d\n", hw_link_id, device_id); @@ -1863,8 +1872,9 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, continue; } - pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params, hw_links[hw_link_id].pdev_idx); + partner_ab = partner_dp->ab; ar = partner_ab->pdevs[pdev_id].ar; if (!ar || !rcu_dereference(ar->ab->pdevs_active[pdev_id])) { diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index b1ba1f8b6bb2d..65f0d7ed4178d 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -9,6 +9,7 @@ #include #include "htc.h" +#include "cmn_defs.h" /* Naming conventions for structures: * @@ -5151,8 +5152,6 @@ struct wmi_probe_tmpl_cmd { __le32 buf_len; } __packed; -#define MAX_RADIOS 2 - #define WMI_MLO_CMD_TIMEOUT_HZ (5 * HZ) #define WMI_SERVICE_READY_TIMEOUT_HZ (5 * HZ) #define WMI_SEND_TIMEOUT_HZ (3 * HZ) From b4e51f42baa6b23611a24391994d4ed3b55bb62a Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Tue, 30 Sep 2025 18:40:03 +0530 Subject: [PATCH 045/140] wifi: ath12k: Add framework for hardware specific ieee80211_ops registration Introduce a framework to register the ieee80211_ops table based on the underlying hardware architecture. This is necessary to support architecture-specific implementations of ieee80211_ops such as .tx, which will be introduced in upcoming patches. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250930131005.2884253-5-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 5 + drivers/net/wireless/ath/ath12k/debugfs.c | 1 + drivers/net/wireless/ath/ath12k/debugfs_sta.c | 3 +- drivers/net/wireless/ath/ath12k/mac.c | 329 ++++++++---------- drivers/net/wireless/ath/ath12k/mac.h | 126 +++++++ drivers/net/wireless/ath/ath12k/testmode.c | 3 +- drivers/net/wireless/ath/ath12k/wifi7/hw.c | 62 ++++ drivers/net/wireless/ath/ath12k/wow.c | 5 +- 8 files changed, 348 insertions(+), 186 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 0c84347901901..1ec6f57bbe699 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1249,6 +1249,11 @@ struct ath12k_base { const struct ath12k_mem_profile_based_param *profile_param; enum ath12k_qmi_mem_mode target_mem_mode; + /* FIXME: Define this field in a ag equivalent object available + * during the initial phase of probe later. + */ + const struct ieee80211_ops *ath12k_ops; + /* must be last */ u8 drv_priv[] __aligned(sizeof(void *)); }; diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c index d6a86f075d73b..f25af9adeac82 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs.c +++ b/drivers/net/wireless/ath/ath12k/debugfs.c @@ -1020,6 +1020,7 @@ void ath12k_debugfs_op_vif_add(struct ieee80211_hw *hw, debugfs_create_file("link_stats", 0400, vif->debugfs_dir, ahvif, &ath12k_fops_link_stats); } +EXPORT_SYMBOL(ath12k_debugfs_op_vif_add); static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file, char __user *user_buf, diff --git a/drivers/net/wireless/ath/ath12k/debugfs_sta.c b/drivers/net/wireless/ath/ath12k/debugfs_sta.c index 5bd2bf4c9dac3..e6665fd521db8 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs_sta.c +++ b/drivers/net/wireless/ath/ath12k/debugfs_sta.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* - * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include @@ -335,3 +335,4 @@ void ath12k_debugfs_link_sta_op_add(struct ieee80211_hw *hw, &fops_reset_rx_stats); } } +EXPORT_SYMBOL(ath12k_debugfs_link_sta_op_add); diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index cb7f491eaba97..9074178c4e8ca 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1459,10 +1459,11 @@ int ath12k_mac_vdev_stop(struct ath12k_link_vif *arvif) return ret; } -static int ath12k_mac_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) +int ath12k_mac_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) { return 0; } +EXPORT_SYMBOL(ath12k_mac_op_config); static int ath12k_mac_setup_bcn_p2p_ie(struct ath12k_link_vif *arvif, struct sk_buff *bcn) @@ -4139,7 +4140,7 @@ static void ath12k_mac_unassign_link_vif(struct ath12k_link_vif *arvif) memset(arvif, 0, sizeof(*arvif)); } -static int +int ath12k_mac_op_change_vif_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 old_links, u16 new_links, @@ -4188,6 +4189,7 @@ ath12k_mac_op_change_vif_links(struct ieee80211_hw *hw, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_change_vif_links); static int ath12k_mac_fils_discovery(struct ath12k_link_vif *arvif, struct ieee80211_bss_conf *info) @@ -4236,9 +4238,9 @@ static int ath12k_mac_fils_discovery(struct ath12k_link_vif *arvif, return ret; } -static void ath12k_mac_op_vif_cfg_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - u64 changed) +void ath12k_mac_op_vif_cfg_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u64 changed) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); unsigned long links = ahvif->links_map; @@ -4306,6 +4308,7 @@ static void ath12k_mac_op_vif_cfg_changed(struct ieee80211_hw *hw, } } } +EXPORT_SYMBOL(ath12k_mac_op_vif_cfg_changed); static void ath12k_mac_vif_setup_ps(struct ath12k_link_vif *arvif) { @@ -4781,10 +4784,10 @@ static void ath12k_ahvif_put_link_cache(struct ath12k_vif *ahvif, u8 link_id) ahvif->cache[link_id] = NULL; } -static void ath12k_mac_op_link_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *info, - u64 changed) +void ath12k_mac_op_link_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, + u64 changed) { struct ath12k *ar; struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); @@ -4814,6 +4817,7 @@ static void ath12k_mac_op_link_info_changed(struct ieee80211_hw *hw, ath12k_mac_bss_info_changed(ar, arvif, info, changed); } +EXPORT_SYMBOL(ath12k_mac_op_link_info_changed); static struct ath12k* ath12k_mac_select_scan_device(struct ieee80211_hw *hw, @@ -5115,10 +5119,10 @@ int ath12k_mac_get_fw_stats(struct ath12k *ar, return 0; } -static int ath12k_mac_op_get_txpower(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - unsigned int link_id, - int *dbm) +int ath12k_mac_op_get_txpower(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + unsigned int link_id, + int *dbm) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_fw_stats_req_params params = {}; @@ -5192,6 +5196,7 @@ static int ath12k_mac_op_get_txpower(struct ieee80211_hw *hw, *dbm); return 0; } +EXPORT_SYMBOL(ath12k_mac_op_get_txpower); static u8 ath12k_mac_find_link_id_by_ar(struct ath12k_vif *ahvif, struct ath12k *ar) @@ -5403,9 +5408,9 @@ static int ath12k_mac_initiate_hw_scan(struct ieee80211_hw *hw, return ret; } -static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_scan_request *hw_req) +int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_scan_request *hw_req) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ieee80211_channel **chan_list, *chan; @@ -5483,9 +5488,10 @@ static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw, kfree(chan_list); return ret; } +EXPORT_SYMBOL(ath12k_mac_op_hw_scan); -static void ath12k_mac_op_cancel_hw_scan(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +void ath12k_mac_op_cancel_hw_scan(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); unsigned long link_id, links_map = ahvif->links_map; @@ -5506,6 +5512,7 @@ static void ath12k_mac_op_cancel_hw_scan(struct ieee80211_hw *hw, cancel_delayed_work_sync(&ar->scan.timeout); } } +EXPORT_SYMBOL(ath12k_mac_op_cancel_hw_scan); static int ath12k_install_key(struct ath12k_link_vif *arvif, struct ieee80211_key_conf *key, @@ -5843,9 +5850,9 @@ static int ath12k_mac_update_key_cache(struct ath12k_vif_cache *cache, return 0; } -static int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) +int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_link_vif *arvif; @@ -5932,6 +5939,7 @@ static int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_set_key); static int ath12k_mac_bitrate_mask_num_vht_rates(struct ath12k *ar, @@ -7268,11 +7276,11 @@ static int ath12k_mac_select_links(struct ath12k_base *ab, return 0; } -static int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - enum ieee80211_sta_state old_state, - enum ieee80211_sta_state new_state) +int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + enum ieee80211_sta_state old_state, + enum ieee80211_sta_state new_state) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta); @@ -7430,10 +7438,11 @@ static int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, return ret; } +EXPORT_SYMBOL(ath12k_mac_op_sta_state); -static int ath12k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +int ath12k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) { struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta); struct ath12k *ar; @@ -7480,11 +7489,12 @@ static int ath12k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, out: return ret; } +EXPORT_SYMBOL(ath12k_mac_op_sta_set_txpwr); -static void ath12k_mac_op_link_sta_rc_update(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_link_sta *link_sta, - u32 changed) +void ath12k_mac_op_link_sta_rc_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_link_sta *link_sta, + u32 changed) { struct ieee80211_sta *sta = link_sta->sta; struct ath12k *ar; @@ -7588,6 +7598,7 @@ static void ath12k_mac_op_link_sta_rc_update(struct ieee80211_hw *hw, rcu_read_unlock(); } +EXPORT_SYMBOL(ath12k_mac_op_link_sta_rc_update); static struct ath12k_link_sta *ath12k_mac_alloc_assign_link_sta(struct ath12k_hw *ah, struct ath12k_sta *ahsta, @@ -7619,10 +7630,10 @@ static struct ath12k_link_sta *ath12k_mac_alloc_assign_link_sta(struct ath12k_hw return arsta; } -static int ath12k_mac_op_change_sta_links(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - u16 old_links, u16 new_links) +int ath12k_mac_op_change_sta_links(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + u16 old_links, u16 new_links) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta); @@ -7683,15 +7694,17 @@ static int ath12k_mac_op_change_sta_links(struct ieee80211_hw *hw, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_change_sta_links); -static bool ath12k_mac_op_can_activate_links(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - u16 active_links) +bool ath12k_mac_op_can_activate_links(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u16 active_links) { /* TODO: Handle recovery case */ return true; } +EXPORT_SYMBOL(ath12k_mac_op_can_activate_links); static int ath12k_conf_tx_uapsd(struct ath12k_link_vif *arvif, u16 ac, bool enable) @@ -7803,10 +7816,10 @@ static int ath12k_mac_conf_tx(struct ath12k_link_vif *arvif, u16 ac, return ret; } -static int ath12k_mac_op_conf_tx(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - unsigned int link_id, u16 ac, - const struct ieee80211_tx_queue_params *params) +int ath12k_mac_op_conf_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + unsigned int link_id, u16 ac, + const struct ieee80211_tx_queue_params *params) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_link_vif *arvif; @@ -7835,6 +7848,7 @@ static int ath12k_mac_op_conf_tx(struct ieee80211_hw *hw, return ret; } +EXPORT_SYMBOL(ath12k_mac_op_conf_tx); static struct ieee80211_sta_ht_cap ath12k_create_ht_cap(struct ath12k *ar, u32 ar_ht_cap, u32 rate_cap_rx_chainmask) @@ -9125,9 +9139,9 @@ static u8 ath12k_mac_get_tx_link(struct ieee80211_sta *sta, struct ieee80211_vif } /* Note: called under rcu_read_lock() */ -static void ath12k_mac_op_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +void ath12k_mac_op_tx(struct ieee80211_hw *hw, + struct ieee80211_tx_control *control, + struct sk_buff *skb) { struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -9307,6 +9321,7 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw, ieee80211_free_txskb(ar->ah->hw, skb); } } +EXPORT_SYMBOL(ath12k_mac_op_tx); void ath12k_mac_drain_tx(struct ath12k *ar) { @@ -9481,7 +9496,7 @@ static void ath12k_drain_tx(struct ath12k_hw *ah) ath12k_mac_drain_tx(ar); } -static int ath12k_mac_op_start(struct ieee80211_hw *hw) +int ath12k_mac_op_start(struct ieee80211_hw *hw) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k *ar; @@ -9534,6 +9549,7 @@ static int ath12k_mac_op_start(struct ieee80211_hw *hw) return ret; } +EXPORT_SYMBOL(ath12k_mac_op_start); int ath12k_mac_rfkill_config(struct ath12k *ar) { @@ -9640,7 +9656,7 @@ static void ath12k_mac_stop(struct ath12k *ar) atomic_set(&ar->num_pending_mgmt_tx, 0); } -static void ath12k_mac_op_stop(struct ieee80211_hw *hw, bool suspend) +void ath12k_mac_op_stop(struct ieee80211_hw *hw, bool suspend) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k *ar; @@ -9659,6 +9675,7 @@ static void ath12k_mac_op_stop(struct ieee80211_hw *hw, bool suspend) mutex_unlock(&ah->hw_mutex); } +EXPORT_SYMBOL(ath12k_mac_op_stop); static u8 ath12k_mac_get_vdev_stats_id(struct ath12k_link_vif *arvif) @@ -9823,8 +9840,8 @@ static void ath12k_mac_update_vif_offload(struct ath12k_link_vif *arvif) } } -static void ath12k_mac_op_update_vif_offload(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +void ath12k_mac_op_update_vif_offload(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_link_vif *arvif; @@ -9848,6 +9865,7 @@ static void ath12k_mac_op_update_vif_offload(struct ieee80211_hw *hw, ath12k_mac_update_vif_offload(&ahvif->deflink); } +EXPORT_SYMBOL(ath12k_mac_op_update_vif_offload); static bool ath12k_mac_vif_ap_active_any(struct ath12k_base *ab) { @@ -10403,8 +10421,8 @@ static struct ath12k *ath12k_mac_assign_vif_to_vdev(struct ieee80211_hw *hw, return arvif->ar; } -static int ath12k_mac_op_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +int ath12k_mac_op_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); @@ -10451,6 +10469,7 @@ static int ath12k_mac_op_add_interface(struct ieee80211_hw *hw, */ return 0; } +EXPORT_SYMBOL(ath12k_mac_op_add_interface); static void ath12k_mac_vif_unref(struct ath12k_dp *dp, struct ieee80211_vif *vif) { @@ -10539,8 +10558,8 @@ static int ath12k_mac_vdev_delete(struct ath12k *ar, struct ath12k_link_vif *arv return ret; } -static void ath12k_mac_op_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +void ath12k_mac_op_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_link_vif *arvif; @@ -10587,6 +10606,7 @@ static void ath12k_mac_op_remove_interface(struct ieee80211_hw *hw, ath12k_mac_unassign_link_vif(arvif); } } +EXPORT_SYMBOL(ath12k_mac_op_remove_interface); /* FIXME: Has to be verified. */ #define SUPPORTED_FILTERS \ @@ -10598,10 +10618,10 @@ static void ath12k_mac_op_remove_interface(struct ieee80211_hw *hw, FIF_PROBE_REQ | \ FIF_FCSFAIL) -static void ath12k_mac_op_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, - u64 multicast) +void ath12k_mac_op_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, + u64 multicast) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k *ar; @@ -10613,9 +10633,10 @@ static void ath12k_mac_op_configure_filter(struct ieee80211_hw *hw, *total_flags &= SUPPORTED_FILTERS; ar->filter_flags = *total_flags; } +EXPORT_SYMBOL(ath12k_mac_op_configure_filter); -static int ath12k_mac_op_get_antenna(struct ieee80211_hw *hw, int radio_idx, - u32 *tx_ant, u32 *rx_ant) +int ath12k_mac_op_get_antenna(struct ieee80211_hw *hw, int radio_idx, + u32 *tx_ant, u32 *rx_ant) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); int antennas_rx = 0, antennas_tx = 0; @@ -10634,9 +10655,10 @@ static int ath12k_mac_op_get_antenna(struct ieee80211_hw *hw, int radio_idx, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_get_antenna); -static int ath12k_mac_op_set_antenna(struct ieee80211_hw *hw, int radio_idx, - u32 tx_ant, u32 rx_ant) +int ath12k_mac_op_set_antenna(struct ieee80211_hw *hw, int radio_idx, + u32 tx_ant, u32 rx_ant) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k *ar; @@ -10653,6 +10675,7 @@ static int ath12k_mac_op_set_antenna(struct ieee80211_hw *hw, int radio_idx, return ret; } +EXPORT_SYMBOL(ath12k_mac_op_set_antenna); static int ath12k_mac_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -10694,9 +10717,9 @@ static int ath12k_mac_ampdu_action(struct ieee80211_hw *hw, return ret; } -static int ath12k_mac_op_ampdu_action(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_ampdu_params *params) +int ath12k_mac_op_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_ampdu_params *params) { struct ieee80211_sta *sta = params->sta; struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta); @@ -10717,9 +10740,10 @@ static int ath12k_mac_op_ampdu_action(struct ieee80211_hw *hw, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_ampdu_action); -static int ath12k_mac_op_add_chanctx(struct ieee80211_hw *hw, - struct ieee80211_chanctx_conf *ctx) +int ath12k_mac_op_add_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *ctx) { struct ath12k *ar; struct ath12k_base *ab; @@ -10746,9 +10770,10 @@ static int ath12k_mac_op_add_chanctx(struct ieee80211_hw *hw, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_add_chanctx); -static void ath12k_mac_op_remove_chanctx(struct ieee80211_hw *hw, - struct ieee80211_chanctx_conf *ctx) +void ath12k_mac_op_remove_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *ctx) { struct ath12k *ar; struct ath12k_base *ab; @@ -10773,6 +10798,7 @@ static void ath12k_mac_op_remove_chanctx(struct ieee80211_hw *hw, spin_unlock_bh(&ar->data_lock); ar->chan_tx_pwr = ATH12K_PDEV_TX_POWER_INVALID; } +EXPORT_SYMBOL(ath12k_mac_op_remove_chanctx); static enum wmi_phy_mode ath12k_mac_check_down_grade_phy_mode(struct ath12k *ar, @@ -11331,9 +11357,9 @@ ath12k_mac_update_active_vif_chan(struct ath12k *ar, kfree(arg.vifs); } -static void ath12k_mac_op_change_chanctx(struct ieee80211_hw *hw, - struct ieee80211_chanctx_conf *ctx, - u32 changed) +void ath12k_mac_op_change_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *ctx, + u32 changed) { struct ath12k *ar; struct ath12k_base *ab; @@ -11363,6 +11389,7 @@ static void ath12k_mac_op_change_chanctx(struct ieee80211_hw *hw, /* TODO: Recalc radar detection */ } +EXPORT_SYMBOL(ath12k_mac_op_change_chanctx); static int ath12k_start_vdev_delay(struct ath12k *ar, struct ath12k_link_vif *arvif) @@ -11804,7 +11831,7 @@ static void ath12k_mac_parse_tx_pwr_env(struct ath12k *ar, } } -static int +int ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *link_conf, @@ -11889,8 +11916,9 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, out: return ret; } +EXPORT_SYMBOL(ath12k_mac_op_assign_vif_chanctx); -static void +void ath12k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *link_conf, @@ -11957,8 +11985,9 @@ ath12k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, ar->scan.arvif = NULL; } } +EXPORT_SYMBOL(ath12k_mac_op_unassign_vif_chanctx); -static int +int ath12k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif_chanctx_switch *vifs, int n_vifs, @@ -11983,6 +12012,7 @@ ath12k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_switch_vif_chanctx); static int ath12k_set_vdev_param_to_all_vifs(struct ath12k *ar, int param, u32 value) @@ -12011,8 +12041,8 @@ ath12k_set_vdev_param_to_all_vifs(struct ath12k *ar, int param, u32 value) /* mac80211 stores device specific RTS/Fragmentation threshold value, * this is set interface specific to firmware from ath12k driver */ -static int ath12k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, - int radio_idx, u32 value) +int ath12k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, + int radio_idx, u32 value) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct wiphy *wiphy = hw->wiphy; @@ -12071,9 +12101,10 @@ static int ath12k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, return ret; } +EXPORT_SYMBOL(ath12k_mac_op_set_rts_threshold); -static int ath12k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, - int radio_idx, u32 value) +int ath12k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, + int radio_idx, u32 value) { /* Even though there's a WMI vdev param for fragmentation threshold no * known firmware actually implements it. Moreover it is not possible to @@ -12090,6 +12121,7 @@ static int ath12k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, return -EOPNOTSUPP; } +EXPORT_SYMBOL(ath12k_mac_op_set_frag_threshold); static int ath12k_mac_flush(struct ath12k *ar) { @@ -12127,8 +12159,8 @@ int ath12k_mac_wait_tx_complete(struct ath12k *ar) return ath12k_mac_flush(ar); } -static void ath12k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - u32 queues, bool drop) +void ath12k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u32 queues, bool drop) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k_link_vif *arvif; @@ -12163,6 +12195,7 @@ static void ath12k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *v ath12k_mac_flush(arvif->ar); } } +EXPORT_SYMBOL(ath12k_mac_op_flush); static int ath12k_mac_bitrate_mask_num_ht_rates(struct ath12k *ar, @@ -12783,7 +12816,7 @@ ath12k_mac_validate_fixed_rate_settings(struct ath12k *ar, enum nl80211_band ban return ret; } -static int +int ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif, const struct cfg80211_bitrate_mask *mask) @@ -12962,8 +12995,9 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, out: return ret; } +EXPORT_SYMBOL(ath12k_mac_op_set_bitrate_mask); -static void +void ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw, enum ieee80211_reconfig_type reconfig_type) { @@ -13044,6 +13078,7 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw, } } } +EXPORT_SYMBOL(ath12k_mac_op_reconfig_complete); static void ath12k_mac_update_bss_chan_survey(struct ath12k *ar, @@ -13077,8 +13112,8 @@ ath12k_mac_update_bss_chan_survey(struct ath12k *ar, ath12k_warn(ar->ab, "bss channel survey timed out\n"); } -static int ath12k_mac_op_get_survey(struct ieee80211_hw *hw, int idx, - struct survey_info *survey) +int ath12k_mac_op_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey) { struct ath12k *ar; struct ieee80211_supported_band *sband; @@ -13132,32 +13167,12 @@ static int ath12k_mac_op_get_survey(struct ieee80211_hw *hw, int idx, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_get_survey); -static void ath12k_mac_put_chain_rssi(struct station_info *sinfo, - struct ath12k_link_sta *arsta) -{ - s8 rssi; - int i; - - for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) { - sinfo->chains &= ~BIT(i); - rssi = arsta->chain_signal[i]; - - if (rssi != ATH12K_DEFAULT_NOISE_FLOOR && - rssi != ATH12K_INVALID_RSSI_FULL && - rssi != ATH12K_INVALID_RSSI_EMPTY && - rssi != 0) { - sinfo->chain_signal[i] = rssi; - sinfo->chains |= BIT(i); - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL); - } - } -} - -static void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct station_info *sinfo) +void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct station_info *sinfo) { struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta); struct ath12k_fw_stats_req_params params = {}; @@ -13242,11 +13257,12 @@ static void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); } +EXPORT_SYMBOL(ath12k_mac_op_sta_statistics); -static void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_link_sta *link_sta, - struct link_station_info *link_sinfo) +void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_link_sta *link_sta, + struct link_station_info *link_sinfo) { struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(link_sta->sta); struct ath12k_fw_stats_req_params params = {}; @@ -13326,9 +13342,10 @@ static void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); } +EXPORT_SYMBOL(ath12k_mac_op_link_sta_statistics); -static int ath12k_mac_op_cancel_remain_on_channel(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +int ath12k_mac_op_cancel_remain_on_channel(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k *ar; @@ -13348,12 +13365,13 @@ static int ath12k_mac_op_cancel_remain_on_channel(struct ieee80211_hw *hw, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_cancel_remain_on_channel); -static int ath12k_mac_op_remain_on_channel(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_channel *chan, - int duration, - enum ieee80211_roc_type type) +int ath12k_mac_op_remain_on_channel(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_channel *chan, + int duration, + enum ieee80211_roc_type type) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_hw *ah = ath12k_hw_to_ah(hw); @@ -13488,10 +13506,11 @@ static int ath12k_mac_op_remain_on_channel(struct ieee80211_hw *hw, return 0; } +EXPORT_SYMBOL(ath12k_mac_op_remain_on_channel); -static void ath12k_mac_op_set_rekey_data(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct cfg80211_gtk_rekey_data *data) +void ath12k_mac_op_set_rekey_data(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct cfg80211_gtk_rekey_data *data) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_rekey_data *rekey_data; @@ -13524,63 +13543,7 @@ static void ath12k_mac_op_set_rekey_data(struct ieee80211_hw *hw, ath12k_dbg_dump(ar->ab, ATH12K_DBG_MAC, "replay ctr", NULL, &rekey_data->replay_ctr, sizeof(rekey_data->replay_ctr)); } - -static const struct ieee80211_ops ath12k_ops = { - .tx = ath12k_mac_op_tx, - .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = ath12k_mac_op_start, - .stop = ath12k_mac_op_stop, - .reconfig_complete = ath12k_mac_op_reconfig_complete, - .add_interface = ath12k_mac_op_add_interface, - .remove_interface = ath12k_mac_op_remove_interface, - .update_vif_offload = ath12k_mac_op_update_vif_offload, - .config = ath12k_mac_op_config, - .link_info_changed = ath12k_mac_op_link_info_changed, - .vif_cfg_changed = ath12k_mac_op_vif_cfg_changed, - .change_vif_links = ath12k_mac_op_change_vif_links, - .configure_filter = ath12k_mac_op_configure_filter, - .hw_scan = ath12k_mac_op_hw_scan, - .cancel_hw_scan = ath12k_mac_op_cancel_hw_scan, - .set_key = ath12k_mac_op_set_key, - .set_rekey_data = ath12k_mac_op_set_rekey_data, - .sta_state = ath12k_mac_op_sta_state, - .sta_set_txpwr = ath12k_mac_op_sta_set_txpwr, - .link_sta_rc_update = ath12k_mac_op_link_sta_rc_update, - .conf_tx = ath12k_mac_op_conf_tx, - .set_antenna = ath12k_mac_op_set_antenna, - .get_antenna = ath12k_mac_op_get_antenna, - .ampdu_action = ath12k_mac_op_ampdu_action, - .add_chanctx = ath12k_mac_op_add_chanctx, - .remove_chanctx = ath12k_mac_op_remove_chanctx, - .change_chanctx = ath12k_mac_op_change_chanctx, - .assign_vif_chanctx = ath12k_mac_op_assign_vif_chanctx, - .unassign_vif_chanctx = ath12k_mac_op_unassign_vif_chanctx, - .switch_vif_chanctx = ath12k_mac_op_switch_vif_chanctx, - .get_txpower = ath12k_mac_op_get_txpower, - .set_rts_threshold = ath12k_mac_op_set_rts_threshold, - .set_frag_threshold = ath12k_mac_op_set_frag_threshold, - .set_bitrate_mask = ath12k_mac_op_set_bitrate_mask, - .get_survey = ath12k_mac_op_get_survey, - .flush = ath12k_mac_op_flush, - .sta_statistics = ath12k_mac_op_sta_statistics, - .link_sta_statistics = ath12k_mac_op_link_sta_statistics, - .remain_on_channel = ath12k_mac_op_remain_on_channel, - .cancel_remain_on_channel = ath12k_mac_op_cancel_remain_on_channel, - .change_sta_links = ath12k_mac_op_change_sta_links, - .can_activate_links = ath12k_mac_op_can_activate_links, -#ifdef CONFIG_PM - .suspend = ath12k_wow_op_suspend, - .resume = ath12k_wow_op_resume, - .set_wakeup = ath12k_wow_op_set_wakeup, -#endif -#ifdef CONFIG_ATH12K_DEBUGFS - .vif_add_debugfs = ath12k_debugfs_op_vif_add, -#endif - CFG80211_TESTMODE_CMD(ath12k_tm_cmd) -#ifdef CONFIG_ATH12K_DEBUGFS - .link_sta_add_debugfs = ath12k_debugfs_link_sta_op_add, -#endif -}; +EXPORT_SYMBOL(ath12k_mac_op_set_rekey_data); void ath12k_mac_update_freq_range(struct ath12k *ar, u32 freq_low, u32 freq_high) @@ -14799,7 +14762,7 @@ static struct ath12k_hw *ath12k_mac_hw_allocate(struct ath12k_hw_group *ag, u8 pdev_idx; hw = ieee80211_alloc_hw(struct_size(ah, radio, num_pdev_map), - &ath12k_ops); + pdev_map->ab->ath12k_ops); if (!hw) return NULL; diff --git a/drivers/net/wireless/ath/ath12k/mac.h b/drivers/net/wireless/ath/ath12k/mac.h index 1f689e367c8a1..2f4a174b88942 100644 --- a/drivers/net/wireless/ath/ath12k/mac.h +++ b/drivers/net/wireless/ath/ath12k/mac.h @@ -206,4 +206,130 @@ void ath12k_mac_update_freq_range(struct ath12k *ar, void ath12k_mac_fill_reg_tpc_info(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ieee80211_chanctx_conf *ctx); +void ath12k_mac_op_tx(struct ieee80211_hw *hw, + struct ieee80211_tx_control *control, + struct sk_buff *skb); +int ath12k_mac_op_start(struct ieee80211_hw *hw); +void ath12k_mac_op_stop(struct ieee80211_hw *hw, bool suspend); +void +ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw, + enum ieee80211_reconfig_type reconfig_type); +int ath12k_mac_op_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +void ath12k_mac_op_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +void ath12k_mac_op_update_vif_offload(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +int ath12k_mac_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed); +void ath12k_mac_op_link_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, + u64 changed); +void ath12k_mac_op_vif_cfg_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u64 changed); +int +ath12k_mac_op_change_vif_links + (struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u16 old_links, u16 new_links, + struct ieee80211_bss_conf *ol[IEEE80211_MLD_MAX_NUM_LINKS]); +void ath12k_mac_op_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, + u64 multicast); +int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_scan_request *hw_req); +void ath12k_mac_op_cancel_hw_scan(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key); +void ath12k_mac_op_set_rekey_data(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct cfg80211_gtk_rekey_data *data); +int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + enum ieee80211_sta_state old_state, + enum ieee80211_sta_state new_state); +int ath12k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +void ath12k_mac_op_link_sta_rc_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_link_sta *link_sta, + u32 changed); +int ath12k_mac_op_conf_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + unsigned int link_id, u16 ac, + const struct ieee80211_tx_queue_params *params); +int ath12k_mac_op_set_antenna(struct ieee80211_hw *hw, int radio_idx, + u32 tx_ant, u32 rx_ant); +int ath12k_mac_op_get_antenna(struct ieee80211_hw *hw, int radio_idx, + u32 *tx_ant, u32 *rx_ant); +int ath12k_mac_op_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_ampdu_params *params); +int ath12k_mac_op_add_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *ctx); +void ath12k_mac_op_remove_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *ctx); +void ath12k_mac_op_change_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *ctx, + u32 changed); +int +ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_chanctx_conf *ctx); +void +ath12k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_chanctx_conf *ctx); +int +ath12k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif_chanctx_switch *vifs, + int n_vifs, + enum ieee80211_chanctx_switch_mode mode); +int ath12k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, + int radio_idx, u32 value); +int ath12k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, + int radio_idx, u32 value); +int +ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const struct cfg80211_bitrate_mask *mask); +int ath12k_mac_op_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey); +void ath12k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u32 queues, bool drop); +void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct station_info *sinfo); +void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_link_sta *link_sta, + struct link_station_info *link_sinfo); +int ath12k_mac_op_remain_on_channel(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_channel *chan, + int duration, + enum ieee80211_roc_type type); +int ath12k_mac_op_cancel_remain_on_channel(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +int ath12k_mac_op_change_sta_links(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + u16 old_links, u16 new_links); +bool ath12k_mac_op_can_activate_links(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u16 active_links); +int ath12k_mac_op_get_txpower(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + unsigned int link_id, + int *dbm); #endif diff --git a/drivers/net/wireless/ath/ath12k/testmode.c b/drivers/net/wireless/ath/ath12k/testmode.c index fb6af7ccf71f4..05a65970c8624 100644 --- a/drivers/net/wireless/ath/ath12k/testmode.c +++ b/drivers/net/wireless/ath/ath12k/testmode.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 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. */ #include "testmode.h" @@ -393,3 +393,4 @@ int ath12k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, return -EOPNOTSUPP; } } +EXPORT_SYMBOL(ath12k_tm_cmd); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 909f7311619cd..1acf6ffaea08f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -19,6 +19,10 @@ #include "dp_rx.h" #include "../peer.h" #include "wmi.h" +#include "../wow.h" +#include "../debugfs.h" +#include "../debugfs_sta.h" +#include "../testmode.h" static const guid_t wcn7850_uuid = GUID_INIT(0xf634f534, 0x6147, 0x11ec, 0x90, 0xd6, 0x02, 0x42, @@ -1042,6 +1046,63 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { }, }; +static const struct ieee80211_ops ath12k_ops_wifi7 = { + .tx = ath12k_mac_op_tx, + .wake_tx_queue = ieee80211_handle_wake_tx_queue, + .start = ath12k_mac_op_start, + .stop = ath12k_mac_op_stop, + .reconfig_complete = ath12k_mac_op_reconfig_complete, + .add_interface = ath12k_mac_op_add_interface, + .remove_interface = ath12k_mac_op_remove_interface, + .update_vif_offload = ath12k_mac_op_update_vif_offload, + .config = ath12k_mac_op_config, + .link_info_changed = ath12k_mac_op_link_info_changed, + .vif_cfg_changed = ath12k_mac_op_vif_cfg_changed, + .change_vif_links = ath12k_mac_op_change_vif_links, + .configure_filter = ath12k_mac_op_configure_filter, + .hw_scan = ath12k_mac_op_hw_scan, + .cancel_hw_scan = ath12k_mac_op_cancel_hw_scan, + .set_key = ath12k_mac_op_set_key, + .set_rekey_data = ath12k_mac_op_set_rekey_data, + .sta_state = ath12k_mac_op_sta_state, + .sta_set_txpwr = ath12k_mac_op_sta_set_txpwr, + .link_sta_rc_update = ath12k_mac_op_link_sta_rc_update, + .conf_tx = ath12k_mac_op_conf_tx, + .set_antenna = ath12k_mac_op_set_antenna, + .get_antenna = ath12k_mac_op_get_antenna, + .ampdu_action = ath12k_mac_op_ampdu_action, + .add_chanctx = ath12k_mac_op_add_chanctx, + .remove_chanctx = ath12k_mac_op_remove_chanctx, + .change_chanctx = ath12k_mac_op_change_chanctx, + .assign_vif_chanctx = ath12k_mac_op_assign_vif_chanctx, + .unassign_vif_chanctx = ath12k_mac_op_unassign_vif_chanctx, + .switch_vif_chanctx = ath12k_mac_op_switch_vif_chanctx, + .get_txpower = ath12k_mac_op_get_txpower, + .set_rts_threshold = ath12k_mac_op_set_rts_threshold, + .set_frag_threshold = ath12k_mac_op_set_frag_threshold, + .set_bitrate_mask = ath12k_mac_op_set_bitrate_mask, + .get_survey = ath12k_mac_op_get_survey, + .flush = ath12k_mac_op_flush, + .sta_statistics = ath12k_mac_op_sta_statistics, + .link_sta_statistics = ath12k_mac_op_link_sta_statistics, + .remain_on_channel = ath12k_mac_op_remain_on_channel, + .cancel_remain_on_channel = ath12k_mac_op_cancel_remain_on_channel, + .change_sta_links = ath12k_mac_op_change_sta_links, + .can_activate_links = ath12k_mac_op_can_activate_links, +#ifdef CONFIG_PM + .suspend = ath12k_wow_op_suspend, + .resume = ath12k_wow_op_resume, + .set_wakeup = ath12k_wow_op_set_wakeup, +#endif +#ifdef CONFIG_ATH12K_DEBUGFS + .vif_add_debugfs = ath12k_debugfs_op_vif_add, +#endif + CFG80211_TESTMODE_CMD(ath12k_tm_cmd) +#ifdef CONFIG_ATH12K_DEBUGFS + .link_sta_add_debugfs = ath12k_debugfs_link_sta_op_add, +#endif +}; + int ath12k_wifi7_hw_init(struct ath12k_base *ab) { const struct ath12k_hw_params *hw_params = NULL; @@ -1061,6 +1122,7 @@ int ath12k_wifi7_hw_init(struct ath12k_base *ab) } ab->hw_params = hw_params; + ab->ath12k_ops = &ath12k_ops_wifi7; ath12k_info(ab, "Wi-Fi 7 Hardware name: %s\n", ab->hw_params->name); diff --git a/drivers/net/wireless/ath/ath12k/wow.c b/drivers/net/wireless/ath/ath12k/wow.c index e8481626f1940..f56ec44a16361 100644 --- a/drivers/net/wireless/ath/ath12k/wow.c +++ b/drivers/net/wireless/ath/ath12k/wow.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include @@ -919,6 +919,7 @@ int ath12k_wow_op_suspend(struct ieee80211_hw *hw, exit: return ret ? 1 : 0; } +EXPORT_SYMBOL(ath12k_wow_op_suspend); void ath12k_wow_op_set_wakeup(struct ieee80211_hw *hw, bool enabled) { @@ -929,6 +930,7 @@ void ath12k_wow_op_set_wakeup(struct ieee80211_hw *hw, bool enabled) device_set_wakeup_enable(ar->ab->dev, enabled); } +EXPORT_SYMBOL(ath12k_wow_op_set_wakeup); int ath12k_wow_op_resume(struct ieee80211_hw *hw) { @@ -1001,6 +1003,7 @@ int ath12k_wow_op_resume(struct ieee80211_hw *hw) return ret; } +EXPORT_SYMBOL(ath12k_wow_op_resume); int ath12k_wow_init(struct ath12k *ar) { From 328eb22fecc8674b0d124872c63db8927626eddb Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Tue, 30 Sep 2025 18:40:04 +0530 Subject: [PATCH 046/140] wifi: ath12k: Add framework for hardware specific DP interrupt handler Currently, the DP service SRNG handler is invoked directly from the NAPI poll handler, which prevents using different handlers for different architectures. To fix this, introduce a DP architecture-ops table to invoke architecture specific handler from NAPI poll handler. Future patches will leverage this framework to invoke architecture-specific handlers from common code. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250930131005.2884253-6-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ahb.c | 3 ++- drivers/net/wireless/ath/ath12k/dp.h | 18 ++++++++++++++++++ drivers/net/wireless/ath/ath12k/pci.c | 3 ++- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 13 ++++++++++--- drivers/net/wireless/ath/ath12k/wifi7/dp.h | 2 -- 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index 5c95bdd36d6aa..b743c05c5fb04 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -525,9 +525,10 @@ static int ath12k_ahb_ext_grp_napi_poll(struct napi_struct *napi, int budget) struct ath12k_ext_irq_grp, napi); struct ath12k_base *ab = irq_grp->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int work_done; - work_done = ath12k_wifi7_dp_service_srng(ab, irq_grp, budget); + work_done = ath12k_dp_service_srng(dp, irq_grp, budget); if (work_done < budget) { napi_complete_done(napi, work_done); ath12k_ahb_ext_grp_enable(irq_grp); diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 84f40a6612d31..6e0e247d93768 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -367,6 +367,15 @@ struct ath12k_link_stats { u32 tx_desc_type[HAL_TCL_DESC_TYPE_MAX]; }; +/* DP arch ops to communicate from common module + * to arch specific module + */ +struct ath12k_dp_arch_ops { + int (*service_srng)(struct ath12k_dp *dp, + struct ath12k_ext_irq_grp *irq_grp, + int budget); +}; + struct ath12k_dp { struct ath12k_base *ab; u32 mon_dest_ring_stuck_cnt; @@ -434,6 +443,8 @@ struct ath12k_dp { struct ath12k_hw_group *ag; u8 device_id; + + struct ath12k_dp_arch_ops *ops; }; static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) @@ -448,6 +459,13 @@ ath12k_dp_hw_grp_to_dp(struct ath12k_dp_hw_group *dp_hw_grp, u8 device_id) return dp_hw_grp->dp[device_id]; } +static inline int +ath12k_dp_service_srng(struct ath12k_dp *dp, struct ath12k_ext_irq_grp *irq_grp, + int budget) +{ + return dp->ops->service_srng(dp, irq_grp, budget); +} + void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif); void ath12k_dp_cc_config(struct ath12k_base *ab); void ath12k_dp_partner_cc_init(struct ath12k_base *ab); diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 12a8c2f55a4cf..529949b3a791f 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -497,10 +497,11 @@ static int ath12k_pci_ext_grp_napi_poll(struct napi_struct *napi, int budget) struct ath12k_ext_irq_grp, napi); struct ath12k_base *ab = irq_grp->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int work_done; int i; - work_done = ath12k_wifi7_dp_service_srng(ab, irq_grp, budget); + work_done = ath12k_dp_service_srng(dp, irq_grp, budget); if (work_done < budget) { napi_complete_done(napi, work_done); for (i = 0; i < irq_grp->num_irq; i++) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index adc3480b282b3..4465a9e93bf85 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -13,10 +13,11 @@ #include "dp.h" #include "dp_tx.h" -int ath12k_wifi7_dp_service_srng(struct ath12k_base *ab, - struct ath12k_ext_irq_grp *irq_grp, - int budget) +static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, + struct ath12k_ext_irq_grp *irq_grp, + int budget) { + struct ath12k_base *ab = dp->ab; struct napi_struct *napi = &irq_grp->napi; int grp_id = irq_grp->grp_id; int work_done = 0; @@ -134,6 +135,10 @@ int ath12k_wifi7_dp_service_srng(struct ath12k_base *ab, return tot_work_done; } +static struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = { + .service_srng = ath12k_wifi7_dp_service_srng, +}; + /* TODO: remove export once this file is built with wifi7 ko */ struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab) { @@ -148,6 +153,8 @@ struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab) dp->dev = ab->dev; dp->hw_params = ab->hw_params; + dp->ops = &ath12k_wifi7_dp_arch_ops; + return dp; } EXPORT_SYMBOL(ath12k_wifi7_dp_device_alloc); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.h b/drivers/net/wireless/ath/ath12k/wifi7/dp.h index 2300fda657865..72fdfb368c994 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.h @@ -13,8 +13,6 @@ struct ath12k_base; struct ath12k_dp; -int ath12k_wifi7_dp_service_srng(struct ath12k_base *ab, - struct ath12k_ext_irq_grp *irq_grp, int budget); struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab); void ath12k_wifi7_dp_device_free(struct ath12k_dp *dp); From 57235cc2be37381fc5644ac88840c0db58181e13 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Tue, 30 Sep 2025 18:40:05 +0530 Subject: [PATCH 047/140] wifi: ath12k: Refactor ath12k_vif structure Move the Data Path (DP)-specific fields from ath12k_vif into a new structure ath12k_dp_vif, embedded within ath12k_vif. This new structure contains an array of per-link DP fields represented by ath12k_dp_link_vif. Since dp_link_vif is small and frequently accessed from ahvif during Tx, it is stored as an array of structs rather than an array of pointers to avoid additional indirections and improve cache efficiency. However, this design comes with a trade-off: because the array is not pointer-based, it increases memory usage. Per packet data path makes use of ath12k_dp_vif and ath12k_dp_link_vif. Add pdev_idx and lmac_id in ath12k_dp_link_vif to avoid accessing ar in dp tx. Diagrammatic view of the new structure is below: +--------------------------------+ | struct ath12k_vif | | | | +--------------------------+ | | | struct ath12k_dp_vif | | | | | | | | +--------------------+ | | | | | ath12k_dp_link_vif | | | | | +--------------------+ | | | | | | | | +--------------------+ | | | | | ath12k_dp_link_vif | | | | | +--------------------+ | | | | | | | | +--------------------+ | | | | | ath12k_dp_link_vif | | | | | +--------------------+ | | | | | | | +--------------------------+ | | | +--------------------------------+ Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20250930131005.2884253-7-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/cmn_defs.h | 6 ++ drivers/net/wireless/ath/ath12k/core.h | 13 +--- drivers/net/wireless/ath/ath12k/dp.c | 59 ++++++++++++------- drivers/net/wireless/ath/ath12k/dp_cmn.h | 26 ++++++++ drivers/net/wireless/ath/ath12k/mac.c | 29 ++++++--- drivers/net/wireless/ath/ath12k/mac.h | 3 - drivers/net/wireless/ath/ath12k/peer.c | 10 +++- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 25 ++++---- 8 files changed, 115 insertions(+), 56 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/cmn_defs.h b/drivers/net/wireless/ath/ath12k/cmn_defs.h index e1f1f50341ff0..1a531357271bc 100644 --- a/drivers/net/wireless/ath/ath12k/cmn_defs.h +++ b/drivers/net/wireless/ath/ath12k/cmn_defs.h @@ -6,8 +6,14 @@ #ifndef ATH12K_CMN_DEFS_H #define ATH12K_CMN_DEFS_H +#include + #define MAX_RADIOS 2 #define ATH12K_MAX_DEVICES 3 #define ATH12K_GROUP_MAX_RADIO (ATH12K_MAX_DEVICES * MAX_RADIOS) +#define ATH12K_SCAN_MAX_LINKS ATH12K_GROUP_MAX_RADIO +/* Define 1 scan link for each radio for parallel scan purposes */ +#define ATH12K_NUM_MAX_LINKS (IEEE80211_MLD_MAX_NUM_LINKS + ATH12K_SCAN_MAX_LINKS) + #endif diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 1ec6f57bbe699..b424ff8428861 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -35,6 +35,7 @@ #include "debugfs_htt_stats.h" #include "coredump.h" #include "cmn_defs.h" +#include "dp_cmn.h" #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) @@ -309,16 +310,9 @@ struct ath12k_link_vif { u32 vdev_id; u32 beacon_interval; u32 dtim_period; - u16 ast_hash; - u16 ast_idx; - u16 tcl_metadata; - u8 hal_addr_search_flags; - u8 search_type; struct ath12k *ar; - int bank_id; - u8 vdev_id_check_en; bool beacon_prot; struct wmi_wmm_params_all_arg wmm_params; @@ -359,6 +353,8 @@ struct ath12k_link_vif { }; struct ath12k_vif { + struct ath12k_dp_vif dp_vif; + enum wmi_vdev_type vdev_type; enum wmi_vdev_subtype vdev_subtype; struct ieee80211_vif *vif; @@ -382,10 +378,7 @@ struct ath12k_vif { } u; u32 aid; - u32 key_cipher; - u8 tx_encap_type; bool ps; - atomic_t mcbc_gsn; struct ath12k_link_vif deflink; struct ath12k_link_vif __rcu *link[ATH12K_NUM_MAX_LINKS]; diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 1e14f3a70904c..36e0dfd89bbde 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -338,18 +338,23 @@ u32 ath12k_dp_tx_get_vdev_bank_config(struct ath12k_base *ab, struct ath12k_link_vif *arvif) { u32 bank_config = 0; + u8 link_id = arvif->link_id; struct ath12k_vif *ahvif = arvif->ahvif; + struct ath12k_dp_vif *dp_vif = &ahvif->dp_vif; + struct ath12k_dp_link_vif *dp_link_vif; + + dp_link_vif = ath12k_dp_vif_to_dp_link_vif(dp_vif, link_id); /* Only valid for raw frames with HW crypto enabled. * With SW crypto, mac80211 sets key per packet */ - if (ahvif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW && + if (dp_vif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW && test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags)) bank_config |= - u32_encode_bits(ath12k_dp_tx_get_encrypt_type(ahvif->key_cipher), + u32_encode_bits(ath12k_dp_tx_get_encrypt_type(dp_vif->key_cipher), HAL_TX_BANK_CONFIG_ENCRYPT_TYPE); - bank_config |= u32_encode_bits(ahvif->tx_encap_type, + bank_config |= u32_encode_bits(dp_vif->tx_encap_type, HAL_TX_BANK_CONFIG_ENCAP_TYPE); bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_SRC_BUFFER_SWAP) | u32_encode_bits(0, HAL_TX_BANK_CONFIG_LINK_META_SWAP) | @@ -361,15 +366,16 @@ u32 ath12k_dp_tx_get_vdev_bank_config(struct ath12k_base *ab, else bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_INDEX_LOOKUP_EN); - bank_config |= u32_encode_bits(arvif->hal_addr_search_flags & HAL_TX_ADDRX_EN, - HAL_TX_BANK_CONFIG_ADDRX_EN) | - u32_encode_bits(!!(arvif->hal_addr_search_flags & + bank_config |= u32_encode_bits(dp_link_vif->hal_addr_search_flags & + HAL_TX_ADDRX_EN, + HAL_TX_BANK_CONFIG_ADDRX_EN) | + u32_encode_bits(!!(dp_link_vif->hal_addr_search_flags & HAL_TX_ADDRY_EN), HAL_TX_BANK_CONFIG_ADDRY_EN); bank_config |= u32_encode_bits(ieee80211_vif_is_mesh(ahvif->vif) ? 3 : 0, HAL_TX_BANK_CONFIG_MESH_EN) | - u32_encode_bits(arvif->vdev_id_check_en, + u32_encode_bits(dp_link_vif->vdev_id_check_en, HAL_TX_BANK_CONFIG_VDEV_ID_CHECK_EN); bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_DSCP_TIP_MAP_ID); @@ -938,15 +944,21 @@ int ath12k_dp_pdev_alloc(struct ath12k_base *ab) static void ath12k_dp_update_vdev_search(struct ath12k_link_vif *arvif) { + u8 link_id = arvif->link_id; + struct ath12k_vif *ahvif = arvif->ahvif; + struct ath12k_dp_link_vif *dp_link_vif; + + dp_link_vif = ath12k_dp_vif_to_dp_link_vif(&ahvif->dp_vif, link_id); + switch (arvif->ahvif->vdev_type) { case WMI_VDEV_TYPE_STA: - arvif->hal_addr_search_flags = HAL_TX_ADDRY_EN; - arvif->search_type = HAL_TX_ADDR_SEARCH_INDEX; + dp_link_vif->hal_addr_search_flags = HAL_TX_ADDRY_EN; + dp_link_vif->search_type = HAL_TX_ADDR_SEARCH_DEFAULT; break; case WMI_VDEV_TYPE_AP: case WMI_VDEV_TYPE_IBSS: - arvif->hal_addr_search_flags = HAL_TX_ADDRX_EN; - arvif->search_type = HAL_TX_ADDR_SEARCH_DEFAULT; + dp_link_vif->hal_addr_search_flags = HAL_TX_ADDRX_EN; + dp_link_vif->search_type = HAL_TX_ADDR_SEARCH_DEFAULT; break; case WMI_VDEV_TYPE_MONITOR: default: @@ -957,22 +969,29 @@ static void ath12k_dp_update_vdev_search(struct ath12k_link_vif *arvif) void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif) { struct ath12k_base *ab = ar->ab; + struct ath12k_vif *ahvif = arvif->ahvif; + u8 link_id = arvif->link_id; + int bank_id; + struct ath12k_dp_link_vif *dp_link_vif; + + dp_link_vif = ath12k_dp_vif_to_dp_link_vif(&ahvif->dp_vif, link_id); - arvif->tcl_metadata |= u32_encode_bits(1, HTT_TCL_META_DATA_TYPE) | - u32_encode_bits(arvif->vdev_id, - HTT_TCL_META_DATA_VDEV_ID) | - u32_encode_bits(ar->pdev->pdev_id, - HTT_TCL_META_DATA_PDEV_ID); + dp_link_vif->tcl_metadata |= u32_encode_bits(1, HTT_TCL_META_DATA_TYPE) | + u32_encode_bits(arvif->vdev_id, + HTT_TCL_META_DATA_VDEV_ID) | + u32_encode_bits(ar->pdev->pdev_id, + HTT_TCL_META_DATA_PDEV_ID); /* set HTT extension valid bit to 0 by default */ - arvif->tcl_metadata &= ~HTT_TCL_META_DATA_VALID_HTT; + dp_link_vif->tcl_metadata &= ~HTT_TCL_META_DATA_VALID_HTT; ath12k_dp_update_vdev_search(arvif); - arvif->vdev_id_check_en = true; - arvif->bank_id = ath12k_dp_tx_get_bank_profile(ab, arvif, ath12k_ab_to_dp(ab)); + dp_link_vif->vdev_id_check_en = true; + bank_id = ath12k_dp_tx_get_bank_profile(ab, arvif, ath12k_ab_to_dp(ab)); + dp_link_vif->bank_id = bank_id; /* TODO: error path for bank id failure */ - if (arvif->bank_id == DP_INVALID_BANK_ID) { + if (bank_id == DP_INVALID_BANK_ID) { ath12k_err(ar->ab, "Failed to initialize DP TX Banks"); return; } diff --git a/drivers/net/wireless/ath/ath12k/dp_cmn.h b/drivers/net/wireless/ath/ath12k/dp_cmn.h index 70c92f6d33d6f..3dc61d1a41625 100644 --- a/drivers/net/wireless/ath/ath12k/dp_cmn.h +++ b/drivers/net/wireless/ath/ath12k/dp_cmn.h @@ -14,6 +14,32 @@ struct ath12k_dp_hw_group { struct ath12k_dp *dp[ATH12K_MAX_DEVICES]; }; +struct ath12k_dp_link_vif { + u32 vdev_id; + u8 search_type; + u8 hal_addr_search_flags; + u8 pdev_idx; + u8 lmac_id; + u16 ast_idx; + u16 ast_hash; + u16 tcl_metadata; + u8 vdev_id_check_en; + int bank_id; +}; + +struct ath12k_dp_vif { + u8 tx_encap_type; + u32 key_cipher; + atomic_t mcbc_gsn; + struct ath12k_dp_link_vif dp_link_vif[ATH12K_NUM_MAX_LINKS]; +}; + +static inline struct ath12k_dp_link_vif * +ath12k_dp_vif_to_dp_link_vif(struct ath12k_dp_vif *dp_vif, u8 link_id) +{ + return &dp_vif->dp_link_vif[link_id]; +} + void ath12k_dp_cmn_device_deinit(struct ath12k_dp *dp); int ath12k_dp_cmn_device_init(struct ath12k_dp *dp); void ath12k_dp_cmn_hw_group_unassign(struct ath12k_dp *dp, diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 9074178c4e8ca..b067281831c30 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -5620,7 +5620,7 @@ static int ath12k_install_key(struct ath12k_link_vif *arvif, return -ETIMEDOUT; if (ether_addr_equal(arg.macaddr, arvif->bssid)) - ahvif->key_cipher = arg.ieee80211_key_cipher; + ahvif->dp_vif.key_cipher = arg.ieee80211_key_cipher; if (ar->install_key_status) { ret = -EINVAL; @@ -9244,7 +9244,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, return; } } else { - mcbc_gsn = atomic_inc_return(&ahvif->mcbc_gsn) & 0xfff; + mcbc_gsn = atomic_inc_return(&ahvif->dp_vif.mcbc_gsn) & 0xfff; links_map = ahvif->links_map; for_each_set_bit(link_id, &links_map, @@ -9268,9 +9268,10 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, skb_cb = ATH12K_SKB_CB(msdu_copied); skb_cb->link_id = link_id; + skb_cb->vif = vif; /* For open mode, skip peer find logic */ - if (unlikely(!ahvif->key_cipher)) + if (unlikely(!ahvif->dp_vif.key_cipher)) goto skip_peer_find; spin_lock_bh(&tmp_ar->ab->base_lock); @@ -9809,14 +9810,14 @@ static void ath12k_mac_update_vif_offload(struct ath12k_link_vif *arvif) IEEE80211_OFFLOAD_DECAP_ENABLED); if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) - ahvif->tx_encap_type = ATH12K_HW_TXRX_ETHERNET; + ahvif->dp_vif.tx_encap_type = ATH12K_HW_TXRX_ETHERNET; else if (test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) - ahvif->tx_encap_type = ATH12K_HW_TXRX_RAW; + ahvif->dp_vif.tx_encap_type = ATH12K_HW_TXRX_RAW; else - ahvif->tx_encap_type = ATH12K_HW_TXRX_NATIVE_WIFI; + ahvif->dp_vif.tx_encap_type = ATH12K_HW_TXRX_NATIVE_WIFI; ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, - param_id, ahvif->tx_encap_type); + param_id, ahvif->dp_vif.tx_encap_type); if (ret) { ath12k_warn(ab, "failed to set vdev %d tx encap mode: %d\n", arvif->vdev_id, ret); @@ -10031,6 +10032,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) int i; int ret, vdev_id; u8 link_id; + struct ath12k_dp_link_vif *dp_link_vif = NULL; lockdep_assert_wiphy(hw->wiphy); @@ -10112,6 +10114,12 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) goto err_vdev_del; } + dp_link_vif = ath12k_dp_vif_to_dp_link_vif(&ahvif->dp_vif, arvif->link_id); + + dp_link_vif->vdev_id = arvif->vdev_id; + dp_link_vif->lmac_id = ar->lmac_id; + dp_link_vif->pdev_idx = ar->pdev_idx; + switch (ahvif->vdev_type) { case WMI_VDEV_TYPE_AP: peer_param.vdev_id = arvif->vdev_id; @@ -10500,6 +10508,7 @@ static int ath12k_mac_vdev_delete(struct ath12k *ar, struct ath12k_link_vif *arv { struct ath12k_vif *ahvif = arvif->ahvif; struct ieee80211_vif *vif = ath12k_ahvif_to_vif(ahvif); + struct ath12k_dp_link_vif *dp_link_vif; struct ath12k_base *ab = ar->ab; unsigned long time_left; int ret; @@ -10546,7 +10555,9 @@ static int ath12k_mac_vdev_delete(struct ath12k *ar, struct ath12k_link_vif *arv ath12k_mac_vif_txmgmt_idr_remove, vif); ath12k_mac_vif_unref(ath12k_ab_to_dp(ab), vif); - ath12k_dp_tx_put_bank_profile(ath12k_ab_to_dp(ab), arvif->bank_id); + + dp_link_vif = ath12k_dp_vif_to_dp_link_vif(&ahvif->dp_vif, arvif->link_id); + ath12k_dp_tx_put_bank_profile(ath12k_ab_to_dp(ab), dp_link_vif->bank_id); /* Recalc txpower for remaining vdev */ ath12k_mac_txpower_recalc(ar); @@ -13058,7 +13069,7 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw, ahvif = arvif->ahvif; ath12k_dbg(ab, ATH12K_DBG_BOOT, "reconfig cipher %d up %d vdev type %d\n", - ahvif->key_cipher, + ahvif->dp_vif.key_cipher, arvif->is_up, ahvif->vdev_type); diff --git a/drivers/net/wireless/ath/ath12k/mac.h b/drivers/net/wireless/ath/ath12k/mac.h index 2f4a174b88942..ef5c3570bef10 100644 --- a/drivers/net/wireless/ath/ath12k/mac.h +++ b/drivers/net/wireless/ath/ath12k/mac.h @@ -54,9 +54,6 @@ struct ath12k_generic_iter { * for driver usage purpose. */ #define ATH12K_FIRST_SCAN_LINK IEEE80211_MLD_MAX_NUM_LINKS -#define ATH12K_SCAN_MAX_LINKS ATH12K_GROUP_MAX_RADIO -/* Define 1 scan link for each radio for parallel scan purposes */ -#define ATH12K_NUM_MAX_LINKS (IEEE80211_MLD_MAX_NUM_LINKS + ATH12K_SCAN_MAX_LINKS) #define ATH12K_SCAN_LINKS_MASK GENMASK(ATH12K_NUM_MAX_LINKS, IEEE80211_MLD_MAX_NUM_LINKS) #define ATH12K_NUM_MAX_ACTIVE_LINKS_PER_DEVICE 2 diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index af95324f27086..ce15642986568 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022, 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include "core.h" @@ -318,6 +318,8 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ath12k_wmi_peer_create_arg *arg) { struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif); + struct ath12k_vif *ahvif = arvif->ahvif; + struct ath12k_dp_link_vif *dp_link_vif; struct ath12k_link_sta *arsta; u8 link_id = arvif->link_id; struct ath12k_peer *peer; @@ -327,6 +329,8 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); + dp_link_vif = ath12k_dp_vif_to_dp_link_vif(&ahvif->dp_vif, link_id); + if (ar->num_peers > (ar->max_num_peers - 1)) { ath12k_warn(ar->ab, "failed to create peer due to insufficient peer entry resource in firmware\n"); @@ -384,8 +388,8 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, peer->sta = sta; if (vif->type == NL80211_IFTYPE_STATION) { - arvif->ast_hash = peer->ast_hash; - arvif->ast_idx = peer->hw_peer_id; + dp_link_vif->ast_hash = peer->ast_hash; + dp_link_vif->ast_idx = peer->hw_peer_id; } if (vif->type == NL80211_IFTYPE_AP) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 6a5d6f5259515..b94b14bda39bf 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -70,6 +70,8 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, struct hal_srng *tcl_ring; struct ieee80211_hdr *hdr = (void *)skb->data; struct ath12k_vif *ahvif = arvif->ahvif; + struct ath12k_dp_vif *dp_vif = &ahvif->dp_vif; + struct ath12k_dp_link_vif *dp_link_vif; struct dp_tx_ring *tx_ring; u8 pool_id; u8 hal_ring_id; @@ -113,10 +115,12 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, if (!tx_desc) return -ENOMEM; - ti.bank_id = arvif->bank_id; - ti.meta_data_flags = arvif->tcl_metadata; + dp_link_vif = ath12k_dp_vif_to_dp_link_vif(&ahvif->dp_vif, arvif->link_id); - if (ahvif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW && + ti.bank_id = dp_link_vif->bank_id; + ti.meta_data_flags = dp_link_vif->tcl_metadata; + + if (dp_vif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW && test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) { if (skb_cb->flags & ATH12K_SKB_CIPHER_SET) { ti.encrypt_type = @@ -142,18 +146,18 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, } ti.encap_type = ath12k_dp_tx_get_encap_type(ab, skb); - ti.addr_search_flags = arvif->hal_addr_search_flags; - ti.search_type = arvif->search_type; + ti.addr_search_flags = dp_link_vif->hal_addr_search_flags; + ti.search_type = dp_link_vif->search_type; ti.type = HAL_TCL_DESC_TYPE_BUFFER; ti.pkt_offset = 0; - ti.lmac_id = ar->lmac_id; + ti.lmac_id = dp_link_vif->lmac_id; - ti.vdev_id = arvif->vdev_id; + ti.vdev_id = dp_link_vif->vdev_id; if (gsn_valid) ti.vdev_id += HTT_TX_MLO_MCAST_HOST_REINJECT_BASE_VDEV_ID; - ti.bss_ast_hash = arvif->ast_hash; - ti.bss_ast_idx = arvif->ast_idx; + ti.bss_ast_hash = dp_link_vif->ast_hash; + ti.bss_ast_idx = dp_link_vif->ast_idx; ti.dscp_tid_tbl_idx = 0; if (skb->ip_summed == CHECKSUM_PARTIAL && @@ -251,11 +255,10 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, } tx_desc->skb = skb; - tx_desc->mac_id = ar->pdev_idx; + tx_desc->mac_id = dp_link_vif->pdev_idx; ti.desc_id = tx_desc->desc_id; ti.data_len = skb->len; skb_cb->paddr = ti.paddr; - skb_cb->vif = ahvif->vif; skb_cb->ar = ar; if (msdu_ext_desc) { From ad26148ebdf8319ebb2df9134c0fd1d619dc4ad0 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Tue, 7 Oct 2025 16:32:02 +0530 Subject: [PATCH 048/140] wifi: ath12k: Refactor data path pdev struct Refactor struct ath12k_pdev_dp to encapsulate all DP related fields of radio (ar) and rely on this single pdev object in per packet DP operations to optimize cache usage. Introduce an array of RCU-protected ath12k_pdev_dp in DP device object to find DP pdev directly from the DP device object. RCU on dp_pdevs[] provides a teardown synchronization mechanism by ensuring all in-flight access to dp_pdev pointers complete before reclaim. Once a dp_pdev pointer is obtained, its internal fields can be accessed as follows: - Writers update internal fields using their own synchronization. - Readers may perform lockless reads if occasional inconsistency is acceptable, or use additional synchronization (e.g., spin_lock, atomic_t) for a coherent view between readers and writers. Please note that RCU is used for dp_pdevs[] at this stage to align with ab->pdevs_active[]. However, if the teardown paths ensure quiescence, both dp_pdevs[] and pdevs_active[] can be converted to plain pointers, removing RCU synchronization overhead. This will be evaluated separately. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251007110203.1541167-2-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 4 + drivers/net/wireless/ath/ath12k/dp.c | 23 ++ drivers/net/wireless/ath/ath12k/dp.h | 35 +++ drivers/net/wireless/ath/ath12k/dp_mon.c | 184 ++++++++------- drivers/net/wireless/ath/ath12k/dp_mon.h | 9 +- drivers/net/wireless/ath/ath12k/dp_rx.c | 106 +++++---- drivers/net/wireless/ath/ath12k/dp_rx.h | 13 +- drivers/net/wireless/ath/ath12k/mac.c | 23 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 216 ++++++++++-------- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 66 +++--- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h | 2 +- 11 files changed, 424 insertions(+), 257 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index b424ff8428861..d11bc1cae9863 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1532,4 +1532,8 @@ static inline struct ath12k_dp *ath12k_ab_to_dp(struct ath12k_base *ab) return ab->dp; } +static inline struct ath12k *ath12k_pdev_dp_to_ar(struct ath12k_pdev_dp *dp) +{ + return container_of(dp, struct ath12k, dp); +} #endif /* _CORE_H_ */ diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 36e0dfd89bbde..088736bead58a 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -888,8 +888,17 @@ int ath12k_dp_link_desc_setup(struct ath12k_base *ab, void ath12k_dp_pdev_free(struct ath12k_base *ab) { + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k *ar; int i; + for (i = 0; i < ab->num_radios; i++) { + ar = ab->pdevs[i].ar; + rcu_assign_pointer(dp->dp_pdevs[ar->pdev_idx], NULL); + } + + synchronize_rcu(); + for (i = 0; i < ab->num_radios; i++) ath12k_dp_rx_pdev_free(ab, i); } @@ -911,6 +920,8 @@ void ath12k_dp_hal_rx_desc_init(struct ath12k_base *ab) int ath12k_dp_pdev_alloc(struct ath12k_base *ab) { + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_pdev_dp *dp_pdev; struct ath12k *ar; int ret; int i; @@ -922,6 +933,13 @@ int ath12k_dp_pdev_alloc(struct ath12k_base *ab) /* TODO: Per-pdev rx ring unlike tx ring which is mapped to different AC's */ for (i = 0; i < ab->num_radios; i++) { ar = ab->pdevs[i].ar; + + dp_pdev = &ar->dp; + + dp_pdev->hw = ar->ah->hw; + dp_pdev->dp = dp; + dp_pdev->hw_link_id = ar->hw_link_id; + ret = ath12k_dp_rx_pdev_alloc(ab, i); if (ret) { ath12k_warn(ab, "failed to allocate pdev rx for pdev_id :%d\n", @@ -935,6 +953,11 @@ int ath12k_dp_pdev_alloc(struct ath12k_base *ab) } } + for (i = 0; i < ab->num_radios; i++) { + ar = ab->pdevs[i].ar; + rcu_assign_pointer(dp->dp_pdevs[ar->pdev_idx], &ar->dp); + } + return 0; err: ath12k_dp_pdev_free(ab); diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 6e0e247d93768..30a101e797fb5 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -151,6 +151,11 @@ struct ath12k_pdev_dp { u32 mac_id; atomic_t num_tx_pending; wait_queue_head_t tx_empty_waitq; + + struct ath12k_dp *dp; + struct ieee80211_hw *hw; + u8 hw_link_id; + struct dp_srng rxdma_mon_dst_ring[MAX_RXDMA_PER_PDEV]; struct dp_srng tx_mon_dst_ring[MAX_RXDMA_PER_PDEV]; @@ -441,6 +446,21 @@ struct ath12k_dp { const struct ath12k_hw_params *hw_params; struct device *dev; + /* RCU on dp_pdevs[] provides a teardown synchronization mechanism, + * ensuring in-flight data path readers complete before reclaim. Writers + * update internal fields under their own synchronization, while readers of + * internal fields may perform lockless read if occasional inconsistency + * is acceptable or use additional synchronization for a coherent view. + * + * RCU is used for dp_pdevs[] at this stage to align with + * ab->pdevs_active[]. However, if the teardown paths ensure quiescence, + * both dp_pdevs[] and pdevs_active[] can be converted to plain pointers, + * removing RCU synchronize overhead. + * + * TODO: evaluate removal of RCU from dp_pdevs in the future + */ + struct ath12k_pdev_dp __rcu *dp_pdevs[MAX_RADIOS]; + struct ath12k_hw_group *ag; u8 device_id; @@ -466,6 +486,21 @@ ath12k_dp_service_srng(struct ath12k_dp *dp, struct ath12k_ext_irq_grp *irq_grp, return dp->ops->service_srng(dp, irq_grp, budget); } +static inline struct ieee80211_hw * +ath12k_pdev_dp_to_hw(struct ath12k_pdev_dp *pdev) +{ + return pdev->hw; +} + +static inline struct ath12k_pdev_dp * +ath12k_dp_to_pdev_dp(struct ath12k_dp *dp, u8 pdev_idx) +{ + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), + "ath12k dp to dp pdev called without rcu lock"); + + return rcu_dereference(dp->dp_pdevs[pdev_idx]); +} + void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif); void ath12k_dp_cc_config(struct ath12k_base *ab); void ath12k_dp_partner_cc_init(struct ath12k_base *ab); diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index c853c96ab220c..d0aaa0a2179cf 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -1485,7 +1485,7 @@ ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, } static enum hal_rx_mon_status -ath12k_dp_mon_rx_parse_status_tlv(struct ath12k *ar, +ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct hal_tlv_64_hdr *tlv) { @@ -1755,8 +1755,7 @@ ath12k_dp_mon_rx_parse_status_tlv(struct ath12k *ar, } static void -ath12k_dp_mon_fill_rx_stats_info(struct ath12k *ar, - struct hal_rx_mon_ppdu_info *ppdu_info, +ath12k_dp_mon_fill_rx_stats_info(struct hal_rx_mon_ppdu_info *ppdu_info, struct ieee80211_rx_status *rx_status) { u32 center_freq = ppdu_info->freq; @@ -1901,10 +1900,12 @@ void ath12k_dp_mon_next_link_desc_get(struct hal_rx_msdu_link *msdu_link, } static void -ath12k_dp_mon_fill_rx_rate(struct ath12k *ar, +ath12k_dp_mon_fill_rx_rate(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_mon_ppdu_info *ppdu_info, struct ieee80211_rx_status *rx_status) { + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct ieee80211_supported_band *sband; enum rx_msdu_start_pkt_type pkt_type; u8 rate_mcs, nss, sgi; @@ -1920,6 +1921,8 @@ ath12k_dp_mon_fill_rx_rate(struct ath12k *ar, case RX_MSDU_START_PKT_TYPE_11B: is_cck = (pkt_type == RX_MSDU_START_PKT_TYPE_11B); if (rx_status->band < NUM_NL80211_BANDS) { + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); + sband = &ar->mac.sbands[rx_status->band]; rx_status->rate_idx = ath12k_mac_hw_rate_to_idx(sband, rate_mcs, is_cck); @@ -1928,7 +1931,7 @@ ath12k_dp_mon_fill_rx_rate(struct ath12k *ar, case RX_MSDU_START_PKT_TYPE_11N: rx_status->encoding = RX_ENC_HT; if (rate_mcs > ATH12K_HT_MCS_MAX) { - ath12k_warn(ar->ab, + ath12k_warn(ab, "Received with invalid mcs in HT mode %d\n", rate_mcs); break; @@ -1941,7 +1944,7 @@ ath12k_dp_mon_fill_rx_rate(struct ath12k *ar, rx_status->encoding = RX_ENC_VHT; rx_status->rate_idx = rate_mcs; if (rate_mcs > ATH12K_VHT_MCS_MAX) { - ath12k_warn(ar->ab, + ath12k_warn(ab, "Received with invalid mcs in VHT mode %d\n", rate_mcs); break; @@ -1952,7 +1955,7 @@ ath12k_dp_mon_fill_rx_rate(struct ath12k *ar, case RX_MSDU_START_PKT_TYPE_11AX: rx_status->rate_idx = rate_mcs; if (rate_mcs > ATH12K_HE_MCS_MAX) { - ath12k_warn(ar->ab, + ath12k_warn(ab, "Received with invalid mcs in HE mode %d\n", rate_mcs); break; @@ -1963,7 +1966,7 @@ ath12k_dp_mon_fill_rx_rate(struct ath12k *ar, case RX_MSDU_START_PKT_TYPE_11BE: rx_status->rate_idx = rate_mcs; if (rate_mcs > ATH12K_EHT_MCS_MAX) { - ath12k_warn(ar->ab, + ath12k_warn(ab, "Received with invalid mcs in EHT mode %d\n", rate_mcs); break; @@ -1972,24 +1975,24 @@ ath12k_dp_mon_fill_rx_rate(struct ath12k *ar, rx_status->he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi); break; default: - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + ath12k_dbg(ab, ATH12K_DBG_DATA, "monitor receives invalid preamble type %d", pkt_type); break; } } -static void ath12k_dp_mon_rx_msdus_set_payload(struct ath12k *ar, +static void ath12k_dp_mon_rx_msdus_set_payload(struct ath12k_base *ab, struct sk_buff *head_msdu, struct sk_buff *tail_msdu) { u32 rx_pkt_offset, l2_hdr_offset, total_offset; - rx_pkt_offset = ar->ab->hal.hal_desc_sz; + rx_pkt_offset = ab->hal.hal_desc_sz; l2_hdr_offset = - ath12k_dp_rx_h_l3pad(ar->ab, (struct hal_rx_desc *)tail_msdu->data); + ath12k_dp_rx_h_l3pad(ab, (struct hal_rx_desc *)tail_msdu->data); - if (ar->ab->hw_params->rxdma1_enable) + if (ab->hw_params->rxdma1_enable) total_offset = ATH12K_MON_RX_PKT_OFFSET; else total_offset = rx_pkt_offset + l2_hdr_offset; @@ -1998,12 +2001,13 @@ static void ath12k_dp_mon_rx_msdus_set_payload(struct ath12k *ar, } static struct sk_buff * -ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar, +ath12k_dp_mon_rx_merg_msdus(struct ath12k_pdev_dp *dp_pdev, struct dp_mon_mpdu *mon_mpdu, struct hal_rx_mon_ppdu_info *ppdu_info, struct ieee80211_rx_status *rxs) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct sk_buff *msdu, *mpdu_buf, *prev_buf, *head_frag_list; struct sk_buff *head_msdu, *tail_msdu; struct hal_rx_desc *rx_desc; @@ -2020,11 +2024,13 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar, if (!head_msdu || !tail_msdu) goto err_merge_fail; - ath12k_dp_mon_fill_rx_stats_info(ar, ppdu_info, rxs); + ath12k_dp_mon_fill_rx_stats_info(ppdu_info, rxs); if (unlikely(rxs->band == NUM_NL80211_BANDS || - !ath12k_ar_to_hw(ar)->wiphy->bands[rxs->band])) { - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + !ath12k_pdev_dp_to_hw(dp_pdev)->wiphy->bands[rxs->band])) { + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); + + ath12k_dbg(ab, ATH12K_DBG_DATA, "sband is NULL for status band %d channel_num %d center_freq %d pdev_id %d\n", rxs->band, channel_num, ppdu_info->freq, ar->pdev_idx); @@ -2042,17 +2048,17 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar, rxs->freq = ieee80211_channel_to_frequency(channel_num, rxs->band); - ath12k_dp_mon_fill_rx_rate(ar, ppdu_info, rxs); + ath12k_dp_mon_fill_rx_rate(dp_pdev, ppdu_info, rxs); if (decap_format == DP_RX_DECAP_TYPE_RAW) { - ath12k_dp_mon_rx_msdus_set_payload(ar, head_msdu, tail_msdu); + ath12k_dp_mon_rx_msdus_set_payload(ab, head_msdu, tail_msdu); prev_buf = head_msdu; msdu = head_msdu->next; head_frag_list = NULL; while (msdu) { - ath12k_dp_mon_rx_msdus_set_payload(ar, head_msdu, tail_msdu); + ath12k_dp_mon_rx_msdus_set_payload(ab, head_msdu, tail_msdu); if (!head_frag_list) head_frag_list = msdu; @@ -2087,7 +2093,7 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar, msdu = head_msdu; while (msdu) { - ath12k_dp_mon_rx_msdus_set_payload(ar, head_msdu, tail_msdu); + ath12k_dp_mon_rx_msdus_set_payload(ab, head_msdu, tail_msdu); if (qos_pkt) { dest = skb_push(msdu, sizeof(__le16)); if (!dest) @@ -2171,11 +2177,12 @@ ath12k_dp_mon_rx_update_radiotap_he_mu(struct hal_rx_mon_ppdu_info *rx_status, rtap_buf[rtap_len] = rx_status->he_RU[3]; } -static void ath12k_dp_mon_update_radiotap(struct ath12k *ar, +static void ath12k_dp_mon_update_radiotap(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_mon_ppdu_info *ppduinfo, struct sk_buff *mon_skb, struct ieee80211_rx_status *rxs) { + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); struct ieee80211_supported_band *sband; s32 noise_floor; u8 *ptr = NULL; @@ -2268,6 +2275,9 @@ static void ath12k_dp_mon_update_radiotap(struct ath12k *ar, rxs->encoding = RX_ENC_HT; rxs->rate_idx = ppduinfo->rate; } else { + struct ath12k *ar; + + ar = ath12k_pdev_dp_to_ar(dp_pdev); rxs->encoding = RX_ENC_LEGACY; sband = &ar->mac.sbands[rxs->band]; rxs->rate_idx = ath12k_mac_hw_rate_to_idx(sband, ppduinfo->rate, @@ -2277,12 +2287,15 @@ static void ath12k_dp_mon_update_radiotap(struct ath12k *ar, rxs->mactime = ppduinfo->tsft; } -static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, +static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, + struct napi_struct *napi, struct sk_buff *msdu, const struct hal_rx_mon_ppdu_info *ppduinfo, struct ieee80211_rx_status *status, u8 decap) { + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; static const struct ieee80211_radiotap_he known = { .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN), @@ -2307,10 +2320,11 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct status->flag |= RX_FLAG_RADIOTAP_HE; } - ath12k_wifi7_dp_extract_rx_desc_data(ar->ab, &rx_info, rx_desc, rx_desc); + ath12k_wifi7_dp_extract_rx_desc_data(ab, &rx_info, rx_desc, rx_desc); - spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_peer_find_by_id(ar->ab, ppduinfo->peer_id); + spin_lock_bh(&ab->base_lock); + rx_info.addr2_present = false; + peer = ath12k_dp_rx_h_find_peer(ab, msdu, &rx_info); if (peer && peer->sta) { pubsta = peer->sta; if (pubsta->valid_links) { @@ -2319,9 +2333,9 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct } } - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&ab->base_lock); - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + ath12k_dbg(ab, ATH12K_DBG_DATA, "rx skb %p len %u peer %pM %u %s %s%s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", msdu, msdu->len, @@ -2345,7 +2359,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct !!(status->flag & RX_FLAG_MMIC_ERROR), !!(status->flag & RX_FLAG_AMSDU_MORE)); - ath12k_dbg_dump(ar->ab, ATH12K_DBG_DP_RX, NULL, "dp rx msdu: ", + ath12k_dbg_dump(ab, ATH12K_DBG_DP_RX, NULL, "dp rx msdu: ", msdu->data, msdu->len); rx_status = IEEE80211_SKB_RXCB(msdu); *rx_status = *status; @@ -2361,20 +2375,19 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct !(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED)) rx_status->flag |= RX_FLAG_8023; - ieee80211_rx_napi(ath12k_ar_to_hw(ar), pubsta, msdu, napi); + ieee80211_rx_napi(ath12k_pdev_dp_to_hw(dp_pdev), pubsta, msdu, napi); } -static int ath12k_dp_mon_rx_deliver(struct ath12k *ar, +static int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, struct dp_mon_mpdu *mon_mpdu, struct hal_rx_mon_ppdu_info *ppduinfo, struct napi_struct *napi) { - struct ath12k_pdev_dp *dp = &ar->dp; struct sk_buff *mon_skb, *skb_next, *header; - struct ieee80211_rx_status *rxs = &dp->rx_status; + struct ieee80211_rx_status *rxs = &dp_pdev->rx_status; u8 decap = DP_RX_DECAP_TYPE_RAW; - mon_skb = ath12k_dp_mon_rx_merg_msdus(ar, mon_mpdu, ppduinfo, rxs); + mon_skb = ath12k_dp_mon_rx_merg_msdus(dp_pdev, mon_mpdu, ppduinfo, rxs); if (!mon_skb) goto mon_deliver_fail; @@ -2402,8 +2415,8 @@ static int ath12k_dp_mon_rx_deliver(struct ath12k *ar, if (!(rxs->flag & RX_FLAG_ONLY_MONITOR)) decap = mon_mpdu->decap_format; - ath12k_dp_mon_update_radiotap(ar, ppduinfo, mon_skb, rxs); - ath12k_dp_mon_rx_deliver_msdu(ar, napi, mon_skb, ppduinfo, rxs, decap); + ath12k_dp_mon_update_radiotap(dp_pdev, ppduinfo, mon_skb, rxs); + ath12k_dp_mon_rx_deliver_msdu(dp_pdev, napi, mon_skb, rxs, decap); mon_skb = skb_next; } while (mon_skb); rxs->flag = 0; @@ -2465,12 +2478,12 @@ ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, } static int -ath12k_dp_mon_parse_status_buf(struct ath12k *ar, +ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct dp_mon_packet_info *packet_info) { - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct dp_rxdma_mon_ring *buf_ring = &dp->rxdma_mon_buf_ring; struct sk_buff *msdu; int buf_id; @@ -2511,7 +2524,7 @@ ath12k_dp_mon_parse_status_buf(struct ath12k *ar, } static int -ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k *ar, +ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, enum hal_rx_mon_status hal_status, const void *tlv_data) @@ -2526,7 +2539,7 @@ ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k *ar, return -ENOMEM; break; case HAL_RX_MON_STATUS_BUF_ADDR: - return ath12k_dp_mon_parse_status_buf(ar, pmon, tlv_data); + return ath12k_dp_mon_parse_status_buf(dp_pdev, pmon, tlv_data); case HAL_RX_MON_STATUS_MPDU_END: /* If no MSDU then free empty MPDU */ if (pmon->mon_mpdu->tail) { @@ -2549,9 +2562,10 @@ ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k *ar, } static enum hal_rx_mon_status -ath12k_dp_mon_parse_rx_dest(struct ath12k *ar, struct ath12k_mon_data *pmon, +ath12k_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, struct sk_buff *skb) { + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); struct hal_tlv_64_hdr *tlv; struct ath12k_skb_rxcb *rxcb; enum hal_rx_mon_status hal_status; @@ -2573,10 +2587,11 @@ ath12k_dp_mon_parse_rx_dest(struct ath12k *ar, struct ath12k_mon_data *pmon, else tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN); - hal_status = ath12k_dp_mon_rx_parse_status_tlv(ar, pmon, tlv); + hal_status = ath12k_dp_mon_rx_parse_status_tlv(dp_pdev, pmon, tlv); if (ar->monitor_started && ar->ab->hw_params->rxdma1_enable && - ath12k_dp_mon_parse_rx_dest_tlv(ar, pmon, hal_status, tlv->value)) + ath12k_dp_mon_parse_rx_dest_tlv(dp_pdev, pmon, hal_status, + tlv->value)) return HAL_RX_MON_STATUS_PPDU_DONE; ptr += sizeof(*tlv) + tlv_len; @@ -2599,7 +2614,7 @@ ath12k_dp_mon_parse_rx_dest(struct ath12k *ar, struct ath12k_mon_data *pmon, } enum hal_rx_mon_status -ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar, +ath12k_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, struct sk_buff *skb, struct napi_struct *napi) @@ -2609,7 +2624,7 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar, struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu; enum hal_rx_mon_status hal_status; - hal_status = ath12k_dp_mon_parse_rx_dest(ar, pmon, skb); + hal_status = ath12k_dp_mon_parse_rx_dest(dp_pdev, pmon, skb); if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) return hal_status; @@ -2617,7 +2632,7 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar, list_del(&mon_mpdu->list); if (mon_mpdu->head && mon_mpdu->tail) - ath12k_dp_mon_rx_deliver(ar, mon_mpdu, ppdu_info, napi); + ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, ppdu_info, napi); kfree(mon_mpdu); } @@ -3385,7 +3400,7 @@ ath12k_dp_mon_tx_status_get_num_user(u16 tlv_tag, } static void -ath12k_dp_mon_tx_process_ppdu_info(struct ath12k *ar, +ath12k_dp_mon_tx_process_ppdu_info(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, struct dp_mon_tx_ppdu_info *tx_ppdu_info) { @@ -3396,7 +3411,7 @@ ath12k_dp_mon_tx_process_ppdu_info(struct ath12k *ar, list_del(&mon_mpdu->list); if (mon_mpdu->head) - ath12k_dp_mon_rx_deliver(ar, mon_mpdu, + ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, &tx_ppdu_info->rx_status, napi); kfree(mon_mpdu); @@ -3404,13 +3419,14 @@ ath12k_dp_mon_tx_process_ppdu_info(struct ath12k *ar, } enum hal_rx_mon_status -ath12k_dp_mon_tx_parse_mon_status(struct ath12k *ar, +ath12k_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, struct sk_buff *skb, struct napi_struct *napi, u32 ppdu_id) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct dp_mon_tx_ppdu_info *tx_prot_ppdu_info, *tx_data_ppdu_info; struct hal_tlv_hdr *tlv; u8 *ptr = skb->data; @@ -3452,8 +3468,8 @@ ath12k_dp_mon_tx_parse_mon_status(struct ath12k *ar, break; } while (tlv_status != DP_MON_TX_FES_STATUS_END); - ath12k_dp_mon_tx_process_ppdu_info(ar, napi, tx_data_ppdu_info); - ath12k_dp_mon_tx_process_ppdu_info(ar, napi, tx_prot_ppdu_info); + ath12k_dp_mon_tx_process_ppdu_info(dp_pdev, napi, tx_data_ppdu_info); + ath12k_dp_mon_tx_process_ppdu_info(dp_pdev, napi, tx_prot_ppdu_info); return tlv_status; } @@ -3491,8 +3507,7 @@ ath12k_dp_mon_rx_update_peer_rate_table_stats(struct ath12k_rx_peer_stats *rx_st stats->rx_rate[bw_idx][gi_idx][nss_idx][mcs_idx] += len; } -static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k *ar, - struct ath12k_link_sta *arsta, +static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_link_sta *arsta, struct hal_rx_mon_ppdu_info *ppdu_info) { struct ath12k_rx_peer_stats *rx_stats = arsta->rx_stats; @@ -3650,7 +3665,7 @@ void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info) } static void -ath12k_dp_mon_rx_update_user_stats(struct ath12k *ar, +ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, struct hal_rx_mon_ppdu_info *ppdu_info, u32 uid) { @@ -3663,17 +3678,17 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k *ar, if (user_stats->ast_index == 0 || user_stats->ast_index == 0xFFFF) return; - peer = ath12k_peer_find_by_ast(ar->ab, user_stats->ast_index); + peer = ath12k_peer_find_by_ast(ab, user_stats->ast_index); if (!peer) { - ath12k_warn(ar->ab, "peer ast idx %d can't be found\n", + ath12k_warn(ab, "peer ast idx %d can't be found\n", user_stats->ast_index); return; } - arsta = ath12k_peer_get_link_sta(ar->ab, peer); + arsta = ath12k_peer_get_link_sta(ab, peer); if (!arsta) { - ath12k_warn(ar->ab, "link sta not found on peer %pM id %d\n", + ath12k_warn(ab, "link sta not found on peer %pM id %d\n", peer->addr, peer->peer_id); return; } @@ -3756,7 +3771,7 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k *ar, } static void -ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k *ar, +ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, struct hal_rx_mon_ppdu_info *ppdu_info) { u32 num_users, i; @@ -3766,7 +3781,7 @@ ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k *ar, num_users = HAL_MAX_UL_MU_USERS; for (i = 0; i < num_users; i++) - ath12k_dp_mon_rx_update_user_stats(ar, ppdu_info, i); + ath12k_dp_mon_rx_update_user_stats(ab, ppdu_info, i); } static void @@ -3776,14 +3791,13 @@ ath12k_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } -int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget, +int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, struct napi_struct *napi) { - struct ath12k_base *ab = ar->ab; - struct ath12k_pdev_dp *pdev_dp = &ar->dp; + struct ath12k_dp *dp = pdev_dp->dp; + struct ath12k_base *ab = dp->ab; struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&pdev_dp->mon_data; struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct hal_mon_dest_desc *mon_dst_desc; struct sk_buff *skb; struct ath12k_skb_rxcb *rxcb; @@ -3796,7 +3810,7 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget, u64 cookie; int num_buffs_reaped = 0, srng_id, buf_id; u32 hal_status, end_offset, info0, end_reason; - u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, ar->pdev_idx); + u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, pdev_dp->mac_id); __skb_queue_head_init(&skb_list); srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, pdev_idx); @@ -3894,7 +3908,7 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget, ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); while ((skb = __skb_dequeue(&skb_list))) { - hal_status = ath12k_dp_mon_rx_parse_mon_status(ar, pmon, skb, napi); + hal_status = ath12k_dp_mon_rx_parse_mon_status(pdev_dp, pmon, skb, napi); if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) { ppdu_info->ppdu_continuation = true; dev_kfree_skb_any(skb); @@ -3915,21 +3929,21 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget, } if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) { - arsta = ath12k_peer_get_link_sta(ar->ab, peer); + arsta = ath12k_peer_get_link_sta(ab, peer); if (!arsta) { - ath12k_warn(ar->ab, "link sta not found on peer %pM id %d\n", + ath12k_warn(ab, "link sta not found on peer %pM id %d\n", peer->addr, peer->peer_id); spin_unlock_bh(&ab->base_lock); rcu_read_unlock(); dev_kfree_skb_any(skb); continue; } - ath12k_dp_mon_rx_update_peer_su_stats(ar, arsta, + ath12k_dp_mon_rx_update_peer_su_stats(arsta, ppdu_info); } else if ((ppdu_info->fc_valid) && (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) { ath12k_dp_mon_rx_process_ulofdma(ppdu_info); - ath12k_dp_mon_rx_update_peer_mu_stats(ar, ppdu_info); + ath12k_dp_mon_rx_update_peer_mu_stats(ab, ppdu_info); } next_skb: @@ -4363,7 +4377,7 @@ static void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, tmp_mpdu->tail = tail_msdu; tmp_mpdu->err_bitmap = pmon->err_bitmap; tmp_mpdu->decap_format = pmon->decap_format; - ath12k_dp_mon_rx_deliver(ar, tmp_mpdu, + ath12k_dp_mon_rx_deliver(&ar->dp, tmp_mpdu, &pmon->mon_ppdu_info, napi); rx_mon_stats->dest_mpdu_done++; kfree(tmp_mpdu); @@ -4408,7 +4422,7 @@ __ath12k_dp_mon_process_ring(struct ath12k *ar, int mac_id, memset(ppdu_info, 0, sizeof(*ppdu_info)); ppdu_info->peer_id = HAL_INVALID_PEERID; - hal_status = ath12k_dp_mon_parse_rx_dest(ar, pmon, skb); + hal_status = ath12k_dp_mon_parse_rx_dest(&ar->dp, pmon, skb); if (ar->monitor_started && pmon->mon_ppdu_status == DP_PPDU_STATUS_START && @@ -4430,17 +4444,33 @@ int ath12k_dp_mon_process_ring(struct ath12k_base *ab, int mac_id, struct napi_struct *napi, int budget, enum dp_monitor_mode monitor_mode) { - struct ath12k *ar = ath12k_ab_to_ar(ab, mac_id); + u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id); + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_pdev_dp *dp_pdev; + struct ath12k *ar; int num_buffs_reaped = 0; + rcu_read_lock(); + + dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); + if (!dp_pdev) { + rcu_read_unlock(); + return 0; + } + if (ab->hw_params->rxdma1_enable) { if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE) - num_buffs_reaped = ath12k_dp_mon_srng_process(ar, &budget, napi); + num_buffs_reaped = ath12k_dp_mon_srng_process(dp_pdev, &budget, + napi); } else { + ar = ath12k_pdev_dp_to_ar(dp_pdev); + if (ar->monitor_started) num_buffs_reaped = __ath12k_dp_mon_process_ring(ar, mac_id, napi, &budget); } + rcu_read_unlock(); + return num_buffs_reaped; } diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index e25595cbdcf37..068df74003456 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2019-2021 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 ATH12K_DP_MON_H @@ -78,7 +78,7 @@ struct dp_mon_tx_ppdu_info { }; enum hal_rx_mon_status -ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar, +ath12k_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, struct sk_buff *skb, struct napi_struct *napi); @@ -97,11 +97,12 @@ ath12k_dp_mon_tx_status_get_num_user(u16 tlv_tag, struct hal_tlv_hdr *tx_tlv, u8 *num_users); enum hal_rx_mon_status -ath12k_dp_mon_tx_parse_mon_status(struct ath12k *ar, +ath12k_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, struct sk_buff *skb, struct napi_struct *napi, u32 ppdu_id); void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info); -int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget, struct napi_struct *napi); +int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, + struct napi_struct *napi); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index f6d7b5f974b1f..b4d28007b24a9 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -806,7 +806,7 @@ struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, return NULL; } -int ath12k_dp_rx_crypto_mic_len(struct ath12k *ar, enum hal_encrypt_type enctype) +int ath12k_dp_rx_crypto_mic_len(struct ath12k_dp *dp, enum hal_encrypt_type enctype) { switch (enctype) { case HAL_ENCRYPT_TYPE_OPEN: @@ -828,11 +828,11 @@ int ath12k_dp_rx_crypto_mic_len(struct ath12k *ar, enum hal_encrypt_type enctype break; } - ath12k_warn(ar->ab, "unsupported encryption type %d for mic len\n", enctype); + ath12k_warn(dp->ab, "unsupported encryption type %d for mic len\n", enctype); return 0; } -static int ath12k_dp_rx_crypto_param_len(struct ath12k *ar, +static int ath12k_dp_rx_crypto_param_len(struct ath12k_pdev_dp *dp_pdev, enum hal_encrypt_type enctype) { switch (enctype) { @@ -856,11 +856,11 @@ static int ath12k_dp_rx_crypto_param_len(struct ath12k *ar, break; } - ath12k_warn(ar->ab, "unsupported encryption type %d\n", enctype); + ath12k_warn(dp_pdev->dp->ab, "unsupported encryption type %d\n", enctype); return 0; } -static int ath12k_dp_rx_crypto_icv_len(struct ath12k *ar, +static int ath12k_dp_rx_crypto_icv_len(struct ath12k_pdev_dp *dp_pdev, enum hal_encrypt_type enctype) { switch (enctype) { @@ -881,15 +881,17 @@ static int ath12k_dp_rx_crypto_icv_len(struct ath12k *ar, break; } - ath12k_warn(ar->ab, "unsupported encryption type %d\n", enctype); + ath12k_warn(dp_pdev->dp->ab, "unsupported encryption type %d\n", enctype); return 0; } -static void ath12k_dp_rx_h_undecap_nwifi(struct ath12k *ar, +static void ath12k_dp_rx_h_undecap_nwifi(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, enum hal_encrypt_type enctype, struct hal_rx_desc_data *rx_info) { + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); u8 decap_hdr[DP_MAX_NWIFI_HDR_LEN]; struct ieee80211_hdr *hdr; @@ -920,8 +922,9 @@ static void ath12k_dp_rx_h_undecap_nwifi(struct ath12k *ar, /* Rebuild crypto header for mac80211 use */ if (!(rx_info->rx_status->flag & RX_FLAG_IV_STRIPPED)) { - crypto_hdr = skb_push(msdu, ath12k_dp_rx_crypto_param_len(ar, enctype)); - ath12k_dp_rx_desc_get_crypto_header(ar->ab, + crypto_hdr = skb_push(msdu, + ath12k_dp_rx_crypto_param_len(dp_pdev, enctype)); + ath12k_dp_rx_desc_get_crypto_header(ab, rxcb->rx_desc, crypto_hdr, enctype); } @@ -932,11 +935,13 @@ static void ath12k_dp_rx_h_undecap_nwifi(struct ath12k *ar, memcpy(skb_push(msdu, hdr_len), decap_hdr, hdr_len); } -static void ath12k_dp_rx_h_undecap_raw(struct ath12k *ar, struct sk_buff *msdu, +static void ath12k_dp_rx_h_undecap_raw(struct ath12k_pdev_dp *dp_pdev, + struct sk_buff *msdu, enum hal_encrypt_type enctype, struct ieee80211_rx_status *status, bool decrypted) { + struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); struct ieee80211_hdr *hdr; size_t hdr_len; @@ -958,20 +963,20 @@ static void ath12k_dp_rx_h_undecap_raw(struct ath12k *ar, struct sk_buff *msdu, /* Tail */ if (status->flag & RX_FLAG_IV_STRIPPED) { skb_trim(msdu, msdu->len - - ath12k_dp_rx_crypto_mic_len(ar, enctype)); + ath12k_dp_rx_crypto_mic_len(dp, enctype)); skb_trim(msdu, msdu->len - - ath12k_dp_rx_crypto_icv_len(ar, enctype)); + ath12k_dp_rx_crypto_icv_len(dp_pdev, enctype)); } else { /* MIC */ if (status->flag & RX_FLAG_MIC_STRIPPED) skb_trim(msdu, msdu->len - - ath12k_dp_rx_crypto_mic_len(ar, enctype)); + ath12k_dp_rx_crypto_mic_len(dp, enctype)); /* ICV */ if (status->flag & RX_FLAG_ICV_STRIPPED) skb_trim(msdu, msdu->len - - ath12k_dp_rx_crypto_icv_len(ar, enctype)); + ath12k_dp_rx_crypto_icv_len(dp_pdev, enctype)); } /* MMIC */ @@ -983,21 +988,22 @@ static void ath12k_dp_rx_h_undecap_raw(struct ath12k *ar, struct sk_buff *msdu, /* Head */ if (status->flag & RX_FLAG_IV_STRIPPED) { hdr_len = ieee80211_hdrlen(hdr->frame_control); - crypto_len = ath12k_dp_rx_crypto_param_len(ar, enctype); + crypto_len = ath12k_dp_rx_crypto_param_len(dp_pdev, enctype); memmove(msdu->data + crypto_len, msdu->data, hdr_len); skb_pull(msdu, crypto_len); } } -static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k *ar, +static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct ath12k_skb_rxcb *rxcb, enum hal_encrypt_type enctype, struct hal_rx_desc_data *rx_info) { struct hal_rx_desc *rx_desc = rxcb->rx_desc; - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; size_t hdr_len, crypto_len; struct ieee80211_hdr hdr; __le16 qos_ctl; @@ -1007,7 +1013,7 @@ static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k *ar, hdr_len = ieee80211_hdrlen(hdr.frame_control); if (!(rx_info->rx_status->flag & RX_FLAG_IV_STRIPPED)) { - crypto_len = ath12k_dp_rx_crypto_param_len(ar, enctype); + crypto_len = ath12k_dp_rx_crypto_param_len(dp_pdev, enctype); crypto_hdr = skb_push(msdu, crypto_len); ath12k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype); } @@ -1030,7 +1036,7 @@ static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k *ar, } } -static void ath12k_dp_rx_h_undecap_eth(struct ath12k *ar, +static void ath12k_dp_rx_h_undecap_eth(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, enum hal_encrypt_type enctype, struct hal_rx_desc_data *rx_info) @@ -1049,7 +1055,7 @@ static void ath12k_dp_rx_h_undecap_eth(struct ath12k *ar, skb_pull(msdu, sizeof(*eth)); memcpy(skb_push(msdu, sizeof(rfc)), &rfc, sizeof(rfc)); - ath12k_get_dot11_hdr_from_rx_desc(ar, msdu, rxcb, enctype, rx_info); + ath12k_get_dot11_hdr_from_rx_desc(dp_pdev, msdu, rxcb, enctype, rx_info); /* original 802.11 header has a different DA and in * case of 4addr it may also have different SA @@ -1059,7 +1065,7 @@ static void ath12k_dp_rx_h_undecap_eth(struct ath12k *ar, ether_addr_copy(ieee80211_get_SA(hdr), sa); } -void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, +void ath12k_dp_rx_h_undecap(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct hal_rx_desc *rx_desc, enum hal_encrypt_type enctype, bool decrypted, @@ -1069,10 +1075,10 @@ void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, switch (rx_info->decap_type) { case DP_RX_DECAP_TYPE_NATIVE_WIFI: - ath12k_dp_rx_h_undecap_nwifi(ar, msdu, enctype, rx_info); + ath12k_dp_rx_h_undecap_nwifi(dp_pdev, msdu, enctype, rx_info); break; case DP_RX_DECAP_TYPE_RAW: - ath12k_dp_rx_h_undecap_raw(ar, msdu, enctype, rx_info->rx_status, + ath12k_dp_rx_h_undecap_raw(dp_pdev, msdu, enctype, rx_info->rx_status, decrypted); break; case DP_RX_DECAP_TYPE_ETHERNET2_DIX: @@ -1081,7 +1087,7 @@ void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, /* mac80211 allows fast path only for authorized STA */ if (ehdr->h_proto == cpu_to_be16(ETH_P_PAE)) { ATH12K_SKB_RXCB(msdu)->is_eapol = true; - ath12k_dp_rx_h_undecap_eth(ar, msdu, enctype, rx_info); + ath12k_dp_rx_h_undecap_eth(dp_pdev, msdu, enctype, rx_info); break; } @@ -1089,7 +1095,7 @@ void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, * remove eth header and add 802.11 header. */ if (ATH12K_SKB_RXCB(msdu)->is_mcbc && decrypted) - ath12k_dp_rx_h_undecap_eth(ar, msdu, enctype, rx_info); + ath12k_dp_rx_h_undecap_eth(dp_pdev, msdu, enctype, rx_info); break; case DP_RX_DECAP_TYPE_8023: /* TODO: Handle undecap for these formats */ @@ -1118,18 +1124,22 @@ ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu, return peer; } -static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct hal_rx_desc_data *rx_info) +static void ath12k_dp_rx_h_rate(struct ath12k_pdev_dp *dp_pdev, + struct hal_rx_desc_data *rx_info) { + struct ath12k_dp *dp = dp_pdev->dp; struct ieee80211_supported_band *sband; struct ieee80211_rx_status *rx_status = rx_info->rx_status; enum rx_msdu_start_pkt_type pkt_type = rx_info->pkt_type; u8 bw = rx_info->bw, sgi = rx_info->sgi; u8 rate_mcs = rx_info->rate_mcs, nss = rx_info->nss; bool is_cck; + struct ath12k *ar; switch (pkt_type) { case RX_MSDU_START_PKT_TYPE_11A: case RX_MSDU_START_PKT_TYPE_11B: + ar = ath12k_pdev_dp_to_ar(dp_pdev); is_cck = (pkt_type == RX_MSDU_START_PKT_TYPE_11B); sband = &ar->mac.sbands[rx_status->band]; rx_status->rate_idx = ath12k_mac_hw_rate_to_idx(sband, rate_mcs, @@ -1138,7 +1148,7 @@ static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct hal_rx_desc_data *rx_i case RX_MSDU_START_PKT_TYPE_11N: rx_status->encoding = RX_ENC_HT; if (rate_mcs > ATH12K_HT_MCS_MAX) { - ath12k_warn(ar->ab, + ath12k_warn(dp->ab, "Received with invalid mcs in HT mode %d\n", rate_mcs); break; @@ -1152,7 +1162,7 @@ static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct hal_rx_desc_data *rx_i rx_status->encoding = RX_ENC_VHT; rx_status->rate_idx = rate_mcs; if (rate_mcs > ATH12K_VHT_MCS_MAX) { - ath12k_warn(ar->ab, + ath12k_warn(dp->ab, "Received with invalid mcs in VHT mode %d\n", rate_mcs); break; @@ -1165,7 +1175,7 @@ static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct hal_rx_desc_data *rx_i case RX_MSDU_START_PKT_TYPE_11AX: rx_status->rate_idx = rate_mcs; if (rate_mcs > ATH12K_HE_MCS_MAX) { - ath12k_warn(ar->ab, + ath12k_warn(dp->ab, "Received with invalid mcs in HE mode %d\n", rate_mcs); break; @@ -1179,7 +1189,7 @@ static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct hal_rx_desc_data *rx_i rx_status->rate_idx = rate_mcs; if (rate_mcs > ATH12K_EHT_MCS_MAX) { - ath12k_warn(ar->ab, + ath12k_warn(dp->ab, "Received with invalid mcs in EHT mode %d\n", rate_mcs); break; @@ -1195,7 +1205,8 @@ static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct hal_rx_desc_data *rx_i } } -void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc_data *rx_info) +void ath12k_dp_rx_h_ppdu(struct ath12k_pdev_dp *dp_pdev, + struct hal_rx_desc_data *rx_info) { struct ieee80211_rx_status *rx_status = rx_info->rx_status; u8 channel_num; @@ -1225,12 +1236,8 @@ void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc_data *rx_info) rx_status->band = NL80211_BAND_2GHZ; } else if (channel_num >= 36 && channel_num <= 173) { rx_status->band = NL80211_BAND_5GHZ; - } - - if (unlikely(rx_status->band == NUM_NL80211_BANDS || - !ath12k_ar_to_hw(ar)->wiphy->bands[rx_status->band])) { - ath12k_warn(ar->ab, "sband is NULL for status band %d channel_num %d center_freq %d pdev_id %d\n", - rx_status->band, channel_num, center_freq, ar->pdev_idx); + } else { + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); spin_lock_bh(&ar->data_lock); channel = ar->rx_channel; @@ -1251,15 +1258,15 @@ void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc_data *rx_info) rx_status->freq = ieee80211_channel_to_frequency(channel_num, rx_status->band); -h_rate: - ath12k_dp_rx_h_rate(ar, rx_info); + ath12k_dp_rx_h_rate(dp_pdev, rx_info); } -void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, +void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct ieee80211_rx_status *rx_status; struct ieee80211_sta *pubsta; struct ath12k_peer *peer; @@ -1324,7 +1331,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, !(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED)) rx_status->flag |= RX_FLAG_8023; - ieee80211_rx_napi(ath12k_ar_to_hw(ar), pubsta, msdu, napi); + ieee80211_rx_napi(ath12k_pdev_dp_to_hw(dp_pdev), pubsta, msdu, napi); } bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, @@ -1470,13 +1477,14 @@ int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, return ret; } -void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu, +void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, enum hal_encrypt_type enctype, u32 flags) { + struct ath12k_dp *dp = dp_pdev->dp; struct ieee80211_hdr *hdr; size_t hdr_len; size_t crypto_len; - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + u32 hal_rx_desc_sz = dp->ab->hal.hal_desc_sz; if (!flags) return; @@ -1485,15 +1493,15 @@ void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu, if (flags & RX_FLAG_MIC_STRIPPED) skb_trim(msdu, msdu->len - - ath12k_dp_rx_crypto_mic_len(ar, enctype)); + ath12k_dp_rx_crypto_mic_len(dp, enctype)); if (flags & RX_FLAG_ICV_STRIPPED) skb_trim(msdu, msdu->len - - ath12k_dp_rx_crypto_icv_len(ar, enctype)); + ath12k_dp_rx_crypto_icv_len(dp_pdev, enctype)); if (flags & RX_FLAG_IV_STRIPPED) { hdr_len = ieee80211_hdrlen(hdr->frame_control); - crypto_len = ath12k_dp_rx_crypto_param_len(ar, enctype); + crypto_len = ath12k_dp_rx_crypto_param_len(dp_pdev, enctype); memmove(msdu->data + hal_rx_desc_sz + crypto_len, msdu->data + hal_rx_desc_sz, hdr_len); @@ -1529,12 +1537,12 @@ void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, __skb_queue_tail(frag_list, cur_frag); } -u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb) +u64 ath12k_dp_rx_h_get_pn(struct ath12k_dp *dp, struct sk_buff *skb) { struct ieee80211_hdr *hdr; u64 pn = 0; u8 *ehdr; - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + u32 hal_rx_desc_sz = dp->ab->hal.hal_desc_sz; hdr = (struct ieee80211_hdr *)(skb->data + hal_rx_desc_sz); ehdr = skb->data + hal_rx_desc_sz + ieee80211_hdrlen(hdr->frame_control); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 1a8802c37443b..97b8f4608087f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -185,23 +185,23 @@ static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) dev_kfree_skb_any(skb); } -void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu, +void ath12k_dp_rx_h_undecap(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct hal_rx_desc *rx_desc, enum hal_encrypt_type enctype, bool decrypted, struct hal_rx_desc_data *rx_info); -void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi, +void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info); bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info); -u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb); +u64 ath12k_dp_rx_h_get_pn(struct ath12k_dp *dp, struct sk_buff *skb); void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, struct sk_buff_head *frag_list, struct sk_buff *cur_frag); -void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu, +void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, enum hal_encrypt_type enctype, u32 flags); void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, bool rel_link_desc); @@ -251,14 +251,15 @@ u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, struct hal_rx_desc *desc); u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, struct hal_rx_desc *desc); -int ath12k_dp_rx_crypto_mic_len(struct ath12k *ar, enum hal_encrypt_type enctype); +int ath12k_dp_rx_crypto_mic_len(struct ath12k_dp *dp, enum hal_encrypt_type enctype); u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); -void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct hal_rx_desc_data *rx_info); +void ath12k_dp_rx_h_ppdu(struct ath12k_pdev_dp *dp_pdev, + struct hal_rx_desc_data *rx_info); struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, struct sk_buff *first); void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx, diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index b067281831c30..06b28f15f0068 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -22,6 +22,7 @@ #include "hif.h" #include "wow.h" #include "debugfs_sta.h" +#include "dp.h" #define CHAN2G(_channel, _freq, _flags) { \ .band = NL80211_BAND_2GHZ, \ @@ -8700,7 +8701,7 @@ static int ath12k_mac_mgmt_tx_wmi(struct ath12k *ar, struct ath12k_link_vif *arv ieee80211_is_disassoc(hdr->frame_control)) && ieee80211_has_protected(hdr->frame_control)) { enctype = ath12k_dp_tx_get_encrypt_type(skb_cb->cipher); - mic_len = ath12k_dp_rx_crypto_mic_len(ar, enctype); + mic_len = ath12k_dp_rx_crypto_mic_len(ab->dp, enctype); skb_put(skb, mic_len); } } @@ -9155,6 +9156,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, u32 info_flags = info->flags; struct sk_buff *msdu_copied; struct ath12k *ar, *tmp_ar; + struct ath12k_pdev_dp *dp_pdev, *tmp_dp_pdev; struct ath12k_peer *peer; unsigned long links_map; bool is_mcast = false; @@ -9200,6 +9202,10 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, ar = arvif->ar; skb_cb->link_id = link_id; + /* as skb_cb is common currently for dp and mgmt tx processing + * set this in the common mac op tx function. + */ + skb_cb->ar = ar; is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { @@ -9227,6 +9233,12 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, if (vif->type == NL80211_IFTYPE_AP && vif->p2p) ath12k_mac_add_p2p_noa_ie(ar, vif, skb, is_prb_rsp); + dp_pdev = ath12k_dp_to_pdev_dp(ar->ab->dp, ar->pdev_idx); + if (!dp_pdev) { + ieee80211_free_txskb(hw, skb); + return; + } + /* Checking if it is a DVLAN frame */ if (!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && !(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) && @@ -9237,7 +9249,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, if (!vif->valid_links || !is_mcast || is_dvlan || (skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) || test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags)) { - ret = ath12k_wifi7_dp_tx(ar, arvif, skb, false, 0, is_mcast); + ret = ath12k_wifi7_dp_tx(dp_pdev, arvif, skb, false, 0, is_mcast); if (unlikely(ret)) { ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret); ieee80211_free_txskb(ar->ah->hw, skb); @@ -9254,6 +9266,10 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, continue; tmp_ar = tmp_arvif->ar; + tmp_dp_pdev = ath12k_dp_to_pdev_dp(tmp_ar->ab->dp, + tmp_ar->pdev_idx); + if (!tmp_dp_pdev) + continue; msdu_copied = skb_copy(skb, GFP_ATOMIC); if (!msdu_copied) { ath12k_err(ar->ab, @@ -9269,6 +9285,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, skb_cb = ATH12K_SKB_CB(msdu_copied); skb_cb->link_id = link_id; skb_cb->vif = vif; + skb_cb->ar = tmp_ar; /* For open mode, skip peer find logic */ if (unlikely(!ahvif->dp_vif.key_cipher)) @@ -9299,7 +9316,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, spin_unlock_bh(&tmp_ar->ab->base_lock); skip_peer_find: - ret = ath12k_wifi7_dp_tx(tmp_ar, tmp_arvif, + ret = ath12k_wifi7_dp_tx(tmp_dp_pdev, tmp_arvif, msdu_copied, true, mcbc_gsn, is_mcast); if (unlikely(ret)) { if (ret == -ENOMEM) { diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 04c64b9046938..d6ce6b9bb4d71 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -310,11 +310,13 @@ static void ath12k_wifi7_dp_rx_h_csum_offload(struct sk_buff *msdu, CHECKSUM_NONE : CHECKSUM_UNNECESSARY; } -static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k *ar, +static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct hal_rx_desc *rx_desc, struct hal_rx_desc_data *rx_info) { + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct ath12k_skb_rxcb *rxcb; enum hal_encrypt_type enctype; bool is_decrypted = false; @@ -330,8 +332,8 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k *ar, if (rxcb->is_mcbc) rxcb->peer_id = rx_info->peer_id; - spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu, rx_info); + spin_lock_bh(&ab->base_lock); + peer = ath12k_dp_rx_h_find_peer(ab, msdu, rx_info); if (peer) { /* resetting mcbc bit because mcbc packets are unicast * packets only for AP as STA sends unicast packets. @@ -345,7 +347,7 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k *ar, } else { enctype = HAL_ENCRYPT_TYPE_OPEN; } - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&ab->base_lock); if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap) is_decrypted = rx_info->is_decrypted; @@ -374,7 +376,7 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k *ar, } ath12k_wifi7_dp_rx_h_csum_offload(msdu, rx_info); - ath12k_dp_rx_h_undecap(ar, msdu, rx_desc, + ath12k_dp_rx_h_undecap(dp_pdev, msdu, rx_desc, enctype, is_decrypted, rx_info); if (!is_decrypted || rx_info->is_mcbc) @@ -386,19 +388,19 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k *ar, } } -static int ath12k_wifi7_dp_rx_msdu_coalesce(struct ath12k *ar, +static int ath12k_wifi7_dp_rx_msdu_coalesce(struct ath12k_dp *dp, struct sk_buff_head *msdu_list, struct sk_buff *first, struct sk_buff *last, u8 l3pad_bytes, int msdu_len, struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; + struct ath12k_base *ab = dp->ab; struct sk_buff *skb; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(first); int buf_first_hdr_len, buf_first_len; struct hal_rx_desc *ldesc; int space_extra, rem_len, buf_len; - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; bool is_continuation; /* As the msdu is spread across multiple rx buffers, @@ -474,19 +476,20 @@ static int ath12k_wifi7_dp_rx_msdu_coalesce(struct ath12k *ar, return 0; } -static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k *ar, +static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct sk_buff_head *msdu_list, struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct hal_rx_desc *rx_desc, *lrx_desc; struct ath12k_skb_rxcb *rxcb; struct sk_buff *last_buf; u8 l3_pad_bytes; u16 msdu_len; int ret; - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; last_buf = ath12k_dp_rx_get_msdu_last_buf(msdu_list, msdu); if (!last_buf) { @@ -524,7 +527,7 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k *ar, skb_put(msdu, hal_rx_desc_sz + l3_pad_bytes + msdu_len); skb_pull(msdu, hal_rx_desc_sz + l3_pad_bytes); } else { - ret = ath12k_wifi7_dp_rx_msdu_coalesce(ar, msdu_list, + ret = ath12k_wifi7_dp_rx_msdu_coalesce(dp, msdu_list, msdu, last_buf, l3_pad_bytes, msdu_len, rx_info); @@ -541,8 +544,8 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k *ar, goto free_out; } - ath12k_dp_rx_h_ppdu(ar, rx_info); - ath12k_wifi7_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_info); + ath12k_dp_rx_h_ppdu(dp_pdev, rx_info); + ath12k_wifi7_dp_rx_h_mpdu(dp_pdev, msdu, rx_desc, rx_info); rx_info->rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; @@ -565,11 +568,12 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, struct ath12k_skb_rxcb *rxcb; struct sk_buff *msdu; struct ath12k *ar; + struct ath12k_pdev_dp *dp_pdev; struct ath12k_hw_link *hw_links = ag->hw_links; struct ath12k_base *partner_ab; struct hal_rx_desc_data rx_info; struct ath12k_dp *partner_dp; - u8 hw_link_id, pdev_id; + u8 hw_link_id, pdev_idx; int ret; if (skb_queue_empty(msdu_list)) @@ -585,11 +589,11 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, hw_link_id = rxcb->hw_link_id; partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, hw_links[hw_link_id].device_id); - pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params, - hw_links[hw_link_id].pdev_idx); + pdev_idx = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params, + hw_links[hw_link_id].pdev_idx); partner_ab = partner_dp->ab; - ar = partner_ab->pdevs[pdev_id].ar; - if (!rcu_dereference(partner_ab->pdevs_active[pdev_id])) { + ar = partner_ab->pdevs[pdev_idx].ar; + if (!rcu_dereference(partner_ab->pdevs_active[pdev_idx])) { dev_kfree_skb_any(msdu); continue; } @@ -599,7 +603,13 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, continue; } - ret = ath12k_wifi7_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_info); + dp_pdev = ath12k_dp_to_pdev_dp(partner_dp, pdev_idx); + if (!dp_pdev) { + dev_kfree_skb_any(msdu); + continue; + } + + ret = ath12k_wifi7_dp_rx_process_msdu(dp_pdev, msdu, msdu_list, &rx_info); if (ret) { ath12k_dbg(ab, ATH12K_DBG_DATA, "Unable to process msdu %d", ret); @@ -607,7 +617,7 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, continue; } - ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info); + ath12k_dp_rx_deliver_msdu(dp_pdev, napi, msdu, &rx_info); } rcu_read_unlock(); @@ -778,10 +788,11 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, } static bool -ath12k_wifi7_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, +ath12k_wifi7_dp_rx_h_defrag_validate_incr_pn(struct ath12k_pdev_dp *dp_pdev, struct ath12k_dp_rx_tid *rx_tid, enum hal_encrypt_type encrypt_type) { + struct ath12k_dp *dp = dp_pdev->dp; struct sk_buff *first_frag, *skb; u64 last_pn; u64 cur_pn; @@ -794,12 +805,12 @@ ath12k_wifi7_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, encrypt_type != HAL_ENCRYPT_TYPE_AES_GCMP_256) return true; - last_pn = ath12k_dp_rx_h_get_pn(ar, first_frag); + last_pn = ath12k_dp_rx_h_get_pn(dp, first_frag); skb_queue_walk(&rx_tid->rx_frags, skb) { if (skb == first_frag) continue; - cur_pn = ath12k_dp_rx_h_get_pn(ar, skb); + cur_pn = ath12k_dp_rx_h_get_pn(dp, skb); if (cur_pn != last_pn + 1) return false; last_pn = cur_pn; @@ -807,12 +818,11 @@ ath12k_wifi7_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, return true; } -static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, +static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k_dp *dp, struct ath12k_dp_rx_tid *rx_tid, struct sk_buff *defrag_skb) { - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_base *ab = dp->ab; struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)defrag_skb->data; struct hal_reo_entrance_ring *reo_ent_ring; struct hal_reo_dest_ring *reo_dest_ring; @@ -953,13 +963,14 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k *ar, return ret; } -static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k *ar, +static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, struct ath12k_peer *peer, enum hal_encrypt_type enctype, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; struct ieee80211_rx_status *rxs = IEEE80211_SKB_RXCB(msdu); struct ieee80211_key_conf *key_conf; @@ -1014,26 +1025,28 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k *ar, rx_info))) return -EINVAL; - ath12k_dp_rx_h_ppdu(ar, rx_info); - ath12k_dp_rx_h_undecap(ar, msdu, rx_desc, + ath12k_dp_rx_h_ppdu(dp_pdev, rx_info); + ath12k_dp_rx_h_undecap(dp_pdev, msdu, rx_desc, HAL_ENCRYPT_TYPE_TKIP_MIC, true, rx_info); - ieee80211_rx(ath12k_ar_to_hw(ar), msdu); + ieee80211_rx(ath12k_pdev_dp_to_hw(dp_pdev), msdu); return -EINVAL; } -static int ath12k_wifi7_dp_rx_h_defrag(struct ath12k *ar, +static int ath12k_wifi7_dp_rx_h_defrag(struct ath12k_pdev_dp *dp_pdev, struct ath12k_peer *peer, struct ath12k_dp_rx_tid *rx_tid, struct sk_buff **defrag_skb, enum hal_encrypt_type enctype, struct hal_rx_desc_data *rx_info) { + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct sk_buff *skb, *first_frag, *last_frag; struct ieee80211_hdr *hdr; bool is_decrypted = false; int msdu_len = 0; int extra_space; - u32 flags, hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + u32 flags, hal_rx_desc_sz = ab->hal.hal_desc_sz; first_frag = skb_peek(&rx_tid->rx_frags); last_frag = skb_peek_tail(&rx_tid->rx_frags); @@ -1056,7 +1069,7 @@ static int ath12k_wifi7_dp_rx_h_defrag(struct ath12k *ar, /* RX fragments are always raw packets */ if (skb != last_frag) skb_trim(skb, skb->len - FCS_LEN); - ath12k_dp_rx_h_undecap_frag(ar, skb, enctype, flags); + ath12k_dp_rx_h_undecap_frag(dp_pdev, skb, enctype, flags); if (skb != first_frag) skb_pull(skb, hal_rx_desc_sz + @@ -1079,19 +1092,21 @@ static int ath12k_wifi7_dp_rx_h_defrag(struct ath12k *ar, hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); ATH12K_SKB_RXCB(first_frag)->is_frag = 1; - if (ath12k_wifi7_dp_rx_h_verify_tkip_mic(ar, peer, enctype, first_frag, rx_info)) + if (ath12k_wifi7_dp_rx_h_verify_tkip_mic(dp_pdev, peer, enctype, first_frag, + rx_info)) first_frag = NULL; *defrag_skb = first_frag; return 0; } -static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k *ar, +static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct hal_reo_dest_ring *ring_desc, struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct ath12k_peer *peer; struct ath12k_dp_rx_tid *rx_tid; struct sk_buff *defrag_skb = NULL; @@ -1186,17 +1201,17 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k *ar, if (!peer) goto err_frags_cleanup; - if (!ath12k_wifi7_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid, enctype)) + if (!ath12k_wifi7_dp_rx_h_defrag_validate_incr_pn(dp_pdev, rx_tid, enctype)) goto err_frags_cleanup; - if (ath12k_wifi7_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb, + if (ath12k_wifi7_dp_rx_h_defrag(dp_pdev, peer, rx_tid, &defrag_skb, enctype, rx_info)) goto err_frags_cleanup; if (!defrag_skb) goto err_frags_cleanup; - if (ath12k_wifi7_dp_rx_h_defrag_reo_reinject(ar, rx_tid, defrag_skb)) + if (ath12k_wifi7_dp_rx_h_defrag_reo_reinject(dp, rx_tid, defrag_skb)) goto err_frags_cleanup; ath12k_dp_rx_frags_cleanup(rx_tid, false); @@ -1211,12 +1226,14 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k *ar, } static int -ath12k_wifi7_dp_process_rx_err_buf(struct ath12k *ar, +ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, struct hal_reo_dest_ring *desc, struct list_head *used_list, bool drop, u32 cookie) { - struct ath12k_base *ab = ar->ab; + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct sk_buff *msdu; struct ath12k_skb_rxcb *rxcb; struct hal_rx_desc_data rx_info; @@ -1249,7 +1266,7 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k *ar, list_add_tail(&desc_info->list, used_list); rxcb = ATH12K_SKB_RXCB(msdu); - dma_unmap_single(ar->ab->dev, rxcb->paddr, + dma_unmap_single(ab->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), DMA_FROM_DEVICE); @@ -1274,8 +1291,8 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k *ar, msdu_len = rx_info.msdu_len; if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { - ath12k_warn(ar->ab, "invalid msdu leng %u", msdu_len); - ath12k_dbg_dump(ar->ab, ATH12K_DBG_DATA, NULL, "", rx_desc, + ath12k_warn(ab, "invalid msdu leng %u", msdu_len); + ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", rx_desc, sizeof(*rx_desc)); dev_kfree_skb_any(msdu); goto exit; @@ -1283,7 +1300,7 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k *ar, skb_put(msdu, hal_rx_desc_sz + msdu_len); - if (ath12k_wifi7_dp_rx_frag_h_mpdu(ar, msdu, desc, &rx_info)) { + if (ath12k_wifi7_dp_rx_frag_h_mpdu(dp_pdev, msdu, desc, &rx_info)) { dev_kfree_skb_any(msdu); ath12k_wifi7_dp_rx_link_desc_return(ar->ab, &desc->buf_addr_info, HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); @@ -1312,14 +1329,14 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n struct dp_srng *reo_except; struct ath12k_hw_link *hw_links = ag->hw_links; struct ath12k_base *partner_ab; + struct ath12k_pdev_dp *dp_pdev; u8 hw_link_id, device_id; u32 desc_bank, num_msdus; struct hal_srng *srng; - struct ath12k *ar; dma_addr_t paddr; bool is_frag; bool drop; - int pdev_id; + int pdev_idx; struct list_head *used_list; enum hal_wbm_rel_bm_act act; @@ -1356,9 +1373,8 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); partner_ab = partner_dp->ab; - pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, - hw_links[hw_link_id].pdev_idx); - ar = partner_ab->pdevs[pdev_id].ar; + pdev_idx = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + hw_links[hw_link_id].pdev_idx); link_desc_banks = partner_dp->link_desc_banks; link_desc_va = link_desc_banks[desc_bank].vaddr + @@ -1396,10 +1412,18 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n act); } + rcu_read_lock(); + + dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); + if (!dp_pdev) { + rcu_read_unlock(); + continue; + } + for (i = 0; i < num_msdus; i++) { used_list = &rx_desc_used_list[device_id]; - if (!ath12k_wifi7_dp_process_rx_err_buf(ar, reo_desc, + if (!ath12k_wifi7_dp_process_rx_err_buf(dp_pdev, reo_desc, used_list, drop, msdu_cookies[i])) { @@ -1408,6 +1432,8 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n } } + rcu_read_unlock(); + if (tot_n_bufs_reaped >= quota) { tot_n_bufs_reaped = quota; goto exit; @@ -1438,7 +1464,7 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n } static void -ath12k_wifi7_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, int msdu_len, +ath12k_wifi7_dp_rx_null_q_desc_sg_drop(struct ath12k_dp *dp, int msdu_len, struct sk_buff_head *msdu_list) { struct sk_buff *skb, *tmp; @@ -1446,7 +1472,7 @@ ath12k_wifi7_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, int msdu_len, int n_buffs; n_buffs = DIV_ROUND_UP(msdu_len, - (DP_RX_BUFFER_SIZE - ar->ab->hal.hal_desc_sz)); + (DP_RX_BUFFER_SIZE - dp->ab->hal.hal_desc_sz)); skb_queue_walk_safe(msdu_list, skb, tmp) { rxcb = ATH12K_SKB_RXCB(skb); @@ -1461,21 +1487,23 @@ ath12k_wifi7_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, int msdu_len, } } -static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, +static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k_pdev_dp *dp_pdev, + struct sk_buff *msdu, struct hal_rx_desc_data *rx_info, struct sk_buff_head *msdu_list) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; u16 msdu_len = rx_info->msdu_len; struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; u8 l3pad_bytes = rx_info->l3_pad_bytes; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + u32 hal_rx_desc_sz = dp->ab->hal.hal_desc_sz; if (!rxcb->is_frag && ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE)) { /* First buffer will be freed by the caller, so deduct it's length */ msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - hal_rx_desc_sz); - ath12k_wifi7_dp_rx_null_q_desc_sg_drop(ar, msdu_len, msdu_list); + ath12k_wifi7_dp_rx_null_q_desc_sg_drop(dp, msdu_len, msdu_list); return -EINVAL; } @@ -1487,7 +1515,7 @@ static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *m return -EINVAL; if (!rx_info->msdu_done) { - ath12k_warn(ar->ab, + ath12k_warn(ab, "msdu_done bit not set in null_q_des processing\n"); __skb_queue_purge(msdu_list); return -EIO; @@ -1514,8 +1542,8 @@ static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *m if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu, rx_info))) return -EINVAL; - ath12k_dp_rx_h_ppdu(ar, rx_info); - ath12k_wifi7_dp_rx_h_mpdu(ar, msdu, desc, rx_info); + ath12k_dp_rx_h_ppdu(dp_pdev, rx_info); + ath12k_wifi7_dp_rx_h_mpdu(dp_pdev, msdu, desc, rx_info); rxcb->tid = rx_info->tid; @@ -1526,15 +1554,17 @@ static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *m return 0; } -static bool ath12k_wifi7_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, +static bool ath12k_wifi7_dp_rx_h_tkip_mic_err(struct ath12k_pdev_dp *dp_pdev, + struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; u16 msdu_len = rx_info->msdu_len; struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; u8 l3pad_bytes = rx_info->l3_pad_bytes; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); - u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; rxcb->is_first_msdu = rx_info->is_first_msdu; rxcb->is_last_msdu = rx_info->is_last_msdu; @@ -1553,29 +1583,31 @@ static bool ath12k_wifi7_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu, rx_info))) return true; - ath12k_dp_rx_h_ppdu(ar, rx_info); + ath12k_dp_rx_h_ppdu(dp_pdev, rx_info); rx_info->rx_status->flag |= (RX_FLAG_MMIC_STRIPPED | RX_FLAG_MMIC_ERROR | RX_FLAG_DECRYPTED); - ath12k_dp_rx_h_undecap(ar, msdu, desc, + ath12k_dp_rx_h_undecap(dp_pdev, msdu, desc, HAL_ENCRYPT_TYPE_TKIP_MIC, false, rx_info); return false; } -static bool ath12k_wifi7_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, +static bool ath12k_wifi7_dp_rx_h_rxdma_err(struct ath12k_pdev_dp *dp_pdev, + struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) { + struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); bool drop = false; - ar->ab->device_stats.rxdma_error[rxcb->err_code]++; + dp->ab->device_stats.rxdma_error[rxcb->err_code]++; switch (rxcb->err_code) { case HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR: case HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR: if (rx_info->err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) { - drop = ath12k_wifi7_dp_rx_h_tkip_mic_err(ar, msdu, rx_info); + drop = ath12k_wifi7_dp_rx_h_tkip_mic_err(dp_pdev, msdu, rx_info); break; } fallthrough; @@ -1590,18 +1622,20 @@ static bool ath12k_wifi7_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *m return drop; } -static bool ath12k_wifi7_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu, +static bool ath12k_wifi7_dp_rx_h_reo_err(struct ath12k_pdev_dp *dp_pdev, + struct sk_buff *msdu, struct hal_rx_desc_data *rx_info, struct sk_buff_head *msdu_list) { + struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); bool drop = false; - ar->ab->device_stats.reo_error[rxcb->err_code]++; + dp->ab->device_stats.reo_error[rxcb->err_code]++; switch (rxcb->err_code) { case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO: - if (ath12k_wifi7_dp_rx_h_null_q_desc(ar, msdu, rx_info, msdu_list)) + if (ath12k_wifi7_dp_rx_h_null_q_desc(dp_pdev, msdu, rx_info, msdu_list)) drop = true; break; case HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED: @@ -1621,11 +1655,12 @@ static bool ath12k_wifi7_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu return drop; } -static void ath12k_wifi7_dp_rx_wbm_err(struct ath12k *ar, +static void ath12k_wifi7_dp_rx_wbm_err(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, struct sk_buff *msdu, struct sk_buff_head *msdu_list) { + struct ath12k_dp *dp = dp_pdev->dp; struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); struct ieee80211_rx_status rxs = {}; @@ -1635,14 +1670,14 @@ static void ath12k_wifi7_dp_rx_wbm_err(struct ath12k *ar, rx_info.addr2_present = false; rx_info.rx_status = &rxs; - ath12k_wifi7_dp_extract_rx_desc_data(ar->ab, &rx_info, rx_desc, rx_desc); + ath12k_wifi7_dp_extract_rx_desc_data(dp->ab, &rx_info, rx_desc, rx_desc); switch (rxcb->err_rel_src) { case HAL_WBM_REL_SRC_MODULE_REO: - drop = ath12k_wifi7_dp_rx_h_reo_err(ar, msdu, &rx_info, msdu_list); + drop = ath12k_wifi7_dp_rx_h_reo_err(dp_pdev, msdu, &rx_info, msdu_list); break; case HAL_WBM_REL_SRC_MODULE_RXDMA: - drop = ath12k_wifi7_dp_rx_h_rxdma_err(ar, msdu, &rx_info); + drop = ath12k_wifi7_dp_rx_h_rxdma_err(dp_pdev, msdu, &rx_info); break; default: /* msdu will get freed */ @@ -1656,7 +1691,7 @@ static void ath12k_wifi7_dp_rx_wbm_err(struct ath12k *ar, rx_info.rx_status->flag |= RX_FLAG_SKIP_MONITOR; - ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info); + ath12k_dp_rx_deliver_msdu(dp_pdev, napi, msdu, &rx_info); } void ath12k_wifi7_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, @@ -1694,6 +1729,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, { struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; struct ath12k *ar; + struct ath12k_pdev_dp *dp_pdev; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_hw_group *ag = dp->ag; struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; @@ -1710,9 +1746,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, struct ath12k_rx_desc_info *desc_info; struct ath12k_device_dp_stats *device_stats = &ab->device_stats; struct ath12k_hw_link *hw_links = ag->hw_links; - struct ath12k_base *partner_ab; u8 hw_link_id, device_id; - int ret, pdev_id; + int ret, pdev_idx; struct hal_rx_desc *msdu_data; __skb_queue_head_init(&msdu_list); @@ -1770,8 +1805,6 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, continue; } - partner_ab = partner_dp->ab; - list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]); rxcb = ATH12K_SKB_RXCB(msdu); @@ -1804,7 +1837,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, continue; } - hw_link_id = ath12k_dp_rx_get_msdu_src_link(partner_ab, + hw_link_id = ath12k_dp_rx_get_msdu_src_link(partner_dp->ab, msdu_data); if (hw_link_id >= ATH12K_GROUP_MAX_RADIO) { dev_kfree_skb_any(msdu); @@ -1872,12 +1905,17 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, continue; } - pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params, - hw_links[hw_link_id].pdev_idx); - partner_ab = partner_dp->ab; - ar = partner_ab->pdevs[pdev_id].ar; + pdev_idx = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params, + hw_links[hw_link_id].pdev_idx); + + dp_pdev = ath12k_dp_to_pdev_dp(partner_dp, pdev_idx); + if (!dp_pdev) { + dev_kfree_skb_any(msdu); + continue; + } + ar = ath12k_pdev_dp_to_ar(dp_pdev); - if (!ar || !rcu_dereference(ar->ab->pdevs_active[pdev_id])) { + if (!ar || !rcu_dereference(ar->ab->pdevs_active[pdev_idx])) { dev_kfree_skb_any(msdu); continue; } @@ -1892,7 +1930,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, device_stats->rx_wbm_rel_source[rxcb->err_rel_src][device_id]++; } - ath12k_wifi7_dp_rx_wbm_err(ar, napi, msdu, &msdu_list); + ath12k_wifi7_dp_rx_wbm_err(dp_pdev, napi, msdu, &msdu_list); } rcu_read_unlock(); done: diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index b94b14bda39bf..ab5824abfe758 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -54,12 +54,12 @@ static int ath12k_wifi7_dp_prepare_htt_metadata(struct sk_buff *skb) return 0; } -int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, +int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *arvif, struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, bool is_mcast) { - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct hal_tx_info ti = {}; struct ath12k_tx_desc_info *tx_desc; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -84,7 +84,7 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, bool is_diff_encap = false; bool is_null_frame = false; - if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags)) + if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags)) return -ESHUTDOWN; if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && @@ -121,7 +121,7 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, ti.meta_data_flags = dp_link_vif->tcl_metadata; if (dp_vif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW && - test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) { + test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags)) { if (skb_cb->flags & ATH12K_SKB_CIPHER_SET) { ti.encrypt_type = ath12k_dp_tx_get_encrypt_type(skb_cb->cipher); @@ -231,7 +231,7 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, goto fail_remove_tx_buf; } - if ((!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && + if ((!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags) && !(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) && !(skb_cb->flags & ATH12K_SKB_CIPHER_SET) && ieee80211_has_protected(hdr->frame_control)) || @@ -259,7 +259,6 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, ti.desc_id = tx_desc->desc_id; ti.data_len = skb->len; skb_cb->paddr = ti.paddr; - skb_cb->ar = ar; if (msdu_ext_desc) { skb_ext_desc = dev_alloc_skb(sizeof(struct hal_tx_msdu_ext_desc)); @@ -349,7 +348,7 @@ int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, ath12k_dbg_dump(ab, ATH12K_DBG_DP_TX, NULL, "dp tx msdu: ", skb->data, skb->len); - atomic_inc(&ar->dp.num_tx_pending); + atomic_inc(&dp_pdev->num_tx_pending); return 0; @@ -511,10 +510,11 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc, } } -static void -ath12k_wifi7_dp_tx_update_txcompl(struct ath12k *ar, struct hal_tx_status *ts) +static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, + struct hal_tx_status *ts) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct ath12k_peer *peer; struct ieee80211_sta *sta; struct ath12k_sta *ahsta; @@ -630,13 +630,13 @@ ath12k_wifi7_dp_tx_update_txcompl(struct ath12k *ar, struct hal_tx_status *ts) spin_unlock_bh(&ab->base_lock); } -static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k *ar, +static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, struct ath12k_tx_desc_params *desc_params, struct hal_tx_status *ts, int ring) { - struct ath12k_base *ab = ar->ab; - struct ath12k_hw *ah = ar->ah; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct ieee80211_tx_info *info; struct ath12k_link_vif *arvif; struct ath12k_skb_cb *skb_cb; @@ -668,13 +668,13 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k *ar, rcu_read_lock(); - if (!rcu_dereference(ab->pdevs_active[ar->pdev_idx])) { - ieee80211_free_txskb(ah->hw, msdu); + if (!rcu_dereference(ab->pdevs_active[dp_pdev->mac_id])) { + ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); goto exit; } if (!skb_cb->vif) { - ieee80211_free_txskb(ah->hw, msdu); + ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); goto exit; } @@ -703,6 +703,8 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k *ar, if (!test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, ab->wmi_ab.svc_map)) { + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); + spin_lock_bh(&ar->data_lock); noise_floor = ath12k_pdev_get_noise_floor(ar); spin_unlock_bh(&ar->data_lock); @@ -726,7 +728,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k *ar, * hence drop the frame; do not update the status of frame to * the upper layer */ - ieee80211_free_txskb(ah->hw, msdu); + ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); goto exit; default: ath12k_dbg(ab, ATH12K_DBG_DP_TX, "tx frame is not acked status %d\n", @@ -739,7 +741,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k *ar, * Might end up reporting it out-of-band from HTT stats. */ - ath12k_wifi7_dp_tx_update_txcompl(ar, ts); + ath12k_wifi7_dp_tx_update_txcompl(dp_pdev, ts); spin_lock_bh(&ab->base_lock); peer = ath12k_peer_find_by_id(ab, ts->peer_id); @@ -748,7 +750,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k *ar, "dp_tx: failed to find the peer with peer_id %d\n", ts->peer_id); spin_unlock_bh(&ab->base_lock); - ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu); + ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); goto exit; } ahsta = ath12k_sta_to_ahsta(peer->sta); @@ -766,7 +768,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k *ar, status.rates = &status_rate; status.n_rates = 1; - ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status); + ieee80211_tx_status_ext(ath12k_pdev_dp_to_hw(dp_pdev), &status); exit: rcu_read_unlock(); @@ -811,7 +813,7 @@ ath12k_wifi7_dp_tx_status_parse(struct ath12k_base *ab, void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) { - struct ath12k *ar; + struct ath12k_pdev_dp *dp_pdev; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id; struct hal_srng *status_ring = &ab->hal.srng_list[hal_ring_id]; @@ -820,7 +822,7 @@ void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) struct ath12k_tx_desc_params desc_params; struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id]; struct hal_wbm_release_ring *desc; - u8 pdev_id; + u8 pdev_idx; u64 desc_va; enum hal_wbm_rel_src_module buf_rel_source; enum hal_wbm_tqm_rel_reason rel_status; @@ -902,13 +904,21 @@ void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) continue; } - pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, desc_params.mac_id); - ar = ab->pdevs[pdev_id].ar; + pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, desc_params.mac_id); - if (atomic_dec_and_test(&ar->dp.num_tx_pending)) - wake_up(&ar->dp.tx_empty_waitq); + rcu_read_lock(); + + dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); + if (!dp_pdev) { + rcu_read_unlock(); + continue; + } + + if (atomic_dec_and_test(&dp_pdev->num_tx_pending)) + wake_up(&dp_pdev->tx_empty_waitq); - ath12k_wifi7_dp_tx_complete_msdu(ar, &desc_params, &ts, + ath12k_wifi7_dp_tx_complete_msdu(dp_pdev, &desc_params, &ts, tx_ring->tcl_data_ring_id); + rcu_read_unlock(); } } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h index 061c4de4d4e62..524e23b8ed808 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h @@ -7,7 +7,7 @@ #ifndef ATH12K_DP_TX_WIFI7_H #define ATH12K_DP_TX_WIFI7_H -int ath12k_wifi7_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif, +int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *arvif, struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, bool is_mcast); void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id); From 5757aee9a6564e8ed5fce16e82bc9267670353ac Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Tue, 7 Oct 2025 16:32:03 +0530 Subject: [PATCH 049/140] wifi: ath12k: Rearrange PPDU radio stats Encapsulate PPDU stats in dp_pdev as these stats are related to data path out-of-band operations. This reorganization improves the structuring of data path stats and enhances the efficiency of data path operations by consolidating both in-band (per packet) fields and out-of-band data path stats within the same ath12k_pdev_dp object. ppdu_list_lock is used to protect HTT pdev stats update. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251007110203.1541167-3-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 20 -------- drivers/net/wireless/ath/ath12k/dp.h | 6 +++ drivers/net/wireless/ath/ath12k/dp_cmn.h | 18 ++++++++ drivers/net/wireless/ath/ath12k/dp_htt.c | 59 ++++++++++++++---------- drivers/net/wireless/ath/ath12k/mac.c | 11 +++-- 5 files changed, 65 insertions(+), 49 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index d11bc1cae9863..49637b56b8f9e 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -659,23 +659,6 @@ struct ath12k_debug { bool extd_rx_stats; }; -struct ath12k_per_peer_tx_stats { - u32 succ_bytes; - u32 retry_bytes; - u32 failed_bytes; - u32 duration; - u16 succ_pkts; - u16 retry_pkts; - u16 failed_pkts; - u16 ru_start; - u16 ru_tones; - u8 ba_fails; - u8 ppdu_type; - u32 mu_grpid; - u32 mu_pos; - bool is_ampdu; -}; - struct ath12k_pdev_rssi_offsets { s32 temp_offset; s8 min_nf_dbm; @@ -801,9 +784,6 @@ struct ath12k { struct ath12k_wow wow; struct completion target_suspend; bool target_suspend_ack; - struct ath12k_per_peer_tx_stats peer_tx_stats; - struct list_head ppdu_stats_info; - u32 ppdu_stat_list_depth; struct ath12k_per_peer_tx_stats cached_stats; u32 last_ppdu_id; diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 30a101e797fb5..d592974f8e066 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -156,6 +156,12 @@ struct ath12k_pdev_dp { struct ieee80211_hw *hw; u8 hw_link_id; + /* Protects ppdu stats */ + spinlock_t ppdu_list_lock; + struct ath12k_per_peer_tx_stats peer_tx_stats; + struct list_head ppdu_stats_info; + u32 ppdu_stat_list_depth; + struct dp_srng rxdma_mon_dst_ring[MAX_RXDMA_PER_PDEV]; struct dp_srng tx_mon_dst_ring[MAX_RXDMA_PER_PDEV]; diff --git a/drivers/net/wireless/ath/ath12k/dp_cmn.h b/drivers/net/wireless/ath/ath12k/dp_cmn.h index 3dc61d1a41625..243fb5a680167 100644 --- a/drivers/net/wireless/ath/ath12k/dp_cmn.h +++ b/drivers/net/wireless/ath/ath12k/dp_cmn.h @@ -34,6 +34,24 @@ struct ath12k_dp_vif { struct ath12k_dp_link_vif dp_link_vif[ATH12K_NUM_MAX_LINKS]; }; +/* TODO: Move this to a separate dp_stats file */ +struct ath12k_per_peer_tx_stats { + u32 succ_bytes; + u32 retry_bytes; + u32 failed_bytes; + u32 duration; + u16 succ_pkts; + u16 retry_pkts; + u16 failed_pkts; + u16 ru_start; + u16 ru_tones; + u8 ba_fails; + u8 ppdu_type; + u32 mu_grpid; + u32 mu_pos; + bool is_ampdu; +}; + static inline struct ath12k_dp_link_vif * ath12k_dp_vif_to_dp_link_vif(struct ath12k_dp_vif *dp_vif, u8 link_id) { diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index 267220f43fd2c..1a0d3e4ac8bb7 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -183,14 +183,15 @@ int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len, } static void -ath12k_update_per_peer_tx_stats(struct ath12k *ar, +ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, struct htt_ppdu_stats *ppdu_stats, u8 user) { - struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; struct ath12k_peer *peer; struct ath12k_link_sta *arsta; struct htt_ppdu_stats_user_rate *user_rate; - struct ath12k_per_peer_tx_stats *peer_stats = &ar->peer_tx_stats; + struct ath12k_per_peer_tx_stats *peer_stats = &dp_pdev->peer_tx_stats; struct htt_ppdu_user_stats *usr_stats = &ppdu_stats->user_stats[user]; struct htt_ppdu_stats_common *common = &ppdu_stats->common; int ret; @@ -360,34 +361,34 @@ ath12k_update_per_peer_tx_stats(struct ath12k *ar, rcu_read_unlock(); } -static void ath12k_htt_update_ppdu_stats(struct ath12k *ar, +static void ath12k_htt_update_ppdu_stats(struct ath12k_pdev_dp *dp_pdev, struct htt_ppdu_stats *ppdu_stats) { u8 user; for (user = 0; user < HTT_PPDU_STATS_MAX_USERS - 1; user++) - ath12k_update_per_peer_tx_stats(ar, ppdu_stats, user); + ath12k_update_per_peer_tx_stats(dp_pdev, ppdu_stats, user); } static -struct htt_ppdu_stats_info *ath12k_dp_htt_get_ppdu_desc(struct ath12k *ar, +struct htt_ppdu_stats_info *ath12k_dp_htt_get_ppdu_desc(struct ath12k_pdev_dp *dp_pdev, u32 ppdu_id) { struct htt_ppdu_stats_info *ppdu_info; - lockdep_assert_held(&ar->data_lock); - if (!list_empty(&ar->ppdu_stats_info)) { - list_for_each_entry(ppdu_info, &ar->ppdu_stats_info, list) { + lockdep_assert_held(&dp_pdev->ppdu_list_lock); + if (!list_empty(&dp_pdev->ppdu_stats_info)) { + list_for_each_entry(ppdu_info, &dp_pdev->ppdu_stats_info, list) { if (ppdu_info->ppdu_id == ppdu_id) return ppdu_info; } - if (ar->ppdu_stat_list_depth > HTT_PPDU_DESC_MAX_DEPTH) { - ppdu_info = list_first_entry(&ar->ppdu_stats_info, + if (dp_pdev->ppdu_stat_list_depth > HTT_PPDU_DESC_MAX_DEPTH) { + ppdu_info = list_first_entry(&dp_pdev->ppdu_stats_info, typeof(*ppdu_info), list); list_del(&ppdu_info->list); - ar->ppdu_stat_list_depth--; - ath12k_htt_update_ppdu_stats(ar, &ppdu_info->ppdu_stats); + dp_pdev->ppdu_stat_list_depth--; + ath12k_htt_update_ppdu_stats(dp_pdev, &ppdu_info->ppdu_stats); kfree(ppdu_info); } } @@ -396,8 +397,8 @@ struct htt_ppdu_stats_info *ath12k_dp_htt_get_ppdu_desc(struct ath12k *ar, if (!ppdu_info) return NULL; - list_add_tail(&ppdu_info->list, &ar->ppdu_stats_info); - ar->ppdu_stat_list_depth++; + list_add_tail(&ppdu_info->list, &dp_pdev->ppdu_stats_info); + dp_pdev->ppdu_stat_list_depth++; return ppdu_info; } @@ -435,14 +436,15 @@ static void ath12k_copy_to_bar(struct ath12k_peer *peer, static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, struct sk_buff *skb) { + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_htt_ppdu_stats_msg *msg; struct htt_ppdu_stats_info *ppdu_info; struct ath12k_peer *peer = NULL; struct htt_ppdu_user_stats *usr_stats = NULL; u32 peer_id = 0; - struct ath12k *ar; + struct ath12k_pdev_dp *dp_pdev; int ret, i; - u8 pdev_id; + u8 pdev_id, pdev_idx; u32 ppdu_id, len; msg = (struct ath12k_htt_ppdu_stats_msg *)skb->data; @@ -457,17 +459,24 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, pdev_id = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PDEV_ID); ppdu_id = le32_to_cpu(msg->ppdu_id); + pdev_idx = DP_HW2SW_MACID(pdev_id); + if (pdev_idx >= MAX_RADIOS) { + ath12k_warn(ab, "HTT PPDU STATS invalid pdev id %u", pdev_id); + return -EINVAL; + } + rcu_read_lock(); - ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id); - if (!ar) { + + dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); + if (!dp_pdev) { ret = -EINVAL; goto exit; } - spin_lock_bh(&ar->data_lock); - ppdu_info = ath12k_dp_htt_get_ppdu_desc(ar, ppdu_id); + spin_lock_bh(&dp_pdev->ppdu_list_lock); + ppdu_info = ath12k_dp_htt_get_ppdu_desc(dp_pdev, ppdu_id); if (!ppdu_info) { - spin_unlock_bh(&ar->data_lock); + spin_unlock_bh(&dp_pdev->ppdu_list_lock); ret = -EINVAL; goto exit; } @@ -477,13 +486,13 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, ath12k_htt_tlv_ppdu_stats_parse, (void *)ppdu_info); if (ret) { - spin_unlock_bh(&ar->data_lock); + spin_unlock_bh(&dp_pdev->ppdu_list_lock); ath12k_warn(ab, "Failed to parse tlv %d\n", ret); goto exit; } if (ppdu_info->ppdu_stats.common.num_users >= HTT_PPDU_STATS_MAX_USERS) { - spin_unlock_bh(&ar->data_lock); + spin_unlock_bh(&dp_pdev->ppdu_list_lock); ath12k_warn(ab, "HTT PPDU STATS event has unexpected num_users %u, should be smaller than %u\n", ppdu_info->ppdu_stats.common.num_users, @@ -531,7 +540,7 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, } } - spin_unlock_bh(&ar->data_lock); + spin_unlock_bh(&dp_pdev->ppdu_list_lock); exit: rcu_read_unlock(); diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 06b28f15f0068..5c963b6efc9be 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -9628,6 +9628,7 @@ int ath12k_mac_rfkill_enable_radio(struct ath12k *ar, bool enable) static void ath12k_mac_stop(struct ath12k *ar) { + struct ath12k_pdev_dp *dp_pdev = &ar->dp; struct ath12k_hw *ah = ar->ah; struct htt_ppdu_stats_info *ppdu_stats, *tmp; struct ath12k_wmi_scan_chan_list_arg *arg; @@ -9652,13 +9653,14 @@ static void ath12k_mac_stop(struct ath12k *ar) ar->state_11d = ATH12K_11D_IDLE; complete(&ar->completed_11d_scan); - spin_lock_bh(&ar->data_lock); - - list_for_each_entry_safe(ppdu_stats, tmp, &ar->ppdu_stats_info, list) { + spin_lock_bh(&dp_pdev->ppdu_list_lock); + list_for_each_entry_safe(ppdu_stats, tmp, &dp_pdev->ppdu_stats_info, list) { list_del(&ppdu_stats->list); kfree(ppdu_stats); } + spin_unlock_bh(&dp_pdev->ppdu_list_lock); + spin_lock_bh(&ar->data_lock); while ((arg = list_first_entry_or_null(&ar->regd_channel_update_queue, struct ath12k_wmi_scan_chan_list_arg, list))) { @@ -14550,8 +14552,9 @@ static void ath12k_mac_setup(struct ath12k *ar) ar->vdev_id_11d_scan = ATH12K_11D_INVALID_VDEV_ID; spin_lock_init(&ar->data_lock); + spin_lock_init(&ar->dp.ppdu_list_lock); INIT_LIST_HEAD(&ar->arvifs); - INIT_LIST_HEAD(&ar->ppdu_stats_info); + INIT_LIST_HEAD(&ar->dp.ppdu_stats_info); init_completion(&ar->vdev_setup_done); init_completion(&ar->vdev_delete_done); From 9b278ee3405d21d37cf90b6637b51c4272938010 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:28 +0530 Subject: [PATCH 050/140] wifi: ath12k: Move srng config and hal_ops to hw specific hal files Move srng config and hal_ops from common hal file to hw specific hal files, since these implementations are specific and configurable for each hardware Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-2-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.c | 474 +----------------- .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 329 ++++++++++++ .../wireless/ath/ath12k/wifi7/hal_qcn9274.h | 3 + .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 344 +++++++++++++ .../wireless/ath/ath12k/wifi7/hal_wcn7850.h | 3 + 5 files changed, 681 insertions(+), 472 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index a14a7d8dc69f2..4ff906854970f 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -12,210 +12,7 @@ #include "wifi7/hal_qcn9274.h" #include "wifi7/hal_wcn7850.h" -static const struct hal_srng_config hw_srng_config_template[] = { - /* TODO: max_rings can populated by querying HW capabilities */ - [HAL_REO_DST] = { - .start_ring_id = HAL_SRNG_RING_ID_REO2SW1, - .max_rings = 8, - .entry_size = sizeof(struct hal_reo_dest_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_REO_REO2SW1_RING_BASE_MSB_RING_SIZE, - }, - [HAL_REO_EXCEPTION] = { - /* Designating REO2SW0 ring as exception ring. - * Any of theREO2SW rings can be used as exception ring. - */ - .start_ring_id = HAL_SRNG_RING_ID_REO2SW0, - .max_rings = 1, - .entry_size = sizeof(struct hal_reo_dest_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_REO_REO2SW0_RING_BASE_MSB_RING_SIZE, - }, - [HAL_REO_REINJECT] = { - .start_ring_id = HAL_SRNG_RING_ID_SW2REO, - .max_rings = 4, - .entry_size = sizeof(struct hal_reo_entrance_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_REO_SW2REO_RING_BASE_MSB_RING_SIZE, - }, - [HAL_REO_CMD] = { - .start_ring_id = HAL_SRNG_RING_ID_REO_CMD, - .max_rings = 1, - .entry_size = (sizeof(struct hal_tlv_64_hdr) + - sizeof(struct hal_reo_get_queue_stats)) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_REO_CMD_RING_BASE_MSB_RING_SIZE, - }, - [HAL_REO_STATUS] = { - .start_ring_id = HAL_SRNG_RING_ID_REO_STATUS, - .max_rings = 1, - .entry_size = (sizeof(struct hal_tlv_64_hdr) + - sizeof(struct hal_reo_get_queue_stats_status)) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_REO_STATUS_RING_BASE_MSB_RING_SIZE, - }, - [HAL_TCL_DATA] = { - .start_ring_id = HAL_SRNG_RING_ID_SW2TCL1, - .max_rings = 6, - .entry_size = sizeof(struct hal_tcl_data_cmd) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, - }, - [HAL_TCL_CMD] = { - .start_ring_id = HAL_SRNG_RING_ID_SW2TCL_CMD, - .max_rings = 1, - .entry_size = sizeof(struct hal_tcl_gse_cmd) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_SW2TCL1_CMD_RING_BASE_MSB_RING_SIZE, - }, - [HAL_TCL_STATUS] = { - .start_ring_id = HAL_SRNG_RING_ID_TCL_STATUS, - .max_rings = 1, - .entry_size = (sizeof(struct hal_tlv_hdr) + - sizeof(struct hal_tcl_status_ring)) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_TCL_STATUS_RING_BASE_MSB_RING_SIZE, - }, - [HAL_CE_SRC] = { - .start_ring_id = HAL_SRNG_RING_ID_CE0_SRC, - .max_rings = 16, - .entry_size = sizeof(struct hal_ce_srng_src_desc) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_CE_SRC_RING_BASE_MSB_RING_SIZE, - }, - [HAL_CE_DST] = { - .start_ring_id = HAL_SRNG_RING_ID_CE0_DST, - .max_rings = 16, - .entry_size = sizeof(struct hal_ce_srng_dest_desc) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_CE_DST_RING_BASE_MSB_RING_SIZE, - }, - [HAL_CE_DST_STATUS] = { - .start_ring_id = HAL_SRNG_RING_ID_CE0_DST_STATUS, - .max_rings = 16, - .entry_size = sizeof(struct hal_ce_srng_dst_status_desc) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_CE_DST_STATUS_RING_BASE_MSB_RING_SIZE, - }, - [HAL_WBM_IDLE_LINK] = { - .start_ring_id = HAL_SRNG_RING_ID_WBM_IDLE_LINK, - .max_rings = 1, - .entry_size = sizeof(struct hal_wbm_link_desc) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE, - }, - [HAL_SW2WBM_RELEASE] = { - .start_ring_id = HAL_SRNG_RING_ID_WBM_SW0_RELEASE, - .max_rings = 2, - .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_SW2WBM_RELEASE_RING_BASE_MSB_RING_SIZE, - }, - [HAL_WBM2SW_RELEASE] = { - .start_ring_id = HAL_SRNG_RING_ID_WBM2SW0_RELEASE, - .max_rings = 8, - .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_UMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE, - }, - [HAL_RXDMA_BUF] = { - .start_ring_id = HAL_SRNG_SW2RXDMA_BUF0, - .max_rings = 1, - .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_DMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, - [HAL_RXDMA_DST] = { - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_RXDMA2SW0, - .max_rings = 0, - .entry_size = 0, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, - [HAL_RXDMA_MONITOR_BUF] = { - .start_ring_id = HAL_SRNG_SW2RXMON_BUF0, - .max_rings = 1, - .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, - [HAL_RXDMA_MONITOR_STATUS] = { - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_STATBUF, - .max_rings = 1, - .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, - [HAL_RXDMA_MONITOR_DESC] = { 0, }, - [HAL_RXDMA_DIR_BUF] = { - .start_ring_id = HAL_SRNG_RING_ID_RXDMA_DIR_BUF, - .max_rings = 2, - .entry_size = 8 >> 2, /* TODO: Define the struct */ - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, - [HAL_PPE2TCL] = { - .start_ring_id = HAL_SRNG_RING_ID_PPE2TCL1, - .max_rings = 1, - .entry_size = sizeof(struct hal_tcl_entrance_from_ppe_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, - }, - [HAL_PPE_RELEASE] = { - .start_ring_id = HAL_SRNG_RING_ID_WBM_PPE_RELEASE, - .max_rings = 1, - .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_WBM2PPE_RELEASE_RING_BASE_MSB_RING_SIZE, - }, - [HAL_TX_MONITOR_BUF] = { - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2TXMON_BUF0, - .max_rings = 1, - .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, - [HAL_RXDMA_MONITOR_DST] = { - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXMON_BUF0, - .max_rings = 1, - .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, - [HAL_TX_MONITOR_DST] = { - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_TXMON2SW0_BUF0, - .max_rings = 1, - .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - } -}; - -static const struct ath12k_hal_tcl_to_wbm_rbm_map +const struct ath12k_hal_tcl_to_wbm_rbm_map ath12k_hal_qcn9274_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX] = { { .wbm_ring_num = 0, @@ -235,7 +32,7 @@ ath12k_hal_qcn9274_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX] = { } }; -static const struct ath12k_hal_tcl_to_wbm_rbm_map +const struct ath12k_hal_tcl_to_wbm_rbm_map ath12k_hal_wcn7850_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX] = { { .wbm_ring_num = 0, @@ -296,273 +93,6 @@ static unsigned int ath12k_hal_reo1_ring_misc_offset(struct ath12k_base *ab) return HAL_REO1_RING_MISC(ab) - HAL_REO1_RING_BASE_LSB(ab); } -static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) -{ - struct ath12k_hal *hal = &ab->hal; - struct hal_srng_config *s; - - hal->srng_config = kmemdup(hw_srng_config_template, - sizeof(hw_srng_config_template), - GFP_KERNEL); - if (!hal->srng_config) - return -ENOMEM; - - s = &hal->srng_config[HAL_REO_DST]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP; - s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); - s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP; - - s = &hal->srng_config[HAL_REO_EXCEPTION]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP; - - s = &hal->srng_config[HAL_REO_REINJECT]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP; - s->reg_size[0] = HAL_SW2REO1_RING_BASE_LSB(ab) - HAL_SW2REO_RING_BASE_LSB(ab); - s->reg_size[1] = HAL_SW2REO1_RING_HP - HAL_SW2REO_RING_HP; - - s = &hal->srng_config[HAL_REO_CMD]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP; - - s = &hal->srng_config[HAL_REO_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP; - - s = &hal->srng_config[HAL_TCL_DATA]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP; - s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(ab) - HAL_TCL1_RING_BASE_LSB(ab); - s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP; - - s = &hal->srng_config[HAL_TCL_CMD]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP; - - s = &hal->srng_config[HAL_TCL_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP; - - s = &hal->srng_config[HAL_CE_SRC]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); - - s = &hal->srng_config[HAL_CE_DST]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - - s = &hal->srng_config[HAL_CE_DST_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + - HAL_CE_DST_STATUS_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - - s = &hal->srng_config[HAL_WBM_IDLE_LINK]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP; - - s = &hal->srng_config[HAL_SW2WBM_RELEASE]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP; - s->reg_size[0] = HAL_WBM_SW1_RELEASE_RING_BASE_LSB(ab) - - HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); - s->reg_size[1] = HAL_WBM_SW1_RELEASE_RING_HP - HAL_WBM_SW_RELEASE_RING_HP; - - s = &hal->srng_config[HAL_WBM2SW_RELEASE]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP; - s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) - - HAL_WBM0_RELEASE_RING_BASE_LSB(ab); - s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP; - - /* Some LMAC rings are not accessed from the host: - * RXDMA_BUG, RXDMA_DST, RXDMA_MONITOR_BUF, RXDMA_MONITOR_STATUS, - * RXDMA_MONITOR_DST, RXDMA_MONITOR_DESC, RXDMA_DIR_BUF_SRC, - * RXDMA_RX_MONITOR_BUF, TX_MONITOR_BUF, TX_MONITOR_DST, SW2RXDMA - */ - s = &hal->srng_config[HAL_PPE2TCL]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_PPE2TCL1_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_PPE2TCL1_RING_HP; - - s = &hal->srng_config[HAL_PPE_RELEASE]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_PPE_RELEASE_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_PPE_RELEASE_RING_HP; - - return 0; -} - -const struct hal_ops hal_qcn9274_ops = { - .create_srng_config = ath12k_hal_srng_create_config_qcn9274, - .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, - .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcn9274, - .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_qcn9274, - .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcn9274, - .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcn9274, - .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_qcn9274, - .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_qcn9274, - .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_qcn9274, - .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274, - .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, - .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, -}; -EXPORT_SYMBOL(hal_qcn9274_ops); - -static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) -{ - struct ath12k_hal *hal = &ab->hal; - struct hal_srng_config *s; - - hal->srng_config = kmemdup(hw_srng_config_template, - sizeof(hw_srng_config_template), - GFP_KERNEL); - if (!hal->srng_config) - return -ENOMEM; - - s = &hal->srng_config[HAL_REO_DST]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP; - s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); - s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP; - - s = &hal->srng_config[HAL_REO_EXCEPTION]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP; - - s = &hal->srng_config[HAL_REO_REINJECT]; - s->max_rings = 1; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP; - - s = &hal->srng_config[HAL_REO_CMD]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP; - - s = &hal->srng_config[HAL_REO_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP; - - s = &hal->srng_config[HAL_TCL_DATA]; - s->max_rings = 5; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP; - s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(ab) - HAL_TCL1_RING_BASE_LSB(ab); - s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP; - - s = &hal->srng_config[HAL_TCL_CMD]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP; - - s = &hal->srng_config[HAL_TCL_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP; - - s = &hal->srng_config[HAL_CE_SRC]; - s->max_rings = 12; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); - - s = &hal->srng_config[HAL_CE_DST]; - s->max_rings = 12; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - - s = &hal->srng_config[HAL_CE_DST_STATUS]; - s->max_rings = 12; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + - HAL_CE_DST_STATUS_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - - s = &hal->srng_config[HAL_WBM_IDLE_LINK]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP; - - s = &hal->srng_config[HAL_SW2WBM_RELEASE]; - s->max_rings = 1; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP; - - s = &hal->srng_config[HAL_WBM2SW_RELEASE]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP; - s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) - - HAL_WBM0_RELEASE_RING_BASE_LSB(ab); - s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP; - - s = &hal->srng_config[HAL_RXDMA_BUF]; - s->max_rings = 2; - s->mac_type = ATH12K_HAL_SRNG_PMAC; - - s = &hal->srng_config[HAL_RXDMA_DST]; - s->max_rings = 1; - s->entry_size = sizeof(struct hal_reo_entrance_ring) >> 2; - - /* below rings are not used */ - s = &hal->srng_config[HAL_RXDMA_DIR_BUF]; - s->max_rings = 0; - - s = &hal->srng_config[HAL_PPE2TCL]; - s->max_rings = 0; - - s = &hal->srng_config[HAL_PPE_RELEASE]; - s->max_rings = 0; - - s = &hal->srng_config[HAL_TX_MONITOR_BUF]; - s->max_rings = 0; - - s = &hal->srng_config[HAL_TX_MONITOR_DST]; - s->max_rings = 0; - - s = &hal->srng_config[HAL_PPE2TCL]; - s->max_rings = 0; - - return 0; -} - -const struct hal_ops hal_wcn7850_ops = { - .create_srng_config = ath12k_hal_srng_create_config_wcn7850, - .tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map, - .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_wcn7850, - .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_wcn7850, - .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_wcn7850, - .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_wcn7850, - .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_wcn7850, - .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_wcn7850, - .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_wcn7850, - .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850, - .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, - .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, - .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, -}; -EXPORT_SYMBOL(hal_wcn7850_ops); - static int ath12k_hal_alloc_cont_rdp(struct ath12k_base *ab) { struct ath12k_hal *hal = &ab->hal; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 2e84c830d9b2b..c98ffc991ad81 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -6,6 +6,209 @@ #include "hal_desc.h" #include "hal_qcn9274.h" +static const struct hal_srng_config hw_srng_config_template[] = { + /* TODO: max_rings can populated by querying HW capabilities */ + [HAL_REO_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_REO2SW1, + .max_rings = 8, + .entry_size = sizeof(struct hal_reo_dest_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_REO_REO2SW1_RING_BASE_MSB_RING_SIZE, + }, + [HAL_REO_EXCEPTION] = { + /* Designating REO2SW0 ring as exception ring. + * Any of theREO2SW rings can be used as exception ring. + */ + .start_ring_id = HAL_SRNG_RING_ID_REO2SW0, + .max_rings = 1, + .entry_size = sizeof(struct hal_reo_dest_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_REO_REO2SW0_RING_BASE_MSB_RING_SIZE, + }, + [HAL_REO_REINJECT] = { + .start_ring_id = HAL_SRNG_RING_ID_SW2REO, + .max_rings = 4, + .entry_size = sizeof(struct hal_reo_entrance_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_REO_SW2REO_RING_BASE_MSB_RING_SIZE, + }, + [HAL_REO_CMD] = { + .start_ring_id = HAL_SRNG_RING_ID_REO_CMD, + .max_rings = 1, + .entry_size = (sizeof(struct hal_tlv_64_hdr) + + sizeof(struct hal_reo_get_queue_stats)) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_REO_CMD_RING_BASE_MSB_RING_SIZE, + }, + [HAL_REO_STATUS] = { + .start_ring_id = HAL_SRNG_RING_ID_REO_STATUS, + .max_rings = 1, + .entry_size = (sizeof(struct hal_tlv_64_hdr) + + sizeof(struct hal_reo_get_queue_stats_status)) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_REO_STATUS_RING_BASE_MSB_RING_SIZE, + }, + [HAL_TCL_DATA] = { + .start_ring_id = HAL_SRNG_RING_ID_SW2TCL1, + .max_rings = 6, + .entry_size = sizeof(struct hal_tcl_data_cmd) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, + }, + [HAL_TCL_CMD] = { + .start_ring_id = HAL_SRNG_RING_ID_SW2TCL_CMD, + .max_rings = 1, + .entry_size = sizeof(struct hal_tcl_gse_cmd) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_SW2TCL1_CMD_RING_BASE_MSB_RING_SIZE, + }, + [HAL_TCL_STATUS] = { + .start_ring_id = HAL_SRNG_RING_ID_TCL_STATUS, + .max_rings = 1, + .entry_size = (sizeof(struct hal_tlv_hdr) + + sizeof(struct hal_tcl_status_ring)) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_TCL_STATUS_RING_BASE_MSB_RING_SIZE, + }, + [HAL_CE_SRC] = { + .start_ring_id = HAL_SRNG_RING_ID_CE0_SRC, + .max_rings = 16, + .entry_size = sizeof(struct hal_ce_srng_src_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_CE_SRC_RING_BASE_MSB_RING_SIZE, + }, + [HAL_CE_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_CE0_DST, + .max_rings = 16, + .entry_size = sizeof(struct hal_ce_srng_dest_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_CE_DST_RING_BASE_MSB_RING_SIZE, + }, + [HAL_CE_DST_STATUS] = { + .start_ring_id = HAL_SRNG_RING_ID_CE0_DST_STATUS, + .max_rings = 16, + .entry_size = sizeof(struct hal_ce_srng_dst_status_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_CE_DST_STATUS_RING_BASE_MSB_RING_SIZE, + }, + [HAL_WBM_IDLE_LINK] = { + .start_ring_id = HAL_SRNG_RING_ID_WBM_IDLE_LINK, + .max_rings = 1, + .entry_size = sizeof(struct hal_wbm_link_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE, + }, + [HAL_SW2WBM_RELEASE] = { + .start_ring_id = HAL_SRNG_RING_ID_WBM_SW0_RELEASE, + .max_rings = 2, + .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_SW2WBM_RELEASE_RING_BASE_MSB_RING_SIZE, + }, + [HAL_WBM2SW_RELEASE] = { + .start_ring_id = HAL_SRNG_RING_ID_WBM2SW0_RELEASE, + .max_rings = 8, + .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE, + }, + [HAL_RXDMA_BUF] = { + .start_ring_id = HAL_SRNG_SW2RXDMA_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_DMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_RXDMA2SW0, + .max_rings = 0, + .entry_size = 0, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_MONITOR_BUF] = { + .start_ring_id = HAL_SRNG_SW2RXMON_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_MONITOR_STATUS] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_STATBUF, + .max_rings = 1, + .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_MONITOR_DESC] = { 0, }, + [HAL_RXDMA_DIR_BUF] = { + .start_ring_id = HAL_SRNG_RING_ID_RXDMA_DIR_BUF, + .max_rings = 2, + .entry_size = 8 >> 2, /* TODO: Define the struct */ + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_PPE2TCL] = { + .start_ring_id = HAL_SRNG_RING_ID_PPE2TCL1, + .max_rings = 1, + .entry_size = sizeof(struct hal_tcl_entrance_from_ppe_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, + }, + [HAL_PPE_RELEASE] = { + .start_ring_id = HAL_SRNG_RING_ID_WBM_PPE_RELEASE, + .max_rings = 1, + .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_WBM2PPE_RELEASE_RING_BASE_MSB_RING_SIZE, + }, + [HAL_TX_MONITOR_BUF] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2TXMON_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_MONITOR_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXMON_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_TX_MONITOR_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_TXMON2SW0_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + } +}; + static inline bool ath12k_hal_rx_desc_get_first_msdu_qcn9274(struct hal_rx_desc *desc) { @@ -367,3 +570,129 @@ void ath12k_hal_extract_rx_desc_data_qcn9274(struct hal_rx_desc_data *rx_desc_da rx_desc_data->is_decrypted = ath12k_hal_rx_h_is_decrypted_qcn9274(rx_desc); rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_qcn9274(rx_desc); } + +static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) +{ + struct ath12k_hal *hal = &ab->hal; + struct hal_srng_config *s; + + hal->srng_config = kmemdup(hw_srng_config_template, + sizeof(hw_srng_config_template), + GFP_KERNEL); + if (!hal->srng_config) + return -ENOMEM; + + s = &hal->srng_config[HAL_REO_DST]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP; + s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); + s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP; + + s = &hal->srng_config[HAL_REO_EXCEPTION]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP; + + s = &hal->srng_config[HAL_REO_REINJECT]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP; + s->reg_size[0] = HAL_SW2REO1_RING_BASE_LSB(ab) - HAL_SW2REO_RING_BASE_LSB(ab); + s->reg_size[1] = HAL_SW2REO1_RING_HP - HAL_SW2REO_RING_HP; + + s = &hal->srng_config[HAL_REO_CMD]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP; + + s = &hal->srng_config[HAL_REO_STATUS]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP; + + s = &hal->srng_config[HAL_TCL_DATA]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP; + s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(ab) - HAL_TCL1_RING_BASE_LSB(ab); + s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP; + + s = &hal->srng_config[HAL_TCL_CMD]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP; + + s = &hal->srng_config[HAL_TCL_STATUS]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP; + + s = &hal->srng_config[HAL_CE_SRC]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); + + s = &hal->srng_config[HAL_CE_DST]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + + s = &hal->srng_config[HAL_CE_DST_STATUS]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + + HAL_CE_DST_STATUS_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + + s = &hal->srng_config[HAL_WBM_IDLE_LINK]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP; + + s = &hal->srng_config[HAL_SW2WBM_RELEASE]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP; + s->reg_size[0] = HAL_WBM_SW1_RELEASE_RING_BASE_LSB(ab) - + HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); + s->reg_size[1] = HAL_WBM_SW1_RELEASE_RING_HP - HAL_WBM_SW_RELEASE_RING_HP; + + s = &hal->srng_config[HAL_WBM2SW_RELEASE]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP; + s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) - + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); + s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP; + + /* Some LMAC rings are not accessed from the host: + * RXDMA_BUG, RXDMA_DST, RXDMA_MONITOR_BUF, RXDMA_MONITOR_STATUS, + * RXDMA_MONITOR_DST, RXDMA_MONITOR_DESC, RXDMA_DIR_BUF_SRC, + * RXDMA_RX_MONITOR_BUF, TX_MONITOR_BUF, TX_MONITOR_DST, SW2RXDMA + */ + s = &hal->srng_config[HAL_PPE2TCL]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_PPE2TCL1_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_PPE2TCL1_RING_HP; + + s = &hal->srng_config[HAL_PPE_RELEASE]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_PPE_RELEASE_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_PPE_RELEASE_RING_HP; + + return 0; +} + +const struct hal_ops hal_qcn9274_ops = { + .create_srng_config = ath12k_hal_srng_create_config_qcn9274, + .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, + .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcn9274, + .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_qcn9274, + .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcn9274, + .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcn9274, + .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_qcn9274, + .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_qcn9274, + .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_qcn9274, + .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274, + .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, + .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, +}; +EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h index 9a918824e093f..1563854b5b6a5 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h @@ -12,6 +12,9 @@ #include "../hal.h" #include "hal_rx.h" +extern const struct ath12k_hal_tcl_to_wbm_rbm_map +ath12k_hal_qcn9274_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX]; + u8 ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_copy_end_tlv_qcn9274(struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 0fa1d9fad2e19..2e88ac0ae7971 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -7,6 +7,209 @@ #include "hal_desc.h" #include "hal_wcn7850.h" +static const struct hal_srng_config hw_srng_config_template[] = { + /* TODO: max_rings can populated by querying HW capabilities */ + [HAL_REO_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_REO2SW1, + .max_rings = 8, + .entry_size = sizeof(struct hal_reo_dest_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_REO_REO2SW1_RING_BASE_MSB_RING_SIZE, + }, + [HAL_REO_EXCEPTION] = { + /* Designating REO2SW0 ring as exception ring. + * Any of theREO2SW rings can be used as exception ring. + */ + .start_ring_id = HAL_SRNG_RING_ID_REO2SW0, + .max_rings = 1, + .entry_size = sizeof(struct hal_reo_dest_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_REO_REO2SW0_RING_BASE_MSB_RING_SIZE, + }, + [HAL_REO_REINJECT] = { + .start_ring_id = HAL_SRNG_RING_ID_SW2REO, + .max_rings = 4, + .entry_size = sizeof(struct hal_reo_entrance_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_REO_SW2REO_RING_BASE_MSB_RING_SIZE, + }, + [HAL_REO_CMD] = { + .start_ring_id = HAL_SRNG_RING_ID_REO_CMD, + .max_rings = 1, + .entry_size = (sizeof(struct hal_tlv_64_hdr) + + sizeof(struct hal_reo_get_queue_stats)) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_REO_CMD_RING_BASE_MSB_RING_SIZE, + }, + [HAL_REO_STATUS] = { + .start_ring_id = HAL_SRNG_RING_ID_REO_STATUS, + .max_rings = 1, + .entry_size = (sizeof(struct hal_tlv_64_hdr) + + sizeof(struct hal_reo_get_queue_stats_status)) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_REO_STATUS_RING_BASE_MSB_RING_SIZE, + }, + [HAL_TCL_DATA] = { + .start_ring_id = HAL_SRNG_RING_ID_SW2TCL1, + .max_rings = 6, + .entry_size = sizeof(struct hal_tcl_data_cmd) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, + }, + [HAL_TCL_CMD] = { + .start_ring_id = HAL_SRNG_RING_ID_SW2TCL_CMD, + .max_rings = 1, + .entry_size = sizeof(struct hal_tcl_gse_cmd) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_SW2TCL1_CMD_RING_BASE_MSB_RING_SIZE, + }, + [HAL_TCL_STATUS] = { + .start_ring_id = HAL_SRNG_RING_ID_TCL_STATUS, + .max_rings = 1, + .entry_size = (sizeof(struct hal_tlv_hdr) + + sizeof(struct hal_tcl_status_ring)) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_TCL_STATUS_RING_BASE_MSB_RING_SIZE, + }, + [HAL_CE_SRC] = { + .start_ring_id = HAL_SRNG_RING_ID_CE0_SRC, + .max_rings = 16, + .entry_size = sizeof(struct hal_ce_srng_src_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_CE_SRC_RING_BASE_MSB_RING_SIZE, + }, + [HAL_CE_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_CE0_DST, + .max_rings = 16, + .entry_size = sizeof(struct hal_ce_srng_dest_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_CE_DST_RING_BASE_MSB_RING_SIZE, + }, + [HAL_CE_DST_STATUS] = { + .start_ring_id = HAL_SRNG_RING_ID_CE0_DST_STATUS, + .max_rings = 16, + .entry_size = sizeof(struct hal_ce_srng_dst_status_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_CE_DST_STATUS_RING_BASE_MSB_RING_SIZE, + }, + [HAL_WBM_IDLE_LINK] = { + .start_ring_id = HAL_SRNG_RING_ID_WBM_IDLE_LINK, + .max_rings = 1, + .entry_size = sizeof(struct hal_wbm_link_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE, + }, + [HAL_SW2WBM_RELEASE] = { + .start_ring_id = HAL_SRNG_RING_ID_WBM_SW0_RELEASE, + .max_rings = 2, + .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_SW2WBM_RELEASE_RING_BASE_MSB_RING_SIZE, + }, + [HAL_WBM2SW_RELEASE] = { + .start_ring_id = HAL_SRNG_RING_ID_WBM2SW0_RELEASE, + .max_rings = 8, + .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_UMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE, + }, + [HAL_RXDMA_BUF] = { + .start_ring_id = HAL_SRNG_SW2RXDMA_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_DMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_RXDMA2SW0, + .max_rings = 0, + .entry_size = 0, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_MONITOR_BUF] = { + .start_ring_id = HAL_SRNG_SW2RXMON_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_MONITOR_STATUS] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_STATBUF, + .max_rings = 1, + .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_MONITOR_DESC] = { 0, }, + [HAL_RXDMA_DIR_BUF] = { + .start_ring_id = HAL_SRNG_RING_ID_RXDMA_DIR_BUF, + .max_rings = 2, + .entry_size = 8 >> 2, /* TODO: Define the struct */ + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_PPE2TCL] = { + .start_ring_id = HAL_SRNG_RING_ID_PPE2TCL1, + .max_rings = 1, + .entry_size = sizeof(struct hal_tcl_entrance_from_ppe_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, + }, + [HAL_PPE_RELEASE] = { + .start_ring_id = HAL_SRNG_RING_ID_WBM_PPE_RELEASE, + .max_rings = 1, + .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_WBM2PPE_RELEASE_RING_BASE_MSB_RING_SIZE, + }, + [HAL_TX_MONITOR_BUF] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2TXMON_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_SRC, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_RXDMA_MONITOR_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXMON_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + }, + [HAL_TX_MONITOR_DST] = { + .start_ring_id = HAL_SRNG_RING_ID_WMAC1_TXMON2SW0_BUF0, + .max_rings = 1, + .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, + .mac_type = ATH12K_HAL_SRNG_PMAC, + .ring_dir = HAL_SRNG_DIR_DST, + .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, + } +}; + static inline bool ath12k_hal_rx_desc_get_first_msdu_wcn7850(struct hal_rx_desc *desc) { @@ -362,3 +565,144 @@ void ath12k_hal_extract_rx_desc_data_wcn7850(struct hal_rx_desc_data *rx_desc_da rx_desc_data->is_decrypted = ath12k_hal_rx_h_is_decrypted_wcn7850(rx_desc); rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_wcn7850(rx_desc); } + +static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) +{ + struct ath12k_hal *hal = &ab->hal; + struct hal_srng_config *s; + + hal->srng_config = kmemdup(hw_srng_config_template, + sizeof(hw_srng_config_template), + GFP_KERNEL); + if (!hal->srng_config) + return -ENOMEM; + + s = &hal->srng_config[HAL_REO_DST]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP; + s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); + s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP; + + s = &hal->srng_config[HAL_REO_EXCEPTION]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP; + + s = &hal->srng_config[HAL_REO_REINJECT]; + s->max_rings = 1; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP; + + s = &hal->srng_config[HAL_REO_CMD]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP; + + s = &hal->srng_config[HAL_REO_STATUS]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP; + + s = &hal->srng_config[HAL_TCL_DATA]; + s->max_rings = 5; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP; + s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(ab) - HAL_TCL1_RING_BASE_LSB(ab); + s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP; + + s = &hal->srng_config[HAL_TCL_CMD]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP; + + s = &hal->srng_config[HAL_TCL_STATUS]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP; + + s = &hal->srng_config[HAL_CE_SRC]; + s->max_rings = 12; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); + + s = &hal->srng_config[HAL_CE_DST]; + s->max_rings = 12; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + + s = &hal->srng_config[HAL_CE_DST_STATUS]; + s->max_rings = 12; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + + HAL_CE_DST_STATUS_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + + s = &hal->srng_config[HAL_WBM_IDLE_LINK]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP; + + s = &hal->srng_config[HAL_SW2WBM_RELEASE]; + s->max_rings = 1; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP; + + s = &hal->srng_config[HAL_WBM2SW_RELEASE]; + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP; + s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) - + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); + s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP; + + s = &hal->srng_config[HAL_RXDMA_BUF]; + s->max_rings = 2; + s->mac_type = ATH12K_HAL_SRNG_PMAC; + + s = &hal->srng_config[HAL_RXDMA_DST]; + s->max_rings = 1; + s->entry_size = sizeof(struct hal_reo_entrance_ring) >> 2; + + /* below rings are not used */ + s = &hal->srng_config[HAL_RXDMA_DIR_BUF]; + s->max_rings = 0; + + s = &hal->srng_config[HAL_PPE2TCL]; + s->max_rings = 0; + + s = &hal->srng_config[HAL_PPE_RELEASE]; + s->max_rings = 0; + + s = &hal->srng_config[HAL_TX_MONITOR_BUF]; + s->max_rings = 0; + + s = &hal->srng_config[HAL_TX_MONITOR_DST]; + s->max_rings = 0; + + s = &hal->srng_config[HAL_PPE2TCL]; + s->max_rings = 0; + + return 0; +} + +const struct hal_ops hal_wcn7850_ops = { + .create_srng_config = ath12k_hal_srng_create_config_wcn7850, + .tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map, + .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_wcn7850, + .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_wcn7850, + .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_wcn7850, + .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_wcn7850, + .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_wcn7850, + .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_wcn7850, + .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_wcn7850, + .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850, + .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, + .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, + .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, +}; +EXPORT_SYMBOL(hal_wcn7850_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h index a90978b2a4543..80de7ea522b54 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -10,6 +10,9 @@ #include "../hal.h" #include "hal_rx.h" +extern const struct ath12k_hal_tcl_to_wbm_rbm_map +ath12k_hal_wcn7850_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX]; + u8 ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_copy_end_tlv_wcn7850(struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc); From 03bffe149142b90a97caa46b6bae65a28e07e585 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:29 +0530 Subject: [PATCH 051/140] wifi: ath12k: Initialize desc_size through hal_init Currently desc_size uses a dedicated hal_ops API for initialization. Combine it with other hal_params to be initialized in a single API "hal_init" during probe time using a static array. hal_init will be used as the common API to initialize all hal parameters during the probe. Add hal.c file to add hal definitions that are wifi7 specific but common between qca and wcn chipsets. Add hal.h header to add wifi7 specific prototypes/Macros etc Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-3-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/core.c | 2 -- drivers/net/wireless/ath/ath12k/dp.c | 5 --- drivers/net/wireless/ath/ath12k/dp.h | 1 - drivers/net/wireless/ath/ath12k/hal.c | 3 -- drivers/net/wireless/ath/ath12k/hal.h | 5 ++- drivers/net/wireless/ath/ath12k/wifi7/hal.c | 36 +++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/hal.h | 12 +++++++ .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 1 - .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 1 - drivers/net/wireless/ath/ath12k/wifi7/hw.c | 3 ++ 11 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/hal.c create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/hal.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index e148444021633..32a0f30faf922 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -28,6 +28,7 @@ ath12k-y += wifi7/hal_tx.o \ wifi7/dp_rx.o \ wifi7/dp_tx.o \ wifi7/dp.o \ + wifi7/hal.o \ wifi7/hal_qcn9274.o \ wifi7/hal_wcn7850.o diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index c82c0746a3494..04983074e9467 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -930,8 +930,6 @@ static int ath12k_core_start(struct ath12k_base *ab) goto err_hif_stop; } - ath12k_dp_hal_rx_desc_init(ab); - ret = ath12k_wmi_cmd_init(ab); if (ret) { ath12k_err(ab, "failed to send wmi init cmd: %d\n", ret); diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 088736bead58a..1887a517161d6 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -913,11 +913,6 @@ void ath12k_dp_pdev_pre_alloc(struct ath12k *ar) /* TODO: Add any RXDMA setup required per pdev */ } -void ath12k_dp_hal_rx_desc_init(struct ath12k_base *ab) -{ - ab->hal.hal_desc_sz = ab->hw_params->hal_ops->rx_desc_get_desc_size(); -} - int ath12k_dp_pdev_alloc(struct ath12k_base *ab) { struct ath12k_dp *dp = ath12k_ab_to_dp(ab); diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index d592974f8e066..f7cf83806eb07 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -530,5 +530,4 @@ struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_base *ab, u32 cookie); struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_base *ab, u32 desc_id); -void ath12k_dp_hal_rx_desc_init(struct ath12k_base *ab); #endif diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 4ff906854970f..87abacc8ae8e1 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -1103,11 +1103,8 @@ static void ath12k_hal_unregister_srng_lock_keys(struct ath12k_base *ab) int ath12k_hal_srng_init(struct ath12k_base *ab) { - struct ath12k_hal *hal = &ab->hal; int ret; - memset(hal, 0, sizeof(*hal)); - ret = ab->hw_params->hal_ops->create_srng_config(ab); if (ret) goto err_hal; diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 8d539b72d6677..ee0d31b7788ab 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1579,6 +1579,10 @@ enum nl80211_he_ru_alloc ath12k_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones) return ret; } +struct ath12k_hw_version_map { + u32 hal_desc_sz; +}; + struct hal_ops { int (*create_srng_config)(struct ath12k_base *ab); const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; @@ -1594,7 +1598,6 @@ struct hal_ops { void (*extract_rx_desc_data)(struct hal_rx_desc_data *rx_desc_data, struct hal_rx_desc *rx_desc, struct hal_rx_desc *ldesc); - u32 (*rx_desc_get_desc_size)(void); u32 (*rx_desc_get_mpdu_start_tag)(struct hal_rx_desc *desc); u32 (*rx_desc_get_mpdu_ppdu_id)(struct hal_rx_desc *desc); u8 (*rx_desc_get_l3_pad_bytes)(struct hal_rx_desc *desc); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c new file mode 100644 index 0000000000000..4ad3ef3ba5e0f --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#include "hw.h" +#include "hal_desc.h" +#include "../hal.h" +#include "hal.h" + +static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = { + [ATH12K_HW_QCN9274_HW10] = { + .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), + }, + [ATH12K_HW_QCN9274_HW20] = { + .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), + }, + [ATH12K_HW_WCN7850_HW20] = { + .hal_desc_sz = sizeof(struct hal_rx_desc_wcn7850), + }, + [ATH12K_HW_IPQ5332_HW10] = { + .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), + }, +}; + +int ath12k_wifi7_hal_init(struct ath12k_base *ab) +{ + struct ath12k_hal *hal = &ab->hal; + + memset(hal, 0, sizeof(*hal)); + + hal->hal_desc_sz = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_desc_sz; + + return 0; +} +EXPORT_SYMBOL(ath12k_wifi7_hal_init); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h new file mode 100644 index 0000000000000..0dc5eaec5fb0a --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_HAL_WIFI7_H +#define ATH12K_HAL_WIFI7_H + +int ath12k_wifi7_hal_init(struct ath12k_base *ab); + +#endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index c98ffc991ad81..6a1c13565700b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -690,7 +690,6 @@ const struct hal_ops hal_qcn9274_ops = { .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcn9274, .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_qcn9274, .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_qcn9274, - .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_qcn9274, .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 2e88ac0ae7971..275de9c1a359d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -699,7 +699,6 @@ const struct hal_ops hal_wcn7850_ops = { .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_wcn7850, .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_wcn7850, .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_wcn7850, - .rx_desc_get_desc_size = ath12k_hal_get_rx_desc_size_wcn7850, .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850, .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 1acf6ffaea08f..621022064962e 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -23,6 +23,7 @@ #include "../debugfs.h" #include "../debugfs_sta.h" #include "../testmode.h" +#include "hal.h" static const guid_t wcn7850_uuid = GUID_INIT(0xf634f534, 0x6147, 0x11ec, 0x90, 0xd6, 0x02, 0x42, @@ -1124,6 +1125,8 @@ int ath12k_wifi7_hw_init(struct ath12k_base *ab) ab->hw_params = hw_params; ab->ath12k_ops = &ath12k_ops_wifi7; + ath12k_wifi7_hal_init(ab); + ath12k_info(ab, "Wi-Fi 7 Hardware name: %s\n", ab->hw_params->name); return 0; From a1039e8a63c6be782ffdbe68753054bd6636e02f Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:30 +0530 Subject: [PATCH 052/140] wifi: ath12k: Initialize hal_ops through hal_init Modularize the HAL layer by moving hal_ops from ab->hw_params into the ab->hal. This reduces indirection and allows data path to access HAL ops directly through the HAL context. Initialize hal_ops via hal_init using a const table ath12k_hw_version_map. This approach will be extended to register other HAL parameters during init. Remove ab->hw_params->hal_ops as it is no longer needed. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-4-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ahb.c | 2 +- drivers/net/wireless/ath/ath12k/dp.c | 4 ++-- drivers/net/wireless/ath/ath12k/dp_mon.c | 2 +- drivers/net/wireless/ath/ath12k/dp_rx.h | 16 ++++++++-------- drivers/net/wireless/ath/ath12k/hal.c | 2 +- drivers/net/wireless/ath/ath12k/hal.h | 5 ++--- drivers/net/wireless/ath/ath12k/hw.h | 2 -- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 2 +- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 2 +- drivers/net/wireless/ath/ath12k/wifi7/hal.c | 7 +++++++ .../net/wireless/ath/ath12k/wifi7/hal_qcn9274.h | 1 + .../net/wireless/ath/ath12k/wifi7/hal_wcn7850.h | 1 + drivers/net/wireless/ath/ath12k/wifi7/hw.c | 8 -------- 13 files changed, 26 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index b743c05c5fb04..c22bc7da882eb 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -563,7 +563,7 @@ static int ath12k_ahb_config_ext_irq(struct ath12k_base *ab) u32 num_irq; ring_mask = ab->hw_params->ring_mask; - hal_ops = ab->hw_params->hal_ops; + hal_ops = ab->hal.hal_ops; for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) { irq_grp = &ab->ext_irq_grp[i]; num_irq = 0; diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 1887a517161d6..8926c0a5c34fe 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -142,7 +142,7 @@ static int ath12k_dp_srng_calculate_msi_group(struct ath12k_base *ab, grp_mask = &ab->hw_params->ring_mask->rx_wbm_rel[0]; ring_num = 0; } else { - map = ab->hw_params->hal_ops->tcl_to_wbm_rbm_map; + map = ab->hal.hal_ops->tcl_to_wbm_rbm_map; for (i = 0; i < ab->hw_params->max_tx_ring; i++) { if (ring_num == map[i].wbm_ring_num) { ring_num = i; @@ -508,7 +508,7 @@ static int ath12k_dp_srng_common_setup(struct ath12k_base *ab) } for (i = 0; i < ab->hw_params->max_tx_ring; i++) { - map = ab->hw_params->hal_ops->tcl_to_wbm_rbm_map; + map = ab->hal.hal_ops->tcl_to_wbm_rbm_map; tx_comp_ring_num = map[i].wbm_ring_num; ret = ath12k_dp_srng_setup(ab, &dp->tx_ring[i].tcl_data_ring, diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index d0aaa0a2179cf..69cb6343bb232 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2082,7 +2082,7 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k_pdev_dp *dp_pdev, rx_desc = (struct hal_rx_desc *)head_msdu->data; hdr_desc = - ab->hw_params->hal_ops->rx_desc_get_msdu_payload(rx_desc); + ab->hal.hal_ops->rx_desc_get_msdu_payload(rx_desc); /* Base size */ wh = (struct ieee80211_hdr_3addr *)hdr_desc; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 97b8f4608087f..09042d41976bf 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -123,27 +123,27 @@ static inline u16 ath12k_dp_rx_h_frag_no(struct ath12k_base *ab, static inline u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, struct hal_rx_desc *desc) { - return ab->hw_params->hal_ops->rx_desc_get_l3_pad_bytes(desc); + return ab->hal.hal_ops->rx_desc_get_l3_pad_bytes(desc); } static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab, struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc) { - ab->hw_params->hal_ops->rx_desc_copy_end_tlv(fdesc, ldesc); + ab->hal.hal_ops->rx_desc_copy_end_tlv(fdesc, ldesc); } static inline void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab, struct hal_rx_desc *desc, u16 len) { - ab->hw_params->hal_ops->rx_desc_set_msdu_len(desc, len); + ab->hal.hal_ops->rx_desc_set_msdu_len(desc, len); } static inline u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc) { - return ab->hw_params->hal_ops->rx_desc_get_mpdu_ppdu_id(rx_desc); + return ab->hal.hal_ops->rx_desc_get_mpdu_ppdu_id(rx_desc); } static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, @@ -151,7 +151,7 @@ static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, { u32 tlv_tag; - tlv_tag = ab->hw_params->hal_ops->rx_desc_get_mpdu_start_tag(rx_desc); + tlv_tag = ab->hal.hal_ops->rx_desc_get_mpdu_start_tag(rx_desc); return tlv_tag == HAL_RX_MPDU_START; } @@ -160,7 +160,7 @@ static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab, struct hal_rx_desc *desc, struct ieee80211_hdr *hdr) { - ab->hw_params->hal_ops->rx_desc_get_dot11_hdr(desc, hdr); + ab->hal.hal_ops->rx_desc_get_dot11_hdr(desc, hdr); } static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, @@ -168,13 +168,13 @@ static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, u8 *crypto_hdr, enum hal_encrypt_type enctype) { - ab->hw_params->hal_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); + ab->hal.hal_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); } static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab, struct hal_rx_desc *desc) { - return ab->hw_params->hal_ops->rx_desc_get_msdu_src_link_id(desc); + return ab->hal.hal_ops->rx_desc_get_msdu_src_link_id(desc); } static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 87abacc8ae8e1..338a4e5244ddf 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -1105,7 +1105,7 @@ int ath12k_hal_srng_init(struct ath12k_base *ab) { int ret; - ret = ab->hw_params->hal_ops->create_srng_config(ab); + ret = ab->hal.hal_ops->create_srng_config(ab); if (ret) goto err_hal; diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index ee0d31b7788ab..195728d270c01 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1463,6 +1463,7 @@ struct ath12k_hal { dma_addr_t paddr; } wrp; + const struct hal_ops *hal_ops; /* Available REO blocking resources bitmap */ u8 avail_blk_resource; @@ -1580,6 +1581,7 @@ enum nl80211_he_ru_alloc ath12k_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones) } struct ath12k_hw_version_map { + const struct hal_ops *hal_ops; u32 hal_desc_sz; }; @@ -1604,9 +1606,6 @@ struct hal_ops { u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc); }; -extern const struct hal_ops hal_qcn9274_ops; -extern const struct hal_ops hal_wcn7850_ops; - u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, int tid, u32 ba_window_size, diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h index 35d6900720fee..7e8f1f7ef5847 100644 --- a/drivers/net/wireless/ath/ath12k/hw.h +++ b/drivers/net/wireless/ath/ath12k/hw.h @@ -193,8 +193,6 @@ struct ath12k_hw_params { void (*wmi_init)(struct ath12k_base *ab, struct ath12k_wmi_resource_config_arg *config); - const struct hal_ops *hal_ops; - u64 qmi_cnss_feature_bitmap; u32 rfkill_pin; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 35709dfccbcf3..ece6a1311ef0c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -50,6 +50,6 @@ void ath12k_wifi7_dp_extract_rx_desc_data(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, struct hal_rx_desc *ldesc) { - ab->hw_params->hal_ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); + ab->hal.hal_ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); } #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index ab5824abfe758..036bacd704e92 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -107,7 +107,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a ti.ring_id = ring_selector % ab->hw_params->max_tx_ring; ring_map |= BIT(ti.ring_id); - ti.rbm_id = ab->hw_params->hal_ops->tcl_to_wbm_rbm_map[ti.ring_id].rbm_id; + ti.rbm_id = ab->hal.hal_ops->tcl_to_wbm_rbm_map[ti.ring_id].rbm_id; tx_ring = &dp->tx_ring[ti.ring_id]; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 4ad3ef3ba5e0f..0e3930c8575a2 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -7,18 +7,24 @@ #include "hal_desc.h" #include "../hal.h" #include "hal.h" +#include "hal_qcn9274.h" +#include "hal_wcn7850.h" static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = { [ATH12K_HW_QCN9274_HW10] = { + .hal_ops = &hal_qcn9274_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), }, [ATH12K_HW_QCN9274_HW20] = { + .hal_ops = &hal_qcn9274_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), }, [ATH12K_HW_WCN7850_HW20] = { + .hal_ops = &hal_wcn7850_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_wcn7850), }, [ATH12K_HW_IPQ5332_HW10] = { + .hal_ops = &hal_qcn9274_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), }, }; @@ -29,6 +35,7 @@ int ath12k_wifi7_hal_init(struct ath12k_base *ab) memset(hal, 0, sizeof(*hal)); + hal->hal_ops = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_ops; hal->hal_desc_sz = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_desc_sz; return 0; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h index 1563854b5b6a5..4d08292d8a7f9 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h @@ -12,6 +12,7 @@ #include "../hal.h" #include "hal_rx.h" +extern const struct hal_ops hal_qcn9274_ops; extern const struct ath12k_hal_tcl_to_wbm_rbm_map ath12k_hal_qcn9274_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX]; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h index 80de7ea522b54..8207e73602b3c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -10,6 +10,7 @@ #include "../hal.h" #include "hal_rx.h" +extern const struct hal_ops hal_wcn7850_ops; extern const struct ath12k_hal_tcl_to_wbm_rbm_map ath12k_hal_wcn7850_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX]; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 621022064962e..f469a829ae9a7 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -758,8 +758,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .wmi_init = ath12k_wifi7_wmi_init_qcn9274, - .hal_ops = &hal_qcn9274_ops, - .qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01), .rfkill_pin = 0, @@ -847,8 +845,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .wmi_init = ath12k_wifi7_wmi_init_wcn7850, - .hal_ops = &hal_wcn7850_ops, - .qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01) | BIT(CNSS_PCIE_PERST_NO_PULL_V01), @@ -934,8 +930,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .wmi_init = ath12k_wifi7_wmi_init_qcn9274, - .hal_ops = &hal_qcn9274_ops, - .qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01), .rfkill_pin = 0, @@ -1017,8 +1011,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .wmi_init = &ath12k_wifi7_wmi_init_qcn9274, - .hal_ops = &hal_qcn9274_ops, - .qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01), .rfkill_pin = 0, From ec6536e0504b3682085fe5c0d748a26c2e9d416e Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:31 +0530 Subject: [PATCH 053/140] wifi: ath12k: Move wbm_rbm_map to hw specific hal files Move wbm_rbm_map from common hal file to hw specific hal files, since these implementations are specific and configurable for each hardware. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-5-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ahb.c | 4 +-- drivers/net/wireless/ath/ath12k/dp.c | 4 +-- drivers/net/wireless/ath/ath12k/hal.c | 36 ------------------- drivers/net/wireless/ath/ath12k/hal.h | 4 ++- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 2 +- drivers/net/wireless/ath/ath12k/wifi7/hal.c | 5 +++ .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 21 ++++++++++- .../wireless/ath/ath12k/wifi7/hal_qcn9274.h | 2 +- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 17 ++++++++- .../wireless/ath/ath12k/wifi7/hal_wcn7850.h | 2 +- 10 files changed, 50 insertions(+), 47 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index c22bc7da882eb..2628d53845eb8 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -558,12 +558,10 @@ static int ath12k_ahb_config_ext_irq(struct ath12k_base *ab) { const struct ath12k_hw_ring_mask *ring_mask; struct ath12k_ext_irq_grp *irq_grp; - const struct hal_ops *hal_ops; int i, j, irq, irq_idx, ret; u32 num_irq; ring_mask = ab->hw_params->ring_mask; - hal_ops = ab->hal.hal_ops; for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) { irq_grp = &ab->ext_irq_grp[i]; num_irq = 0; @@ -583,7 +581,7 @@ static int ath12k_ahb_config_ext_irq(struct ath12k_base *ab) * tcl_to_wbm_rbm_map point to the same ring number. */ if (ring_mask->tx[i] & - BIT(hal_ops->tcl_to_wbm_rbm_map[j].wbm_ring_num)) { + BIT(ab->hal.tcl_to_wbm_rbm_map[j].wbm_ring_num)) { irq_grp->irqs[num_irq++] = wbm2host_tx_completions_ring1 - j; } diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 8926c0a5c34fe..fc4626d770e58 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -142,7 +142,7 @@ static int ath12k_dp_srng_calculate_msi_group(struct ath12k_base *ab, grp_mask = &ab->hw_params->ring_mask->rx_wbm_rel[0]; ring_num = 0; } else { - map = ab->hal.hal_ops->tcl_to_wbm_rbm_map; + map = ab->hal.tcl_to_wbm_rbm_map; for (i = 0; i < ab->hw_params->max_tx_ring; i++) { if (ring_num == map[i].wbm_ring_num) { ring_num = i; @@ -508,7 +508,7 @@ static int ath12k_dp_srng_common_setup(struct ath12k_base *ab) } for (i = 0; i < ab->hw_params->max_tx_ring; i++) { - map = ab->hal.hal_ops->tcl_to_wbm_rbm_map; + map = ab->hal.tcl_to_wbm_rbm_map; tx_comp_ring_num = map[i].wbm_ring_num; ret = ath12k_dp_srng_setup(ab, &dp->tx_ring[i].tcl_data_ring, diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 338a4e5244ddf..d1dfbe2f9a654 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -12,42 +12,6 @@ #include "wifi7/hal_qcn9274.h" #include "wifi7/hal_wcn7850.h" -const struct ath12k_hal_tcl_to_wbm_rbm_map -ath12k_hal_qcn9274_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX] = { - { - .wbm_ring_num = 0, - .rbm_id = HAL_RX_BUF_RBM_SW0_BM, - }, - { - .wbm_ring_num = 1, - .rbm_id = HAL_RX_BUF_RBM_SW1_BM, - }, - { - .wbm_ring_num = 2, - .rbm_id = HAL_RX_BUF_RBM_SW2_BM, - }, - { - .wbm_ring_num = 4, - .rbm_id = HAL_RX_BUF_RBM_SW4_BM, - } -}; - -const struct ath12k_hal_tcl_to_wbm_rbm_map -ath12k_hal_wcn7850_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX] = { - { - .wbm_ring_num = 0, - .rbm_id = HAL_RX_BUF_RBM_SW0_BM, - }, - { - .wbm_ring_num = 2, - .rbm_id = HAL_RX_BUF_RBM_SW2_BM, - }, - { - .wbm_ring_num = 4, - .rbm_id = HAL_RX_BUF_RBM_SW4_BM, - }, -}; - static unsigned int ath12k_hal_reo1_ring_id_offset(struct ath12k_base *ab) { return HAL_REO1_RING_ID(ab) - HAL_REO1_RING_BASE_LSB(ab); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 195728d270c01..dc834d16bb3f2 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1474,6 +1474,8 @@ struct ath12k_hal { int num_shadow_reg_configured; u32 hal_desc_sz; + + const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; }; /* Maps WBM ring number and Return Buffer Manager Id per TCL ring */ @@ -1583,11 +1585,11 @@ enum nl80211_he_ru_alloc ath12k_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones) struct ath12k_hw_version_map { const struct hal_ops *hal_ops; u32 hal_desc_sz; + const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; }; struct hal_ops { int (*create_srng_config)(struct ath12k_base *ab); - const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; void (*rx_desc_set_msdu_len)(struct hal_rx_desc *desc, u16 len); void (*rx_desc_get_dot11_hdr)(struct hal_rx_desc *desc, struct ieee80211_hdr *hdr); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 036bacd704e92..b3c0f8a6a5ce0 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -107,7 +107,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a ti.ring_id = ring_selector % ab->hw_params->max_tx_ring; ring_map |= BIT(ti.ring_id); - ti.rbm_id = ab->hal.hal_ops->tcl_to_wbm_rbm_map[ti.ring_id].rbm_id; + ti.rbm_id = ab->hal.tcl_to_wbm_rbm_map[ti.ring_id].rbm_id; tx_ring = &dp->tx_ring[ti.ring_id]; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 0e3930c8575a2..53ea3792ef518 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -14,18 +14,22 @@ static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = { [ATH12K_HW_QCN9274_HW10] = { .hal_ops = &hal_qcn9274_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), + .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_qcn9274, }, [ATH12K_HW_QCN9274_HW20] = { .hal_ops = &hal_qcn9274_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), + .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_qcn9274, }, [ATH12K_HW_WCN7850_HW20] = { .hal_ops = &hal_wcn7850_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_wcn7850), + .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_wcn7850, }, [ATH12K_HW_IPQ5332_HW10] = { .hal_ops = &hal_qcn9274_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), + .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_qcn9274, }, }; @@ -37,6 +41,7 @@ int ath12k_wifi7_hal_init(struct ath12k_base *ab) hal->hal_ops = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_ops; hal->hal_desc_sz = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_desc_sz; + hal->tcl_to_wbm_rbm_map = ath12k_wifi7_hw_ver_map[ab->hw_rev].tcl_to_wbm_rbm_map; return 0; } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 6a1c13565700b..fefa151efaefc 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -681,9 +681,28 @@ static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) return 0; } +const struct ath12k_hal_tcl_to_wbm_rbm_map +ath12k_hal_tcl_to_wbm_rbm_map_qcn9274[DP_TCL_NUM_RING_MAX] = { + { + .wbm_ring_num = 0, + .rbm_id = HAL_RX_BUF_RBM_SW0_BM, + }, + { + .wbm_ring_num = 1, + .rbm_id = HAL_RX_BUF_RBM_SW1_BM, + }, + { + .wbm_ring_num = 2, + .rbm_id = HAL_RX_BUF_RBM_SW2_BM, + }, + { + .wbm_ring_num = 4, + .rbm_id = HAL_RX_BUF_RBM_SW4_BM, + }, +}; + const struct hal_ops hal_qcn9274_ops = { .create_srng_config = ath12k_hal_srng_create_config_qcn9274, - .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcn9274, .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_qcn9274, .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcn9274, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h index 4d08292d8a7f9..1b431d5b64170 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h @@ -14,7 +14,7 @@ extern const struct hal_ops hal_qcn9274_ops; extern const struct ath12k_hal_tcl_to_wbm_rbm_map -ath12k_hal_qcn9274_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX]; +ath12k_hal_tcl_to_wbm_rbm_map_qcn9274[DP_TCL_NUM_RING_MAX]; u8 ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_copy_end_tlv_qcn9274(struct hal_rx_desc *fdesc, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 275de9c1a359d..3e88a1e68b87b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -690,9 +690,24 @@ static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) return 0; } +const struct ath12k_hal_tcl_to_wbm_rbm_map +ath12k_hal_tcl_to_wbm_rbm_map_wcn7850[DP_TCL_NUM_RING_MAX] = { + { + .wbm_ring_num = 0, + .rbm_id = HAL_RX_BUF_RBM_SW0_BM, + }, + { + .wbm_ring_num = 2, + .rbm_id = HAL_RX_BUF_RBM_SW2_BM, + }, + { + .wbm_ring_num = 4, + .rbm_id = HAL_RX_BUF_RBM_SW4_BM, + }, +}; + const struct hal_ops hal_wcn7850_ops = { .create_srng_config = ath12k_hal_srng_create_config_wcn7850, - .tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map, .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_wcn7850, .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_wcn7850, .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_wcn7850, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h index 8207e73602b3c..2df4976f59aa4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -12,7 +12,7 @@ extern const struct hal_ops hal_wcn7850_ops; extern const struct ath12k_hal_tcl_to_wbm_rbm_map -ath12k_hal_wcn7850_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX]; +ath12k_hal_tcl_to_wbm_rbm_map_wcn7850[DP_TCL_NUM_RING_MAX]; u8 ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_copy_end_tlv_wcn7850(struct hal_rx_desc *fdesc, From cf09be6c312f163f254bef9e43fc31a270b9e378 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:32 +0530 Subject: [PATCH 054/140] wifi: ath12k: Move hal_params and regs to hal from hw Move hal_params and regs to hal structure from the hw structure, since these parameters are used by hal layer and make corresponding initializations in hal_init. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-6-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 2 +- drivers/net/wireless/ath/ath12k/dp_mon.c | 4 +- drivers/net/wireless/ath/ath12k/dp_rx.c | 2 +- drivers/net/wireless/ath/ath12k/hal.h | 211 +++++++--- drivers/net/wireless/ath/ath12k/hw.h | 90 +--- drivers/net/wireless/ath/ath12k/pci.h | 10 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 2 +- drivers/net/wireless/ath/ath12k/wifi7/hal.c | 10 + drivers/net/wireless/ath/ath12k/wifi7/hal.h | 1 - .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 288 +++++++++++++ .../wireless/ath/ath12k/wifi7/hal_qcn9274.h | 5 + .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 97 +++++ .../wireless/ath/ath12k/wifi7/hal_wcn7850.h | 2 + drivers/net/wireless/ath/ath12k/wifi7/hw.c | 393 ------------------ 14 files changed, 563 insertions(+), 554 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index fc4626d770e58..3289d609fefb4 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1243,7 +1243,7 @@ void ath12k_dp_cc_config(struct ath12k_base *ab) /* Enable Cookie conversion for WBM2SW Rings */ val = ath12k_hif_read32(ab, wbm_base + HAL_WBM_SW_COOKIE_CONVERT_CFG); val |= u32_encode_bits(1, HAL_WBM_SW_COOKIE_CONV_CFG_GLOBAL_EN) | - ab->hw_params->hal_params->wbm2sw_cc_enable; + ab->hal.hal_params->wbm2sw_cc_enable; ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CONVERT_CFG, val); } diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 69cb6343bb232..9a23575cfdb25 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2720,7 +2720,7 @@ int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, int req_entries) { enum hal_rx_buf_return_buf_manager mgr = - ab->hw_params->hal_params->rx_buf_rbm; + ab->hal.hal_params->rx_buf_rbm; int num_free, num_remain, buf_id; struct ath12k_buffer_addr *desc; struct hal_srng *srng; @@ -4077,7 +4077,7 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, move_next: skb = ath12k_dp_rx_alloc_mon_status_buf(ab, rx_ring, &buf_id); - hal_params = ab->hw_params->hal_params; + hal_params = ab->hal.hal_params; if (!skb) { ath12k_warn(ab, "failed to alloc buffer for status ring\n"); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index b4d28007b24a9..e05dff11357c9 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -78,7 +78,7 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, dma_addr_t paddr; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_rx_desc_info *rx_desc; - enum hal_rx_buf_return_buf_manager mgr = ab->hw_params->hal_params->rx_buf_rbm; + enum hal_rx_buf_return_buf_manager mgr = ab->hal.hal_params->rx_buf_rbm; req_entries = min(req_entries, rx_ring->bufs_max); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index dc834d16bb3f2..f9cd3d5011441 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -73,13 +73,13 @@ struct ath12k_base; #define HAL_SEQ_WCSS_UMAC_REO_REG 0x00a38000 #define HAL_SEQ_WCSS_UMAC_TCL_REG 0x00a44000 #define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) \ - ((ab)->hw_params->regs->hal_umac_ce0_src_reg_base) + ((ab)->hal.regs->hal_umac_ce0_src_reg_base) #define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) \ - ((ab)->hw_params->regs->hal_umac_ce0_dest_reg_base) + ((ab)->hal.regs->hal_umac_ce0_dest_reg_base) #define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) \ - ((ab)->hw_params->regs->hal_umac_ce1_src_reg_base) + ((ab)->hal.regs->hal_umac_ce1_src_reg_base) #define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) \ - ((ab)->hw_params->regs->hal_umac_ce1_dest_reg_base) + ((ab)->hal.regs->hal_umac_ce1_dest_reg_base) #define HAL_SEQ_WCSS_UMAC_WBM_REG 0x00a34000 #define HAL_CE_WFSS_CE_REG_BASE 0x01b80000 @@ -90,30 +90,30 @@ struct ath12k_base; #define HAL_TCL1_RING_CMN_CTRL_REG 0x00000020 #define HAL_TCL1_RING_DSCP_TID_MAP 0x00000240 #define HAL_TCL1_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_base_lsb) + ((ab)->hal.regs->hal_tcl1_ring_base_lsb) #define HAL_TCL1_RING_BASE_MSB(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_base_msb) -#define HAL_TCL1_RING_ID(ab) ((ab)->hw_params->regs->hal_tcl1_ring_id) + ((ab)->hal.regs->hal_tcl1_ring_base_msb) +#define HAL_TCL1_RING_ID(ab) ((ab)->hal.regs->hal_tcl1_ring_id) #define HAL_TCL1_RING_MISC(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_misc) + ((ab)->hal.regs->hal_tcl1_ring_misc) #define HAL_TCL1_RING_TP_ADDR_LSB(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_tp_addr_lsb) + ((ab)->hal.regs->hal_tcl1_ring_tp_addr_lsb) #define HAL_TCL1_RING_TP_ADDR_MSB(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_tp_addr_msb) + ((ab)->hal.regs->hal_tcl1_ring_tp_addr_msb) #define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_consumer_int_setup_ix0) + ((ab)->hal.regs->hal_tcl1_ring_consumer_int_setup_ix0) #define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_consumer_int_setup_ix1) + ((ab)->hal.regs->hal_tcl1_ring_consumer_int_setup_ix1) #define HAL_TCL1_RING_MSI1_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_msi1_base_lsb) + ((ab)->hal.regs->hal_tcl1_ring_msi1_base_lsb) #define HAL_TCL1_RING_MSI1_BASE_MSB(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_msi1_base_msb) + ((ab)->hal.regs->hal_tcl1_ring_msi1_base_msb) #define HAL_TCL1_RING_MSI1_DATA(ab) \ - ((ab)->hw_params->regs->hal_tcl1_ring_msi1_data) + ((ab)->hal.regs->hal_tcl1_ring_msi1_data) #define HAL_TCL2_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_tcl2_ring_base_lsb) + ((ab)->hal.regs->hal_tcl2_ring_base_lsb) #define HAL_TCL_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_tcl_ring_base_lsb) + ((ab)->hal.regs->hal_tcl_ring_base_lsb) #define HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ (HAL_TCL1_RING_MSI1_BASE_LSB(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) @@ -147,7 +147,7 @@ struct ath12k_base; /* TCL STATUS ring address */ #define HAL_TCL_STATUS_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_tcl_status_ring_base_lsb) + ((ab)->hal.regs->hal_tcl_status_ring_base_lsb) #define HAL_TCL_STATUS_RING_HP 0x00002048 /* PPE2TCL1 Ring address */ @@ -156,41 +156,41 @@ struct ath12k_base; /* WBM PPE Release Ring address */ #define HAL_WBM_PPE_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_ppe_rel_ring_base) + ((ab)->hal.regs->hal_ppe_rel_ring_base) #define HAL_WBM_PPE_RELEASE_RING_HP 0x00003020 /* REO2SW(x) R0 ring configuration address */ #define HAL_REO1_GEN_ENABLE 0x00000000 #define HAL_REO1_MISC_CTRL_ADDR(ab) \ - ((ab)->hw_params->regs->hal_reo1_misc_ctrl_addr) + ((ab)->hal.regs->hal_reo1_misc_ctrl_addr) #define HAL_REO1_DEST_RING_CTRL_IX_0 0x00000004 #define HAL_REO1_DEST_RING_CTRL_IX_1 0x00000008 #define HAL_REO1_DEST_RING_CTRL_IX_2 0x0000000c #define HAL_REO1_DEST_RING_CTRL_IX_3 0x00000010 -#define HAL_REO1_QDESC_ADDR(ab) ((ab)->hw_params->regs->hal_reo1_qdesc_addr) -#define HAL_REO1_QDESC_MAX_PEERID(ab) ((ab)->hw_params->regs->hal_reo1_qdesc_max_peerid) -#define HAL_REO1_SW_COOKIE_CFG0(ab) ((ab)->hw_params->regs->hal_reo1_sw_cookie_cfg0) -#define HAL_REO1_SW_COOKIE_CFG1(ab) ((ab)->hw_params->regs->hal_reo1_sw_cookie_cfg1) -#define HAL_REO1_QDESC_LUT_BASE0(ab) ((ab)->hw_params->regs->hal_reo1_qdesc_lut_base0) -#define HAL_REO1_QDESC_LUT_BASE1(ab) ((ab)->hw_params->regs->hal_reo1_qdesc_lut_base1) -#define HAL_REO1_RING_BASE_LSB(ab) ((ab)->hw_params->regs->hal_reo1_ring_base_lsb) -#define HAL_REO1_RING_BASE_MSB(ab) ((ab)->hw_params->regs->hal_reo1_ring_base_msb) -#define HAL_REO1_RING_ID(ab) ((ab)->hw_params->regs->hal_reo1_ring_id) -#define HAL_REO1_RING_MISC(ab) ((ab)->hw_params->regs->hal_reo1_ring_misc) -#define HAL_REO1_RING_HP_ADDR_LSB(ab) ((ab)->hw_params->regs->hal_reo1_ring_hp_addr_lsb) -#define HAL_REO1_RING_HP_ADDR_MSB(ab) ((ab)->hw_params->regs->hal_reo1_ring_hp_addr_msb) +#define HAL_REO1_QDESC_ADDR(ab) ((ab)->hal.regs->hal_reo1_qdesc_addr) +#define HAL_REO1_QDESC_MAX_PEERID(ab) ((ab)->hal.regs->hal_reo1_qdesc_max_peerid) +#define HAL_REO1_SW_COOKIE_CFG0(ab) ((ab)->hal.regs->hal_reo1_sw_cookie_cfg0) +#define HAL_REO1_SW_COOKIE_CFG1(ab) ((ab)->hal.regs->hal_reo1_sw_cookie_cfg1) +#define HAL_REO1_QDESC_LUT_BASE0(ab) ((ab)->hal.regs->hal_reo1_qdesc_lut_base0) +#define HAL_REO1_QDESC_LUT_BASE1(ab) ((ab)->hal.regs->hal_reo1_qdesc_lut_base1) +#define HAL_REO1_RING_BASE_LSB(ab) ((ab)->hal.regs->hal_reo1_ring_base_lsb) +#define HAL_REO1_RING_BASE_MSB(ab) ((ab)->hal.regs->hal_reo1_ring_base_msb) +#define HAL_REO1_RING_ID(ab) ((ab)->hal.regs->hal_reo1_ring_id) +#define HAL_REO1_RING_MISC(ab) ((ab)->hal.regs->hal_reo1_ring_misc) +#define HAL_REO1_RING_HP_ADDR_LSB(ab) ((ab)->hal.regs->hal_reo1_ring_hp_addr_lsb) +#define HAL_REO1_RING_HP_ADDR_MSB(ab) ((ab)->hal.regs->hal_reo1_ring_hp_addr_msb) #define HAL_REO1_RING_PRODUCER_INT_SETUP(ab) \ - ((ab)->hw_params->regs->hal_reo1_ring_producer_int_setup) + ((ab)->hal.regs->hal_reo1_ring_producer_int_setup) #define HAL_REO1_RING_MSI1_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_reo1_ring_msi1_base_lsb) + ((ab)->hal.regs->hal_reo1_ring_msi1_base_lsb) #define HAL_REO1_RING_MSI1_BASE_MSB(ab) \ - ((ab)->hw_params->regs->hal_reo1_ring_msi1_base_msb) -#define HAL_REO1_RING_MSI1_DATA(ab) ((ab)->hw_params->regs->hal_reo1_ring_msi1_data) -#define HAL_REO2_RING_BASE_LSB(ab) ((ab)->hw_params->regs->hal_reo2_ring_base) -#define HAL_REO1_AGING_THRESH_IX_0(ab) ((ab)->hw_params->regs->hal_reo1_aging_thres_ix0) -#define HAL_REO1_AGING_THRESH_IX_1(ab) ((ab)->hw_params->regs->hal_reo1_aging_thres_ix1) -#define HAL_REO1_AGING_THRESH_IX_2(ab) ((ab)->hw_params->regs->hal_reo1_aging_thres_ix2) -#define HAL_REO1_AGING_THRESH_IX_3(ab) ((ab)->hw_params->regs->hal_reo1_aging_thres_ix3) + ((ab)->hal.regs->hal_reo1_ring_msi1_base_msb) +#define HAL_REO1_RING_MSI1_DATA(ab) ((ab)->hal.regs->hal_reo1_ring_msi1_data) +#define HAL_REO2_RING_BASE_LSB(ab) ((ab)->hal.regs->hal_reo2_ring_base) +#define HAL_REO1_AGING_THRESH_IX_0(ab) ((ab)->hal.regs->hal_reo1_aging_thres_ix0) +#define HAL_REO1_AGING_THRESH_IX_1(ab) ((ab)->hal.regs->hal_reo1_aging_thres_ix1) +#define HAL_REO1_AGING_THRESH_IX_2(ab) ((ab)->hal.regs->hal_reo1_aging_thres_ix2) +#define HAL_REO1_AGING_THRESH_IX_3(ab) ((ab)->hal.regs->hal_reo1_aging_thres_ix3) /* REO2SW(x) R2 ring pointers (head/tail) address */ #define HAL_REO1_RING_HP 0x00003048 @@ -201,23 +201,23 @@ struct ath12k_base; /* REO2SW0 ring configuration address */ #define HAL_REO_SW0_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_reo2_sw0_ring_base) + ((ab)->hal.regs->hal_reo2_sw0_ring_base) /* REO2SW0 R2 ring pointer (head/tail) address */ #define HAL_REO_SW0_RING_HP 0x00003088 /* REO CMD R0 address */ #define HAL_REO_CMD_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_reo_cmd_ring_base) + ((ab)->hal.regs->hal_reo_cmd_ring_base) /* REO CMD R2 address */ #define HAL_REO_CMD_HP 0x00003020 /* SW2REO R0 address */ #define HAL_SW2REO_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_sw2reo_ring_base) + ((ab)->hal.regs->hal_sw2reo_ring_base) #define HAL_SW2REO1_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_sw2reo1_ring_base) + ((ab)->hal.regs->hal_sw2reo1_ring_base) /* SW2REO R2 address */ #define HAL_SW2REO_RING_HP 0x00003028 @@ -235,41 +235,41 @@ struct ath12k_base; /* REO status address */ #define HAL_REO_STATUS_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_reo_status_ring_base) + ((ab)->hal.regs->hal_reo_status_ring_base) #define HAL_REO_STATUS_HP 0x000030a8 /* WBM Idle R0 address */ #define HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_wbm_idle_ring_base_lsb) + ((ab)->hal.regs->hal_wbm_idle_ring_base_lsb) #define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(ab) \ - ((ab)->hw_params->regs->hal_wbm_idle_ring_misc_addr) + ((ab)->hal.regs->hal_wbm_idle_ring_misc_addr) #define HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(ab) \ - ((ab)->hw_params->regs->hal_wbm_r0_idle_list_cntl_addr) + ((ab)->hal.regs->hal_wbm_r0_idle_list_cntl_addr) #define HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(ab) \ - ((ab)->hw_params->regs->hal_wbm_r0_idle_list_size_addr) + ((ab)->hal.regs->hal_wbm_r0_idle_list_size_addr) #define HAL_WBM_SCATTERED_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_wbm_scattered_ring_base_lsb) + ((ab)->hal.regs->hal_wbm_scattered_ring_base_lsb) #define HAL_WBM_SCATTERED_RING_BASE_MSB(ab) \ - ((ab)->hw_params->regs->hal_wbm_scattered_ring_base_msb) + ((ab)->hal.regs->hal_wbm_scattered_ring_base_msb) #define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(ab) \ - ((ab)->hw_params->regs->hal_wbm_scattered_desc_head_info_ix0) + ((ab)->hal.regs->hal_wbm_scattered_desc_head_info_ix0) #define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(ab) \ - ((ab)->hw_params->regs->hal_wbm_scattered_desc_head_info_ix1) + ((ab)->hal.regs->hal_wbm_scattered_desc_head_info_ix1) #define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(ab) \ - ((ab)->hw_params->regs->hal_wbm_scattered_desc_tail_info_ix0) + ((ab)->hal.regs->hal_wbm_scattered_desc_tail_info_ix0) #define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(ab) \ - ((ab)->hw_params->regs->hal_wbm_scattered_desc_tail_info_ix1) + ((ab)->hal.regs->hal_wbm_scattered_desc_tail_info_ix1) #define HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(ab) \ - ((ab)->hw_params->regs->hal_wbm_scattered_desc_ptr_hp_addr) + ((ab)->hal.regs->hal_wbm_scattered_desc_ptr_hp_addr) /* WBM Idle R2 address */ #define HAL_WBM_IDLE_LINK_RING_HP 0x000030b8 /* SW2WBM R0 release address */ #define HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_wbm_sw_release_ring_base_lsb) + ((ab)->hal.regs->hal_wbm_sw_release_ring_base_lsb) #define HAL_WBM_SW1_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_wbm_sw1_release_ring_base_lsb) + ((ab)->hal.regs->hal_wbm_sw1_release_ring_base_lsb) /* SW2WBM R2 release address */ #define HAL_WBM_SW_RELEASE_RING_HP 0x00003010 @@ -277,10 +277,10 @@ struct ath12k_base; /* WBM2SW R0 release address */ #define HAL_WBM0_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_wbm0_release_ring_base_lsb) + ((ab)->hal.regs->hal_wbm0_release_ring_base_lsb) #define HAL_WBM1_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hw_params->regs->hal_wbm1_release_ring_base_lsb) + ((ab)->hal.regs->hal_wbm1_release_ring_base_lsb) /* WBM2SW R2 release address */ #define HAL_WBM0_RELEASE_RING_HP 0x000030c8 @@ -1440,6 +1440,91 @@ struct hal_reo_status { } u; }; +struct ath12k_hw_hal_params { + enum hal_rx_buf_return_buf_manager rx_buf_rbm; + u32 wbm2sw_cc_enable; +}; + +struct ath12k_hw_regs { + u32 hal_tcl1_ring_id; + u32 hal_tcl1_ring_misc; + u32 hal_tcl1_ring_tp_addr_lsb; + u32 hal_tcl1_ring_tp_addr_msb; + u32 hal_tcl1_ring_consumer_int_setup_ix0; + u32 hal_tcl1_ring_consumer_int_setup_ix1; + u32 hal_tcl1_ring_msi1_base_lsb; + u32 hal_tcl1_ring_msi1_base_msb; + u32 hal_tcl1_ring_msi1_data; + u32 hal_tcl_ring_base_lsb; + u32 hal_tcl1_ring_base_lsb; + u32 hal_tcl1_ring_base_msb; + u32 hal_tcl2_ring_base_lsb; + + u32 hal_tcl_status_ring_base_lsb; + + u32 hal_reo1_qdesc_addr; + u32 hal_reo1_qdesc_max_peerid; + + u32 hal_wbm_idle_ring_base_lsb; + u32 hal_wbm_idle_ring_misc_addr; + u32 hal_wbm_r0_idle_list_cntl_addr; + u32 hal_wbm_r0_idle_list_size_addr; + u32 hal_wbm_scattered_ring_base_lsb; + u32 hal_wbm_scattered_ring_base_msb; + u32 hal_wbm_scattered_desc_head_info_ix0; + u32 hal_wbm_scattered_desc_head_info_ix1; + u32 hal_wbm_scattered_desc_tail_info_ix0; + u32 hal_wbm_scattered_desc_tail_info_ix1; + u32 hal_wbm_scattered_desc_ptr_hp_addr; + + u32 hal_wbm_sw_release_ring_base_lsb; + u32 hal_wbm_sw1_release_ring_base_lsb; + u32 hal_wbm0_release_ring_base_lsb; + u32 hal_wbm1_release_ring_base_lsb; + + u32 pcie_qserdes_sysclk_en_sel; + u32 pcie_pcs_osc_dtct_config_base; + + u32 hal_umac_ce0_src_reg_base; + u32 hal_umac_ce0_dest_reg_base; + u32 hal_umac_ce1_src_reg_base; + u32 hal_umac_ce1_dest_reg_base; + + u32 hal_ppe_rel_ring_base; + + u32 hal_reo2_ring_base; + u32 hal_reo1_misc_ctrl_addr; + u32 hal_reo1_sw_cookie_cfg0; + u32 hal_reo1_sw_cookie_cfg1; + u32 hal_reo1_qdesc_lut_base0; + u32 hal_reo1_qdesc_lut_base1; + u32 hal_reo1_ring_base_lsb; + u32 hal_reo1_ring_base_msb; + u32 hal_reo1_ring_id; + u32 hal_reo1_ring_misc; + u32 hal_reo1_ring_hp_addr_lsb; + u32 hal_reo1_ring_hp_addr_msb; + u32 hal_reo1_ring_producer_int_setup; + u32 hal_reo1_ring_msi1_base_lsb; + u32 hal_reo1_ring_msi1_base_msb; + u32 hal_reo1_ring_msi1_data; + u32 hal_reo1_aging_thres_ix0; + u32 hal_reo1_aging_thres_ix1; + u32 hal_reo1_aging_thres_ix2; + u32 hal_reo1_aging_thres_ix3; + + u32 hal_reo2_sw0_ring_base; + + u32 hal_sw2reo_ring_base; + u32 hal_sw2reo1_ring_base; + + u32 hal_reo_cmd_ring_base; + + u32 hal_reo_status_ring_base; + + u32 gcc_gcc_pcie_hot_rst; +}; + /* HAL context to be used to access SRNG APIs (currently used by data path * and transport (CE) modules) */ @@ -1464,6 +1549,8 @@ struct ath12k_hal { } wrp; const struct hal_ops *hal_ops; + const struct ath12k_hw_regs *regs; + const struct ath12k_hw_hal_params *hal_params; /* Available REO blocking resources bitmap */ u8 avail_blk_resource; @@ -1586,6 +1673,8 @@ struct ath12k_hw_version_map { const struct hal_ops *hal_ops; u32 hal_desc_sz; const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; + const struct ath12k_hw_hal_params *hal_params; + const struct ath12k_hw_regs *hw_regs; }; struct hal_ops { diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h index 7e8f1f7ef5847..655753d0413ae 100644 --- a/drivers/net/wireless/ath/ath12k/hw.h +++ b/drivers/net/wireless/ath/ath12k/hw.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 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 ATH12K_HW_H @@ -128,11 +128,6 @@ struct ath12k_hw_ring_mask { u8 tx_mon_dest[ATH12K_EXT_IRQ_GRP_NUM_MAX]; }; -struct ath12k_hw_hal_params { - enum hal_rx_buf_return_buf_manager rx_buf_rbm; - u32 wbm2sw_cc_enable; -}; - enum ath12k_m3_fw_loaders { ath12k_m3_fw_loader_driver, ath12k_m3_fw_loader_remoteproc, @@ -156,7 +151,6 @@ struct ath12k_hw_params { const struct ath12k_hw_ops *hw_ops; const struct ath12k_hw_ring_mask *ring_mask; - const struct ath12k_hw_regs *regs; const struct ce_attr *host_ce_config; u32 ce_count; @@ -165,8 +159,6 @@ struct ath12k_hw_params { const struct service_to_pipe *svc_to_ce_map; u32 svc_to_ce_map_len; - const struct ath12k_hw_hal_params *hal_params; - bool rxdma1_enable:1; int num_rxdma_per_pdev; int num_rxdma_dst_ring; @@ -283,86 +275,6 @@ enum ath12k_bd_ie_type { ATH12K_BD_IE_REGDB = 1, }; -struct ath12k_hw_regs { - u32 hal_tcl1_ring_id; - u32 hal_tcl1_ring_misc; - u32 hal_tcl1_ring_tp_addr_lsb; - u32 hal_tcl1_ring_tp_addr_msb; - u32 hal_tcl1_ring_consumer_int_setup_ix0; - u32 hal_tcl1_ring_consumer_int_setup_ix1; - u32 hal_tcl1_ring_msi1_base_lsb; - u32 hal_tcl1_ring_msi1_base_msb; - u32 hal_tcl1_ring_msi1_data; - u32 hal_tcl_ring_base_lsb; - u32 hal_tcl1_ring_base_lsb; - u32 hal_tcl1_ring_base_msb; - u32 hal_tcl2_ring_base_lsb; - - u32 hal_tcl_status_ring_base_lsb; - - u32 hal_reo1_qdesc_addr; - u32 hal_reo1_qdesc_max_peerid; - - u32 hal_wbm_idle_ring_base_lsb; - u32 hal_wbm_idle_ring_misc_addr; - u32 hal_wbm_r0_idle_list_cntl_addr; - u32 hal_wbm_r0_idle_list_size_addr; - u32 hal_wbm_scattered_ring_base_lsb; - u32 hal_wbm_scattered_ring_base_msb; - u32 hal_wbm_scattered_desc_head_info_ix0; - u32 hal_wbm_scattered_desc_head_info_ix1; - u32 hal_wbm_scattered_desc_tail_info_ix0; - u32 hal_wbm_scattered_desc_tail_info_ix1; - u32 hal_wbm_scattered_desc_ptr_hp_addr; - - u32 hal_wbm_sw_release_ring_base_lsb; - u32 hal_wbm_sw1_release_ring_base_lsb; - u32 hal_wbm0_release_ring_base_lsb; - u32 hal_wbm1_release_ring_base_lsb; - - u32 pcie_qserdes_sysclk_en_sel; - u32 pcie_pcs_osc_dtct_config_base; - - u32 hal_umac_ce0_src_reg_base; - u32 hal_umac_ce0_dest_reg_base; - u32 hal_umac_ce1_src_reg_base; - u32 hal_umac_ce1_dest_reg_base; - - u32 hal_ppe_rel_ring_base; - - u32 hal_reo2_ring_base; - u32 hal_reo1_misc_ctrl_addr; - u32 hal_reo1_sw_cookie_cfg0; - u32 hal_reo1_sw_cookie_cfg1; - u32 hal_reo1_qdesc_lut_base0; - u32 hal_reo1_qdesc_lut_base1; - u32 hal_reo1_ring_base_lsb; - u32 hal_reo1_ring_base_msb; - u32 hal_reo1_ring_id; - u32 hal_reo1_ring_misc; - u32 hal_reo1_ring_hp_addr_lsb; - u32 hal_reo1_ring_hp_addr_msb; - u32 hal_reo1_ring_producer_int_setup; - u32 hal_reo1_ring_msi1_base_lsb; - u32 hal_reo1_ring_msi1_base_msb; - u32 hal_reo1_ring_msi1_data; - u32 hal_reo1_aging_thres_ix0; - u32 hal_reo1_aging_thres_ix1; - u32 hal_reo1_aging_thres_ix2; - u32 hal_reo1_aging_thres_ix3; - - u32 hal_reo2_sw0_ring_base; - - u32 hal_sw2reo_ring_base; - u32 hal_sw2reo1_ring_base; - - u32 hal_reo_cmd_ring_base; - - u32 hal_reo_status_ring_base; - - u32 gcc_gcc_pcie_hot_rst; -}; - static inline const char *ath12k_bd_ie_type_str(enum ath12k_bd_ie_type type) { switch (type) { diff --git a/drivers/net/wireless/ath/ath12k/pci.h b/drivers/net/wireless/ath/ath12k/pci.h index 2c19bb42f0f70..1cc4f0e050f95 100644 --- a/drivers/net/wireless/ath/ath12k/pci.h +++ b/drivers/net/wireless/ath/ath12k/pci.h @@ -30,7 +30,7 @@ #define PARM_LTSSM_VALUE 0x111 #define GCC_GCC_PCIE_HOT_RST(ab) \ - ((ab)->hw_params->regs->gcc_gcc_pcie_hot_rst) + ((ab)->hal.regs->gcc_gcc_pcie_hot_rst) #define GCC_GCC_PCIE_HOT_RST_VAL 0x10 @@ -39,17 +39,17 @@ #define PCIE_INT_CLEAR_ALL 0xffffffff #define PCIE_QSERDES_COM_SYSCLK_EN_SEL_REG(ab) \ - ((ab)->hw_params->regs->pcie_qserdes_sysclk_en_sel) + ((ab)->hal.regs->pcie_qserdes_sysclk_en_sel) #define PCIE_QSERDES_COM_SYSCLK_EN_SEL_VAL 0x10 #define PCIE_QSERDES_COM_SYSCLK_EN_SEL_MSK 0xffffffff #define PCIE_PCS_OSC_DTCT_CONFIG1_REG(ab) \ - ((ab)->hw_params->regs->pcie_pcs_osc_dtct_config_base) + ((ab)->hal.regs->pcie_pcs_osc_dtct_config_base) #define PCIE_PCS_OSC_DTCT_CONFIG1_VAL 0x02 #define PCIE_PCS_OSC_DTCT_CONFIG2_REG(ab) \ - ((ab)->hw_params->regs->pcie_pcs_osc_dtct_config_base + 0x4) + ((ab)->hal.regs->pcie_pcs_osc_dtct_config_base + 0x4) #define PCIE_PCS_OSC_DTCT_CONFIG2_VAL 0x52 #define PCIE_PCS_OSC_DTCT_CONFIG4_REG(ab) \ - ((ab)->hw_params->regs->pcie_pcs_osc_dtct_config_base + 0xc) + ((ab)->hal.regs->pcie_pcs_osc_dtct_config_base + 0xc) #define PCIE_PCS_OSC_DTCT_CONFIG4_VAL 0xff #define PCIE_PCS_OSC_DTCT_CONFIG_MSK 0x000000ff diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index d6ce6b9bb4d71..eef8d25584946 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -1383,7 +1383,7 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n msdu_cookies, &rbm); if (rbm != partner_dp->idle_link_rbm && rbm != HAL_RX_BUF_RBM_SW3_BM && - rbm != partner_ab->hw_params->hal_params->rx_buf_rbm) { + rbm != partner_ab->hal.hal_params->rx_buf_rbm) { act = HAL_WBM_REL_BM_ACT_REL_MSDU; ab->device_stats.invalid_rbm++; ath12k_warn(ab, "invalid return buffer manager %d\n", rbm); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 53ea3792ef518..25963ac18cb9b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -15,21 +15,29 @@ static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = { .hal_ops = &hal_qcn9274_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_qcn9274, + .hal_params = &ath12k_hw_hal_params_qcn9274, + .hw_regs = &qcn9274_v1_regs, }, [ATH12K_HW_QCN9274_HW20] = { .hal_ops = &hal_qcn9274_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_qcn9274, + .hal_params = &ath12k_hw_hal_params_qcn9274, + .hw_regs = &qcn9274_v2_regs, }, [ATH12K_HW_WCN7850_HW20] = { .hal_ops = &hal_wcn7850_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_wcn7850), .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_wcn7850, + .hal_params = &ath12k_hw_hal_params_wcn7850, + .hw_regs = &wcn7850_regs, }, [ATH12K_HW_IPQ5332_HW10] = { .hal_ops = &hal_qcn9274_ops, .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact), .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_qcn9274, + .hal_params = &ath12k_hw_hal_params_ipq5332, + .hw_regs = &ipq5332_regs, }, }; @@ -42,6 +50,8 @@ int ath12k_wifi7_hal_init(struct ath12k_base *ab) hal->hal_ops = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_ops; hal->hal_desc_sz = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_desc_sz; hal->tcl_to_wbm_rbm_map = ath12k_wifi7_hw_ver_map[ab->hw_rev].tcl_to_wbm_rbm_map; + hal->regs = ath12k_wifi7_hw_ver_map[ab->hw_rev].hw_regs; + hal->hal_params = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_params; return 0; } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index 0dc5eaec5fb0a..1a8a720c49236 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -8,5 +8,4 @@ #define ATH12K_HAL_WIFI7_H int ath12k_wifi7_hal_init(struct ath12k_base *ab); - #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index fefa151efaefc..265e9f3688587 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -5,6 +5,8 @@ */ #include "hal_desc.h" #include "hal_qcn9274.h" +#include "hw.h" +#include "hal.h" static const struct hal_srng_config hw_srng_config_template[] = { /* TODO: max_rings can populated by querying HW capabilities */ @@ -209,6 +211,274 @@ static const struct hal_srng_config hw_srng_config_template[] = { } }; +const struct ath12k_hw_regs qcn9274_v1_regs = { + /* SW2TCL(x) R0 ring configuration address */ + .hal_tcl1_ring_id = 0x00000908, + .hal_tcl1_ring_misc = 0x00000910, + .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, + .hal_tcl1_ring_tp_addr_msb = 0x00000920, + .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, + .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, + .hal_tcl1_ring_msi1_base_lsb = 0x00000948, + .hal_tcl1_ring_msi1_base_msb = 0x0000094c, + .hal_tcl1_ring_msi1_data = 0x00000950, + .hal_tcl_ring_base_lsb = 0x00000b58, + .hal_tcl1_ring_base_lsb = 0x00000900, + .hal_tcl1_ring_base_msb = 0x00000904, + .hal_tcl2_ring_base_lsb = 0x00000978, + + /* TCL STATUS ring address */ + .hal_tcl_status_ring_base_lsb = 0x00000d38, + + .hal_wbm_idle_ring_base_lsb = 0x00000d0c, + .hal_wbm_idle_ring_misc_addr = 0x00000d1c, + .hal_wbm_r0_idle_list_cntl_addr = 0x00000210, + .hal_wbm_r0_idle_list_size_addr = 0x00000214, + .hal_wbm_scattered_ring_base_lsb = 0x00000220, + .hal_wbm_scattered_ring_base_msb = 0x00000224, + .hal_wbm_scattered_desc_head_info_ix0 = 0x00000230, + .hal_wbm_scattered_desc_head_info_ix1 = 0x00000234, + .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000240, + .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000244, + .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000024c, + + .hal_wbm_sw_release_ring_base_lsb = 0x0000034c, + .hal_wbm_sw1_release_ring_base_lsb = 0x000003c4, + .hal_wbm0_release_ring_base_lsb = 0x00000dd8, + .hal_wbm1_release_ring_base_lsb = 0x00000e50, + + /* PCIe base address */ + .pcie_qserdes_sysclk_en_sel = 0x01e0c0a8, + .pcie_pcs_osc_dtct_config_base = 0x01e0d45c, + + /* PPE release ring address */ + .hal_ppe_rel_ring_base = 0x0000043c, + + /* REO DEST ring address */ + .hal_reo2_ring_base = 0x0000055c, + .hal_reo1_misc_ctrl_addr = 0x00000b7c, + .hal_reo1_sw_cookie_cfg0 = 0x00000050, + .hal_reo1_sw_cookie_cfg1 = 0x00000054, + .hal_reo1_qdesc_lut_base0 = 0x00000058, + .hal_reo1_qdesc_lut_base1 = 0x0000005c, + .hal_reo1_ring_base_lsb = 0x000004e4, + .hal_reo1_ring_base_msb = 0x000004e8, + .hal_reo1_ring_id = 0x000004ec, + .hal_reo1_ring_misc = 0x000004f4, + .hal_reo1_ring_hp_addr_lsb = 0x000004f8, + .hal_reo1_ring_hp_addr_msb = 0x000004fc, + .hal_reo1_ring_producer_int_setup = 0x00000508, + .hal_reo1_ring_msi1_base_lsb = 0x0000052C, + .hal_reo1_ring_msi1_base_msb = 0x00000530, + .hal_reo1_ring_msi1_data = 0x00000534, + .hal_reo1_aging_thres_ix0 = 0x00000b08, + .hal_reo1_aging_thres_ix1 = 0x00000b0c, + .hal_reo1_aging_thres_ix2 = 0x00000b10, + .hal_reo1_aging_thres_ix3 = 0x00000b14, + + /* REO Exception ring address */ + .hal_reo2_sw0_ring_base = 0x000008a4, + + /* REO Reinject ring address */ + .hal_sw2reo_ring_base = 0x00000304, + .hal_sw2reo1_ring_base = 0x0000037c, + + /* REO cmd ring address */ + .hal_reo_cmd_ring_base = 0x0000028c, + + /* REO status ring address */ + .hal_reo_status_ring_base = 0x00000a84, + + /* CE base address */ + .hal_umac_ce0_src_reg_base = 0x01b80000, + .hal_umac_ce0_dest_reg_base = 0x01b81000, + .hal_umac_ce1_src_reg_base = 0x01b82000, + .hal_umac_ce1_dest_reg_base = 0x01b83000, + + .gcc_gcc_pcie_hot_rst = 0x1e38338, +}; + +const struct ath12k_hw_regs qcn9274_v2_regs = { + /* SW2TCL(x) R0 ring configuration address */ + .hal_tcl1_ring_id = 0x00000908, + .hal_tcl1_ring_misc = 0x00000910, + .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, + .hal_tcl1_ring_tp_addr_msb = 0x00000920, + .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, + .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, + .hal_tcl1_ring_msi1_base_lsb = 0x00000948, + .hal_tcl1_ring_msi1_base_msb = 0x0000094c, + .hal_tcl1_ring_msi1_data = 0x00000950, + .hal_tcl_ring_base_lsb = 0x00000b58, + .hal_tcl1_ring_base_lsb = 0x00000900, + .hal_tcl1_ring_base_msb = 0x00000904, + .hal_tcl2_ring_base_lsb = 0x00000978, + + /* TCL STATUS ring address */ + .hal_tcl_status_ring_base_lsb = 0x00000d38, + + /* WBM idle link ring address */ + .hal_wbm_idle_ring_base_lsb = 0x00000d3c, + .hal_wbm_idle_ring_misc_addr = 0x00000d4c, + .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, + .hal_wbm_r0_idle_list_size_addr = 0x00000244, + .hal_wbm_scattered_ring_base_lsb = 0x00000250, + .hal_wbm_scattered_ring_base_msb = 0x00000254, + .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, + .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, + .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, + .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, + .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000027c, + + /* SW2WBM release ring address */ + .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, + .hal_wbm_sw1_release_ring_base_lsb = 0x000003f4, + + /* WBM2SW release ring address */ + .hal_wbm0_release_ring_base_lsb = 0x00000e08, + .hal_wbm1_release_ring_base_lsb = 0x00000e80, + + /* PCIe base address */ + .pcie_qserdes_sysclk_en_sel = 0x01e0c0a8, + .pcie_pcs_osc_dtct_config_base = 0x01e0d45c, + + /* PPE release ring address */ + .hal_ppe_rel_ring_base = 0x0000046c, + + /* REO DEST ring address */ + .hal_reo2_ring_base = 0x00000578, + .hal_reo1_misc_ctrl_addr = 0x00000b9c, + .hal_reo1_sw_cookie_cfg0 = 0x0000006c, + .hal_reo1_sw_cookie_cfg1 = 0x00000070, + .hal_reo1_qdesc_lut_base0 = 0x00000074, + .hal_reo1_qdesc_lut_base1 = 0x00000078, + .hal_reo1_qdesc_addr = 0x0000007c, + .hal_reo1_qdesc_max_peerid = 0x00000088, + .hal_reo1_ring_base_lsb = 0x00000500, + .hal_reo1_ring_base_msb = 0x00000504, + .hal_reo1_ring_id = 0x00000508, + .hal_reo1_ring_misc = 0x00000510, + .hal_reo1_ring_hp_addr_lsb = 0x00000514, + .hal_reo1_ring_hp_addr_msb = 0x00000518, + .hal_reo1_ring_producer_int_setup = 0x00000524, + .hal_reo1_ring_msi1_base_lsb = 0x00000548, + .hal_reo1_ring_msi1_base_msb = 0x0000054C, + .hal_reo1_ring_msi1_data = 0x00000550, + .hal_reo1_aging_thres_ix0 = 0x00000B28, + .hal_reo1_aging_thres_ix1 = 0x00000B2C, + .hal_reo1_aging_thres_ix2 = 0x00000B30, + .hal_reo1_aging_thres_ix3 = 0x00000B34, + + /* REO Exception ring address */ + .hal_reo2_sw0_ring_base = 0x000008c0, + + /* REO Reinject ring address */ + .hal_sw2reo_ring_base = 0x00000320, + .hal_sw2reo1_ring_base = 0x00000398, + + /* REO cmd ring address */ + .hal_reo_cmd_ring_base = 0x000002A8, + + /* REO status ring address */ + .hal_reo_status_ring_base = 0x00000aa0, + + /* CE base address */ + .hal_umac_ce0_src_reg_base = 0x01b80000, + .hal_umac_ce0_dest_reg_base = 0x01b81000, + .hal_umac_ce1_src_reg_base = 0x01b82000, + .hal_umac_ce1_dest_reg_base = 0x01b83000, + + .gcc_gcc_pcie_hot_rst = 0x1e38338, +}; + +const struct ath12k_hw_regs ipq5332_regs = { + /* SW2TCL(x) R0 ring configuration address */ + .hal_tcl1_ring_id = 0x00000918, + .hal_tcl1_ring_misc = 0x00000920, + .hal_tcl1_ring_tp_addr_lsb = 0x0000092c, + .hal_tcl1_ring_tp_addr_msb = 0x00000930, + .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000940, + .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000944, + .hal_tcl1_ring_msi1_base_lsb = 0x00000958, + .hal_tcl1_ring_msi1_base_msb = 0x0000095c, + .hal_tcl1_ring_base_lsb = 0x00000910, + .hal_tcl1_ring_base_msb = 0x00000914, + .hal_tcl1_ring_msi1_data = 0x00000960, + .hal_tcl2_ring_base_lsb = 0x00000988, + .hal_tcl_ring_base_lsb = 0x00000b68, + + /* TCL STATUS ring address */ + .hal_tcl_status_ring_base_lsb = 0x00000d48, + + /* REO DEST ring address */ + .hal_reo2_ring_base = 0x00000578, + .hal_reo1_misc_ctrl_addr = 0x00000b9c, + .hal_reo1_sw_cookie_cfg0 = 0x0000006c, + .hal_reo1_sw_cookie_cfg1 = 0x00000070, + .hal_reo1_qdesc_lut_base0 = 0x00000074, + .hal_reo1_qdesc_lut_base1 = 0x00000078, + .hal_reo1_ring_base_lsb = 0x00000500, + .hal_reo1_ring_base_msb = 0x00000504, + .hal_reo1_ring_id = 0x00000508, + .hal_reo1_ring_misc = 0x00000510, + .hal_reo1_ring_hp_addr_lsb = 0x00000514, + .hal_reo1_ring_hp_addr_msb = 0x00000518, + .hal_reo1_ring_producer_int_setup = 0x00000524, + .hal_reo1_ring_msi1_base_lsb = 0x00000548, + .hal_reo1_ring_msi1_base_msb = 0x0000054C, + .hal_reo1_ring_msi1_data = 0x00000550, + .hal_reo1_aging_thres_ix0 = 0x00000B28, + .hal_reo1_aging_thres_ix1 = 0x00000B2C, + .hal_reo1_aging_thres_ix2 = 0x00000B30, + .hal_reo1_aging_thres_ix3 = 0x00000B34, + + /* REO Exception ring address */ + .hal_reo2_sw0_ring_base = 0x000008c0, + + /* REO Reinject ring address */ + .hal_sw2reo_ring_base = 0x00000320, + .hal_sw2reo1_ring_base = 0x00000398, + + /* REO cmd ring address */ + .hal_reo_cmd_ring_base = 0x000002A8, + + /* REO status ring address */ + .hal_reo_status_ring_base = 0x00000aa0, + + /* WBM idle link ring address */ + .hal_wbm_idle_ring_base_lsb = 0x00000d3c, + .hal_wbm_idle_ring_misc_addr = 0x00000d4c, + .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, + .hal_wbm_r0_idle_list_size_addr = 0x00000244, + .hal_wbm_scattered_ring_base_lsb = 0x00000250, + .hal_wbm_scattered_ring_base_msb = 0x00000254, + .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, + .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, + .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, + .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, + .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000027c, + + /* SW2WBM release ring address */ + .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, + + /* WBM2SW release ring address */ + .hal_wbm0_release_ring_base_lsb = 0x00000e08, + .hal_wbm1_release_ring_base_lsb = 0x00000e80, + + /* PPE release ring address */ + .hal_ppe_rel_ring_base = 0x0000046c, + + /* CE address */ + .hal_umac_ce0_src_reg_base = 0x00740000 - + HAL_IPQ5332_CE_WFSS_REG_BASE, + .hal_umac_ce0_dest_reg_base = 0x00741000 - + HAL_IPQ5332_CE_WFSS_REG_BASE, + .hal_umac_ce1_src_reg_base = 0x00742000 - + HAL_IPQ5332_CE_WFSS_REG_BASE, + .hal_umac_ce1_dest_reg_base = 0x00743000 - + HAL_IPQ5332_CE_WFSS_REG_BASE, +}; + static inline bool ath12k_hal_rx_desc_get_first_msdu_qcn9274(struct hal_rx_desc *desc) { @@ -571,6 +841,24 @@ void ath12k_hal_extract_rx_desc_data_qcn9274(struct hal_rx_desc_data *rx_desc_da rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_qcn9274(rx_desc); } +const struct ath12k_hw_hal_params ath12k_hw_hal_params_qcn9274 = { + .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, + .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW1_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, +}; + +const struct ath12k_hw_hal_params ath12k_hw_hal_params_ipq5332 = { + .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, + .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW1_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, +}; + static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) { struct ath12k_hal *hal = &ab->hal; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h index 1b431d5b64170..c48dd029f52ee 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h @@ -13,8 +13,13 @@ #include "hal_rx.h" extern const struct hal_ops hal_qcn9274_ops; +extern const struct ath12k_hw_regs qcn9274_v1_regs; +extern const struct ath12k_hw_regs qcn9274_v2_regs; +extern const struct ath12k_hw_regs ipq5332_regs; extern const struct ath12k_hal_tcl_to_wbm_rbm_map ath12k_hal_tcl_to_wbm_rbm_map_qcn9274[DP_TCL_NUM_RING_MAX]; +extern const struct ath12k_hw_hal_params ath12k_hw_hal_params_qcn9274; +extern const struct ath12k_hw_hal_params ath12k_hw_hal_params_ipq5332; u8 ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_copy_end_tlv_qcn9274(struct hal_rx_desc *fdesc, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 3e88a1e68b87b..b3ed7c8d738d8 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -6,6 +6,8 @@ #include "hal_desc.h" #include "hal_wcn7850.h" +#include "hw.h" +#include "hal.h" static const struct hal_srng_config hw_srng_config_template[] = { /* TODO: max_rings can populated by querying HW capabilities */ @@ -210,6 +212,93 @@ static const struct hal_srng_config hw_srng_config_template[] = { } }; +const struct ath12k_hw_regs wcn7850_regs = { + /* SW2TCL(x) R0 ring configuration address */ + .hal_tcl1_ring_id = 0x00000908, + .hal_tcl1_ring_misc = 0x00000910, + .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, + .hal_tcl1_ring_tp_addr_msb = 0x00000920, + .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, + .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, + .hal_tcl1_ring_msi1_base_lsb = 0x00000948, + .hal_tcl1_ring_msi1_base_msb = 0x0000094c, + .hal_tcl1_ring_msi1_data = 0x00000950, + .hal_tcl_ring_base_lsb = 0x00000b58, + .hal_tcl1_ring_base_lsb = 0x00000900, + .hal_tcl1_ring_base_msb = 0x00000904, + .hal_tcl2_ring_base_lsb = 0x00000978, + + /* TCL STATUS ring address */ + .hal_tcl_status_ring_base_lsb = 0x00000d38, + + .hal_wbm_idle_ring_base_lsb = 0x00000d3c, + .hal_wbm_idle_ring_misc_addr = 0x00000d4c, + .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, + .hal_wbm_r0_idle_list_size_addr = 0x00000244, + .hal_wbm_scattered_ring_base_lsb = 0x00000250, + .hal_wbm_scattered_ring_base_msb = 0x00000254, + .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, + .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, + .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, + .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, + .hal_wbm_scattered_desc_ptr_hp_addr = 0x00000027c, + + .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, + .hal_wbm_sw1_release_ring_base_lsb = 0x00000284, + .hal_wbm0_release_ring_base_lsb = 0x00000e08, + .hal_wbm1_release_ring_base_lsb = 0x00000e80, + + /* PCIe base address */ + .pcie_qserdes_sysclk_en_sel = 0x01e0e0a8, + .pcie_pcs_osc_dtct_config_base = 0x01e0f45c, + + /* PPE release ring address */ + .hal_ppe_rel_ring_base = 0x0000043c, + + /* REO DEST ring address */ + .hal_reo2_ring_base = 0x0000055c, + .hal_reo1_misc_ctrl_addr = 0x00000b7c, + .hal_reo1_sw_cookie_cfg0 = 0x00000050, + .hal_reo1_sw_cookie_cfg1 = 0x00000054, + .hal_reo1_qdesc_lut_base0 = 0x00000058, + .hal_reo1_qdesc_lut_base1 = 0x0000005c, + .hal_reo1_ring_base_lsb = 0x000004e4, + .hal_reo1_ring_base_msb = 0x000004e8, + .hal_reo1_ring_id = 0x000004ec, + .hal_reo1_ring_misc = 0x000004f4, + .hal_reo1_ring_hp_addr_lsb = 0x000004f8, + .hal_reo1_ring_hp_addr_msb = 0x000004fc, + .hal_reo1_ring_producer_int_setup = 0x00000508, + .hal_reo1_ring_msi1_base_lsb = 0x0000052C, + .hal_reo1_ring_msi1_base_msb = 0x00000530, + .hal_reo1_ring_msi1_data = 0x00000534, + .hal_reo1_aging_thres_ix0 = 0x00000b08, + .hal_reo1_aging_thres_ix1 = 0x00000b0c, + .hal_reo1_aging_thres_ix2 = 0x00000b10, + .hal_reo1_aging_thres_ix3 = 0x00000b14, + + /* REO Exception ring address */ + .hal_reo2_sw0_ring_base = 0x000008a4, + + /* REO Reinject ring address */ + .hal_sw2reo_ring_base = 0x00000304, + .hal_sw2reo1_ring_base = 0x0000037c, + + /* REO cmd ring address */ + .hal_reo_cmd_ring_base = 0x0000028c, + + /* REO status ring address */ + .hal_reo_status_ring_base = 0x00000a84, + + /* CE base address */ + .hal_umac_ce0_src_reg_base = 0x01b80000, + .hal_umac_ce0_dest_reg_base = 0x01b81000, + .hal_umac_ce1_src_reg_base = 0x01b82000, + .hal_umac_ce1_dest_reg_base = 0x01b83000, + + .gcc_gcc_pcie_hot_rst = 0x1e40304, +}; + static inline bool ath12k_hal_rx_desc_get_first_msdu_wcn7850(struct hal_rx_desc *desc) { @@ -706,6 +795,14 @@ ath12k_hal_tcl_to_wbm_rbm_map_wcn7850[DP_TCL_NUM_RING_MAX] = { }, }; +const struct ath12k_hw_hal_params ath12k_hw_hal_params_wcn7850 = { + .rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM, + .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN | + HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, +}; + const struct hal_ops hal_wcn7850_ops = { .create_srng_config = ath12k_hal_srng_create_config_wcn7850, .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_wcn7850, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h index 2df4976f59aa4..7d0b0c9854468 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -11,8 +11,10 @@ #include "hal_rx.h" extern const struct hal_ops hal_wcn7850_ops; +extern const struct ath12k_hw_regs wcn7850_regs; extern const struct ath12k_hal_tcl_to_wbm_rbm_map ath12k_hal_tcl_to_wbm_rbm_map_wcn7850[DP_TCL_NUM_RING_MAX]; +extern const struct ath12k_hw_hal_params ath12k_hw_hal_params_wcn7850; u8 ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850(struct hal_rx_desc *desc); void ath12k_hal_rx_desc_copy_end_tlv_wcn7850(struct hal_rx_desc *fdesc, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index f469a829ae9a7..01c859f35a937 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -310,387 +310,6 @@ static const struct ath12k_hw_ring_mask ath12k_wifi7_hw_ring_mask_wcn7850 = { }, }; -static const struct ath12k_hw_regs qcn9274_v1_regs = { - /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_id = 0x00000908, - .hal_tcl1_ring_misc = 0x00000910, - .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, - .hal_tcl1_ring_tp_addr_msb = 0x00000920, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, - .hal_tcl1_ring_msi1_base_lsb = 0x00000948, - .hal_tcl1_ring_msi1_base_msb = 0x0000094c, - .hal_tcl1_ring_msi1_data = 0x00000950, - .hal_tcl_ring_base_lsb = 0x00000b58, - .hal_tcl1_ring_base_lsb = 0x00000900, - .hal_tcl1_ring_base_msb = 0x00000904, - .hal_tcl2_ring_base_lsb = 0x00000978, - - /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000d38, - - .hal_wbm_idle_ring_base_lsb = 0x00000d0c, - .hal_wbm_idle_ring_misc_addr = 0x00000d1c, - .hal_wbm_r0_idle_list_cntl_addr = 0x00000210, - .hal_wbm_r0_idle_list_size_addr = 0x00000214, - .hal_wbm_scattered_ring_base_lsb = 0x00000220, - .hal_wbm_scattered_ring_base_msb = 0x00000224, - .hal_wbm_scattered_desc_head_info_ix0 = 0x00000230, - .hal_wbm_scattered_desc_head_info_ix1 = 0x00000234, - .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000240, - .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000244, - .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000024c, - - .hal_wbm_sw_release_ring_base_lsb = 0x0000034c, - .hal_wbm_sw1_release_ring_base_lsb = 0x000003c4, - .hal_wbm0_release_ring_base_lsb = 0x00000dd8, - .hal_wbm1_release_ring_base_lsb = 0x00000e50, - - /* PCIe base address */ - .pcie_qserdes_sysclk_en_sel = 0x01e0c0a8, - .pcie_pcs_osc_dtct_config_base = 0x01e0d45c, - - /* PPE release ring address */ - .hal_ppe_rel_ring_base = 0x0000043c, - - /* REO DEST ring address */ - .hal_reo2_ring_base = 0x0000055c, - .hal_reo1_misc_ctrl_addr = 0x00000b7c, - .hal_reo1_sw_cookie_cfg0 = 0x00000050, - .hal_reo1_sw_cookie_cfg1 = 0x00000054, - .hal_reo1_qdesc_lut_base0 = 0x00000058, - .hal_reo1_qdesc_lut_base1 = 0x0000005c, - .hal_reo1_ring_base_lsb = 0x000004e4, - .hal_reo1_ring_base_msb = 0x000004e8, - .hal_reo1_ring_id = 0x000004ec, - .hal_reo1_ring_misc = 0x000004f4, - .hal_reo1_ring_hp_addr_lsb = 0x000004f8, - .hal_reo1_ring_hp_addr_msb = 0x000004fc, - .hal_reo1_ring_producer_int_setup = 0x00000508, - .hal_reo1_ring_msi1_base_lsb = 0x0000052C, - .hal_reo1_ring_msi1_base_msb = 0x00000530, - .hal_reo1_ring_msi1_data = 0x00000534, - .hal_reo1_aging_thres_ix0 = 0x00000b08, - .hal_reo1_aging_thres_ix1 = 0x00000b0c, - .hal_reo1_aging_thres_ix2 = 0x00000b10, - .hal_reo1_aging_thres_ix3 = 0x00000b14, - - /* REO Exception ring address */ - .hal_reo2_sw0_ring_base = 0x000008a4, - - /* REO Reinject ring address */ - .hal_sw2reo_ring_base = 0x00000304, - .hal_sw2reo1_ring_base = 0x0000037c, - - /* REO cmd ring address */ - .hal_reo_cmd_ring_base = 0x0000028c, - - /* REO status ring address */ - .hal_reo_status_ring_base = 0x00000a84, - - /* CE base address */ - .hal_umac_ce0_src_reg_base = 0x01b80000, - .hal_umac_ce0_dest_reg_base = 0x01b81000, - .hal_umac_ce1_src_reg_base = 0x01b82000, - .hal_umac_ce1_dest_reg_base = 0x01b83000, - - .gcc_gcc_pcie_hot_rst = 0x1e38338, -}; - -static const struct ath12k_hw_regs qcn9274_v2_regs = { - /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_id = 0x00000908, - .hal_tcl1_ring_misc = 0x00000910, - .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, - .hal_tcl1_ring_tp_addr_msb = 0x00000920, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, - .hal_tcl1_ring_msi1_base_lsb = 0x00000948, - .hal_tcl1_ring_msi1_base_msb = 0x0000094c, - .hal_tcl1_ring_msi1_data = 0x00000950, - .hal_tcl_ring_base_lsb = 0x00000b58, - .hal_tcl1_ring_base_lsb = 0x00000900, - .hal_tcl1_ring_base_msb = 0x00000904, - .hal_tcl2_ring_base_lsb = 0x00000978, - - /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000d38, - - /* WBM idle link ring address */ - .hal_wbm_idle_ring_base_lsb = 0x00000d3c, - .hal_wbm_idle_ring_misc_addr = 0x00000d4c, - .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, - .hal_wbm_r0_idle_list_size_addr = 0x00000244, - .hal_wbm_scattered_ring_base_lsb = 0x00000250, - .hal_wbm_scattered_ring_base_msb = 0x00000254, - .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, - .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, - .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, - .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, - .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000027c, - - /* SW2WBM release ring address */ - .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, - .hal_wbm_sw1_release_ring_base_lsb = 0x000003f4, - - /* WBM2SW release ring address */ - .hal_wbm0_release_ring_base_lsb = 0x00000e08, - .hal_wbm1_release_ring_base_lsb = 0x00000e80, - - /* PCIe base address */ - .pcie_qserdes_sysclk_en_sel = 0x01e0c0a8, - .pcie_pcs_osc_dtct_config_base = 0x01e0d45c, - - /* PPE release ring address */ - .hal_ppe_rel_ring_base = 0x0000046c, - - /* REO DEST ring address */ - .hal_reo2_ring_base = 0x00000578, - .hal_reo1_misc_ctrl_addr = 0x00000b9c, - .hal_reo1_sw_cookie_cfg0 = 0x0000006c, - .hal_reo1_sw_cookie_cfg1 = 0x00000070, - .hal_reo1_qdesc_lut_base0 = 0x00000074, - .hal_reo1_qdesc_lut_base1 = 0x00000078, - .hal_reo1_qdesc_addr = 0x0000007c, - .hal_reo1_qdesc_max_peerid = 0x00000088, - .hal_reo1_ring_base_lsb = 0x00000500, - .hal_reo1_ring_base_msb = 0x00000504, - .hal_reo1_ring_id = 0x00000508, - .hal_reo1_ring_misc = 0x00000510, - .hal_reo1_ring_hp_addr_lsb = 0x00000514, - .hal_reo1_ring_hp_addr_msb = 0x00000518, - .hal_reo1_ring_producer_int_setup = 0x00000524, - .hal_reo1_ring_msi1_base_lsb = 0x00000548, - .hal_reo1_ring_msi1_base_msb = 0x0000054C, - .hal_reo1_ring_msi1_data = 0x00000550, - .hal_reo1_aging_thres_ix0 = 0x00000B28, - .hal_reo1_aging_thres_ix1 = 0x00000B2C, - .hal_reo1_aging_thres_ix2 = 0x00000B30, - .hal_reo1_aging_thres_ix3 = 0x00000B34, - - /* REO Exception ring address */ - .hal_reo2_sw0_ring_base = 0x000008c0, - - /* REO Reinject ring address */ - .hal_sw2reo_ring_base = 0x00000320, - .hal_sw2reo1_ring_base = 0x00000398, - - /* REO cmd ring address */ - .hal_reo_cmd_ring_base = 0x000002A8, - - /* REO status ring address */ - .hal_reo_status_ring_base = 0x00000aa0, - - /* CE base address */ - .hal_umac_ce0_src_reg_base = 0x01b80000, - .hal_umac_ce0_dest_reg_base = 0x01b81000, - .hal_umac_ce1_src_reg_base = 0x01b82000, - .hal_umac_ce1_dest_reg_base = 0x01b83000, - - .gcc_gcc_pcie_hot_rst = 0x1e38338, -}; - -static const struct ath12k_hw_regs ipq5332_regs = { - /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_id = 0x00000918, - .hal_tcl1_ring_misc = 0x00000920, - .hal_tcl1_ring_tp_addr_lsb = 0x0000092c, - .hal_tcl1_ring_tp_addr_msb = 0x00000930, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000940, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000944, - .hal_tcl1_ring_msi1_base_lsb = 0x00000958, - .hal_tcl1_ring_msi1_base_msb = 0x0000095c, - .hal_tcl1_ring_base_lsb = 0x00000910, - .hal_tcl1_ring_base_msb = 0x00000914, - .hal_tcl1_ring_msi1_data = 0x00000960, - .hal_tcl2_ring_base_lsb = 0x00000988, - .hal_tcl_ring_base_lsb = 0x00000b68, - - /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000d48, - - /* REO DEST ring address */ - .hal_reo2_ring_base = 0x00000578, - .hal_reo1_misc_ctrl_addr = 0x00000b9c, - .hal_reo1_sw_cookie_cfg0 = 0x0000006c, - .hal_reo1_sw_cookie_cfg1 = 0x00000070, - .hal_reo1_qdesc_lut_base0 = 0x00000074, - .hal_reo1_qdesc_lut_base1 = 0x00000078, - .hal_reo1_ring_base_lsb = 0x00000500, - .hal_reo1_ring_base_msb = 0x00000504, - .hal_reo1_ring_id = 0x00000508, - .hal_reo1_ring_misc = 0x00000510, - .hal_reo1_ring_hp_addr_lsb = 0x00000514, - .hal_reo1_ring_hp_addr_msb = 0x00000518, - .hal_reo1_ring_producer_int_setup = 0x00000524, - .hal_reo1_ring_msi1_base_lsb = 0x00000548, - .hal_reo1_ring_msi1_base_msb = 0x0000054C, - .hal_reo1_ring_msi1_data = 0x00000550, - .hal_reo1_aging_thres_ix0 = 0x00000B28, - .hal_reo1_aging_thres_ix1 = 0x00000B2C, - .hal_reo1_aging_thres_ix2 = 0x00000B30, - .hal_reo1_aging_thres_ix3 = 0x00000B34, - - /* REO Exception ring address */ - .hal_reo2_sw0_ring_base = 0x000008c0, - - /* REO Reinject ring address */ - .hal_sw2reo_ring_base = 0x00000320, - .hal_sw2reo1_ring_base = 0x00000398, - - /* REO cmd ring address */ - .hal_reo_cmd_ring_base = 0x000002A8, - - /* REO status ring address */ - .hal_reo_status_ring_base = 0x00000aa0, - - /* WBM idle link ring address */ - .hal_wbm_idle_ring_base_lsb = 0x00000d3c, - .hal_wbm_idle_ring_misc_addr = 0x00000d4c, - .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, - .hal_wbm_r0_idle_list_size_addr = 0x00000244, - .hal_wbm_scattered_ring_base_lsb = 0x00000250, - .hal_wbm_scattered_ring_base_msb = 0x00000254, - .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, - .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, - .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, - .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, - .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000027c, - - /* SW2WBM release ring address */ - .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, - - /* WBM2SW release ring address */ - .hal_wbm0_release_ring_base_lsb = 0x00000e08, - .hal_wbm1_release_ring_base_lsb = 0x00000e80, - - /* PPE release ring address */ - .hal_ppe_rel_ring_base = 0x0000046c, - - /* CE address */ - .hal_umac_ce0_src_reg_base = 0x00740000 - - HAL_IPQ5332_CE_WFSS_REG_BASE, - .hal_umac_ce0_dest_reg_base = 0x00741000 - - HAL_IPQ5332_CE_WFSS_REG_BASE, - .hal_umac_ce1_src_reg_base = 0x00742000 - - HAL_IPQ5332_CE_WFSS_REG_BASE, - .hal_umac_ce1_dest_reg_base = 0x00743000 - - HAL_IPQ5332_CE_WFSS_REG_BASE, -}; - -static const struct ath12k_hw_regs wcn7850_regs = { - /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_id = 0x00000908, - .hal_tcl1_ring_misc = 0x00000910, - .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, - .hal_tcl1_ring_tp_addr_msb = 0x00000920, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, - .hal_tcl1_ring_msi1_base_lsb = 0x00000948, - .hal_tcl1_ring_msi1_base_msb = 0x0000094c, - .hal_tcl1_ring_msi1_data = 0x00000950, - .hal_tcl_ring_base_lsb = 0x00000b58, - .hal_tcl1_ring_base_lsb = 0x00000900, - .hal_tcl1_ring_base_msb = 0x00000904, - .hal_tcl2_ring_base_lsb = 0x00000978, - - /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000d38, - - .hal_wbm_idle_ring_base_lsb = 0x00000d3c, - .hal_wbm_idle_ring_misc_addr = 0x00000d4c, - .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, - .hal_wbm_r0_idle_list_size_addr = 0x00000244, - .hal_wbm_scattered_ring_base_lsb = 0x00000250, - .hal_wbm_scattered_ring_base_msb = 0x00000254, - .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, - .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, - .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, - .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, - .hal_wbm_scattered_desc_ptr_hp_addr = 0x00000027c, - - .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, - .hal_wbm_sw1_release_ring_base_lsb = 0x00000284, - .hal_wbm0_release_ring_base_lsb = 0x00000e08, - .hal_wbm1_release_ring_base_lsb = 0x00000e80, - - /* PCIe base address */ - .pcie_qserdes_sysclk_en_sel = 0x01e0e0a8, - .pcie_pcs_osc_dtct_config_base = 0x01e0f45c, - - /* PPE release ring address */ - .hal_ppe_rel_ring_base = 0x0000043c, - - /* REO DEST ring address */ - .hal_reo2_ring_base = 0x0000055c, - .hal_reo1_misc_ctrl_addr = 0x00000b7c, - .hal_reo1_sw_cookie_cfg0 = 0x00000050, - .hal_reo1_sw_cookie_cfg1 = 0x00000054, - .hal_reo1_qdesc_lut_base0 = 0x00000058, - .hal_reo1_qdesc_lut_base1 = 0x0000005c, - .hal_reo1_ring_base_lsb = 0x000004e4, - .hal_reo1_ring_base_msb = 0x000004e8, - .hal_reo1_ring_id = 0x000004ec, - .hal_reo1_ring_misc = 0x000004f4, - .hal_reo1_ring_hp_addr_lsb = 0x000004f8, - .hal_reo1_ring_hp_addr_msb = 0x000004fc, - .hal_reo1_ring_producer_int_setup = 0x00000508, - .hal_reo1_ring_msi1_base_lsb = 0x0000052C, - .hal_reo1_ring_msi1_base_msb = 0x00000530, - .hal_reo1_ring_msi1_data = 0x00000534, - .hal_reo1_aging_thres_ix0 = 0x00000b08, - .hal_reo1_aging_thres_ix1 = 0x00000b0c, - .hal_reo1_aging_thres_ix2 = 0x00000b10, - .hal_reo1_aging_thres_ix3 = 0x00000b14, - - /* REO Exception ring address */ - .hal_reo2_sw0_ring_base = 0x000008a4, - - /* REO Reinject ring address */ - .hal_sw2reo_ring_base = 0x00000304, - .hal_sw2reo1_ring_base = 0x0000037c, - - /* REO cmd ring address */ - .hal_reo_cmd_ring_base = 0x0000028c, - - /* REO status ring address */ - .hal_reo_status_ring_base = 0x00000a84, - - /* CE base address */ - .hal_umac_ce0_src_reg_base = 0x01b80000, - .hal_umac_ce0_dest_reg_base = 0x01b81000, - .hal_umac_ce1_src_reg_base = 0x01b82000, - .hal_umac_ce1_dest_reg_base = 0x01b83000, - - .gcc_gcc_pcie_hot_rst = 0x1e40304, -}; - -static const struct ath12k_hw_hal_params ath12k_wifi7_hw_hal_params_qcn9274 = { - .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, - .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW1_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, -}; - -static const struct ath12k_hw_hal_params ath12k_wifi7_hw_hal_params_wcn7850 = { - .rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM, - .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, -}; - -static const struct ath12k_hw_hal_params ath12k_wifi7_hw_hal_params_ipq5332 = { - .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, - .wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW1_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN | - HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, -}; - static const struct ce_ie_addr ath12k_wifi7_ce_ie_addr_ipq5332 = { .ie1_reg_addr = CE_HOST_IE_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE, .ie2_reg_addr = CE_HOST_IE_2_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE, @@ -720,7 +339,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .hw_ops = &qcn9274_ops, .ring_mask = &ath12k_wifi7_hw_ring_mask_qcn9274, - .regs = &qcn9274_v1_regs, .host_ce_config = ath12k_wifi7_host_ce_config_qcn9274, .ce_count = 16, @@ -730,8 +348,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { ath12k_wifi7_target_service_to_ce_map_wlan_qcn9274, .svc_to_ce_map_len = 18, - .hal_params = &ath12k_wifi7_hw_hal_params_qcn9274, - .rxdma1_enable = false, .num_rxdma_per_pdev = 1, .num_rxdma_dst_ring = 0, @@ -806,7 +422,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .hw_ops = &wcn7850_ops, .ring_mask = &ath12k_wifi7_hw_ring_mask_wcn7850, - .regs = &wcn7850_regs, .host_ce_config = ath12k_wifi7_host_ce_config_wcn7850, .ce_count = 9, @@ -816,8 +431,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { ath12k_wifi7_target_service_to_ce_map_wlan_wcn7850, .svc_to_ce_map_len = 14, - .hal_params = &ath12k_wifi7_hw_hal_params_wcn7850, - .rxdma1_enable = false, .num_rxdma_per_pdev = 2, .num_rxdma_dst_ring = 1, @@ -892,7 +505,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .hw_ops = &qcn9274_ops, .ring_mask = &ath12k_wifi7_hw_ring_mask_qcn9274, - .regs = &qcn9274_v2_regs, .host_ce_config = ath12k_wifi7_host_ce_config_qcn9274, .ce_count = 16, @@ -902,8 +514,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { ath12k_wifi7_target_service_to_ce_map_wlan_qcn9274, .svc_to_ce_map_len = 18, - .hal_params = &ath12k_wifi7_hw_hal_params_qcn9274, - .rxdma1_enable = true, .num_rxdma_per_pdev = 1, .num_rxdma_dst_ring = 0, @@ -975,7 +585,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .internal_sleep_clock = false, .hw_ops = &qcn9274_ops, - .regs = &ipq5332_regs, .ring_mask = &ath12k_wifi7_hw_ring_mask_ipq5332, .host_ce_config = ath12k_wifi7_host_ce_config_ipq5332, @@ -986,8 +595,6 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { ath12k_wifi7_target_service_to_ce_map_wlan_ipq5332, .svc_to_ce_map_len = 18, - .hal_params = &ath12k_wifi7_hw_hal_params_ipq5332, - .rxdma1_enable = false, .num_rxdma_per_pdev = 1, .num_rxdma_dst_ring = 0, From aa1925120ff535b0df8386dacd43cb118dce64ba Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:33 +0530 Subject: [PATCH 055/140] wifi: ath12k: Add direct HAL pointer in ath12k_dp Add a direct pointer to the HAL context in ath12k_dp. Since ath12k_dp is frequenctly used in the per-packet data path, this avoids the need to access the HAL handle through the ab pointer, reducing indirection in the per-packet data path. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-7-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.h | 1 + drivers/net/wireless/ath/ath12k/wifi7/dp.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index f7cf83806eb07..d0efe5b2de6ce 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -451,6 +451,7 @@ struct ath12k_dp { struct ath12k_reo_q_addr_lut ml_reoq_lut; const struct ath12k_hw_params *hw_params; struct device *dev; + struct ath12k_hal *hal; /* RCU on dp_pdevs[] provides a teardown synchronization mechanism, * ensuring in-flight data path readers complete before reclaim. Writers diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 4465a9e93bf85..e691d0ca0d75c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -152,6 +152,7 @@ struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab) dp->ab = ab; dp->dev = ab->dev; dp->hw_params = ab->hw_params; + dp->hal = &ab->hal; dp->ops = &ath12k_wifi7_dp_arch_ops; From 0eff9e2eeb43a32be8dbcce7dc1abf011a1181f5 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:34 +0530 Subject: [PATCH 056/140] wifi: ath12k: Use hal handle instead of ab handle Use hal handle instead of ab handle in hal config APIs and register access APIs, as this reduces the indirection. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-8-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 22 +- drivers/net/wireless/ath/ath12k/hal.c | 143 +++++----- drivers/net/wireless/ath/ath12k/hal.h | 252 +++++++++--------- .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 78 +++--- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 21 +- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 70 ++--- 6 files changed, 296 insertions(+), 290 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 3289d609fefb4..3550c88c34bb9 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1150,7 +1150,7 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab) if (dp->reoq_lut.vaddr_unaligned) { ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + - HAL_REO1_QDESC_LUT_BASE0(ab), 0); + HAL_REO1_QDESC_LUT_BASE0(dp->hal), 0); dma_free_coherent(ab->dev, dp->reoq_lut.size, dp->reoq_lut.vaddr_unaligned, dp->reoq_lut.paddr_unaligned); @@ -1160,7 +1160,7 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab) if (dp->ml_reoq_lut.vaddr_unaligned) { ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + - HAL_REO1_QDESC_LUT_BASE1(ab), 0); + HAL_REO1_QDESC_LUT_BASE1(dp->hal), 0); dma_free_coherent(ab->dev, dp->ml_reoq_lut.size, dp->ml_reoq_lut.vaddr_unaligned, dp->ml_reoq_lut.paddr_unaligned); @@ -1201,11 +1201,12 @@ void ath12k_dp_cc_config(struct ath12k_base *ab) u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; u32 wbm_base = HAL_SEQ_WCSS_UMAC_WBM_REG; u32 val = 0; + struct ath12k_hal *hal = &ab->hal; if (ath12k_ftm_mode) return; - ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG0(ab), cmem_base); + ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG0(hal), cmem_base); val |= u32_encode_bits(ATH12K_CMEM_ADDR_MSB, HAL_REO1_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB) | @@ -1217,7 +1218,7 @@ void ath12k_dp_cc_config(struct ath12k_base *ab) u32_encode_bits(1, HAL_REO1_SW_COOKIE_CFG_ENABLE) | u32_encode_bits(1, HAL_REO1_SW_COOKIE_CFG_GLOBAL_ENABLE); - ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG1(ab), val); + ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG1(hal), val); /* Enable HW CC for WBM */ ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CFG0, cmem_base); @@ -1243,7 +1244,7 @@ void ath12k_dp_cc_config(struct ath12k_base *ab) /* Enable Cookie conversion for WBM2SW Rings */ val = ath12k_hif_read32(ab, wbm_base + HAL_WBM_SW_COOKIE_CONVERT_CFG); val |= u32_encode_bits(1, HAL_WBM_SW_COOKIE_CONV_CFG_GLOBAL_EN) | - ab->hal.hal_params->wbm2sw_cc_enable; + hal->hal_params->wbm2sw_cc_enable; ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CONVERT_CFG, val); } @@ -1537,6 +1538,7 @@ static int ath12k_dp_alloc_reoq_lut(struct ath12k_base *ab, static int ath12k_dp_reoq_lut_setup(struct ath12k_base *ab) { struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_hal *hal = dp->hal; u32 val; int ret; @@ -1565,18 +1567,18 @@ static int ath12k_dp_reoq_lut_setup(struct ath12k_base *ab) * register only */ - ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE0(ab), + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE0(hal), dp->reoq_lut.paddr >> 8); - ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE1(ab), + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE1(hal), dp->ml_reoq_lut.paddr >> 8); - val = ath12k_hif_read32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_ADDR(ab)); + val = ath12k_hif_read32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_ADDR(hal)); - ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_ADDR(ab), + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_ADDR(hal), val | HAL_REO_QDESC_ADDR_READ_LUT_ENABLE); - ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_MAX_PEERID(ab), + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_MAX_PEERID(hal), HAL_REO_QDESC_MAX_PEERID); return 0; diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index d1dfbe2f9a654..fb369f464b2df 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -12,58 +12,57 @@ #include "wifi7/hal_qcn9274.h" #include "wifi7/hal_wcn7850.h" -static unsigned int ath12k_hal_reo1_ring_id_offset(struct ath12k_base *ab) +static unsigned int ath12k_hal_reo1_ring_id_offset(struct ath12k_hal *hal) { - return HAL_REO1_RING_ID(ab) - HAL_REO1_RING_BASE_LSB(ab); + return HAL_REO1_RING_ID(hal) - HAL_REO1_RING_BASE_LSB(hal); } -static unsigned int ath12k_hal_reo1_ring_msi1_base_lsb_offset(struct ath12k_base *ab) +static unsigned int ath12k_hal_reo1_ring_msi1_base_lsb_offset(struct ath12k_hal *hal) { - return HAL_REO1_RING_MSI1_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); + return HAL_REO1_RING_MSI1_BASE_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); } -static unsigned int ath12k_hal_reo1_ring_msi1_base_msb_offset(struct ath12k_base *ab) +static unsigned int ath12k_hal_reo1_ring_msi1_base_msb_offset(struct ath12k_hal *hal) { - return HAL_REO1_RING_MSI1_BASE_MSB(ab) - HAL_REO1_RING_BASE_LSB(ab); + return HAL_REO1_RING_MSI1_BASE_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); } -static unsigned int ath12k_hal_reo1_ring_msi1_data_offset(struct ath12k_base *ab) +static unsigned int ath12k_hal_reo1_ring_msi1_data_offset(struct ath12k_hal *hal) { - return HAL_REO1_RING_MSI1_DATA(ab) - HAL_REO1_RING_BASE_LSB(ab); + return HAL_REO1_RING_MSI1_DATA(hal) - HAL_REO1_RING_BASE_LSB(hal); } -static unsigned int ath12k_hal_reo1_ring_base_msb_offset(struct ath12k_base *ab) +static unsigned int ath12k_hal_reo1_ring_base_msb_offset(struct ath12k_hal *hal) { - return HAL_REO1_RING_BASE_MSB(ab) - HAL_REO1_RING_BASE_LSB(ab); + return HAL_REO1_RING_BASE_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); } -static unsigned int ath12k_hal_reo1_ring_producer_int_setup_offset(struct ath12k_base *ab) +static unsigned int ath12k_hal_reo1_ring_producer_int_setup_offset(struct ath12k_hal *hal) { - return HAL_REO1_RING_PRODUCER_INT_SETUP(ab) - HAL_REO1_RING_BASE_LSB(ab); + return HAL_REO1_RING_PRODUCER_INT_SETUP(hal) - HAL_REO1_RING_BASE_LSB(hal); } -static unsigned int ath12k_hal_reo1_ring_hp_addr_lsb_offset(struct ath12k_base *ab) +static unsigned int ath12k_hal_reo1_ring_hp_addr_lsb_offset(struct ath12k_hal *hal) { - return HAL_REO1_RING_HP_ADDR_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); + return HAL_REO1_RING_HP_ADDR_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); } -static unsigned int ath12k_hal_reo1_ring_hp_addr_msb_offset(struct ath12k_base *ab) +static unsigned int ath12k_hal_reo1_ring_hp_addr_msb_offset(struct ath12k_hal *hal) { - return HAL_REO1_RING_HP_ADDR_MSB(ab) - HAL_REO1_RING_BASE_LSB(ab); + return HAL_REO1_RING_HP_ADDR_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); } -static unsigned int ath12k_hal_reo1_ring_misc_offset(struct ath12k_base *ab) +static unsigned int ath12k_hal_reo1_ring_misc_offset(struct ath12k_hal *hal) { - return HAL_REO1_RING_MISC(ab) - HAL_REO1_RING_BASE_LSB(ab); + return HAL_REO1_RING_MISC(hal) - HAL_REO1_RING_BASE_LSB(hal); } -static int ath12k_hal_alloc_cont_rdp(struct ath12k_base *ab) +static int ath12k_hal_alloc_cont_rdp(struct ath12k_hal *hal) { - struct ath12k_hal *hal = &ab->hal; size_t size; size = sizeof(u32) * HAL_SRNG_RING_ID_MAX; - hal->rdp.vaddr = dma_alloc_coherent(ab->dev, size, &hal->rdp.paddr, + hal->rdp.vaddr = dma_alloc_coherent(hal->dev, size, &hal->rdp.paddr, GFP_KERNEL); if (!hal->rdp.vaddr) return -ENOMEM; @@ -71,27 +70,25 @@ static int ath12k_hal_alloc_cont_rdp(struct ath12k_base *ab) return 0; } -static void ath12k_hal_free_cont_rdp(struct ath12k_base *ab) +static void ath12k_hal_free_cont_rdp(struct ath12k_hal *hal) { - struct ath12k_hal *hal = &ab->hal; size_t size; if (!hal->rdp.vaddr) return; size = sizeof(u32) * HAL_SRNG_RING_ID_MAX; - dma_free_coherent(ab->dev, size, + dma_free_coherent(hal->dev, size, hal->rdp.vaddr, hal->rdp.paddr); hal->rdp.vaddr = NULL; } -static int ath12k_hal_alloc_cont_wrp(struct ath12k_base *ab) +static int ath12k_hal_alloc_cont_wrp(struct ath12k_hal *hal) { - struct ath12k_hal *hal = &ab->hal; size_t size; size = sizeof(u32) * (HAL_SRNG_NUM_PMAC_RINGS + HAL_SRNG_NUM_DMAC_RINGS); - hal->wrp.vaddr = dma_alloc_coherent(ab->dev, size, &hal->wrp.paddr, + hal->wrp.vaddr = dma_alloc_coherent(hal->dev, size, &hal->wrp.paddr, GFP_KERNEL); if (!hal->wrp.vaddr) return -ENOMEM; @@ -99,16 +96,15 @@ static int ath12k_hal_alloc_cont_wrp(struct ath12k_base *ab) return 0; } -static void ath12k_hal_free_cont_wrp(struct ath12k_base *ab) +static void ath12k_hal_free_cont_wrp(struct ath12k_hal *hal) { - struct ath12k_hal *hal = &ab->hal; size_t size; if (!hal->wrp.vaddr) return; size = sizeof(u32) * (HAL_SRNG_NUM_PMAC_RINGS + HAL_SRNG_NUM_DMAC_RINGS); - dma_free_coherent(ab->dev, size, + dma_free_coherent(hal->dev, size, hal->wrp.vaddr, hal->wrp.paddr); hal->wrp.vaddr = NULL; } @@ -143,17 +139,17 @@ static void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab, if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { ath12k_hif_write32(ab, reg_base + - ath12k_hal_reo1_ring_msi1_base_lsb_offset(ab), + ath12k_hal_reo1_ring_msi1_base_lsb_offset(hal), srng->msi_addr); val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT), HAL_REO1_RING_MSI1_BASE_MSB_ADDR) | HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE; ath12k_hif_write32(ab, reg_base + - ath12k_hal_reo1_ring_msi1_base_msb_offset(ab), val); + ath12k_hal_reo1_ring_msi1_base_msb_offset(hal), val); ath12k_hif_write32(ab, - reg_base + ath12k_hal_reo1_ring_msi1_data_offset(ab), + reg_base + ath12k_hal_reo1_ring_msi1_data_offset(hal), srng->msi_data); } @@ -163,11 +159,11 @@ static void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab, HAL_REO1_RING_BASE_MSB_RING_BASE_ADDR_MSB) | u32_encode_bits((srng->entry_size * srng->num_entries), HAL_REO1_RING_BASE_MSB_RING_SIZE); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_base_msb_offset(ab), val); + ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_base_msb_offset(hal), val); val = u32_encode_bits(srng->ring_id, HAL_REO1_RING_ID_RING_ID) | u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_id_offset(ab), val); + ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_id_offset(hal), val); /* interrupt setup */ val = u32_encode_bits((srng->intr_timer_thres_us >> 3), @@ -177,15 +173,15 @@ static void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab, HAL_REO1_RING_PRDR_INT_SETUP_BATCH_COUNTER_THOLD); ath12k_hif_write32(ab, - reg_base + ath12k_hal_reo1_ring_producer_int_setup_offset(ab), + reg_base + ath12k_hal_reo1_ring_producer_int_setup_offset(hal), val); hp_addr = hal->rdp.paddr + ((unsigned long)srng->u.dst_ring.hp_addr - (unsigned long)hal->rdp.vaddr); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_lsb_offset(ab), + ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_lsb_offset(hal), hp_addr & HAL_ADDR_LSB_REG_MASK); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_msb_offset(ab), + ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_msb_offset(hal), hp_addr >> HAL_ADDR_MSB_REG_SHIFT); /* Initialize head and tail pointers to indicate ring is empty */ @@ -204,7 +200,7 @@ static void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab, val |= HAL_REO1_RING_MISC_MSI_SWAP; val |= HAL_REO1_RING_MISC_SRNG_ENABLE; - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_misc_offset(ab), val); + ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_misc_offset(hal), val); } static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, @@ -219,18 +215,18 @@ static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { ath12k_hif_write32(ab, reg_base + - HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(ab), + HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(hal), srng->msi_addr); val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT), HAL_TCL1_RING_MSI1_BASE_MSB_ADDR) | HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE; ath12k_hif_write32(ab, reg_base + - HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(ab), + HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(hal), val); ath12k_hif_write32(ab, reg_base + - HAL_TCL1_RING_MSI1_DATA_OFFSET(ab), + HAL_TCL1_RING_MSI1_DATA_OFFSET(hal), srng->msi_data); } @@ -240,10 +236,10 @@ static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB) | u32_encode_bits((srng->entry_size * srng->num_entries), HAL_TCL1_RING_BASE_MSB_RING_SIZE); - ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET(ab), val); + ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET(hal), val); val = u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE); - ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_ID_OFFSET(ab), val); + ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_ID_OFFSET(hal), val); val = u32_encode_bits(srng->intr_timer_thres_us, HAL_TCL1_RING_CONSR_INT_SETUP_IX0_INTR_TMR_THOLD); @@ -252,7 +248,7 @@ static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, HAL_TCL1_RING_CONSR_INT_SETUP_IX0_BATCH_COUNTER_THOLD); ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(ab), + reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(hal), val); val = 0; @@ -261,7 +257,7 @@ static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD); } ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(ab), + reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(hal), val); if (srng->ring_id != HAL_SRNG_RING_ID_WBM_IDLE_LINK) { @@ -269,10 +265,10 @@ static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, ((unsigned long)srng->u.src_ring.tp_addr - (unsigned long)hal->rdp.vaddr); ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(ab), + reg_base + HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(hal), tp_addr & HAL_ADDR_LSB_REG_MASK); ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(ab), + reg_base + HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(hal), tp_addr >> HAL_ADDR_MSB_REG_SHIFT); } @@ -299,7 +295,7 @@ static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, if (srng->ring_id == HAL_SRNG_RING_ID_WBM_IDLE_LINK) val |= HAL_TCL1_RING_MISC_MSI_RING_ID_DISABLE; - ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_MISC_OFFSET(ab), val); + ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_MISC_OFFSET(hal), val); } static void ath12k_hal_srng_hw_init(struct ath12k_base *ab, @@ -719,6 +715,7 @@ void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, u32 nsbufs, u32 tot_link_desc, u32 end_offset) { + struct ath12k_hal *hal = &ab->hal; struct ath12k_buffer_addr *link_addr; int i; u32 reg_scatter_buf_sz = HAL_WBM_IDLE_SCATTER_BUF_SIZE / 64; @@ -744,20 +741,21 @@ void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(ab), + HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(hal), val); val = u32_encode_bits(reg_scatter_buf_sz * nsbufs, HAL_WBM_SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST); ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(ab), + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(hal), val); val = u32_encode_bits(sbuf[0].paddr & HAL_ADDR_LSB_REG_MASK, BUFFER_ADDR_INFO0_ADDR); ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_RING_BASE_LSB(ab), + HAL_WBM_SCATTERED_RING_BASE_LSB(hal), val); val = u32_encode_bits(BASE_ADDR_MATCH_TAG_VAL, @@ -766,14 +764,14 @@ void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32); ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_RING_BASE_MSB(ab), + HAL_WBM_SCATTERED_RING_BASE_MSB(hal), val); /* Setup head and tail pointers for the idle list */ val = u32_encode_bits(sbuf[nsbufs - 1].paddr, BUFFER_ADDR_INFO0_ADDR); ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(ab), + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal), val); val = u32_encode_bits(((u64)sbuf[nsbufs - 1].paddr >> HAL_ADDR_MSB_REG_SHIFT), @@ -782,19 +780,19 @@ void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, HAL_WBM_SCATTERED_DESC_HEAD_P_OFFSET_IX1); ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(ab), + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(hal), val); val = u32_encode_bits(sbuf[0].paddr, BUFFER_ADDR_INFO0_ADDR); ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(ab), + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal), val); val = u32_encode_bits(sbuf[0].paddr, BUFFER_ADDR_INFO0_ADDR); ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(ab), + HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(hal), val); val = u32_encode_bits(((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT), @@ -802,13 +800,13 @@ void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, u32_encode_bits(0, HAL_WBM_SCATTERED_DESC_TAIL_P_OFFSET_IX1); ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(ab), + HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(hal), val); val = 2 * tot_link_desc; ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(ab), + HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(hal), val); /* Enable the SRNG */ @@ -816,7 +814,7 @@ void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, u32_encode_bits(1, HAL_WBM_IDLE_LINK_RING_MISC_RIND_ID_DISABLE); ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_IDLE_LINK_RING_MISC_ADDR(ab), + HAL_WBM_IDLE_LINK_RING_MISC_ADDR(hal), val); } @@ -1047,18 +1045,16 @@ void ath12k_hal_srng_shadow_update_hp_tp(struct ath12k_base *ab, ath12k_hal_srng_access_end(ab, srng); } -static void ath12k_hal_register_srng_lock_keys(struct ath12k_base *ab) +static void ath12k_hal_register_srng_lock_keys(struct ath12k_hal *hal) { - struct ath12k_hal *hal = &ab->hal; u32 ring_id; for (ring_id = 0; ring_id < HAL_SRNG_RING_ID_MAX; ring_id++) lockdep_register_key(&hal->srng_list[ring_id].lock_key); } -static void ath12k_hal_unregister_srng_lock_keys(struct ath12k_base *ab) +static void ath12k_hal_unregister_srng_lock_keys(struct ath12k_hal *hal) { - struct ath12k_hal *hal = &ab->hal; u32 ring_id; for (ring_id = 0; ring_id < HAL_SRNG_RING_ID_MAX; ring_id++) @@ -1067,26 +1063,29 @@ static void ath12k_hal_unregister_srng_lock_keys(struct ath12k_base *ab) int ath12k_hal_srng_init(struct ath12k_base *ab) { + struct ath12k_hal *hal = &ab->hal; int ret; - ret = ab->hal.hal_ops->create_srng_config(ab); + ret = hal->hal_ops->create_srng_config(hal); if (ret) goto err_hal; - ret = ath12k_hal_alloc_cont_rdp(ab); + hal->dev = ab->dev; + + ret = ath12k_hal_alloc_cont_rdp(hal); if (ret) goto err_hal; - ret = ath12k_hal_alloc_cont_wrp(ab); + ret = ath12k_hal_alloc_cont_wrp(hal); if (ret) goto err_free_cont_rdp; - ath12k_hal_register_srng_lock_keys(ab); + ath12k_hal_register_srng_lock_keys(hal); return 0; err_free_cont_rdp: - ath12k_hal_free_cont_rdp(ab); + ath12k_hal_free_cont_rdp(hal); err_hal: return ret; @@ -1096,9 +1095,9 @@ void ath12k_hal_srng_deinit(struct ath12k_base *ab) { struct ath12k_hal *hal = &ab->hal; - ath12k_hal_unregister_srng_lock_keys(ab); - ath12k_hal_free_cont_rdp(ab); - ath12k_hal_free_cont_wrp(ab); + ath12k_hal_unregister_srng_lock_keys(hal); + ath12k_hal_free_cont_rdp(hal); + ath12k_hal_free_cont_wrp(hal); kfree(hal->srng_config); hal->srng_config = NULL; } diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index f9cd3d5011441..db284c58be99b 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -72,14 +72,14 @@ struct ath12k_base; #define HAL_SEQ_WCSS_UMAC_OFFSET 0x00a00000 #define HAL_SEQ_WCSS_UMAC_REO_REG 0x00a38000 #define HAL_SEQ_WCSS_UMAC_TCL_REG 0x00a44000 -#define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) \ - ((ab)->hal.regs->hal_umac_ce0_src_reg_base) -#define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) \ - ((ab)->hal.regs->hal_umac_ce0_dest_reg_base) -#define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) \ - ((ab)->hal.regs->hal_umac_ce1_src_reg_base) -#define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) \ - ((ab)->hal.regs->hal_umac_ce1_dest_reg_base) +#define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal) \ + ((hal)->regs->hal_umac_ce0_src_reg_base) +#define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) \ + ((hal)->regs->hal_umac_ce0_dest_reg_base) +#define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(hal) \ + ((hal)->regs->hal_umac_ce1_src_reg_base) +#define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) \ + ((hal)->regs->hal_umac_ce1_dest_reg_base) #define HAL_SEQ_WCSS_UMAC_WBM_REG 0x00a34000 #define HAL_CE_WFSS_CE_REG_BASE 0x01b80000 @@ -89,52 +89,53 @@ struct ath12k_base; /* SW2TCL(x) R0 ring configuration address */ #define HAL_TCL1_RING_CMN_CTRL_REG 0x00000020 #define HAL_TCL1_RING_DSCP_TID_MAP 0x00000240 -#define HAL_TCL1_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_base_lsb) -#define HAL_TCL1_RING_BASE_MSB(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_base_msb) -#define HAL_TCL1_RING_ID(ab) ((ab)->hal.regs->hal_tcl1_ring_id) -#define HAL_TCL1_RING_MISC(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_misc) -#define HAL_TCL1_RING_TP_ADDR_LSB(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_tp_addr_lsb) -#define HAL_TCL1_RING_TP_ADDR_MSB(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_tp_addr_msb) -#define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_consumer_int_setup_ix0) -#define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_consumer_int_setup_ix1) -#define HAL_TCL1_RING_MSI1_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_msi1_base_lsb) -#define HAL_TCL1_RING_MSI1_BASE_MSB(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_msi1_base_msb) -#define HAL_TCL1_RING_MSI1_DATA(ab) \ - ((ab)->hal.regs->hal_tcl1_ring_msi1_data) -#define HAL_TCL2_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_tcl2_ring_base_lsb) -#define HAL_TCL_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_tcl_ring_base_lsb) - -#define HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_MSI1_BASE_LSB(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) -#define HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_MSI1_BASE_MSB(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) -#define HAL_TCL1_RING_MSI1_DATA_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_MSI1_DATA(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) -#define HAL_TCL1_RING_BASE_MSB_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_BASE_MSB(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) -#define HAL_TCL1_RING_ID_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_ID(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) -#define HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) -#define HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) -#define HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_TP_ADDR_LSB(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) -#define HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_TP_ADDR_MSB(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) -#define HAL_TCL1_RING_MISC_OFFSET(ab) ({ typeof(ab) _ab = (ab); \ - (HAL_TCL1_RING_MISC(_ab) - HAL_TCL1_RING_BASE_LSB(_ab)); }) + +#define HAL_TCL1_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl1_ring_base_lsb) +#define HAL_TCL1_RING_BASE_MSB(hal) \ + ((hal)->regs->hal_tcl1_ring_base_msb) +#define HAL_TCL1_RING_ID(hal) ((hal)->regs->hal_tcl1_ring_id) +#define HAL_TCL1_RING_MISC(hal) \ + ((hal)->regs->hal_tcl1_ring_misc) +#define HAL_TCL1_RING_TP_ADDR_LSB(hal) \ + ((hal)->regs->hal_tcl1_ring_tp_addr_lsb) +#define HAL_TCL1_RING_TP_ADDR_MSB(hal) \ + ((hal)->regs->hal_tcl1_ring_tp_addr_msb) +#define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(hal) \ + ((hal)->regs->hal_tcl1_ring_consumer_int_setup_ix0) +#define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(hal) \ + ((hal)->regs->hal_tcl1_ring_consumer_int_setup_ix1) +#define HAL_TCL1_RING_MSI1_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl1_ring_msi1_base_lsb) +#define HAL_TCL1_RING_MSI1_BASE_MSB(hal) \ + ((hal)->regs->hal_tcl1_ring_msi1_base_msb) +#define HAL_TCL1_RING_MSI1_DATA(hal) \ + ((hal)->regs->hal_tcl1_ring_msi1_data) +#define HAL_TCL2_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl2_ring_base_lsb) +#define HAL_TCL_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl_ring_base_lsb) + +#define HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_MSI1_BASE_LSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_MSI1_BASE_MSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_MSI1_DATA_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_MSI1_DATA(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_BASE_MSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_BASE_MSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_ID_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_ID(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_TP_ADDR_LSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_TP_ADDR_MSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_MISC_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_MISC(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) /* SW2TCL(x) R2 ring pointers (head/tail) address */ #define HAL_TCL1_RING_HP 0x00002000 @@ -146,8 +147,8 @@ struct ath12k_base; (HAL_TCL1_RING_TP - HAL_TCL1_RING_HP) /* TCL STATUS ring address */ -#define HAL_TCL_STATUS_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_tcl_status_ring_base_lsb) +#define HAL_TCL_STATUS_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl_status_ring_base_lsb) #define HAL_TCL_STATUS_RING_HP 0x00002048 /* PPE2TCL1 Ring address */ @@ -155,42 +156,42 @@ struct ath12k_base; #define HAL_TCL_PPE2TCL1_RING_HP 0x00002038 /* WBM PPE Release Ring address */ -#define HAL_WBM_PPE_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_ppe_rel_ring_base) +#define HAL_WBM_PPE_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_ppe_rel_ring_base) #define HAL_WBM_PPE_RELEASE_RING_HP 0x00003020 /* REO2SW(x) R0 ring configuration address */ #define HAL_REO1_GEN_ENABLE 0x00000000 -#define HAL_REO1_MISC_CTRL_ADDR(ab) \ - ((ab)->hal.regs->hal_reo1_misc_ctrl_addr) +#define HAL_REO1_MISC_CTRL_ADDR(hal) \ + ((hal)->regs->hal_reo1_misc_ctrl_addr) #define HAL_REO1_DEST_RING_CTRL_IX_0 0x00000004 #define HAL_REO1_DEST_RING_CTRL_IX_1 0x00000008 #define HAL_REO1_DEST_RING_CTRL_IX_2 0x0000000c #define HAL_REO1_DEST_RING_CTRL_IX_3 0x00000010 -#define HAL_REO1_QDESC_ADDR(ab) ((ab)->hal.regs->hal_reo1_qdesc_addr) -#define HAL_REO1_QDESC_MAX_PEERID(ab) ((ab)->hal.regs->hal_reo1_qdesc_max_peerid) -#define HAL_REO1_SW_COOKIE_CFG0(ab) ((ab)->hal.regs->hal_reo1_sw_cookie_cfg0) -#define HAL_REO1_SW_COOKIE_CFG1(ab) ((ab)->hal.regs->hal_reo1_sw_cookie_cfg1) -#define HAL_REO1_QDESC_LUT_BASE0(ab) ((ab)->hal.regs->hal_reo1_qdesc_lut_base0) -#define HAL_REO1_QDESC_LUT_BASE1(ab) ((ab)->hal.regs->hal_reo1_qdesc_lut_base1) -#define HAL_REO1_RING_BASE_LSB(ab) ((ab)->hal.regs->hal_reo1_ring_base_lsb) -#define HAL_REO1_RING_BASE_MSB(ab) ((ab)->hal.regs->hal_reo1_ring_base_msb) -#define HAL_REO1_RING_ID(ab) ((ab)->hal.regs->hal_reo1_ring_id) -#define HAL_REO1_RING_MISC(ab) ((ab)->hal.regs->hal_reo1_ring_misc) -#define HAL_REO1_RING_HP_ADDR_LSB(ab) ((ab)->hal.regs->hal_reo1_ring_hp_addr_lsb) -#define HAL_REO1_RING_HP_ADDR_MSB(ab) ((ab)->hal.regs->hal_reo1_ring_hp_addr_msb) -#define HAL_REO1_RING_PRODUCER_INT_SETUP(ab) \ - ((ab)->hal.regs->hal_reo1_ring_producer_int_setup) -#define HAL_REO1_RING_MSI1_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_reo1_ring_msi1_base_lsb) -#define HAL_REO1_RING_MSI1_BASE_MSB(ab) \ - ((ab)->hal.regs->hal_reo1_ring_msi1_base_msb) -#define HAL_REO1_RING_MSI1_DATA(ab) ((ab)->hal.regs->hal_reo1_ring_msi1_data) -#define HAL_REO2_RING_BASE_LSB(ab) ((ab)->hal.regs->hal_reo2_ring_base) -#define HAL_REO1_AGING_THRESH_IX_0(ab) ((ab)->hal.regs->hal_reo1_aging_thres_ix0) -#define HAL_REO1_AGING_THRESH_IX_1(ab) ((ab)->hal.regs->hal_reo1_aging_thres_ix1) -#define HAL_REO1_AGING_THRESH_IX_2(ab) ((ab)->hal.regs->hal_reo1_aging_thres_ix2) -#define HAL_REO1_AGING_THRESH_IX_3(ab) ((ab)->hal.regs->hal_reo1_aging_thres_ix3) +#define HAL_REO1_QDESC_ADDR(hal) ((hal)->regs->hal_reo1_qdesc_addr) +#define HAL_REO1_QDESC_MAX_PEERID(hal) ((hal)->regs->hal_reo1_qdesc_max_peerid) +#define HAL_REO1_SW_COOKIE_CFG0(hal) ((hal)->regs->hal_reo1_sw_cookie_cfg0) +#define HAL_REO1_SW_COOKIE_CFG1(hal) ((hal)->regs->hal_reo1_sw_cookie_cfg1) +#define HAL_REO1_QDESC_LUT_BASE0(hal) ((hal)->regs->hal_reo1_qdesc_lut_base0) +#define HAL_REO1_QDESC_LUT_BASE1(hal) ((hal)->regs->hal_reo1_qdesc_lut_base1) +#define HAL_REO1_RING_BASE_LSB(hal) ((hal)->regs->hal_reo1_ring_base_lsb) +#define HAL_REO1_RING_BASE_MSB(hal) ((hal)->regs->hal_reo1_ring_base_msb) +#define HAL_REO1_RING_ID(hal) ((hal)->regs->hal_reo1_ring_id) +#define HAL_REO1_RING_MISC(hal) ((hal)->regs->hal_reo1_ring_misc) +#define HAL_REO1_RING_HP_ADDR_LSB(hal) ((hal)->regs->hal_reo1_ring_hp_addr_lsb) +#define HAL_REO1_RING_HP_ADDR_MSB(hal) ((hal)->regs->hal_reo1_ring_hp_addr_msb) +#define HAL_REO1_RING_PRODUCER_INT_SETUP(hal) \ + ((hal)->regs->hal_reo1_ring_producer_int_setup) +#define HAL_REO1_RING_MSI1_BASE_LSB(hal) \ + ((hal)->regs->hal_reo1_ring_msi1_base_lsb) +#define HAL_REO1_RING_MSI1_BASE_MSB(hal) \ + ((hal)->regs->hal_reo1_ring_msi1_base_msb) +#define HAL_REO1_RING_MSI1_DATA(hal) ((hal)->regs->hal_reo1_ring_msi1_data) +#define HAL_REO2_RING_BASE_LSB(hal) ((hal)->regs->hal_reo2_ring_base) +#define HAL_REO1_AGING_THRESH_IX_0(hal) ((hal)->regs->hal_reo1_aging_thres_ix0) +#define HAL_REO1_AGING_THRESH_IX_1(hal) ((hal)->regs->hal_reo1_aging_thres_ix1) +#define HAL_REO1_AGING_THRESH_IX_2(hal) ((hal)->regs->hal_reo1_aging_thres_ix2) +#define HAL_REO1_AGING_THRESH_IX_3(hal) ((hal)->regs->hal_reo1_aging_thres_ix3) /* REO2SW(x) R2 ring pointers (head/tail) address */ #define HAL_REO1_RING_HP 0x00003048 @@ -200,24 +201,24 @@ struct ath12k_base; #define HAL_REO1_RING_TP_OFFSET (HAL_REO1_RING_TP - HAL_REO1_RING_HP) /* REO2SW0 ring configuration address */ -#define HAL_REO_SW0_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_reo2_sw0_ring_base) +#define HAL_REO_SW0_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_reo2_sw0_ring_base) /* REO2SW0 R2 ring pointer (head/tail) address */ #define HAL_REO_SW0_RING_HP 0x00003088 /* REO CMD R0 address */ -#define HAL_REO_CMD_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_reo_cmd_ring_base) +#define HAL_REO_CMD_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_reo_cmd_ring_base) /* REO CMD R2 address */ #define HAL_REO_CMD_HP 0x00003020 /* SW2REO R0 address */ -#define HAL_SW2REO_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_sw2reo_ring_base) -#define HAL_SW2REO1_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_sw2reo1_ring_base) +#define HAL_SW2REO_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_sw2reo_ring_base) +#define HAL_SW2REO1_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_sw2reo1_ring_base) /* SW2REO R2 address */ #define HAL_SW2REO_RING_HP 0x00003028 @@ -234,53 +235,53 @@ struct ath12k_base; #define HAL_CE_DST_STATUS_RING_HP 0x00000408 /* REO status address */ -#define HAL_REO_STATUS_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_reo_status_ring_base) +#define HAL_REO_STATUS_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_reo_status_ring_base) #define HAL_REO_STATUS_HP 0x000030a8 /* WBM Idle R0 address */ -#define HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_wbm_idle_ring_base_lsb) -#define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(ab) \ - ((ab)->hal.regs->hal_wbm_idle_ring_misc_addr) -#define HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(ab) \ - ((ab)->hal.regs->hal_wbm_r0_idle_list_cntl_addr) -#define HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(ab) \ - ((ab)->hal.regs->hal_wbm_r0_idle_list_size_addr) -#define HAL_WBM_SCATTERED_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_wbm_scattered_ring_base_lsb) -#define HAL_WBM_SCATTERED_RING_BASE_MSB(ab) \ - ((ab)->hal.regs->hal_wbm_scattered_ring_base_msb) -#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(ab) \ - ((ab)->hal.regs->hal_wbm_scattered_desc_head_info_ix0) -#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(ab) \ - ((ab)->hal.regs->hal_wbm_scattered_desc_head_info_ix1) -#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(ab) \ - ((ab)->hal.regs->hal_wbm_scattered_desc_tail_info_ix0) -#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(ab) \ - ((ab)->hal.regs->hal_wbm_scattered_desc_tail_info_ix1) -#define HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(ab) \ - ((ab)->hal.regs->hal_wbm_scattered_desc_ptr_hp_addr) +#define HAL_WBM_IDLE_LINK_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm_idle_ring_base_lsb) +#define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(hal) \ + ((hal)->regs->hal_wbm_idle_ring_misc_addr) +#define HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(hal) \ + ((hal)->regs->hal_wbm_r0_idle_list_cntl_addr) +#define HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(hal) \ + ((hal)->regs->hal_wbm_r0_idle_list_size_addr) +#define HAL_WBM_SCATTERED_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm_scattered_ring_base_lsb) +#define HAL_WBM_SCATTERED_RING_BASE_MSB(hal) \ + ((hal)->regs->hal_wbm_scattered_ring_base_msb) +#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_head_info_ix0) +#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_head_info_ix1) +#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_tail_info_ix0) +#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_tail_info_ix1) +#define HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_ptr_hp_addr) /* WBM Idle R2 address */ #define HAL_WBM_IDLE_LINK_RING_HP 0x000030b8 /* SW2WBM R0 release address */ -#define HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_wbm_sw_release_ring_base_lsb) -#define HAL_WBM_SW1_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_wbm_sw1_release_ring_base_lsb) +#define HAL_WBM_SW_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm_sw_release_ring_base_lsb) +#define HAL_WBM_SW1_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm_sw1_release_ring_base_lsb) /* SW2WBM R2 release address */ #define HAL_WBM_SW_RELEASE_RING_HP 0x00003010 #define HAL_WBM_SW1_RELEASE_RING_HP 0x00003018 /* WBM2SW R0 release address */ -#define HAL_WBM0_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_wbm0_release_ring_base_lsb) +#define HAL_WBM0_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm0_release_ring_base_lsb) -#define HAL_WBM1_RELEASE_RING_BASE_LSB(ab) \ - ((ab)->hal.regs->hal_wbm1_release_ring_base_lsb) +#define HAL_WBM1_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm1_release_ring_base_lsb) /* WBM2SW R2 release address */ #define HAL_WBM0_RELEASE_RING_HP 0x000030c8 @@ -1548,6 +1549,7 @@ struct ath12k_hal { dma_addr_t paddr; } wrp; + struct device *dev; const struct hal_ops *hal_ops; const struct ath12k_hw_regs *regs; const struct ath12k_hw_hal_params *hal_params; @@ -1678,7 +1680,7 @@ struct ath12k_hw_version_map { }; struct hal_ops { - int (*create_srng_config)(struct ath12k_base *ab); + int (*create_srng_config)(struct ath12k_hal *hal); void (*rx_desc_set_msdu_len)(struct hal_rx_desc *desc, u16 len); void (*rx_desc_get_dot11_hdr)(struct hal_rx_desc *desc, struct ieee80211_hdr *hdr); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 265e9f3688587..592007f1cad66 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -859,9 +859,8 @@ const struct ath12k_hw_hal_params ath12k_hw_hal_params_ipq5332 = { HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN, }; -static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) +static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_hal *hal) { - struct ath12k_hal *hal = &ab->hal; struct hal_srng_config *s; hal->srng_config = kmemdup(hw_srng_config_template, @@ -871,85 +870,86 @@ static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) return -ENOMEM; s = &hal->srng_config[HAL_REO_DST]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP; - s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); + s->reg_size[0] = HAL_REO2_RING_BASE_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP; s = &hal->srng_config[HAL_REO_EXCEPTION]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP; s = &hal->srng_config[HAL_REO_REINJECT]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP; - s->reg_size[0] = HAL_SW2REO1_RING_BASE_LSB(ab) - HAL_SW2REO_RING_BASE_LSB(ab); + s->reg_size[0] = HAL_SW2REO1_RING_BASE_LSB(hal) - HAL_SW2REO_RING_BASE_LSB(hal); s->reg_size[1] = HAL_SW2REO1_RING_HP - HAL_SW2REO_RING_HP; s = &hal->srng_config[HAL_REO_CMD]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP; s = &hal->srng_config[HAL_REO_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP; s = &hal->srng_config[HAL_TCL_DATA]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP; - s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(ab) - HAL_TCL1_RING_BASE_LSB(ab); + s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(hal) - HAL_TCL1_RING_BASE_LSB(hal); s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP; s = &hal->srng_config[HAL_TCL_CMD]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP; s = &hal->srng_config[HAL_TCL_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP; s = &hal->srng_config[HAL_CE_SRC]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal) + HAL_CE_DST_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal) + HAL_CE_DST_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal); s = &hal->srng_config[HAL_CE_DST]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) + HAL_CE_DST_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) + HAL_CE_DST_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal); s = &hal->srng_config[HAL_CE_DST_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) + HAL_CE_DST_STATUS_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) + HAL_CE_DST_STATUS_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal); s = &hal->srng_config[HAL_WBM_IDLE_LINK]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab); + s->reg_start[0] = + HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP; s = &hal->srng_config[HAL_SW2WBM_RELEASE]; s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); + HAL_WBM_SW_RELEASE_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP; - s->reg_size[0] = HAL_WBM_SW1_RELEASE_RING_BASE_LSB(ab) - - HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); + s->reg_size[0] = HAL_WBM_SW1_RELEASE_RING_BASE_LSB(hal) - + HAL_WBM_SW_RELEASE_RING_BASE_LSB(hal); s->reg_size[1] = HAL_WBM_SW1_RELEASE_RING_HP - HAL_WBM_SW_RELEASE_RING_HP; s = &hal->srng_config[HAL_WBM2SW_RELEASE]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP; - s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) - - HAL_WBM0_RELEASE_RING_BASE_LSB(ab); + s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(hal) - + HAL_WBM0_RELEASE_RING_BASE_LSB(hal); s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP; /* Some LMAC rings are not accessed from the host: @@ -963,7 +963,7 @@ static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) s = &hal->srng_config[HAL_PPE_RELEASE]; s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_PPE_RELEASE_RING_BASE_LSB(ab); + HAL_WBM_PPE_RELEASE_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_PPE_RELEASE_RING_HP; return 0; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index 7da840e3dac85..449e1285c3752 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -918,6 +918,8 @@ void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) { + struct ath12k_hal *hal = &ab->hal; + u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; u32 val; @@ -927,7 +929,7 @@ void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) u32_encode_bits(1, HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE); ath12k_hif_write32(ab, reo_base + HAL_REO1_GEN_ENABLE, val); - val = ath12k_hif_read32(ab, reo_base + HAL_REO1_MISC_CTRL_ADDR(ab)); + val = ath12k_hif_read32(ab, reo_base + HAL_REO1_MISC_CTRL_ADDR(hal)); val &= ~(HAL_REO1_MISC_CTL_FRAG_DST_RING | HAL_REO1_MISC_CTL_BAR_DST_RING); @@ -935,15 +937,15 @@ void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) HAL_REO1_MISC_CTL_FRAG_DST_RING); val |= u32_encode_bits(HAL_SRNG_RING_ID_REO2SW0, HAL_REO1_MISC_CTL_BAR_DST_RING); - ath12k_hif_write32(ab, reo_base + HAL_REO1_MISC_CTRL_ADDR(ab), val); + ath12k_hif_write32(ab, reo_base + HAL_REO1_MISC_CTRL_ADDR(hal), val); - ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_0(ab), + ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_0(hal), HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC); - ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_1(ab), + ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_1(hal), HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC); - ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_2(ab), + ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_2(hal), HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC); - ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3(ab), + ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3(hal), HAL_DEFAULT_VO_REO_TIMEOUT_USEC); ath12k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_2, @@ -955,16 +957,17 @@ void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) void ath12k_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab) { u32 val; + struct ath12k_hal *hal = &ab->hal; lockdep_assert_held(&ab->base_lock); val = ath12k_hif_read32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + - HAL_REO1_QDESC_ADDR(ab)); + HAL_REO1_QDESC_ADDR(hal)); val |= u32_encode_bits(1, HAL_REO_QDESC_ADDR_READ_CLEAR_QDESC_ARRAY); ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + - HAL_REO1_QDESC_ADDR(ab), val); + HAL_REO1_QDESC_ADDR(hal), val); val &= ~HAL_REO_QDESC_ADDR_READ_CLEAR_QDESC_ARRAY; ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + - HAL_REO1_QDESC_ADDR(ab), val); + HAL_REO1_QDESC_ADDR(hal), val); } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index b3ed7c8d738d8..8949b6fc833a4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -655,9 +655,8 @@ void ath12k_hal_extract_rx_desc_data_wcn7850(struct hal_rx_desc_data *rx_desc_da rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_wcn7850(rx_desc); } -static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) +static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_hal *hal) { - struct ath12k_hal *hal = &ab->hal; struct hal_srng_config *s; hal->srng_config = kmemdup(hw_srng_config_template, @@ -667,86 +666,87 @@ static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) return -ENOMEM; s = &hal->srng_config[HAL_REO_DST]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP; - s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); + s->reg_size[0] = HAL_REO2_RING_BASE_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP; s = &hal->srng_config[HAL_REO_EXCEPTION]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP; s = &hal->srng_config[HAL_REO_REINJECT]; s->max_rings = 1; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP; s = &hal->srng_config[HAL_REO_CMD]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP; s = &hal->srng_config[HAL_REO_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP; s = &hal->srng_config[HAL_TCL_DATA]; s->max_rings = 5; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP; - s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(ab) - HAL_TCL1_RING_BASE_LSB(ab); + s->reg_size[0] = HAL_TCL2_RING_BASE_LSB(hal) - HAL_TCL1_RING_BASE_LSB(hal); s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP; s = &hal->srng_config[HAL_TCL_CMD]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP; s = &hal->srng_config[HAL_TCL_STATUS]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP; s = &hal->srng_config[HAL_CE_SRC]; s->max_rings = 12; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal) + HAL_CE_DST_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal) + HAL_CE_DST_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal); s = &hal->srng_config[HAL_CE_DST]; s->max_rings = 12; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) + HAL_CE_DST_RING_BASE_LSB; + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) + HAL_CE_DST_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal); s = &hal->srng_config[HAL_CE_DST_STATUS]; s->max_rings = 12; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) + HAL_CE_DST_STATUS_RING_BASE_LSB; - s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP; - s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); - s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - - HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); + s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) + HAL_CE_DST_STATUS_RING_HP; + s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal); + s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) - + HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal); s = &hal->srng_config[HAL_WBM_IDLE_LINK]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab); + s->reg_start[0] = + HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP; s = &hal->srng_config[HAL_SW2WBM_RELEASE]; s->max_rings = 1; s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); + HAL_WBM_SW_RELEASE_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP; s = &hal->srng_config[HAL_WBM2SW_RELEASE]; - s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); + s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(hal); s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP; - s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) - - HAL_WBM0_RELEASE_RING_BASE_LSB(ab); + s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(hal) - + HAL_WBM0_RELEASE_RING_BASE_LSB(hal); s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP; s = &hal->srng_config[HAL_RXDMA_BUF]; From bb6330878b7fa42d8212e6e89784c4a121ae2ea3 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:35 +0530 Subject: [PATCH 057/140] wifi: ath12k: Move HAL CE setup and SRNG related APIs to wifi7 directory Move the hardware specific HAL APIs to hal.c file inside wifi7 directory. These APIs will be called through the hal_ops mechanism, which are registered separately by qcn and wcn Handling following APIs: ath12k_wifi7_hal_ce_dst_setup ath12k_wifi7_hal_srng_src_hw_init ath12k_wifi7_hal_srng_dst_hw_init ath12k_wifi7_hal_set_umac_srng_ptr_addr Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-9-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.c | 260 +--------------- drivers/net/wireless/ath/ath12k/hal.h | 6 + drivers/net/wireless/ath/ath12k/wifi7/hal.c | 277 ++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/hal.h | 8 + .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 4 + .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 4 + 6 files changed, 313 insertions(+), 246 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index fb369f464b2df..67a7285dc7697 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -12,49 +12,28 @@ #include "wifi7/hal_qcn9274.h" #include "wifi7/hal_wcn7850.h" -static unsigned int ath12k_hal_reo1_ring_id_offset(struct ath12k_hal *hal) -{ - return HAL_REO1_RING_ID(hal) - HAL_REO1_RING_BASE_LSB(hal); -} - -static unsigned int ath12k_hal_reo1_ring_msi1_base_lsb_offset(struct ath12k_hal *hal) -{ - return HAL_REO1_RING_MSI1_BASE_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); -} - -static unsigned int ath12k_hal_reo1_ring_msi1_base_msb_offset(struct ath12k_hal *hal) -{ - return HAL_REO1_RING_MSI1_BASE_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); -} - -static unsigned int ath12k_hal_reo1_ring_msi1_data_offset(struct ath12k_hal *hal) -{ - return HAL_REO1_RING_MSI1_DATA(hal) - HAL_REO1_RING_BASE_LSB(hal); -} - -static unsigned int ath12k_hal_reo1_ring_base_msb_offset(struct ath12k_hal *hal) -{ - return HAL_REO1_RING_BASE_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); -} - -static unsigned int ath12k_hal_reo1_ring_producer_int_setup_offset(struct ath12k_hal *hal) +static void ath12k_hal_ce_dst_setup(struct ath12k_base *ab, + struct hal_srng *srng, int ring_num) { - return HAL_REO1_RING_PRODUCER_INT_SETUP(hal) - HAL_REO1_RING_BASE_LSB(hal); + ab->hal.hal_ops->ce_dst_setup(ab, srng, ring_num); } -static unsigned int ath12k_hal_reo1_ring_hp_addr_lsb_offset(struct ath12k_hal *hal) +static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, + struct hal_srng *srng) { - return HAL_REO1_RING_HP_ADDR_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); + ab->hal.hal_ops->srng_src_hw_init(ab, srng); } -static unsigned int ath12k_hal_reo1_ring_hp_addr_msb_offset(struct ath12k_hal *hal) +static void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab, + struct hal_srng *srng) { - return HAL_REO1_RING_HP_ADDR_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); + ab->hal.hal_ops->srng_dst_hw_init(ab, srng); } -static unsigned int ath12k_hal_reo1_ring_misc_offset(struct ath12k_hal *hal) +static void ath12k_hal_set_umac_srng_ptr_addr(struct ath12k_base *ab, + struct hal_srng *srng) { - return HAL_REO1_RING_MISC(hal) - HAL_REO1_RING_BASE_LSB(hal); + ab->hal.hal_ops->set_umac_srng_ptr_addr(ab, srng); } static int ath12k_hal_alloc_cont_rdp(struct ath12k_hal *hal) @@ -109,195 +88,6 @@ static void ath12k_hal_free_cont_wrp(struct ath12k_hal *hal) hal->wrp.vaddr = NULL; } -static void ath12k_hal_ce_dst_setup(struct ath12k_base *ab, - struct hal_srng *srng, int ring_num) -{ - struct hal_srng_config *srng_config = &ab->hal.srng_config[HAL_CE_DST]; - u32 addr; - u32 val; - - addr = HAL_CE_DST_RING_CTRL + - srng_config->reg_start[HAL_SRNG_REG_GRP_R0] + - ring_num * srng_config->reg_size[HAL_SRNG_REG_GRP_R0]; - - val = ath12k_hif_read32(ab, addr); - val &= ~HAL_CE_DST_R0_DEST_CTRL_MAX_LEN; - val |= u32_encode_bits(srng->u.dst_ring.max_buffer_length, - HAL_CE_DST_R0_DEST_CTRL_MAX_LEN); - ath12k_hif_write32(ab, addr, val); -} - -static void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab, - struct hal_srng *srng) -{ - struct ath12k_hal *hal = &ab->hal; - u32 val; - u64 hp_addr; - u32 reg_base; - - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; - - if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { - ath12k_hif_write32(ab, reg_base + - ath12k_hal_reo1_ring_msi1_base_lsb_offset(hal), - srng->msi_addr); - - val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_REO1_RING_MSI1_BASE_MSB_ADDR) | - HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE; - ath12k_hif_write32(ab, reg_base + - ath12k_hal_reo1_ring_msi1_base_msb_offset(hal), val); - - ath12k_hif_write32(ab, - reg_base + ath12k_hal_reo1_ring_msi1_data_offset(hal), - srng->msi_data); - } - - ath12k_hif_write32(ab, reg_base, srng->ring_base_paddr); - - val = u32_encode_bits(((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_REO1_RING_BASE_MSB_RING_BASE_ADDR_MSB) | - u32_encode_bits((srng->entry_size * srng->num_entries), - HAL_REO1_RING_BASE_MSB_RING_SIZE); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_base_msb_offset(hal), val); - - val = u32_encode_bits(srng->ring_id, HAL_REO1_RING_ID_RING_ID) | - u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_id_offset(hal), val); - - /* interrupt setup */ - val = u32_encode_bits((srng->intr_timer_thres_us >> 3), - HAL_REO1_RING_PRDR_INT_SETUP_INTR_TMR_THOLD); - - val |= u32_encode_bits((srng->intr_batch_cntr_thres_entries * srng->entry_size), - HAL_REO1_RING_PRDR_INT_SETUP_BATCH_COUNTER_THOLD); - - ath12k_hif_write32(ab, - reg_base + ath12k_hal_reo1_ring_producer_int_setup_offset(hal), - val); - - hp_addr = hal->rdp.paddr + - ((unsigned long)srng->u.dst_ring.hp_addr - - (unsigned long)hal->rdp.vaddr); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_lsb_offset(hal), - hp_addr & HAL_ADDR_LSB_REG_MASK); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_msb_offset(hal), - hp_addr >> HAL_ADDR_MSB_REG_SHIFT); - - /* Initialize head and tail pointers to indicate ring is empty */ - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; - ath12k_hif_write32(ab, reg_base, 0); - ath12k_hif_write32(ab, reg_base + HAL_REO1_RING_TP_OFFSET, 0); - *srng->u.dst_ring.hp_addr = 0; - - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; - val = 0; - if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP) - val |= HAL_REO1_RING_MISC_DATA_TLV_SWAP; - if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP) - val |= HAL_REO1_RING_MISC_HOST_FW_SWAP; - if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP) - val |= HAL_REO1_RING_MISC_MSI_SWAP; - val |= HAL_REO1_RING_MISC_SRNG_ENABLE; - - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_misc_offset(hal), val); -} - -static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, - struct hal_srng *srng) -{ - struct ath12k_hal *hal = &ab->hal; - u32 val; - u64 tp_addr; - u32 reg_base; - - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; - - if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { - ath12k_hif_write32(ab, reg_base + - HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(hal), - srng->msi_addr); - - val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_TCL1_RING_MSI1_BASE_MSB_ADDR) | - HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE; - ath12k_hif_write32(ab, reg_base + - HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(hal), - val); - - ath12k_hif_write32(ab, reg_base + - HAL_TCL1_RING_MSI1_DATA_OFFSET(hal), - srng->msi_data); - } - - ath12k_hif_write32(ab, reg_base, srng->ring_base_paddr); - - val = u32_encode_bits(((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB) | - u32_encode_bits((srng->entry_size * srng->num_entries), - HAL_TCL1_RING_BASE_MSB_RING_SIZE); - ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET(hal), val); - - val = u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE); - ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_ID_OFFSET(hal), val); - - val = u32_encode_bits(srng->intr_timer_thres_us, - HAL_TCL1_RING_CONSR_INT_SETUP_IX0_INTR_TMR_THOLD); - - val |= u32_encode_bits((srng->intr_batch_cntr_thres_entries * srng->entry_size), - HAL_TCL1_RING_CONSR_INT_SETUP_IX0_BATCH_COUNTER_THOLD); - - ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(hal), - val); - - val = 0; - if (srng->flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) { - val |= u32_encode_bits(srng->u.src_ring.low_threshold, - HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD); - } - ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(hal), - val); - - if (srng->ring_id != HAL_SRNG_RING_ID_WBM_IDLE_LINK) { - tp_addr = hal->rdp.paddr + - ((unsigned long)srng->u.src_ring.tp_addr - - (unsigned long)hal->rdp.vaddr); - ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(hal), - tp_addr & HAL_ADDR_LSB_REG_MASK); - ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(hal), - tp_addr >> HAL_ADDR_MSB_REG_SHIFT); - } - - /* Initialize head and tail pointers to indicate ring is empty */ - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; - ath12k_hif_write32(ab, reg_base, 0); - ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_TP_OFFSET, 0); - *srng->u.src_ring.tp_addr = 0; - - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; - val = 0; - if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP) - val |= HAL_TCL1_RING_MISC_DATA_TLV_SWAP; - if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP) - val |= HAL_TCL1_RING_MISC_HOST_FW_SWAP; - if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP) - val |= HAL_TCL1_RING_MISC_MSI_SWAP; - - /* Loop count is not used for SRC rings */ - val |= HAL_TCL1_RING_MISC_MSI_LOOPCNT_DISABLE; - - val |= HAL_TCL1_RING_MISC_SRNG_ENABLE; - - if (srng->ring_id == HAL_SRNG_RING_ID_WBM_IDLE_LINK) - val |= HAL_TCL1_RING_MISC_MSI_RING_ID_DISABLE; - - ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_MISC_OFFSET(hal), val); -} - static void ath12k_hal_srng_hw_init(struct ath12k_base *ab, struct hal_srng *srng) { @@ -828,7 +618,6 @@ int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, int ring_id; u32 idx; int i; - u32 reg_base; ring_id = ath12k_hal_srng_get_ring_id(ab, type, ring_num, mac_id); if (ring_id < 0) @@ -863,8 +652,6 @@ int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, memset(srng->ring_base_vaddr, 0, (srng->entry_size * srng->num_entries) << 2); - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; - if (srng->ring_dir == HAL_SRNG_DIR_SRC) { srng->u.src_ring.hp = 0; srng->u.src_ring.cached_tp = 0; @@ -873,16 +660,7 @@ int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, srng->u.src_ring.low_threshold = params->low_threshold * srng->entry_size; if (srng_config->mac_type == ATH12K_HAL_SRNG_UMAC) { - if (!ab->hw_params->supports_shadow_regs) - srng->u.src_ring.hp_addr = - (u32 *)((unsigned long)ab->mem + reg_base); - else - ath12k_dbg(ab, ATH12K_DBG_HAL, - "hal type %d ring_num %d reg_base 0x%x shadow 0x%lx\n", - type, ring_num, - reg_base, - (unsigned long)srng->u.src_ring.hp_addr - - (unsigned long)ab->mem); + ath12k_hal_set_umac_srng_ptr_addr(ab, srng); } else { idx = ring_id - HAL_SRNG_RING_ID_DMAC_CMN_ID_START; srng->u.src_ring.hp_addr = (void *)(hal->wrp.vaddr + @@ -903,17 +681,7 @@ int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, srng->u.dst_ring.cached_hp = 0; srng->u.dst_ring.hp_addr = (void *)(hal->rdp.vaddr + ring_id); if (srng_config->mac_type == ATH12K_HAL_SRNG_UMAC) { - if (!ab->hw_params->supports_shadow_regs) - srng->u.dst_ring.tp_addr = - (u32 *)((unsigned long)ab->mem + reg_base + - (HAL_REO1_RING_TP - HAL_REO1_RING_HP)); - else - ath12k_dbg(ab, ATH12K_DBG_HAL, - "type %d ring_num %d target_reg 0x%x shadow 0x%lx\n", - type, ring_num, - reg_base + HAL_REO1_RING_TP - HAL_REO1_RING_HP, - (unsigned long)srng->u.dst_ring.tp_addr - - (unsigned long)ab->mem); + ath12k_hal_set_umac_srng_ptr_addr(ab, srng); } else { /* For PMAC & DMAC rings, tail pointer updates will be done * through FW by writing to a shared memory location diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index db284c58be99b..9d94bad6ef73a 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1697,6 +1697,12 @@ struct hal_ops { u32 (*rx_desc_get_mpdu_ppdu_id)(struct hal_rx_desc *desc); u8 (*rx_desc_get_l3_pad_bytes)(struct hal_rx_desc *desc); u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc); + void (*ce_dst_setup)(struct ath12k_base *ab, + struct hal_srng *srng, int ring_num); + void (*set_umac_srng_ptr_addr)(struct ath12k_base *ab, + struct hal_srng *srng); + void (*srng_src_hw_init)(struct ath12k_base *ab, struct hal_srng *srng); + void (*srng_dst_hw_init)(struct ath12k_base *ab, struct hal_srng *srng); }; u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 25963ac18cb9b..2b81d70e60df8 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -7,6 +7,8 @@ #include "hal_desc.h" #include "../hal.h" #include "hal.h" +#include "../debug.h" +#include "../hif.h" #include "hal_qcn9274.h" #include "hal_wcn7850.h" @@ -56,3 +58,278 @@ int ath12k_wifi7_hal_init(struct ath12k_base *ab) return 0; } EXPORT_SYMBOL(ath12k_wifi7_hal_init); + +static unsigned int ath12k_wifi7_hal_reo1_ring_id_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_ID(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned +int ath12k_wifi7_hal_reo1_ring_msi1_base_lsb_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_MSI1_BASE_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned +int ath12k_wifi7_hal_reo1_ring_msi1_base_msb_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_MSI1_BASE_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned int ath12k_wifi7_hal_reo1_ring_msi1_data_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_MSI1_DATA(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned int ath12k_wifi7_hal_reo1_ring_base_msb_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_BASE_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned +int ath12k_wifi7_hal_reo1_ring_producer_int_setup_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_PRODUCER_INT_SETUP(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned int ath12k_wifi7_hal_reo1_ring_hp_addr_lsb_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_HP_ADDR_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned int ath12k_wifi7_hal_reo1_ring_hp_addr_msb_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_HP_ADDR_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned int ath12k_wifi7_hal_reo1_ring_misc_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_MISC(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +void ath12k_wifi7_hal_ce_dst_setup(struct ath12k_base *ab, + struct hal_srng *srng, int ring_num) +{ + struct hal_srng_config *srng_config = &ab->hal.srng_config[HAL_CE_DST]; + u32 addr; + u32 val; + + addr = HAL_CE_DST_RING_CTRL + + srng_config->reg_start[HAL_SRNG_REG_GRP_R0] + + ring_num * srng_config->reg_size[HAL_SRNG_REG_GRP_R0]; + + val = ath12k_hif_read32(ab, addr); + val &= ~HAL_CE_DST_R0_DEST_CTRL_MAX_LEN; + val |= u32_encode_bits(srng->u.dst_ring.max_buffer_length, + HAL_CE_DST_R0_DEST_CTRL_MAX_LEN); + ath12k_hif_write32(ab, addr, val); +} + +void ath12k_wifi7_hal_srng_dst_hw_init(struct ath12k_base *ab, + struct hal_srng *srng) +{ + struct ath12k_hal *hal = &ab->hal; + u32 val; + u64 hp_addr; + u32 reg_base; + + reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; + + if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { + ath12k_hif_write32(ab, reg_base + + ath12k_wifi7_hal_reo1_ring_msi1_base_lsb_offset(hal), + srng->msi_addr); + + val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_REO1_RING_MSI1_BASE_MSB_ADDR) | + HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE; + ath12k_hif_write32(ab, reg_base + + ath12k_wifi7_hal_reo1_ring_msi1_base_msb_offset(hal), + val); + + ath12k_hif_write32(ab, + reg_base + + ath12k_wifi7_hal_reo1_ring_msi1_data_offset(hal), + srng->msi_data); + } + + ath12k_hif_write32(ab, reg_base, srng->ring_base_paddr); + + val = u32_encode_bits(((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_REO1_RING_BASE_MSB_RING_BASE_ADDR_MSB) | + u32_encode_bits((srng->entry_size * srng->num_entries), + HAL_REO1_RING_BASE_MSB_RING_SIZE); + ath12k_hif_write32(ab, reg_base + ath12k_wifi7_hal_reo1_ring_base_msb_offset(hal), + val); + + val = u32_encode_bits(srng->ring_id, HAL_REO1_RING_ID_RING_ID) | + u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE); + ath12k_hif_write32(ab, reg_base + ath12k_wifi7_hal_reo1_ring_id_offset(hal), val); + + /* interrupt setup */ + val = u32_encode_bits((srng->intr_timer_thres_us >> 3), + HAL_REO1_RING_PRDR_INT_SETUP_INTR_TMR_THOLD); + + val |= u32_encode_bits((srng->intr_batch_cntr_thres_entries * srng->entry_size), + HAL_REO1_RING_PRDR_INT_SETUP_BATCH_COUNTER_THOLD); + + ath12k_hif_write32(ab, + reg_base + + ath12k_wifi7_hal_reo1_ring_producer_int_setup_offset(hal), + val); + + hp_addr = hal->rdp.paddr + + ((unsigned long)srng->u.dst_ring.hp_addr - + (unsigned long)hal->rdp.vaddr); + ath12k_hif_write32(ab, reg_base + + ath12k_wifi7_hal_reo1_ring_hp_addr_lsb_offset(hal), + hp_addr & HAL_ADDR_LSB_REG_MASK); + ath12k_hif_write32(ab, reg_base + + ath12k_wifi7_hal_reo1_ring_hp_addr_msb_offset(hal), + hp_addr >> HAL_ADDR_MSB_REG_SHIFT); + + /* Initialize head and tail pointers to indicate ring is empty */ + reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; + ath12k_hif_write32(ab, reg_base, 0); + ath12k_hif_write32(ab, reg_base + HAL_REO1_RING_TP_OFFSET, 0); + *srng->u.dst_ring.hp_addr = 0; + + reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; + val = 0; + if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP) + val |= HAL_REO1_RING_MISC_DATA_TLV_SWAP; + if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP) + val |= HAL_REO1_RING_MISC_HOST_FW_SWAP; + if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP) + val |= HAL_REO1_RING_MISC_MSI_SWAP; + val |= HAL_REO1_RING_MISC_SRNG_ENABLE; + + ath12k_hif_write32(ab, reg_base + ath12k_wifi7_hal_reo1_ring_misc_offset(hal), + val); +} + +void ath12k_wifi7_hal_srng_src_hw_init(struct ath12k_base *ab, + struct hal_srng *srng) +{ + struct ath12k_hal *hal = &ab->hal; + u32 val; + u64 tp_addr; + u32 reg_base; + + reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; + + if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { + ath12k_hif_write32(ab, reg_base + + HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(hal), + srng->msi_addr); + + val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_TCL1_RING_MSI1_BASE_MSB_ADDR) | + HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE; + ath12k_hif_write32(ab, reg_base + + HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(hal), + val); + + ath12k_hif_write32(ab, reg_base + + HAL_TCL1_RING_MSI1_DATA_OFFSET(hal), + srng->msi_data); + } + + ath12k_hif_write32(ab, reg_base, srng->ring_base_paddr); + + val = u32_encode_bits(((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB) | + u32_encode_bits((srng->entry_size * srng->num_entries), + HAL_TCL1_RING_BASE_MSB_RING_SIZE); + ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET(hal), val); + + val = u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE); + ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_ID_OFFSET(hal), val); + + val = u32_encode_bits(srng->intr_timer_thres_us, + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_INTR_TMR_THOLD); + + val |= u32_encode_bits((srng->intr_batch_cntr_thres_entries * srng->entry_size), + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_BATCH_COUNTER_THOLD); + + ath12k_hif_write32(ab, + reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(hal), + val); + + val = 0; + if (srng->flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) { + val |= u32_encode_bits(srng->u.src_ring.low_threshold, + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD); + } + ath12k_hif_write32(ab, + reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(hal), + val); + + if (srng->ring_id != HAL_SRNG_RING_ID_WBM_IDLE_LINK) { + tp_addr = hal->rdp.paddr + + ((unsigned long)srng->u.src_ring.tp_addr - + (unsigned long)hal->rdp.vaddr); + ath12k_hif_write32(ab, + reg_base + HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(hal), + tp_addr & HAL_ADDR_LSB_REG_MASK); + ath12k_hif_write32(ab, + reg_base + HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(hal), + tp_addr >> HAL_ADDR_MSB_REG_SHIFT); + } + + /* Initialize head and tail pointers to indicate ring is empty */ + reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; + ath12k_hif_write32(ab, reg_base, 0); + ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_TP_OFFSET, 0); + *srng->u.src_ring.tp_addr = 0; + + reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; + val = 0; + if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP) + val |= HAL_TCL1_RING_MISC_DATA_TLV_SWAP; + if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP) + val |= HAL_TCL1_RING_MISC_HOST_FW_SWAP; + if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP) + val |= HAL_TCL1_RING_MISC_MSI_SWAP; + + /* Loop count is not used for SRC rings */ + val |= HAL_TCL1_RING_MISC_MSI_LOOPCNT_DISABLE; + + val |= HAL_TCL1_RING_MISC_SRNG_ENABLE; + + if (srng->ring_id == HAL_SRNG_RING_ID_WBM_IDLE_LINK) + val |= HAL_TCL1_RING_MISC_MSI_RING_ID_DISABLE; + + ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_MISC_OFFSET(hal), val); +} + +void ath12k_wifi7_hal_set_umac_srng_ptr_addr(struct ath12k_base *ab, + struct hal_srng *srng) +{ + u32 reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; + + if (srng->ring_dir == HAL_SRNG_DIR_SRC) { + if (!ab->hw_params->supports_shadow_regs) { + srng->u.src_ring.hp_addr = + (u32 *)((unsigned long)ab->mem + reg_base); + } else { + ath12k_dbg(ab, ATH12K_DBG_HAL, + "hal reg_base 0x%x shadow 0x%lx\n", + reg_base, + (unsigned long)srng->u.src_ring.hp_addr - + (unsigned long)ab->mem); + } + } else { + if (!ab->hw_params->supports_shadow_regs) { + srng->u.dst_ring.tp_addr = + (u32 *)((unsigned long)ab->mem + reg_base + + (HAL_REO1_RING_TP - HAL_REO1_RING_HP)); + } else { + ath12k_dbg(ab, ATH12K_DBG_HAL, + "target_reg 0x%x shadow 0x%lx\n", + reg_base + HAL_REO1_RING_TP - HAL_REO1_RING_HP, + (unsigned long)srng->u.dst_ring.tp_addr - + (unsigned long)ab->mem); + } + } +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index 1a8a720c49236..044ed1dce323f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -8,4 +8,12 @@ #define ATH12K_HAL_WIFI7_H int ath12k_wifi7_hal_init(struct ath12k_base *ab); +void ath12k_wifi7_hal_ce_dst_setup(struct ath12k_base *ab, + struct hal_srng *srng, int ring_num); +void ath12k_wifi7_hal_srng_dst_hw_init(struct ath12k_base *ab, + struct hal_srng *srng); +void ath12k_wifi7_hal_srng_src_hw_init(struct ath12k_base *ab, + struct hal_srng *srng); +void ath12k_wifi7_hal_set_umac_srng_ptr_addr(struct ath12k_base *ab, + struct hal_srng *srng); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 592007f1cad66..070e28a38a70e 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1000,5 +1000,9 @@ const struct hal_ops hal_qcn9274_ops = { .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, + .ce_dst_setup = ath12k_wifi7_hal_ce_dst_setup, + .srng_src_hw_init = ath12k_wifi7_hal_srng_src_hw_init, + .srng_dst_hw_init = ath12k_wifi7_hal_srng_dst_hw_init, + .set_umac_srng_ptr_addr = ath12k_wifi7_hal_set_umac_srng_ptr_addr, }; EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 8949b6fc833a4..9d1f94db60bd4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -815,5 +815,9 @@ const struct hal_ops hal_wcn7850_ops = { .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, + .ce_dst_setup = ath12k_wifi7_hal_ce_dst_setup, + .srng_src_hw_init = ath12k_wifi7_hal_srng_src_hw_init, + .srng_dst_hw_init = ath12k_wifi7_hal_srng_dst_hw_init, + .set_umac_srng_ptr_addr = ath12k_wifi7_hal_set_umac_srng_ptr_addr, }; EXPORT_SYMBOL(hal_wcn7850_ops); From 144e6fd01f6c97d662bd816c97e253dc7d27d6d7 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:36 +0530 Subject: [PATCH 058/140] wifi: ath12k: Move HAL SRNG shadow config and get ring id APIs to wifi7 directory Move the hardware specific HAL APIs to hal.c file inside wifi7 directory. These APIs will be called through the hal_ops mechanism, which are registered separately by qcn and wcn Handling following APIs: ath12k_wifi7_hal_srng_update_shadow_config ath12k_wifi7_hal_srng_get_ring_id Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-10-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.c | 101 +++--------------- drivers/net/wireless/ath/ath12k/hal.h | 5 + drivers/net/wireless/ath/ath12k/wifi7/hal.c | 86 +++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/hal.h | 6 ++ .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 2 + .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 2 + 6 files changed, 117 insertions(+), 85 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 67a7285dc7697..d4dd83d9e67f6 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -36,6 +36,21 @@ static void ath12k_hal_set_umac_srng_ptr_addr(struct ath12k_base *ab, ab->hal.hal_ops->set_umac_srng_ptr_addr(ab, srng); } +static int ath12k_hal_srng_get_ring_id(struct ath12k_hal *hal, + enum hal_ring_type type, + int ring_num, int mac_id) +{ + return hal->hal_ops->srng_get_ring_id(hal, type, ring_num, mac_id); +} + +int ath12k_hal_srng_update_shadow_config(struct ath12k_base *ab, + enum hal_ring_type ring_type, + int ring_num) +{ + return ab->hal.hal_ops->srng_update_shadow_config(ab, ring_type, + ring_num); +} + static int ath12k_hal_alloc_cont_rdp(struct ath12k_hal *hal) { size_t size; @@ -97,28 +112,6 @@ static void ath12k_hal_srng_hw_init(struct ath12k_base *ab, ath12k_hal_srng_dst_hw_init(ab, srng); } -static int ath12k_hal_srng_get_ring_id(struct ath12k_base *ab, - enum hal_ring_type type, - int ring_num, int mac_id) -{ - struct hal_srng_config *srng_config = &ab->hal.srng_config[type]; - int ring_id; - - if (ring_num >= srng_config->max_rings) { - ath12k_warn(ab, "invalid ring number :%d\n", ring_num); - return -EINVAL; - } - - ring_id = srng_config->start_ring_id + ring_num; - if (srng_config->mac_type == ATH12K_HAL_SRNG_PMAC) - ring_id += mac_id * HAL_SRNG_RINGS_PER_PMAC; - - if (WARN_ON(ring_id >= HAL_SRNG_RING_ID_MAX)) - return -EINVAL; - - return ring_id; -} - int ath12k_hal_srng_get_entrysize(struct ath12k_base *ab, u32 ring_type) { struct hal_srng_config *srng_config; @@ -619,7 +612,7 @@ int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, u32 idx; int i; - ring_id = ath12k_hal_srng_get_ring_id(ab, type, ring_num, mac_id); + ring_id = ath12k_hal_srng_get_ring_id(hal, type, ring_num, mac_id); if (ring_id < 0) return ring_id; @@ -706,68 +699,6 @@ int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, return ring_id; } -static void ath12k_hal_srng_update_hp_tp_addr(struct ath12k_base *ab, - int shadow_cfg_idx, - enum hal_ring_type ring_type, - int ring_num) -{ - struct hal_srng *srng; - struct ath12k_hal *hal = &ab->hal; - int ring_id; - struct hal_srng_config *srng_config = &hal->srng_config[ring_type]; - - ring_id = ath12k_hal_srng_get_ring_id(ab, ring_type, ring_num, 0); - if (ring_id < 0) - return; - - srng = &hal->srng_list[ring_id]; - - if (srng_config->ring_dir == HAL_SRNG_DIR_DST) - srng->u.dst_ring.tp_addr = (u32 *)(HAL_SHADOW_REG(shadow_cfg_idx) + - (unsigned long)ab->mem); - else - srng->u.src_ring.hp_addr = (u32 *)(HAL_SHADOW_REG(shadow_cfg_idx) + - (unsigned long)ab->mem); -} - -int ath12k_hal_srng_update_shadow_config(struct ath12k_base *ab, - enum hal_ring_type ring_type, - int ring_num) -{ - struct ath12k_hal *hal = &ab->hal; - struct hal_srng_config *srng_config = &hal->srng_config[ring_type]; - int shadow_cfg_idx = hal->num_shadow_reg_configured; - u32 target_reg; - - if (shadow_cfg_idx >= HAL_SHADOW_NUM_REGS) - return -EINVAL; - - hal->num_shadow_reg_configured++; - - target_reg = srng_config->reg_start[HAL_HP_OFFSET_IN_REG_START]; - target_reg += srng_config->reg_size[HAL_HP_OFFSET_IN_REG_START] * - ring_num; - - /* For destination ring, shadow the TP */ - if (srng_config->ring_dir == HAL_SRNG_DIR_DST) - target_reg += HAL_OFFSET_FROM_HP_TO_TP; - - hal->shadow_reg_addr[shadow_cfg_idx] = target_reg; - - /* update hp/tp addr to hal structure*/ - ath12k_hal_srng_update_hp_tp_addr(ab, shadow_cfg_idx, ring_type, - ring_num); - - ath12k_dbg(ab, ATH12K_DBG_HAL, - "target_reg %x, shadow reg 0x%x shadow_idx 0x%x, ring_type %d, ring num %d", - target_reg, - HAL_SHADOW_REG(shadow_cfg_idx), - shadow_cfg_idx, - ring_type, ring_num); - - return 0; -} - void ath12k_hal_srng_shadow_config(struct ath12k_base *ab) { struct ath12k_hal *hal = &ab->hal; diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 9d94bad6ef73a..8e7e64be970c4 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1703,6 +1703,11 @@ struct hal_ops { struct hal_srng *srng); void (*srng_src_hw_init)(struct ath12k_base *ab, struct hal_srng *srng); void (*srng_dst_hw_init)(struct ath12k_base *ab, struct hal_srng *srng); + int (*srng_update_shadow_config)(struct ath12k_base *ab, + enum hal_ring_type ring_type, + int ring_num); + int (*srng_get_ring_id)(struct ath12k_hal *hal, enum hal_ring_type type, + int ring_num, int mac_id); }; u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 2b81d70e60df8..565f43a30deb9 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -333,3 +333,89 @@ void ath12k_wifi7_hal_set_umac_srng_ptr_addr(struct ath12k_base *ab, } } } + +int ath12k_wifi7_hal_srng_get_ring_id(struct ath12k_hal *hal, + enum hal_ring_type type, + int ring_num, int mac_id) +{ + struct hal_srng_config *srng_config = &hal->srng_config[type]; + int ring_id; + + if (ring_num >= srng_config->max_rings) { + ath12k_warn(hal, "invalid ring number :%d\n", ring_num); + return -EINVAL; + } + + ring_id = srng_config->start_ring_id + ring_num; + if (srng_config->mac_type == ATH12K_HAL_SRNG_PMAC) + ring_id += mac_id * HAL_SRNG_RINGS_PER_PMAC; + + if (WARN_ON(ring_id >= HAL_SRNG_RING_ID_MAX)) + return -EINVAL; + + return ring_id; +} + +static +void ath12k_wifi7_hal_srng_update_hp_tp_addr(struct ath12k_base *ab, + int shadow_cfg_idx, + enum hal_ring_type ring_type, + int ring_num) +{ + struct hal_srng *srng; + struct ath12k_hal *hal = &ab->hal; + int ring_id; + struct hal_srng_config *srng_config = &hal->srng_config[ring_type]; + + ring_id = ath12k_wifi7_hal_srng_get_ring_id(hal, ring_type, ring_num, + 0); + if (ring_id < 0) + return; + + srng = &hal->srng_list[ring_id]; + + if (srng_config->ring_dir == HAL_SRNG_DIR_DST) + srng->u.dst_ring.tp_addr = (u32 *)(HAL_SHADOW_REG(shadow_cfg_idx) + + (unsigned long)ab->mem); + else + srng->u.src_ring.hp_addr = (u32 *)(HAL_SHADOW_REG(shadow_cfg_idx) + + (unsigned long)ab->mem); +} + +int ath12k_wifi7_hal_srng_update_shadow_config(struct ath12k_base *ab, + enum hal_ring_type ring_type, + int ring_num) +{ + struct ath12k_hal *hal = &ab->hal; + struct hal_srng_config *srng_config = &hal->srng_config[ring_type]; + int shadow_cfg_idx = hal->num_shadow_reg_configured; + u32 target_reg; + + if (shadow_cfg_idx >= HAL_SHADOW_NUM_REGS) + return -EINVAL; + + hal->num_shadow_reg_configured++; + + target_reg = srng_config->reg_start[HAL_HP_OFFSET_IN_REG_START]; + target_reg += srng_config->reg_size[HAL_HP_OFFSET_IN_REG_START] * + ring_num; + + /* For destination ring, shadow the TP */ + if (srng_config->ring_dir == HAL_SRNG_DIR_DST) + target_reg += HAL_OFFSET_FROM_HP_TO_TP; + + hal->shadow_reg_addr[shadow_cfg_idx] = target_reg; + + /* update hp/tp addr to hal structure*/ + ath12k_wifi7_hal_srng_update_hp_tp_addr(ab, shadow_cfg_idx, ring_type, + ring_num); + + ath12k_dbg(ab, ATH12K_DBG_HAL, + "target_reg %x, shadow reg 0x%x shadow_idx 0x%x, ring_type %d, ring num %d", + target_reg, + HAL_SHADOW_REG(shadow_cfg_idx), + shadow_cfg_idx, + ring_type, ring_num); + + return 0; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index 044ed1dce323f..1ea7b025ed713 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -16,4 +16,10 @@ void ath12k_wifi7_hal_srng_src_hw_init(struct ath12k_base *ab, struct hal_srng *srng); void ath12k_wifi7_hal_set_umac_srng_ptr_addr(struct ath12k_base *ab, struct hal_srng *srng); +int ath12k_wifi7_hal_srng_update_shadow_config(struct ath12k_base *ab, + enum hal_ring_type ring_type, + int ring_num); +int ath12k_wifi7_hal_srng_get_ring_id(struct ath12k_hal *hal, + enum hal_ring_type type, + int ring_num, int mac_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 070e28a38a70e..92769a525c6d2 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1004,5 +1004,7 @@ const struct hal_ops hal_qcn9274_ops = { .srng_src_hw_init = ath12k_wifi7_hal_srng_src_hw_init, .srng_dst_hw_init = ath12k_wifi7_hal_srng_dst_hw_init, .set_umac_srng_ptr_addr = ath12k_wifi7_hal_set_umac_srng_ptr_addr, + .srng_update_shadow_config = ath12k_wifi7_hal_srng_update_shadow_config, + .srng_get_ring_id = ath12k_wifi7_hal_srng_get_ring_id, }; EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 9d1f94db60bd4..a941bb4783ae4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -819,5 +819,7 @@ const struct hal_ops hal_wcn7850_ops = { .srng_src_hw_init = ath12k_wifi7_hal_srng_src_hw_init, .srng_dst_hw_init = ath12k_wifi7_hal_srng_dst_hw_init, .set_umac_srng_ptr_addr = ath12k_wifi7_hal_set_umac_srng_ptr_addr, + .srng_update_shadow_config = ath12k_wifi7_hal_srng_update_shadow_config, + .srng_get_ring_id = ath12k_wifi7_hal_srng_get_ring_id, }; EXPORT_SYMBOL(hal_wcn7850_ops); From 7e5ab8c2dfcf7bda89c569b0eced6df39d5d5777 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:37 +0530 Subject: [PATCH 059/140] wifi: ath12k: Move HAL CE desc related APIs to wifi7 directory Move the hardware specific HAL APIs to hal.c file inside wifi7 directory. These APIs will be called through the hal_ops mechanism, which are registered separately by qcn and wcn Handling following APIs: ath12k_wifi7_hal_ce_get_desc_size ath12k_wifi7_hal_ce_src_set_desc ath12k_wifi7_hal_ce_dst_set_desc Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-11-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ce.c | 23 ++++++---- drivers/net/wireless/ath/ath12k/hal.c | 44 ++++++------------- drivers/net/wireless/ath/ath12k/hal.h | 18 ++++++-- drivers/net/wireless/ath/ath12k/wifi7/hal.c | 38 ++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/hal.h | 6 +++ .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 3 ++ .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 3 ++ 7 files changed, 92 insertions(+), 43 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ce.c b/drivers/net/wireless/ath/ath12k/ce.c index 7b8abc13a5e1c..30140a3330476 100644 --- a/drivers/net/wireless/ath/ath12k/ce.c +++ b/drivers/net/wireless/ath/ath12k/ce.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022, 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include "dp_rx.h" @@ -40,7 +40,7 @@ static int ath12k_ce_rx_buf_enqueue_pipe(struct ath12k_ce_pipe *pipe, goto exit; } - ath12k_hal_ce_dst_set_desc(desc, paddr); + ath12k_hal_ce_dst_set_desc(&ab->hal, desc, paddr); ring->skb[write_index] = skb; write_index = CE_RING_IDX_INCR(nentries_mask, write_index); @@ -365,6 +365,7 @@ ath12k_ce_alloc_ring(struct ath12k_base *ab, int nentries, int desc_sz) static int ath12k_ce_alloc_pipe(struct ath12k_base *ab, int ce_id) { + struct ath12k_hal *hal = &ab->hal; struct ath12k_ce_pipe *pipe = &ab->ce.ce_pipe[ce_id]; const struct ce_attr *attr = &ab->hw_params->host_ce_config[ce_id]; struct ath12k_ce_ring *ring; @@ -376,7 +377,7 @@ static int ath12k_ce_alloc_pipe(struct ath12k_base *ab, int ce_id) if (attr->src_nentries) { pipe->send_cb = ath12k_ce_send_done_cb; nentries = roundup_pow_of_two(attr->src_nentries); - desc_sz = ath12k_hal_ce_get_desc_size(HAL_CE_DESC_SRC); + desc_sz = ath12k_hal_ce_get_desc_size(hal, HAL_CE_DESC_SRC); ring = ath12k_ce_alloc_ring(ab, nentries, desc_sz); if (IS_ERR(ring)) return PTR_ERR(ring); @@ -386,13 +387,13 @@ static int ath12k_ce_alloc_pipe(struct ath12k_base *ab, int ce_id) if (attr->dest_nentries) { pipe->recv_cb = attr->recv_cb; nentries = roundup_pow_of_two(attr->dest_nentries); - desc_sz = ath12k_hal_ce_get_desc_size(HAL_CE_DESC_DST); + desc_sz = ath12k_hal_ce_get_desc_size(hal, HAL_CE_DESC_DST); ring = ath12k_ce_alloc_ring(ab, nentries, desc_sz); if (IS_ERR(ring)) return PTR_ERR(ring); pipe->dest_ring = ring; - desc_sz = ath12k_hal_ce_get_desc_size(HAL_CE_DESC_DST_STATUS); + desc_sz = ath12k_hal_ce_get_desc_size(hal, HAL_CE_DESC_DST_STATUS); ring = ath12k_ce_alloc_ring(ab, nentries, desc_sz); if (IS_ERR(ring)) return PTR_ERR(ring); @@ -485,7 +486,7 @@ int ath12k_ce_send(struct ath12k_base *ab, struct sk_buff *skb, u8 pipe_id, if (pipe->attr_flags & CE_ATTR_BYTE_SWAP_DATA) byte_swap_data = 1; - ath12k_hal_ce_src_set_desc(desc, ATH12K_SKB_CB(skb)->paddr, + ath12k_hal_ce_src_set_desc(&ab->hal, desc, ATH12K_SKB_CB(skb)->paddr, skb->len, transfer_id, byte_swap_data); pipe->src_ring->skb[write_index] = skb; @@ -671,6 +672,7 @@ int ath12k_ce_init_pipes(struct ath12k_base *ab) void ath12k_ce_free_pipes(struct ath12k_base *ab) { + struct ath12k_hal *hal = &ab->hal; struct ath12k_ce_pipe *pipe; int desc_sz; int i; @@ -679,7 +681,8 @@ void ath12k_ce_free_pipes(struct ath12k_base *ab) pipe = &ab->ce.ce_pipe[i]; if (pipe->src_ring) { - desc_sz = ath12k_hal_ce_get_desc_size(HAL_CE_DESC_SRC); + desc_sz = ath12k_hal_ce_get_desc_size(hal, + HAL_CE_DESC_SRC); dma_free_coherent(ab->dev, pipe->src_ring->nentries * desc_sz + CE_DESC_RING_ALIGN, @@ -690,7 +693,8 @@ void ath12k_ce_free_pipes(struct ath12k_base *ab) } if (pipe->dest_ring) { - desc_sz = ath12k_hal_ce_get_desc_size(HAL_CE_DESC_DST); + desc_sz = ath12k_hal_ce_get_desc_size(hal, + HAL_CE_DESC_DST); dma_free_coherent(ab->dev, pipe->dest_ring->nentries * desc_sz + CE_DESC_RING_ALIGN, @@ -702,7 +706,8 @@ void ath12k_ce_free_pipes(struct ath12k_base *ab) if (pipe->status_ring) { desc_sz = - ath12k_hal_ce_get_desc_size(HAL_CE_DESC_DST_STATUS); + ath12k_hal_ce_get_desc_size(hal, + HAL_CE_DESC_DST_STATUS); dma_free_coherent(ab->dev, pipe->status_ring->nentries * desc_sz + CE_DESC_RING_ALIGN, diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index d4dd83d9e67f6..490a483b8c306 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -51,6 +51,11 @@ int ath12k_hal_srng_update_shadow_config(struct ath12k_base *ab, ring_num); } +u32 ath12k_hal_ce_get_desc_size(struct ath12k_hal *hal, enum hal_ce_desc type) +{ + return hal->hal_ops->ce_get_desc_size(type); +} + static int ath12k_hal_alloc_cont_rdp(struct ath12k_hal *hal) { size_t size; @@ -185,40 +190,19 @@ dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab, (unsigned long)ab->hal.wrp.vaddr); } -u32 ath12k_hal_ce_get_desc_size(enum hal_ce_desc type) -{ - switch (type) { - case HAL_CE_DESC_SRC: - return sizeof(struct hal_ce_srng_src_desc); - case HAL_CE_DESC_DST: - return sizeof(struct hal_ce_srng_dest_desc); - case HAL_CE_DESC_DST_STATUS: - return sizeof(struct hal_ce_srng_dst_status_desc); - } - - return 0; -} - -void ath12k_hal_ce_src_set_desc(struct hal_ce_srng_src_desc *desc, dma_addr_t paddr, - u32 len, u32 id, u8 byte_swap_data) +void ath12k_hal_ce_src_set_desc(struct ath12k_hal *hal, + struct hal_ce_srng_src_desc *desc, + dma_addr_t paddr, u32 len, u32 id, + u8 byte_swap_data) { - desc->buffer_addr_low = cpu_to_le32(paddr & HAL_ADDR_LSB_REG_MASK); - desc->buffer_addr_info = - le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_CE_SRC_DESC_ADDR_INFO_ADDR_HI) | - le32_encode_bits(byte_swap_data, - HAL_CE_SRC_DESC_ADDR_INFO_BYTE_SWAP) | - le32_encode_bits(0, HAL_CE_SRC_DESC_ADDR_INFO_GATHER) | - le32_encode_bits(len, HAL_CE_SRC_DESC_ADDR_INFO_LEN); - desc->meta_info = le32_encode_bits(id, HAL_CE_SRC_DESC_META_INFO_DATA); + hal->hal_ops->ce_src_set_desc(desc, paddr, len, id, byte_swap_data); } -void ath12k_hal_ce_dst_set_desc(struct hal_ce_srng_dest_desc *desc, dma_addr_t paddr) +void ath12k_hal_ce_dst_set_desc(struct ath12k_hal *hal, + struct hal_ce_srng_dest_desc *desc, + dma_addr_t paddr) { - desc->buffer_addr_low = cpu_to_le32(paddr & HAL_ADDR_LSB_REG_MASK); - desc->buffer_addr_info = - le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_CE_DEST_DESC_ADDR_INFO_ADDR_HI); + hal->hal_ops->ce_dst_set_desc(desc, paddr); } u32 ath12k_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc) diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 8e7e64be970c4..651ad31b05b2b 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1708,6 +1708,12 @@ struct hal_ops { int ring_num); int (*srng_get_ring_id)(struct ath12k_hal *hal, enum hal_ring_type type, int ring_num, int mac_id); + u32 (*ce_get_desc_size)(enum hal_ce_desc type); + void (*ce_src_set_desc)(struct hal_ce_srng_src_desc *desc, + dma_addr_t paddr, u32 len, u32 id, + u8 byte_swap_data); + void (*ce_dst_set_desc)(struct hal_ce_srng_dest_desc *desc, + dma_addr_t paddr); }; u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); @@ -1730,10 +1736,14 @@ dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab, void ath12k_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, u32 cookie, dma_addr_t paddr, enum hal_rx_buf_return_buf_manager rbm); -u32 ath12k_hal_ce_get_desc_size(enum hal_ce_desc type); -void ath12k_hal_ce_src_set_desc(struct hal_ce_srng_src_desc *desc, dma_addr_t paddr, - u32 len, u32 id, u8 byte_swap_data); -void ath12k_hal_ce_dst_set_desc(struct hal_ce_srng_dest_desc *desc, dma_addr_t paddr); +u32 ath12k_hal_ce_get_desc_size(struct ath12k_hal *hal, enum hal_ce_desc type); +void ath12k_hal_ce_dst_set_desc(struct ath12k_hal *hal, + struct hal_ce_srng_dest_desc *desc, + dma_addr_t paddr); +void ath12k_hal_ce_src_set_desc(struct ath12k_hal *hal, + struct hal_ce_srng_src_desc *desc, + dma_addr_t paddr, u32 len, u32 id, + u8 byte_swap_data); u32 ath12k_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc); int ath12k_hal_srng_get_entrysize(struct ath12k_base *ab, u32 ring_type); int ath12k_hal_srng_get_max_entries(struct ath12k_base *ab, u32 ring_type); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 565f43a30deb9..06a6af8c9c8a7 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -382,6 +382,20 @@ void ath12k_wifi7_hal_srng_update_hp_tp_addr(struct ath12k_base *ab, (unsigned long)ab->mem); } +u32 ath12k_wifi7_hal_ce_get_desc_size(enum hal_ce_desc type) +{ + switch (type) { + case HAL_CE_DESC_SRC: + return sizeof(struct hal_ce_srng_src_desc); + case HAL_CE_DESC_DST: + return sizeof(struct hal_ce_srng_dest_desc); + case HAL_CE_DESC_DST_STATUS: + return sizeof(struct hal_ce_srng_dst_status_desc); + } + + return 0; +} + int ath12k_wifi7_hal_srng_update_shadow_config(struct ath12k_base *ab, enum hal_ring_type ring_type, int ring_num) @@ -419,3 +433,27 @@ int ath12k_wifi7_hal_srng_update_shadow_config(struct ath12k_base *ab, return 0; } + +void ath12k_wifi7_hal_ce_src_set_desc(struct hal_ce_srng_src_desc *desc, + dma_addr_t paddr, + u32 len, u32 id, u8 byte_swap_data) +{ + desc->buffer_addr_low = cpu_to_le32(paddr & HAL_ADDR_LSB_REG_MASK); + desc->buffer_addr_info = + le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_CE_SRC_DESC_ADDR_INFO_ADDR_HI) | + le32_encode_bits(byte_swap_data, + HAL_CE_SRC_DESC_ADDR_INFO_BYTE_SWAP) | + le32_encode_bits(0, HAL_CE_SRC_DESC_ADDR_INFO_GATHER) | + le32_encode_bits(len, HAL_CE_SRC_DESC_ADDR_INFO_LEN); + desc->meta_info = le32_encode_bits(id, HAL_CE_SRC_DESC_META_INFO_DATA); +} + +void ath12k_wifi7_hal_ce_dst_set_desc(struct hal_ce_srng_dest_desc *desc, + dma_addr_t paddr) +{ + desc->buffer_addr_low = cpu_to_le32(paddr & HAL_ADDR_LSB_REG_MASK); + desc->buffer_addr_info = + le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_CE_DEST_DESC_ADDR_INFO_ADDR_HI); +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index 1ea7b025ed713..b0b591eb5a0a4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -22,4 +22,10 @@ int ath12k_wifi7_hal_srng_update_shadow_config(struct ath12k_base *ab, int ath12k_wifi7_hal_srng_get_ring_id(struct ath12k_hal *hal, enum hal_ring_type type, int ring_num, int mac_id); +u32 ath12k_wifi7_hal_ce_get_desc_size(enum hal_ce_desc type); +void ath12k_wifi7_hal_ce_src_set_desc(struct hal_ce_srng_src_desc *desc, + dma_addr_t paddr, + u32 len, u32 id, u8 byte_swap_data); +void ath12k_wifi7_hal_ce_dst_set_desc(struct hal_ce_srng_dest_desc *desc, + dma_addr_t paddr); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 92769a525c6d2..113a0424d5eb2 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1006,5 +1006,8 @@ const struct hal_ops hal_qcn9274_ops = { .set_umac_srng_ptr_addr = ath12k_wifi7_hal_set_umac_srng_ptr_addr, .srng_update_shadow_config = ath12k_wifi7_hal_srng_update_shadow_config, .srng_get_ring_id = ath12k_wifi7_hal_srng_get_ring_id, + .ce_get_desc_size = ath12k_wifi7_hal_ce_get_desc_size, + .ce_src_set_desc = ath12k_wifi7_hal_ce_src_set_desc, + .ce_dst_set_desc = ath12k_wifi7_hal_ce_dst_set_desc, }; EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index a941bb4783ae4..60a21137bd358 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -821,5 +821,8 @@ const struct hal_ops hal_wcn7850_ops = { .set_umac_srng_ptr_addr = ath12k_wifi7_hal_set_umac_srng_ptr_addr, .srng_update_shadow_config = ath12k_wifi7_hal_srng_update_shadow_config, .srng_get_ring_id = ath12k_wifi7_hal_srng_get_ring_id, + .ce_get_desc_size = ath12k_wifi7_hal_ce_get_desc_size, + .ce_src_set_desc = ath12k_wifi7_hal_ce_src_set_desc, + .ce_dst_set_desc = ath12k_wifi7_hal_ce_dst_set_desc, }; EXPORT_SYMBOL(hal_wcn7850_ops); From 8f49e53b801fb05645f465e48dd565c790cbc254 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:38 +0530 Subject: [PATCH 060/140] wifi: ath12k: Move HAL CE status and set link desc addr APIs to wifi7 directory Move the hardware specific HAL APIs to hal.c file inside wifi7 directory. These APIs will be called through the hal_ops mechanism, which are registered separately by qcn and wcn Handling following APIs: ath12k_wifi7_hal_ce_dst_status_get_length ath12k_wifi7_hal_set_link_desc_addr Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-12-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ce.c | 2 +- drivers/net/wireless/ath/ath12k/dp.c | 5 ++-- drivers/net/wireless/ath/ath12k/hal.c | 24 ++++++------------- drivers/net/wireless/ath/ath12k/hal.h | 14 +++++++---- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 1 + drivers/net/wireless/ath/ath12k/wifi7/hal.c | 23 ++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/hal.h | 6 +++++ .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 2 ++ .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 2 ++ 9 files changed, 55 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ce.c b/drivers/net/wireless/ath/ath12k/ce.c index 30140a3330476..9f9d2f2477c77 100644 --- a/drivers/net/wireless/ath/ath12k/ce.c +++ b/drivers/net/wireless/ath/ath12k/ce.c @@ -133,7 +133,7 @@ static int ath12k_ce_completed_recv_next(struct ath12k_ce_pipe *pipe, goto err; } - *nbytes = ath12k_hal_ce_dst_status_get_length(desc); + *nbytes = ath12k_hal_ce_dst_status_get_length(&ab->hal, desc); *skb = pipe->dest_ring->skb[sw_index]; pipe->dest_ring->skb[sw_index] = NULL; diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 3550c88c34bb9..6d405f4aa11a2 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -661,7 +661,7 @@ static int ath12k_dp_scatter_idle_link_desc_setup(struct ath12k_base *ab, paddr = link_desc_banks[i].paddr; while (n_entries) { cookie = DP_LINK_DESC_COOKIE_SET(n_entries, i); - ath12k_hal_set_link_desc_addr(scatter_buf, cookie, + ath12k_hal_set_link_desc_addr(dp->hal, scatter_buf, cookie, paddr, rbm); n_entries--; paddr += HAL_LINK_DESC_SIZE; @@ -868,7 +868,8 @@ int ath12k_dp_link_desc_setup(struct ath12k_base *ab, while (n_entries && (desc = ath12k_hal_srng_src_get_next_entry(ab, srng))) { cookie = DP_LINK_DESC_COOKIE_SET(n_entries, i); - ath12k_hal_set_link_desc_addr(desc, cookie, paddr, rbm); + ath12k_hal_set_link_desc_addr(dp->hal, desc, cookie, paddr, + rbm); n_entries--; paddr += HAL_LINK_DESC_SIZE; } diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 490a483b8c306..5c13eaf9c19e7 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -205,27 +205,17 @@ void ath12k_hal_ce_dst_set_desc(struct ath12k_hal *hal, hal->hal_ops->ce_dst_set_desc(desc, paddr); } -u32 ath12k_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc) +u32 ath12k_hal_ce_dst_status_get_length(struct ath12k_hal *hal, + struct hal_ce_srng_dst_status_desc *desc) { - u32 len; - - len = le32_get_bits(desc->flags, HAL_CE_DST_STATUS_DESC_FLAGS_LEN); - desc->flags &= ~cpu_to_le32(HAL_CE_DST_STATUS_DESC_FLAGS_LEN); - - return len; + return hal->hal_ops->ce_dst_status_get_length(desc); } -void ath12k_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, u32 cookie, - dma_addr_t paddr, - enum hal_rx_buf_return_buf_manager rbm) +void ath12k_hal_set_link_desc_addr(struct ath12k_hal *hal, + struct hal_wbm_link_desc *desc, u32 cookie, + dma_addr_t paddr, int rbm) { - desc->buf_addr_info.info0 = le32_encode_bits((paddr & HAL_ADDR_LSB_REG_MASK), - BUFFER_ADDR_INFO0_ADDR); - desc->buf_addr_info.info1 = - le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT), - BUFFER_ADDR_INFO1_ADDR) | - le32_encode_bits(rbm, BUFFER_ADDR_INFO1_RET_BUF_MGR) | - le32_encode_bits(cookie, BUFFER_ADDR_INFO1_SW_COOKIE); + hal->hal_ops->set_link_desc_addr(desc, cookie, paddr, rbm); } void *ath12k_hal_srng_dst_peek(struct ath12k_base *ab, struct hal_srng *srng) diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 651ad31b05b2b..74ceb3d74eb80 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1714,6 +1714,10 @@ struct hal_ops { u8 byte_swap_data); void (*ce_dst_set_desc)(struct hal_ce_srng_dest_desc *desc, dma_addr_t paddr); + u32 (*ce_dst_status_get_length)(struct hal_ce_srng_dst_status_desc *desc); + void (*set_link_desc_addr)(struct hal_wbm_link_desc *desc, u32 cookie, + dma_addr_t paddr, + enum hal_rx_buf_return_buf_manager rbm); }; u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); @@ -1733,9 +1737,6 @@ dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab, struct hal_srng *srng); dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab, struct hal_srng *srng); -void ath12k_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, u32 cookie, - dma_addr_t paddr, - enum hal_rx_buf_return_buf_manager rbm); u32 ath12k_hal_ce_get_desc_size(struct ath12k_hal *hal, enum hal_ce_desc type); void ath12k_hal_ce_dst_set_desc(struct ath12k_hal *hal, struct hal_ce_srng_dest_desc *desc, @@ -1744,7 +1745,6 @@ void ath12k_hal_ce_src_set_desc(struct ath12k_hal *hal, struct hal_ce_srng_src_desc *desc, dma_addr_t paddr, u32 len, u32 id, u8 byte_swap_data); -u32 ath12k_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc); int ath12k_hal_srng_get_entrysize(struct ath12k_base *ab, u32 ring_type); int ath12k_hal_srng_get_max_entries(struct ath12k_base *ab, u32 ring_type); void ath12k_hal_srng_get_params(struct ath12k_base *ab, struct hal_srng *srng, @@ -1783,4 +1783,10 @@ void ath12k_hal_srng_shadow_config(struct ath12k_base *ab); void ath12k_hal_srng_shadow_update_hp_tp(struct ath12k_base *ab, struct hal_srng *srng); void ath12k_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab); +void ath12k_hal_set_link_desc_addr(struct ath12k_hal *hal, + struct hal_wbm_link_desc *desc, u32 cookie, + dma_addr_t paddr, int rbm); +u32 +ath12k_hal_ce_dst_status_get_length(struct ath12k_hal *hal, + struct hal_ce_srng_dst_status_desc *desc); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index e691d0ca0d75c..06d3690ff0c63 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -12,6 +12,7 @@ #include "dp_rx.h" #include "dp.h" #include "dp_tx.h" +#include "hal.h" static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, struct ath12k_ext_irq_grp *irq_grp, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 06a6af8c9c8a7..c9e853a32378c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -457,3 +457,26 @@ void ath12k_wifi7_hal_ce_dst_set_desc(struct hal_ce_srng_dest_desc *desc, le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT), HAL_CE_DEST_DESC_ADDR_INFO_ADDR_HI); } + +void ath12k_wifi7_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, + u32 cookie, dma_addr_t paddr, + enum hal_rx_buf_return_buf_manager rbm) +{ + desc->buf_addr_info.info0 = le32_encode_bits((paddr & HAL_ADDR_LSB_REG_MASK), + BUFFER_ADDR_INFO0_ADDR); + desc->buf_addr_info.info1 = + le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT), + BUFFER_ADDR_INFO1_ADDR) | + le32_encode_bits(rbm, BUFFER_ADDR_INFO1_RET_BUF_MGR) | + le32_encode_bits(cookie, BUFFER_ADDR_INFO1_SW_COOKIE); +} + +u32 ath12k_wifi7_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc) +{ + u32 len; + + len = le32_get_bits(READ_ONCE(desc->flags), HAL_CE_DST_STATUS_DESC_FLAGS_LEN); + desc->flags &= ~cpu_to_le32(HAL_CE_DST_STATUS_DESC_FLAGS_LEN); + + return len; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index b0b591eb5a0a4..308f804276768 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -28,4 +28,10 @@ void ath12k_wifi7_hal_ce_src_set_desc(struct hal_ce_srng_src_desc *desc, u32 len, u32 id, u8 byte_swap_data); void ath12k_wifi7_hal_ce_dst_set_desc(struct hal_ce_srng_dest_desc *desc, dma_addr_t paddr); +void +ath12k_wifi7_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, + u32 cookie, dma_addr_t paddr, + enum hal_rx_buf_return_buf_manager rbm); +u32 +ath12k_wifi7_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 113a0424d5eb2..b764d5cd8aeb6 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1009,5 +1009,7 @@ const struct hal_ops hal_qcn9274_ops = { .ce_get_desc_size = ath12k_wifi7_hal_ce_get_desc_size, .ce_src_set_desc = ath12k_wifi7_hal_ce_src_set_desc, .ce_dst_set_desc = ath12k_wifi7_hal_ce_dst_set_desc, + .ce_dst_status_get_length = ath12k_wifi7_hal_ce_dst_status_get_length, + .set_link_desc_addr = ath12k_wifi7_hal_set_link_desc_addr, }; EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 60a21137bd358..0985f929a4b58 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -824,5 +824,7 @@ const struct hal_ops hal_wcn7850_ops = { .ce_get_desc_size = ath12k_wifi7_hal_ce_get_desc_size, .ce_src_set_desc = ath12k_wifi7_hal_ce_src_set_desc, .ce_dst_set_desc = ath12k_wifi7_hal_ce_dst_set_desc, + .ce_dst_status_get_length = ath12k_wifi7_hal_ce_dst_status_get_length, + .set_link_desc_addr = ath12k_wifi7_hal_set_link_desc_addr, }; EXPORT_SYMBOL(hal_wcn7850_ops); From 2e2462cadbc1dc1c84c619be820df77e2fd99de3 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:39 +0530 Subject: [PATCH 061/140] wifi: ath12k: Move HAL Tx, REO and link idle setup related APIs to wifi7 directory Move the hardware specific HAL APIs to hal.c file inside wifi7 directory. These APIs will be called through the hal_ops mechanism, which are registered separately by qcn and wcn Handling following APIs: ath12k_wifi7_hal_tx_set_dscp_tid_map ath12k_wifi7_hal_tx_configure_bank_register ath12k_hal_reoq_lut_addr_read_enable ath12k_hal_reoq_lut_set_max_peerid ath12k_wifi7_hal_write_reoq_lut_addr ath12k_wifi7_hal_write_ml_reoq_lut_addr ath12k_wifi7_hal_setup_link_idle_list Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-13-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 33 ++-- drivers/net/wireless/ath/ath12k/hal.c | 148 +++++------------ drivers/net/wireless/ath/ath12k/hal.h | 30 +++- drivers/net/wireless/ath/ath12k/wifi7/hal.c | 150 ++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/hal.h | 11 ++ .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 9 ++ .../net/wireless/ath/ath12k/wifi7/hal_tx.c | 8 - .../net/wireless/ath/ath12k/wifi7/hal_tx.h | 5 +- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 9 ++ 9 files changed, 255 insertions(+), 148 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 6d405f4aa11a2..19bae6a1b9339 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -425,8 +425,8 @@ static int ath12k_dp_tx_get_bank_profile(struct ath12k_base *ab, spin_unlock_bh(&dp->tx_bank_lock); if (configure_register) - ath12k_wifi7_hal_tx_configure_bank_register(ab, bank_config, - bank_id); + ath12k_hal_tx_configure_bank_register(ab, + bank_config, bank_id); ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt tcl bank_id %d input 0x%x match 0x%x num_users %u", bank_id, bank_config, dp->bank_profiles[bank_id].bank_config, @@ -1149,9 +1149,7 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab) return; if (dp->reoq_lut.vaddr_unaligned) { - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_REO_REG + - HAL_REO1_QDESC_LUT_BASE0(dp->hal), 0); + ath12k_hal_write_reoq_lut_addr(ab, 0); dma_free_coherent(ab->dev, dp->reoq_lut.size, dp->reoq_lut.vaddr_unaligned, dp->reoq_lut.paddr_unaligned); @@ -1159,9 +1157,7 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab) } if (dp->ml_reoq_lut.vaddr_unaligned) { - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_REO_REG + - HAL_REO1_QDESC_LUT_BASE1(dp->hal), 0); + ath12k_hal_write_ml_reoq_lut_addr(ab, 0); dma_free_coherent(ab->dev, dp->ml_reoq_lut.size, dp->ml_reoq_lut.vaddr_unaligned, dp->ml_reoq_lut.paddr_unaligned); @@ -1539,8 +1535,6 @@ static int ath12k_dp_alloc_reoq_lut(struct ath12k_base *ab, static int ath12k_dp_reoq_lut_setup(struct ath12k_base *ab) { struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - struct ath12k_hal *hal = dp->hal; - u32 val; int ret; if (!ab->hw_params->reoq_lut_support) @@ -1568,19 +1562,10 @@ static int ath12k_dp_reoq_lut_setup(struct ath12k_base *ab) * register only */ - ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE0(hal), - dp->reoq_lut.paddr >> 8); - - ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE1(hal), - dp->ml_reoq_lut.paddr >> 8); - - val = ath12k_hif_read32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_ADDR(hal)); - - ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_ADDR(hal), - val | HAL_REO_QDESC_ADDR_READ_LUT_ENABLE); - - ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_MAX_PEERID(hal), - HAL_REO_QDESC_MAX_PEERID); + ath12k_hal_write_reoq_lut_addr(ab, dp->reoq_lut.paddr >> 8); + ath12k_hal_write_ml_reoq_lut_addr(ab, dp->ml_reoq_lut.paddr >> 8); + ath12k_hal_reoq_lut_addr_read_enable(ab); + ath12k_hal_reoq_lut_set_max_peerid(ab); return 0; } @@ -1680,7 +1665,7 @@ static int ath12k_dp_setup(struct ath12k_base *ab) } for (i = 0; i < HAL_DSCP_TID_MAP_TBL_NUM_ENTRIES_MAX; i++) - ath12k_wifi7_hal_tx_set_dscp_tid_map(ab, i); + ath12k_hal_tx_set_dscp_tid_map(ab, i); ret = ath12k_dp_rx_alloc(ab); if (ret) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 5c13eaf9c19e7..b3010eea9afca 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -56,6 +56,46 @@ u32 ath12k_hal_ce_get_desc_size(struct ath12k_hal *hal, enum hal_ce_desc type) return hal->hal_ops->ce_get_desc_size(type); } +void ath12k_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id) +{ + ab->hal.hal_ops->tx_set_dscp_tid_map(ab, id); +} + +void ath12k_hal_tx_configure_bank_register(struct ath12k_base *ab, + u32 bank_config, u8 bank_id) +{ + ab->hal.hal_ops->tx_configure_bank_register(ab, bank_config, bank_id); +} + +void ath12k_hal_reoq_lut_addr_read_enable(struct ath12k_base *ab) +{ + ab->hal.hal_ops->reoq_lut_addr_read_enable(ab); +} + +void ath12k_hal_reoq_lut_set_max_peerid(struct ath12k_base *ab) +{ + ab->hal.hal_ops->reoq_lut_set_max_peerid(ab); +} + +void ath12k_hal_write_ml_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr) +{ + ab->hal.hal_ops->write_ml_reoq_lut_addr(ab, paddr); +} + +void ath12k_hal_write_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr) +{ + ab->hal.hal_ops->write_reoq_lut_addr(ab, paddr); +} + +void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, + struct hal_wbm_idle_scatter_list *sbuf, + u32 nsbufs, u32 tot_link_desc, + u32 end_offset) +{ + ab->hal.hal_ops->setup_link_idle_list(ab, sbuf, nsbufs, tot_link_desc, + end_offset); +} + static int ath12k_hal_alloc_cont_rdp(struct ath12k_hal *hal) { size_t size; @@ -467,114 +507,6 @@ void ath12k_hal_srng_access_end(struct ath12k_base *ab, struct hal_srng *srng) srng->timestamp = jiffies; } -void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, - struct hal_wbm_idle_scatter_list *sbuf, - u32 nsbufs, u32 tot_link_desc, - u32 end_offset) -{ - struct ath12k_hal *hal = &ab->hal; - struct ath12k_buffer_addr *link_addr; - int i; - u32 reg_scatter_buf_sz = HAL_WBM_IDLE_SCATTER_BUF_SIZE / 64; - u32 val; - - link_addr = (void *)sbuf[0].vaddr + HAL_WBM_IDLE_SCATTER_BUF_SIZE; - - for (i = 1; i < nsbufs; i++) { - link_addr->info0 = cpu_to_le32(sbuf[i].paddr & HAL_ADDR_LSB_REG_MASK); - - link_addr->info1 = - le32_encode_bits((u64)sbuf[i].paddr >> HAL_ADDR_MSB_REG_SHIFT, - HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) | - le32_encode_bits(BASE_ADDR_MATCH_TAG_VAL, - HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG); - - link_addr = (void *)sbuf[i].vaddr + - HAL_WBM_IDLE_SCATTER_BUF_SIZE; - } - - val = u32_encode_bits(reg_scatter_buf_sz, HAL_WBM_SCATTER_BUFFER_SIZE) | - u32_encode_bits(0x1, HAL_WBM_LINK_DESC_IDLE_LIST_MODE); - - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(hal), - val); - - val = u32_encode_bits(reg_scatter_buf_sz * nsbufs, - HAL_WBM_SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST); - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(hal), - val); - - val = u32_encode_bits(sbuf[0].paddr & HAL_ADDR_LSB_REG_MASK, - BUFFER_ADDR_INFO0_ADDR); - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_RING_BASE_LSB(hal), - val); - - val = u32_encode_bits(BASE_ADDR_MATCH_TAG_VAL, - HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG) | - u32_encode_bits((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT, - HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32); - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_RING_BASE_MSB(hal), - val); - - /* Setup head and tail pointers for the idle list */ - val = u32_encode_bits(sbuf[nsbufs - 1].paddr, BUFFER_ADDR_INFO0_ADDR); - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal), - val); - - val = u32_encode_bits(((u64)sbuf[nsbufs - 1].paddr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) | - u32_encode_bits((end_offset >> 2), - HAL_WBM_SCATTERED_DESC_HEAD_P_OFFSET_IX1); - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(hal), - val); - - val = u32_encode_bits(sbuf[0].paddr, BUFFER_ADDR_INFO0_ADDR); - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal), - val); - - val = u32_encode_bits(sbuf[0].paddr, BUFFER_ADDR_INFO0_ADDR); - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(hal), - val); - - val = u32_encode_bits(((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) | - u32_encode_bits(0, HAL_WBM_SCATTERED_DESC_TAIL_P_OFFSET_IX1); - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(hal), - val); - - val = 2 * tot_link_desc; - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(hal), - val); - - /* Enable the SRNG */ - val = u32_encode_bits(1, HAL_WBM_IDLE_LINK_RING_MISC_SRNG_ENABLE) | - u32_encode_bits(1, HAL_WBM_IDLE_LINK_RING_MISC_RIND_ID_DISABLE); - ath12k_hif_write32(ab, - HAL_SEQ_WCSS_UMAC_WBM_REG + - HAL_WBM_IDLE_LINK_RING_MISC_ADDR(hal), - val); -} - int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, int ring_num, int mac_id, struct hal_srng_params *params) diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 74ceb3d74eb80..fb9aaee5c2539 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1718,6 +1718,18 @@ struct hal_ops { void (*set_link_desc_addr)(struct hal_wbm_link_desc *desc, u32 cookie, dma_addr_t paddr, enum hal_rx_buf_return_buf_manager rbm); + void (*tx_set_dscp_tid_map)(struct ath12k_base *ab, int id); + void (*tx_configure_bank_register)(struct ath12k_base *ab, + u32 bank_config, u8 bank_id); + void (*reoq_lut_addr_read_enable)(struct ath12k_base *ab); + void (*reoq_lut_set_max_peerid)(struct ath12k_base *ab); + void (*write_ml_reoq_lut_addr)(struct ath12k_base *ab, + dma_addr_t paddr); + void (*write_reoq_lut_addr)(struct ath12k_base *ab, dma_addr_t paddr); + void (*setup_link_idle_list)(struct ath12k_base *ab, + struct hal_wbm_idle_scatter_list *sbuf, + u32 nsbufs, u32 tot_link_desc, + u32 end_offset); }; u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); @@ -1727,12 +1739,6 @@ void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, struct hal_srng *srng); void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); - -void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, - struct hal_wbm_idle_scatter_list *sbuf, - u32 nsbufs, u32 tot_link_desc, - u32 end_offset); - dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab, struct hal_srng *srng); dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab, @@ -1786,7 +1792,19 @@ void ath12k_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab); void ath12k_hal_set_link_desc_addr(struct ath12k_hal *hal, struct hal_wbm_link_desc *desc, u32 cookie, dma_addr_t paddr, int rbm); +void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, + struct hal_wbm_idle_scatter_list *sbuf, + u32 nsbufs, u32 tot_link_desc, + u32 end_offset); u32 ath12k_hal_ce_dst_status_get_length(struct ath12k_hal *hal, struct hal_ce_srng_dst_status_desc *desc); +void ath12k_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id); +void ath12k_hal_tx_configure_bank_register(struct ath12k_base *ab, + u32 bank_config, u8 bank_id); +void ath12k_hal_reoq_lut_addr_read_enable(struct ath12k_base *ab); +void ath12k_hal_reoq_lut_set_max_peerid(struct ath12k_base *ab); +void ath12k_hal_write_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr); +void +ath12k_hal_write_ml_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index c9e853a32378c..73d86dedadb1d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -7,6 +7,7 @@ #include "hal_desc.h" #include "../hal.h" #include "hal.h" +#include "hal_tx.h" #include "../debug.h" #include "../hif.h" #include "hal_qcn9274.h" @@ -480,3 +481,152 @@ u32 ath12k_wifi7_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc return len; } + +void +ath12k_wifi7_hal_setup_link_idle_list(struct ath12k_base *ab, + struct hal_wbm_idle_scatter_list *sbuf, + u32 nsbufs, u32 tot_link_desc, + u32 end_offset) +{ + struct ath12k_hal *hal = &ab->hal; + struct ath12k_buffer_addr *link_addr; + int i; + u32 reg_scatter_buf_sz = HAL_WBM_IDLE_SCATTER_BUF_SIZE / 64; + u32 val; + + link_addr = (void *)sbuf[0].vaddr + HAL_WBM_IDLE_SCATTER_BUF_SIZE; + + for (i = 1; i < nsbufs; i++) { + link_addr->info0 = cpu_to_le32(sbuf[i].paddr & HAL_ADDR_LSB_REG_MASK); + + link_addr->info1 = + le32_encode_bits((u64)sbuf[i].paddr >> HAL_ADDR_MSB_REG_SHIFT, + HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) | + le32_encode_bits(BASE_ADDR_MATCH_TAG_VAL, + HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG); + + link_addr = (void *)sbuf[i].vaddr + + HAL_WBM_IDLE_SCATTER_BUF_SIZE; + } + + val = u32_encode_bits(reg_scatter_buf_sz, HAL_WBM_SCATTER_BUFFER_SIZE) | + u32_encode_bits(0x1, HAL_WBM_LINK_DESC_IDLE_LIST_MODE); + + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(hal), + val); + + val = u32_encode_bits(reg_scatter_buf_sz * nsbufs, + HAL_WBM_SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST); + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(hal), + val); + + val = u32_encode_bits(sbuf[0].paddr & HAL_ADDR_LSB_REG_MASK, + BUFFER_ADDR_INFO0_ADDR); + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SCATTERED_RING_BASE_LSB(hal), + val); + + val = u32_encode_bits(BASE_ADDR_MATCH_TAG_VAL, + HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG) | + u32_encode_bits((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT, + HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32); + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SCATTERED_RING_BASE_MSB(hal), + val); + + /* Setup head and tail pointers for the idle list */ + val = u32_encode_bits(sbuf[nsbufs - 1].paddr, BUFFER_ADDR_INFO0_ADDR); + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal), + val); + + val = u32_encode_bits(((u64)sbuf[nsbufs - 1].paddr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) | + u32_encode_bits((end_offset >> 2), + HAL_WBM_SCATTERED_DESC_HEAD_P_OFFSET_IX1); + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(hal), + val); + + val = u32_encode_bits(sbuf[0].paddr, BUFFER_ADDR_INFO0_ADDR); + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal), + val); + + val = u32_encode_bits(sbuf[0].paddr, BUFFER_ADDR_INFO0_ADDR); + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(hal), + val); + + val = u32_encode_bits(((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) | + u32_encode_bits(0, HAL_WBM_SCATTERED_DESC_TAIL_P_OFFSET_IX1); + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(hal), + val); + + val = 2 * tot_link_desc; + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(hal), + val); + + /* Enable the SRNG */ + val = u32_encode_bits(1, HAL_WBM_IDLE_LINK_RING_MISC_SRNG_ENABLE) | + u32_encode_bits(1, HAL_WBM_IDLE_LINK_RING_MISC_RIND_ID_DISABLE); + ath12k_hif_write32(ab, + HAL_SEQ_WCSS_UMAC_WBM_REG + + HAL_WBM_IDLE_LINK_RING_MISC_ADDR(hal), + val); +} + +void ath12k_wifi7_hal_tx_configure_bank_register(struct ath12k_base *ab, + u32 bank_config, + u8 bank_id) +{ + ath12k_hif_write32(ab, HAL_TCL_SW_CONFIG_BANK_ADDR + 4 * bank_id, + bank_config); +} + +void ath12k_wifi7_hal_reoq_lut_addr_read_enable(struct ath12k_base *ab) +{ + struct ath12k_hal *hal = &ab->hal; + + u32 val = ath12k_hif_read32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + + HAL_REO1_QDESC_ADDR(hal)); + + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_ADDR(hal), + val | HAL_REO_QDESC_ADDR_READ_LUT_ENABLE); +} + +void ath12k_wifi7_hal_reoq_lut_set_max_peerid(struct ath12k_base *ab) +{ + struct ath12k_hal *hal = &ab->hal; + + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_MAX_PEERID(hal), + HAL_REO_QDESC_MAX_PEERID); +} + +void ath12k_wifi7_hal_write_reoq_lut_addr(struct ath12k_base *ab, + dma_addr_t paddr) +{ + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + + HAL_REO1_QDESC_LUT_BASE0(&ab->hal), paddr); +} + +void ath12k_wifi7_hal_write_ml_reoq_lut_addr(struct ath12k_base *ab, + dma_addr_t paddr) +{ + ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + + HAL_REO1_QDESC_LUT_BASE1(&ab->hal), paddr); +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index 308f804276768..6e67f06ffa438 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -34,4 +34,15 @@ ath12k_wifi7_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, enum hal_rx_buf_return_buf_manager rbm); u32 ath12k_wifi7_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc); +void +ath12k_wifi7_hal_setup_link_idle_list(struct ath12k_base *ab, + struct hal_wbm_idle_scatter_list *sbuf, + u32 nsbufs, u32 tot_link_desc, + u32 end_offset); +void ath12k_wifi7_hal_reoq_lut_addr_read_enable(struct ath12k_base *ab); +void ath12k_wifi7_hal_reoq_lut_set_max_peerid(struct ath12k_base *ab); +void ath12k_wifi7_hal_write_reoq_lut_addr(struct ath12k_base *ab, + dma_addr_t paddr); +void ath12k_wifi7_hal_write_ml_reoq_lut_addr(struct ath12k_base *ab, + dma_addr_t paddr); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index b764d5cd8aeb6..9cbae6d11dd84 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -7,6 +7,7 @@ #include "hal_qcn9274.h" #include "hw.h" #include "hal.h" +#include "hal_tx.h" static const struct hal_srng_config hw_srng_config_template[] = { /* TODO: max_rings can populated by querying HW capabilities */ @@ -1011,5 +1012,13 @@ const struct hal_ops hal_qcn9274_ops = { .ce_dst_set_desc = ath12k_wifi7_hal_ce_dst_set_desc, .ce_dst_status_get_length = ath12k_wifi7_hal_ce_dst_status_get_length, .set_link_desc_addr = ath12k_wifi7_hal_set_link_desc_addr, + .tx_set_dscp_tid_map = ath12k_wifi7_hal_tx_set_dscp_tid_map, + .tx_configure_bank_register = + ath12k_wifi7_hal_tx_configure_bank_register, + .reoq_lut_addr_read_enable = ath12k_wifi7_hal_reoq_lut_addr_read_enable, + .reoq_lut_set_max_peerid = ath12k_wifi7_hal_reoq_lut_set_max_peerid, + .write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr, + .write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr, + .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list, }; EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c index 027e02141ec2c..24f905c5b0624 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c @@ -136,11 +136,3 @@ void ath12k_wifi7_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id) HAL_TCL1_RING_CMN_CTRL_REG, ctrl_reg_val); } - -void ath12k_wifi7_hal_tx_configure_bank_register(struct ath12k_base *ab, - u32 bank_config, - u8 bank_id) -{ - ath12k_hif_write32(ab, HAL_TCL_SW_CONFIG_BANK_ADDR + 4 * bank_id, - bank_config); -} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h index d0f6a174f347c..07392b31d0ab9 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h @@ -181,13 +181,14 @@ struct hal_tx_fes_status_end { /* STA mode will have MCAST_PKT_CTRL instead of DSCP_TID_MAP bitfield */ #define HAL_TX_BANK_CONFIG_DSCP_TIP_MAP_ID GENMASK(22, 17) +void ath12k_wifi7_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id); void ath12k_wifi7_hal_tx_cmd_desc_setup(struct ath12k_base *ab, struct hal_tcl_data_cmd *tcl_cmd, struct hal_tx_info *ti); -void ath12k_wifi7_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id); int ath12k_wifi7_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, enum hal_reo_cmd_type type, struct ath12k_hal_reo_cmd *cmd); void ath12k_wifi7_hal_tx_configure_bank_register(struct ath12k_base *ab, - u32 bank_config, u8 bank_id); + u32 bank_config, + u8 bank_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 0985f929a4b58..2e645f8f4a144 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -8,6 +8,7 @@ #include "hal_wcn7850.h" #include "hw.h" #include "hal.h" +#include "hal_tx.h" static const struct hal_srng_config hw_srng_config_template[] = { /* TODO: max_rings can populated by querying HW capabilities */ @@ -826,5 +827,13 @@ const struct hal_ops hal_wcn7850_ops = { .ce_dst_set_desc = ath12k_wifi7_hal_ce_dst_set_desc, .ce_dst_status_get_length = ath12k_wifi7_hal_ce_dst_status_get_length, .set_link_desc_addr = ath12k_wifi7_hal_set_link_desc_addr, + .tx_set_dscp_tid_map = ath12k_wifi7_hal_tx_set_dscp_tid_map, + .tx_configure_bank_register = + ath12k_wifi7_hal_tx_configure_bank_register, + .reoq_lut_addr_read_enable = ath12k_wifi7_hal_reoq_lut_addr_read_enable, + .reoq_lut_set_max_peerid = ath12k_wifi7_hal_reoq_lut_set_max_peerid, + .write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr, + .write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr, + .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list, }; EXPORT_SYMBOL(hal_wcn7850_ops); From 4cb14cf11a6e9511b1c220cb847495eace903c75 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:40 +0530 Subject: [PATCH 062/140] wifi: ath12k: Move HAL REO and Rx buf related APIs to wifi7 directory Move the hardware specific HAL APIs to hal.c file inside wifi7 directory. These APIs will be called through the hal_ops mechanism, which are registered separately by qcn and wcn Handling following APIs: ath12k_wifi7_hal_reo_qdesc_setup ath12k_wifi7_hal_reo_init_cmd_ring ath12k_wifi7_hal_reo_hw_setup ath12k_wifi7_hal_rx_buf_addr_info_set ath12k_wifi7_hal_rx_buf_addr_info_get Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-14-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dbring.c | 4 +-- drivers/net/wireless/ath/ath12k/dp.c | 4 +-- drivers/net/wireless/ath/ath12k/dp_rx.c | 3 ++- drivers/net/wireless/ath/ath12k/hal.c | 25 +++++++++++++++++++ drivers/net/wireless/ath/ath12k/hal.h | 23 ++++++++++++----- .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 4 +++ .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 6 +++++ .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 4 +++ 8 files changed, 62 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dbring.c b/drivers/net/wireless/ath/ath12k/dbring.c index 093298f8acabd..a387cb9554d24 100644 --- a/drivers/net/wireless/ath/ath12k/dbring.c +++ b/drivers/net/wireless/ath/ath12k/dbring.c @@ -54,7 +54,7 @@ static int ath12k_dbring_bufs_replenish(struct ath12k *ar, cookie = u32_encode_bits(ar->pdev_idx, DP_RXDMA_BUF_COOKIE_PDEV_ID) | u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID); - ath12k_wifi7_hal_rx_buf_addr_info_set(desc, paddr, cookie, 0); + ath12k_hal_rx_buf_addr_info_set(&ab->hal, desc, paddr, cookie, 0); ath12k_hal_srng_access_end(ab, srng); @@ -297,7 +297,7 @@ int ath12k_dbring_buffer_release_event(struct ath12k_base *ab, num_buff_reaped++; - ath12k_wifi7_hal_rx_buf_addr_info_get(&desc, &paddr, &cookie, &rbm); + ath12k_hal_rx_buf_addr_info_get(&ab->hal, &desc, &paddr, &cookie, &rbm); buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 19bae6a1b9339..2addfe46cea3e 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -562,7 +562,7 @@ static int ath12k_dp_srng_common_setup(struct ath12k_base *ab) } srng = &ab->hal.srng_list[dp->reo_cmd_ring.ring_id]; - ath12k_wifi7_hal_reo_init_cmd_ring(ab, srng); + ath12k_hal_reo_init_cmd_ring(ab, srng); ret = ath12k_dp_srng_setup(ab, &dp->reo_status_ring, HAL_REO_STATUS, 0, 0, DP_REO_STATUS_RING_SIZE); @@ -586,7 +586,7 @@ static int ath12k_dp_srng_common_setup(struct ath12k_base *ab) HAL_HASH_ROUTING_RING_SW3 << 24 | HAL_HASH_ROUTING_RING_SW4 << 28; - ath12k_wifi7_hal_reo_hw_setup(ab, ring_hash_map); + ath12k_hal_reo_hw_setup(ab, ring_hash_map); return 0; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index e05dff11357c9..f1123871ae2e8 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -145,7 +145,8 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, num_remain--; - ath12k_wifi7_hal_rx_buf_addr_info_set(desc, paddr, cookie, mgr); + ath12k_hal_rx_buf_addr_info_set(&ab->hal, desc, paddr, cookie, + mgr); } goto out; diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index b3010eea9afca..00cd6dcb5bada 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -96,6 +96,31 @@ void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, end_offset); } +void ath12k_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) +{ + ab->hal.hal_ops->reo_hw_setup(ab, ring_hash_map); +} + +void ath12k_hal_reo_init_cmd_ring(struct ath12k_base *ab, struct hal_srng *srng) +{ + ab->hal.hal_ops->reo_init_cmd_ring(ab, srng); +} + +void ath12k_hal_rx_buf_addr_info_set(struct ath12k_hal *hal, + struct ath12k_buffer_addr *binfo, + dma_addr_t paddr, u32 cookie, u8 manager) +{ + hal->hal_ops->rx_buf_addr_info_set(binfo, paddr, cookie, manager); +} + +void ath12k_hal_rx_buf_addr_info_get(struct ath12k_hal *hal, + struct ath12k_buffer_addr *binfo, + dma_addr_t *paddr, u32 *msdu_cookies, + u8 *rbm) +{ + hal->hal_ops->rx_buf_addr_info_get(binfo, paddr, msdu_cookies, rbm); +} + static int ath12k_hal_alloc_cont_rdp(struct ath12k_hal *hal) { size_t size; diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index fb9aaee5c2539..e0860b6675bd8 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1730,15 +1730,17 @@ struct hal_ops { struct hal_wbm_idle_scatter_list *sbuf, u32 nsbufs, u32 tot_link_desc, u32 end_offset); + void (*reo_init_cmd_ring)(struct ath12k_base *ab, + struct hal_srng *srng); + void (*reo_hw_setup)(struct ath12k_base *ab, u32 ring_hash_map); + void (*rx_buf_addr_info_set)(struct ath12k_buffer_addr *binfo, + dma_addr_t paddr, u32 cookie, u8 manager); + void (*rx_buf_addr_info_get)(struct ath12k_buffer_addr *binfo, + dma_addr_t *paddr, u32 *msdu_cookies, + u8 *rbm); }; u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); -void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, - int tid, u32 ba_window_size, - u32 start_seq, enum hal_pn_type type); -void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, - struct hal_srng *srng); -void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab, struct hal_srng *srng); dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab, @@ -1807,4 +1809,13 @@ void ath12k_hal_reoq_lut_set_max_peerid(struct ath12k_base *ab); void ath12k_hal_write_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr); void ath12k_hal_write_ml_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr); +void ath12k_hal_reo_init_cmd_ring(struct ath12k_base *ab, struct hal_srng *srng); +void ath12k_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); +void ath12k_hal_rx_buf_addr_info_set(struct ath12k_hal *hal, + struct ath12k_buffer_addr *binfo, + dma_addr_t paddr, u32 cookie, u8 manager); +void ath12k_hal_rx_buf_addr_info_get(struct ath12k_hal *hal, + struct ath12k_buffer_addr *binfo, + dma_addr_t *paddr, u32 *msdu_cookies, + u8 *rbm); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 9cbae6d11dd84..fb723e971f5df 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1020,5 +1020,9 @@ const struct hal_ops hal_qcn9274_ops = { .write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr, .write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr, .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list, + .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring, + .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup, + .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set, + .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, }; EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index 458282343ff30..a029ea3fe93c6 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -870,5 +870,11 @@ void ath12k_hal_rx_msdu_list_get(struct ath12k *ar, struct hal_rx_msdu_link *link_desc, struct hal_rx_msdu_list *msdu_list, u16 *num_msdus); +void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, + struct hal_srng *srng); +void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); +void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, + int tid, u32 ba_window_size, + u32 start_seq, enum hal_pn_type type); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 2e645f8f4a144..33f8ddcedd836 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -835,5 +835,9 @@ const struct hal_ops hal_wcn7850_ops = { .write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr, .write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr, .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list, + .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring, + .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup, + .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set, + .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, }; EXPORT_SYMBOL(hal_wcn7850_ops); From cf00a106419cb379b2b07827a02cad6f4afc1a5e Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:41 +0530 Subject: [PATCH 063/140] wifi: ath12k: Move HAL Cookie Conversion and RBM related APIs to wifi7 directory Move the hardware specific HAL APIs to hal.c file inside wifi7 directory. These APIs will be called through the hal_ops mechanism, which are registered separately by qcn and wcn Handling following APIs: ath12k_wifi7_hal_cc_config ath12k_wifi7_hal_get_idle_link_rbm Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-15-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.c | 2 +- drivers/net/wireless/ath/ath12k/dp.c | 75 +------------------ drivers/net/wireless/ath/ath12k/dp.h | 1 - drivers/net/wireless/ath/ath12k/hal.c | 11 +++ drivers/net/wireless/ath/ath12k/hal.h | 6 ++ drivers/net/wireless/ath/ath12k/wifi7/hal.c | 73 ++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/hal.h | 3 + .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 2 + .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 2 + 9 files changed, 100 insertions(+), 75 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 04983074e9467..4bc56d5ac64fa 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -922,7 +922,7 @@ static int ath12k_core_start(struct ath12k_base *ab) goto err_hif_stop; } - ath12k_dp_cc_config(ab); + ath12k_hal_cc_config(ab); ret = ath12k_dp_rx_pdev_reo_setup(ab); if (ret) { diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 2addfe46cea3e..f6ccd5a4493dc 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1192,60 +1192,6 @@ static void ath12k_dp_cleanup(struct ath12k_base *ab) /* Deinit any SOC level resource */ } -void ath12k_dp_cc_config(struct ath12k_base *ab) -{ - u32 cmem_base = ab->qmi.dev_mem[ATH12K_QMI_DEVMEM_CMEM_INDEX].start; - u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; - u32 wbm_base = HAL_SEQ_WCSS_UMAC_WBM_REG; - u32 val = 0; - struct ath12k_hal *hal = &ab->hal; - - if (ath12k_ftm_mode) - return; - - ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG0(hal), cmem_base); - - val |= u32_encode_bits(ATH12K_CMEM_ADDR_MSB, - HAL_REO1_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB) | - u32_encode_bits(ATH12K_CC_PPT_MSB, - HAL_REO1_SW_COOKIE_CFG_COOKIE_PPT_MSB) | - u32_encode_bits(ATH12K_CC_SPT_MSB, - HAL_REO1_SW_COOKIE_CFG_COOKIE_SPT_MSB) | - u32_encode_bits(1, HAL_REO1_SW_COOKIE_CFG_ALIGN) | - u32_encode_bits(1, HAL_REO1_SW_COOKIE_CFG_ENABLE) | - u32_encode_bits(1, HAL_REO1_SW_COOKIE_CFG_GLOBAL_ENABLE); - - ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG1(hal), val); - - /* Enable HW CC for WBM */ - ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CFG0, cmem_base); - - val = u32_encode_bits(ATH12K_CMEM_ADDR_MSB, - HAL_WBM_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB) | - u32_encode_bits(ATH12K_CC_PPT_MSB, - HAL_WBM_SW_COOKIE_CFG_COOKIE_PPT_MSB) | - u32_encode_bits(ATH12K_CC_SPT_MSB, - HAL_WBM_SW_COOKIE_CFG_COOKIE_SPT_MSB) | - u32_encode_bits(1, HAL_WBM_SW_COOKIE_CFG_ALIGN); - - ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CFG1, val); - - /* Enable conversion complete indication */ - val = ath12k_hif_read32(ab, wbm_base + HAL_WBM_SW_COOKIE_CFG2); - val |= u32_encode_bits(1, HAL_WBM_SW_COOKIE_CFG_RELEASE_PATH_EN) | - u32_encode_bits(1, HAL_WBM_SW_COOKIE_CFG_ERR_PATH_EN) | - u32_encode_bits(1, HAL_WBM_SW_COOKIE_CFG_CONV_IND_EN); - - ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CFG2, val); - - /* Enable Cookie conversion for WBM2SW Rings */ - val = ath12k_hif_read32(ab, wbm_base + HAL_WBM_SW_COOKIE_CONVERT_CFG); - val |= u32_encode_bits(1, HAL_WBM_SW_COOKIE_CONV_CFG_GLOBAL_EN) | - hal->hal_params->wbm2sw_cc_enable; - - ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CONVERT_CFG, val); -} - static u32 ath12k_dp_cc_cookie_gen(u16 ppt_idx, u16 spt_idx) { return (u32)ppt_idx << ATH12K_CC_PPT_SHIFT | spt_idx; @@ -1570,24 +1516,6 @@ static int ath12k_dp_reoq_lut_setup(struct ath12k_base *ab) return 0; } -static enum hal_rx_buf_return_buf_manager -ath12k_dp_get_idle_link_rbm(struct ath12k_base *ab) -{ - switch (ab->device_id) { - case 0: - return HAL_RX_BUF_RBM_WBM_DEV0_IDLE_DESC_LIST; - case 1: - return HAL_RX_BUF_RBM_WBM_DEV1_IDLE_DESC_LIST; - case 2: - return HAL_RX_BUF_RBM_WBM_DEV2_IDLE_DESC_LIST; - default: - ath12k_warn(ab, "invalid %d device id, so choose default rbm\n", - ab->device_id); - WARN_ON(1); - return HAL_RX_BUF_RBM_WBM_DEV0_IDLE_DESC_LIST; - } -} - static int ath12k_dp_setup(struct ath12k_base *ab) { struct ath12k_dp *dp; @@ -1607,7 +1535,8 @@ static int ath12k_dp_setup(struct ath12k_base *ab) spin_lock_init(&dp->reo_rxq_flush_lock); dp->reo_cmd_cache_flush_count = 0; - dp->idle_link_rbm = ath12k_dp_get_idle_link_rbm(ab); + dp->idle_link_rbm = + ath12k_hal_get_idle_link_rbm(&ab->hal, ab->device_id); ret = ath12k_wbm_idle_ring_setup(ab, &n_link_desc); if (ret) { diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index d0efe5b2de6ce..967fcd8ab9927 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -509,7 +509,6 @@ ath12k_dp_to_pdev_dp(struct ath12k_dp *dp, u8 pdev_idx) } void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif); -void ath12k_dp_cc_config(struct ath12k_base *ab); void ath12k_dp_partner_cc_init(struct ath12k_base *ab); int ath12k_dp_pdev_alloc(struct ath12k_base *ab); void ath12k_dp_pdev_pre_alloc(struct ath12k *ar); diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 00cd6dcb5bada..528138a1dc181 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -121,6 +121,17 @@ void ath12k_hal_rx_buf_addr_info_get(struct ath12k_hal *hal, hal->hal_ops->rx_buf_addr_info_get(binfo, paddr, msdu_cookies, rbm); } +void ath12k_hal_cc_config(struct ath12k_base *ab) +{ + ab->hal.hal_ops->cc_config(ab); +} + +enum hal_rx_buf_return_buf_manager +ath12k_hal_get_idle_link_rbm(struct ath12k_hal *hal, u8 device_id) +{ + return hal->hal_ops->get_idle_link_rbm(hal, device_id); +} + static int ath12k_hal_alloc_cont_rdp(struct ath12k_hal *hal) { size_t size; diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index e0860b6675bd8..83834eff6cf45 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1738,6 +1738,9 @@ struct hal_ops { void (*rx_buf_addr_info_get)(struct ath12k_buffer_addr *binfo, dma_addr_t *paddr, u32 *msdu_cookies, u8 *rbm); + void (*cc_config)(struct ath12k_base *ab); + enum hal_rx_buf_return_buf_manager + (*get_idle_link_rbm)(struct ath12k_hal *hal, u8 device_id); }; u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); @@ -1818,4 +1821,7 @@ void ath12k_hal_rx_buf_addr_info_get(struct ath12k_hal *hal, struct ath12k_buffer_addr *binfo, dma_addr_t *paddr, u32 *msdu_cookies, u8 *rbm); +void ath12k_hal_cc_config(struct ath12k_base *ab); +enum hal_rx_buf_return_buf_manager +ath12k_hal_get_idle_link_rbm(struct ath12k_hal *hal, u8 device_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 73d86dedadb1d..4f9f1efbbfcf2 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -630,3 +630,76 @@ void ath12k_wifi7_hal_write_ml_reoq_lut_addr(struct ath12k_base *ab, ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE1(&ab->hal), paddr); } + +void ath12k_wifi7_hal_cc_config(struct ath12k_base *ab) +{ + u32 cmem_base = ab->qmi.dev_mem[ATH12K_QMI_DEVMEM_CMEM_INDEX].start; + u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; + u32 wbm_base = HAL_SEQ_WCSS_UMAC_WBM_REG; + u32 val = 0; + struct ath12k_hal *hal = &ab->hal; + + if (ath12k_ftm_mode) + return; + + ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG0(hal), cmem_base); + + val |= u32_encode_bits(ATH12K_CMEM_ADDR_MSB, + HAL_REO1_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB) | + u32_encode_bits(ATH12K_CC_PPT_MSB, + HAL_REO1_SW_COOKIE_CFG_COOKIE_PPT_MSB) | + u32_encode_bits(ATH12K_CC_SPT_MSB, + HAL_REO1_SW_COOKIE_CFG_COOKIE_SPT_MSB) | + u32_encode_bits(1, HAL_REO1_SW_COOKIE_CFG_ALIGN) | + u32_encode_bits(1, HAL_REO1_SW_COOKIE_CFG_ENABLE) | + u32_encode_bits(1, HAL_REO1_SW_COOKIE_CFG_GLOBAL_ENABLE); + + ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG1(hal), val); + + /* Enable HW CC for WBM */ + ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CFG0, cmem_base); + + val = u32_encode_bits(ATH12K_CMEM_ADDR_MSB, + HAL_WBM_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB) | + u32_encode_bits(ATH12K_CC_PPT_MSB, + HAL_WBM_SW_COOKIE_CFG_COOKIE_PPT_MSB) | + u32_encode_bits(ATH12K_CC_SPT_MSB, + HAL_WBM_SW_COOKIE_CFG_COOKIE_SPT_MSB) | + u32_encode_bits(1, HAL_WBM_SW_COOKIE_CFG_ALIGN); + + ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CFG1, val); + + /* Enable conversion complete indication */ + val = ath12k_hif_read32(ab, wbm_base + HAL_WBM_SW_COOKIE_CFG2); + val |= u32_encode_bits(1, HAL_WBM_SW_COOKIE_CFG_RELEASE_PATH_EN) | + u32_encode_bits(1, HAL_WBM_SW_COOKIE_CFG_ERR_PATH_EN) | + u32_encode_bits(1, HAL_WBM_SW_COOKIE_CFG_CONV_IND_EN); + + ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CFG2, val); + + /* Enable Cookie conversion for WBM2SW Rings */ + val = ath12k_hif_read32(ab, wbm_base + HAL_WBM_SW_COOKIE_CONVERT_CFG); + val |= u32_encode_bits(1, HAL_WBM_SW_COOKIE_CONV_CFG_GLOBAL_EN) | + hal->hal_params->wbm2sw_cc_enable; + + ath12k_hif_write32(ab, wbm_base + HAL_WBM_SW_COOKIE_CONVERT_CFG, val); +} + +enum hal_rx_buf_return_buf_manager +ath12k_wifi7_hal_get_idle_link_rbm(struct ath12k_hal *hal, u8 device_id) +{ + switch (device_id) { + case 0: + return HAL_RX_BUF_RBM_WBM_DEV0_IDLE_DESC_LIST; + case 1: + return HAL_RX_BUF_RBM_WBM_DEV1_IDLE_DESC_LIST; + case 2: + return HAL_RX_BUF_RBM_WBM_DEV2_IDLE_DESC_LIST; + default: + ath12k_warn(hal, + "invalid %d device id, so choose default rbm\n", + device_id); + WARN_ON(1); + return HAL_RX_BUF_RBM_WBM_DEV0_IDLE_DESC_LIST; + } +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index 6e67f06ffa438..b600b2e3cb78d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -23,6 +23,9 @@ int ath12k_wifi7_hal_srng_get_ring_id(struct ath12k_hal *hal, enum hal_ring_type type, int ring_num, int mac_id); u32 ath12k_wifi7_hal_ce_get_desc_size(enum hal_ce_desc type); +void ath12k_wifi7_hal_cc_config(struct ath12k_base *ab); +enum hal_rx_buf_return_buf_manager +ath12k_wifi7_hal_get_idle_link_rbm(struct ath12k_hal *hal, u8 device_id); void ath12k_wifi7_hal_ce_src_set_desc(struct hal_ce_srng_src_desc *desc, dma_addr_t paddr, u32 len, u32 id, u8 byte_swap_data); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index fb723e971f5df..2dc4f1539d684 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1024,5 +1024,7 @@ const struct hal_ops hal_qcn9274_ops = { .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup, .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set, .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, + .cc_config = ath12k_wifi7_hal_cc_config, + .get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm, }; EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 33f8ddcedd836..233350ccd06e4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -839,5 +839,7 @@ const struct hal_ops hal_wcn7850_ops = { .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup, .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set, .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, + .cc_config = ath12k_wifi7_hal_cc_config, + .get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm, }; EXPORT_SYMBOL(hal_wcn7850_ops); From 543e886f4c04fd0d87e626579f06333b9ccfa695 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:42 +0530 Subject: [PATCH 064/140] wifi: ath12k: Segregate the common and wifi7 specific structures Segregate the common and wifi7 specific structures in hal, and move them to corresponding header files. hal.h file in common directory is used by both common and wifi7 directory files, while hal.h and other hal headers are used only by files within the wifi7 directory since these headers contain hw specific hal data. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-16-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/cmn_defs.h | 1 + drivers/net/wireless/ath/ath12k/core.h | 2 +- drivers/net/wireless/ath/ath12k/dbring.c | 1 + drivers/net/wireless/ath/ath12k/debugfs.c | 2 +- drivers/net/wireless/ath/ath12k/dp.c | 54 +- drivers/net/wireless/ath/ath12k/dp.h | 14 +- drivers/net/wireless/ath/ath12k/dp_mon.h | 1 + drivers/net/wireless/ath/ath12k/dp_rx.c | 2 - drivers/net/wireless/ath/ath12k/dp_rx.h | 1 - drivers/net/wireless/ath/ath12k/dp_tx.h | 1 - drivers/net/wireless/ath/ath12k/hal.c | 5 - drivers/net/wireless/ath/ath12k/hal.h | 610 +++--------------- drivers/net/wireless/ath/ath12k/pci.c | 2 +- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 1 + drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 3 + drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 52 ++ drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h | 2 + drivers/net/wireless/ath/ath12k/wifi7/hal.c | 2 +- drivers/net/wireless/ath/ath12k/wifi7/hal.h | 512 +++++++++++++++ .../net/wireless/ath/ath12k/wifi7/hal_desc.h | 80 --- .../wireless/ath/ath12k/wifi7/hal_qcn9274.h | 1 + .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 1 + .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 4 + .../net/wireless/ath/ath12k/wifi7/hal_tx.c | 2 +- .../net/wireless/ath/ath12k/wifi7/hal_tx.h | 2 +- .../wireless/ath/ath12k/wifi7/hal_wcn7850.h | 1 + drivers/net/wireless/ath/ath12k/wifi7/pci.c | 1 + 27 files changed, 695 insertions(+), 665 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/cmn_defs.h b/drivers/net/wireless/ath/ath12k/cmn_defs.h index 1a531357271bc..20208ffea1c9a 100644 --- a/drivers/net/wireless/ath/ath12k/cmn_defs.h +++ b/drivers/net/wireless/ath/ath12k/cmn_defs.h @@ -16,4 +16,5 @@ /* Define 1 scan link for each radio for parallel scan purposes */ #define ATH12K_NUM_MAX_LINKS (IEEE80211_MLD_MAX_NUM_LINKS + ATH12K_SCAN_MAX_LINKS) +#define MAX_MU_GROUP_ID 64 #endif diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 49637b56b8f9e..1548116b0228f 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -26,7 +26,7 @@ #include "ce.h" #include "mac.h" #include "hw.h" -#include "wifi7/hal_rx.h" +#include "wifi7/hal_desc.h" #include "reg.h" #include "dbring.h" #include "fw.h" diff --git a/drivers/net/wireless/ath/ath12k/dbring.c b/drivers/net/wireless/ath/ath12k/dbring.c index a387cb9554d24..f71ec2a58469f 100644 --- a/drivers/net/wireless/ath/ath12k/dbring.c +++ b/drivers/net/wireless/ath/ath12k/dbring.c @@ -6,6 +6,7 @@ #include "core.h" #include "debug.h" +#include "hal.h" static int ath12k_dbring_bufs_replenish(struct ath12k *ar, struct ath12k_dbring *ring, diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c index f25af9adeac82..19c4fabecff8e 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs.c +++ b/drivers/net/wireless/ath/ath12k/debugfs.c @@ -967,7 +967,7 @@ static int ath12k_open_link_stats(struct inode *inode, struct file *file) "\nlink[%d] Tx Frame descriptor Encrypt Type = ", link_id); - for (i = 0; i < HAL_ENCRYPT_TYPE_MAX; i++) { + for (i = 0; i < DP_ENCRYPT_TYPE_MAX; i++) { len += scnprintf(buf + len, buf_len - len, " %d:%d", i, linkstat.tx_encrypt_type[i]); diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index f6ccd5a4493dc..a3f97ef96686d 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -7,8 +7,8 @@ #include #include "core.h" #include "dp_tx.h" -#include "wifi7/hal_tx.h" #include "hif.h" +#include "hal.h" #include "debug.h" #include "wifi7/dp_rx.h" #include "peer.h" @@ -333,56 +333,6 @@ int ath12k_dp_srng_setup(struct ath12k_base *ab, struct dp_srng *ring, return 0; } -static -u32 ath12k_dp_tx_get_vdev_bank_config(struct ath12k_base *ab, - struct ath12k_link_vif *arvif) -{ - u32 bank_config = 0; - u8 link_id = arvif->link_id; - struct ath12k_vif *ahvif = arvif->ahvif; - struct ath12k_dp_vif *dp_vif = &ahvif->dp_vif; - struct ath12k_dp_link_vif *dp_link_vif; - - dp_link_vif = ath12k_dp_vif_to_dp_link_vif(dp_vif, link_id); - - /* Only valid for raw frames with HW crypto enabled. - * With SW crypto, mac80211 sets key per packet - */ - if (dp_vif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW && - test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags)) - bank_config |= - u32_encode_bits(ath12k_dp_tx_get_encrypt_type(dp_vif->key_cipher), - HAL_TX_BANK_CONFIG_ENCRYPT_TYPE); - - bank_config |= u32_encode_bits(dp_vif->tx_encap_type, - HAL_TX_BANK_CONFIG_ENCAP_TYPE); - bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_SRC_BUFFER_SWAP) | - u32_encode_bits(0, HAL_TX_BANK_CONFIG_LINK_META_SWAP) | - u32_encode_bits(0, HAL_TX_BANK_CONFIG_EPD); - - /* only valid if idx_lookup_override is not set in tcl_data_cmd */ - if (ahvif->vdev_type == WMI_VDEV_TYPE_STA) - bank_config |= u32_encode_bits(1, HAL_TX_BANK_CONFIG_INDEX_LOOKUP_EN); - else - bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_INDEX_LOOKUP_EN); - - bank_config |= u32_encode_bits(dp_link_vif->hal_addr_search_flags & - HAL_TX_ADDRX_EN, - HAL_TX_BANK_CONFIG_ADDRX_EN) | - u32_encode_bits(!!(dp_link_vif->hal_addr_search_flags & - HAL_TX_ADDRY_EN), - HAL_TX_BANK_CONFIG_ADDRY_EN); - - bank_config |= u32_encode_bits(ieee80211_vif_is_mesh(ahvif->vif) ? 3 : 0, - HAL_TX_BANK_CONFIG_MESH_EN) | - u32_encode_bits(dp_link_vif->vdev_id_check_en, - HAL_TX_BANK_CONFIG_VDEV_ID_CHECK_EN); - - bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_DSCP_TIP_MAP_ID); - - return bank_config; -} - static int ath12k_dp_tx_get_bank_profile(struct ath12k_base *ab, struct ath12k_link_vif *arvif, struct ath12k_dp *dp) @@ -393,7 +343,7 @@ static int ath12k_dp_tx_get_bank_profile(struct ath12k_base *ab, bool configure_register = false; /* convert vdev params into hal_tx_bank_config */ - bank_config = ath12k_dp_tx_get_vdev_bank_config(ab, arvif); + bank_config = dp->ops->dp_tx_get_vdev_bank_config(ab, arvif); spin_lock_bh(&dp->tx_bank_lock); /* TODO: implement using idr kernel framework*/ diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 967fcd8ab9927..4318ec13cb8f1 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -7,8 +7,6 @@ #ifndef ATH12K_DP_H #define ATH12K_DP_H -#include "wifi7/hal_desc.h" -#include "wifi7/hal_rx.h" #include "hw.h" #include "dp_htt.h" #include "dp_cmn.h" @@ -26,6 +24,10 @@ struct ath12k_ext_irq_grp; #define DP_MON_PURGE_TIMEOUT_MS 100 #define DP_MON_SERVICE_BUDGET 128 +#define DP_ENCAP_TYPE_MAX 4 +#define DP_ENCRYPT_TYPE_MAX 12 +#define DP_DESC_TYPE_MAX 2 + struct dp_srng { u32 *vaddr_unaligned; u32 *vaddr; @@ -373,9 +375,9 @@ struct ath12k_link_stats { u32 tx_completed; u32 tx_bcast_mcast; u32 tx_dropped; - u32 tx_encap_type[HAL_TCL_ENCAP_TYPE_MAX]; - u32 tx_encrypt_type[HAL_ENCRYPT_TYPE_MAX]; - u32 tx_desc_type[HAL_TCL_DESC_TYPE_MAX]; + u32 tx_encap_type[DP_ENCAP_TYPE_MAX]; + u32 tx_encrypt_type[DP_ENCRYPT_TYPE_MAX]; + u32 tx_desc_type[DP_DESC_TYPE_MAX]; }; /* DP arch ops to communicate from common module @@ -385,6 +387,8 @@ struct ath12k_dp_arch_ops { int (*service_srng)(struct ath12k_dp *dp, struct ath12k_ext_irq_grp *irq_grp, int budget); + u32 (*dp_tx_get_vdev_bank_config)(struct ath12k_base *ab, + struct ath12k_link_vif *arvif); }; struct ath12k_dp { diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 068df74003456..6110227a40dd3 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -8,6 +8,7 @@ #define ATH12K_DP_MON_H #include "core.h" +#include "wifi7/hal_desc.h" #define ATH12K_MON_RX_DOT11_OFFSET 5 #define ATH12K_MON_RX_PKT_OFFSET 8 diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index f1123871ae2e8..3a762d00acb50 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -10,11 +10,9 @@ #include #include "core.h" #include "debug.h" -#include "wifi7/hal_desc.h" #include "hw.h" #include "dp_rx.h" #include "wifi7/dp_rx.h" -#include "wifi7/hal_rx.h" #include "dp_tx.h" #include "peer.h" #include "dp_mon.h" diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 09042d41976bf..9b0ed9142a8be 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -8,7 +8,6 @@ #include #include "core.h" -#include "wifi7/hal_rx_desc.h" #include "debug.h" #define DP_MAX_NWIFI_HDR_LEN 30 diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.h b/drivers/net/wireless/ath/ath12k/dp_tx.h index 5b8fe280c32ae..147409f9ac408 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/dp_tx.h @@ -8,7 +8,6 @@ #define ATH12K_DP_TX_H #include "core.h" -#include "wifi7/hal_tx.h" struct ath12k_dp_htt_wbm_tx_status { bool acked; diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 528138a1dc181..296bd7824ae2d 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -4,13 +4,8 @@ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include -#include "wifi7/hal_tx.h" -#include "wifi7/hal_rx.h" #include "debug.h" -#include "wifi7/hal_desc.h" #include "hif.h" -#include "wifi7/hal_qcn9274.h" -#include "wifi7/hal_wcn7850.h" static void ath12k_hal_ce_dst_setup(struct ath12k_base *ab, struct hal_srng *srng, int ring_num) diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 83834eff6cf45..63ad67318b0e5 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -7,8 +7,7 @@ #ifndef ATH12K_HAL_H #define ATH12K_HAL_H -#include "wifi7/hal_desc.h" -#include "wifi7/hal_rx_desc.h" +#include "hw.h" struct ath12k_base; @@ -26,6 +25,10 @@ struct ath12k_base; #define HAL_RX_MAX_MPDU 256 #define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP (HAL_RX_MAX_MPDU >> 5) +/* TODO: 16 entries per radio times MAX_VAPS_SUPPORTED */ +#define HAL_DSCP_TID_MAP_TBL_NUM_ENTRIES_MAX 32 +#define HAL_DSCP_TID_TBL_SIZE 24 + #define EHT_MAX_USER_INFO 4 #define HAL_RX_MON_MAX_AGGR_SIZE 128 #define HAL_MAX_UL_MU_USERS 37 @@ -48,366 +51,19 @@ struct ath12k_base; #define HAL_RING_BASE_ALIGN 8 #define HAL_REO_QLUT_ADDR_ALIGN 256 +#define HAL_ADDR_LSB_REG_MASK 0xffffffff +#define HAL_ADDR_MSB_REG_SHIFT 32 + +#define HAL_WBM2SW_REL_ERR_RING_NUM 3 + +#define HAL_SHADOW_NUM_REGS_MAX 40 + #define HAL_WBM_IDLE_SCATTER_BUF_SIZE_MAX 32704 /* TODO: Check with hw team on the supported scatter buf size */ #define HAL_WBM_IDLE_SCATTER_NEXT_PTR_SIZE 8 #define HAL_WBM_IDLE_SCATTER_BUF_SIZE (HAL_WBM_IDLE_SCATTER_BUF_SIZE_MAX - \ HAL_WBM_IDLE_SCATTER_NEXT_PTR_SIZE) -/* TODO: 16 entries per radio times MAX_VAPS_SUPPORTED */ -#define HAL_DSCP_TID_MAP_TBL_NUM_ENTRIES_MAX 32 -#define HAL_DSCP_TID_TBL_SIZE 24 - -/* calculate the register address from bar0 of shadow register x */ -#define HAL_SHADOW_BASE_ADDR 0x000008fc -#define HAL_SHADOW_NUM_REGS 40 -#define HAL_HP_OFFSET_IN_REG_START 1 -#define HAL_OFFSET_FROM_HP_TO_TP 4 - -#define HAL_SHADOW_REG(x) (HAL_SHADOW_BASE_ADDR + (4 * (x))) -#define HAL_REO_QDESC_MAX_PEERID 8191 - -/* WCSS Relative address */ -#define HAL_SEQ_WCSS_CMEM_OFFSET 0x00100000 -#define HAL_SEQ_WCSS_UMAC_OFFSET 0x00a00000 -#define HAL_SEQ_WCSS_UMAC_REO_REG 0x00a38000 -#define HAL_SEQ_WCSS_UMAC_TCL_REG 0x00a44000 -#define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal) \ - ((hal)->regs->hal_umac_ce0_src_reg_base) -#define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) \ - ((hal)->regs->hal_umac_ce0_dest_reg_base) -#define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(hal) \ - ((hal)->regs->hal_umac_ce1_src_reg_base) -#define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) \ - ((hal)->regs->hal_umac_ce1_dest_reg_base) -#define HAL_SEQ_WCSS_UMAC_WBM_REG 0x00a34000 - -#define HAL_CE_WFSS_CE_REG_BASE 0x01b80000 - -#define HAL_TCL_SW_CONFIG_BANK_ADDR 0x00a4408c - -/* SW2TCL(x) R0 ring configuration address */ -#define HAL_TCL1_RING_CMN_CTRL_REG 0x00000020 -#define HAL_TCL1_RING_DSCP_TID_MAP 0x00000240 - -#define HAL_TCL1_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl1_ring_base_lsb) -#define HAL_TCL1_RING_BASE_MSB(hal) \ - ((hal)->regs->hal_tcl1_ring_base_msb) -#define HAL_TCL1_RING_ID(hal) ((hal)->regs->hal_tcl1_ring_id) -#define HAL_TCL1_RING_MISC(hal) \ - ((hal)->regs->hal_tcl1_ring_misc) -#define HAL_TCL1_RING_TP_ADDR_LSB(hal) \ - ((hal)->regs->hal_tcl1_ring_tp_addr_lsb) -#define HAL_TCL1_RING_TP_ADDR_MSB(hal) \ - ((hal)->regs->hal_tcl1_ring_tp_addr_msb) -#define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(hal) \ - ((hal)->regs->hal_tcl1_ring_consumer_int_setup_ix0) -#define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(hal) \ - ((hal)->regs->hal_tcl1_ring_consumer_int_setup_ix1) -#define HAL_TCL1_RING_MSI1_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl1_ring_msi1_base_lsb) -#define HAL_TCL1_RING_MSI1_BASE_MSB(hal) \ - ((hal)->regs->hal_tcl1_ring_msi1_base_msb) -#define HAL_TCL1_RING_MSI1_DATA(hal) \ - ((hal)->regs->hal_tcl1_ring_msi1_data) -#define HAL_TCL2_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl2_ring_base_lsb) -#define HAL_TCL_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl_ring_base_lsb) - -#define HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_MSI1_BASE_LSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) -#define HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_MSI1_BASE_MSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) -#define HAL_TCL1_RING_MSI1_DATA_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_MSI1_DATA(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) -#define HAL_TCL1_RING_BASE_MSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_BASE_MSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) -#define HAL_TCL1_RING_ID_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_ID(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) -#define HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) -#define HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) -#define HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_TP_ADDR_LSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) -#define HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_TP_ADDR_MSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) -#define HAL_TCL1_RING_MISC_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ - (HAL_TCL1_RING_MISC(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) - -/* SW2TCL(x) R2 ring pointers (head/tail) address */ -#define HAL_TCL1_RING_HP 0x00002000 -#define HAL_TCL1_RING_TP 0x00002004 -#define HAL_TCL2_RING_HP 0x00002008 -#define HAL_TCL_RING_HP 0x00002028 - -#define HAL_TCL1_RING_TP_OFFSET \ - (HAL_TCL1_RING_TP - HAL_TCL1_RING_HP) - -/* TCL STATUS ring address */ -#define HAL_TCL_STATUS_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl_status_ring_base_lsb) -#define HAL_TCL_STATUS_RING_HP 0x00002048 - -/* PPE2TCL1 Ring address */ -#define HAL_TCL_PPE2TCL1_RING_BASE_LSB 0x00000c48 -#define HAL_TCL_PPE2TCL1_RING_HP 0x00002038 - -/* WBM PPE Release Ring address */ -#define HAL_WBM_PPE_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_ppe_rel_ring_base) -#define HAL_WBM_PPE_RELEASE_RING_HP 0x00003020 - -/* REO2SW(x) R0 ring configuration address */ -#define HAL_REO1_GEN_ENABLE 0x00000000 -#define HAL_REO1_MISC_CTRL_ADDR(hal) \ - ((hal)->regs->hal_reo1_misc_ctrl_addr) -#define HAL_REO1_DEST_RING_CTRL_IX_0 0x00000004 -#define HAL_REO1_DEST_RING_CTRL_IX_1 0x00000008 -#define HAL_REO1_DEST_RING_CTRL_IX_2 0x0000000c -#define HAL_REO1_DEST_RING_CTRL_IX_3 0x00000010 -#define HAL_REO1_QDESC_ADDR(hal) ((hal)->regs->hal_reo1_qdesc_addr) -#define HAL_REO1_QDESC_MAX_PEERID(hal) ((hal)->regs->hal_reo1_qdesc_max_peerid) -#define HAL_REO1_SW_COOKIE_CFG0(hal) ((hal)->regs->hal_reo1_sw_cookie_cfg0) -#define HAL_REO1_SW_COOKIE_CFG1(hal) ((hal)->regs->hal_reo1_sw_cookie_cfg1) -#define HAL_REO1_QDESC_LUT_BASE0(hal) ((hal)->regs->hal_reo1_qdesc_lut_base0) -#define HAL_REO1_QDESC_LUT_BASE1(hal) ((hal)->regs->hal_reo1_qdesc_lut_base1) -#define HAL_REO1_RING_BASE_LSB(hal) ((hal)->regs->hal_reo1_ring_base_lsb) -#define HAL_REO1_RING_BASE_MSB(hal) ((hal)->regs->hal_reo1_ring_base_msb) -#define HAL_REO1_RING_ID(hal) ((hal)->regs->hal_reo1_ring_id) -#define HAL_REO1_RING_MISC(hal) ((hal)->regs->hal_reo1_ring_misc) -#define HAL_REO1_RING_HP_ADDR_LSB(hal) ((hal)->regs->hal_reo1_ring_hp_addr_lsb) -#define HAL_REO1_RING_HP_ADDR_MSB(hal) ((hal)->regs->hal_reo1_ring_hp_addr_msb) -#define HAL_REO1_RING_PRODUCER_INT_SETUP(hal) \ - ((hal)->regs->hal_reo1_ring_producer_int_setup) -#define HAL_REO1_RING_MSI1_BASE_LSB(hal) \ - ((hal)->regs->hal_reo1_ring_msi1_base_lsb) -#define HAL_REO1_RING_MSI1_BASE_MSB(hal) \ - ((hal)->regs->hal_reo1_ring_msi1_base_msb) -#define HAL_REO1_RING_MSI1_DATA(hal) ((hal)->regs->hal_reo1_ring_msi1_data) -#define HAL_REO2_RING_BASE_LSB(hal) ((hal)->regs->hal_reo2_ring_base) -#define HAL_REO1_AGING_THRESH_IX_0(hal) ((hal)->regs->hal_reo1_aging_thres_ix0) -#define HAL_REO1_AGING_THRESH_IX_1(hal) ((hal)->regs->hal_reo1_aging_thres_ix1) -#define HAL_REO1_AGING_THRESH_IX_2(hal) ((hal)->regs->hal_reo1_aging_thres_ix2) -#define HAL_REO1_AGING_THRESH_IX_3(hal) ((hal)->regs->hal_reo1_aging_thres_ix3) - -/* REO2SW(x) R2 ring pointers (head/tail) address */ -#define HAL_REO1_RING_HP 0x00003048 -#define HAL_REO1_RING_TP 0x0000304c -#define HAL_REO2_RING_HP 0x00003050 - -#define HAL_REO1_RING_TP_OFFSET (HAL_REO1_RING_TP - HAL_REO1_RING_HP) - -/* REO2SW0 ring configuration address */ -#define HAL_REO_SW0_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_reo2_sw0_ring_base) - -/* REO2SW0 R2 ring pointer (head/tail) address */ -#define HAL_REO_SW0_RING_HP 0x00003088 - -/* REO CMD R0 address */ -#define HAL_REO_CMD_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_reo_cmd_ring_base) - -/* REO CMD R2 address */ -#define HAL_REO_CMD_HP 0x00003020 - -/* SW2REO R0 address */ -#define HAL_SW2REO_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_sw2reo_ring_base) -#define HAL_SW2REO1_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_sw2reo1_ring_base) - -/* SW2REO R2 address */ -#define HAL_SW2REO_RING_HP 0x00003028 -#define HAL_SW2REO1_RING_HP 0x00003030 - -/* CE ring R0 address */ -#define HAL_CE_SRC_RING_BASE_LSB 0x00000000 -#define HAL_CE_DST_RING_BASE_LSB 0x00000000 -#define HAL_CE_DST_STATUS_RING_BASE_LSB 0x00000058 -#define HAL_CE_DST_RING_CTRL 0x000000b0 - -/* CE ring R2 address */ -#define HAL_CE_DST_RING_HP 0x00000400 -#define HAL_CE_DST_STATUS_RING_HP 0x00000408 - -/* REO status address */ -#define HAL_REO_STATUS_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_reo_status_ring_base) -#define HAL_REO_STATUS_HP 0x000030a8 - -/* WBM Idle R0 address */ -#define HAL_WBM_IDLE_LINK_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm_idle_ring_base_lsb) -#define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(hal) \ - ((hal)->regs->hal_wbm_idle_ring_misc_addr) -#define HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(hal) \ - ((hal)->regs->hal_wbm_r0_idle_list_cntl_addr) -#define HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(hal) \ - ((hal)->regs->hal_wbm_r0_idle_list_size_addr) -#define HAL_WBM_SCATTERED_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm_scattered_ring_base_lsb) -#define HAL_WBM_SCATTERED_RING_BASE_MSB(hal) \ - ((hal)->regs->hal_wbm_scattered_ring_base_msb) -#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_head_info_ix0) -#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_head_info_ix1) -#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_tail_info_ix0) -#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_tail_info_ix1) -#define HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_ptr_hp_addr) - -/* WBM Idle R2 address */ -#define HAL_WBM_IDLE_LINK_RING_HP 0x000030b8 - -/* SW2WBM R0 release address */ -#define HAL_WBM_SW_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm_sw_release_ring_base_lsb) -#define HAL_WBM_SW1_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm_sw1_release_ring_base_lsb) - -/* SW2WBM R2 release address */ -#define HAL_WBM_SW_RELEASE_RING_HP 0x00003010 -#define HAL_WBM_SW1_RELEASE_RING_HP 0x00003018 - -/* WBM2SW R0 release address */ -#define HAL_WBM0_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm0_release_ring_base_lsb) - -#define HAL_WBM1_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm1_release_ring_base_lsb) - -/* WBM2SW R2 release address */ -#define HAL_WBM0_RELEASE_RING_HP 0x000030c8 -#define HAL_WBM1_RELEASE_RING_HP 0x000030d0 - -/* WBM cookie config address and mask */ -#define HAL_WBM_SW_COOKIE_CFG0 0x00000040 -#define HAL_WBM_SW_COOKIE_CFG1 0x00000044 -#define HAL_WBM_SW_COOKIE_CFG2 0x00000090 -#define HAL_WBM_SW_COOKIE_CONVERT_CFG 0x00000094 - -#define HAL_WBM_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB GENMASK(7, 0) -#define HAL_WBM_SW_COOKIE_CFG_COOKIE_PPT_MSB GENMASK(12, 8) -#define HAL_WBM_SW_COOKIE_CFG_COOKIE_SPT_MSB GENMASK(17, 13) -#define HAL_WBM_SW_COOKIE_CFG_ALIGN BIT(18) -#define HAL_WBM_SW_COOKIE_CFG_RELEASE_PATH_EN BIT(0) -#define HAL_WBM_SW_COOKIE_CFG_ERR_PATH_EN BIT(1) -#define HAL_WBM_SW_COOKIE_CFG_CONV_IND_EN BIT(3) - -#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN BIT(1) -#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW1_EN BIT(2) -#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN BIT(3) -#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN BIT(4) -#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN BIT(5) -#define HAL_WBM_SW_COOKIE_CONV_CFG_GLOBAL_EN BIT(8) - -/* TCL ring field mask and offset */ -#define HAL_TCL1_RING_BASE_MSB_RING_SIZE GENMASK(27, 8) -#define HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB GENMASK(7, 0) -#define HAL_TCL1_RING_ID_ENTRY_SIZE GENMASK(7, 0) -#define HAL_TCL1_RING_MISC_MSI_RING_ID_DISABLE BIT(0) -#define HAL_TCL1_RING_MISC_MSI_LOOPCNT_DISABLE BIT(1) -#define HAL_TCL1_RING_MISC_MSI_SWAP BIT(3) -#define HAL_TCL1_RING_MISC_HOST_FW_SWAP BIT(4) -#define HAL_TCL1_RING_MISC_DATA_TLV_SWAP BIT(5) -#define HAL_TCL1_RING_MISC_SRNG_ENABLE BIT(6) -#define HAL_TCL1_RING_CONSR_INT_SETUP_IX0_INTR_TMR_THOLD GENMASK(31, 16) -#define HAL_TCL1_RING_CONSR_INT_SETUP_IX0_BATCH_COUNTER_THOLD GENMASK(14, 0) -#define HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD GENMASK(15, 0) -#define HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE BIT(8) -#define HAL_TCL1_RING_MSI1_BASE_MSB_ADDR GENMASK(7, 0) -#define HAL_TCL1_RING_CMN_CTRL_DSCP_TID_MAP_PROG_EN BIT(23) -#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP GENMASK(31, 0) -#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP0 GENMASK(2, 0) -#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP1 GENMASK(5, 3) -#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP2 GENMASK(8, 6) -#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP3 GENMASK(11, 9) -#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP4 GENMASK(14, 12) -#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP5 GENMASK(17, 15) -#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP6 GENMASK(20, 18) -#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP7 GENMASK(23, 21) - -/* REO ring field mask and offset */ -#define HAL_REO1_RING_BASE_MSB_RING_SIZE GENMASK(27, 8) -#define HAL_REO1_RING_BASE_MSB_RING_BASE_ADDR_MSB GENMASK(7, 0) -#define HAL_REO1_RING_ID_RING_ID GENMASK(15, 8) -#define HAL_REO1_RING_ID_ENTRY_SIZE GENMASK(7, 0) -#define HAL_REO1_RING_MISC_MSI_SWAP BIT(3) -#define HAL_REO1_RING_MISC_HOST_FW_SWAP BIT(4) -#define HAL_REO1_RING_MISC_DATA_TLV_SWAP BIT(5) -#define HAL_REO1_RING_MISC_SRNG_ENABLE BIT(6) -#define HAL_REO1_RING_PRDR_INT_SETUP_INTR_TMR_THOLD GENMASK(31, 16) -#define HAL_REO1_RING_PRDR_INT_SETUP_BATCH_COUNTER_THOLD GENMASK(14, 0) -#define HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE BIT(8) -#define HAL_REO1_RING_MSI1_BASE_MSB_ADDR GENMASK(7, 0) -#define HAL_REO1_MISC_CTL_FRAG_DST_RING GENMASK(20, 17) -#define HAL_REO1_MISC_CTL_BAR_DST_RING GENMASK(24, 21) -#define HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE BIT(2) -#define HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE BIT(3) -#define HAL_REO1_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB GENMASK(7, 0) -#define HAL_REO1_SW_COOKIE_CFG_COOKIE_PPT_MSB GENMASK(12, 8) -#define HAL_REO1_SW_COOKIE_CFG_COOKIE_SPT_MSB GENMASK(17, 13) -#define HAL_REO1_SW_COOKIE_CFG_ALIGN BIT(18) -#define HAL_REO1_SW_COOKIE_CFG_ENABLE BIT(19) -#define HAL_REO1_SW_COOKIE_CFG_GLOBAL_ENABLE BIT(20) -#define HAL_REO_QDESC_ADDR_READ_LUT_ENABLE BIT(7) -#define HAL_REO_QDESC_ADDR_READ_CLEAR_QDESC_ARRAY BIT(6) - -/* CE ring bit field mask and shift */ -#define HAL_CE_DST_R0_DEST_CTRL_MAX_LEN GENMASK(15, 0) - -#define HAL_ADDR_LSB_REG_MASK 0xffffffff - -#define HAL_ADDR_MSB_REG_SHIFT 32 - -/* WBM ring bit field mask and shift */ -#define HAL_WBM_LINK_DESC_IDLE_LIST_MODE BIT(1) -#define HAL_WBM_SCATTER_BUFFER_SIZE GENMASK(10, 2) -#define HAL_WBM_SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST GENMASK(31, 16) -#define HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32 GENMASK(7, 0) -#define HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG GENMASK(31, 8) - -#define HAL_WBM_SCATTERED_DESC_HEAD_P_OFFSET_IX1 GENMASK(20, 8) -#define HAL_WBM_SCATTERED_DESC_TAIL_P_OFFSET_IX1 GENMASK(20, 8) - -#define HAL_WBM_IDLE_LINK_RING_MISC_SRNG_ENABLE BIT(6) -#define HAL_WBM_IDLE_LINK_RING_MISC_RIND_ID_DISABLE BIT(0) - -#define BASE_ADDR_MATCH_TAG_VAL 0x5 - -#define HAL_REO_REO2SW1_RING_BASE_MSB_RING_SIZE 0x000fffff -#define HAL_REO_REO2SW0_RING_BASE_MSB_RING_SIZE 0x000fffff -#define HAL_REO_SW2REO_RING_BASE_MSB_RING_SIZE 0x0000ffff -#define HAL_REO_CMD_RING_BASE_MSB_RING_SIZE 0x0000ffff -#define HAL_REO_STATUS_RING_BASE_MSB_RING_SIZE 0x0000ffff -#define HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE 0x000fffff -#define HAL_SW2TCL1_CMD_RING_BASE_MSB_RING_SIZE 0x000fffff -#define HAL_TCL_STATUS_RING_BASE_MSB_RING_SIZE 0x0000ffff -#define HAL_CE_SRC_RING_BASE_MSB_RING_SIZE 0x0000ffff -#define HAL_CE_DST_RING_BASE_MSB_RING_SIZE 0x0000ffff -#define HAL_CE_DST_STATUS_RING_BASE_MSB_RING_SIZE 0x0000ffff -#define HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE 0x000fffff -#define HAL_SW2WBM_RELEASE_RING_BASE_MSB_RING_SIZE 0x0000ffff -#define HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE 0x000fffff -#define HAL_RXDMA_RING_MAX_SIZE 0x0000ffff -#define HAL_RXDMA_RING_MAX_SIZE_BE 0x000fffff -#define HAL_WBM2PPE_RELEASE_RING_BASE_MSB_RING_SIZE 0x000fffff - -#define HAL_WBM2SW_REL_ERR_RING_NUM 3 -/* Add any other errors here and return them in - * ath12k_hal_rx_desc_get_err(). - */ - -#define HAL_IPQ5332_CE_WFSS_REG_BASE 0x740000 -#define HAL_IPQ5332_CE_SIZE 0x100000 - enum hal_srng_ring_id { HAL_SRNG_RING_ID_REO2SW0 = 0, HAL_SRNG_RING_ID_REO2SW1, @@ -637,11 +293,6 @@ enum hal_ring_type { HAL_MAX_RING_TYPES, }; -#define HAL_RX_MAX_BA_WINDOW 256 - -#define HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC (100 * 1000) -#define HAL_DEFAULT_VO_REO_TIMEOUT_USEC (40 * 1000) - /** * enum hal_reo_cmd_type: Enum for REO command type * @HAL_REO_CMD_GET_QUEUE_STATS: Get REO queue status/stats @@ -1053,6 +704,90 @@ struct hal_rx_desc_data { u8 tid; }; +#define BUFFER_ADDR_INFO0_ADDR GENMASK(31, 0) + +#define BUFFER_ADDR_INFO1_ADDR GENMASK(7, 0) +#define BUFFER_ADDR_INFO1_RET_BUF_MGR GENMASK(11, 8) +#define BUFFER_ADDR_INFO1_SW_COOKIE GENMASK(31, 12) + +struct ath12k_buffer_addr { + __le32 info0; + __le32 info1; +} __packed; + +/* ath12k_buffer_addr + * + * buffer_addr_31_0 + * Address (lower 32 bits) of the MSDU buffer or MSDU_EXTENSION + * descriptor or Link descriptor + * + * buffer_addr_39_32 + * Address (upper 8 bits) of the MSDU buffer or MSDU_EXTENSION + * descriptor or Link descriptor + * + * return_buffer_manager (RBM) + * Consumer: WBM + * Producer: SW/FW + * Indicates to which buffer manager the buffer or MSDU_EXTENSION + * descriptor or link descriptor that is being pointed to shall be + * returned after the frame has been processed. It is used by WBM + * for routing purposes. + * + * Values are defined in enum %HAL_RX_BUF_RBM_ + * + * sw_buffer_cookie + * Cookie field exclusively used by SW. HW ignores the contents, + * accept that it passes the programmed value on to other + * descriptors together with the physical address. + * + * Field can be used by SW to for example associate the buffers + * physical address with the virtual address. + * + * NOTE1: + * The three most significant bits can have a special meaning + * in case this struct is embedded in a TX_MPDU_DETAILS STRUCT, + * and field transmit_bw_restriction is set + * + * In case of NON punctured transmission: + * Sw_buffer_cookie[19:17] = 3'b000: 20 MHz TX only + * Sw_buffer_cookie[19:17] = 3'b001: 40 MHz TX only + * Sw_buffer_cookie[19:17] = 3'b010: 80 MHz TX only + * Sw_buffer_cookie[19:17] = 3'b011: 160 MHz TX only + * Sw_buffer_cookie[19:17] = 3'b101: 240 MHz TX only + * Sw_buffer_cookie[19:17] = 3'b100: 320 MHz TX only + * Sw_buffer_cookie[19:18] = 2'b11: reserved + * + * In case of punctured transmission: + * Sw_buffer_cookie[19:16] = 4'b0000: pattern 0 only + * Sw_buffer_cookie[19:16] = 4'b0001: pattern 1 only + * Sw_buffer_cookie[19:16] = 4'b0010: pattern 2 only + * Sw_buffer_cookie[19:16] = 4'b0011: pattern 3 only + * Sw_buffer_cookie[19:16] = 4'b0100: pattern 4 only + * Sw_buffer_cookie[19:16] = 4'b0101: pattern 5 only + * Sw_buffer_cookie[19:16] = 4'b0110: pattern 6 only + * Sw_buffer_cookie[19:16] = 4'b0111: pattern 7 only + * Sw_buffer_cookie[19:16] = 4'b1000: pattern 8 only + * Sw_buffer_cookie[19:16] = 4'b1001: pattern 9 only + * Sw_buffer_cookie[19:16] = 4'b1010: pattern 10 only + * Sw_buffer_cookie[19:16] = 4'b1011: pattern 11 only + * Sw_buffer_cookie[19:18] = 2'b11: reserved + * + * Note: a punctured transmission is indicated by the presence + * of TLV TX_PUNCTURE_SETUP embedded in the scheduler TLV + * + * Sw_buffer_cookie[20:17]: Tid: The TID field in the QoS control + * field + * + * Sw_buffer_cookie[16]: Mpdu_qos_control_valid: This field + * indicates MPDUs with a QoS control field. + * + */ + +struct hal_ce_srng_dest_desc; +struct hal_ce_srng_dst_status_desc; +struct hal_ce_srng_src_desc; +struct hal_wbm_link_desc; + /* srng flags */ #define HAL_SRNG_FLAGS_MSI_SWAP 0x00000008 #define HAL_SRNG_FLAGS_RING_PTR_SWAP 0x00000010 @@ -1062,9 +797,6 @@ struct hal_rx_desc_data { #define HAL_SRNG_FLAGS_HIGH_THRESH_INTR_EN 0x00080000 #define HAL_SRNG_FLAGS_LMAC_RING 0x80000000 -#define HAL_SRNG_TLV_HDR_TAG GENMASK(9, 1) -#define HAL_SRNG_TLV_HDR_LEN GENMASK(25, 10) - /* Common SRNG ring structure for source and destination rings */ struct hal_srng { /* Unique SRNG ring ID */ @@ -1249,66 +981,6 @@ enum hal_rx_buf_return_buf_manager { HAL_RX_BUF_RBM_SW6_BM, }; -#define HAL_SRNG_DESC_LOOP_CNT 0xf0000000 - -#define HAL_REO_CMD_FLG_NEED_STATUS BIT(0) -#define HAL_REO_CMD_FLG_STATS_CLEAR BIT(1) -#define HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER BIT(2) -#define HAL_REO_CMD_FLG_FLUSH_RELEASE_BLOCKING BIT(3) -#define HAL_REO_CMD_FLG_FLUSH_NO_INVAL BIT(4) -#define HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS BIT(5) -#define HAL_REO_CMD_FLG_FLUSH_ALL BIT(6) -#define HAL_REO_CMD_FLG_UNBLK_RESOURCE BIT(7) -#define HAL_REO_CMD_FLG_UNBLK_CACHE BIT(8) -#define HAL_REO_CMD_FLG_FLUSH_QUEUE_1K_DESC BIT(9) - -/* Should be matching with HAL_REO_UPD_RX_QUEUE_INFO0_UPD_* fields */ -#define HAL_REO_CMD_UPD0_RX_QUEUE_NUM BIT(8) -#define HAL_REO_CMD_UPD0_VLD BIT(9) -#define HAL_REO_CMD_UPD0_ALDC BIT(10) -#define HAL_REO_CMD_UPD0_DIS_DUP_DETECTION BIT(11) -#define HAL_REO_CMD_UPD0_SOFT_REORDER_EN BIT(12) -#define HAL_REO_CMD_UPD0_AC BIT(13) -#define HAL_REO_CMD_UPD0_BAR BIT(14) -#define HAL_REO_CMD_UPD0_RETRY BIT(15) -#define HAL_REO_CMD_UPD0_CHECK_2K_MODE BIT(16) -#define HAL_REO_CMD_UPD0_OOR_MODE BIT(17) -#define HAL_REO_CMD_UPD0_BA_WINDOW_SIZE BIT(18) -#define HAL_REO_CMD_UPD0_PN_CHECK BIT(19) -#define HAL_REO_CMD_UPD0_EVEN_PN BIT(20) -#define HAL_REO_CMD_UPD0_UNEVEN_PN BIT(21) -#define HAL_REO_CMD_UPD0_PN_HANDLE_ENABLE BIT(22) -#define HAL_REO_CMD_UPD0_PN_SIZE BIT(23) -#define HAL_REO_CMD_UPD0_IGNORE_AMPDU_FLG BIT(24) -#define HAL_REO_CMD_UPD0_SVLD BIT(25) -#define HAL_REO_CMD_UPD0_SSN BIT(26) -#define HAL_REO_CMD_UPD0_SEQ_2K_ERR BIT(27) -#define HAL_REO_CMD_UPD0_PN_ERR BIT(28) -#define HAL_REO_CMD_UPD0_PN_VALID BIT(29) -#define HAL_REO_CMD_UPD0_PN BIT(30) - -/* Should be matching with HAL_REO_UPD_RX_QUEUE_INFO1_* fields */ -#define HAL_REO_CMD_UPD1_VLD BIT(16) -#define HAL_REO_CMD_UPD1_ALDC GENMASK(18, 17) -#define HAL_REO_CMD_UPD1_DIS_DUP_DETECTION BIT(19) -#define HAL_REO_CMD_UPD1_SOFT_REORDER_EN BIT(20) -#define HAL_REO_CMD_UPD1_AC GENMASK(22, 21) -#define HAL_REO_CMD_UPD1_BAR BIT(23) -#define HAL_REO_CMD_UPD1_RETRY BIT(24) -#define HAL_REO_CMD_UPD1_CHECK_2K_MODE BIT(25) -#define HAL_REO_CMD_UPD1_OOR_MODE BIT(26) -#define HAL_REO_CMD_UPD1_PN_CHECK BIT(27) -#define HAL_REO_CMD_UPD1_EVEN_PN BIT(28) -#define HAL_REO_CMD_UPD1_UNEVEN_PN BIT(29) -#define HAL_REO_CMD_UPD1_PN_HANDLE_ENABLE BIT(30) -#define HAL_REO_CMD_UPD1_IGNORE_AMPDU_FLG BIT(31) - -/* Should be matching with HAL_REO_UPD_RX_QUEUE_INFO2_* fields */ -#define HAL_REO_CMD_UPD2_SVLD BIT(10) -#define HAL_REO_CMD_UPD2_SSN GENMASK(22, 11) -#define HAL_REO_CMD_UPD2_SEQ_2K_ERR BIT(23) -#define HAL_REO_CMD_UPD2_PN_ERR BIT(24) - struct ath12k_hal_reo_cmd { u32 addr_lo; u32 flag; @@ -1354,93 +1026,6 @@ struct hal_reo_status_header { u32 timestamp; }; -struct hal_reo_status_queue_stats { - u16 ssn; - u16 curr_idx; - u32 pn[4]; - u32 last_rx_queue_ts; - u32 last_rx_dequeue_ts; - u32 rx_bitmap[8]; /* Bitmap from 0-255 */ - u32 curr_mpdu_cnt; - u32 curr_msdu_cnt; - u16 fwd_due_to_bar_cnt; - u16 dup_cnt; - u32 frames_in_order_cnt; - u32 num_mpdu_processed_cnt; - u32 num_msdu_processed_cnt; - u32 total_num_processed_byte_cnt; - u32 late_rx_mpdu_cnt; - u32 reorder_hole_cnt; - u8 timeout_cnt; - u8 bar_rx_cnt; - u8 num_window_2k_jump_cnt; -}; - -struct hal_reo_status_flush_queue { - bool err_detected; -}; - -enum hal_reo_status_flush_cache_err_code { - HAL_REO_STATUS_FLUSH_CACHE_ERR_CODE_SUCCESS, - HAL_REO_STATUS_FLUSH_CACHE_ERR_CODE_IN_USE, - HAL_REO_STATUS_FLUSH_CACHE_ERR_CODE_NOT_FOUND, -}; - -struct hal_reo_status_flush_cache { - bool err_detected; - enum hal_reo_status_flush_cache_err_code err_code; - bool cache_controller_flush_status_hit; - u8 cache_controller_flush_status_desc_type; - u8 cache_controller_flush_status_client_id; - u8 cache_controller_flush_status_err; - u8 cache_controller_flush_status_cnt; -}; - -enum hal_reo_status_unblock_cache_type { - HAL_REO_STATUS_UNBLOCK_BLOCKING_RESOURCE, - HAL_REO_STATUS_UNBLOCK_ENTIRE_CACHE_USAGE, -}; - -struct hal_reo_status_unblock_cache { - bool err_detected; - enum hal_reo_status_unblock_cache_type unblock_type; -}; - -struct hal_reo_status_flush_timeout_list { - bool err_detected; - bool list_empty; - u16 release_desc_cnt; - u16 fwd_buf_cnt; -}; - -enum hal_reo_threshold_idx { - HAL_REO_THRESHOLD_IDX_DESC_COUNTER0, - HAL_REO_THRESHOLD_IDX_DESC_COUNTER1, - HAL_REO_THRESHOLD_IDX_DESC_COUNTER2, - HAL_REO_THRESHOLD_IDX_DESC_COUNTER_SUM, -}; - -struct hal_reo_status_desc_thresh_reached { - enum hal_reo_threshold_idx threshold_idx; - u32 link_desc_counter0; - u32 link_desc_counter1; - u32 link_desc_counter2; - u32 link_desc_counter_sum; -}; - -struct hal_reo_status { - struct hal_reo_status_header uniform_hdr; - u8 loop_cnt; - union { - struct hal_reo_status_queue_stats queue_stats; - struct hal_reo_status_flush_queue flush_queue; - struct hal_reo_status_flush_cache flush_cache; - struct hal_reo_status_unblock_cache unblock_cache; - struct hal_reo_status_flush_timeout_list timeout_list; - struct hal_reo_status_desc_thresh_reached desc_thresh_reached; - } u; -}; - struct ath12k_hw_hal_params { enum hal_rx_buf_return_buf_manager rx_buf_rbm; u32 wbm2sw_cc_enable; @@ -1559,7 +1144,7 @@ struct ath12k_hal { u8 current_blk_index; /* shadow register configuration */ - u32 shadow_reg_addr[HAL_SHADOW_NUM_REGS]; + u32 shadow_reg_addr[HAL_SHADOW_NUM_REGS_MAX]; int num_shadow_reg_configured; u32 hal_desc_sz; @@ -1743,7 +1328,6 @@ struct hal_ops { (*get_idle_link_rbm)(struct ath12k_hal *hal, u8 device_id); }; -u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab, struct hal_srng *srng); dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab, diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 529949b3a791f..e9ead1b75af39 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -15,7 +15,7 @@ #include "hif.h" #include "mhi.h" #include "debug.h" -#include "wifi7/dp.h" +#include "hal.h" #define ATH12K_PCI_BAR_NUM 0 #define ATH12K_PCI_DMA_MASK 36 diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 06d3690ff0c63..976dfe1b90874 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -138,6 +138,7 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, static struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = { .service_srng = ath12k_wifi7_dp_service_srng, + .dp_tx_get_vdev_bank_config = ath12k_wifi7_dp_tx_get_vdev_bank_config, }; /* TODO: remove export once this file is built with wifi7 ko */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index ece6a1311ef0c..5ecbbf548b056 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -8,6 +8,9 @@ #include "../core.h" #include "../dp_rx.h" +#include "hal_rx_desc.h" + +struct ath12k_hal_reo_cmd; int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, struct napi_struct *napi, int budget); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index b3c0f8a6a5ce0..2f523ed00dedd 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -9,6 +9,9 @@ #include "../dp_tx.h" #include "../peer.h" #include "dp_tx.h" +#include "hal_desc.h" +#include "hal.h" +#include "hal_tx.h" static void ath12k_wifi7_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, @@ -922,3 +925,52 @@ void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) rcu_read_unlock(); } } + +u32 ath12k_wifi7_dp_tx_get_vdev_bank_config(struct ath12k_base *ab, + struct ath12k_link_vif *arvif) +{ + u32 bank_config = 0; + u8 link_id = arvif->link_id; + struct ath12k_vif *ahvif = arvif->ahvif; + struct ath12k_dp_vif *dp_vif = &ahvif->dp_vif; + struct ath12k_dp_link_vif *dp_link_vif; + + dp_link_vif = ath12k_dp_vif_to_dp_link_vif(dp_vif, link_id); + + /* Only valid for raw frames with HW crypto enabled. + * With SW crypto, mac80211 sets key per packet + */ + if (dp_vif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW && + test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags)) + bank_config |= + u32_encode_bits(ath12k_dp_tx_get_encrypt_type(dp_vif->key_cipher), + HAL_TX_BANK_CONFIG_ENCRYPT_TYPE); + + bank_config |= u32_encode_bits(dp_vif->tx_encap_type, + HAL_TX_BANK_CONFIG_ENCAP_TYPE); + bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_SRC_BUFFER_SWAP) | + u32_encode_bits(0, HAL_TX_BANK_CONFIG_LINK_META_SWAP) | + u32_encode_bits(0, HAL_TX_BANK_CONFIG_EPD); + + /* only valid if idx_lookup_override is not set in tcl_data_cmd */ + if (ahvif->vdev_type == WMI_VDEV_TYPE_STA) + bank_config |= u32_encode_bits(1, HAL_TX_BANK_CONFIG_INDEX_LOOKUP_EN); + else + bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_INDEX_LOOKUP_EN); + + bank_config |= u32_encode_bits(dp_link_vif->hal_addr_search_flags & + HAL_TX_ADDRX_EN, + HAL_TX_BANK_CONFIG_ADDRX_EN) | + u32_encode_bits(!!(dp_link_vif->hal_addr_search_flags & + HAL_TX_ADDRY_EN), + HAL_TX_BANK_CONFIG_ADDRY_EN); + + bank_config |= u32_encode_bits(ieee80211_vif_is_mesh(ahvif->vif) ? 3 : 0, + HAL_TX_BANK_CONFIG_MESH_EN) | + u32_encode_bits(dp_link_vif->vdev_id_check_en, + HAL_TX_BANK_CONFIG_VDEV_ID_CHECK_EN); + + bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_DSCP_TIP_MAP_ID); + + return bank_config; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h index 524e23b8ed808..94a5c59289cca 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h @@ -11,4 +11,6 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, bool is_mcast); void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id); +u32 ath12k_wifi7_dp_tx_get_vdev_bank_config(struct ath12k_base *ab, + struct ath12k_link_vif *arvif); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 4f9f1efbbfcf2..e42970346e3dd 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -406,7 +406,7 @@ int ath12k_wifi7_hal_srng_update_shadow_config(struct ath12k_base *ab, int shadow_cfg_idx = hal->num_shadow_reg_configured; u32 target_reg; - if (shadow_cfg_idx >= HAL_SHADOW_NUM_REGS) + if (shadow_cfg_idx >= HAL_SHADOW_NUM_REGS_MAX) return -EINVAL; hal->num_shadow_reg_configured++; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index b600b2e3cb78d..8a40b91764065 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -7,6 +7,517 @@ #ifndef ATH12K_HAL_WIFI7_H #define ATH12K_HAL_WIFI7_H +#include "../core.h" +#include "../hal.h" +#include "hal_desc.h" +#include "hal_tx.h" +#include "hal_rx.h" +#include "hal_rx_desc.h" + +/* calculate the register address from bar0 of shadow register x */ +#define HAL_SHADOW_BASE_ADDR 0x000008fc +#define HAL_SHADOW_NUM_REGS 40 +#define HAL_HP_OFFSET_IN_REG_START 1 +#define HAL_OFFSET_FROM_HP_TO_TP 4 + +#define HAL_SHADOW_REG(x) (HAL_SHADOW_BASE_ADDR + (4 * (x))) +#define HAL_REO_QDESC_MAX_PEERID 8191 + +/* WCSS Relative address */ +#define HAL_SEQ_WCSS_CMEM_OFFSET 0x00100000 +#define HAL_SEQ_WCSS_UMAC_OFFSET 0x00a00000 +#define HAL_SEQ_WCSS_UMAC_REO_REG 0x00a38000 +#define HAL_SEQ_WCSS_UMAC_TCL_REG 0x00a44000 +#define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal) \ + ((hal)->regs->hal_umac_ce0_src_reg_base) +#define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) \ + ((hal)->regs->hal_umac_ce0_dest_reg_base) +#define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(hal) \ + ((hal)->regs->hal_umac_ce1_src_reg_base) +#define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) \ + ((hal)->regs->hal_umac_ce1_dest_reg_base) +#define HAL_SEQ_WCSS_UMAC_WBM_REG 0x00a34000 + +#define HAL_CE_WFSS_CE_REG_BASE 0x01b80000 + +#define HAL_TCL_SW_CONFIG_BANK_ADDR 0x00a4408c + +/* SW2TCL(x) R0 ring configuration address */ +#define HAL_TCL1_RING_CMN_CTRL_REG 0x00000020 +#define HAL_TCL1_RING_DSCP_TID_MAP 0x00000240 + +#define HAL_TCL1_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl1_ring_base_lsb) +#define HAL_TCL1_RING_BASE_MSB(hal) \ + ((hal)->regs->hal_tcl1_ring_base_msb) +#define HAL_TCL1_RING_ID(hal) ((hal)->regs->hal_tcl1_ring_id) +#define HAL_TCL1_RING_MISC(hal) \ + ((hal)->regs->hal_tcl1_ring_misc) +#define HAL_TCL1_RING_TP_ADDR_LSB(hal) \ + ((hal)->regs->hal_tcl1_ring_tp_addr_lsb) +#define HAL_TCL1_RING_TP_ADDR_MSB(hal) \ + ((hal)->regs->hal_tcl1_ring_tp_addr_msb) +#define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(hal) \ + ((hal)->regs->hal_tcl1_ring_consumer_int_setup_ix0) +#define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(hal) \ + ((hal)->regs->hal_tcl1_ring_consumer_int_setup_ix1) +#define HAL_TCL1_RING_MSI1_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl1_ring_msi1_base_lsb) +#define HAL_TCL1_RING_MSI1_BASE_MSB(hal) \ + ((hal)->regs->hal_tcl1_ring_msi1_base_msb) +#define HAL_TCL1_RING_MSI1_DATA(hal) \ + ((hal)->regs->hal_tcl1_ring_msi1_data) +#define HAL_TCL2_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl2_ring_base_lsb) +#define HAL_TCL_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl_ring_base_lsb) + +#define HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_MSI1_BASE_LSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_MSI1_BASE_MSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_MSI1_DATA_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_MSI1_DATA(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_BASE_MSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_BASE_MSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_ID_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_ID(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_TP_ADDR_LSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_TP_ADDR_MSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) +#define HAL_TCL1_RING_MISC_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ + (HAL_TCL1_RING_MISC(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) + +/* SW2TCL(x) R2 ring pointers (head/tail) address */ +#define HAL_TCL1_RING_HP 0x00002000 +#define HAL_TCL1_RING_TP 0x00002004 +#define HAL_TCL2_RING_HP 0x00002008 +#define HAL_TCL_RING_HP 0x00002028 + +#define HAL_TCL1_RING_TP_OFFSET \ + (HAL_TCL1_RING_TP - HAL_TCL1_RING_HP) + +/* TCL STATUS ring address */ +#define HAL_TCL_STATUS_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_tcl_status_ring_base_lsb) +#define HAL_TCL_STATUS_RING_HP 0x00002048 + +/* PPE2TCL1 Ring address */ +#define HAL_TCL_PPE2TCL1_RING_BASE_LSB 0x00000c48 +#define HAL_TCL_PPE2TCL1_RING_HP 0x00002038 + +/* WBM PPE Release Ring address */ +#define HAL_WBM_PPE_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_ppe_rel_ring_base) +#define HAL_WBM_PPE_RELEASE_RING_HP 0x00003020 + +/* REO2SW(x) R0 ring configuration address */ +#define HAL_REO1_GEN_ENABLE 0x00000000 +#define HAL_REO1_MISC_CTRL_ADDR(hal) \ + ((hal)->regs->hal_reo1_misc_ctrl_addr) +#define HAL_REO1_DEST_RING_CTRL_IX_0 0x00000004 +#define HAL_REO1_DEST_RING_CTRL_IX_1 0x00000008 +#define HAL_REO1_DEST_RING_CTRL_IX_2 0x0000000c +#define HAL_REO1_DEST_RING_CTRL_IX_3 0x00000010 +#define HAL_REO1_QDESC_ADDR(hal) ((hal)->regs->hal_reo1_qdesc_addr) +#define HAL_REO1_QDESC_MAX_PEERID(hal) ((hal)->regs->hal_reo1_qdesc_max_peerid) +#define HAL_REO1_SW_COOKIE_CFG0(hal) ((hal)->regs->hal_reo1_sw_cookie_cfg0) +#define HAL_REO1_SW_COOKIE_CFG1(hal) ((hal)->regs->hal_reo1_sw_cookie_cfg1) +#define HAL_REO1_QDESC_LUT_BASE0(hal) ((hal)->regs->hal_reo1_qdesc_lut_base0) +#define HAL_REO1_QDESC_LUT_BASE1(hal) ((hal)->regs->hal_reo1_qdesc_lut_base1) +#define HAL_REO1_RING_BASE_LSB(hal) ((hal)->regs->hal_reo1_ring_base_lsb) +#define HAL_REO1_RING_BASE_MSB(hal) ((hal)->regs->hal_reo1_ring_base_msb) +#define HAL_REO1_RING_ID(hal) ((hal)->regs->hal_reo1_ring_id) +#define HAL_REO1_RING_MISC(hal) ((hal)->regs->hal_reo1_ring_misc) +#define HAL_REO1_RING_HP_ADDR_LSB(hal) ((hal)->regs->hal_reo1_ring_hp_addr_lsb) +#define HAL_REO1_RING_HP_ADDR_MSB(hal) ((hal)->regs->hal_reo1_ring_hp_addr_msb) +#define HAL_REO1_RING_PRODUCER_INT_SETUP(hal) \ + ((hal)->regs->hal_reo1_ring_producer_int_setup) +#define HAL_REO1_RING_MSI1_BASE_LSB(hal) \ + ((hal)->regs->hal_reo1_ring_msi1_base_lsb) +#define HAL_REO1_RING_MSI1_BASE_MSB(hal) \ + ((hal)->regs->hal_reo1_ring_msi1_base_msb) +#define HAL_REO1_RING_MSI1_DATA(hal) ((hal)->regs->hal_reo1_ring_msi1_data) +#define HAL_REO2_RING_BASE_LSB(hal) ((hal)->regs->hal_reo2_ring_base) +#define HAL_REO1_AGING_THRESH_IX_0(hal) ((hal)->regs->hal_reo1_aging_thres_ix0) +#define HAL_REO1_AGING_THRESH_IX_1(hal) ((hal)->regs->hal_reo1_aging_thres_ix1) +#define HAL_REO1_AGING_THRESH_IX_2(hal) ((hal)->regs->hal_reo1_aging_thres_ix2) +#define HAL_REO1_AGING_THRESH_IX_3(hal) ((hal)->regs->hal_reo1_aging_thres_ix3) + +/* REO2SW(x) R2 ring pointers (head/tail) address */ +#define HAL_REO1_RING_HP 0x00003048 +#define HAL_REO1_RING_TP 0x0000304c +#define HAL_REO2_RING_HP 0x00003050 + +#define HAL_REO1_RING_TP_OFFSET (HAL_REO1_RING_TP - HAL_REO1_RING_HP) + +/* REO2SW0 ring configuration address */ +#define HAL_REO_SW0_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_reo2_sw0_ring_base) + +/* REO2SW0 R2 ring pointer (head/tail) address */ +#define HAL_REO_SW0_RING_HP 0x00003088 + +/* REO CMD R0 address */ +#define HAL_REO_CMD_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_reo_cmd_ring_base) + +/* REO CMD R2 address */ +#define HAL_REO_CMD_HP 0x00003020 + +/* SW2REO R0 address */ +#define HAL_SW2REO_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_sw2reo_ring_base) +#define HAL_SW2REO1_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_sw2reo1_ring_base) + +/* SW2REO R2 address */ +#define HAL_SW2REO_RING_HP 0x00003028 +#define HAL_SW2REO1_RING_HP 0x00003030 + +/* CE ring R0 address */ +#define HAL_CE_SRC_RING_BASE_LSB 0x00000000 +#define HAL_CE_DST_RING_BASE_LSB 0x00000000 +#define HAL_CE_DST_STATUS_RING_BASE_LSB 0x00000058 +#define HAL_CE_DST_RING_CTRL 0x000000b0 + +/* CE ring R2 address */ +#define HAL_CE_DST_RING_HP 0x00000400 +#define HAL_CE_DST_STATUS_RING_HP 0x00000408 + +/* REO status address */ +#define HAL_REO_STATUS_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_reo_status_ring_base) +#define HAL_REO_STATUS_HP 0x000030a8 + +/* WBM Idle R0 address */ +#define HAL_WBM_IDLE_LINK_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm_idle_ring_base_lsb) +#define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(hal) \ + ((hal)->regs->hal_wbm_idle_ring_misc_addr) +#define HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(hal) \ + ((hal)->regs->hal_wbm_r0_idle_list_cntl_addr) +#define HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(hal) \ + ((hal)->regs->hal_wbm_r0_idle_list_size_addr) +#define HAL_WBM_SCATTERED_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm_scattered_ring_base_lsb) +#define HAL_WBM_SCATTERED_RING_BASE_MSB(hal) \ + ((hal)->regs->hal_wbm_scattered_ring_base_msb) +#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_head_info_ix0) +#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_head_info_ix1) +#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_tail_info_ix0) +#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_tail_info_ix1) +#define HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(hal) \ + ((hal)->regs->hal_wbm_scattered_desc_ptr_hp_addr) + +/* WBM Idle R2 address */ +#define HAL_WBM_IDLE_LINK_RING_HP 0x000030b8 + +/* SW2WBM R0 release address */ +#define HAL_WBM_SW_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm_sw_release_ring_base_lsb) +#define HAL_WBM_SW1_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm_sw1_release_ring_base_lsb) + +/* SW2WBM R2 release address */ +#define HAL_WBM_SW_RELEASE_RING_HP 0x00003010 +#define HAL_WBM_SW1_RELEASE_RING_HP 0x00003018 + +/* WBM2SW R0 release address */ +#define HAL_WBM0_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm0_release_ring_base_lsb) + +#define HAL_WBM1_RELEASE_RING_BASE_LSB(hal) \ + ((hal)->regs->hal_wbm1_release_ring_base_lsb) + +/* WBM2SW R2 release address */ +#define HAL_WBM0_RELEASE_RING_HP 0x000030c8 +#define HAL_WBM1_RELEASE_RING_HP 0x000030d0 + +/* WBM cookie config address and mask */ +#define HAL_WBM_SW_COOKIE_CFG0 0x00000040 +#define HAL_WBM_SW_COOKIE_CFG1 0x00000044 +#define HAL_WBM_SW_COOKIE_CFG2 0x00000090 +#define HAL_WBM_SW_COOKIE_CONVERT_CFG 0x00000094 + +#define HAL_WBM_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB GENMASK(7, 0) +#define HAL_WBM_SW_COOKIE_CFG_COOKIE_PPT_MSB GENMASK(12, 8) +#define HAL_WBM_SW_COOKIE_CFG_COOKIE_SPT_MSB GENMASK(17, 13) +#define HAL_WBM_SW_COOKIE_CFG_ALIGN BIT(18) +#define HAL_WBM_SW_COOKIE_CFG_RELEASE_PATH_EN BIT(0) +#define HAL_WBM_SW_COOKIE_CFG_ERR_PATH_EN BIT(1) +#define HAL_WBM_SW_COOKIE_CFG_CONV_IND_EN BIT(3) + +#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN BIT(1) +#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW1_EN BIT(2) +#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW2_EN BIT(3) +#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW3_EN BIT(4) +#define HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW4_EN BIT(5) +#define HAL_WBM_SW_COOKIE_CONV_CFG_GLOBAL_EN BIT(8) + +/* TCL ring field mask and offset */ +#define HAL_TCL1_RING_BASE_MSB_RING_SIZE GENMASK(27, 8) +#define HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB GENMASK(7, 0) +#define HAL_TCL1_RING_ID_ENTRY_SIZE GENMASK(7, 0) +#define HAL_TCL1_RING_MISC_MSI_RING_ID_DISABLE BIT(0) +#define HAL_TCL1_RING_MISC_MSI_LOOPCNT_DISABLE BIT(1) +#define HAL_TCL1_RING_MISC_MSI_SWAP BIT(3) +#define HAL_TCL1_RING_MISC_HOST_FW_SWAP BIT(4) +#define HAL_TCL1_RING_MISC_DATA_TLV_SWAP BIT(5) +#define HAL_TCL1_RING_MISC_SRNG_ENABLE BIT(6) +#define HAL_TCL1_RING_CONSR_INT_SETUP_IX0_INTR_TMR_THOLD GENMASK(31, 16) +#define HAL_TCL1_RING_CONSR_INT_SETUP_IX0_BATCH_COUNTER_THOLD GENMASK(14, 0) +#define HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD GENMASK(15, 0) +#define HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE BIT(8) +#define HAL_TCL1_RING_MSI1_BASE_MSB_ADDR GENMASK(7, 0) +#define HAL_TCL1_RING_CMN_CTRL_DSCP_TID_MAP_PROG_EN BIT(23) +#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP GENMASK(31, 0) +#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP0 GENMASK(2, 0) +#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP1 GENMASK(5, 3) +#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP2 GENMASK(8, 6) +#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP3 GENMASK(11, 9) +#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP4 GENMASK(14, 12) +#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP5 GENMASK(17, 15) +#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP6 GENMASK(20, 18) +#define HAL_TCL1_RING_FIELD_DSCP_TID_MAP7 GENMASK(23, 21) + +/* REO ring field mask and offset */ +#define HAL_REO1_RING_BASE_MSB_RING_SIZE GENMASK(27, 8) +#define HAL_REO1_RING_BASE_MSB_RING_BASE_ADDR_MSB GENMASK(7, 0) +#define HAL_REO1_RING_ID_RING_ID GENMASK(15, 8) +#define HAL_REO1_RING_ID_ENTRY_SIZE GENMASK(7, 0) +#define HAL_REO1_RING_MISC_MSI_SWAP BIT(3) +#define HAL_REO1_RING_MISC_HOST_FW_SWAP BIT(4) +#define HAL_REO1_RING_MISC_DATA_TLV_SWAP BIT(5) +#define HAL_REO1_RING_MISC_SRNG_ENABLE BIT(6) +#define HAL_REO1_RING_PRDR_INT_SETUP_INTR_TMR_THOLD GENMASK(31, 16) +#define HAL_REO1_RING_PRDR_INT_SETUP_BATCH_COUNTER_THOLD GENMASK(14, 0) +#define HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE BIT(8) +#define HAL_REO1_RING_MSI1_BASE_MSB_ADDR GENMASK(7, 0) +#define HAL_REO1_MISC_CTL_FRAG_DST_RING GENMASK(20, 17) +#define HAL_REO1_MISC_CTL_BAR_DST_RING GENMASK(24, 21) +#define HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE BIT(2) +#define HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE BIT(3) +#define HAL_REO1_SW_COOKIE_CFG_CMEM_BASE_ADDR_MSB GENMASK(7, 0) +#define HAL_REO1_SW_COOKIE_CFG_COOKIE_PPT_MSB GENMASK(12, 8) +#define HAL_REO1_SW_COOKIE_CFG_COOKIE_SPT_MSB GENMASK(17, 13) +#define HAL_REO1_SW_COOKIE_CFG_ALIGN BIT(18) +#define HAL_REO1_SW_COOKIE_CFG_ENABLE BIT(19) +#define HAL_REO1_SW_COOKIE_CFG_GLOBAL_ENABLE BIT(20) +#define HAL_REO_QDESC_ADDR_READ_LUT_ENABLE BIT(7) +#define HAL_REO_QDESC_ADDR_READ_CLEAR_QDESC_ARRAY BIT(6) + +/* CE ring bit field mask and shift */ +#define HAL_CE_DST_R0_DEST_CTRL_MAX_LEN GENMASK(15, 0) + +#define HAL_ADDR_LSB_REG_MASK 0xffffffff + +#define HAL_ADDR_MSB_REG_SHIFT 32 + +/* WBM ring bit field mask and shift */ +#define HAL_WBM_LINK_DESC_IDLE_LIST_MODE BIT(1) +#define HAL_WBM_SCATTER_BUFFER_SIZE GENMASK(10, 2) +#define HAL_WBM_SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST GENMASK(31, 16) +#define HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32 GENMASK(7, 0) +#define HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG GENMASK(31, 8) + +#define HAL_WBM_SCATTERED_DESC_HEAD_P_OFFSET_IX1 GENMASK(20, 8) +#define HAL_WBM_SCATTERED_DESC_TAIL_P_OFFSET_IX1 GENMASK(20, 8) + +#define HAL_WBM_IDLE_LINK_RING_MISC_SRNG_ENABLE BIT(6) +#define HAL_WBM_IDLE_LINK_RING_MISC_RIND_ID_DISABLE BIT(0) + +#define BASE_ADDR_MATCH_TAG_VAL 0x5 + +#define HAL_REO_REO2SW1_RING_BASE_MSB_RING_SIZE 0x000fffff +#define HAL_REO_REO2SW0_RING_BASE_MSB_RING_SIZE 0x000fffff +#define HAL_REO_SW2REO_RING_BASE_MSB_RING_SIZE 0x0000ffff +#define HAL_REO_CMD_RING_BASE_MSB_RING_SIZE 0x0000ffff +#define HAL_REO_STATUS_RING_BASE_MSB_RING_SIZE 0x0000ffff +#define HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE 0x000fffff +#define HAL_SW2TCL1_CMD_RING_BASE_MSB_RING_SIZE 0x000fffff +#define HAL_TCL_STATUS_RING_BASE_MSB_RING_SIZE 0x0000ffff +#define HAL_CE_SRC_RING_BASE_MSB_RING_SIZE 0x0000ffff +#define HAL_CE_DST_RING_BASE_MSB_RING_SIZE 0x0000ffff +#define HAL_CE_DST_STATUS_RING_BASE_MSB_RING_SIZE 0x0000ffff +#define HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE 0x000fffff +#define HAL_SW2WBM_RELEASE_RING_BASE_MSB_RING_SIZE 0x0000ffff +#define HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE 0x000fffff +#define HAL_RXDMA_RING_MAX_SIZE 0x0000ffff +#define HAL_RXDMA_RING_MAX_SIZE_BE 0x000fffff +#define HAL_WBM2PPE_RELEASE_RING_BASE_MSB_RING_SIZE 0x000fffff + +#define HAL_WBM2SW_REL_ERR_RING_NUM 3 +/* Add any other errors here and return them in + * ath12k_hal_rx_desc_get_err(). + */ + +#define HAL_IPQ5332_CE_WFSS_REG_BASE 0x740000 +#define HAL_IPQ5332_CE_SIZE 0x100000 + +#define HAL_RX_MAX_BA_WINDOW 256 + +#define HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC (100 * 1000) +#define HAL_DEFAULT_VO_REO_TIMEOUT_USEC (40 * 1000) + +#define HAL_SRNG_TLV_HDR_TAG GENMASK(9, 1) +#define HAL_SRNG_TLV_HDR_LEN GENMASK(25, 10) + +#define HAL_SRNG_DESC_LOOP_CNT 0xf0000000 + +#define HAL_REO_CMD_FLG_NEED_STATUS BIT(0) +#define HAL_REO_CMD_FLG_STATS_CLEAR BIT(1) +#define HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER BIT(2) +#define HAL_REO_CMD_FLG_FLUSH_RELEASE_BLOCKING BIT(3) +#define HAL_REO_CMD_FLG_FLUSH_NO_INVAL BIT(4) +#define HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS BIT(5) +#define HAL_REO_CMD_FLG_FLUSH_ALL BIT(6) +#define HAL_REO_CMD_FLG_UNBLK_RESOURCE BIT(7) +#define HAL_REO_CMD_FLG_UNBLK_CACHE BIT(8) + +/* Should be matching with HAL_REO_UPD_RX_QUEUE_INFO0_UPD_* fields */ +#define HAL_REO_CMD_UPD0_RX_QUEUE_NUM BIT(8) +#define HAL_REO_CMD_UPD0_VLD BIT(9) +#define HAL_REO_CMD_UPD0_ALDC BIT(10) +#define HAL_REO_CMD_UPD0_DIS_DUP_DETECTION BIT(11) +#define HAL_REO_CMD_UPD0_SOFT_REORDER_EN BIT(12) +#define HAL_REO_CMD_UPD0_AC BIT(13) +#define HAL_REO_CMD_UPD0_BAR BIT(14) +#define HAL_REO_CMD_UPD0_RETRY BIT(15) +#define HAL_REO_CMD_UPD0_CHECK_2K_MODE BIT(16) +#define HAL_REO_CMD_UPD0_OOR_MODE BIT(17) +#define HAL_REO_CMD_UPD0_BA_WINDOW_SIZE BIT(18) +#define HAL_REO_CMD_UPD0_PN_CHECK BIT(19) +#define HAL_REO_CMD_UPD0_EVEN_PN BIT(20) +#define HAL_REO_CMD_UPD0_UNEVEN_PN BIT(21) +#define HAL_REO_CMD_UPD0_PN_HANDLE_ENABLE BIT(22) +#define HAL_REO_CMD_UPD0_PN_SIZE BIT(23) +#define HAL_REO_CMD_UPD0_IGNORE_AMPDU_FLG BIT(24) +#define HAL_REO_CMD_UPD0_SVLD BIT(25) +#define HAL_REO_CMD_UPD0_SSN BIT(26) +#define HAL_REO_CMD_UPD0_SEQ_2K_ERR BIT(27) +#define HAL_REO_CMD_UPD0_PN_ERR BIT(28) +#define HAL_REO_CMD_UPD0_PN_VALID BIT(29) +#define HAL_REO_CMD_UPD0_PN BIT(30) + +/* Should be matching with HAL_REO_UPD_RX_QUEUE_INFO1_* fields */ +#define HAL_REO_CMD_UPD1_VLD BIT(16) +#define HAL_REO_CMD_UPD1_ALDC GENMASK(18, 17) +#define HAL_REO_CMD_UPD1_DIS_DUP_DETECTION BIT(19) +#define HAL_REO_CMD_UPD1_SOFT_REORDER_EN BIT(20) +#define HAL_REO_CMD_UPD1_AC GENMASK(22, 21) +#define HAL_REO_CMD_UPD1_BAR BIT(23) +#define HAL_REO_CMD_UPD1_RETRY BIT(24) +#define HAL_REO_CMD_UPD1_CHECK_2K_MODE BIT(25) +#define HAL_REO_CMD_UPD1_OOR_MODE BIT(26) +#define HAL_REO_CMD_UPD1_PN_CHECK BIT(27) +#define HAL_REO_CMD_UPD1_EVEN_PN BIT(28) +#define HAL_REO_CMD_UPD1_UNEVEN_PN BIT(29) +#define HAL_REO_CMD_UPD1_PN_HANDLE_ENABLE BIT(30) +#define HAL_REO_CMD_UPD1_IGNORE_AMPDU_FLG BIT(31) + +/* Should be matching with HAL_REO_UPD_RX_QUEUE_INFO2_* fields */ +#define HAL_REO_CMD_UPD2_SVLD BIT(10) +#define HAL_REO_CMD_UPD2_SSN GENMASK(22, 11) +#define HAL_REO_CMD_UPD2_SEQ_2K_ERR BIT(23) +#define HAL_REO_CMD_UPD2_PN_ERR BIT(24) + +struct hal_reo_status_queue_stats { + u16 ssn; + u16 curr_idx; + u32 pn[4]; + u32 last_rx_queue_ts; + u32 last_rx_dequeue_ts; + u32 rx_bitmap[8]; /* Bitmap from 0-255 */ + u32 curr_mpdu_cnt; + u32 curr_msdu_cnt; + u16 fwd_due_to_bar_cnt; + u16 dup_cnt; + u32 frames_in_order_cnt; + u32 num_mpdu_processed_cnt; + u32 num_msdu_processed_cnt; + u32 total_num_processed_byte_cnt; + u32 late_rx_mpdu_cnt; + u32 reorder_hole_cnt; + u8 timeout_cnt; + u8 bar_rx_cnt; + u8 num_window_2k_jump_cnt; +}; + +struct hal_reo_status_flush_queue { + bool err_detected; +}; + +enum hal_reo_status_flush_cache_err_code { + HAL_REO_STATUS_FLUSH_CACHE_ERR_CODE_SUCCESS, + HAL_REO_STATUS_FLUSH_CACHE_ERR_CODE_IN_USE, + HAL_REO_STATUS_FLUSH_CACHE_ERR_CODE_NOT_FOUND, +}; + +struct hal_reo_status_flush_cache { + bool err_detected; + enum hal_reo_status_flush_cache_err_code err_code; + bool cache_controller_flush_status_hit; + u8 cache_controller_flush_status_desc_type; + u8 cache_controller_flush_status_client_id; + u8 cache_controller_flush_status_err; + u8 cache_controller_flush_status_cnt; +}; + +enum hal_reo_status_unblock_cache_type { + HAL_REO_STATUS_UNBLOCK_BLOCKING_RESOURCE, + HAL_REO_STATUS_UNBLOCK_ENTIRE_CACHE_USAGE, +}; + +struct hal_reo_status_unblock_cache { + bool err_detected; + enum hal_reo_status_unblock_cache_type unblock_type; +}; + +struct hal_reo_status_flush_timeout_list { + bool err_detected; + bool list_empty; + u16 release_desc_cnt; + u16 fwd_buf_cnt; +}; + +enum hal_reo_threshold_idx { + HAL_REO_THRESHOLD_IDX_DESC_COUNTER0, + HAL_REO_THRESHOLD_IDX_DESC_COUNTER1, + HAL_REO_THRESHOLD_IDX_DESC_COUNTER2, + HAL_REO_THRESHOLD_IDX_DESC_COUNTER_SUM, +}; + +struct hal_reo_status_desc_thresh_reached { + enum hal_reo_threshold_idx threshold_idx; + u32 link_desc_counter0; + u32 link_desc_counter1; + u32 link_desc_counter2; + u32 link_desc_counter_sum; +}; + +struct hal_reo_status { + struct hal_reo_status_header uniform_hdr; + u8 loop_cnt; + union { + struct hal_reo_status_queue_stats queue_stats; + struct hal_reo_status_flush_queue flush_queue; + struct hal_reo_status_flush_cache flush_cache; + struct hal_reo_status_unblock_cache unblock_cache; + struct hal_reo_status_flush_timeout_list timeout_list; + struct hal_reo_status_desc_thresh_reached desc_thresh_reached; + } u; +}; + int ath12k_wifi7_hal_init(struct ath12k_base *ab); void ath12k_wifi7_hal_ce_dst_setup(struct ath12k_base *ab, struct hal_srng *srng, int ring_num); @@ -48,4 +559,5 @@ void ath12k_wifi7_hal_write_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr); void ath12k_wifi7_hal_write_ml_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr); +u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h index b884f4f089387..57940d7ffba48 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h @@ -8,85 +8,6 @@ #ifndef ATH12K_HAL_DESC_H #define ATH12K_HAL_DESC_H -#define BUFFER_ADDR_INFO0_ADDR GENMASK(31, 0) - -#define BUFFER_ADDR_INFO1_ADDR GENMASK(7, 0) -#define BUFFER_ADDR_INFO1_RET_BUF_MGR GENMASK(11, 8) -#define BUFFER_ADDR_INFO1_SW_COOKIE GENMASK(31, 12) - -struct ath12k_buffer_addr { - __le32 info0; - __le32 info1; -} __packed; - -/* ath12k_buffer_addr - * - * buffer_addr_31_0 - * Address (lower 32 bits) of the MSDU buffer or MSDU_EXTENSION - * descriptor or Link descriptor - * - * buffer_addr_39_32 - * Address (upper 8 bits) of the MSDU buffer or MSDU_EXTENSION - * descriptor or Link descriptor - * - * return_buffer_manager (RBM) - * Consumer: WBM - * Producer: SW/FW - * Indicates to which buffer manager the buffer or MSDU_EXTENSION - * descriptor or link descriptor that is being pointed to shall be - * returned after the frame has been processed. It is used by WBM - * for routing purposes. - * - * Values are defined in enum %HAL_RX_BUF_RBM_ - * - * sw_buffer_cookie - * Cookie field exclusively used by SW. HW ignores the contents, - * accept that it passes the programmed value on to other - * descriptors together with the physical address. - * - * Field can be used by SW to for example associate the buffers - * physical address with the virtual address. - * - * NOTE1: - * The three most significant bits can have a special meaning - * in case this struct is embedded in a TX_MPDU_DETAILS STRUCT, - * and field transmit_bw_restriction is set - * - * In case of NON punctured transmission: - * Sw_buffer_cookie[19:17] = 3'b000: 20 MHz TX only - * Sw_buffer_cookie[19:17] = 3'b001: 40 MHz TX only - * Sw_buffer_cookie[19:17] = 3'b010: 80 MHz TX only - * Sw_buffer_cookie[19:17] = 3'b011: 160 MHz TX only - * Sw_buffer_cookie[19:17] = 3'b101: 240 MHz TX only - * Sw_buffer_cookie[19:17] = 3'b100: 320 MHz TX only - * Sw_buffer_cookie[19:18] = 2'b11: reserved - * - * In case of punctured transmission: - * Sw_buffer_cookie[19:16] = 4'b0000: pattern 0 only - * Sw_buffer_cookie[19:16] = 4'b0001: pattern 1 only - * Sw_buffer_cookie[19:16] = 4'b0010: pattern 2 only - * Sw_buffer_cookie[19:16] = 4'b0011: pattern 3 only - * Sw_buffer_cookie[19:16] = 4'b0100: pattern 4 only - * Sw_buffer_cookie[19:16] = 4'b0101: pattern 5 only - * Sw_buffer_cookie[19:16] = 4'b0110: pattern 6 only - * Sw_buffer_cookie[19:16] = 4'b0111: pattern 7 only - * Sw_buffer_cookie[19:16] = 4'b1000: pattern 8 only - * Sw_buffer_cookie[19:16] = 4'b1001: pattern 9 only - * Sw_buffer_cookie[19:16] = 4'b1010: pattern 10 only - * Sw_buffer_cookie[19:16] = 4'b1011: pattern 11 only - * Sw_buffer_cookie[19:18] = 2'b11: reserved - * - * Note: a punctured transmission is indicated by the presence - * of TLV TX_PUNCTURE_SETUP embedded in the scheduler TLV - * - * Sw_buffer_cookie[20:17]: Tid: The TID field in the QoS control - * field - * - * Sw_buffer_cookie[16]: Mpdu_qos_control_valid: This field - * indicates MPDUs with a QoS control field. - * - */ - enum hal_tlv_tag { HAL_MACTX_CBF_START = 0 /* 0x0 */, HAL_PHYRX_DATA = 1 /* 0x1 */, @@ -1863,7 +1784,6 @@ struct hal_wbm_release_ring_cc_rx { #define HAL_WBM_RELEASE_INFO3_CONTINUATION BIT(2) #define HAL_WBM_RELEASE_INFO5_LOOPING_COUNT GENMASK(31, 28) -#define HAL_ENCRYPT_TYPE_MAX 12 struct hal_wbm_release_ring { struct ath12k_buffer_addr buf_addr_info; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h index c48dd029f52ee..08c0a04694741 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h @@ -11,6 +11,7 @@ #include #include "../hal.h" #include "hal_rx.h" +#include "hal.h" extern const struct hal_ops hal_qcn9274_ops; extern const struct ath12k_hw_regs qcn9274_v1_regs; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index 449e1285c3752..8828187dc3315 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -10,6 +10,7 @@ #include "hal_tx.h" #include "hal_rx.h" #include "hal_desc.h" +#include "hal.h" static void ath12k_wifi7_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index a029ea3fe93c6..d6f33fcd2e961 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -7,6 +7,10 @@ #ifndef ATH12K_HAL_RX_H #define ATH12K_HAL_RX_H +#include "hal_desc.h" + +struct hal_reo_status; + struct hal_rx_wbm_rel_info { u32 cookie; enum hal_wbm_rel_src_module err_rel_src; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c index 24f905c5b0624..02d3cadf03fea 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c @@ -4,10 +4,10 @@ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ -#include "hal_desc.h" #include "../hal.h" #include "hal_tx.h" #include "../hif.h" +#include "hal.h" #define DSCP_TID_MAP_TBL_ENTRY_SIZE 64 diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h index 07392b31d0ab9..9d2b1552c2f51 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h @@ -7,8 +7,8 @@ #ifndef ATH12K_HAL_TX_H #define ATH12K_HAL_TX_H +#include "../mac.h" #include "hal_desc.h" -#include "../core.h" /* TODO: check all these data can be managed with struct ath12k_tx_desc_info for perf */ struct hal_tx_info { diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h index 7d0b0c9854468..46047fd6a3127 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -9,6 +9,7 @@ #include "../hal.h" #include "hal_rx.h" +#include "hal.h" extern const struct hal_ops hal_wcn7850_ops; extern const struct ath12k_hw_regs wcn7850_regs; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/pci.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c index f6dfdcf95025a..dedc88858bb0f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/pci.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -15,6 +15,7 @@ #include "../hal.h" #include "dp.h" #include "core.h" +#include "hal.h" #define QCN9274_DEVICE_ID 0x1109 #define WCN7850_DEVICE_ID 0x1107 From fcb8f46f17363e3dc28d7d030f133747b8e3a3af Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Thu, 9 Oct 2025 16:40:43 +0530 Subject: [PATCH 065/140] wifi: ath12k: Remove the unused ring inits in wcn Remove the initialization for the following rings in wcn as these rings are not used for wcn chips. HAL_RXDMA_MONITOR_BUF HAL_PPE2TCL HAL_PPE_RELEASE HAL_TX_MONITOR_BUF HAL_RXDMA_MONITOR_DST HAL_TX_MONITOR_DST Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-17-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 54 +++---------------- 1 file changed, 6 insertions(+), 48 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 233350ccd06e4..8151c216a5e1b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -146,14 +146,7 @@ static const struct hal_srng_config hw_srng_config_template[] = { .ring_dir = HAL_SRNG_DIR_DST, .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, }, - [HAL_RXDMA_MONITOR_BUF] = { - .start_ring_id = HAL_SRNG_SW2RXMON_BUF0, - .max_rings = 1, - .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, + [HAL_RXDMA_MONITOR_BUF] = {}, [HAL_RXDMA_MONITOR_STATUS] = { .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_STATBUF, .max_rings = 1, @@ -171,46 +164,11 @@ static const struct hal_srng_config hw_srng_config_template[] = { .ring_dir = HAL_SRNG_DIR_SRC, .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, }, - [HAL_PPE2TCL] = { - .start_ring_id = HAL_SRNG_RING_ID_PPE2TCL1, - .max_rings = 1, - .entry_size = sizeof(struct hal_tcl_entrance_from_ppe_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, - }, - [HAL_PPE_RELEASE] = { - .start_ring_id = HAL_SRNG_RING_ID_WBM_PPE_RELEASE, - .max_rings = 1, - .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_WBM2PPE_RELEASE_RING_BASE_MSB_RING_SIZE, - }, - [HAL_TX_MONITOR_BUF] = { - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2TXMON_BUF0, - .max_rings = 1, - .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_SRC, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, - [HAL_RXDMA_MONITOR_DST] = { - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXMON_BUF0, - .max_rings = 1, - .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - }, - [HAL_TX_MONITOR_DST] = { - .start_ring_id = HAL_SRNG_RING_ID_WMAC1_TXMON2SW0_BUF0, - .max_rings = 1, - .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, - .mac_type = ATH12K_HAL_SRNG_PMAC, - .ring_dir = HAL_SRNG_DIR_DST, - .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, - } + [HAL_PPE2TCL] = {}, + [HAL_PPE_RELEASE] = {}, + [HAL_TX_MONITOR_BUF] = {}, + [HAL_RXDMA_MONITOR_DST] = {}, + [HAL_TX_MONITOR_DST] = {} }; const struct ath12k_hw_regs wcn7850_regs = { From a7eb31e30369672cce3d60201fd4187846e85719 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Thu, 9 Oct 2025 16:40:44 +0530 Subject: [PATCH 066/140] wifi: ath12k: Rename hal_ops to ops Rename the hal_ops member in the HAL context to ops. The prefix is dropped to avoid redundancy, as the structure already resides within the HAL context. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-18-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 2 +- drivers/net/wireless/ath/ath12k/dp_rx.h | 16 +++--- drivers/net/wireless/ath/ath12k/hal.c | 50 +++++++++---------- drivers/net/wireless/ath/ath12k/hal.h | 2 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 2 +- drivers/net/wireless/ath/ath12k/wifi7/hal.c | 2 +- 6 files changed, 37 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 9a23575cfdb25..27cf53303bf82 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2082,7 +2082,7 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k_pdev_dp *dp_pdev, rx_desc = (struct hal_rx_desc *)head_msdu->data; hdr_desc = - ab->hal.hal_ops->rx_desc_get_msdu_payload(rx_desc); + ab->hal.ops->rx_desc_get_msdu_payload(rx_desc); /* Base size */ wh = (struct ieee80211_hdr_3addr *)hdr_desc; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 9b0ed9142a8be..1a97264f0328f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -122,27 +122,27 @@ static inline u16 ath12k_dp_rx_h_frag_no(struct ath12k_base *ab, static inline u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, struct hal_rx_desc *desc) { - return ab->hal.hal_ops->rx_desc_get_l3_pad_bytes(desc); + return ab->hal.ops->rx_desc_get_l3_pad_bytes(desc); } static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab, struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc) { - ab->hal.hal_ops->rx_desc_copy_end_tlv(fdesc, ldesc); + ab->hal.ops->rx_desc_copy_end_tlv(fdesc, ldesc); } static inline void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab, struct hal_rx_desc *desc, u16 len) { - ab->hal.hal_ops->rx_desc_set_msdu_len(desc, len); + ab->hal.ops->rx_desc_set_msdu_len(desc, len); } static inline u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc) { - return ab->hal.hal_ops->rx_desc_get_mpdu_ppdu_id(rx_desc); + return ab->hal.ops->rx_desc_get_mpdu_ppdu_id(rx_desc); } static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, @@ -150,7 +150,7 @@ static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, { u32 tlv_tag; - tlv_tag = ab->hal.hal_ops->rx_desc_get_mpdu_start_tag(rx_desc); + tlv_tag = ab->hal.ops->rx_desc_get_mpdu_start_tag(rx_desc); return tlv_tag == HAL_RX_MPDU_START; } @@ -159,7 +159,7 @@ static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab, struct hal_rx_desc *desc, struct ieee80211_hdr *hdr) { - ab->hal.hal_ops->rx_desc_get_dot11_hdr(desc, hdr); + ab->hal.ops->rx_desc_get_dot11_hdr(desc, hdr); } static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, @@ -167,13 +167,13 @@ static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, u8 *crypto_hdr, enum hal_encrypt_type enctype) { - ab->hal.hal_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); + ab->hal.ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); } static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab, struct hal_rx_desc *desc) { - return ab->hal.hal_ops->rx_desc_get_msdu_src_link_id(desc); + return ab->hal.ops->rx_desc_get_msdu_src_link_id(desc); } static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 296bd7824ae2d..3f9c2183c9a69 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -10,76 +10,76 @@ static void ath12k_hal_ce_dst_setup(struct ath12k_base *ab, struct hal_srng *srng, int ring_num) { - ab->hal.hal_ops->ce_dst_setup(ab, srng, ring_num); + ab->hal.ops->ce_dst_setup(ab, srng, ring_num); } static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, struct hal_srng *srng) { - ab->hal.hal_ops->srng_src_hw_init(ab, srng); + ab->hal.ops->srng_src_hw_init(ab, srng); } static void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab, struct hal_srng *srng) { - ab->hal.hal_ops->srng_dst_hw_init(ab, srng); + ab->hal.ops->srng_dst_hw_init(ab, srng); } static void ath12k_hal_set_umac_srng_ptr_addr(struct ath12k_base *ab, struct hal_srng *srng) { - ab->hal.hal_ops->set_umac_srng_ptr_addr(ab, srng); + ab->hal.ops->set_umac_srng_ptr_addr(ab, srng); } static int ath12k_hal_srng_get_ring_id(struct ath12k_hal *hal, enum hal_ring_type type, int ring_num, int mac_id) { - return hal->hal_ops->srng_get_ring_id(hal, type, ring_num, mac_id); + return hal->ops->srng_get_ring_id(hal, type, ring_num, mac_id); } int ath12k_hal_srng_update_shadow_config(struct ath12k_base *ab, enum hal_ring_type ring_type, int ring_num) { - return ab->hal.hal_ops->srng_update_shadow_config(ab, ring_type, + return ab->hal.ops->srng_update_shadow_config(ab, ring_type, ring_num); } u32 ath12k_hal_ce_get_desc_size(struct ath12k_hal *hal, enum hal_ce_desc type) { - return hal->hal_ops->ce_get_desc_size(type); + return hal->ops->ce_get_desc_size(type); } void ath12k_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id) { - ab->hal.hal_ops->tx_set_dscp_tid_map(ab, id); + ab->hal.ops->tx_set_dscp_tid_map(ab, id); } void ath12k_hal_tx_configure_bank_register(struct ath12k_base *ab, u32 bank_config, u8 bank_id) { - ab->hal.hal_ops->tx_configure_bank_register(ab, bank_config, bank_id); + ab->hal.ops->tx_configure_bank_register(ab, bank_config, bank_id); } void ath12k_hal_reoq_lut_addr_read_enable(struct ath12k_base *ab) { - ab->hal.hal_ops->reoq_lut_addr_read_enable(ab); + ab->hal.ops->reoq_lut_addr_read_enable(ab); } void ath12k_hal_reoq_lut_set_max_peerid(struct ath12k_base *ab) { - ab->hal.hal_ops->reoq_lut_set_max_peerid(ab); + ab->hal.ops->reoq_lut_set_max_peerid(ab); } void ath12k_hal_write_ml_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr) { - ab->hal.hal_ops->write_ml_reoq_lut_addr(ab, paddr); + ab->hal.ops->write_ml_reoq_lut_addr(ab, paddr); } void ath12k_hal_write_reoq_lut_addr(struct ath12k_base *ab, dma_addr_t paddr) { - ab->hal.hal_ops->write_reoq_lut_addr(ab, paddr); + ab->hal.ops->write_reoq_lut_addr(ab, paddr); } void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, @@ -87,25 +87,25 @@ void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, u32 nsbufs, u32 tot_link_desc, u32 end_offset) { - ab->hal.hal_ops->setup_link_idle_list(ab, sbuf, nsbufs, tot_link_desc, + ab->hal.ops->setup_link_idle_list(ab, sbuf, nsbufs, tot_link_desc, end_offset); } void ath12k_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) { - ab->hal.hal_ops->reo_hw_setup(ab, ring_hash_map); + ab->hal.ops->reo_hw_setup(ab, ring_hash_map); } void ath12k_hal_reo_init_cmd_ring(struct ath12k_base *ab, struct hal_srng *srng) { - ab->hal.hal_ops->reo_init_cmd_ring(ab, srng); + ab->hal.ops->reo_init_cmd_ring(ab, srng); } void ath12k_hal_rx_buf_addr_info_set(struct ath12k_hal *hal, struct ath12k_buffer_addr *binfo, dma_addr_t paddr, u32 cookie, u8 manager) { - hal->hal_ops->rx_buf_addr_info_set(binfo, paddr, cookie, manager); + hal->ops->rx_buf_addr_info_set(binfo, paddr, cookie, manager); } void ath12k_hal_rx_buf_addr_info_get(struct ath12k_hal *hal, @@ -113,18 +113,18 @@ void ath12k_hal_rx_buf_addr_info_get(struct ath12k_hal *hal, dma_addr_t *paddr, u32 *msdu_cookies, u8 *rbm) { - hal->hal_ops->rx_buf_addr_info_get(binfo, paddr, msdu_cookies, rbm); + hal->ops->rx_buf_addr_info_get(binfo, paddr, msdu_cookies, rbm); } void ath12k_hal_cc_config(struct ath12k_base *ab) { - ab->hal.hal_ops->cc_config(ab); + ab->hal.ops->cc_config(ab); } enum hal_rx_buf_return_buf_manager ath12k_hal_get_idle_link_rbm(struct ath12k_hal *hal, u8 device_id) { - return hal->hal_ops->get_idle_link_rbm(hal, device_id); + return hal->ops->get_idle_link_rbm(hal, device_id); } static int ath12k_hal_alloc_cont_rdp(struct ath12k_hal *hal) @@ -266,27 +266,27 @@ void ath12k_hal_ce_src_set_desc(struct ath12k_hal *hal, dma_addr_t paddr, u32 len, u32 id, u8 byte_swap_data) { - hal->hal_ops->ce_src_set_desc(desc, paddr, len, id, byte_swap_data); + hal->ops->ce_src_set_desc(desc, paddr, len, id, byte_swap_data); } void ath12k_hal_ce_dst_set_desc(struct ath12k_hal *hal, struct hal_ce_srng_dest_desc *desc, dma_addr_t paddr) { - hal->hal_ops->ce_dst_set_desc(desc, paddr); + hal->ops->ce_dst_set_desc(desc, paddr); } u32 ath12k_hal_ce_dst_status_get_length(struct ath12k_hal *hal, struct hal_ce_srng_dst_status_desc *desc) { - return hal->hal_ops->ce_dst_status_get_length(desc); + return hal->ops->ce_dst_status_get_length(desc); } void ath12k_hal_set_link_desc_addr(struct ath12k_hal *hal, struct hal_wbm_link_desc *desc, u32 cookie, dma_addr_t paddr, int rbm) { - hal->hal_ops->set_link_desc_addr(desc, cookie, paddr, rbm); + hal->ops->set_link_desc_addr(desc, cookie, paddr, rbm); } void *ath12k_hal_srng_dst_peek(struct ath12k_base *ab, struct hal_srng *srng) @@ -702,7 +702,7 @@ int ath12k_hal_srng_init(struct ath12k_base *ab) struct ath12k_hal *hal = &ab->hal; int ret; - ret = hal->hal_ops->create_srng_config(hal); + ret = hal->ops->create_srng_config(hal); if (ret) goto err_hal; diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 63ad67318b0e5..68c873a1f454c 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1135,7 +1135,7 @@ struct ath12k_hal { } wrp; struct device *dev; - const struct hal_ops *hal_ops; + const struct hal_ops *ops; const struct ath12k_hw_regs *regs; const struct ath12k_hw_hal_params *hal_params; /* Available REO blocking resources bitmap */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 5ecbbf548b056..df25164e08f24 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -53,6 +53,6 @@ void ath12k_wifi7_dp_extract_rx_desc_data(struct ath12k_base *ab, struct hal_rx_desc *rx_desc, struct hal_rx_desc *ldesc) { - ab->hal.hal_ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); + ab->hal.ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); } #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index e42970346e3dd..84c0ba2d1fbe9 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -50,7 +50,7 @@ int ath12k_wifi7_hal_init(struct ath12k_base *ab) memset(hal, 0, sizeof(*hal)); - hal->hal_ops = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_ops; + hal->ops = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_ops; hal->hal_desc_sz = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_desc_sz; hal->tcl_to_wbm_rbm_map = ath12k_wifi7_hw_ver_map[ab->hw_rev].tcl_to_wbm_rbm_map; hal->regs = ath12k_wifi7_hw_ver_map[ab->hw_rev].hw_regs; From 6572b03ac06644b8d6d440518df09a0d1988c631 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Thu, 9 Oct 2025 16:40:45 +0530 Subject: [PATCH 067/140] wifi: ath12k: Drop hal_ prefix from hardware register names Remove the hal_ prefix from hardware register names in ath12k_hw_regs as the registers have been moved from ab->regs to hal->regs. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251009111045.1763001-19-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.h | 142 +++---- drivers/net/wireless/ath/ath12k/wifi7/hal.h | 122 +++--- .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 360 +++++++++--------- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 122 +++--- 4 files changed, 373 insertions(+), 373 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 68c873a1f454c..dbf07c15481b8 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1032,81 +1032,81 @@ struct ath12k_hw_hal_params { }; struct ath12k_hw_regs { - u32 hal_tcl1_ring_id; - u32 hal_tcl1_ring_misc; - u32 hal_tcl1_ring_tp_addr_lsb; - u32 hal_tcl1_ring_tp_addr_msb; - u32 hal_tcl1_ring_consumer_int_setup_ix0; - u32 hal_tcl1_ring_consumer_int_setup_ix1; - u32 hal_tcl1_ring_msi1_base_lsb; - u32 hal_tcl1_ring_msi1_base_msb; - u32 hal_tcl1_ring_msi1_data; - u32 hal_tcl_ring_base_lsb; - u32 hal_tcl1_ring_base_lsb; - u32 hal_tcl1_ring_base_msb; - u32 hal_tcl2_ring_base_lsb; - - u32 hal_tcl_status_ring_base_lsb; - - u32 hal_reo1_qdesc_addr; - u32 hal_reo1_qdesc_max_peerid; - - u32 hal_wbm_idle_ring_base_lsb; - u32 hal_wbm_idle_ring_misc_addr; - u32 hal_wbm_r0_idle_list_cntl_addr; - u32 hal_wbm_r0_idle_list_size_addr; - u32 hal_wbm_scattered_ring_base_lsb; - u32 hal_wbm_scattered_ring_base_msb; - u32 hal_wbm_scattered_desc_head_info_ix0; - u32 hal_wbm_scattered_desc_head_info_ix1; - u32 hal_wbm_scattered_desc_tail_info_ix0; - u32 hal_wbm_scattered_desc_tail_info_ix1; - u32 hal_wbm_scattered_desc_ptr_hp_addr; - - u32 hal_wbm_sw_release_ring_base_lsb; - u32 hal_wbm_sw1_release_ring_base_lsb; - u32 hal_wbm0_release_ring_base_lsb; - u32 hal_wbm1_release_ring_base_lsb; + u32 tcl1_ring_id; + u32 tcl1_ring_misc; + u32 tcl1_ring_tp_addr_lsb; + u32 tcl1_ring_tp_addr_msb; + u32 tcl1_ring_consumer_int_setup_ix0; + u32 tcl1_ring_consumer_int_setup_ix1; + u32 tcl1_ring_msi1_base_lsb; + u32 tcl1_ring_msi1_base_msb; + u32 tcl1_ring_msi1_data; + u32 tcl_ring_base_lsb; + u32 tcl1_ring_base_lsb; + u32 tcl1_ring_base_msb; + u32 tcl2_ring_base_lsb; + + u32 tcl_status_ring_base_lsb; + + u32 reo1_qdesc_addr; + u32 reo1_qdesc_max_peerid; + + u32 wbm_idle_ring_base_lsb; + u32 wbm_idle_ring_misc_addr; + u32 wbm_r0_idle_list_cntl_addr; + u32 wbm_r0_idle_list_size_addr; + u32 wbm_scattered_ring_base_lsb; + u32 wbm_scattered_ring_base_msb; + u32 wbm_scattered_desc_head_info_ix0; + u32 wbm_scattered_desc_head_info_ix1; + u32 wbm_scattered_desc_tail_info_ix0; + u32 wbm_scattered_desc_tail_info_ix1; + u32 wbm_scattered_desc_ptr_hp_addr; + + u32 wbm_sw_release_ring_base_lsb; + u32 wbm_sw1_release_ring_base_lsb; + u32 wbm0_release_ring_base_lsb; + u32 wbm1_release_ring_base_lsb; u32 pcie_qserdes_sysclk_en_sel; u32 pcie_pcs_osc_dtct_config_base; - u32 hal_umac_ce0_src_reg_base; - u32 hal_umac_ce0_dest_reg_base; - u32 hal_umac_ce1_src_reg_base; - u32 hal_umac_ce1_dest_reg_base; - - u32 hal_ppe_rel_ring_base; - - u32 hal_reo2_ring_base; - u32 hal_reo1_misc_ctrl_addr; - u32 hal_reo1_sw_cookie_cfg0; - u32 hal_reo1_sw_cookie_cfg1; - u32 hal_reo1_qdesc_lut_base0; - u32 hal_reo1_qdesc_lut_base1; - u32 hal_reo1_ring_base_lsb; - u32 hal_reo1_ring_base_msb; - u32 hal_reo1_ring_id; - u32 hal_reo1_ring_misc; - u32 hal_reo1_ring_hp_addr_lsb; - u32 hal_reo1_ring_hp_addr_msb; - u32 hal_reo1_ring_producer_int_setup; - u32 hal_reo1_ring_msi1_base_lsb; - u32 hal_reo1_ring_msi1_base_msb; - u32 hal_reo1_ring_msi1_data; - u32 hal_reo1_aging_thres_ix0; - u32 hal_reo1_aging_thres_ix1; - u32 hal_reo1_aging_thres_ix2; - u32 hal_reo1_aging_thres_ix3; - - u32 hal_reo2_sw0_ring_base; - - u32 hal_sw2reo_ring_base; - u32 hal_sw2reo1_ring_base; - - u32 hal_reo_cmd_ring_base; - - u32 hal_reo_status_ring_base; + u32 umac_ce0_src_reg_base; + u32 umac_ce0_dest_reg_base; + u32 umac_ce1_src_reg_base; + u32 umac_ce1_dest_reg_base; + + u32 ppe_rel_ring_base; + + u32 reo2_ring_base; + u32 reo1_misc_ctrl_addr; + u32 reo1_sw_cookie_cfg0; + u32 reo1_sw_cookie_cfg1; + u32 reo1_qdesc_lut_base0; + u32 reo1_qdesc_lut_base1; + u32 reo1_ring_base_lsb; + u32 reo1_ring_base_msb; + u32 reo1_ring_id; + u32 reo1_ring_misc; + u32 reo1_ring_hp_addr_lsb; + u32 reo1_ring_hp_addr_msb; + u32 reo1_ring_producer_int_setup; + u32 reo1_ring_msi1_base_lsb; + u32 reo1_ring_msi1_base_msb; + u32 reo1_ring_msi1_data; + u32 reo1_aging_thres_ix0; + u32 reo1_aging_thres_ix1; + u32 reo1_aging_thres_ix2; + u32 reo1_aging_thres_ix3; + + u32 reo2_sw0_ring_base; + + u32 sw2reo_ring_base; + u32 sw2reo1_ring_base; + + u32 reo_cmd_ring_base; + + u32 reo_status_ring_base; u32 gcc_gcc_pcie_hot_rst; }; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index 8a40b91764065..0a39862d07c45 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -29,13 +29,13 @@ #define HAL_SEQ_WCSS_UMAC_REO_REG 0x00a38000 #define HAL_SEQ_WCSS_UMAC_TCL_REG 0x00a44000 #define HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(hal) \ - ((hal)->regs->hal_umac_ce0_src_reg_base) + ((hal)->regs->umac_ce0_src_reg_base) #define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) \ - ((hal)->regs->hal_umac_ce0_dest_reg_base) + ((hal)->regs->umac_ce0_dest_reg_base) #define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(hal) \ - ((hal)->regs->hal_umac_ce1_src_reg_base) + ((hal)->regs->umac_ce1_src_reg_base) #define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) \ - ((hal)->regs->hal_umac_ce1_dest_reg_base) + ((hal)->regs->umac_ce1_dest_reg_base) #define HAL_SEQ_WCSS_UMAC_WBM_REG 0x00a34000 #define HAL_CE_WFSS_CE_REG_BASE 0x01b80000 @@ -47,30 +47,30 @@ #define HAL_TCL1_RING_DSCP_TID_MAP 0x00000240 #define HAL_TCL1_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl1_ring_base_lsb) + ((hal)->regs->tcl1_ring_base_lsb) #define HAL_TCL1_RING_BASE_MSB(hal) \ - ((hal)->regs->hal_tcl1_ring_base_msb) -#define HAL_TCL1_RING_ID(hal) ((hal)->regs->hal_tcl1_ring_id) + ((hal)->regs->tcl1_ring_base_msb) +#define HAL_TCL1_RING_ID(hal) ((hal)->regs->tcl1_ring_id) #define HAL_TCL1_RING_MISC(hal) \ - ((hal)->regs->hal_tcl1_ring_misc) + ((hal)->regs->tcl1_ring_misc) #define HAL_TCL1_RING_TP_ADDR_LSB(hal) \ - ((hal)->regs->hal_tcl1_ring_tp_addr_lsb) + ((hal)->regs->tcl1_ring_tp_addr_lsb) #define HAL_TCL1_RING_TP_ADDR_MSB(hal) \ - ((hal)->regs->hal_tcl1_ring_tp_addr_msb) + ((hal)->regs->tcl1_ring_tp_addr_msb) #define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(hal) \ - ((hal)->regs->hal_tcl1_ring_consumer_int_setup_ix0) + ((hal)->regs->tcl1_ring_consumer_int_setup_ix0) #define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(hal) \ - ((hal)->regs->hal_tcl1_ring_consumer_int_setup_ix1) + ((hal)->regs->tcl1_ring_consumer_int_setup_ix1) #define HAL_TCL1_RING_MSI1_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl1_ring_msi1_base_lsb) + ((hal)->regs->tcl1_ring_msi1_base_lsb) #define HAL_TCL1_RING_MSI1_BASE_MSB(hal) \ - ((hal)->regs->hal_tcl1_ring_msi1_base_msb) + ((hal)->regs->tcl1_ring_msi1_base_msb) #define HAL_TCL1_RING_MSI1_DATA(hal) \ - ((hal)->regs->hal_tcl1_ring_msi1_data) + ((hal)->regs->tcl1_ring_msi1_data) #define HAL_TCL2_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl2_ring_base_lsb) + ((hal)->regs->tcl2_ring_base_lsb) #define HAL_TCL_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl_ring_base_lsb) + ((hal)->regs->tcl_ring_base_lsb) #define HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(hal) ({ typeof(hal) _hal = (hal); \ (HAL_TCL1_RING_MSI1_BASE_LSB(_hal) - HAL_TCL1_RING_BASE_LSB(_hal)); }) @@ -104,7 +104,7 @@ /* TCL STATUS ring address */ #define HAL_TCL_STATUS_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_tcl_status_ring_base_lsb) + ((hal)->regs->tcl_status_ring_base_lsb) #define HAL_TCL_STATUS_RING_HP 0x00002048 /* PPE2TCL1 Ring address */ @@ -113,41 +113,41 @@ /* WBM PPE Release Ring address */ #define HAL_WBM_PPE_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_ppe_rel_ring_base) + ((hal)->regs->ppe_rel_ring_base) #define HAL_WBM_PPE_RELEASE_RING_HP 0x00003020 /* REO2SW(x) R0 ring configuration address */ #define HAL_REO1_GEN_ENABLE 0x00000000 #define HAL_REO1_MISC_CTRL_ADDR(hal) \ - ((hal)->regs->hal_reo1_misc_ctrl_addr) + ((hal)->regs->reo1_misc_ctrl_addr) #define HAL_REO1_DEST_RING_CTRL_IX_0 0x00000004 #define HAL_REO1_DEST_RING_CTRL_IX_1 0x00000008 #define HAL_REO1_DEST_RING_CTRL_IX_2 0x0000000c #define HAL_REO1_DEST_RING_CTRL_IX_3 0x00000010 -#define HAL_REO1_QDESC_ADDR(hal) ((hal)->regs->hal_reo1_qdesc_addr) -#define HAL_REO1_QDESC_MAX_PEERID(hal) ((hal)->regs->hal_reo1_qdesc_max_peerid) -#define HAL_REO1_SW_COOKIE_CFG0(hal) ((hal)->regs->hal_reo1_sw_cookie_cfg0) -#define HAL_REO1_SW_COOKIE_CFG1(hal) ((hal)->regs->hal_reo1_sw_cookie_cfg1) -#define HAL_REO1_QDESC_LUT_BASE0(hal) ((hal)->regs->hal_reo1_qdesc_lut_base0) -#define HAL_REO1_QDESC_LUT_BASE1(hal) ((hal)->regs->hal_reo1_qdesc_lut_base1) -#define HAL_REO1_RING_BASE_LSB(hal) ((hal)->regs->hal_reo1_ring_base_lsb) -#define HAL_REO1_RING_BASE_MSB(hal) ((hal)->regs->hal_reo1_ring_base_msb) -#define HAL_REO1_RING_ID(hal) ((hal)->regs->hal_reo1_ring_id) -#define HAL_REO1_RING_MISC(hal) ((hal)->regs->hal_reo1_ring_misc) -#define HAL_REO1_RING_HP_ADDR_LSB(hal) ((hal)->regs->hal_reo1_ring_hp_addr_lsb) -#define HAL_REO1_RING_HP_ADDR_MSB(hal) ((hal)->regs->hal_reo1_ring_hp_addr_msb) +#define HAL_REO1_QDESC_ADDR(hal) ((hal)->regs->reo1_qdesc_addr) +#define HAL_REO1_QDESC_MAX_PEERID(hal) ((hal)->regs->reo1_qdesc_max_peerid) +#define HAL_REO1_SW_COOKIE_CFG0(hal) ((hal)->regs->reo1_sw_cookie_cfg0) +#define HAL_REO1_SW_COOKIE_CFG1(hal) ((hal)->regs->reo1_sw_cookie_cfg1) +#define HAL_REO1_QDESC_LUT_BASE0(hal) ((hal)->regs->reo1_qdesc_lut_base0) +#define HAL_REO1_QDESC_LUT_BASE1(hal) ((hal)->regs->reo1_qdesc_lut_base1) +#define HAL_REO1_RING_BASE_LSB(hal) ((hal)->regs->reo1_ring_base_lsb) +#define HAL_REO1_RING_BASE_MSB(hal) ((hal)->regs->reo1_ring_base_msb) +#define HAL_REO1_RING_ID(hal) ((hal)->regs->reo1_ring_id) +#define HAL_REO1_RING_MISC(hal) ((hal)->regs->reo1_ring_misc) +#define HAL_REO1_RING_HP_ADDR_LSB(hal) ((hal)->regs->reo1_ring_hp_addr_lsb) +#define HAL_REO1_RING_HP_ADDR_MSB(hal) ((hal)->regs->reo1_ring_hp_addr_msb) #define HAL_REO1_RING_PRODUCER_INT_SETUP(hal) \ - ((hal)->regs->hal_reo1_ring_producer_int_setup) + ((hal)->regs->reo1_ring_producer_int_setup) #define HAL_REO1_RING_MSI1_BASE_LSB(hal) \ - ((hal)->regs->hal_reo1_ring_msi1_base_lsb) + ((hal)->regs->reo1_ring_msi1_base_lsb) #define HAL_REO1_RING_MSI1_BASE_MSB(hal) \ - ((hal)->regs->hal_reo1_ring_msi1_base_msb) -#define HAL_REO1_RING_MSI1_DATA(hal) ((hal)->regs->hal_reo1_ring_msi1_data) -#define HAL_REO2_RING_BASE_LSB(hal) ((hal)->regs->hal_reo2_ring_base) -#define HAL_REO1_AGING_THRESH_IX_0(hal) ((hal)->regs->hal_reo1_aging_thres_ix0) -#define HAL_REO1_AGING_THRESH_IX_1(hal) ((hal)->regs->hal_reo1_aging_thres_ix1) -#define HAL_REO1_AGING_THRESH_IX_2(hal) ((hal)->regs->hal_reo1_aging_thres_ix2) -#define HAL_REO1_AGING_THRESH_IX_3(hal) ((hal)->regs->hal_reo1_aging_thres_ix3) + ((hal)->regs->reo1_ring_msi1_base_msb) +#define HAL_REO1_RING_MSI1_DATA(hal) ((hal)->regs->reo1_ring_msi1_data) +#define HAL_REO2_RING_BASE_LSB(hal) ((hal)->regs->reo2_ring_base) +#define HAL_REO1_AGING_THRESH_IX_0(hal) ((hal)->regs->reo1_aging_thres_ix0) +#define HAL_REO1_AGING_THRESH_IX_1(hal) ((hal)->regs->reo1_aging_thres_ix1) +#define HAL_REO1_AGING_THRESH_IX_2(hal) ((hal)->regs->reo1_aging_thres_ix2) +#define HAL_REO1_AGING_THRESH_IX_3(hal) ((hal)->regs->reo1_aging_thres_ix3) /* REO2SW(x) R2 ring pointers (head/tail) address */ #define HAL_REO1_RING_HP 0x00003048 @@ -158,23 +158,23 @@ /* REO2SW0 ring configuration address */ #define HAL_REO_SW0_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_reo2_sw0_ring_base) + ((hal)->regs->reo2_sw0_ring_base) /* REO2SW0 R2 ring pointer (head/tail) address */ #define HAL_REO_SW0_RING_HP 0x00003088 /* REO CMD R0 address */ #define HAL_REO_CMD_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_reo_cmd_ring_base) + ((hal)->regs->reo_cmd_ring_base) /* REO CMD R2 address */ #define HAL_REO_CMD_HP 0x00003020 /* SW2REO R0 address */ #define HAL_SW2REO_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_sw2reo_ring_base) + ((hal)->regs->sw2reo_ring_base) #define HAL_SW2REO1_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_sw2reo1_ring_base) + ((hal)->regs->sw2reo1_ring_base) /* SW2REO R2 address */ #define HAL_SW2REO_RING_HP 0x00003028 @@ -192,41 +192,41 @@ /* REO status address */ #define HAL_REO_STATUS_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_reo_status_ring_base) + ((hal)->regs->reo_status_ring_base) #define HAL_REO_STATUS_HP 0x000030a8 /* WBM Idle R0 address */ #define HAL_WBM_IDLE_LINK_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm_idle_ring_base_lsb) + ((hal)->regs->wbm_idle_ring_base_lsb) #define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(hal) \ - ((hal)->regs->hal_wbm_idle_ring_misc_addr) + ((hal)->regs->wbm_idle_ring_misc_addr) #define HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(hal) \ - ((hal)->regs->hal_wbm_r0_idle_list_cntl_addr) + ((hal)->regs->wbm_r0_idle_list_cntl_addr) #define HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(hal) \ - ((hal)->regs->hal_wbm_r0_idle_list_size_addr) + ((hal)->regs->wbm_r0_idle_list_size_addr) #define HAL_WBM_SCATTERED_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm_scattered_ring_base_lsb) + ((hal)->regs->wbm_scattered_ring_base_lsb) #define HAL_WBM_SCATTERED_RING_BASE_MSB(hal) \ - ((hal)->regs->hal_wbm_scattered_ring_base_msb) + ((hal)->regs->wbm_scattered_ring_base_msb) #define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_head_info_ix0) + ((hal)->regs->wbm_scattered_desc_head_info_ix0) #define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_head_info_ix1) + ((hal)->regs->wbm_scattered_desc_head_info_ix1) #define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_tail_info_ix0) + ((hal)->regs->wbm_scattered_desc_tail_info_ix0) #define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_tail_info_ix1) + ((hal)->regs->wbm_scattered_desc_tail_info_ix1) #define HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(hal) \ - ((hal)->regs->hal_wbm_scattered_desc_ptr_hp_addr) + ((hal)->regs->wbm_scattered_desc_ptr_hp_addr) /* WBM Idle R2 address */ #define HAL_WBM_IDLE_LINK_RING_HP 0x000030b8 /* SW2WBM R0 release address */ #define HAL_WBM_SW_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm_sw_release_ring_base_lsb) + ((hal)->regs->wbm_sw_release_ring_base_lsb) #define HAL_WBM_SW1_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm_sw1_release_ring_base_lsb) + ((hal)->regs->wbm_sw1_release_ring_base_lsb) /* SW2WBM R2 release address */ #define HAL_WBM_SW_RELEASE_RING_HP 0x00003010 @@ -234,10 +234,10 @@ /* WBM2SW R0 release address */ #define HAL_WBM0_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm0_release_ring_base_lsb) + ((hal)->regs->wbm0_release_ring_base_lsb) #define HAL_WBM1_RELEASE_RING_BASE_LSB(hal) \ - ((hal)->regs->hal_wbm1_release_ring_base_lsb) + ((hal)->regs->wbm1_release_ring_base_lsb) /* WBM2SW R2 release address */ #define HAL_WBM0_RELEASE_RING_HP 0x000030c8 diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 2dc4f1539d684..3ccd689bbf1ca 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -214,269 +214,269 @@ static const struct hal_srng_config hw_srng_config_template[] = { const struct ath12k_hw_regs qcn9274_v1_regs = { /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_id = 0x00000908, - .hal_tcl1_ring_misc = 0x00000910, - .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, - .hal_tcl1_ring_tp_addr_msb = 0x00000920, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, - .hal_tcl1_ring_msi1_base_lsb = 0x00000948, - .hal_tcl1_ring_msi1_base_msb = 0x0000094c, - .hal_tcl1_ring_msi1_data = 0x00000950, - .hal_tcl_ring_base_lsb = 0x00000b58, - .hal_tcl1_ring_base_lsb = 0x00000900, - .hal_tcl1_ring_base_msb = 0x00000904, - .hal_tcl2_ring_base_lsb = 0x00000978, + .tcl1_ring_id = 0x00000908, + .tcl1_ring_misc = 0x00000910, + .tcl1_ring_tp_addr_lsb = 0x0000091c, + .tcl1_ring_tp_addr_msb = 0x00000920, + .tcl1_ring_consumer_int_setup_ix0 = 0x00000930, + .tcl1_ring_consumer_int_setup_ix1 = 0x00000934, + .tcl1_ring_msi1_base_lsb = 0x00000948, + .tcl1_ring_msi1_base_msb = 0x0000094c, + .tcl1_ring_msi1_data = 0x00000950, + .tcl_ring_base_lsb = 0x00000b58, + .tcl1_ring_base_lsb = 0x00000900, + .tcl1_ring_base_msb = 0x00000904, + .tcl2_ring_base_lsb = 0x00000978, /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000d38, - - .hal_wbm_idle_ring_base_lsb = 0x00000d0c, - .hal_wbm_idle_ring_misc_addr = 0x00000d1c, - .hal_wbm_r0_idle_list_cntl_addr = 0x00000210, - .hal_wbm_r0_idle_list_size_addr = 0x00000214, - .hal_wbm_scattered_ring_base_lsb = 0x00000220, - .hal_wbm_scattered_ring_base_msb = 0x00000224, - .hal_wbm_scattered_desc_head_info_ix0 = 0x00000230, - .hal_wbm_scattered_desc_head_info_ix1 = 0x00000234, - .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000240, - .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000244, - .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000024c, - - .hal_wbm_sw_release_ring_base_lsb = 0x0000034c, - .hal_wbm_sw1_release_ring_base_lsb = 0x000003c4, - .hal_wbm0_release_ring_base_lsb = 0x00000dd8, - .hal_wbm1_release_ring_base_lsb = 0x00000e50, + .tcl_status_ring_base_lsb = 0x00000d38, + + .wbm_idle_ring_base_lsb = 0x00000d0c, + .wbm_idle_ring_misc_addr = 0x00000d1c, + .wbm_r0_idle_list_cntl_addr = 0x00000210, + .wbm_r0_idle_list_size_addr = 0x00000214, + .wbm_scattered_ring_base_lsb = 0x00000220, + .wbm_scattered_ring_base_msb = 0x00000224, + .wbm_scattered_desc_head_info_ix0 = 0x00000230, + .wbm_scattered_desc_head_info_ix1 = 0x00000234, + .wbm_scattered_desc_tail_info_ix0 = 0x00000240, + .wbm_scattered_desc_tail_info_ix1 = 0x00000244, + .wbm_scattered_desc_ptr_hp_addr = 0x0000024c, + + .wbm_sw_release_ring_base_lsb = 0x0000034c, + .wbm_sw1_release_ring_base_lsb = 0x000003c4, + .wbm0_release_ring_base_lsb = 0x00000dd8, + .wbm1_release_ring_base_lsb = 0x00000e50, /* PCIe base address */ .pcie_qserdes_sysclk_en_sel = 0x01e0c0a8, .pcie_pcs_osc_dtct_config_base = 0x01e0d45c, /* PPE release ring address */ - .hal_ppe_rel_ring_base = 0x0000043c, + .ppe_rel_ring_base = 0x0000043c, /* REO DEST ring address */ - .hal_reo2_ring_base = 0x0000055c, - .hal_reo1_misc_ctrl_addr = 0x00000b7c, - .hal_reo1_sw_cookie_cfg0 = 0x00000050, - .hal_reo1_sw_cookie_cfg1 = 0x00000054, - .hal_reo1_qdesc_lut_base0 = 0x00000058, - .hal_reo1_qdesc_lut_base1 = 0x0000005c, - .hal_reo1_ring_base_lsb = 0x000004e4, - .hal_reo1_ring_base_msb = 0x000004e8, - .hal_reo1_ring_id = 0x000004ec, - .hal_reo1_ring_misc = 0x000004f4, - .hal_reo1_ring_hp_addr_lsb = 0x000004f8, - .hal_reo1_ring_hp_addr_msb = 0x000004fc, - .hal_reo1_ring_producer_int_setup = 0x00000508, - .hal_reo1_ring_msi1_base_lsb = 0x0000052C, - .hal_reo1_ring_msi1_base_msb = 0x00000530, - .hal_reo1_ring_msi1_data = 0x00000534, - .hal_reo1_aging_thres_ix0 = 0x00000b08, - .hal_reo1_aging_thres_ix1 = 0x00000b0c, - .hal_reo1_aging_thres_ix2 = 0x00000b10, - .hal_reo1_aging_thres_ix3 = 0x00000b14, + .reo2_ring_base = 0x0000055c, + .reo1_misc_ctrl_addr = 0x00000b7c, + .reo1_sw_cookie_cfg0 = 0x00000050, + .reo1_sw_cookie_cfg1 = 0x00000054, + .reo1_qdesc_lut_base0 = 0x00000058, + .reo1_qdesc_lut_base1 = 0x0000005c, + .reo1_ring_base_lsb = 0x000004e4, + .reo1_ring_base_msb = 0x000004e8, + .reo1_ring_id = 0x000004ec, + .reo1_ring_misc = 0x000004f4, + .reo1_ring_hp_addr_lsb = 0x000004f8, + .reo1_ring_hp_addr_msb = 0x000004fc, + .reo1_ring_producer_int_setup = 0x00000508, + .reo1_ring_msi1_base_lsb = 0x0000052C, + .reo1_ring_msi1_base_msb = 0x00000530, + .reo1_ring_msi1_data = 0x00000534, + .reo1_aging_thres_ix0 = 0x00000b08, + .reo1_aging_thres_ix1 = 0x00000b0c, + .reo1_aging_thres_ix2 = 0x00000b10, + .reo1_aging_thres_ix3 = 0x00000b14, /* REO Exception ring address */ - .hal_reo2_sw0_ring_base = 0x000008a4, + .reo2_sw0_ring_base = 0x000008a4, /* REO Reinject ring address */ - .hal_sw2reo_ring_base = 0x00000304, - .hal_sw2reo1_ring_base = 0x0000037c, + .sw2reo_ring_base = 0x00000304, + .sw2reo1_ring_base = 0x0000037c, /* REO cmd ring address */ - .hal_reo_cmd_ring_base = 0x0000028c, + .reo_cmd_ring_base = 0x0000028c, /* REO status ring address */ - .hal_reo_status_ring_base = 0x00000a84, + .reo_status_ring_base = 0x00000a84, /* CE base address */ - .hal_umac_ce0_src_reg_base = 0x01b80000, - .hal_umac_ce0_dest_reg_base = 0x01b81000, - .hal_umac_ce1_src_reg_base = 0x01b82000, - .hal_umac_ce1_dest_reg_base = 0x01b83000, + .umac_ce0_src_reg_base = 0x01b80000, + .umac_ce0_dest_reg_base = 0x01b81000, + .umac_ce1_src_reg_base = 0x01b82000, + .umac_ce1_dest_reg_base = 0x01b83000, .gcc_gcc_pcie_hot_rst = 0x1e38338, }; const struct ath12k_hw_regs qcn9274_v2_regs = { /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_id = 0x00000908, - .hal_tcl1_ring_misc = 0x00000910, - .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, - .hal_tcl1_ring_tp_addr_msb = 0x00000920, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, - .hal_tcl1_ring_msi1_base_lsb = 0x00000948, - .hal_tcl1_ring_msi1_base_msb = 0x0000094c, - .hal_tcl1_ring_msi1_data = 0x00000950, - .hal_tcl_ring_base_lsb = 0x00000b58, - .hal_tcl1_ring_base_lsb = 0x00000900, - .hal_tcl1_ring_base_msb = 0x00000904, - .hal_tcl2_ring_base_lsb = 0x00000978, + .tcl1_ring_id = 0x00000908, + .tcl1_ring_misc = 0x00000910, + .tcl1_ring_tp_addr_lsb = 0x0000091c, + .tcl1_ring_tp_addr_msb = 0x00000920, + .tcl1_ring_consumer_int_setup_ix0 = 0x00000930, + .tcl1_ring_consumer_int_setup_ix1 = 0x00000934, + .tcl1_ring_msi1_base_lsb = 0x00000948, + .tcl1_ring_msi1_base_msb = 0x0000094c, + .tcl1_ring_msi1_data = 0x00000950, + .tcl_ring_base_lsb = 0x00000b58, + .tcl1_ring_base_lsb = 0x00000900, + .tcl1_ring_base_msb = 0x00000904, + .tcl2_ring_base_lsb = 0x00000978, /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000d38, + .tcl_status_ring_base_lsb = 0x00000d38, /* WBM idle link ring address */ - .hal_wbm_idle_ring_base_lsb = 0x00000d3c, - .hal_wbm_idle_ring_misc_addr = 0x00000d4c, - .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, - .hal_wbm_r0_idle_list_size_addr = 0x00000244, - .hal_wbm_scattered_ring_base_lsb = 0x00000250, - .hal_wbm_scattered_ring_base_msb = 0x00000254, - .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, - .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, - .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, - .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, - .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000027c, + .wbm_idle_ring_base_lsb = 0x00000d3c, + .wbm_idle_ring_misc_addr = 0x00000d4c, + .wbm_r0_idle_list_cntl_addr = 0x00000240, + .wbm_r0_idle_list_size_addr = 0x00000244, + .wbm_scattered_ring_base_lsb = 0x00000250, + .wbm_scattered_ring_base_msb = 0x00000254, + .wbm_scattered_desc_head_info_ix0 = 0x00000260, + .wbm_scattered_desc_head_info_ix1 = 0x00000264, + .wbm_scattered_desc_tail_info_ix0 = 0x00000270, + .wbm_scattered_desc_tail_info_ix1 = 0x00000274, + .wbm_scattered_desc_ptr_hp_addr = 0x0000027c, /* SW2WBM release ring address */ - .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, - .hal_wbm_sw1_release_ring_base_lsb = 0x000003f4, + .wbm_sw_release_ring_base_lsb = 0x0000037c, + .wbm_sw1_release_ring_base_lsb = 0x000003f4, /* WBM2SW release ring address */ - .hal_wbm0_release_ring_base_lsb = 0x00000e08, - .hal_wbm1_release_ring_base_lsb = 0x00000e80, + .wbm0_release_ring_base_lsb = 0x00000e08, + .wbm1_release_ring_base_lsb = 0x00000e80, /* PCIe base address */ .pcie_qserdes_sysclk_en_sel = 0x01e0c0a8, .pcie_pcs_osc_dtct_config_base = 0x01e0d45c, /* PPE release ring address */ - .hal_ppe_rel_ring_base = 0x0000046c, + .ppe_rel_ring_base = 0x0000046c, /* REO DEST ring address */ - .hal_reo2_ring_base = 0x00000578, - .hal_reo1_misc_ctrl_addr = 0x00000b9c, - .hal_reo1_sw_cookie_cfg0 = 0x0000006c, - .hal_reo1_sw_cookie_cfg1 = 0x00000070, - .hal_reo1_qdesc_lut_base0 = 0x00000074, - .hal_reo1_qdesc_lut_base1 = 0x00000078, - .hal_reo1_qdesc_addr = 0x0000007c, - .hal_reo1_qdesc_max_peerid = 0x00000088, - .hal_reo1_ring_base_lsb = 0x00000500, - .hal_reo1_ring_base_msb = 0x00000504, - .hal_reo1_ring_id = 0x00000508, - .hal_reo1_ring_misc = 0x00000510, - .hal_reo1_ring_hp_addr_lsb = 0x00000514, - .hal_reo1_ring_hp_addr_msb = 0x00000518, - .hal_reo1_ring_producer_int_setup = 0x00000524, - .hal_reo1_ring_msi1_base_lsb = 0x00000548, - .hal_reo1_ring_msi1_base_msb = 0x0000054C, - .hal_reo1_ring_msi1_data = 0x00000550, - .hal_reo1_aging_thres_ix0 = 0x00000B28, - .hal_reo1_aging_thres_ix1 = 0x00000B2C, - .hal_reo1_aging_thres_ix2 = 0x00000B30, - .hal_reo1_aging_thres_ix3 = 0x00000B34, + .reo2_ring_base = 0x00000578, + .reo1_misc_ctrl_addr = 0x00000b9c, + .reo1_sw_cookie_cfg0 = 0x0000006c, + .reo1_sw_cookie_cfg1 = 0x00000070, + .reo1_qdesc_lut_base0 = 0x00000074, + .reo1_qdesc_lut_base1 = 0x00000078, + .reo1_qdesc_addr = 0x0000007c, + .reo1_qdesc_max_peerid = 0x00000088, + .reo1_ring_base_lsb = 0x00000500, + .reo1_ring_base_msb = 0x00000504, + .reo1_ring_id = 0x00000508, + .reo1_ring_misc = 0x00000510, + .reo1_ring_hp_addr_lsb = 0x00000514, + .reo1_ring_hp_addr_msb = 0x00000518, + .reo1_ring_producer_int_setup = 0x00000524, + .reo1_ring_msi1_base_lsb = 0x00000548, + .reo1_ring_msi1_base_msb = 0x0000054C, + .reo1_ring_msi1_data = 0x00000550, + .reo1_aging_thres_ix0 = 0x00000B28, + .reo1_aging_thres_ix1 = 0x00000B2C, + .reo1_aging_thres_ix2 = 0x00000B30, + .reo1_aging_thres_ix3 = 0x00000B34, /* REO Exception ring address */ - .hal_reo2_sw0_ring_base = 0x000008c0, + .reo2_sw0_ring_base = 0x000008c0, /* REO Reinject ring address */ - .hal_sw2reo_ring_base = 0x00000320, - .hal_sw2reo1_ring_base = 0x00000398, + .sw2reo_ring_base = 0x00000320, + .sw2reo1_ring_base = 0x00000398, /* REO cmd ring address */ - .hal_reo_cmd_ring_base = 0x000002A8, + .reo_cmd_ring_base = 0x000002A8, /* REO status ring address */ - .hal_reo_status_ring_base = 0x00000aa0, + .reo_status_ring_base = 0x00000aa0, /* CE base address */ - .hal_umac_ce0_src_reg_base = 0x01b80000, - .hal_umac_ce0_dest_reg_base = 0x01b81000, - .hal_umac_ce1_src_reg_base = 0x01b82000, - .hal_umac_ce1_dest_reg_base = 0x01b83000, + .umac_ce0_src_reg_base = 0x01b80000, + .umac_ce0_dest_reg_base = 0x01b81000, + .umac_ce1_src_reg_base = 0x01b82000, + .umac_ce1_dest_reg_base = 0x01b83000, .gcc_gcc_pcie_hot_rst = 0x1e38338, }; const struct ath12k_hw_regs ipq5332_regs = { /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_id = 0x00000918, - .hal_tcl1_ring_misc = 0x00000920, - .hal_tcl1_ring_tp_addr_lsb = 0x0000092c, - .hal_tcl1_ring_tp_addr_msb = 0x00000930, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000940, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000944, - .hal_tcl1_ring_msi1_base_lsb = 0x00000958, - .hal_tcl1_ring_msi1_base_msb = 0x0000095c, - .hal_tcl1_ring_base_lsb = 0x00000910, - .hal_tcl1_ring_base_msb = 0x00000914, - .hal_tcl1_ring_msi1_data = 0x00000960, - .hal_tcl2_ring_base_lsb = 0x00000988, - .hal_tcl_ring_base_lsb = 0x00000b68, + .tcl1_ring_id = 0x00000918, + .tcl1_ring_misc = 0x00000920, + .tcl1_ring_tp_addr_lsb = 0x0000092c, + .tcl1_ring_tp_addr_msb = 0x00000930, + .tcl1_ring_consumer_int_setup_ix0 = 0x00000940, + .tcl1_ring_consumer_int_setup_ix1 = 0x00000944, + .tcl1_ring_msi1_base_lsb = 0x00000958, + .tcl1_ring_msi1_base_msb = 0x0000095c, + .tcl1_ring_base_lsb = 0x00000910, + .tcl1_ring_base_msb = 0x00000914, + .tcl1_ring_msi1_data = 0x00000960, + .tcl2_ring_base_lsb = 0x00000988, + .tcl_ring_base_lsb = 0x00000b68, /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000d48, + .tcl_status_ring_base_lsb = 0x00000d48, /* REO DEST ring address */ - .hal_reo2_ring_base = 0x00000578, - .hal_reo1_misc_ctrl_addr = 0x00000b9c, - .hal_reo1_sw_cookie_cfg0 = 0x0000006c, - .hal_reo1_sw_cookie_cfg1 = 0x00000070, - .hal_reo1_qdesc_lut_base0 = 0x00000074, - .hal_reo1_qdesc_lut_base1 = 0x00000078, - .hal_reo1_ring_base_lsb = 0x00000500, - .hal_reo1_ring_base_msb = 0x00000504, - .hal_reo1_ring_id = 0x00000508, - .hal_reo1_ring_misc = 0x00000510, - .hal_reo1_ring_hp_addr_lsb = 0x00000514, - .hal_reo1_ring_hp_addr_msb = 0x00000518, - .hal_reo1_ring_producer_int_setup = 0x00000524, - .hal_reo1_ring_msi1_base_lsb = 0x00000548, - .hal_reo1_ring_msi1_base_msb = 0x0000054C, - .hal_reo1_ring_msi1_data = 0x00000550, - .hal_reo1_aging_thres_ix0 = 0x00000B28, - .hal_reo1_aging_thres_ix1 = 0x00000B2C, - .hal_reo1_aging_thres_ix2 = 0x00000B30, - .hal_reo1_aging_thres_ix3 = 0x00000B34, + .reo2_ring_base = 0x00000578, + .reo1_misc_ctrl_addr = 0x00000b9c, + .reo1_sw_cookie_cfg0 = 0x0000006c, + .reo1_sw_cookie_cfg1 = 0x00000070, + .reo1_qdesc_lut_base0 = 0x00000074, + .reo1_qdesc_lut_base1 = 0x00000078, + .reo1_ring_base_lsb = 0x00000500, + .reo1_ring_base_msb = 0x00000504, + .reo1_ring_id = 0x00000508, + .reo1_ring_misc = 0x00000510, + .reo1_ring_hp_addr_lsb = 0x00000514, + .reo1_ring_hp_addr_msb = 0x00000518, + .reo1_ring_producer_int_setup = 0x00000524, + .reo1_ring_msi1_base_lsb = 0x00000548, + .reo1_ring_msi1_base_msb = 0x0000054C, + .reo1_ring_msi1_data = 0x00000550, + .reo1_aging_thres_ix0 = 0x00000B28, + .reo1_aging_thres_ix1 = 0x00000B2C, + .reo1_aging_thres_ix2 = 0x00000B30, + .reo1_aging_thres_ix3 = 0x00000B34, /* REO Exception ring address */ - .hal_reo2_sw0_ring_base = 0x000008c0, + .reo2_sw0_ring_base = 0x000008c0, /* REO Reinject ring address */ - .hal_sw2reo_ring_base = 0x00000320, - .hal_sw2reo1_ring_base = 0x00000398, + .sw2reo_ring_base = 0x00000320, + .sw2reo1_ring_base = 0x00000398, /* REO cmd ring address */ - .hal_reo_cmd_ring_base = 0x000002A8, + .reo_cmd_ring_base = 0x000002A8, /* REO status ring address */ - .hal_reo_status_ring_base = 0x00000aa0, + .reo_status_ring_base = 0x00000aa0, /* WBM idle link ring address */ - .hal_wbm_idle_ring_base_lsb = 0x00000d3c, - .hal_wbm_idle_ring_misc_addr = 0x00000d4c, - .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, - .hal_wbm_r0_idle_list_size_addr = 0x00000244, - .hal_wbm_scattered_ring_base_lsb = 0x00000250, - .hal_wbm_scattered_ring_base_msb = 0x00000254, - .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, - .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, - .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, - .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, - .hal_wbm_scattered_desc_ptr_hp_addr = 0x0000027c, + .wbm_idle_ring_base_lsb = 0x00000d3c, + .wbm_idle_ring_misc_addr = 0x00000d4c, + .wbm_r0_idle_list_cntl_addr = 0x00000240, + .wbm_r0_idle_list_size_addr = 0x00000244, + .wbm_scattered_ring_base_lsb = 0x00000250, + .wbm_scattered_ring_base_msb = 0x00000254, + .wbm_scattered_desc_head_info_ix0 = 0x00000260, + .wbm_scattered_desc_head_info_ix1 = 0x00000264, + .wbm_scattered_desc_tail_info_ix0 = 0x00000270, + .wbm_scattered_desc_tail_info_ix1 = 0x00000274, + .wbm_scattered_desc_ptr_hp_addr = 0x0000027c, /* SW2WBM release ring address */ - .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, + .wbm_sw_release_ring_base_lsb = 0x0000037c, /* WBM2SW release ring address */ - .hal_wbm0_release_ring_base_lsb = 0x00000e08, - .hal_wbm1_release_ring_base_lsb = 0x00000e80, + .wbm0_release_ring_base_lsb = 0x00000e08, + .wbm1_release_ring_base_lsb = 0x00000e80, /* PPE release ring address */ - .hal_ppe_rel_ring_base = 0x0000046c, + .ppe_rel_ring_base = 0x0000046c, /* CE address */ - .hal_umac_ce0_src_reg_base = 0x00740000 - + .umac_ce0_src_reg_base = 0x00740000 - HAL_IPQ5332_CE_WFSS_REG_BASE, - .hal_umac_ce0_dest_reg_base = 0x00741000 - + .umac_ce0_dest_reg_base = 0x00741000 - HAL_IPQ5332_CE_WFSS_REG_BASE, - .hal_umac_ce1_src_reg_base = 0x00742000 - + .umac_ce1_src_reg_base = 0x00742000 - HAL_IPQ5332_CE_WFSS_REG_BASE, - .hal_umac_ce1_dest_reg_base = 0x00743000 - + .umac_ce1_dest_reg_base = 0x00743000 - HAL_IPQ5332_CE_WFSS_REG_BASE, }; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 8151c216a5e1b..8966de3d64a41 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -173,87 +173,87 @@ static const struct hal_srng_config hw_srng_config_template[] = { const struct ath12k_hw_regs wcn7850_regs = { /* SW2TCL(x) R0 ring configuration address */ - .hal_tcl1_ring_id = 0x00000908, - .hal_tcl1_ring_misc = 0x00000910, - .hal_tcl1_ring_tp_addr_lsb = 0x0000091c, - .hal_tcl1_ring_tp_addr_msb = 0x00000920, - .hal_tcl1_ring_consumer_int_setup_ix0 = 0x00000930, - .hal_tcl1_ring_consumer_int_setup_ix1 = 0x00000934, - .hal_tcl1_ring_msi1_base_lsb = 0x00000948, - .hal_tcl1_ring_msi1_base_msb = 0x0000094c, - .hal_tcl1_ring_msi1_data = 0x00000950, - .hal_tcl_ring_base_lsb = 0x00000b58, - .hal_tcl1_ring_base_lsb = 0x00000900, - .hal_tcl1_ring_base_msb = 0x00000904, - .hal_tcl2_ring_base_lsb = 0x00000978, + .tcl1_ring_id = 0x00000908, + .tcl1_ring_misc = 0x00000910, + .tcl1_ring_tp_addr_lsb = 0x0000091c, + .tcl1_ring_tp_addr_msb = 0x00000920, + .tcl1_ring_consumer_int_setup_ix0 = 0x00000930, + .tcl1_ring_consumer_int_setup_ix1 = 0x00000934, + .tcl1_ring_msi1_base_lsb = 0x00000948, + .tcl1_ring_msi1_base_msb = 0x0000094c, + .tcl1_ring_msi1_data = 0x00000950, + .tcl_ring_base_lsb = 0x00000b58, + .tcl1_ring_base_lsb = 0x00000900, + .tcl1_ring_base_msb = 0x00000904, + .tcl2_ring_base_lsb = 0x00000978, /* TCL STATUS ring address */ - .hal_tcl_status_ring_base_lsb = 0x00000d38, - - .hal_wbm_idle_ring_base_lsb = 0x00000d3c, - .hal_wbm_idle_ring_misc_addr = 0x00000d4c, - .hal_wbm_r0_idle_list_cntl_addr = 0x00000240, - .hal_wbm_r0_idle_list_size_addr = 0x00000244, - .hal_wbm_scattered_ring_base_lsb = 0x00000250, - .hal_wbm_scattered_ring_base_msb = 0x00000254, - .hal_wbm_scattered_desc_head_info_ix0 = 0x00000260, - .hal_wbm_scattered_desc_head_info_ix1 = 0x00000264, - .hal_wbm_scattered_desc_tail_info_ix0 = 0x00000270, - .hal_wbm_scattered_desc_tail_info_ix1 = 0x00000274, - .hal_wbm_scattered_desc_ptr_hp_addr = 0x00000027c, - - .hal_wbm_sw_release_ring_base_lsb = 0x0000037c, - .hal_wbm_sw1_release_ring_base_lsb = 0x00000284, - .hal_wbm0_release_ring_base_lsb = 0x00000e08, - .hal_wbm1_release_ring_base_lsb = 0x00000e80, + .tcl_status_ring_base_lsb = 0x00000d38, + + .wbm_idle_ring_base_lsb = 0x00000d3c, + .wbm_idle_ring_misc_addr = 0x00000d4c, + .wbm_r0_idle_list_cntl_addr = 0x00000240, + .wbm_r0_idle_list_size_addr = 0x00000244, + .wbm_scattered_ring_base_lsb = 0x00000250, + .wbm_scattered_ring_base_msb = 0x00000254, + .wbm_scattered_desc_head_info_ix0 = 0x00000260, + .wbm_scattered_desc_head_info_ix1 = 0x00000264, + .wbm_scattered_desc_tail_info_ix0 = 0x00000270, + .wbm_scattered_desc_tail_info_ix1 = 0x00000274, + .wbm_scattered_desc_ptr_hp_addr = 0x00000027c, + + .wbm_sw_release_ring_base_lsb = 0x0000037c, + .wbm_sw1_release_ring_base_lsb = 0x00000284, + .wbm0_release_ring_base_lsb = 0x00000e08, + .wbm1_release_ring_base_lsb = 0x00000e80, /* PCIe base address */ .pcie_qserdes_sysclk_en_sel = 0x01e0e0a8, .pcie_pcs_osc_dtct_config_base = 0x01e0f45c, /* PPE release ring address */ - .hal_ppe_rel_ring_base = 0x0000043c, + .ppe_rel_ring_base = 0x0000043c, /* REO DEST ring address */ - .hal_reo2_ring_base = 0x0000055c, - .hal_reo1_misc_ctrl_addr = 0x00000b7c, - .hal_reo1_sw_cookie_cfg0 = 0x00000050, - .hal_reo1_sw_cookie_cfg1 = 0x00000054, - .hal_reo1_qdesc_lut_base0 = 0x00000058, - .hal_reo1_qdesc_lut_base1 = 0x0000005c, - .hal_reo1_ring_base_lsb = 0x000004e4, - .hal_reo1_ring_base_msb = 0x000004e8, - .hal_reo1_ring_id = 0x000004ec, - .hal_reo1_ring_misc = 0x000004f4, - .hal_reo1_ring_hp_addr_lsb = 0x000004f8, - .hal_reo1_ring_hp_addr_msb = 0x000004fc, - .hal_reo1_ring_producer_int_setup = 0x00000508, - .hal_reo1_ring_msi1_base_lsb = 0x0000052C, - .hal_reo1_ring_msi1_base_msb = 0x00000530, - .hal_reo1_ring_msi1_data = 0x00000534, - .hal_reo1_aging_thres_ix0 = 0x00000b08, - .hal_reo1_aging_thres_ix1 = 0x00000b0c, - .hal_reo1_aging_thres_ix2 = 0x00000b10, - .hal_reo1_aging_thres_ix3 = 0x00000b14, + .reo2_ring_base = 0x0000055c, + .reo1_misc_ctrl_addr = 0x00000b7c, + .reo1_sw_cookie_cfg0 = 0x00000050, + .reo1_sw_cookie_cfg1 = 0x00000054, + .reo1_qdesc_lut_base0 = 0x00000058, + .reo1_qdesc_lut_base1 = 0x0000005c, + .reo1_ring_base_lsb = 0x000004e4, + .reo1_ring_base_msb = 0x000004e8, + .reo1_ring_id = 0x000004ec, + .reo1_ring_misc = 0x000004f4, + .reo1_ring_hp_addr_lsb = 0x000004f8, + .reo1_ring_hp_addr_msb = 0x000004fc, + .reo1_ring_producer_int_setup = 0x00000508, + .reo1_ring_msi1_base_lsb = 0x0000052C, + .reo1_ring_msi1_base_msb = 0x00000530, + .reo1_ring_msi1_data = 0x00000534, + .reo1_aging_thres_ix0 = 0x00000b08, + .reo1_aging_thres_ix1 = 0x00000b0c, + .reo1_aging_thres_ix2 = 0x00000b10, + .reo1_aging_thres_ix3 = 0x00000b14, /* REO Exception ring address */ - .hal_reo2_sw0_ring_base = 0x000008a4, + .reo2_sw0_ring_base = 0x000008a4, /* REO Reinject ring address */ - .hal_sw2reo_ring_base = 0x00000304, - .hal_sw2reo1_ring_base = 0x0000037c, + .sw2reo_ring_base = 0x00000304, + .sw2reo1_ring_base = 0x0000037c, /* REO cmd ring address */ - .hal_reo_cmd_ring_base = 0x0000028c, + .reo_cmd_ring_base = 0x0000028c, /* REO status ring address */ - .hal_reo_status_ring_base = 0x00000a84, + .reo_status_ring_base = 0x00000a84, /* CE base address */ - .hal_umac_ce0_src_reg_base = 0x01b80000, - .hal_umac_ce0_dest_reg_base = 0x01b81000, - .hal_umac_ce1_src_reg_base = 0x01b82000, - .hal_umac_ce1_dest_reg_base = 0x01b83000, + .umac_ce0_src_reg_base = 0x01b80000, + .umac_ce0_dest_reg_base = 0x01b81000, + .umac_ce1_src_reg_base = 0x01b82000, + .umac_ce1_dest_reg_base = 0x01b83000, .gcc_gcc_pcie_hot_rst = 0x1e40304, }; From b38b76473c28ee77f32f7e0dedda4894ee6eae82 Mon Sep 17 00:00:00 2001 From: Sarika Sharma Date: Tue, 30 Sep 2025 14:45:50 +0530 Subject: [PATCH 068/140] wifi: ath12k: Fix MSDU buffer types handling in RX error path Currently, packets received on the REO exception ring from unassociated peers are of MSDU buffer type, while the driver expects link descriptor type packets. These packets are not parsed further due to a return check on packet type in ath12k_hal_desc_reo_parse_err(), but the associated skb is not freed. This may lead to kernel crashes and buffer leaks. Hence to fix, update the RX error handler to explicitly drop MSDU buffer type packets received on the REO exception ring. This prevents further processing of invalid packets and ensures stability in the RX error handling path. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") Signed-off-by: Sarika Sharma Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20250930091551.3305312-2-sarika.sharma@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 944 ++++++++++++++++++ .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 9 +- 2 files changed, 945 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 3a762d00acb50..722a9cca2f8bc 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -1556,6 +1556,950 @@ u64 ath12k_dp_rx_h_get_pn(struct ath12k_dp *dp, struct sk_buff *skb) return pn; } +static bool +ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, struct ath12k_dp_rx_tid *rx_tid) +{ + struct ath12k_base *ab = ar->ab; + enum hal_encrypt_type encrypt_type; + struct sk_buff *first_frag, *skb; + struct hal_rx_desc *desc; + u64 last_pn; + u64 cur_pn; + + first_frag = skb_peek(&rx_tid->rx_frags); + desc = (struct hal_rx_desc *)first_frag->data; + + encrypt_type = ath12k_dp_rx_h_enctype(ab, desc); + if (encrypt_type != HAL_ENCRYPT_TYPE_CCMP_128 && + encrypt_type != HAL_ENCRYPT_TYPE_CCMP_256 && + encrypt_type != HAL_ENCRYPT_TYPE_GCMP_128 && + encrypt_type != HAL_ENCRYPT_TYPE_AES_GCMP_256) + return true; + + last_pn = ath12k_dp_rx_h_get_pn(ar, first_frag); + skb_queue_walk(&rx_tid->rx_frags, skb) { + if (skb == first_frag) + continue; + + cur_pn = ath12k_dp_rx_h_get_pn(ar, skb); + if (cur_pn != last_pn + 1) + return false; + last_pn = cur_pn; + } + return true; +} + +static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, + struct sk_buff *msdu, + struct hal_reo_dest_ring *ring_desc) +{ + struct ath12k_base *ab = ar->ab; + struct hal_rx_desc *rx_desc; + struct ath12k_peer *peer; + struct ath12k_dp_rx_tid *rx_tid; + struct sk_buff *defrag_skb = NULL; + u32 peer_id; + u16 seqno, frag_no; + u8 tid; + int ret = 0; + bool more_frags; + + rx_desc = (struct hal_rx_desc *)msdu->data; + peer_id = ath12k_dp_rx_h_peer_id(ab, rx_desc); + tid = ath12k_dp_rx_h_tid(ab, rx_desc); + seqno = ath12k_dp_rx_h_seq_no(ab, rx_desc); + frag_no = ath12k_dp_rx_h_frag_no(ab, msdu); + more_frags = ath12k_dp_rx_h_more_frags(ab, msdu); + + if (!ath12k_dp_rx_h_seq_ctrl_valid(ab, rx_desc) || + !ath12k_dp_rx_h_fc_valid(ab, rx_desc) || + tid > IEEE80211_NUM_TIDS) + return -EINVAL; + + /* received unfragmented packet in reo + * exception ring, this shouldn't happen + * as these packets typically come from + * reo2sw srngs. + */ + if (WARN_ON_ONCE(!frag_no && !more_frags)) + return -EINVAL; + + spin_lock_bh(&ab->base_lock); + peer = ath12k_peer_find_by_id(ab, peer_id); + if (!peer) { + ath12k_warn(ab, "failed to find the peer to de-fragment received fragment peer_id %d\n", + peer_id); + ret = -ENOENT; + goto out_unlock; + } + + if (!peer->dp_setup_done) { + ath12k_warn(ab, "The peer %pM [%d] has uninitialized datapath\n", + peer->addr, peer_id); + ret = -ENOENT; + goto out_unlock; + } + + rx_tid = &peer->rx_tid[tid]; + + if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) || + skb_queue_empty(&rx_tid->rx_frags)) { + /* Flush stored fragments and start a new sequence */ + ath12k_dp_rx_frags_cleanup(rx_tid, true); + rx_tid->cur_sn = seqno; + } + + if (rx_tid->rx_frag_bitmap & BIT(frag_no)) { + /* Fragment already present */ + ret = -EINVAL; + goto out_unlock; + } + + if ((!rx_tid->rx_frag_bitmap || frag_no > __fls(rx_tid->rx_frag_bitmap))) + __skb_queue_tail(&rx_tid->rx_frags, msdu); + else + ath12k_dp_rx_h_sort_frags(ab, &rx_tid->rx_frags, msdu); + + rx_tid->rx_frag_bitmap |= BIT(frag_no); + if (!more_frags) + rx_tid->last_frag_no = frag_no; + + if (frag_no == 0) { + rx_tid->dst_ring_desc = kmemdup(ring_desc, + sizeof(*rx_tid->dst_ring_desc), + GFP_ATOMIC); + if (!rx_tid->dst_ring_desc) { + ret = -ENOMEM; + goto out_unlock; + } + } else { + ath12k_dp_rx_link_desc_return(ab, &ring_desc->buf_addr_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + } + + if (!rx_tid->last_frag_no || + rx_tid->rx_frag_bitmap != GENMASK(rx_tid->last_frag_no, 0)) { + mod_timer(&rx_tid->frag_timer, jiffies + + ATH12K_DP_RX_FRAGMENT_TIMEOUT_MS); + goto out_unlock; + } + + spin_unlock_bh(&ab->base_lock); + timer_delete_sync(&rx_tid->frag_timer); + spin_lock_bh(&ab->base_lock); + + peer = ath12k_peer_find_by_id(ab, peer_id); + if (!peer) + goto err_frags_cleanup; + + if (!ath12k_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid)) + goto err_frags_cleanup; + + if (ath12k_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb)) + goto err_frags_cleanup; + + if (!defrag_skb) + goto err_frags_cleanup; + + if (ath12k_dp_rx_h_defrag_reo_reinject(ar, rx_tid, defrag_skb)) + goto err_frags_cleanup; + + ath12k_dp_rx_frags_cleanup(rx_tid, false); + goto out_unlock; + +err_frags_cleanup: + dev_kfree_skb_any(defrag_skb); + ath12k_dp_rx_frags_cleanup(rx_tid, true); +out_unlock: + spin_unlock_bh(&ab->base_lock); + return ret; +} + +static int +ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc, + struct list_head *used_list, + bool drop, u32 cookie) +{ + struct ath12k_base *ab = ar->ab; + struct sk_buff *msdu; + struct ath12k_skb_rxcb *rxcb; + struct hal_rx_desc *rx_desc; + u16 msdu_len; + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; + struct ath12k_rx_desc_info *desc_info; + u64 desc_va; + + desc_va = ((u64)le32_to_cpu(desc->buf_va_hi) << 32 | + le32_to_cpu(desc->buf_va_lo)); + desc_info = (struct ath12k_rx_desc_info *)((unsigned long)desc_va); + + /* retry manual desc retrieval */ + if (!desc_info) { + desc_info = ath12k_dp_get_rx_desc(ab, cookie); + if (!desc_info) { + ath12k_warn(ab, "Invalid cookie in DP rx error descriptor retrieval: 0x%x\n", + cookie); + return -EINVAL; + } + } + + if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) + ath12k_warn(ab, " RX Exception, Check HW CC implementation"); + + msdu = desc_info->skb; + desc_info->skb = NULL; + + list_add_tail(&desc_info->list, used_list); + + rxcb = ATH12K_SKB_RXCB(msdu); + dma_unmap_single(ar->ab->dev, rxcb->paddr, + msdu->len + skb_tailroom(msdu), + DMA_FROM_DEVICE); + + if (drop) { + dev_kfree_skb_any(msdu); + return 0; + } + + rcu_read_lock(); + if (!rcu_dereference(ar->ab->pdevs_active[ar->pdev_idx])) { + dev_kfree_skb_any(msdu); + goto exit; + } + + if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) { + dev_kfree_skb_any(msdu); + goto exit; + } + + rx_desc = (struct hal_rx_desc *)msdu->data; + msdu_len = ath12k_dp_rx_h_msdu_len(ar->ab, rx_desc); + if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { + ath12k_warn(ar->ab, "invalid msdu leng %u", msdu_len); + ath12k_dbg_dump(ar->ab, ATH12K_DBG_DATA, NULL, "", rx_desc, + sizeof(*rx_desc)); + dev_kfree_skb_any(msdu); + goto exit; + } + + skb_put(msdu, hal_rx_desc_sz + msdu_len); + + if (ath12k_dp_rx_frag_h_mpdu(ar, msdu, desc)) { + dev_kfree_skb_any(msdu); + ath12k_dp_rx_link_desc_return(ar->ab, &desc->buf_addr_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + } +exit: + rcu_read_unlock(); + return 0; +} + +static int ath12k_dp_h_msdu_buffer_type(struct ath12k_base *ab, + struct list_head *list, + struct hal_reo_dest_ring *desc) +{ + struct ath12k_rx_desc_info *desc_info; + struct ath12k_skb_rxcb *rxcb; + struct sk_buff *msdu; + u64 desc_va; + + desc_va = (u64)le32_to_cpu(desc->buf_va_hi) << 32 | + le32_to_cpu(desc->buf_va_lo); + desc_info = (struct ath12k_rx_desc_info *)(uintptr_t)desc_va; + if (!desc_info) { + u32 cookie; + + cookie = le32_get_bits(desc->buf_addr_info.info1, + BUFFER_ADDR_INFO1_SW_COOKIE); + desc_info = ath12k_dp_get_rx_desc(ab, cookie); + if (!desc_info) { + ath12k_warn(ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n", + cookie); + return -EINVAL; + } + } + + if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) { + ath12k_warn(ab, "rx exception, magic check failed with value: %u\n", + desc_info->magic); + return -EINVAL; + } + + msdu = desc_info->skb; + desc_info->skb = NULL; + list_add_tail(&desc_info->list, list); + rxcb = ATH12K_SKB_RXCB(msdu); + dma_unmap_single(ab->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), + DMA_FROM_DEVICE); + dev_kfree_skb_any(msdu); + + return 0; +} + +int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, + int budget) +{ + struct ath12k_hw_group *ag = ab->ag; + struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; + u32 msdu_cookies[HAL_NUM_RX_MSDUS_PER_LINK_DESC]; + int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; + struct dp_link_desc_bank *link_desc_banks; + enum hal_rx_buf_return_buf_manager rbm; + struct hal_rx_msdu_link *link_desc_va; + int tot_n_bufs_reaped, quota, ret, i; + struct hal_reo_dest_ring *reo_desc; + struct dp_rxdma_ring *rx_ring; + struct dp_srng *reo_except; + struct ath12k_hw_link *hw_links = ag->hw_links; + struct ath12k_base *partner_ab; + u8 hw_link_id, device_id; + u32 desc_bank, num_msdus; + struct hal_srng *srng; + struct ath12k *ar; + dma_addr_t paddr; + bool is_frag; + bool drop; + int pdev_id; + + tot_n_bufs_reaped = 0; + quota = budget; + + for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) + INIT_LIST_HEAD(&rx_desc_used_list[device_id]); + + reo_except = &ab->dp.reo_except_ring; + + srng = &ab->hal.srng_list[reo_except->ring_id]; + + spin_lock_bh(&srng->lock); + + ath12k_hal_srng_access_begin(ab, srng); + + while (budget && + (reo_desc = ath12k_hal_srng_dst_get_next_entry(ab, srng))) { + drop = false; + ab->device_stats.err_ring_pkts++; + + hw_link_id = le32_get_bits(reo_desc->info0, + HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); + device_id = hw_links[hw_link_id].device_id; + partner_ab = ath12k_ag_to_ab(ag, device_id); + + /* Below case is added to handle data packet from un-associated clients. + * As it is expected that AST lookup will fail for + * un-associated station's data packets. + */ + if (le32_get_bits(reo_desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE) == + HAL_REO_DEST_RING_BUFFER_TYPE_MSDU) { + if (!ath12k_dp_h_msdu_buffer_type(partner_ab, + &rx_desc_used_list[device_id], + reo_desc)) { + num_buffs_reaped[device_id]++; + tot_n_bufs_reaped++; + } + goto next_desc; + } + + ret = ath12k_hal_desc_reo_parse_err(ab, reo_desc, &paddr, + &desc_bank); + if (ret) { + ath12k_warn(ab, "failed to parse error reo desc %d\n", + ret); + continue; + } + + pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + hw_links[hw_link_id].pdev_idx); + ar = partner_ab->pdevs[pdev_id].ar; + + link_desc_banks = partner_ab->dp.link_desc_banks; + link_desc_va = link_desc_banks[desc_bank].vaddr + + (paddr - link_desc_banks[desc_bank].paddr); + ath12k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies, + &rbm); + if (rbm != partner_ab->dp.idle_link_rbm && + rbm != HAL_RX_BUF_RBM_SW3_BM && + rbm != partner_ab->hw_params->hal_params->rx_buf_rbm) { + ab->device_stats.invalid_rbm++; + ath12k_warn(ab, "invalid return buffer manager %d\n", rbm); + ath12k_dp_rx_link_desc_return(partner_ab, + &reo_desc->buf_addr_info, + HAL_WBM_REL_BM_ACT_REL_MSDU); + continue; + } + + is_frag = !!(le32_to_cpu(reo_desc->rx_mpdu_info.info0) & + RX_MPDU_DESC_INFO0_FRAG_FLAG); + + /* Process only rx fragments with one msdu per link desc below, and drop + * msdu's indicated due to error reasons. + * Dynamic fragmentation not supported in Multi-link client, so drop the + * partner device buffers. + */ + if (!is_frag || num_msdus > 1 || + partner_ab->device_id != ab->device_id) { + drop = true; + + /* Return the link desc back to wbm idle list */ + ath12k_dp_rx_link_desc_return(partner_ab, + &reo_desc->buf_addr_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + } + + for (i = 0; i < num_msdus; i++) { + if (!ath12k_dp_process_rx_err_buf(ar, reo_desc, + &rx_desc_used_list[device_id], + drop, + msdu_cookies[i])) { + num_buffs_reaped[device_id]++; + tot_n_bufs_reaped++; + } + } + +next_desc: + if (tot_n_bufs_reaped >= quota) { + tot_n_bufs_reaped = quota; + goto exit; + } + + budget = quota - tot_n_bufs_reaped; + } + +exit: + ath12k_hal_srng_access_end(ab, srng); + + spin_unlock_bh(&srng->lock); + + for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) { + if (!num_buffs_reaped[device_id]) + continue; + + partner_ab = ath12k_ag_to_ab(ag, device_id); + rx_ring = &partner_ab->dp.rx_refill_buf_ring; + + ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, + &rx_desc_used_list[device_id], + num_buffs_reaped[device_id]); + } + + return tot_n_bufs_reaped; +} + +static void ath12k_dp_rx_null_q_desc_sg_drop(struct ath12k *ar, + int msdu_len, + struct sk_buff_head *msdu_list) +{ + struct sk_buff *skb, *tmp; + struct ath12k_skb_rxcb *rxcb; + int n_buffs; + + n_buffs = DIV_ROUND_UP(msdu_len, + (DP_RX_BUFFER_SIZE - ar->ab->hal.hal_desc_sz)); + + skb_queue_walk_safe(msdu_list, skb, tmp) { + rxcb = ATH12K_SKB_RXCB(skb); + if (rxcb->err_rel_src == HAL_WBM_REL_SRC_MODULE_REO && + rxcb->err_code == HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO) { + if (!n_buffs) + break; + __skb_unlink(skb, msdu_list); + dev_kfree_skb_any(skb); + n_buffs--; + } + } +} + +static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info, + struct sk_buff_head *msdu_list) +{ + struct ath12k_base *ab = ar->ab; + u16 msdu_len; + struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; + u8 l3pad_bytes; + struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); + u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + + msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc); + + if (!rxcb->is_frag && ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE)) { + /* First buffer will be freed by the caller, so deduct it's length */ + msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - hal_rx_desc_sz); + ath12k_dp_rx_null_q_desc_sg_drop(ar, msdu_len, msdu_list); + return -EINVAL; + } + + /* Even after cleaning up the sg buffers in the msdu list with above check + * any msdu received with continuation flag needs to be dropped as invalid. + * This protects against some random err frame with continuation flag. + */ + if (rxcb->is_continuation) + return -EINVAL; + + if (!ath12k_dp_rx_h_msdu_done(ab, desc)) { + ath12k_warn(ar->ab, + "msdu_done bit not set in null_q_des processing\n"); + __skb_queue_purge(msdu_list); + return -EIO; + } + + /* Handle NULL queue descriptor violations arising out a missing + * REO queue for a given peer or a given TID. This typically + * may happen if a packet is received on a QOS enabled TID before the + * ADDBA negotiation for that TID, when the TID queue is setup. Or + * it may also happen for MC/BC frames if they are not routed to the + * non-QOS TID queue, in the absence of any other default TID queue. + * This error can show up both in a REO destination or WBM release ring. + */ + + if (rxcb->is_frag) { + skb_pull(msdu, hal_rx_desc_sz); + } else { + l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc); + + if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) + return -EINVAL; + + skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); + skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); + } + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu))) + return -EINVAL; + + ath12k_dp_rx_h_fetch_info(ab, desc, rx_info); + ath12k_dp_rx_h_ppdu(ar, rx_info); + ath12k_dp_rx_h_mpdu(ar, msdu, desc, rx_info); + + rxcb->tid = rx_info->tid; + + /* Please note that caller will having the access to msdu and completing + * rx with mac80211. Need not worry about cleaning up amsdu_list. + */ + + return 0; +} + +static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info, + struct sk_buff_head *msdu_list) +{ + struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); + bool drop = false; + + ar->ab->device_stats.reo_error[rxcb->err_code]++; + + switch (rxcb->err_code) { + case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO: + if (ath12k_dp_rx_h_null_q_desc(ar, msdu, rx_info, msdu_list)) + drop = true; + break; + case HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED: + /* TODO: Do not drop PN failed packets in the driver; + * instead, it is good to drop such packets in mac80211 + * after incrementing the replay counters. + */ + fallthrough; + default: + /* TODO: Review other errors and process them to mac80211 + * as appropriate. + */ + drop = true; + break; + } + + return drop; +} + +static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info) +{ + struct ath12k_base *ab = ar->ab; + u16 msdu_len; + struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; + u8 l3pad_bytes; + struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); + u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz; + + rxcb->is_first_msdu = ath12k_dp_rx_h_first_msdu(ab, desc); + rxcb->is_last_msdu = ath12k_dp_rx_h_last_msdu(ab, desc); + + l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc); + msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc); + + if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) { + ath12k_dbg(ab, ATH12K_DBG_DATA, + "invalid msdu len in tkip mic err %u\n", msdu_len); + ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", desc, + sizeof(*desc)); + return true; + } + + skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); + skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); + + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu))) + return true; + + ath12k_dp_rx_h_ppdu(ar, rx_info); + + rx_info->rx_status->flag |= (RX_FLAG_MMIC_STRIPPED | RX_FLAG_MMIC_ERROR | + RX_FLAG_DECRYPTED); + + ath12k_dp_rx_h_undecap(ar, msdu, desc, + HAL_ENCRYPT_TYPE_TKIP_MIC, rx_info->rx_status, false); + return false; +} + +static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu, + struct ath12k_dp_rx_info *rx_info) +{ + struct ath12k_base *ab = ar->ab; + struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); + struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; + bool drop = false; + u32 err_bitmap; + + ar->ab->device_stats.rxdma_error[rxcb->err_code]++; + + switch (rxcb->err_code) { + case HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR: + case HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR: + err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc); + if (err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) { + ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info); + drop = ath12k_dp_rx_h_tkip_mic_err(ar, msdu, rx_info); + break; + } + fallthrough; + default: + /* TODO: Review other rxdma error code to check if anything is + * worth reporting to mac80211 + */ + drop = true; + break; + } + + return drop; +} + +static void ath12k_dp_rx_wbm_err(struct ath12k *ar, + struct napi_struct *napi, + struct sk_buff *msdu, + struct sk_buff_head *msdu_list) +{ + struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); + struct ieee80211_rx_status rxs = {}; + struct ath12k_dp_rx_info rx_info; + bool drop = true; + + rx_info.addr2_present = false; + rx_info.rx_status = &rxs; + + switch (rxcb->err_rel_src) { + case HAL_WBM_REL_SRC_MODULE_REO: + drop = ath12k_dp_rx_h_reo_err(ar, msdu, &rx_info, msdu_list); + break; + case HAL_WBM_REL_SRC_MODULE_RXDMA: + drop = ath12k_dp_rx_h_rxdma_err(ar, msdu, &rx_info); + break; + default: + /* msdu will get freed */ + break; + } + + if (drop) { + dev_kfree_skb_any(msdu); + return; + } + + rx_info.rx_status->flag |= RX_FLAG_SKIP_MONITOR; + + ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info); +} + +int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab, + struct napi_struct *napi, int budget) +{ + struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; + struct ath12k_hw_group *ag = ab->ag; + struct ath12k *ar; + struct ath12k_dp *dp = &ab->dp; + struct dp_rxdma_ring *rx_ring; + struct hal_rx_wbm_rel_info err_info; + struct hal_srng *srng; + struct sk_buff *msdu; + struct sk_buff_head msdu_list, scatter_msdu_list; + struct ath12k_skb_rxcb *rxcb; + void *rx_desc; + int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; + int total_num_buffs_reaped = 0; + struct ath12k_rx_desc_info *desc_info; + struct ath12k_device_dp_stats *device_stats = &ab->device_stats; + struct ath12k_hw_link *hw_links = ag->hw_links; + struct ath12k_base *partner_ab; + u8 hw_link_id, device_id; + int ret, pdev_id; + struct hal_rx_desc *msdu_data; + + __skb_queue_head_init(&msdu_list); + __skb_queue_head_init(&scatter_msdu_list); + + for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) + INIT_LIST_HEAD(&rx_desc_used_list[device_id]); + + srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id]; + spin_lock_bh(&srng->lock); + + ath12k_hal_srng_access_begin(ab, srng); + + while (budget) { + rx_desc = ath12k_hal_srng_dst_get_next_entry(ab, srng); + if (!rx_desc) + break; + + ret = ath12k_hal_wbm_desc_parse_err(ab, rx_desc, &err_info); + if (ret) { + ath12k_warn(ab, + "failed to parse rx error in wbm_rel ring desc %d\n", + ret); + continue; + } + + desc_info = err_info.rx_desc; + + /* retry manual desc retrieval if hw cc is not done */ + if (!desc_info) { + desc_info = ath12k_dp_get_rx_desc(ab, err_info.cookie); + if (!desc_info) { + ath12k_warn(ab, "Invalid cookie in DP WBM rx error descriptor retrieval: 0x%x\n", + err_info.cookie); + continue; + } + } + + if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) + ath12k_warn(ab, "WBM RX err, Check HW CC implementation"); + + msdu = desc_info->skb; + desc_info->skb = NULL; + + device_id = desc_info->device_id; + partner_ab = ath12k_ag_to_ab(ag, device_id); + if (unlikely(!partner_ab)) { + dev_kfree_skb_any(msdu); + + /* In any case continuation bit is set + * in the previous record, cleanup scatter_msdu_list + */ + ath12k_dp_clean_up_skb_list(&scatter_msdu_list); + continue; + } + + list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]); + + rxcb = ATH12K_SKB_RXCB(msdu); + dma_unmap_single(partner_ab->dev, rxcb->paddr, + msdu->len + skb_tailroom(msdu), + DMA_FROM_DEVICE); + + num_buffs_reaped[device_id]++; + total_num_buffs_reaped++; + + if (!err_info.continuation) + budget--; + + if (err_info.push_reason != + HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED) { + dev_kfree_skb_any(msdu); + continue; + } + + msdu_data = (struct hal_rx_desc *)msdu->data; + rxcb->err_rel_src = err_info.err_rel_src; + rxcb->err_code = err_info.err_code; + rxcb->is_first_msdu = err_info.first_msdu; + rxcb->is_last_msdu = err_info.last_msdu; + rxcb->is_continuation = err_info.continuation; + rxcb->rx_desc = msdu_data; + + if (err_info.continuation) { + __skb_queue_tail(&scatter_msdu_list, msdu); + continue; + } + + hw_link_id = ath12k_dp_rx_get_msdu_src_link(partner_ab, + msdu_data); + if (hw_link_id >= ATH12K_GROUP_MAX_RADIO) { + dev_kfree_skb_any(msdu); + + /* In any case continuation bit is set + * in the previous record, cleanup scatter_msdu_list + */ + ath12k_dp_clean_up_skb_list(&scatter_msdu_list); + continue; + } + + if (!skb_queue_empty(&scatter_msdu_list)) { + struct sk_buff *msdu; + + skb_queue_walk(&scatter_msdu_list, msdu) { + rxcb = ATH12K_SKB_RXCB(msdu); + rxcb->hw_link_id = hw_link_id; + } + + skb_queue_splice_tail_init(&scatter_msdu_list, + &msdu_list); + } + + rxcb = ATH12K_SKB_RXCB(msdu); + rxcb->hw_link_id = hw_link_id; + __skb_queue_tail(&msdu_list, msdu); + } + + /* In any case continuation bit is set in the + * last record, cleanup scatter_msdu_list + */ + ath12k_dp_clean_up_skb_list(&scatter_msdu_list); + + ath12k_hal_srng_access_end(ab, srng); + + spin_unlock_bh(&srng->lock); + + if (!total_num_buffs_reaped) + goto done; + + for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) { + if (!num_buffs_reaped[device_id]) + continue; + + partner_ab = ath12k_ag_to_ab(ag, device_id); + rx_ring = &partner_ab->dp.rx_refill_buf_ring; + + ath12k_dp_rx_bufs_replenish(ab, rx_ring, + &rx_desc_used_list[device_id], + num_buffs_reaped[device_id]); + } + + rcu_read_lock(); + while ((msdu = __skb_dequeue(&msdu_list))) { + rxcb = ATH12K_SKB_RXCB(msdu); + hw_link_id = rxcb->hw_link_id; + + device_id = hw_links[hw_link_id].device_id; + partner_ab = ath12k_ag_to_ab(ag, device_id); + if (unlikely(!partner_ab)) { + ath12k_dbg(ab, ATH12K_DBG_DATA, + "Unable to process WBM error msdu due to invalid hw link id %d device id %d\n", + hw_link_id, device_id); + dev_kfree_skb_any(msdu); + continue; + } + + pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + hw_links[hw_link_id].pdev_idx); + ar = partner_ab->pdevs[pdev_id].ar; + + if (!ar || !rcu_dereference(ar->ab->pdevs_active[pdev_id])) { + dev_kfree_skb_any(msdu); + continue; + } + + if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) { + dev_kfree_skb_any(msdu); + continue; + } + + if (rxcb->err_rel_src < HAL_WBM_REL_SRC_MODULE_MAX) { + device_id = ar->ab->device_id; + device_stats->rx_wbm_rel_source[rxcb->err_rel_src][device_id]++; + } + + ath12k_dp_rx_wbm_err(ar, napi, msdu, &msdu_list); + } + rcu_read_unlock(); +done: + return total_num_buffs_reaped; +} + +void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab) +{ + struct ath12k_dp *dp = &ab->dp; + struct hal_tlv_64_hdr *hdr; + struct hal_srng *srng; + struct ath12k_dp_rx_reo_cmd *cmd, *tmp; + bool found = false; + u16 tag; + struct hal_reo_status reo_status; + + srng = &ab->hal.srng_list[dp->reo_status_ring.ring_id]; + + memset(&reo_status, 0, sizeof(reo_status)); + + spin_lock_bh(&srng->lock); + + ath12k_hal_srng_access_begin(ab, srng); + + while ((hdr = ath12k_hal_srng_dst_get_next_entry(ab, srng))) { + tag = le64_get_bits(hdr->tl, HAL_SRNG_TLV_HDR_TAG); + + switch (tag) { + case HAL_REO_GET_QUEUE_STATS_STATUS: + ath12k_hal_reo_status_queue_stats(ab, hdr, + &reo_status); + break; + case HAL_REO_FLUSH_QUEUE_STATUS: + ath12k_hal_reo_flush_queue_status(ab, hdr, + &reo_status); + break; + case HAL_REO_FLUSH_CACHE_STATUS: + ath12k_hal_reo_flush_cache_status(ab, hdr, + &reo_status); + break; + case HAL_REO_UNBLOCK_CACHE_STATUS: + ath12k_hal_reo_unblk_cache_status(ab, hdr, + &reo_status); + break; + case HAL_REO_FLUSH_TIMEOUT_LIST_STATUS: + ath12k_hal_reo_flush_timeout_list_status(ab, hdr, + &reo_status); + break; + case HAL_REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS: + ath12k_hal_reo_desc_thresh_reached_status(ab, hdr, + &reo_status); + break; + case HAL_REO_UPDATE_RX_REO_QUEUE_STATUS: + ath12k_hal_reo_update_rx_reo_queue_status(ab, hdr, + &reo_status); + break; + default: + ath12k_warn(ab, "Unknown reo status type %d\n", tag); + continue; + } + + spin_lock_bh(&dp->reo_cmd_lock); + list_for_each_entry_safe(cmd, tmp, &dp->reo_cmd_list, list) { + if (reo_status.uniform_hdr.cmd_num == cmd->cmd_num) { + found = true; + list_del(&cmd->list); + break; + } + } + spin_unlock_bh(&dp->reo_cmd_lock); + + if (found) { + cmd->handler(dp, (void *)&cmd->data, + reo_status.uniform_hdr.cmd_status); + kfree(cmd); + } + + found = false; + } + + ath12k_hal_srng_access_end(ab, srng); + + spin_unlock_bh(&srng->lock); +} + void ath12k_dp_rx_free(struct ath12k_base *ab) { struct ath12k_dp *dp = ath12k_ab_to_dp(ab); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index 8828187dc3315..4cf00c80a3a60 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -344,14 +344,7 @@ int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_base *ab, return -EINVAL; } - val = le32_get_bits(desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE); - if (val != HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC) { - ath12k_warn(ab, "expected buffer type link_desc"); - return -EINVAL; - } - - ath12k_wifi7_hal_rx_reo_ent_paddr_get(ab, &desc->buf_addr_info, paddr, - &cookie); + ath12k_hal_rx_reo_ent_paddr_get(ab, &desc->buf_addr_info, paddr, &cookie); *desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK); return 0; From 286c36e0b7a273de8d9eae2f2655f23a7eb165d6 Mon Sep 17 00:00:00 2001 From: Sarika Sharma Date: Tue, 30 Sep 2025 14:45:51 +0530 Subject: [PATCH 069/140] wifi: ath12k: track dropped MSDU buffer type packets in REO exception ring Add a counter "reo_excep_msdu_buf_type" in ath12k_debugfs_dump_device_dp_stats() to account for packets dropped due to unexpected MSDU buffer types in the RX error path. These packets are discarded to prevent incorrect parsing and potential kernel crashes. This helps in debugging and monitoring RX error handling behavior. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Signed-off-by: Sarika Sharma Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20250930091551.3305312-3-sarika.sharma@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 722a9cca2f8bc..4db3cbaaa661d 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -1803,6 +1803,8 @@ static int ath12k_dp_h_msdu_buffer_type(struct ath12k_base *ab, struct sk_buff *msdu; u64 desc_va; + ab->device_stats.reo_excep_msdu_buf_type++; + desc_va = (u64)le32_to_cpu(desc->buf_va_hi) << 32 | le32_to_cpu(desc->buf_va_lo); desc_info = (struct ath12k_rx_desc_info *)(uintptr_t)desc_va; From 57e782a315596b6190f2ec81eeb5f56cfb172749 Mon Sep 17 00:00:00 2001 From: Aditya Kumar Singh Date: Wed, 24 Sep 2025 19:13:36 +0530 Subject: [PATCH 070/140] wifi: ath12k: Defer vdev bring-up until CSA finalize to avoid stale beacon Mac80211 schedules CSA finalize work twice during a channel switch: first during the reserved switch phase and again during the finalize phase. The beacon content is updated only during the second schedule, which occurs after the reserved switch completes. However, the ath12k driver attempts to bring up the VDEV during the channel switch callback (ath12k_mac_update_vif_chan()), which leads to premature installation of stale beacon templates before the updated content is available. This premature VDEV bring-up causes outdated beacon information to be broadcast, which can result in updated channel parameters during the transition. In MBSSID scenarios, this behavior is particularly problematic because the transmitting interface's beacon must be updated before non-transmitting interfaces are brought up. Failing to do so can lead to beacon mismatches across interfaces. Introduce a is_csa_in_progress flag to defer VDEV_UP until CSA finalize is complete. Set this flag during the channel switch callback when CSA is active. In bss_info_changed(), check this flag and issue VDEV_UP only after the beacon template has been updated. Ensure that in MBSSID cases, the transmitting interface is brought up first, followed by all non-transmitting interfaces. This ordering makes sure correct beacon propagation and avoids stale beacon installation during CSA transitions. Additionally, move the call to ath12k_mac_update_peer_puncturing_width() before VDEV bring-up during CSA handling. This ensures that the puncturing bitmap and bandwidth settings are applied before the VDEV is brought up. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Fixes: 8c6faa56bfb2 ("wifi: ath12k: add MBSSID beacon support") Signed-off-by: Aditya Kumar Singh Signed-off-by: Maharaja Kennadyrajan Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20250924134336.888-1-maharaja.kennadyrajan@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 1 - drivers/net/wireless/ath/ath12k/mac.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 1548116b0228f..0794b17e65e9a 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -349,7 +349,6 @@ struct ath12k_link_vif { bool pairwise_key_done; u16 num_stations; bool is_csa_in_progress; - struct wiphy_work bcn_tx_work; }; struct ath12k_vif { diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 5c963b6efc9be..f480fa18ead6a 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -4409,7 +4409,6 @@ static void ath12k_mac_bss_info_changed(struct ath12k *ar, { struct ath12k_vif *ahvif = arvif->ahvif; struct ieee80211_vif *vif = ath12k_ahvif_to_vif(ahvif); - struct ieee80211_vif_cfg *vif_cfg = &vif->cfg; struct ath12k_link_vif *tx_arvif; struct cfg80211_chan_def def; u32 param_id, param_value; From e2cc3c9409a81e7d084e29dba987b8e1aefa07e1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 3 Oct 2025 10:29:19 +0200 Subject: [PATCH 071/140] wifi: ath12k: Add MODULE_FIRMWARE() entries Some systems such as live-image or installer require the firmware information for each module declared by MODULE_FIRMWARE(), which is currently missing in ath12k driver. For addressing it, this patch adds the MODULE_FIRMWARE() entries. Like ath11k driver, we can just put the currently used firmware entries for QCN9274 and WCN7850 with wildcards. Signed-off-by: Takashi Iwai Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251003082955.11436-1-tiwai@suse.de Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/pci.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index e9ead1b75af39..fd4c25ad8f07d 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -1836,15 +1836,7 @@ int ath12k_pci_register_driver(const enum ath12k_device_family device_id, return pci_register_driver(pci_driver); } -EXPORT_SYMBOL(ath12k_pci_register_driver); -void ath12k_pci_unregister_driver(const enum ath12k_device_family device_id) -{ - if (device_id >= ATH12K_DEVICE_FAMILY_MAX || - !ath12k_pci_family_drivers[device_id]) - return; - - pci_unregister_driver(&ath12k_pci_family_drivers[device_id]->driver); - ath12k_pci_family_drivers[device_id] = NULL; -} -EXPORT_SYMBOL(ath12k_pci_unregister_driver); +/* firmware files */ +MODULE_FIRMWARE(ATH12K_FW_DIR "/QCN9274/hw2.0/*"); +MODULE_FIRMWARE(ATH12K_FW_DIR "/WCN7850/hw2.0/*"); From 501a569faca036a83e4efe0fdb228da89892e1a0 Mon Sep 17 00:00:00 2001 From: Wei Zhang Date: Thu, 16 Oct 2025 23:01:00 -0700 Subject: [PATCH 072/140] wifi: ath12k: add support for BSS color change Add support for handling BSS color collision events reported by firmware. There are two scenarios where a BSS color collision may be detected: 1. The AP's MAC detects the collision directly, and firmware reports a BSS color collision event to the host. 2. A STA associated with the AP detects the collision. The notification frame from the peer is routed directly to the AP firmware, which handles it and sends the BSS color collision event to the host. Add logic to parse and handle such events, and pass the data up to mac80211. Unlike CSA, firmware does not provide an offload mechanism for BSS color change. Instead, the color change process is triggered via beacon offload TX completion events sent by firmware. BSS color feature is enabled depending on service flag advertised by firmware, based on which color change functionality is invoked. This change builds upon the following ath11k patch. commit 886433a98425 ("ath11k: add support for BSS color change") Tested-on: WCN7850 hw2.0 PCI WLAN.IOE_HMT.1.1-00011-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1 Signed-off-by: Wei Zhang Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251017060100.1751692-1-wei.zhang@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 0794b17e65e9a..1548116b0228f 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -349,6 +349,7 @@ struct ath12k_link_vif { bool pairwise_key_done; u16 num_stations; bool is_csa_in_progress; + struct wiphy_work bcn_tx_work; }; struct ath12k_vif { From 8034a88f53052caa54764c03d0f97b46d872c5bc Mon Sep 17 00:00:00 2001 From: Sarika Sharma Date: Tue, 21 Oct 2025 16:52:04 +0530 Subject: [PATCH 073/140] wifi: ath12k: Assert base_lock is held before allocating REO update element Add a lockdep assertion to verify that ab->base_lock is held prior to allocating a REO update element in ath12k_dp_prepare_reo_update_elem(). This helps detect potential concurrency issues during development and improves code robustness. Compiled tested only. Signed-off-by: Sarika Sharma Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251021112204.323242-1-sarika.sharma@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 113 ++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 4db3cbaaa661d..7a93d0f35b832 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -542,6 +542,119 @@ void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_peer *peer) } } +static int ath12k_peer_rx_tid_reo_update(struct ath12k *ar, + struct ath12k_peer *peer, + struct ath12k_dp_rx_tid *rx_tid, + u32 ba_win_sz, u16 ssn, + bool update_ssn) +{ + struct ath12k_hal_reo_cmd cmd = {}; + int ret; + struct ath12k_dp_rx_tid_rxq rx_tid_rxq; + + ath12k_dp_init_rx_tid_rxq(&rx_tid_rxq, rx_tid); + + cmd.addr_lo = lower_32_bits(rx_tid_rxq.qbuf.paddr_aligned); + cmd.addr_hi = upper_32_bits(rx_tid_rxq.qbuf.paddr_aligned); + cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; + cmd.upd0 = HAL_REO_CMD_UPD0_BA_WINDOW_SIZE; + cmd.ba_window_size = ba_win_sz; + + if (update_ssn) { + cmd.upd0 |= HAL_REO_CMD_UPD0_SSN; + cmd.upd2 = u32_encode_bits(ssn, HAL_REO_CMD_UPD2_SSN); + } + + ret = ath12k_dp_reo_cmd_send(ar->ab, &rx_tid_rxq, + HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, + NULL); + if (ret) { + ath12k_warn(ar->ab, "failed to update rx tid queue, tid %d (%d)\n", + rx_tid_rxq.tid, ret); + return ret; + } + + rx_tid->ba_win_sz = ba_win_sz; + + return 0; +} + +static int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, + struct ath12k_sta *ahsta, + struct ath12k_dp_rx_tid *rx_tid, + u16 ssn, enum hal_pn_type pn_type) +{ + u32 ba_win_sz = rx_tid->ba_win_sz; + struct ath12k_reoq_buf *buf; + void *vaddr, *vaddr_aligned; + dma_addr_t paddr_aligned; + u8 tid = rx_tid->tid; + u32 hw_desc_sz; + int ret; + + buf = &ahsta->reoq_bufs[tid]; + if (!buf->vaddr) { + /* TODO: Optimize the memory allocation for qos tid based on + * the actual BA window size in REO tid update path. + */ + if (tid == HAL_DESC_REO_NON_QOS_TID) + hw_desc_sz = ath12k_hal_reo_qdesc_size(ba_win_sz, tid); + else + hw_desc_sz = ath12k_hal_reo_qdesc_size(DP_BA_WIN_SZ_MAX, tid); + + vaddr = kzalloc(hw_desc_sz + HAL_LINK_DESC_ALIGN - 1, GFP_ATOMIC); + if (!vaddr) + return -ENOMEM; + + vaddr_aligned = PTR_ALIGN(vaddr, HAL_LINK_DESC_ALIGN); + + ath12k_hal_reo_qdesc_setup(vaddr_aligned, tid, ba_win_sz, + ssn, pn_type); + + paddr_aligned = dma_map_single(ab->dev, vaddr_aligned, hw_desc_sz, + DMA_BIDIRECTIONAL); + ret = dma_mapping_error(ab->dev, paddr_aligned); + if (ret) { + kfree(vaddr); + return ret; + } + + buf->vaddr = vaddr; + buf->paddr_aligned = paddr_aligned; + buf->size = hw_desc_sz; + } + + rx_tid->qbuf = *buf; + rx_tid->active = true; + + return 0; +} + +static int ath12k_dp_prepare_reo_update_elem(struct ath12k_dp *dp, + struct ath12k_peer *peer, + struct ath12k_dp_rx_tid *rx_tid) +{ + struct dp_reo_update_rx_queue_elem *elem; + + lockdep_assert_held(&dp->ab->base_lock); + + elem = kzalloc(sizeof(*elem), GFP_ATOMIC); + if (!elem) + return -ENOMEM; + + elem->peer_id = peer->peer_id; + elem->is_ml_peer = peer->mlo; + elem->ml_peer_id = peer->ml_id; + + ath12k_dp_init_rx_tid_rxq(&elem->rx_tid, rx_tid); + + spin_lock_bh(&dp->reo_rxq_flush_lock); + list_add_tail(&elem->list, &dp->reo_cmd_update_rx_queue_list); + spin_unlock_bh(&dp->reo_rxq_flush_lock); + + return 0; +} + int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id, u8 tid, u32 ba_win_sz, u16 ssn, enum hal_pn_type pn_type) From 1efde18761a45511d0b29f9aef4f0d5c18bbe272 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Fri, 24 Oct 2025 23:45:40 +0530 Subject: [PATCH 074/140] wifi: ath12k: Move DP related functions from peer.c to dp_peer.c file Refactor the structures and APIs defined in files peer.h and peer.c in such a way that the APIs making use of ath12k_peer are moved to newly introduced files dp_peer.h and dp_peer.c. Have this new file dp_peer.c compiled as part of kernel module ath12k.ko. Move these APIs from peer.h and peer.c to dp_peer.h and dp_peer.c: ath12k_peer_find() ath12k_peer_find_by_pdev_idx() ath12k_peer_find_by_addr() ath12k_peer_find_by_ml_id() ath12k_peer_find_by_id() ath12k_peer_exist_by_vdev_id() ath12k_peer_find_by_ast() ath12k_peer_unmap_event() ath12k_peer_map_event() ath12k_peer_get_link_sta() Background: In current ath12k architecture, connected station is represented by struct ath12k_sta. struct ath12k_sta has an array of struct ath12k_link_sta wherein each index represents one link of the connected station. For each ath12k_link_sta, there is a corresponding data path peer which is represented by struct ath12k_peer. Diagrammatic view of the station is as below: ath12k_sta | |-> ath12k_link_sta <--> ath12k_peer | |-> ath12k_link_sta <--> ath12k_peer | |-> ath12k_link_sta <--> ath12k_peer Currently, in control path, ath12k_link_sta and ath12k_peer are used interchangeably, while the data path makes use of ath12k_peer only. For ath12k next-generation driver framework, in order to have a clean segregation between control and data path, use ath12k_link_sta only for control path operations. Station view for the data path is revamped as below: ath12k_dp_peer | |-> ath12k_dp_link_peer | |-> ath12k_dp_link_peer | |-> ath12k_dp_link_peer Introduce the structure ath12k_dp_peer to represent the data path version of corresponding ath12k_sta. This ath12k_dp_peer contains the fields used in the per packet Tx Rx paths applicable across all the links and maintains an array of ath12k_dp_link_peer. Per packet Tx and Rx path operates on ath12k_dp_peer. This ath12k_dp_peer is a standalone new object and has back pointer reference to ieee80211_sta. Rename ath12k_peer to ath12k_dp_link_peer and move the fields which are common across all the links to ath12k_dp_peer. Add the fields specific to a link which are mostly for statistics and monitor usage to ath12k_dp_link_peer. Final view of station in ath12k next-generation driver is shown as below: Control Path Data Path ------------------------------------------------------------------- ath12k_sta ath12k_dp_peer | | |-> ath12k_link_sta <----> |-> ath12k_dp_link_peer | | |-> ath12k_link_sta <----> |-> ath12k_dp_link_peer | | |-> ath12k_link_sta <----> |-> ath12k_dp_link_peer This patch and the subsequent patches in this series are meant to achieve the modularization of peer object as mentioned above. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251024181548.3255166-2-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 1 + drivers/net/wireless/ath/ath12k/dp_peer.c | 207 ++++++++++++++++++++++ drivers/net/wireless/ath/ath12k/dp_peer.h | 82 +++++++++ drivers/net/wireless/ath/ath12k/peer.c | 172 ------------------ drivers/net/wireless/ath/ath12k/peer.h | 97 +--------- 5 files changed, 292 insertions(+), 267 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/dp_peer.c create mode 100644 drivers/net/wireless/ath/ath12k/dp_peer.h diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index 32a0f30faf922..d397bc494cf25 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -11,6 +11,7 @@ ath12k-y += core.o \ dp_tx.o \ dp_rx.o \ dp_htt.o \ + dp_peer.o \ debug.o \ ce.o \ peer.o \ diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c new file mode 100644 index 0000000000000..e32d3ea76a6f8 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "core.h" +#include "dp_peer.h" +#include "debug.h" + +struct ath12k_peer *ath12k_peer_find(struct ath12k_base *ab, int vdev_id, + const u8 *addr) +{ + struct ath12k_peer *peer; + + lockdep_assert_held(&ab->base_lock); + + list_for_each_entry(peer, &ab->peers, list) { + if (peer->vdev_id != vdev_id) + continue; + if (!ether_addr_equal(peer->addr, addr)) + continue; + + return peer; + } + + return NULL; +} + +struct ath12k_peer *ath12k_peer_find_by_pdev_idx(struct ath12k_base *ab, + u8 pdev_idx, const u8 *addr) +{ + struct ath12k_peer *peer; + + lockdep_assert_held(&ab->base_lock); + + list_for_each_entry(peer, &ab->peers, list) { + if (peer->pdev_idx != pdev_idx) + continue; + if (!ether_addr_equal(peer->addr, addr)) + continue; + + return peer; + } + + return NULL; +} + +struct ath12k_peer *ath12k_peer_find_by_addr(struct ath12k_base *ab, + const u8 *addr) +{ + struct ath12k_peer *peer; + + lockdep_assert_held(&ab->base_lock); + + list_for_each_entry(peer, &ab->peers, list) { + if (!ether_addr_equal(peer->addr, addr)) + continue; + + return peer; + } + + return NULL; +} +EXPORT_SYMBOL(ath12k_peer_find_by_addr); + +static struct ath12k_peer *ath12k_peer_find_by_ml_id(struct ath12k_base *ab, + int ml_peer_id) +{ + struct ath12k_peer *peer; + + lockdep_assert_held(&ab->base_lock); + + list_for_each_entry(peer, &ab->peers, list) + if (ml_peer_id == peer->ml_id) + return peer; + + return NULL; +} + +struct ath12k_peer *ath12k_peer_find_by_id(struct ath12k_base *ab, + int peer_id) +{ + struct ath12k_peer *peer; + + lockdep_assert_held(&ab->base_lock); + + if (peer_id == HAL_INVALID_PEERID) + return NULL; + + if (peer_id & ATH12K_PEER_ML_ID_VALID) + return ath12k_peer_find_by_ml_id(ab, peer_id); + + list_for_each_entry(peer, &ab->peers, list) + if (peer_id == peer->peer_id) + return peer; + + return NULL; +} + +bool ath12k_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id) +{ + struct ath12k_peer *peer; + + spin_lock_bh(&ab->base_lock); + + list_for_each_entry(peer, &ab->peers, list) { + if (vdev_id == peer->vdev_id) { + spin_unlock_bh(&ab->base_lock); + return true; + } + } + spin_unlock_bh(&ab->base_lock); + return false; +} + +struct ath12k_peer *ath12k_peer_find_by_ast(struct ath12k_base *ab, + int ast_hash) +{ + struct ath12k_peer *peer; + + lockdep_assert_held(&ab->base_lock); + + list_for_each_entry(peer, &ab->peers, list) + if (ast_hash == peer->ast_hash) + return peer; + + return NULL; +} + +void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) +{ + struct ath12k_peer *peer; + + spin_lock_bh(&ab->base_lock); + + peer = ath12k_peer_find_by_id(ab, peer_id); + if (!peer) { + ath12k_warn(ab, "peer-unmap-event: unknown peer id %d\n", + peer_id); + goto exit; + } + + ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "htt peer unmap vdev %d peer %pM id %d\n", + peer->vdev_id, peer->addr, peer_id); + + list_del(&peer->list); + kfree(peer); + wake_up(&ab->peer_mapping_wq); + +exit: + spin_unlock_bh(&ab->base_lock); +} + +void ath12k_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, + u8 *mac_addr, u16 ast_hash, u16 hw_peer_id) +{ + struct ath12k_peer *peer; + + spin_lock_bh(&ab->base_lock); + peer = ath12k_peer_find(ab, vdev_id, mac_addr); + if (!peer) { + peer = kzalloc(sizeof(*peer), GFP_ATOMIC); + if (!peer) + goto exit; + + peer->vdev_id = vdev_id; + peer->peer_id = peer_id; + peer->ast_hash = ast_hash; + peer->hw_peer_id = hw_peer_id; + ether_addr_copy(peer->addr, mac_addr); + list_add(&peer->list, &ab->peers); + wake_up(&ab->peer_mapping_wq); + } + + ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "htt peer map vdev %d peer %pM id %d\n", + vdev_id, mac_addr, peer_id); + +exit: + spin_unlock_bh(&ab->base_lock); +} + +struct ath12k_link_sta *ath12k_peer_get_link_sta(struct ath12k_base *ab, + struct ath12k_peer *peer) +{ + struct ath12k_sta *ahsta; + struct ath12k_link_sta *arsta; + + if (!peer->sta) + return NULL; + + ahsta = ath12k_sta_to_ahsta(peer->sta); + if (peer->ml_id & ATH12K_PEER_ML_ID_VALID) { + if (!(ahsta->links_map & BIT(peer->link_id))) { + ath12k_warn(ab, "peer %pM id %d link_id %d can't found in STA link_map 0x%x\n", + peer->addr, peer->peer_id, peer->link_id, + ahsta->links_map); + return NULL; + } + arsta = rcu_dereference(ahsta->link[peer->link_id]); + if (!arsta) + return NULL; + } else { + arsta = &ahsta->deflink; + } + return arsta; +} diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h new file mode 100644 index 0000000000000..19f01d69e5d3c --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_DP_PEER_H +#define ATH12K_DP_PEER_H + +#include "dp_rx.h" + +struct ppdu_user_delayba { + u16 sw_peer_id; + u32 info0; + u16 ru_end; + u16 ru_start; + u32 info1; + u32 rate_flags; + u32 resp_rate_flags; +}; + +#define ATH12K_PEER_ML_ID_VALID BIT(13) + +struct ath12k_peer { + struct list_head list; + struct ieee80211_sta *sta; + int vdev_id; + u8 addr[ETH_ALEN]; + int peer_id; + u16 ast_hash; + u8 pdev_idx; + u16 hw_peer_id; + + /* protected by ab->data_lock */ + struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; + struct ath12k_dp_rx_tid rx_tid[IEEE80211_NUM_TIDS + 1]; + + /* Info used in MMIC verification of + * RX fragments + */ + struct crypto_shash *tfm_mmic; + u8 mcast_keyidx; + u8 ucast_keyidx; + u16 sec_type; + u16 sec_type_grp; + struct ppdu_user_delayba ppdu_stats_delayba; + bool delayba_flag; + bool is_authorized; + bool mlo; + /* protected by ab->data_lock */ + bool dp_setup_done; + + u16 ml_id; + + /* any other ML info common for all partners can be added + * here and would be same for all partner peers. + */ + u8 ml_addr[ETH_ALEN]; + + /* To ensure only certain work related to dp is done once */ + bool primary_link; + + /* for reference to ath12k_link_sta */ + u8 link_id; + bool ucast_ra_only; +}; + +void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); +void ath12k_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, + u8 *mac_addr, u16 ast_hash, u16 hw_peer_id); +struct ath12k_peer *ath12k_peer_find(struct ath12k_base *ab, int vdev_id, + const u8 *addr); +struct ath12k_peer *ath12k_peer_find_by_addr(struct ath12k_base *ab, + const u8 *addr); +struct ath12k_peer *ath12k_peer_find_by_id(struct ath12k_base *ab, int peer_id); +bool ath12k_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id); +struct ath12k_peer *ath12k_peer_find_by_ast(struct ath12k_base *ab, int ast_hash); +struct ath12k_peer *ath12k_peer_find_by_pdev_idx(struct ath12k_base *ab, + u8 pdev_idx, const u8 *addr); +struct ath12k_link_sta *ath12k_peer_get_link_sta(struct ath12k_base *ab, + struct ath12k_peer *peer); +#endif diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index ce15642986568..1e2526bb11865 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -25,178 +25,6 @@ struct ath12k_ml_peer *ath12k_peer_ml_find(struct ath12k_hw *ah, const u8 *addr) } EXPORT_SYMBOL(ath12k_peer_ml_find); -struct ath12k_peer *ath12k_peer_find(struct ath12k_base *ab, int vdev_id, - const u8 *addr) -{ - struct ath12k_peer *peer; - - lockdep_assert_held(&ab->base_lock); - - list_for_each_entry(peer, &ab->peers, list) { - if (peer->vdev_id != vdev_id) - continue; - if (!ether_addr_equal(peer->addr, addr)) - continue; - - return peer; - } - - return NULL; -} - -static struct ath12k_peer *ath12k_peer_find_by_pdev_idx(struct ath12k_base *ab, - u8 pdev_idx, const u8 *addr) -{ - struct ath12k_peer *peer; - - lockdep_assert_held(&ab->base_lock); - - list_for_each_entry(peer, &ab->peers, list) { - if (peer->pdev_idx != pdev_idx) - continue; - if (!ether_addr_equal(peer->addr, addr)) - continue; - - return peer; - } - - return NULL; -} - -struct ath12k_peer *ath12k_peer_find_by_addr(struct ath12k_base *ab, - const u8 *addr) -{ - struct ath12k_peer *peer; - - lockdep_assert_held(&ab->base_lock); - - list_for_each_entry(peer, &ab->peers, list) { - if (!ether_addr_equal(peer->addr, addr)) - continue; - - return peer; - } - - return NULL; -} -EXPORT_SYMBOL(ath12k_peer_find_by_addr); - -static struct ath12k_peer *ath12k_peer_find_by_ml_id(struct ath12k_base *ab, - int ml_peer_id) -{ - struct ath12k_peer *peer; - - lockdep_assert_held(&ab->base_lock); - - list_for_each_entry(peer, &ab->peers, list) - if (ml_peer_id == peer->ml_id) - return peer; - - return NULL; -} - -struct ath12k_peer *ath12k_peer_find_by_id(struct ath12k_base *ab, - int peer_id) -{ - struct ath12k_peer *peer; - - lockdep_assert_held(&ab->base_lock); - - if (peer_id == HAL_INVALID_PEERID) - return NULL; - - if (peer_id & ATH12K_PEER_ML_ID_VALID) - return ath12k_peer_find_by_ml_id(ab, peer_id); - - list_for_each_entry(peer, &ab->peers, list) - if (peer_id == peer->peer_id) - return peer; - - return NULL; -} - -bool ath12k_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id) -{ - struct ath12k_peer *peer; - - spin_lock_bh(&ab->base_lock); - - list_for_each_entry(peer, &ab->peers, list) { - if (vdev_id == peer->vdev_id) { - spin_unlock_bh(&ab->base_lock); - return true; - } - } - spin_unlock_bh(&ab->base_lock); - return false; -} - -struct ath12k_peer *ath12k_peer_find_by_ast(struct ath12k_base *ab, - int ast_hash) -{ - struct ath12k_peer *peer; - - lockdep_assert_held(&ab->base_lock); - - list_for_each_entry(peer, &ab->peers, list) - if (ast_hash == peer->ast_hash) - return peer; - - return NULL; -} - -void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) -{ - struct ath12k_peer *peer; - - spin_lock_bh(&ab->base_lock); - - peer = ath12k_peer_find_by_id(ab, peer_id); - if (!peer) { - ath12k_warn(ab, "peer-unmap-event: unknown peer id %d\n", - peer_id); - goto exit; - } - - ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "htt peer unmap vdev %d peer %pM id %d\n", - peer->vdev_id, peer->addr, peer_id); - - list_del(&peer->list); - kfree(peer); - wake_up(&ab->peer_mapping_wq); - -exit: - spin_unlock_bh(&ab->base_lock); -} - -void ath12k_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, - u8 *mac_addr, u16 ast_hash, u16 hw_peer_id) -{ - struct ath12k_peer *peer; - - spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, vdev_id, mac_addr); - if (!peer) { - peer = kzalloc(sizeof(*peer), GFP_ATOMIC); - if (!peer) - goto exit; - - peer->vdev_id = vdev_id; - peer->peer_id = peer_id; - peer->ast_hash = ast_hash; - peer->hw_peer_id = hw_peer_id; - ether_addr_copy(peer->addr, mac_addr); - list_add(&peer->list, &ab->peers); - wake_up(&ab->peer_mapping_wq); - } - - ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "htt peer map vdev %d peer %pM id %d\n", - vdev_id, mac_addr, peer_id); - -exit: - spin_unlock_bh(&ab->base_lock); -} - static int ath12k_wait_for_peer_common(struct ath12k_base *ab, int vdev_id, const u8 *addr, bool expect_mapped) { diff --git a/drivers/net/wireless/ath/ath12k/peer.h b/drivers/net/wireless/ath/ath12k/peer.h index 44afc0b7dd53e..81e9bcc067ff4 100644 --- a/drivers/net/wireless/ath/ath12k/peer.h +++ b/drivers/net/wireless/ath/ath12k/peer.h @@ -1,69 +1,13 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 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 ATH12K_PEER_H #define ATH12K_PEER_H -#include "dp_rx.h" - -struct ppdu_user_delayba { - u16 sw_peer_id; - u32 info0; - u16 ru_end; - u16 ru_start; - u32 info1; - u32 rate_flags; - u32 resp_rate_flags; -}; - -#define ATH12K_PEER_ML_ID_VALID BIT(13) - -struct ath12k_peer { - struct list_head list; - struct ieee80211_sta *sta; - int vdev_id; - u8 addr[ETH_ALEN]; - int peer_id; - u16 ast_hash; - u8 pdev_idx; - u16 hw_peer_id; - - /* protected by ab->data_lock */ - struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; - struct ath12k_dp_rx_tid rx_tid[IEEE80211_NUM_TIDS + 1]; - - /* Info used in MMIC verification of - * RX fragments - */ - struct crypto_shash *tfm_mmic; - u8 mcast_keyidx; - u8 ucast_keyidx; - u16 sec_type; - u16 sec_type_grp; - struct ppdu_user_delayba ppdu_stats_delayba; - bool delayba_flag; - bool is_authorized; - bool mlo; - /* protected by ab->data_lock */ - bool dp_setup_done; - - u16 ml_id; - - /* any other ML info common for all partners can be added - * here and would be same for all partner peers. - */ - u8 ml_addr[ETH_ALEN]; - - /* To ensure only certain work related to dp is done once */ - bool primary_link; - - /* for reference to ath12k_link_sta */ - u8 link_id; - bool ucast_ra_only; -}; +#include "dp_peer.h" struct ath12k_ml_peer { struct list_head list; @@ -71,14 +15,6 @@ struct ath12k_ml_peer { u16 id; }; -void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); -void ath12k_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, - u8 *mac_addr, u16 ast_hash, u16 hw_peer_id); -struct ath12k_peer *ath12k_peer_find(struct ath12k_base *ab, int vdev_id, - const u8 *addr); -struct ath12k_peer *ath12k_peer_find_by_addr(struct ath12k_base *ab, - const u8 *addr); -struct ath12k_peer *ath12k_peer_find_by_id(struct ath12k_base *ab, int peer_id); void ath12k_peer_cleanup(struct ath12k *ar, u32 vdev_id); int ath12k_peer_delete(struct ath12k *ar, u32 vdev_id, u8 *addr); int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, @@ -86,38 +22,9 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ath12k_wmi_peer_create_arg *arg); int ath12k_wait_for_peer_delete_done(struct ath12k *ar, u32 vdev_id, const u8 *addr); -bool ath12k_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id); -struct ath12k_peer *ath12k_peer_find_by_ast(struct ath12k_base *ab, int ast_hash); int ath12k_peer_ml_create(struct ath12k_hw *ah, struct ieee80211_sta *sta); int ath12k_peer_ml_delete(struct ath12k_hw *ah, struct ieee80211_sta *sta); int ath12k_peer_mlo_link_peers_delete(struct ath12k_vif *ahvif, struct ath12k_sta *ahsta); struct ath12k_ml_peer *ath12k_peer_ml_find(struct ath12k_hw *ah, const u8 *addr); -static inline -struct ath12k_link_sta *ath12k_peer_get_link_sta(struct ath12k_base *ab, - struct ath12k_peer *peer) -{ - struct ath12k_sta *ahsta; - struct ath12k_link_sta *arsta; - - if (!peer->sta) - return NULL; - - ahsta = ath12k_sta_to_ahsta(peer->sta); - if (peer->ml_id & ATH12K_PEER_ML_ID_VALID) { - if (!(ahsta->links_map & BIT(peer->link_id))) { - ath12k_warn(ab, "peer %pM id %d link_id %d can't found in STA link_map 0x%x\n", - peer->addr, peer->peer_id, peer->link_id, - ahsta->links_map); - return NULL; - } - arsta = rcu_dereference(ahsta->link[peer->link_id]); - if (!arsta) - return NULL; - } else { - arsta = &ahsta->deflink; - } - return arsta; -} - #endif /* _PEER_H_ */ From fe043d7aa13dc8c9dafd0e374a4d3b3e3fd4d6dc Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Fri, 24 Oct 2025 23:45:41 +0530 Subject: [PATCH 075/140] wifi: ath12k: Rename ath12k_peer to ath12k_dp_link_peer Rename ath12k_peer to ath12k_dp_link_peer for all instances and rename the following find APIs accordingly to reflect the API names as per the structural name change. APIs renamed: ath12k_peer_find() ath12k_peer_find_by_pdev_idx() ath12k_peer_find_by_addr() ath12k_peer_find_by_ml_id() ath12k_peer_find_by_id() ath12k_peer_find_by_ast() ath12k_peer_exist_by_vdev_id() ath12k_peer_get_link_sta() Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251024181548.3255166-3-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 8 +-- drivers/net/wireless/ath/ath12k/dp.h | 2 +- drivers/net/wireless/ath/ath12k/dp_htt.c | 28 ++++---- drivers/net/wireless/ath/ath12k/dp_mon.c | 16 ++--- drivers/net/wireless/ath/ath12k/dp_peer.c | 64 ++++++++++--------- drivers/net/wireless/ath/ath12k/dp_peer.h | 34 +++++----- drivers/net/wireless/ath/ath12k/dp_rx.c | 35 +++++----- drivers/net/wireless/ath/ath12k/dp_rx.h | 10 +-- drivers/net/wireless/ath/ath12k/mac.c | 50 +++++++++------ drivers/net/wireless/ath/ath12k/peer.c | 22 ++++--- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 18 +++--- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 4 +- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 12 ++-- drivers/net/wireless/ath/ath12k/wifi7/hw.c | 2 +- drivers/net/wireless/ath/ath12k/wmi.c | 5 +- 15 files changed, 164 insertions(+), 146 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index a3f97ef96686d..afad0c2cb6b9b 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -23,12 +23,12 @@ enum ath12k_dp_desc_type { void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr) { struct ath12k_base *ab = ar->ab; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; /* TODO: Any other peer specific DP cleanup */ spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, vdev_id, addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, addr); if (!peer) { ath12k_warn(ab, "failed to lookup peer %pM on vdev %d\n", addr, vdev_id); @@ -50,7 +50,7 @@ void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr) int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr) { struct ath12k_base *ab = ar->ab; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; u32 reo_dest; int ret = 0, tid; @@ -89,7 +89,7 @@ int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr) peer_clean: spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, vdev_id, addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, addr); if (!peer) { ath12k_warn(ab, "failed to find the peer to del rx tid\n"); spin_unlock_bh(&ab->base_lock); diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 4318ec13cb8f1..43a05c6f78ecd 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -14,7 +14,7 @@ #define MAX_RXDMA_PER_PDEV 2 struct ath12k_base; -struct ath12k_peer; +struct ath12k_dp_link_peer; struct ath12k_dp; struct ath12k_vif; struct ath12k_link_vif; diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index 1a0d3e4ac8bb7..cae5a90c1c659 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -188,7 +188,7 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, { struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_base *ab = dp->ab; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_link_sta *arsta; struct htt_ppdu_stats_user_rate *user_rate; struct ath12k_per_peer_tx_stats *peer_stats = &dp_pdev->peer_tx_stats; @@ -273,7 +273,7 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, rcu_read_lock(); spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, usr_stats->peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, usr_stats->peer_id); if (!peer || !peer->sta) { spin_unlock_bh(&ab->base_lock); @@ -281,7 +281,7 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, return; } - arsta = ath12k_peer_get_link_sta(ab, peer); + arsta = ath12k_dp_link_peer_to_link_sta(ab, peer); if (!arsta) { spin_unlock_bh(&ab->base_lock); rcu_read_unlock(); @@ -403,7 +403,7 @@ struct htt_ppdu_stats_info *ath12k_dp_htt_get_ppdu_desc(struct ath12k_pdev_dp *d return ppdu_info; } -static void ath12k_copy_to_delay_stats(struct ath12k_peer *peer, +static void ath12k_copy_to_delay_stats(struct ath12k_dp_link_peer *peer, struct htt_ppdu_user_stats *usr_stats) { peer->ppdu_stats_delayba.sw_peer_id = le16_to_cpu(usr_stats->rate.sw_peer_id); @@ -418,7 +418,7 @@ static void ath12k_copy_to_delay_stats(struct ath12k_peer *peer, peer->delayba_flag = true; } -static void ath12k_copy_to_bar(struct ath12k_peer *peer, +static void ath12k_copy_to_bar(struct ath12k_dp_link_peer *peer, struct htt_ppdu_user_stats *usr_stats) { usr_stats->rate.sw_peer_id = cpu_to_le16(peer->ppdu_stats_delayba.sw_peer_id); @@ -439,7 +439,7 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_htt_ppdu_stats_msg *msg; struct htt_ppdu_stats_info *ppdu_info; - struct ath12k_peer *peer = NULL; + struct ath12k_dp_link_peer *peer = NULL; struct htt_ppdu_user_stats *usr_stats = NULL; u32 peer_id = 0; struct ath12k_pdev_dp *dp_pdev; @@ -508,7 +508,7 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, for (i = 0; i < ppdu_info->ppdu_stats.common.num_users; i++) { peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); if (!peer) { spin_unlock_bh(&ab->base_lock); continue; @@ -527,7 +527,7 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, for (i = 0; i < ppdu_info->bar_num_users; i++) { peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); if (!peer) { spin_unlock_bh(&ab->base_lock); continue; @@ -623,7 +623,7 @@ void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16); ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32), peer_mac_h16, mac_addr); - ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, 0, 0); + ath12k_dp_link_peer_map_event(ab, vdev_id, peer_id, mac_addr, 0, 0); break; case HTT_T2H_MSG_TYPE_PEER_MAP2: vdev_id = le32_get_bits(resp->peer_map_ev.info, @@ -638,8 +638,8 @@ void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL); hw_peer_id = le32_get_bits(resp->peer_map_ev.info1, HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID); - ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash, - hw_peer_id); + ath12k_dp_link_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash, + hw_peer_id); break; case HTT_T2H_MSG_TYPE_PEER_MAP3: vdev_id = le32_get_bits(resp->peer_map_ev.info, @@ -654,14 +654,14 @@ void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab, HTT_T2H_PEER_MAP3_INFO2_AST_HASH_VAL); hw_peer_id = le32_get_bits(resp->peer_map_ev.info2, HTT_T2H_PEER_MAP3_INFO2_HW_PEER_ID); - ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash, - hw_peer_id); + ath12k_dp_link_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash, + hw_peer_id); break; case HTT_T2H_MSG_TYPE_PEER_UNMAP: case HTT_T2H_MSG_TYPE_PEER_UNMAP2: peer_id = le32_get_bits(resp->peer_unmap_ev.info, HTT_T2H_PEER_UNMAP_INFO_PEER_ID); - ath12k_peer_unmap_event(ab, peer_id); + ath12k_dp_link_peer_unmap_event(ab, peer_id); break; case HTT_T2H_MSG_TYPE_PPDU_STATS_IND: ath12k_htt_pull_ppdu_stats(ab, skb); diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 27cf53303bf82..c76edd9b5dfc8 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2304,7 +2304,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct ieee80211_rx_status *rx_status; struct ieee80211_radiotap_he *he = NULL; struct ieee80211_sta *pubsta = NULL; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); struct hal_rx_desc_data rx_info; bool is_mcbc = rxcb->is_mcbc; @@ -2324,7 +2324,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, spin_lock_bh(&ab->base_lock); rx_info.addr2_present = false; - peer = ath12k_dp_rx_h_find_peer(ab, msdu, &rx_info); + peer = ath12k_dp_rx_h_find_link_peer(ab, msdu, &rx_info); if (peer && peer->sta) { pubsta = peer->sta; if (pubsta->valid_links) { @@ -3672,13 +3672,13 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, struct ath12k_link_sta *arsta; struct ath12k_rx_peer_stats *rx_stats = NULL; struct hal_rx_user_status *user_stats = &ppdu_info->userstats[uid]; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; u32 num_msdu; if (user_stats->ast_index == 0 || user_stats->ast_index == 0xFFFF) return; - peer = ath12k_peer_find_by_ast(ab, user_stats->ast_index); + peer = ath12k_dp_link_peer_find_by_ast(ab, user_stats->ast_index); if (!peer) { ath12k_warn(ab, "peer ast idx %d can't be found\n", @@ -3686,7 +3686,7 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, return; } - arsta = ath12k_peer_get_link_sta(ab, peer); + arsta = ath12k_dp_link_peer_to_link_sta(ab, peer); if (!arsta) { ath12k_warn(ab, "link sta not found on peer %pM id %d\n", peer->addr, peer->peer_id); @@ -3805,7 +3805,7 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, struct hal_srng *srng; struct dp_rxdma_mon_ring *buf_ring; struct ath12k_link_sta *arsta; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct sk_buff_head skb_list; u64 cookie; int num_buffs_reaped = 0, srng_id, buf_id; @@ -3920,7 +3920,7 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, rcu_read_lock(); spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, ppdu_info->peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, ppdu_info->peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DATA, "failed to find the peer with monitor peer_id %d\n", @@ -3929,7 +3929,7 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, } if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) { - arsta = ath12k_peer_get_link_sta(ab, peer); + arsta = ath12k_dp_link_peer_to_link_sta(ab, peer); if (!arsta) { ath12k_warn(ab, "link sta not found on peer %pM id %d\n", peer->addr, peer->peer_id); diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index e32d3ea76a6f8..843369a00d3e4 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -8,10 +8,11 @@ #include "dp_peer.h" #include "debug.h" -struct ath12k_peer *ath12k_peer_find(struct ath12k_base *ab, int vdev_id, - const u8 *addr) +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_base *ab, + int vdev_id, const u8 *addr) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; lockdep_assert_held(&ab->base_lock); @@ -27,10 +28,11 @@ struct ath12k_peer *ath12k_peer_find(struct ath12k_base *ab, int vdev_id, return NULL; } -struct ath12k_peer *ath12k_peer_find_by_pdev_idx(struct ath12k_base *ab, - u8 pdev_idx, const u8 *addr) +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_pdev_and_addr(struct ath12k_base *ab, u8 pdev_idx, + const u8 *addr) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; lockdep_assert_held(&ab->base_lock); @@ -46,10 +48,10 @@ struct ath12k_peer *ath12k_peer_find_by_pdev_idx(struct ath12k_base *ab, return NULL; } -struct ath12k_peer *ath12k_peer_find_by_addr(struct ath12k_base *ab, - const u8 *addr) +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_addr(struct ath12k_base *ab, const u8 *addr) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; lockdep_assert_held(&ab->base_lock); @@ -62,12 +64,12 @@ struct ath12k_peer *ath12k_peer_find_by_addr(struct ath12k_base *ab, return NULL; } -EXPORT_SYMBOL(ath12k_peer_find_by_addr); +EXPORT_SYMBOL(ath12k_dp_link_peer_find_by_addr); -static struct ath12k_peer *ath12k_peer_find_by_ml_id(struct ath12k_base *ab, - int ml_peer_id) +static struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_ml_id(struct ath12k_base *ab, int ml_peer_id) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; lockdep_assert_held(&ab->base_lock); @@ -78,10 +80,10 @@ static struct ath12k_peer *ath12k_peer_find_by_ml_id(struct ath12k_base *ab, return NULL; } -struct ath12k_peer *ath12k_peer_find_by_id(struct ath12k_base *ab, - int peer_id) +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_id(struct ath12k_base *ab, int peer_id) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; lockdep_assert_held(&ab->base_lock); @@ -89,7 +91,7 @@ struct ath12k_peer *ath12k_peer_find_by_id(struct ath12k_base *ab, return NULL; if (peer_id & ATH12K_PEER_ML_ID_VALID) - return ath12k_peer_find_by_ml_id(ab, peer_id); + return ath12k_dp_link_peer_find_by_ml_id(ab, peer_id); list_for_each_entry(peer, &ab->peers, list) if (peer_id == peer->peer_id) @@ -98,9 +100,9 @@ struct ath12k_peer *ath12k_peer_find_by_id(struct ath12k_base *ab, return NULL; } -bool ath12k_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id) +bool ath12k_dp_link_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; spin_lock_bh(&ab->base_lock); @@ -114,10 +116,10 @@ bool ath12k_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id) return false; } -struct ath12k_peer *ath12k_peer_find_by_ast(struct ath12k_base *ab, - int ast_hash) +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_ast(struct ath12k_base *ab, int ast_hash) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; lockdep_assert_held(&ab->base_lock); @@ -128,13 +130,13 @@ struct ath12k_peer *ath12k_peer_find_by_ast(struct ath12k_base *ab, return NULL; } -void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) +void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); if (!peer) { ath12k_warn(ab, "peer-unmap-event: unknown peer id %d\n", peer_id); @@ -152,13 +154,13 @@ void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) spin_unlock_bh(&ab->base_lock); } -void ath12k_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, - u8 *mac_addr, u16 ast_hash, u16 hw_peer_id) +void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, + u8 *mac_addr, u16 ast_hash, u16 hw_peer_id) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, vdev_id, mac_addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, mac_addr); if (!peer) { peer = kzalloc(sizeof(*peer), GFP_ATOMIC); if (!peer) @@ -180,8 +182,8 @@ void ath12k_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, spin_unlock_bh(&ab->base_lock); } -struct ath12k_link_sta *ath12k_peer_get_link_sta(struct ath12k_base *ab, - struct ath12k_peer *peer) +struct ath12k_link_sta *ath12k_dp_link_peer_to_link_sta(struct ath12k_base *ab, + struct ath12k_dp_link_peer *peer) { struct ath12k_sta *ahsta; struct ath12k_link_sta *arsta; diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h index 19f01d69e5d3c..aec73d8e35ce6 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.h +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h @@ -21,7 +21,7 @@ struct ppdu_user_delayba { #define ATH12K_PEER_ML_ID_VALID BIT(13) -struct ath12k_peer { +struct ath12k_dp_link_peer { struct list_head list; struct ieee80211_sta *sta; int vdev_id; @@ -65,18 +65,22 @@ struct ath12k_peer { bool ucast_ra_only; }; -void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); -void ath12k_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, - u8 *mac_addr, u16 ast_hash, u16 hw_peer_id); -struct ath12k_peer *ath12k_peer_find(struct ath12k_base *ab, int vdev_id, - const u8 *addr); -struct ath12k_peer *ath12k_peer_find_by_addr(struct ath12k_base *ab, - const u8 *addr); -struct ath12k_peer *ath12k_peer_find_by_id(struct ath12k_base *ab, int peer_id); -bool ath12k_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id); -struct ath12k_peer *ath12k_peer_find_by_ast(struct ath12k_base *ab, int ast_hash); -struct ath12k_peer *ath12k_peer_find_by_pdev_idx(struct ath12k_base *ab, - u8 pdev_idx, const u8 *addr); -struct ath12k_link_sta *ath12k_peer_get_link_sta(struct ath12k_base *ab, - struct ath12k_peer *peer); +void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); +void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, + u8 *mac_addr, u16 ast_hash, u16 hw_peer_id); +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_base *ab, + int vdev_id, const u8 *addr); +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_addr(struct ath12k_base *ab, const u8 *addr); +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_id(struct ath12k_base *ab, int peer_id); +bool ath12k_dp_link_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id); +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_ast(struct ath12k_base *ab, int ast_hash); +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_pdev_and_addr(struct ath12k_base *ab, u8 pdev_idx, + const u8 *addr); +struct ath12k_link_sta *ath12k_dp_link_peer_to_link_sta(struct ath12k_base *ab, + struct ath12k_dp_link_peer *peer); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 7a93d0f35b832..5e41f2d1318cd 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -523,7 +523,7 @@ void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, __skb_queue_purge(&rx_tid->rx_frags); } -void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_peer *peer) +void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer *peer) { struct ath12k_dp_rx_tid *rx_tid; int i; @@ -661,7 +661,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ { struct ath12k_base *ab = ar->ab; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_sta *ahsta; struct ath12k_dp_rx_tid *rx_tid; dma_addr_t paddr_aligned; @@ -669,7 +669,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, vdev_id, peer_mac); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, peer_mac); if (!peer) { spin_unlock_bh(&ab->base_lock); ath12k_warn(ab, "failed to find the peer to set up rx tid\n"); @@ -804,7 +804,7 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, u8 link_id) { struct ath12k_base *ab = ar->ab; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(params->sta); struct ath12k_link_sta *arsta; int vdev_id; @@ -822,7 +822,7 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, vdev_id, arsta->addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, arsta->addr); if (!peer) { spin_unlock_bh(&ab->base_lock); ath12k_warn(ab, "failed to find the peer to stop rx aggregation\n"); @@ -855,7 +855,7 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, struct ath12k *ar = arvif->ar; struct ath12k_base *ab = ar->ab; struct ath12k_hal_reo_cmd cmd = {}; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_dp_rx_tid *rx_tid; struct ath12k_dp_rx_tid_rxq rx_tid_rxq; u8 tid; @@ -870,7 +870,8 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, arvif->vdev_id, peer_addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, arvif->vdev_id, + peer_addr); if (!peer) { spin_unlock_bh(&ab->base_lock); ath12k_warn(ab, "failed to find the peer %pM to configure pn replay detection\n", @@ -1215,23 +1216,23 @@ void ath12k_dp_rx_h_undecap(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu } } -struct ath12k_peer * -ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu, - struct hal_rx_desc_data *rx_info) +struct ath12k_dp_link_peer * +ath12k_dp_rx_h_find_link_peer(struct ath12k_base *ab, struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info) { struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); - struct ath12k_peer *peer = NULL; + struct ath12k_dp_link_peer *peer = NULL; lockdep_assert_held(&ab->base_lock); if (rxcb->peer_id) - peer = ath12k_peer_find_by_id(ab, rxcb->peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, rxcb->peer_id); if (peer) return peer; if (rx_info->addr2_present) - peer = ath12k_peer_find_by_addr(ab, rx_info->addr2); + peer = ath12k_dp_link_peer_find_by_addr(ab, rx_info->addr2); return peer; } @@ -1381,7 +1382,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc struct ath12k_base *ab = dp->ab; struct ieee80211_rx_status *rx_status; struct ieee80211_sta *pubsta; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); struct ieee80211_rx_status *status = rx_info->rx_status; u8 decap = rx_info->decap_type; @@ -1389,7 +1390,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc bool is_eapol = rxcb->is_eapol; spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_rx_h_find_peer(ab, msdu, rx_info); + peer = ath12k_dp_rx_h_find_link_peer(ab, msdu, rx_info); pubsta = peer ? peer->sta : NULL; @@ -1510,7 +1511,7 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev { struct ath12k_base *ab = ar->ab; struct crypto_shash *tfm; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_dp_rx_tid *rx_tid; int i; @@ -1520,7 +1521,7 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, vdev_id, peer_mac); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, peer_mac); if (!peer) { spin_unlock_bh(&ab->base_lock); crypto_free_shash(tfm); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 1a97264f0328f..ff568254b686f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -220,9 +220,9 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, const u8 *peer_addr, enum set_key_cmd key_cmd, struct ieee80211_key_conf *key); -void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_peer *peer); +void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer *peer); void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar, - struct ath12k_peer *peer, u8 tid); + struct ath12k_dp_link_peer *peer, u8 tid); int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id, u8 tid, u32 ba_win_sz, u16 ssn, enum hal_pn_type pn_type); @@ -243,9 +243,9 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, struct hal_rx_desc *desc); -struct ath12k_peer * -ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu, - struct hal_rx_desc_data *rx_info); +struct ath12k_dp_link_peer * +ath12k_dp_rx_h_find_link_peer(struct ath12k_base *ab, struct sk_buff *msdu, + struct hal_rx_desc_data *rx_info); u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, struct hal_rx_desc *desc); u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index f480fa18ead6a..f43d78f38b330 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1171,7 +1171,7 @@ static int ath12k_mac_set_kickout(struct ath12k_link_vif *arvif) void ath12k_mac_peer_cleanup_all(struct ath12k *ar) { - struct ath12k_peer *peer, *tmp; + struct ath12k_dp_link_peer *peer, *tmp; struct ath12k_base *ab = ar->ab; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -3731,7 +3731,7 @@ static void ath12k_bss_assoc(struct ath12k *ar, struct ath12k_link_sta *arsta; struct ieee80211_sta *ap_sta; struct ath12k_sta *ahsta; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; bool is_auth = false; u32 hemode = 0; int ret; @@ -3848,7 +3848,8 @@ static void ath12k_bss_assoc(struct ath12k *ar, spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_peer_find(ar->ab, arvif->vdev_id, arvif->bssid); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + arvif->bssid); if (peer && peer->is_authorized) is_auth = true; @@ -5663,7 +5664,7 @@ static int ath12k_clear_peer_keys(struct ath12k_link_vif *arvif, { struct ath12k *ar = arvif->ar; struct ath12k_base *ab = ar->ab; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; int first_errno = 0; int ret; int i; @@ -5672,7 +5673,7 @@ static int ath12k_clear_peer_keys(struct ath12k_link_vif *arvif, lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, arvif->vdev_id, addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, arvif->vdev_id, addr); spin_unlock_bh(&ab->base_lock); if (!peer) @@ -5707,7 +5708,7 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, { struct ieee80211_sta *sta = NULL; struct ath12k_base *ab = ar->ab; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_sta *ahsta; const u8 *peer_addr; int ret; @@ -5732,7 +5733,8 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, * we already hold wiphy lock. we just make sure its there now. */ spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, arvif->vdev_id, peer_addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, arvif->vdev_id, + peer_addr); spin_unlock_bh(&ab->base_lock); if (!peer) { @@ -5766,7 +5768,8 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, } spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find(ab, arvif->vdev_id, peer_addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, arvif->vdev_id, + peer_addr); if (peer && cmd == SET_KEY) { peer->keys[key->keyidx] = key; if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { @@ -6565,7 +6568,7 @@ static void ath12k_mac_station_post_remove(struct ath12k *ar, { struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif); struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta); - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -6573,7 +6576,8 @@ static void ath12k_mac_station_post_remove(struct ath12k *ar, spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_peer_find(ar->ab, arvif->vdev_id, arsta->addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + arsta->addr); if (peer && peer->sta == sta) { ath12k_warn(ar->ab, "Found peer entry %pM n vdev %i after it was supposedly removed\n", vif->addr, arvif->vdev_id); @@ -6593,14 +6597,15 @@ static int ath12k_mac_station_unauthorize(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ath12k_link_sta *arsta) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; int ret; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_peer_find(ar->ab, arvif->vdev_id, arsta->addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + arsta->addr); if (peer) peer->is_authorized = false; @@ -6626,7 +6631,7 @@ static int ath12k_mac_station_authorize(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ath12k_link_sta *arsta) { - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif); int ret; @@ -6634,7 +6639,8 @@ static int ath12k_mac_station_authorize(struct ath12k *ar, spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_peer_find(ar->ab, arvif->vdev_id, arsta->addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + arsta->addr); if (peer) peer->is_authorized = true; @@ -7503,7 +7509,7 @@ void ath12k_mac_op_link_sta_rc_update(struct ieee80211_hw *hw, struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k_link_sta *arsta; struct ath12k_link_vif *arvif; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; u32 bw, smps; rcu_read_lock(); @@ -7526,7 +7532,8 @@ void ath12k_mac_op_link_sta_rc_update(struct ieee80211_hw *hw, } spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_peer_find(ar->ab, arvif->vdev_id, arsta->addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + arsta->addr); if (!peer) { spin_unlock_bh(&ar->ab->base_lock); rcu_read_unlock(); @@ -9156,7 +9163,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, struct sk_buff *msdu_copied; struct ath12k *ar, *tmp_ar; struct ath12k_pdev_dp *dp_pdev, *tmp_dp_pdev; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; unsigned long links_map; bool is_mcast = false; bool is_dvlan = false; @@ -9291,7 +9298,8 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, goto skip_peer_find; spin_lock_bh(&tmp_ar->ab->base_lock); - peer = ath12k_peer_find_by_addr(tmp_ar->ab, tmp_arvif->bssid); + peer = ath12k_dp_link_peer_find_by_addr(tmp_ar->ab, + tmp_arvif->bssid); if (!peer) { spin_unlock_bh(&tmp_ar->ab->base_lock); ath12k_warn(tmp_ar->ab, @@ -11909,7 +11917,7 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, if (ab->hw_params->vdev_start_delay && ahvif->vdev_type != WMI_VDEV_TYPE_AP && ahvif->vdev_type != WMI_VDEV_TYPE_MONITOR && - !ath12k_peer_exist_by_vdev_id(ab, arvif->vdev_id)) { + !ath12k_dp_link_peer_exist_by_vdev_id(ab, arvif->vdev_id)) { ret = 0; goto out; } @@ -12788,8 +12796,8 @@ ath12k_mac_validate_fixed_rate_settings(struct ath12k *ar, enum nl80211_band ban bool eht_fixed_rate = false, he_fixed_rate = false, vht_fixed_rate = false; const u16 *vht_mcs_mask, *he_mcs_mask, *eht_mcs_mask; struct ieee80211_link_sta *link_sta; - struct ath12k_peer *peer, *tmp; - u8 vht_nss, he_nss, eht_nss; + struct ath12k_dp_link_peer *peer, *tmp; + u8 vht_nss, he_nss; int ret = true; vht_mcs_mask = mask->control[band].vht_mcs; diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index 1e2526bb11865..16f4a74712d81 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -25,8 +25,8 @@ struct ath12k_ml_peer *ath12k_peer_ml_find(struct ath12k_hw *ah, const u8 *addr) } EXPORT_SYMBOL(ath12k_peer_ml_find); -static int ath12k_wait_for_peer_common(struct ath12k_base *ab, int vdev_id, - const u8 *addr, bool expect_mapped) +static int ath12k_wait_for_dp_link_peer_common(struct ath12k_base *ab, int vdev_id, + const u8 *addr, bool expect_mapped) { int ret; @@ -34,7 +34,9 @@ static int ath12k_wait_for_peer_common(struct ath12k_base *ab, int vdev_id, bool mapped; spin_lock_bh(&ab->base_lock); - mapped = !!ath12k_peer_find(ab, vdev_id, addr); + mapped = !!ath12k_dp_link_peer_find_by_vdev_and_addr(ab, + vdev_id, + addr); spin_unlock_bh(&ab->base_lock); (mapped == expect_mapped || @@ -49,7 +51,7 @@ static int ath12k_wait_for_peer_common(struct ath12k_base *ab, int vdev_id, void ath12k_peer_cleanup(struct ath12k *ar, u32 vdev_id) { - struct ath12k_peer *peer, *tmp; + struct ath12k_dp_link_peer *peer, *tmp; struct ath12k_base *ab = ar->ab; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -72,7 +74,7 @@ void ath12k_peer_cleanup(struct ath12k *ar, u32 vdev_id) static int ath12k_wait_for_peer_deleted(struct ath12k *ar, int vdev_id, const u8 *addr) { - return ath12k_wait_for_peer_common(ar->ab, vdev_id, addr, false); + return ath12k_wait_for_dp_link_peer_common(ar->ab, vdev_id, addr, false); } int ath12k_wait_for_peer_delete_done(struct ath12k *ar, u32 vdev_id, @@ -138,7 +140,7 @@ int ath12k_peer_delete(struct ath12k *ar, u32 vdev_id, u8 *addr) static int ath12k_wait_for_peer_created(struct ath12k *ar, int vdev_id, const u8 *addr) { - return ath12k_wait_for_peer_common(ar->ab, vdev_id, addr, true); + return ath12k_wait_for_dp_link_peer_common(ar->ab, vdev_id, addr, true); } int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, @@ -150,7 +152,7 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ath12k_dp_link_vif *dp_link_vif; struct ath12k_link_sta *arsta; u8 link_id = arvif->link_id; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_sta *ahsta; u16 ml_peer_id; int ret; @@ -166,7 +168,8 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, } spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_peer_find_by_pdev_idx(ar->ab, ar->pdev_idx, arg->peer_addr); + peer = ath12k_dp_link_peer_find_by_pdev_and_addr(ar->ab, ar->pdev_idx, + arg->peer_addr); if (peer) { spin_unlock_bh(&ar->ab->base_lock); return -EINVAL; @@ -188,7 +191,8 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_peer_find(ar->ab, arg->vdev_id, arg->peer_addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arg->vdev_id, + arg->peer_addr); if (!peer) { spin_unlock_bh(&ar->ab->base_lock); ath12k_warn(ar->ab, "failed to find peer %pM on vdev %i after creation\n", diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index eef8d25584946..4180db504c312 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -68,7 +68,7 @@ static void ath12k_wifi7_peer_rx_tid_qref_reset(struct ath12k_base *ab, } void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k *ar, - struct ath12k_peer *peer, u8 tid) + struct ath12k_dp_link_peer *peer, u8 tid) { struct ath12k_hal_reo_cmd cmd = {}; struct ath12k_dp_rx_tid *rx_tid = &peer->rx_tid[tid]; @@ -179,7 +179,7 @@ int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, } int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k *ar, - struct ath12k_peer *peer, + struct ath12k_dp_link_peer *peer, struct ath12k_dp_rx_tid *rx_tid, u32 ba_win_sz, u16 ssn, bool update_ssn) @@ -321,7 +321,7 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, enum hal_encrypt_type enctype; bool is_decrypted = false; struct ieee80211_hdr *hdr; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ieee80211_rx_status *rx_status = rx_info->rx_status; u32 err_bitmap = rx_info->err_bitmap; @@ -333,7 +333,7 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, rxcb->peer_id = rx_info->peer_id; spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_rx_h_find_peer(ab, msdu, rx_info); + peer = ath12k_dp_rx_h_find_link_peer(ab, msdu, rx_info); if (peer) { /* resetting mcbc bit because mcbc packets are unicast * packets only for AP as STA sends unicast packets. @@ -964,7 +964,7 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k_dp *dp, } static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_peer *peer, + struct ath12k_dp_link_peer *peer, enum hal_encrypt_type enctype, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) @@ -1033,7 +1033,7 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, } static int ath12k_wifi7_dp_rx_h_defrag(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_peer *peer, + struct ath12k_dp_link_peer *peer, struct ath12k_dp_rx_tid *rx_tid, struct sk_buff **defrag_skb, enum hal_encrypt_type enctype, @@ -1107,7 +1107,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, { struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_base *ab = dp->ab; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_dp_rx_tid *rx_tid; struct sk_buff *defrag_skb = NULL; u32 peer_id = rx_info->peer_id; @@ -1134,7 +1134,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, return -EINVAL; spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); if (!peer) { ath12k_warn(ab, "failed to find the peer to de-fragment received fragment peer_id %d\n", peer_id); @@ -1197,7 +1197,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, timer_delete_sync(&rx_tid->frag_timer); spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); if (!peer) goto err_frags_cleanup; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index df25164e08f24..f75588519cfff 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -34,7 +34,7 @@ int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, dma_addr_t paddr); void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k *ar, - struct ath12k_peer *peer, u8 tid); + struct ath12k_dp_link_peer *peer, u8 tid); int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid, enum hal_reo_cmd_type type, struct ath12k_hal_reo_cmd *cmd, @@ -43,7 +43,7 @@ int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid void ath12k_wifi7_dp_reo_cache_flush(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid); int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k *ar, - struct ath12k_peer *peer, + struct ath12k_dp_link_peer *peer, struct ath12k_dp_rx_tid *rx_tid, u32 ba_win_sz, u16 ssn, bool update_ssn); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 2f523ed00dedd..3d06987cfc0e6 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -395,7 +395,7 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, struct sk_buff *msdu = desc_params->skb; s32 noise_floor; struct ieee80211_tx_status status = {}; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; skb_cb = ATH12K_SKB_CB(msdu); info = IEEE80211_SKB_CB(msdu); @@ -449,7 +449,7 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, } rcu_read_lock(); spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DATA, "dp_tx: failed to find the peer with peer_id %d\n", peer_id); @@ -518,7 +518,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, { struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_base *ab = dp->ab; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ieee80211_sta *sta; struct ath12k_sta *ahsta; struct ath12k_link_sta *arsta; @@ -528,7 +528,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, int ret; spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, ts->peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, ts->peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DP_TX, "failed to find the peer by id %u\n", ts->peer_id); @@ -649,7 +649,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, s32 noise_floor; struct ieee80211_tx_status status = {}; struct ieee80211_rate_status status_rate = {}; - struct ath12k_peer *peer; + struct ath12k_dp_link_peer *peer; struct ath12k_link_sta *arsta; struct ath12k_sta *ahsta; struct rate_info rate; @@ -747,7 +747,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, ath12k_wifi7_dp_tx_update_txcompl(dp_pdev, ts); spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_id(ab, ts->peer_id); + peer = ath12k_dp_link_peer_find_by_id(ab, ts->peer_id); if (!peer || !peer->sta) { ath12k_err(ab, "dp_tx: failed to find the peer with peer_id %d\n", diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 01c859f35a937..a3ea42fc09331 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -119,7 +119,7 @@ ath12k_wifi7_is_frame_link_agnostic_wcn7850(struct ath12k_link_vif *arvif, __le16 fc = mgmt->frame_control; spin_lock_bh(&ab->base_lock); - if (!ath12k_peer_find_by_addr(ab, mgmt->da) && + if (!ath12k_dp_link_peer_find_by_addr(ab, mgmt->da) && !ath12k_peer_ml_find(ah, mgmt->da)) { spin_unlock_bh(&ab->base_lock); return false; diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index a8a6159f8ee53..a854c381d550a 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -7283,8 +7283,7 @@ static void ath12k_peer_sta_kickout_event(struct ath12k_base *ab, struct sk_buff struct wmi_peer_sta_kickout_arg arg = {}; struct ath12k_link_vif *arvif; struct ieee80211_sta *sta; - struct ath12k_peer *peer; - unsigned int link_id; + struct ath12k_dp_link_peer *peer; struct ath12k *ar; if (ath12k_pull_peer_sta_kickout_ev(ab, skb, &arg) != 0) { @@ -7296,7 +7295,7 @@ static void ath12k_peer_sta_kickout_event(struct ath12k_base *ab, struct sk_buff spin_lock_bh(&ab->base_lock); - peer = ath12k_peer_find_by_addr(ab, arg.mac_addr); + peer = ath12k_dp_link_peer_find_by_addr(ab, arg.mac_addr); if (!peer) { ath12k_warn(ab, "peer not found %pM\n", From b683074e295e4c416ab29a6de253147e72ccafea Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Fri, 24 Oct 2025 23:45:42 +0530 Subject: [PATCH 076/140] wifi: ath12k: Add hash table for ath12k_link_sta in ath12k_base Currently ath12k_base maintains a linked list of ath12k_dp_link_peer as "peers". This linked list is used for all kinds of peer search operations. In the control path, if there is a requirement to search for ath12k_link_sta using mac address, then below sequence is to be followed: 1. Find ath12k_dp_link_peer in the linked list using mac address 2. Fetch ieee80211_sta from ath12k_dp_link_peer 3. Fetch ath12k_sta from ieee80211_sta 4. Finally fetch ath12k_link_sta from ath12k_sta using link_id In the above sequence, there are too many indirections involved. In order to simplify this, add hash table for ath12k_link_sta in ath12k_base. This hash table is lock protected by existing spinlock "base_lock" in ath12k_base as this table can be concurrently accessed in different contexts. Use this table for ath12k_link_sta search operations using mac address in the control path. Ex: For WMI interface and mac80211_ops interface in the control path, sta mac address is received and this hash table can be used to search for ath12k_link_sta directly instead of following the longer route mentioned above. Helper APIs added: - ath12k_link_sta_rhash_add() - To add arsta entry to hash table - ath12k_link_sta_rhash_delete() - To remove arsta entry from hash table - ath12k_link_sta_find_by_addr() - To find arsta from hash table using mac address Make changes in API ath12k_peer_sta_kickout_event() to find arsta using above mechanism. ath11k driver has been taken as reference for implementation of hash table. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251024181548.3255166-4-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.c | 10 +++ drivers/net/wireless/ath/ath12k/core.h | 7 ++ drivers/net/wireless/ath/ath12k/mac.c | 72 +++++++++++++++ drivers/net/wireless/ath/ath12k/peer.c | 116 +++++++++++++++++++++++++ drivers/net/wireless/ath/ath12k/peer.h | 6 ++ drivers/net/wireless/ath/ath12k/wmi.c | 16 ++-- 6 files changed, 219 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 4bc56d5ac64fa..d58b164886645 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -23,6 +23,7 @@ #include "pci.h" #include "wow.h" #include "dp_cmn.h" +#include "peer.h" unsigned int ath12k_debug_mask; module_param_named(debug_mask, ath12k_debug_mask, uint, 0644); @@ -702,6 +703,8 @@ void ath12k_core_to_group_ref_put(struct ath12k_base *ab) static void ath12k_core_stop(struct ath12k_base *ab) { + ath12k_link_sta_rhash_tbl_destroy(ab); + ath12k_core_to_group_ref_put(ab); if (!test_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags)) @@ -964,6 +967,12 @@ static int ath12k_core_start(struct ath12k_base *ab) /* Indicate the core start in the appropriate group */ ath12k_core_to_group_ref_get(ab); + ret = ath12k_link_sta_rhash_tbl_init(ab); + if (ret) { + ath12k_warn(ab, "failed to init peer addr rhash table %d\n", ret); + goto err_reo_cleanup; + } + return 0; err_reo_cleanup: @@ -1350,6 +1359,7 @@ static int ath12k_core_reconfigure_on_crash(struct ath12k_base *ab) int ret, total_vdev; mutex_lock(&ab->core_lock); + ath12k_link_sta_rhash_tbl_destroy(ab); ath12k_dp_pdev_free(ab); ath12k_ce_cleanup_pipes(ab); ath12k_wmi_detach(ab); diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 1548116b0228f..5565cd5e0cd8a 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -18,6 +18,7 @@ #include #include #include +#include #include "qmi.h" #include "htc.h" #include "wmi.h" @@ -566,6 +567,9 @@ struct ath12k_link_sta { u8 link_idx; u32 tx_retry_failed; u32 tx_retry_count; + + /* peer addr based rhashtable list pointer */ + struct rhash_head rhash_addr; }; struct ath12k_reoq_buf { @@ -1227,6 +1231,9 @@ struct ath12k_base { */ const struct ieee80211_ops *ath12k_ops; + struct rhashtable *rhead_sta_addr; + struct rhashtable_params rhash_sta_addr_param; + /* must be last */ u8 drv_priv[] __aligned(sizeof(void *)); }; diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index f43d78f38b330..2431485c56afa 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1169,6 +1169,35 @@ static int ath12k_mac_set_kickout(struct ath12k_link_vif *arvif) return 0; } +static void ath12k_mac_link_sta_rhash_cleanup(void *data, struct ieee80211_sta *sta) +{ + u8 link_id; + unsigned long links_map; + struct ath12k_sta *ahsta; + struct ath12k *ar = data; + struct ath12k_link_sta *arsta; + struct ath12k_link_vif *arvif; + struct ath12k_base *ab = ar->ab; + + ahsta = ath12k_sta_to_ahsta(sta); + links_map = ahsta->links_map; + + rcu_read_lock(); + for_each_set_bit(link_id, &links_map, IEEE80211_MLD_MAX_NUM_LINKS) { + arsta = rcu_dereference(ahsta->link[link_id]); + if (!arsta) + continue; + arvif = arsta->arvif; + if (!(arvif->ar == ar)) + continue; + + spin_lock_bh(&ab->base_lock); + ath12k_link_sta_rhash_delete(ab, arsta); + spin_unlock_bh(&ab->base_lock); + } + rcu_read_unlock(); +} + void ath12k_mac_peer_cleanup_all(struct ath12k *ar) { struct ath12k_dp_link_peer *peer, *tmp; @@ -1189,6 +1218,10 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) ar->num_peers = 0; ar->num_stations = 0; + + /* Cleanup rhash table maintained for arsta by iterating over sta */ + ieee80211_iterate_stations_mtx(ar->ah->hw, ath12k_mac_link_sta_rhash_cleanup, + ar); } static int ath12k_mac_vdev_setup_sync(struct ath12k *ar) @@ -6668,6 +6701,7 @@ static int ath12k_mac_station_remove(struct ath12k *ar, struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta); struct ath12k_vif *ahvif = arvif->ahvif; int ret = 0; + struct ath12k_link_sta *temp_arsta; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -6696,6 +6730,15 @@ static int ath12k_mac_station_remove(struct ath12k *ar, ath12k_mac_station_post_remove(ar, arvif, arsta); + spin_lock_bh(&ar->ab->base_lock); + + /* To handle roaming and split phy scenario */ + temp_arsta = ath12k_link_sta_find_by_addr(ar->ab, arsta->addr); + if (temp_arsta && temp_arsta->arvif->ar == ar) + ath12k_link_sta_rhash_delete(ar->ab, arsta); + + spin_unlock_bh(&ar->ab->base_lock); + if (sta->valid_links) ath12k_mac_free_unassign_link_sta(ahvif->ah, arsta->ahsta, arsta->link_id); @@ -6712,6 +6755,7 @@ static int ath12k_mac_station_add(struct ath12k *ar, struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta); struct ath12k_wmi_peer_create_arg peer_param = {}; int ret; + struct ath12k_link_sta *temp_arsta; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -6730,6 +6774,26 @@ static int ath12k_mac_station_add(struct ath12k *ar, } } + spin_lock_bh(&ab->base_lock); + + /* + * In case of Split PHY and roaming scenario, pdev idx + * might differ but both the pdev will share same rhash + * table. In that case update the rhash table if link_sta is + * already present + */ + temp_arsta = ath12k_link_sta_find_by_addr(ab, arsta->addr); + if (temp_arsta && temp_arsta->arvif->ar != ar) + ath12k_link_sta_rhash_delete(ab, temp_arsta); + + ret = ath12k_link_sta_rhash_add(ab, arsta); + spin_unlock_bh(&ab->base_lock); + if (ret) { + ath12k_warn(ab, "Failed to add arsta: %pM to hash table, ret: %d", + arsta->addr, ret); + goto free_rx_stats; + } + peer_param.vdev_id = arvif->vdev_id; peer_param.peer_addr = arsta->addr; peer_param.peer_type = WMI_PEER_TYPE_DEFAULT; @@ -6778,6 +6842,10 @@ static int ath12k_mac_station_add(struct ath12k *ar, free_peer: ath12k_peer_delete(ar, arvif->vdev_id, arsta->addr); + spin_lock_bh(&ab->base_lock); + ath12k_link_sta_rhash_delete(ab, arsta); + spin_unlock_bh(&ab->base_lock); +free_rx_stats: kfree(arsta->rx_stats); arsta->rx_stats = NULL; dec_num_station: @@ -6856,6 +6924,10 @@ static void ath12k_mac_ml_station_remove(struct ath12k_vif *ahvif, ath12k_mac_station_post_remove(ar, arvif, arsta); + spin_lock_bh(&ar->ab->base_lock); + ath12k_link_sta_rhash_delete(ar->ab, arsta); + spin_unlock_bh(&ar->ab->base_lock); + ath12k_mac_free_unassign_link_sta(ah, ahsta, link_id); } diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index 16f4a74712d81..28801d87e6ed2 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -406,3 +406,119 @@ int ath12k_peer_mlo_link_peers_delete(struct ath12k_vif *ahvif, struct ath12k_st return err_ret; } + +static int ath12k_link_sta_rhash_insert(struct ath12k_base *ab, + struct ath12k_link_sta *arsta) +{ + struct ath12k_link_sta *tmp; + + lockdep_assert_held(&ab->base_lock); + + tmp = rhashtable_lookup_get_insert_fast(ab->rhead_sta_addr, &arsta->rhash_addr, + ab->rhash_sta_addr_param); + if (!tmp) + return 0; + else if (IS_ERR(tmp)) + return PTR_ERR(tmp); + else + return -EEXIST; +} + +static int ath12k_link_sta_rhash_remove(struct ath12k_base *ab, + struct ath12k_link_sta *arsta) +{ + int ret; + + lockdep_assert_held(&ab->base_lock); + + ret = rhashtable_remove_fast(ab->rhead_sta_addr, &arsta->rhash_addr, + ab->rhash_sta_addr_param); + if (ret && ret != -ENOENT) + return ret; + + return 0; +} + +int ath12k_link_sta_rhash_add(struct ath12k_base *ab, + struct ath12k_link_sta *arsta) +{ + int ret; + + lockdep_assert_held(&ab->base_lock); + + ret = ath12k_link_sta_rhash_insert(ab, arsta); + if (ret) + ath12k_warn(ab, "failed to add arsta %pM in rhash_addr ret %d\n", + arsta->addr, ret); + + return ret; +} + +void ath12k_link_sta_rhash_delete(struct ath12k_base *ab, + struct ath12k_link_sta *arsta) +{ + /* + * Return type of this function is void since there is nothing to be + * done in failure case + */ + int ret; + + lockdep_assert_held(&ab->base_lock); + + ret = ath12k_link_sta_rhash_remove(ab, arsta); + if (ret) + ath12k_warn(ab, + "failed to remove arsta %pM in rhash_addr ret %d\n", + arsta->addr, ret); +} + +int ath12k_link_sta_rhash_tbl_init(struct ath12k_base *ab) +{ + struct rhashtable_params *param; + struct rhashtable *rhash_addr_tbl; + int ret; + + rhash_addr_tbl = kzalloc(sizeof(*ab->rhead_sta_addr), GFP_KERNEL); + if (!rhash_addr_tbl) + return -ENOMEM; + + param = &ab->rhash_sta_addr_param; + + param->key_offset = offsetof(struct ath12k_link_sta, addr); + param->head_offset = offsetof(struct ath12k_link_sta, rhash_addr); + param->key_len = sizeof_field(struct ath12k_link_sta, addr); + param->automatic_shrinking = true; + param->nelem_hint = ab->num_radios * ath12k_core_get_max_peers_per_radio(ab); + + ret = rhashtable_init(rhash_addr_tbl, param); + if (ret) { + ath12k_warn(ab, "failed to init peer addr rhash table %d\n", + ret); + goto err_free; + } + + ab->rhead_sta_addr = rhash_addr_tbl; + + return 0; + +err_free: + kfree(rhash_addr_tbl); + + return ret; +} + +void ath12k_link_sta_rhash_tbl_destroy(struct ath12k_base *ab) +{ + rhashtable_destroy(ab->rhead_sta_addr); + kfree(ab->rhead_sta_addr); + ab->rhead_sta_addr = NULL; +} + +struct ath12k_link_sta *ath12k_link_sta_find_by_addr(struct ath12k_base *ab, + const u8 *addr) +{ + lockdep_assert_held(&ab->base_lock); + + return rhashtable_lookup_fast(ab->rhead_sta_addr, addr, + ab->rhash_sta_addr_param); +} diff --git a/drivers/net/wireless/ath/ath12k/peer.h b/drivers/net/wireless/ath/ath12k/peer.h index 81e9bcc067ff4..cf8a463d4c371 100644 --- a/drivers/net/wireless/ath/ath12k/peer.h +++ b/drivers/net/wireless/ath/ath12k/peer.h @@ -27,4 +27,10 @@ int ath12k_peer_ml_delete(struct ath12k_hw *ah, struct ieee80211_sta *sta); int ath12k_peer_mlo_link_peers_delete(struct ath12k_vif *ahvif, struct ath12k_sta *ahsta); struct ath12k_ml_peer *ath12k_peer_ml_find(struct ath12k_hw *ah, const u8 *addr); +int ath12k_link_sta_rhash_tbl_init(struct ath12k_base *ab); +void ath12k_link_sta_rhash_tbl_destroy(struct ath12k_base *ab); +void ath12k_link_sta_rhash_delete(struct ath12k_base *ab, struct ath12k_link_sta *arsta); +int ath12k_link_sta_rhash_add(struct ath12k_base *ab, struct ath12k_link_sta *arsta); +struct ath12k_link_sta *ath12k_link_sta_find_by_addr(struct ath12k_base *ab, + const u8 *addr); #endif /* _PEER_H_ */ diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index a854c381d550a..dce9417918eeb 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -7283,7 +7283,7 @@ static void ath12k_peer_sta_kickout_event(struct ath12k_base *ab, struct sk_buff struct wmi_peer_sta_kickout_arg arg = {}; struct ath12k_link_vif *arvif; struct ieee80211_sta *sta; - struct ath12k_dp_link_peer *peer; + struct ath12k_link_sta *arsta; struct ath12k *ar; if (ath12k_pull_peer_sta_kickout_ev(ab, skb, &arg) != 0) { @@ -7295,18 +7295,18 @@ static void ath12k_peer_sta_kickout_event(struct ath12k_base *ab, struct sk_buff spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_addr(ab, arg.mac_addr); + arsta = ath12k_link_sta_find_by_addr(ab, arg.mac_addr); - if (!peer) { - ath12k_warn(ab, "peer not found %pM\n", + if (!arsta) { + ath12k_warn(ab, "arsta not found %pM\n", arg.mac_addr); goto exit; } - arvif = ath12k_mac_get_arvif_by_vdev_id(ab, peer->vdev_id); - if (!arvif) { - ath12k_warn(ab, "invalid vdev id in peer sta kickout ev %d", - peer->vdev_id); + ar = arsta->arvif->ar; + if (!ar) { + ath12k_warn(ab, "invalid ar in peer sta kickout ev for STA %pM\n", + arg.mac_addr); goto exit; } From b31c2f195ee512d1d63454b17002fb849e348852 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Fri, 24 Oct 2025 23:45:43 +0530 Subject: [PATCH 077/140] wifi: ath12k: Move ath12k_dp_link_peer list from ath12k_base to ath12k_dp ath12k_base maintains a linked list of ath12k_dp_link_peer. This linked list is used for all kind of peer search operations. With the modularization of device and peer objects for ath12k next-generation driver, ath12k_dp_link_peer and ath12k_dp are exclusively meant for datapath related operations. Hence move ath12k_dp_link_peer linked list from ath12k_base to ath12k_dp. This linked list is to be lock protected by newly introduced spinlock "dp_lock" defined in ath12k_dp as this list can be concurrently accessed in different contexts for insert, delete and search operations. With the above changes, update following APIs to make use of lock "dp->dp_lock" instead of lock "ab->base_lock" and also update API signatures to pass ath12k_dp pointer instead of ath12k_base pointer as the function argument. ath12k_dp_link_peer_find_by_vdev_and_addr() ath12k_dp_link_peer_find_by_id() ath12k_dp_link_peer_find_by_ast() ath12k_dp_link_peer_find_by_pdev__and_addr() ath12k_dp_link_peer_find_by_ml_id() ath12k_dp_link_peer_find_by_addr() ath12k_dp_rx_h_find_link_peer() Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251024181548.3255166-5-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.c | 1 - drivers/net/wireless/ath/ath12k/core.h | 1 - drivers/net/wireless/ath/ath12k/dp.c | 23 +++-- drivers/net/wireless/ath/ath12k/dp.h | 6 ++ drivers/net/wireless/ath/ath12k/dp_htt.c | 26 ++--- drivers/net/wireless/ath/ath12k/dp_mon.c | 17 ++-- drivers/net/wireless/ath/ath12k/dp_peer.c | 64 ++++++------ drivers/net/wireless/ath/ath12k/dp_peer.h | 12 +-- drivers/net/wireless/ath/ath12k/dp_rx.c | 86 ++++++++-------- drivers/net/wireless/ath/ath12k/dp_rx.h | 4 +- drivers/net/wireless/ath/ath12k/mac.c | 99 +++++++++++-------- drivers/net/wireless/ath/ath12k/peer.c | 31 +++--- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 20 ++-- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 25 ++--- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 3 +- drivers/net/wireless/ath/ath12k/wifi7/hw.c | 9 +- 16 files changed, 234 insertions(+), 193 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index d58b164886645..0bd863f83cb0e 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -2261,7 +2261,6 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size, spin_lock_init(&ab->base_lock); init_completion(&ab->reset_complete); - INIT_LIST_HEAD(&ab->peers); init_waitqueue_head(&ab->peer_mapping_wq); init_waitqueue_head(&ab->wmi_ab.tx_credits_wq); INIT_WORK(&ab->restart_work, ath12k_core_restart); diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 5565cd5e0cd8a..bb48e93b9b937 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1092,7 +1092,6 @@ struct ath12k_base { struct ath12k_wmi_hal_reg_capabilities_ext_arg hal_reg_cap[MAX_RADIOS]; unsigned long long free_vdev_map; unsigned long long free_vdev_stats_id_map; - struct list_head peers; wait_queue_head_t peer_mapping_wq; u8 mac_addr[ETH_ALEN]; bool wmi_ready; diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index afad0c2cb6b9b..ee7244d709909 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -24,27 +24,28 @@ void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr) { struct ath12k_base *ab = ar->ab; struct ath12k_dp_link_peer *peer; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); /* TODO: Any other peer specific DP cleanup */ - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, addr); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, addr); if (!peer) { ath12k_warn(ab, "failed to lookup peer %pM on vdev %d\n", addr, vdev_id); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return; } if (!peer->primary_link) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return; } ath12k_dp_rx_peer_tid_cleanup(ar, peer); crypto_free_shash(peer->tfm_mmic); peer->dp_setup_done = false; - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); } int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr) @@ -53,6 +54,7 @@ int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr) struct ath12k_dp_link_peer *peer; u32 reo_dest; int ret = 0, tid; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); /* NOTE: reo_dest ring id starts from 1 unlike mac_id which starts from 0 */ reo_dest = ar->dp.mac_id + 1; @@ -87,19 +89,19 @@ int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr) return 0; peer_clean: - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, addr); if (!peer) { ath12k_warn(ab, "failed to find the peer to del rx tid\n"); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return -ENOENT; } for (tid--; tid >= 0; tid--) ath12k_wifi7_dp_rx_peer_tid_delete(ar, peer, tid); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return ret; } @@ -1484,6 +1486,9 @@ static int ath12k_dp_setup(struct ath12k_base *ab) spin_lock_init(&dp->reo_cmd_lock); spin_lock_init(&dp->reo_rxq_flush_lock); + spin_lock_init(&dp->dp_lock); + INIT_LIST_HEAD(&dp->peers); + dp->reo_cmd_cache_flush_count = 0; dp->idle_link_rbm = ath12k_hal_get_idle_link_rbm(&ab->hal, ab->device_id); diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 43a05c6f78ecd..b2c27cb7361d3 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -475,7 +475,13 @@ struct ath12k_dp { struct ath12k_hw_group *ag; u8 device_id; + /* Lock for protection of peers */ + spinlock_t dp_lock; + struct ath12k_dp_arch_ops *ops; + + /* Linked list of struct ath12k_dp_link_peer */ + struct list_head peers; }; static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index cae5a90c1c659..f3dca108c614e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -272,18 +272,18 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, } rcu_read_lock(); - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, usr_stats->peer_id); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_id(dp, usr_stats->peer_id); if (!peer || !peer->sta) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); return; } arsta = ath12k_dp_link_peer_to_link_sta(ab, peer); if (!arsta) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); return; } @@ -357,7 +357,7 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags); } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); } @@ -507,17 +507,17 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, ppdu_info->delay_ba) { for (i = 0; i < ppdu_info->ppdu_stats.common.num_users; i++) { peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); if (!peer) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); continue; } usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; if (usr_stats->delay_ba) ath12k_copy_to_delay_stats(peer, usr_stats); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); } } @@ -526,17 +526,17 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON))) { for (i = 0; i < ppdu_info->bar_num_users; i++) { peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); if (!peer) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); continue; } usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; if (peer->delayba_flag) ath12k_copy_to_bar(peer, usr_stats); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); } } diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index c76edd9b5dfc8..d75edfefa3d4d 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2322,9 +2322,9 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, ath12k_wifi7_dp_extract_rx_desc_data(ab, &rx_info, rx_desc, rx_desc); - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); rx_info.addr2_present = false; - peer = ath12k_dp_rx_h_find_link_peer(ab, msdu, &rx_info); + peer = ath12k_dp_rx_h_find_link_peer(dp, msdu, &rx_info); if (peer && peer->sta) { pubsta = peer->sta; if (pubsta->valid_links) { @@ -2333,7 +2333,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, } } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ath12k_dbg(ab, ATH12K_DBG_DATA, "rx skb %p len %u peer %pM %u %s %s%s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", @@ -3674,11 +3674,12 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, struct hal_rx_user_status *user_stats = &ppdu_info->userstats[uid]; struct ath12k_dp_link_peer *peer; u32 num_msdu; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); if (user_stats->ast_index == 0 || user_stats->ast_index == 0xFFFF) return; - peer = ath12k_dp_link_peer_find_by_ast(ab, user_stats->ast_index); + peer = ath12k_dp_link_peer_find_by_ast(dp, user_stats->ast_index); if (!peer) { ath12k_warn(ab, "peer ast idx %d can't be found\n", @@ -3919,8 +3920,8 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, goto free_skb; rcu_read_lock(); - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, ppdu_info->peer_id); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_id(dp, ppdu_info->peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DATA, "failed to find the peer with monitor peer_id %d\n", @@ -3933,7 +3934,7 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, if (!arsta) { ath12k_warn(ab, "link sta not found on peer %pM id %d\n", peer->addr, peer->peer_id); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); dev_kfree_skb_any(skb); continue; @@ -3947,7 +3948,7 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, } next_skb: - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); free_skb: dev_kfree_skb_any(skb); diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index 843369a00d3e4..0267f68f85734 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -9,14 +9,14 @@ #include "debug.h" struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_base *ab, +ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_dp *dp, int vdev_id, const u8 *addr) { struct ath12k_dp_link_peer *peer; - lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&dp->dp_lock); - list_for_each_entry(peer, &ab->peers, list) { + list_for_each_entry(peer, &dp->peers, list) { if (peer->vdev_id != vdev_id) continue; if (!ether_addr_equal(peer->addr, addr)) @@ -29,14 +29,14 @@ ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_base *ab, } struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_pdev_and_addr(struct ath12k_base *ab, u8 pdev_idx, +ath12k_dp_link_peer_find_by_pdev_and_addr(struct ath12k_dp *dp, u8 pdev_idx, const u8 *addr) { struct ath12k_dp_link_peer *peer; - lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&dp->dp_lock); - list_for_each_entry(peer, &ab->peers, list) { + list_for_each_entry(peer, &dp->peers, list) { if (peer->pdev_idx != pdev_idx) continue; if (!ether_addr_equal(peer->addr, addr)) @@ -49,13 +49,13 @@ ath12k_dp_link_peer_find_by_pdev_and_addr(struct ath12k_base *ab, u8 pdev_idx, } struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_addr(struct ath12k_base *ab, const u8 *addr) +ath12k_dp_link_peer_find_by_addr(struct ath12k_dp *dp, const u8 *addr) { struct ath12k_dp_link_peer *peer; - lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&dp->dp_lock); - list_for_each_entry(peer, &ab->peers, list) { + list_for_each_entry(peer, &dp->peers, list) { if (!ether_addr_equal(peer->addr, addr)) continue; @@ -67,13 +67,13 @@ ath12k_dp_link_peer_find_by_addr(struct ath12k_base *ab, const u8 *addr) EXPORT_SYMBOL(ath12k_dp_link_peer_find_by_addr); static struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_ml_id(struct ath12k_base *ab, int ml_peer_id) +ath12k_dp_link_peer_find_by_ml_id(struct ath12k_dp *dp, int ml_peer_id) { struct ath12k_dp_link_peer *peer; - lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&dp->dp_lock); - list_for_each_entry(peer, &ab->peers, list) + list_for_each_entry(peer, &dp->peers, list) if (ml_peer_id == peer->ml_id) return peer; @@ -81,49 +81,49 @@ ath12k_dp_link_peer_find_by_ml_id(struct ath12k_base *ab, int ml_peer_id) } struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_id(struct ath12k_base *ab, int peer_id) +ath12k_dp_link_peer_find_by_id(struct ath12k_dp *dp, int peer_id) { struct ath12k_dp_link_peer *peer; - lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&dp->dp_lock); if (peer_id == HAL_INVALID_PEERID) return NULL; if (peer_id & ATH12K_PEER_ML_ID_VALID) - return ath12k_dp_link_peer_find_by_ml_id(ab, peer_id); + return ath12k_dp_link_peer_find_by_ml_id(dp, peer_id); - list_for_each_entry(peer, &ab->peers, list) + list_for_each_entry(peer, &dp->peers, list) if (peer_id == peer->peer_id) return peer; return NULL; } -bool ath12k_dp_link_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id) +bool ath12k_dp_link_peer_exist_by_vdev_id(struct ath12k_dp *dp, int vdev_id) { struct ath12k_dp_link_peer *peer; - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); - list_for_each_entry(peer, &ab->peers, list) { + list_for_each_entry(peer, &dp->peers, list) { if (vdev_id == peer->vdev_id) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return true; } } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return false; } struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_ast(struct ath12k_base *ab, int ast_hash) +ath12k_dp_link_peer_find_by_ast(struct ath12k_dp *dp, int ast_hash) { struct ath12k_dp_link_peer *peer; - lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&dp->dp_lock); - list_for_each_entry(peer, &ab->peers, list) + list_for_each_entry(peer, &dp->peers, list) if (ast_hash == peer->ast_hash) return peer; @@ -133,10 +133,11 @@ ath12k_dp_link_peer_find_by_ast(struct ath12k_base *ab, int ast_hash) void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) { struct ath12k_dp_link_peer *peer; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); + peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); if (!peer) { ath12k_warn(ab, "peer-unmap-event: unknown peer id %d\n", peer_id); @@ -151,16 +152,17 @@ void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) wake_up(&ab->peer_mapping_wq); exit: - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); } void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, u8 *mac_addr, u16 ast_hash, u16 hw_peer_id) { struct ath12k_dp_link_peer *peer; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, mac_addr); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, mac_addr); if (!peer) { peer = kzalloc(sizeof(*peer), GFP_ATOMIC); if (!peer) @@ -171,7 +173,7 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ peer->ast_hash = ast_hash; peer->hw_peer_id = hw_peer_id; ether_addr_copy(peer->addr, mac_addr); - list_add(&peer->list, &ab->peers); + list_add(&peer->list, &dp->peers); wake_up(&ab->peer_mapping_wq); } @@ -179,7 +181,7 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ vdev_id, mac_addr, peer_id); exit: - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); } struct ath12k_link_sta *ath12k_dp_link_peer_to_link_sta(struct ath12k_base *ab, diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h index aec73d8e35ce6..ecc90df05b444 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.h +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h @@ -69,17 +69,17 @@ void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, u8 *mac_addr, u16 ast_hash, u16 hw_peer_id); struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_base *ab, +ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_dp *dp, int vdev_id, const u8 *addr); struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_addr(struct ath12k_base *ab, const u8 *addr); +ath12k_dp_link_peer_find_by_addr(struct ath12k_dp *dp, const u8 *addr); struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_id(struct ath12k_base *ab, int peer_id); -bool ath12k_dp_link_peer_exist_by_vdev_id(struct ath12k_base *ab, int vdev_id); +ath12k_dp_link_peer_find_by_id(struct ath12k_dp *dp, int peer_id); +bool ath12k_dp_link_peer_exist_by_vdev_id(struct ath12k_dp *dp, int vdev_id); struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_ast(struct ath12k_base *ab, int ast_hash); +ath12k_dp_link_peer_find_by_ast(struct ath12k_dp *dp, int ast_hash); struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_pdev_and_addr(struct ath12k_base *ab, u8 pdev_idx, +ath12k_dp_link_peer_find_by_pdev_and_addr(struct ath12k_dp *dp, u8 pdev_idx, const u8 *addr); struct ath12k_link_sta *ath12k_dp_link_peer_to_link_sta(struct ath12k_base *ab, struct ath12k_dp_link_peer *peer); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 5e41f2d1318cd..1a8aa7d4ed003 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -502,9 +502,10 @@ void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, bool rel_link_desc) { struct ath12k_buffer_addr *buf_addr_info; - struct ath12k_base *ab = rx_tid->ab; + struct ath12k_dp *dp = rx_tid->dp; + struct ath12k_base *ab = dp->ab; - lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&dp->dp_lock); if (rx_tid->dst_ring_desc) { if (rel_link_desc) { @@ -527,8 +528,10 @@ void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer { struct ath12k_dp_rx_tid *rx_tid; int i; + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - lockdep_assert_held(&ar->ab->base_lock); + lockdep_assert_held(&dp->dp_lock); for (i = 0; i <= IEEE80211_NUM_TIDS; i++) { rx_tid = &peer->rx_tid[i]; @@ -536,9 +539,9 @@ void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer ath12k_wifi7_dp_rx_peer_tid_delete(ar, peer, i); ath12k_dp_rx_frags_cleanup(rx_tid, true); - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); timer_delete_sync(&rx_tid->frag_timer); - spin_lock_bh(&ar->ab->base_lock); + spin_lock_bh(&dp->dp_lock); } } @@ -667,24 +670,24 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ dma_addr_t paddr_aligned; int ret; - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, peer_mac); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, peer_mac); if (!peer) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "failed to find the peer to set up rx tid\n"); return -ENOENT; } if (ab->hw_params->dp_primary_link_only && !peer->primary_link) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return 0; } if (ab->hw_params->reoq_lut_support && (!dp->reoq_lut.vaddr || !dp->ml_reoq_lut.vaddr)) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "reo qref table is not setup\n"); return -EINVAL; } @@ -692,7 +695,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ if (peer->peer_id > DP_MAX_PEER_ID || tid > IEEE80211_NUM_TIDS) { ath12k_warn(ab, "peer id of peer %d or tid %d doesn't allow reoq setup\n", peer->peer_id, tid); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return -EINVAL; } @@ -701,7 +704,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ if (rx_tid->active) { ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, rx_tid, ba_win_sz, ssn, true); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); if (ret) { ath12k_warn(ab, "failed to update reo for rx tid %d\n", tid); return ret; @@ -730,7 +733,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ ahsta = ath12k_sta_to_ahsta(peer->sta); ret = ath12k_wifi7_dp_rx_assign_reoq(ab, ahsta, rx_tid, ssn, pn_type); if (ret) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "failed to assign reoq buf for rx tid %u\n", tid); return ret; } @@ -760,9 +763,9 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ ath12k_wifi7_peer_rx_tid_qref_setup(ab, peer->peer_id, tid, paddr_aligned); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); } else { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ret = ath12k_wmi_peer_rx_reorder_queue_setup(ar, vdev_id, peer_mac, paddr_aligned, tid, 1, ba_win_sz); @@ -804,6 +807,7 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, u8 link_id) { struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_dp_link_peer *peer; struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(params->sta); struct ath12k_link_sta *arsta; @@ -820,11 +824,11 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, vdev_id = arsta->arvif->vdev_id; - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, arsta->addr); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, arsta->addr); if (!peer) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "failed to find the peer to stop rx aggregation\n"); return -ENOENT; } @@ -832,12 +836,12 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, active = peer->rx_tid[params->tid].active; if (!active) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return 0; } ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, peer->rx_tid, 1, 0, false); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); if (ret) { ath12k_warn(ab, "failed to update reo for rx tid %d: %d\n", params->tid, ret); @@ -854,6 +858,7 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, { struct ath12k *ar = arvif->ar; struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_hal_reo_cmd cmd = {}; struct ath12k_dp_link_peer *peer; struct ath12k_dp_rx_tid *rx_tid; @@ -868,12 +873,12 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) return 0; - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, arvif->vdev_id, + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, peer_addr); if (!peer) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "failed to find the peer %pM to configure pn replay detection\n", peer_addr); return -ENOENT; @@ -896,7 +901,7 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, } } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return ret; } @@ -1217,22 +1222,22 @@ void ath12k_dp_rx_h_undecap(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu } struct ath12k_dp_link_peer * -ath12k_dp_rx_h_find_link_peer(struct ath12k_base *ab, struct sk_buff *msdu, +ath12k_dp_rx_h_find_link_peer(struct ath12k_dp *dp, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) { struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); struct ath12k_dp_link_peer *peer = NULL; - lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&dp->dp_lock); if (rxcb->peer_id) - peer = ath12k_dp_link_peer_find_by_id(ab, rxcb->peer_id); + peer = ath12k_dp_link_peer_find_by_id(dp, rxcb->peer_id); if (peer) return peer; if (rx_info->addr2_present) - peer = ath12k_dp_link_peer_find_by_addr(ab, rx_info->addr2); + peer = ath12k_dp_link_peer_find_by_addr(dp, rx_info->addr2); return peer; } @@ -1389,8 +1394,8 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc bool is_mcbc = rxcb->is_mcbc; bool is_eapol = rxcb->is_eapol; - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_rx_h_find_link_peer(ab, msdu, rx_info); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_rx_h_find_link_peer(dp, msdu, rx_info); pubsta = peer ? peer->sta : NULL; @@ -1399,7 +1404,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc status->link_id = peer->link_id; } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ath12k_dbg(ab, ATH12K_DBG_DATA, "rx skb %p len %u peer %pM %d %s sn %u %s%s%s%s%s%s%s%s%s%s rate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", @@ -1497,14 +1502,14 @@ static void ath12k_dp_rx_frag_timer(struct timer_list *timer) struct ath12k_dp_rx_tid *rx_tid = timer_container_of(rx_tid, timer, frag_timer); - spin_lock_bh(&rx_tid->ab->base_lock); + spin_lock_bh(&rx_tid->dp->dp_lock); if (rx_tid->last_frag_no && rx_tid->rx_frag_bitmap == GENMASK(rx_tid->last_frag_no, 0)) { - spin_unlock_bh(&rx_tid->ab->base_lock); + spin_unlock_bh(&rx_tid->dp->dp_lock); return; } ath12k_dp_rx_frags_cleanup(rx_tid, true); - spin_unlock_bh(&rx_tid->ab->base_lock); + spin_unlock_bh(&rx_tid->dp->dp_lock); } int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id) @@ -1514,37 +1519,38 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev struct ath12k_dp_link_peer *peer; struct ath12k_dp_rx_tid *rx_tid; int i; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); tfm = crypto_alloc_shash("michael_mic", 0, 0); if (IS_ERR(tfm)) return PTR_ERR(tfm); - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, vdev_id, peer_mac); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, peer_mac); if (!peer) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); crypto_free_shash(tfm); ath12k_warn(ab, "failed to find the peer to set up fragment info\n"); return -ENOENT; } if (!peer->primary_link) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); crypto_free_shash(tfm); return 0; } for (i = 0; i <= IEEE80211_NUM_TIDS; i++) { rx_tid = &peer->rx_tid[i]; - rx_tid->ab = ab; + rx_tid->dp = dp; timer_setup(&rx_tid->frag_timer, ath12k_dp_rx_frag_timer, 0); skb_queue_head_init(&rx_tid->rx_frags); } peer->tfm_mmic = tfm; peer->dp_setup_done = true; - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return 0; } diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index ff568254b686f..365f2c6449e42 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -28,7 +28,7 @@ struct ath12k_dp_rx_tid { /* Timer info related to fragments */ struct timer_list frag_timer; - struct ath12k_base *ab; + struct ath12k_dp *dp; }; struct ath12k_dp_rx_tid_rxq { @@ -244,7 +244,7 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, struct hal_rx_desc *desc); struct ath12k_dp_link_peer * -ath12k_dp_rx_h_find_link_peer(struct ath12k_base *ab, struct sk_buff *msdu, +ath12k_dp_rx_h_find_link_peer(struct ath12k_dp *dp, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info); u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, struct hal_rx_desc *desc); diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 2431485c56afa..b797d7fac88e0 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1202,11 +1202,12 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) { struct ath12k_dp_link_peer *peer, *tmp; struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); - spin_lock_bh(&ab->base_lock); - list_for_each_entry_safe(peer, tmp, &ab->peers, list) { + spin_lock_bh(&dp->dp_lock); + list_for_each_entry_safe(peer, tmp, &dp->peers, list) { /* Skip Rx TID cleanup for self peer */ if (peer->sta) ath12k_dp_rx_peer_tid_cleanup(ar, peer); @@ -1214,7 +1215,7 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) list_del(&peer->list); kfree(peer); } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ar->num_peers = 0; ar->num_stations = 0; @@ -3768,6 +3769,7 @@ static void ath12k_bss_assoc(struct ath12k *ar, bool is_auth = false; u32 hemode = 0; int ret; + struct ath12k_dp *dp = ath12k_ab_to_dp(ar->ab); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -3879,14 +3881,14 @@ static void ath12k_bss_assoc(struct ath12k *ar, "mac vdev %d up (associated) bssid %pM aid %d\n", arvif->vdev_id, bss_conf->bssid, vif->cfg.aid); - spin_lock_bh(&ar->ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, arvif->bssid); if (peer && peer->is_authorized) is_auth = true; - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); /* Authorize BSS Peer */ if (is_auth) { @@ -5702,15 +5704,18 @@ static int ath12k_clear_peer_keys(struct ath12k_link_vif *arvif, int ret; int i; u32 flags = 0; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, arvif->vdev_id, addr); - spin_unlock_bh(&ab->base_lock); - - if (!peer) + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, addr); + if (!peer) { + spin_unlock_bh(&dp->dp_lock); return -ENOENT; + } + + spin_unlock_bh(&dp->dp_lock); for (i = 0; i < ARRAY_SIZE(peer->keys); i++) { if (!peer->keys[i]) @@ -5726,9 +5731,9 @@ static int ath12k_clear_peer_keys(struct ath12k_link_vif *arvif, ath12k_warn(ab, "failed to remove peer key %d: %d\n", i, ret); - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); peer->keys[i] = NULL; - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); } return first_errno; @@ -5746,6 +5751,7 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, const u8 *peer_addr; int ret; u32 flags = 0; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -5765,12 +5771,12 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, /* the peer should not disappear in mid-way (unless FW goes awry) since * we already hold wiphy lock. we just make sure its there now. */ - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, arvif->vdev_id, + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, peer_addr); - spin_unlock_bh(&ab->base_lock); - if (!peer) { + spin_unlock_bh(&dp->dp_lock); + if (cmd == SET_KEY) { ath12k_warn(ab, "cannot install key for non-existent peer %pM\n", peer_addr); @@ -5783,6 +5789,8 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, return 0; } + spin_unlock_bh(&dp->dp_lock); + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) flags = WMI_KEY_PAIRWISE; else @@ -5800,8 +5808,8 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, return ret; } - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ab, arvif->vdev_id, + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, peer_addr); if (peer && cmd == SET_KEY) { peer->keys[key->keyidx] = key; @@ -5842,7 +5850,7 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, } } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return 0; } @@ -6602,14 +6610,15 @@ static void ath12k_mac_station_post_remove(struct ath12k *ar, struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif); struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta); struct ath12k_dp_link_peer *peer; + struct ath12k_dp *dp = ath12k_ab_to_dp(ar->ab); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); ath12k_mac_dec_num_stations(arvif, arsta); - spin_lock_bh(&ar->ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, arsta->addr); if (peer && peer->sta == sta) { ath12k_warn(ar->ab, "Found peer entry %pM n vdev %i after it was supposedly removed\n", @@ -6620,7 +6629,7 @@ static void ath12k_mac_station_post_remove(struct ath12k *ar, ar->num_peers--; } - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); kfree(arsta->rx_stats); arsta->rx_stats = NULL; @@ -6632,17 +6641,18 @@ static int ath12k_mac_station_unauthorize(struct ath12k *ar, { struct ath12k_dp_link_peer *peer; int ret; + struct ath12k_dp *dp = ath12k_ab_to_dp(ar->ab); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); - spin_lock_bh(&ar->ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, arsta->addr); if (peer) peer->is_authorized = false; - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); /* Driver must clear the keys during the state change from * IEEE80211_STA_AUTHORIZED to IEEE80211_STA_ASSOC, since after @@ -6667,17 +6677,18 @@ static int ath12k_mac_station_authorize(struct ath12k *ar, struct ath12k_dp_link_peer *peer; struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif); int ret; + struct ath12k_dp *dp = ath12k_ab_to_dp(ar->ab); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); - spin_lock_bh(&ar->ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, arsta->addr); if (peer) peer->is_authorized = true; - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); if (vif->type == NL80211_IFTYPE_STATION && arvif->is_up) { ret = ath12k_wmi_set_peer_param(ar, arsta->addr, @@ -7583,6 +7594,7 @@ void ath12k_mac_op_link_sta_rc_update(struct ieee80211_hw *hw, struct ath12k_link_vif *arvif; struct ath12k_dp_link_peer *peer; u32 bw, smps; + struct ath12k_dp *dp; rcu_read_lock(); arvif = rcu_dereference(ahvif->link[link_sta->link_id]); @@ -7594,6 +7606,7 @@ void ath12k_mac_op_link_sta_rc_update(struct ieee80211_hw *hw, } ar = arvif->ar; + dp = ath12k_ab_to_dp(ar->ab); arsta = rcu_dereference(ahsta->link[link_sta->link_id]); if (!arsta) { @@ -7602,19 +7615,19 @@ void ath12k_mac_op_link_sta_rc_update(struct ieee80211_hw *hw, link_sta->link_id, sta->addr); return; } - spin_lock_bh(&ar->ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arvif->vdev_id, + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, arsta->addr); if (!peer) { - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); ath12k_warn(ar->ab, "mac sta rc update failed to find peer %pM on vdev %i\n", arsta->addr, arvif->vdev_id); return; } - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); if (arsta->link_id >= IEEE80211_MLD_MAX_NUM_LINKS) { rcu_read_unlock(); @@ -9244,6 +9257,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, u16 mcbc_gsn; u8 link_id; int ret; + struct ath12k_dp *tmp_dp; if (ahvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { ieee80211_free_txskb(hw, skb); @@ -9369,11 +9383,12 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, if (unlikely(!ahvif->dp_vif.key_cipher)) goto skip_peer_find; - spin_lock_bh(&tmp_ar->ab->base_lock); - peer = ath12k_dp_link_peer_find_by_addr(tmp_ar->ab, + tmp_dp = ath12k_ab_to_dp(tmp_ar->ab); + spin_lock_bh(&tmp_dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_addr(tmp_dp, tmp_arvif->bssid); if (!peer) { - spin_unlock_bh(&tmp_ar->ab->base_lock); + spin_unlock_bh(&tmp_dp->dp_lock); ath12k_warn(tmp_ar->ab, "failed to find peer for vdev_id 0x%X addr %pM link_map 0x%X\n", tmp_arvif->vdev_id, tmp_arvif->bssid, @@ -9392,7 +9407,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); } - spin_unlock_bh(&tmp_ar->ab->base_lock); + spin_unlock_bh(&tmp_dp->dp_lock); skip_peer_find: ret = ath12k_wifi7_dp_tx(tmp_dp_pdev, tmp_arvif, @@ -11989,7 +12004,7 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, if (ab->hw_params->vdev_start_delay && ahvif->vdev_type != WMI_VDEV_TYPE_AP && ahvif->vdev_type != WMI_VDEV_TYPE_MONITOR && - !ath12k_dp_link_peer_exist_by_vdev_id(ab, arvif->vdev_id)) { + !ath12k_dp_link_peer_exist_by_vdev_id(ath12k_ab_to_dp(ab), arvif->vdev_id)) { ret = 0; goto out; } @@ -12871,6 +12886,8 @@ ath12k_mac_validate_fixed_rate_settings(struct ath12k *ar, enum nl80211_band ban struct ath12k_dp_link_peer *peer, *tmp; u8 vht_nss, he_nss; int ret = true; + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); vht_mcs_mask = mask->control[band].vht_mcs; he_mcs_mask = mask->control[band].he_mcs; @@ -12893,8 +12910,8 @@ ath12k_mac_validate_fixed_rate_settings(struct ath12k *ar, enum nl80211_band ban eht_nss = ath12k_mac_max_eht_nss(eht_mcs_mask); rcu_read_lock(); - spin_lock_bh(&ar->ab->base_lock); - list_for_each_entry_safe(peer, tmp, &ar->ab->peers, list) { + spin_lock_bh(&dp->dp_lock); + list_for_each_entry_safe(peer, tmp, &dp->peers, list) { if (peer->sta) { link_sta = rcu_dereference(peer->sta->link[link_id]); if (!link_sta) { @@ -12920,7 +12937,7 @@ ath12k_mac_validate_fixed_rate_settings(struct ath12k *ar, enum nl80211_band ban } } exit: - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); return ret; } diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index 28801d87e6ed2..68eebaa24ed9c 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -29,15 +29,16 @@ static int ath12k_wait_for_dp_link_peer_common(struct ath12k_base *ab, int vdev_ const u8 *addr, bool expect_mapped) { int ret; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); ret = wait_event_timeout(ab->peer_mapping_wq, ({ bool mapped; - spin_lock_bh(&ab->base_lock); - mapped = !!ath12k_dp_link_peer_find_by_vdev_and_addr(ab, + spin_lock_bh(&dp->dp_lock); + mapped = !!ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, addr); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); (mapped == expect_mapped || test_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags)); @@ -53,11 +54,12 @@ void ath12k_peer_cleanup(struct ath12k *ar, u32 vdev_id) { struct ath12k_dp_link_peer *peer, *tmp; struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); - spin_lock_bh(&ab->base_lock); - list_for_each_entry_safe(peer, tmp, &ab->peers, list) { + spin_lock_bh(&dp->dp_lock); + list_for_each_entry_safe(peer, tmp, &dp->peers, list) { if (peer->vdev_id != vdev_id) continue; @@ -69,7 +71,7 @@ void ath12k_peer_cleanup(struct ath12k *ar, u32 vdev_id) ar->num_peers--; } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); } static int ath12k_wait_for_peer_deleted(struct ath12k *ar, int vdev_id, const u8 *addr) @@ -156,6 +158,7 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ath12k_sta *ahsta; u16 ml_peer_id; int ret; + struct ath12k_dp *dp = ath12k_ab_to_dp(ar->ab); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -167,14 +170,14 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, return -ENOBUFS; } - spin_lock_bh(&ar->ab->base_lock); - peer = ath12k_dp_link_peer_find_by_pdev_and_addr(ar->ab, ar->pdev_idx, + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_pdev_and_addr(dp, ar->pdev_idx, arg->peer_addr); if (peer) { - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return -EINVAL; } - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ret = ath12k_wmi_send_peer_create_cmd(ar, arg); if (ret) { @@ -189,12 +192,12 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, if (ret) return ret; - spin_lock_bh(&ar->ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_vdev_and_addr(ar->ab, arg->vdev_id, + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arg->vdev_id, arg->peer_addr); if (!peer) { - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ath12k_warn(ar->ab, "failed to find peer %pM on vdev %i after creation\n", arg->peer_addr, arg->vdev_id); @@ -255,7 +258,7 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, ar->num_peers++; - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return 0; } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 4180db504c312..da745566aca37 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -37,6 +37,7 @@ void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u1 qref->info1 = u32_encode_bits(upper_32_bits(paddr), BUFFER_ADDR_INFO1_ADDR) | u32_encode_bits(tid, DP_REO_QREF_NUM); + ath12k_hal_reo_shared_qaddr_cache_clear(ab); } @@ -316,7 +317,6 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_desc_data *rx_info) { struct ath12k_dp *dp = dp_pdev->dp; - struct ath12k_base *ab = dp->ab; struct ath12k_skb_rxcb *rxcb; enum hal_encrypt_type enctype; bool is_decrypted = false; @@ -332,8 +332,8 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, if (rxcb->is_mcbc) rxcb->peer_id = rx_info->peer_id; - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_rx_h_find_link_peer(ab, msdu, rx_info); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_rx_h_find_link_peer(dp, msdu, rx_info); if (peer) { /* resetting mcbc bit because mcbc packets are unicast * packets only for AP as STA sends unicast packets. @@ -347,7 +347,7 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, } else { enctype = HAL_ENCRYPT_TYPE_OPEN; } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap) is_decrypted = rx_info->is_decrypted; @@ -1133,8 +1133,8 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, if (WARN_ON_ONCE(!frag_no && !more_frags)) return -EINVAL; - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); if (!peer) { ath12k_warn(ab, "failed to find the peer to de-fragment received fragment peer_id %d\n", peer_id); @@ -1193,11 +1193,11 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, goto out_unlock; } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); timer_delete_sync(&rx_tid->frag_timer); - spin_lock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); + peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); if (!peer) goto err_frags_cleanup; @@ -1221,7 +1221,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, dev_kfree_skb_any(defrag_skb); ath12k_dp_rx_frags_cleanup(rx_tid, true); out_unlock: - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return ret; } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 3d06987cfc0e6..77de02858677a 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -396,6 +396,7 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, s32 noise_floor; struct ieee80211_tx_status status = {}; struct ath12k_dp_link_peer *peer; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); skb_cb = ATH12K_SKB_CB(msdu); info = IEEE80211_SKB_CB(msdu); @@ -448,18 +449,18 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, } } rcu_read_lock(); - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, peer_id); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DATA, "dp_tx: failed to find the peer with peer_id %d\n", peer_id); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu); goto exit; } else { status.sta = peer->sta; } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); status.info = info; status.skb = msdu; @@ -527,12 +528,12 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, u8 rate_idx = 0; int ret; - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, ts->peer_id); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_id(dp, ts->peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DP_TX, "failed to find the peer by id %u\n", ts->peer_id); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return; } sta = peer->sta; @@ -546,7 +547,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, txrate.nss = arsta->last_txrate.nss; else txrate.nss = arsta->peer_nss; - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); switch (ts->pkt_type) { case HAL_TX_RATE_STATS_PKT_TYPE_11A: @@ -746,20 +747,20 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, ath12k_wifi7_dp_tx_update_txcompl(dp_pdev, ts); - spin_lock_bh(&ab->base_lock); - peer = ath12k_dp_link_peer_find_by_id(ab, ts->peer_id); + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_id(dp, ts->peer_id); if (!peer || !peer->sta) { ath12k_err(ab, "dp_tx: failed to find the peer with peer_id %d\n", ts->peer_id); - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); goto exit; } ahsta = ath12k_sta_to_ahsta(peer->sta); arsta = &ahsta->deflink; - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); status.sta = peer->sta; status.info = info; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index 4cf00c80a3a60..783d3091a7ac3 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -952,8 +952,9 @@ void ath12k_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab) { u32 val; struct ath12k_hal *hal = &ab->hal; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - lockdep_assert_held(&ab->base_lock); + lockdep_assert_held(&dp->dp_lock); val = ath12k_hif_read32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_ADDR(hal)); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index a3ea42fc09331..80f499b5df35c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -116,15 +116,16 @@ ath12k_wifi7_is_frame_link_agnostic_wcn7850(struct ath12k_link_vif *arvif, struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif); struct ath12k_hw *ah = ath12k_ar_to_ah(arvif->ar); struct ath12k_base *ab = arvif->ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); __le16 fc = mgmt->frame_control; - spin_lock_bh(&ab->base_lock); - if (!ath12k_dp_link_peer_find_by_addr(ab, mgmt->da) && + spin_lock_bh(&dp->dp_lock); + if (!ath12k_dp_link_peer_find_by_addr(dp, mgmt->da) && !ath12k_peer_ml_find(ah, mgmt->da)) { - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); return false; } - spin_unlock_bh(&ab->base_lock); + spin_unlock_bh(&dp->dp_lock); if (vif->type == NL80211_IFTYPE_STATION) return arvif->is_up && From b3da8ff6176f53cb74da673f3eaa2798849318e1 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Fri, 24 Oct 2025 23:45:44 +0530 Subject: [PATCH 078/140] wifi: ath12k: Add hash table for ath12k_dp_link_peer There is a linked list of ath12k_dp_link_peer maintained in ath12k_dp. For link peer search based on mac address, there is iteration over the list wherein the mac address are compared for each entry in the list. This search operation is a costly operation considering the time complexity involved. In order to reduce the complexity, add hash table for ath12k_dp_link_peer in ath12k_dp where mac address of the link peer is used to derive the hash index. This hash table is lock protected by spinlock "dp_lock" present in ath12k_dp. This hash table is currently used for search of link peer using mac address for any interaction between control path and data path, per packet Rx monitor path and regular multicast Tx path. Update API ath12k_dp_link_peer_find_by_addr() to make use of the hash table for search operation using mac address, while other search APIs still rely on linked list. ath11k driver has been taken as reference for implementation of hash table. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251024181548.3255166-6-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 14 ++- drivers/net/wireless/ath/ath12k/dp.h | 10 +- drivers/net/wireless/ath/ath12k/dp_peer.c | 138 ++++++++++++++++++++-- drivers/net/wireless/ath/ath12k/dp_peer.h | 9 ++ drivers/net/wireless/ath/ath12k/mac.c | 2 + 5 files changed, 160 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index ee7244d709909..03bcecd340134 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1122,6 +1122,8 @@ static void ath12k_dp_cleanup(struct ath12k_base *ab) struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int i; + ath12k_dp_link_peer_rhash_tbl_destroy(dp); + if (!dp->ab) return; @@ -1489,14 +1491,22 @@ static int ath12k_dp_setup(struct ath12k_base *ab) spin_lock_init(&dp->dp_lock); INIT_LIST_HEAD(&dp->peers); + mutex_init(&dp->link_peer_rhash_tbl_lock); + dp->reo_cmd_cache_flush_count = 0; dp->idle_link_rbm = ath12k_hal_get_idle_link_rbm(&ab->hal, ab->device_id); + ret = ath12k_dp_link_peer_rhash_tbl_init(dp); + if (ret) { + ath12k_warn(ab, "failed to init link_peer rhash table: %d\n", ret); + return ret; + } + ret = ath12k_wbm_idle_ring_setup(ab, &n_link_desc); if (ret) { ath12k_warn(ab, "failed to setup wbm_idle_ring: %d\n", ret); - return ret; + goto rhash_destroy; } srng = &ab->hal.srng_list[dp->wbm_idle_ring.ring_id]; @@ -1577,6 +1587,8 @@ static int ath12k_dp_setup(struct ath12k_base *ab) fail_link_desc_cleanup: ath12k_dp_link_desc_cleanup(ab, dp->link_desc_banks, HAL_WBM_IDLE_LINK, &dp->wbm_idle_ring); +rhash_destroy: + ath12k_dp_link_peer_rhash_tbl_destroy(dp); return ret; } diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index b2c27cb7361d3..ca4b99bad16c5 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -10,6 +10,7 @@ #include "hw.h" #include "dp_htt.h" #include "dp_cmn.h" +#include #define MAX_RXDMA_PER_PDEV 2 @@ -475,13 +476,20 @@ struct ath12k_dp { struct ath12k_hw_group *ag; u8 device_id; - /* Lock for protection of peers */ + /* Lock for protection of peers and rhead_peer_addr */ spinlock_t dp_lock; struct ath12k_dp_arch_ops *ops; /* Linked list of struct ath12k_dp_link_peer */ struct list_head peers; + + /* For rhash table init and deinit protection */ + struct mutex link_peer_rhash_tbl_lock; + + /* The rhashtable containing struct ath12k_link_peer keyed by mac addr */ + struct rhashtable *rhead_peer_addr; + struct rhashtable_params rhash_peer_addr_param; }; static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index 0267f68f85734..0cf28791568e7 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -51,18 +51,10 @@ ath12k_dp_link_peer_find_by_pdev_and_addr(struct ath12k_dp *dp, u8 pdev_idx, struct ath12k_dp_link_peer * ath12k_dp_link_peer_find_by_addr(struct ath12k_dp *dp, const u8 *addr) { - struct ath12k_dp_link_peer *peer; - lockdep_assert_held(&dp->dp_lock); - list_for_each_entry(peer, &dp->peers, list) { - if (!ether_addr_equal(peer->addr, addr)) - continue; - - return peer; - } - - return NULL; + return rhashtable_lookup_fast(dp->rhead_peer_addr, addr, + dp->rhash_peer_addr_param); } EXPORT_SYMBOL(ath12k_dp_link_peer_find_by_addr); @@ -147,6 +139,7 @@ void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "htt peer unmap vdev %d peer %pM id %d\n", peer->vdev_id, peer->addr, peer_id); + ath12k_dp_link_peer_rhash_delete(dp, peer); list_del(&peer->list); kfree(peer); wake_up(&ab->peer_mapping_wq); @@ -160,6 +153,7 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ { struct ath12k_dp_link_peer *peer; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + int ret; spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, mac_addr); @@ -173,7 +167,11 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ peer->ast_hash = ast_hash; peer->hw_peer_id = hw_peer_id; ether_addr_copy(peer->addr, mac_addr); - list_add(&peer->list, &dp->peers); + ret = ath12k_dp_link_peer_rhash_add(dp, peer); + if (!ret) + list_add(&peer->list, &dp->peers); + else + kfree(peer); wake_up(&ab->peer_mapping_wq); } @@ -209,3 +207,121 @@ struct ath12k_link_sta *ath12k_dp_link_peer_to_link_sta(struct ath12k_base *ab, } return arsta; } + +static int ath12k_dp_link_peer_rhash_addr_tbl_init(struct ath12k_dp *dp) +{ + struct ath12k_base *ab = dp->ab; + struct rhashtable_params *param; + struct rhashtable *rhash_addr_tbl; + int ret; + + lockdep_assert_held(&dp->link_peer_rhash_tbl_lock); + + rhash_addr_tbl = kzalloc(sizeof(*dp->rhead_peer_addr), GFP_KERNEL); + if (!rhash_addr_tbl) + return -ENOMEM; + + param = &dp->rhash_peer_addr_param; + + param->key_offset = offsetof(struct ath12k_dp_link_peer, addr); + param->head_offset = offsetof(struct ath12k_dp_link_peer, rhash_addr); + param->key_len = sizeof_field(struct ath12k_dp_link_peer, addr); + param->automatic_shrinking = true; + param->nelem_hint = ab->num_radios * ath12k_core_get_max_peers_per_radio(ab); + + ret = rhashtable_init(rhash_addr_tbl, param); + if (ret) { + ath12k_warn(ab, "failed to init peer addr rhash table %d\n", ret); + goto err_free; + } + + dp->rhead_peer_addr = rhash_addr_tbl; + + return 0; + +err_free: + kfree(rhash_addr_tbl); + + return ret; +} + +int ath12k_dp_link_peer_rhash_tbl_init(struct ath12k_dp *dp) +{ + int ret; + + mutex_lock(&dp->link_peer_rhash_tbl_lock); + ret = ath12k_dp_link_peer_rhash_addr_tbl_init(dp); + mutex_unlock(&dp->link_peer_rhash_tbl_lock); + + return ret; +} + +void ath12k_dp_link_peer_rhash_tbl_destroy(struct ath12k_dp *dp) +{ + mutex_lock(&dp->link_peer_rhash_tbl_lock); + rhashtable_destroy(dp->rhead_peer_addr); + kfree(dp->rhead_peer_addr); + dp->rhead_peer_addr = NULL; + mutex_unlock(&dp->link_peer_rhash_tbl_lock); +} + +static int ath12k_dp_link_peer_rhash_insert(struct ath12k_dp *dp, + struct ath12k_dp_link_peer *peer) +{ + struct ath12k_dp_link_peer *tmp; + + lockdep_assert_held(&dp->dp_lock); + + tmp = rhashtable_lookup_get_insert_fast(dp->rhead_peer_addr, &peer->rhash_addr, + dp->rhash_peer_addr_param); + if (!tmp) + return 0; + else if (IS_ERR(tmp)) + return PTR_ERR(tmp); + else + return -EEXIST; +} + +static int ath12k_dp_link_peer_rhash_remove(struct ath12k_dp *dp, + struct ath12k_dp_link_peer *peer) +{ + int ret; + + lockdep_assert_held(&dp->dp_lock); + + ret = rhashtable_remove_fast(dp->rhead_peer_addr, &peer->rhash_addr, + dp->rhash_peer_addr_param); + if (ret && ret != -ENOENT) + return ret; + + return 0; +} + +int ath12k_dp_link_peer_rhash_add(struct ath12k_dp *dp, + struct ath12k_dp_link_peer *peer) +{ + int ret; + + lockdep_assert_held(&dp->dp_lock); + + ret = ath12k_dp_link_peer_rhash_insert(dp, peer); + if (ret) + ath12k_warn(dp, "failed to add peer %pM with id %d in rhash_addr ret %d\n", + peer->addr, peer->peer_id, ret); + + return ret; +} + +void ath12k_dp_link_peer_rhash_delete(struct ath12k_dp *dp, + struct ath12k_dp_link_peer *peer) +{ + /* No failure handling and hence return type is void */ + int ret; + + lockdep_assert_held(&dp->dp_lock); + + ret = ath12k_dp_link_peer_rhash_remove(dp, peer); + if (ret) + ath12k_warn(dp, "failed to remove peer %pM with id %d in rhash_addr ret %d\n", + peer->addr, peer->peer_id, ret); +} diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h index ecc90df05b444..b94a9a5cb311c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.h +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h @@ -63,6 +63,9 @@ struct ath12k_dp_link_peer { /* for reference to ath12k_link_sta */ u8 link_id; bool ucast_ra_only; + + /* peer addr based rhashtable list pointer */ + struct rhash_head rhash_addr; }; void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); @@ -83,4 +86,10 @@ ath12k_dp_link_peer_find_by_pdev_and_addr(struct ath12k_dp *dp, u8 pdev_idx, const u8 *addr); struct ath12k_link_sta *ath12k_dp_link_peer_to_link_sta(struct ath12k_base *ab, struct ath12k_dp_link_peer *peer); +int ath12k_dp_link_peer_rhash_tbl_init(struct ath12k_dp *dp); +void ath12k_dp_link_peer_rhash_tbl_destroy(struct ath12k_dp *dp); +int ath12k_dp_link_peer_rhash_add(struct ath12k_dp *dp, + struct ath12k_dp_link_peer *peer); +void ath12k_dp_link_peer_rhash_delete(struct ath12k_dp *dp, + struct ath12k_dp_link_peer *peer); #endif diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index b797d7fac88e0..e0f063dc4cd4b 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1212,6 +1212,8 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) if (peer->sta) ath12k_dp_rx_peer_tid_cleanup(ar, peer); + ath12k_dp_link_peer_rhash_delete(dp, peer); + list_del(&peer->list); kfree(peer); } From 3b01548beb30108fb1aa1e53834950a9dd9847aa Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Fri, 24 Oct 2025 23:45:45 +0530 Subject: [PATCH 079/140] wifi: ath12k: Define ath12k_dp_peer structure & APIs for create & delete Define the structure of ath12k_dp_peer and also define APIs for creation and deletion of ath12k_dp_peer based on STA state, as the ath12k_dp_peer is intended to be used in the subsequent set of patches. Maintain ath12k_dp_peer in a linked list in ath12k_dp_hw (which is a datapath component of ath12k_hw) and protect this list using spinlock "peer_lock". Store peer id based table (array of RCU pointers) of ath12k_dp_peer in ath12k_dp_hw. Use this peer id table to refer in the per packet Tx and Rx paths as it provides faster access to ath12k_dp_peer in comparison to linked list iterative search using peer id or mac address. Add support to handle deletion of ath12k_dp_peer in case of core reset. This patch is adding and deleting ath12k_dp_peer created for MLO STA to the above mentioned RCU pointer table. Addition and deletion of ath12k_dp_peer for non-MLO STA to RCU pointer table is handled in the subsequent following patch. Structure ath12k_ml_peer is created and deleted for MLO peers at the time of connect and disconnect and there is no other use case of it. With the above design in place for ath12k_dp_peer, ath12k_ml_peer becomes redundant. Hence, remove the structure ath12k_ml_peer and the list "ml_peers" present in ath12k_hw maintaining linked list of ath12k_ml_peer. APIs removed: - ath12k_peer_ml_find() - ath12k_peer_ml_create() - ath12k_peer_ml_delete() Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251024181548.3255166-7-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.c | 1 + drivers/net/wireless/ath/ath12k/core.h | 3 +- drivers/net/wireless/ath/ath12k/dp_cmn.h | 22 ++++ drivers/net/wireless/ath/ath12k/dp_peer.c | 126 +++++++++++++++++++++ drivers/net/wireless/ath/ath12k/dp_peer.h | 24 ++++ drivers/net/wireless/ath/ath12k/mac.c | 115 +++++++++++++++++-- drivers/net/wireless/ath/ath12k/mac.h | 1 + drivers/net/wireless/ath/ath12k/peer.c | 81 +------------ drivers/net/wireless/ath/ath12k/peer.h | 9 +- drivers/net/wireless/ath/ath12k/wifi7/hw.c | 14 ++- 10 files changed, 291 insertions(+), 105 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 0bd863f83cb0e..0ab9a09d43a89 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -1575,6 +1575,7 @@ static void ath12k_core_post_reconfigure_recovery(struct ath12k_base *ab) ath12k_core_halt(ar); } + ath12k_mac_dp_peer_cleanup(ah); break; case ATH12K_HW_STATE_OFF: ath12k_warn(ab, diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index bb48e93b9b937..37e3bf0678a2f 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -842,8 +842,7 @@ struct ath12k_hw { DECLARE_BITMAP(free_ml_peer_id_map, ATH12K_MAX_MLO_PEERS); - /* protected by wiphy_lock() */ - struct list_head ml_peers; + struct ath12k_dp_hw dp_hw; /* Keep last */ struct ath12k radio[] __aligned(sizeof(void *)); diff --git a/drivers/net/wireless/ath/ath12k/dp_cmn.h b/drivers/net/wireless/ath/ath12k/dp_cmn.h index 243fb5a680167..52b7fa2eb138b 100644 --- a/drivers/net/wireless/ath/ath12k/dp_cmn.h +++ b/drivers/net/wireless/ath/ath12k/dp_cmn.h @@ -10,6 +10,21 @@ struct ath12k_hw_group; +/* + * ML Peer IDs start from 8192, assuming max SLO clients count 1536, + * then max peer id shall be 9728, therefore rounding the peer table size + * to the nearest next power of 2 i.e 16384. + */ +#define MAX_DP_PEER_LIST_SIZE 16384 + +struct ath12k_dp_hw { + struct ath12k_dp_peer __rcu *dp_peers[MAX_DP_PEER_LIST_SIZE]; + + /* Lock for protection of dp_peer_list and peers */ + spinlock_t peer_lock; + struct list_head dp_peers_list; +}; + struct ath12k_dp_hw_group { struct ath12k_dp *dp[ATH12K_MAX_DEVICES]; }; @@ -52,6 +67,13 @@ struct ath12k_per_peer_tx_stats { bool is_ampdu; }; +struct ath12k_dp_peer_create_params { + struct ieee80211_sta *sta; + bool is_mlo; + u16 peer_id; + bool ucast_ra_only; +}; + static inline struct ath12k_dp_link_vif * ath12k_dp_vif_to_dp_link_vif(struct ath12k_dp_vif *dp_vif, u8 link_id) { diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index 0cf28791568e7..a2834d043dd52 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -325,3 +325,129 @@ void ath12k_dp_link_peer_rhash_delete(struct ath12k_dp *dp, ath12k_warn(dp, "failed to remove peer %pM with id %d in rhash_addr ret %d\n", peer->addr, peer->peer_id, ret); } + +struct ath12k_dp_peer *ath12k_dp_peer_find_by_addr(struct ath12k_dp_hw *dp_hw, u8 *addr) +{ + struct ath12k_dp_peer *peer; + + lockdep_assert_held(&dp_hw->peer_lock); + + list_for_each_entry(peer, &dp_hw->dp_peers_list, list) { + if (ether_addr_equal(peer->addr, addr)) + return peer; + } + + return NULL; +} +EXPORT_SYMBOL(ath12k_dp_peer_find_by_addr); + +struct ath12k_dp_peer *ath12k_dp_peer_find_by_addr_and_sta(struct ath12k_dp_hw *dp_hw, + u8 *addr, + struct ieee80211_sta *sta) +{ + struct ath12k_dp_peer *dp_peer; + + lockdep_assert_held(&dp_hw->peer_lock); + + list_for_each_entry(dp_peer, &dp_hw->dp_peers_list, list) { + if (ether_addr_equal(dp_peer->addr, addr) && (dp_peer->sta == sta)) + return dp_peer; + } + + return NULL; +} + +static struct ath12k_dp_peer *ath12k_dp_peer_create_find(struct ath12k_dp_hw *dp_hw, + u8 *addr, + struct ieee80211_sta *sta, + bool mlo_peer) +{ + struct ath12k_dp_peer *dp_peer; + + lockdep_assert_held(&dp_hw->peer_lock); + + list_for_each_entry(dp_peer, &dp_hw->dp_peers_list, list) { + if (ether_addr_equal(dp_peer->addr, addr)) { + if (!sta || mlo_peer || dp_peer->is_mlo || + dp_peer->sta == sta) + return dp_peer; + } + } + + return NULL; +} + +int ath12k_dp_peer_create(struct ath12k_dp_hw *dp_hw, u8 *addr, + struct ath12k_dp_peer_create_params *params) +{ + struct ath12k_dp_peer *dp_peer; + + spin_lock_bh(&dp_hw->peer_lock); + dp_peer = ath12k_dp_peer_create_find(dp_hw, addr, params->sta, params->is_mlo); + if (dp_peer) { + spin_unlock_bh(&dp_hw->peer_lock); + return -EEXIST; + } + spin_unlock_bh(&dp_hw->peer_lock); + + dp_peer = kzalloc(sizeof(*dp_peer), GFP_ATOMIC); + if (!dp_peer) + return -ENOMEM; + + ether_addr_copy(dp_peer->addr, addr); + dp_peer->sta = params->sta; + dp_peer->is_mlo = params->is_mlo; + + /* + * For MLO client, the host assigns the ML peer ID, so set peer_id in dp_peer + * For non-MLO client, host gets link peer ID from firmware and will be + * assigned at the time of link peer creation + */ + dp_peer->peer_id = params->is_mlo ? params->peer_id : ATH12K_DP_PEER_ID_INVALID; + dp_peer->ucast_ra_only = params->ucast_ra_only; + + dp_peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; + dp_peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; + + spin_lock_bh(&dp_hw->peer_lock); + + list_add(&dp_peer->list, &dp_hw->dp_peers_list); + + /* + * For MLO client, the peer_id for ath12k_dp_peer is allocated by host + * and that peer_id is known at this point, and hence this ath12k_dp_peer + * can be added to the RCU table using the peer_id. + * For non-MLO client, this addition to RCU table shall be done at the + * time of assignment of ath12k_dp_link_peer to ath12k_dp_peer. + */ + if (dp_peer->is_mlo) + rcu_assign_pointer(dp_hw->dp_peers[dp_peer->peer_id], dp_peer); + + spin_unlock_bh(&dp_hw->peer_lock); + + return 0; +} + +void ath12k_dp_peer_delete(struct ath12k_dp_hw *dp_hw, u8 *addr, + struct ieee80211_sta *sta) +{ + struct ath12k_dp_peer *dp_peer; + + spin_lock_bh(&dp_hw->peer_lock); + + dp_peer = ath12k_dp_peer_find_by_addr_and_sta(dp_hw, addr, sta); + if (!dp_peer) { + spin_unlock_bh(&dp_hw->peer_lock); + return; + } + + if (dp_peer->is_mlo) + rcu_assign_pointer(dp_hw->dp_peers[dp_peer->peer_id], NULL); + + list_del(&dp_peer->list); + + spin_unlock_bh(&dp_hw->peer_lock); + + synchronize_rcu(); + kfree(dp_peer); +} diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h index b94a9a5cb311c..b4aa4f09337e0 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.h +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h @@ -9,6 +9,8 @@ #include "dp_rx.h" +#define ATH12K_DP_PEER_ID_INVALID 0x3FFF + struct ppdu_user_delayba { u16 sw_peer_id; u32 info0; @@ -71,6 +73,20 @@ struct ath12k_dp_link_peer { void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_id, u8 *mac_addr, u16 ast_hash, u16 hw_peer_id); + +struct ath12k_dp_peer { + struct list_head list; + struct ieee80211_sta *sta; + int peer_id; + u8 addr[ETH_ALEN]; + bool is_mlo; + + u16 sec_type; + u16 sec_type_grp; + + bool ucast_ra_only; +}; + struct ath12k_dp_link_peer * ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_dp *dp, int vdev_id, const u8 *addr); @@ -92,4 +108,12 @@ int ath12k_dp_link_peer_rhash_add(struct ath12k_dp *dp, struct ath12k_dp_link_peer *peer); void ath12k_dp_link_peer_rhash_delete(struct ath12k_dp *dp, struct ath12k_dp_link_peer *peer); +int ath12k_dp_peer_create(struct ath12k_dp_hw *dp_hw, u8 *addr, + struct ath12k_dp_peer_create_params *params); +void ath12k_dp_peer_delete(struct ath12k_dp_hw *dp_hw, u8 *addr, + struct ieee80211_sta *sta); +struct ath12k_dp_peer *ath12k_dp_peer_find_by_addr(struct ath12k_dp_hw *dp_hw, u8 *addr); +struct ath12k_dp_peer *ath12k_dp_peer_find_by_addr_and_sta(struct ath12k_dp_hw *dp_hw, + u8 *addr, + struct ieee80211_sta *sta); #endif diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index e0f063dc4cd4b..286d2b7a7730a 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1203,6 +1203,8 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) struct ath12k_dp_link_peer *peer, *tmp; struct ath12k_base *ab = ar->ab; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_link_vif *arvif, *tmp_vif; + struct ath12k_dp_hw *dp_hw = &ar->ah->dp_hw; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -1225,6 +1227,42 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) /* Cleanup rhash table maintained for arsta by iterating over sta */ ieee80211_iterate_stations_mtx(ar->ah->hw, ath12k_mac_link_sta_rhash_cleanup, ar); + + /* Delete all the self dp_peers on asserted radio */ + list_for_each_entry_safe_reverse(arvif, tmp_vif, &ar->arvifs, list) { + if (arvif->ahvif->vdev_type == WMI_VDEV_TYPE_AP) { + ath12k_dp_peer_delete(dp_hw, arvif->bssid, NULL); + arvif->num_stations = 0; + } + } +} + +void ath12k_mac_dp_peer_cleanup(struct ath12k_hw *ah) +{ + struct list_head peers; + struct ath12k_dp_peer *dp_peer, *tmp; + struct ath12k_dp_hw *dp_hw = &ah->dp_hw; + + INIT_LIST_HEAD(&peers); + + spin_lock_bh(&dp_hw->peer_lock); + list_for_each_entry_safe(dp_peer, tmp, &dp_hw->dp_peers_list, list) { + if (dp_peer->is_mlo) { + rcu_assign_pointer(dp_hw->dp_peers[dp_peer->peer_id], NULL); + clear_bit(dp_peer->peer_id, ah->free_ml_peer_id_map); + } + + list_move(&dp_peer->list, &peers); + } + + spin_unlock_bh(&dp_hw->peer_lock); + + synchronize_rcu(); + + list_for_each_entry_safe(dp_peer, tmp, &peers, list) { + list_del(&dp_peer->list); + kfree(dp_peer); + } } static int ath12k_mac_vdev_setup_sync(struct ath12k *ar) @@ -4126,6 +4164,8 @@ static void ath12k_mac_remove_link_interface(struct ieee80211_hw *hw, if (ret) ath12k_warn(ar->ab, "failed to submit AP self-peer removal on vdev %d link id %d: %d", arvif->vdev_id, arvif->link_id, ret); + + ath12k_dp_peer_delete(&ah->dp_hw, arvif->bssid, NULL); } ath12k_mac_vdev_delete(ar, arvif); } @@ -6944,7 +6984,10 @@ static void ath12k_mac_ml_station_remove(struct ath12k_vif *ahvif, ath12k_mac_free_unassign_link_sta(ah, ahsta, link_id); } - ath12k_peer_ml_delete(ah, sta); + if (sta->mlo) { + clear_bit(ahsta->ml_peer_id, ah->free_ml_peer_id_map); + ahsta->ml_peer_id = ATH12K_MLO_PEER_ID_INVALID; + } } static int ath12k_mac_handle_link_sta_state(struct ieee80211_hw *hw, @@ -7383,7 +7426,8 @@ int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, u16 selected_links = 0; u8 link_id = 0, i; struct ath12k *ar; - int ret; + int ret = -EINVAL; + struct ath12k_dp_peer_create_params dp_params = {}; lockdep_assert_wiphy(hw->wiphy); @@ -7406,12 +7450,28 @@ int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, /* ML sta */ if (sta->mlo && !ahsta->links_map && (hweight16(sta->valid_links) == 1)) { - ret = ath12k_peer_ml_create(ah, sta); - if (ret) { - ath12k_hw_warn(ah, "unable to create ML peer for sta %pM", + ahsta->ml_peer_id = ath12k_peer_ml_alloc(ah); + if (ahsta->ml_peer_id == ATH12K_MLO_PEER_ID_INVALID) { + ath12k_hw_warn(ah, "unable to allocate ML peer id for sta %pM", sta->addr); goto exit; } + + dp_params.is_mlo = true; + dp_params.peer_id = ahsta->ml_peer_id | ATH12K_PEER_ML_ID_VALID; + } + + dp_params.sta = sta; + + if (vif->type == NL80211_IFTYPE_AP) + dp_params.ucast_ra_only = true; + + ret = ath12k_dp_peer_create(&ah->dp_hw, sta->addr, &dp_params); + if (ret) { + ath12k_hw_warn(ah, "unable to create ath12k_dp_peer for sta %pM, ret: %d", + sta->addr, ret); + + goto ml_peer_id_clear; } ret = ath12k_mac_assign_link_sta(ah, ahsta, arsta, ahvif, @@ -7419,7 +7479,7 @@ int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, if (ret) { ath12k_hw_warn(ah, "unable assign link %d for sta %pM", link_id, sta->addr); - goto exit; + goto peer_delete; } /* above arsta will get memset, hence do this after assign @@ -7489,7 +7549,12 @@ int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, if (ret) { ath12k_hw_warn(ah, "unable to move link sta %d of sta %pM from state %d to %d", link_id, arsta->addr, old_state, new_state); - goto exit; + + if (old_state == IEEE80211_STA_NOTEXIST && + new_state == IEEE80211_STA_NONE) + goto peer_delete; + else + goto exit; } } @@ -7517,11 +7582,23 @@ int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, * handler below */ if (old_state == IEEE80211_STA_NONE && - new_state == IEEE80211_STA_NOTEXIST && sta->mlo) - ath12k_mac_ml_station_remove(ahvif, ahsta); + new_state == IEEE80211_STA_NOTEXIST) { + if (sta->mlo) + ath12k_mac_ml_station_remove(ahvif, ahsta); + + ath12k_dp_peer_delete(&ah->dp_hw, sta->addr, sta); + } ret = 0; + goto exit; +peer_delete: + ath12k_dp_peer_delete(&ah->dp_hw, sta->addr, sta); +ml_peer_id_clear: + if (sta->mlo) { + clear_bit(ahsta->ml_peer_id, ah->free_ml_peer_id_map); + ahsta->ml_peer_id = ATH12K_MLO_PEER_ID_INVALID; + } exit: /* update the state if everything went well */ if (!ret) @@ -10148,6 +10225,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) int ret, vdev_id; u8 link_id; struct ath12k_dp_link_vif *dp_link_vif = NULL; + struct ath12k_dp_peer_create_params params = {}; lockdep_assert_wiphy(hw->wiphy); @@ -10237,6 +10315,15 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) switch (ahvif->vdev_type) { case WMI_VDEV_TYPE_AP: + params.ucast_ra_only = true; + + ret = ath12k_dp_peer_create(&ah->dp_hw, arvif->bssid, ¶ms); + if (ret) { + ath12k_warn(ab, "failed to vdev %d create dp_peer for AP: %d\n", + arvif->vdev_id, ret); + goto err_vdev_del; + } + peer_param.vdev_id = arvif->vdev_id; peer_param.peer_addr = arvif->bssid; peer_param.peer_type = WMI_PEER_TYPE_DEFAULT; @@ -10244,7 +10331,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) if (ret) { ath12k_warn(ab, "failed to vdev %d create peer for AP: %d\n", arvif->vdev_id, ret); - goto err_vdev_del; + goto err_dp_peer_del; } ret = ath12k_mac_set_kickout(arvif); @@ -10350,6 +10437,10 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) ar->num_peers--; } +err_dp_peer_del: + if (ahvif->vdev_type == WMI_VDEV_TYPE_AP) + ath12k_dp_peer_delete(&ah->dp_hw, arvif->bssid, NULL); + err_vdev_del: if (ahvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { ar->monitor_vdev_id = -1; @@ -14900,7 +14991,9 @@ static struct ath12k_hw *ath12k_mac_hw_allocate(struct ath12k_hw_group *ag, ah->num_radio = num_pdev_map; mutex_init(&ah->hw_mutex); - INIT_LIST_HEAD(&ah->ml_peers); + + spin_lock_init(&ah->dp_hw.peer_lock); + INIT_LIST_HEAD(&ah->dp_hw.dp_peers_list); for (i = 0; i < num_pdev_map; i++) { ab = pdev_map[i].ab; diff --git a/drivers/net/wireless/ath/ath12k/mac.h b/drivers/net/wireless/ath/ath12k/mac.h index ef5c3570bef10..ed7ad3ca4f407 100644 --- a/drivers/net/wireless/ath/ath12k/mac.h +++ b/drivers/net/wireless/ath/ath12k/mac.h @@ -169,6 +169,7 @@ struct ath12k *ath12k_mac_get_ar_by_pdev_id(struct ath12k_base *ab, u32 pdev_id) void ath12k_mac_drain_tx(struct ath12k *ar); void ath12k_mac_peer_cleanup_all(struct ath12k *ar); +void ath12k_mac_dp_peer_cleanup(struct ath12k_hw *ah); int ath12k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx); enum rate_info_bw ath12k_mac_bw_to_mac80211_bw(enum ath12k_supported_bw bw); enum ath12k_supported_bw ath12k_mac_mac80211_bw_to_ath12k_bw(enum rate_info_bw bw); diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index 68eebaa24ed9c..691314efe23f6 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -8,23 +8,6 @@ #include "peer.h" #include "debug.h" -struct ath12k_ml_peer *ath12k_peer_ml_find(struct ath12k_hw *ah, const u8 *addr) -{ - struct ath12k_ml_peer *ml_peer; - - lockdep_assert_wiphy(ah->hw->wiphy); - - list_for_each_entry(ml_peer, &ah->ml_peers, list) { - if (!ether_addr_equal(ml_peer->addr, addr)) - continue; - - return ml_peer; - } - - return NULL; -} -EXPORT_SYMBOL(ath12k_peer_ml_find); - static int ath12k_wait_for_dp_link_peer_common(struct ath12k_base *ab, int vdev_id, const u8 *addr, bool expect_mapped) { @@ -263,7 +246,7 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, return 0; } -static u16 ath12k_peer_ml_alloc(struct ath12k_hw *ah) +u16 ath12k_peer_ml_alloc(struct ath12k_hw *ah) { u16 ml_peer_id; @@ -283,68 +266,6 @@ static u16 ath12k_peer_ml_alloc(struct ath12k_hw *ah) return ml_peer_id; } -int ath12k_peer_ml_create(struct ath12k_hw *ah, struct ieee80211_sta *sta) -{ - struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta); - struct ath12k_ml_peer *ml_peer; - - lockdep_assert_wiphy(ah->hw->wiphy); - - if (!sta->mlo) - return -EINVAL; - - ml_peer = ath12k_peer_ml_find(ah, sta->addr); - if (ml_peer) { - ath12k_hw_warn(ah, "ML peer %d exists already, unable to add new entry for %pM", - ml_peer->id, sta->addr); - return -EEXIST; - } - - ml_peer = kzalloc(sizeof(*ml_peer), GFP_ATOMIC); - if (!ml_peer) - return -ENOMEM; - - ahsta->ml_peer_id = ath12k_peer_ml_alloc(ah); - - if (ahsta->ml_peer_id == ATH12K_MLO_PEER_ID_INVALID) { - ath12k_hw_warn(ah, "unable to allocate ML peer id for sta %pM", - sta->addr); - kfree(ml_peer); - return -ENOMEM; - } - - ether_addr_copy(ml_peer->addr, sta->addr); - ml_peer->id = ahsta->ml_peer_id; - list_add(&ml_peer->list, &ah->ml_peers); - - return 0; -} - -int ath12k_peer_ml_delete(struct ath12k_hw *ah, struct ieee80211_sta *sta) -{ - struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta); - struct ath12k_ml_peer *ml_peer; - - lockdep_assert_wiphy(ah->hw->wiphy); - - if (!sta->mlo) - return -EINVAL; - - clear_bit(ahsta->ml_peer_id, ah->free_ml_peer_id_map); - ahsta->ml_peer_id = ATH12K_MLO_PEER_ID_INVALID; - - ml_peer = ath12k_peer_ml_find(ah, sta->addr); - if (!ml_peer) { - ath12k_hw_warn(ah, "ML peer for %pM not found", sta->addr); - return -EINVAL; - } - - list_del(&ml_peer->list); - kfree(ml_peer); - - return 0; -} - int ath12k_peer_mlo_link_peers_delete(struct ath12k_vif *ahvif, struct ath12k_sta *ahsta) { struct ieee80211_sta *sta = ath12k_ahsta_to_sta(ahsta); diff --git a/drivers/net/wireless/ath/ath12k/peer.h b/drivers/net/wireless/ath/ath12k/peer.h index cf8a463d4c371..49d89796bc46e 100644 --- a/drivers/net/wireless/ath/ath12k/peer.h +++ b/drivers/net/wireless/ath/ath12k/peer.h @@ -9,12 +9,6 @@ #include "dp_peer.h" -struct ath12k_ml_peer { - struct list_head list; - u8 addr[ETH_ALEN]; - u16 id; -}; - void ath12k_peer_cleanup(struct ath12k *ar, u32 vdev_id); int ath12k_peer_delete(struct ath12k *ar, u32 vdev_id, u8 *addr); int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, @@ -22,8 +16,6 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ath12k_wmi_peer_create_arg *arg); int ath12k_wait_for_peer_delete_done(struct ath12k *ar, u32 vdev_id, const u8 *addr); -int ath12k_peer_ml_create(struct ath12k_hw *ah, struct ieee80211_sta *sta); -int ath12k_peer_ml_delete(struct ath12k_hw *ah, struct ieee80211_sta *sta); int ath12k_peer_mlo_link_peers_delete(struct ath12k_vif *ahvif, struct ath12k_sta *ahsta); struct ath12k_ml_peer *ath12k_peer_ml_find(struct ath12k_hw *ah, const u8 *addr); @@ -33,4 +25,5 @@ void ath12k_link_sta_rhash_delete(struct ath12k_base *ab, struct ath12k_link_sta int ath12k_link_sta_rhash_add(struct ath12k_base *ab, struct ath12k_link_sta *arsta); struct ath12k_link_sta *ath12k_link_sta_find_by_addr(struct ath12k_base *ab, const u8 *addr); +u16 ath12k_peer_ml_alloc(struct ath12k_hw *ah); #endif /* _PEER_H_ */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 80f499b5df35c..946771b96fb58 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -117,13 +117,19 @@ ath12k_wifi7_is_frame_link_agnostic_wcn7850(struct ath12k_link_vif *arvif, struct ath12k_hw *ah = ath12k_ar_to_ah(arvif->ar); struct ath12k_base *ab = arvif->ar->ab; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_dp_peer *peer; __le16 fc = mgmt->frame_control; spin_lock_bh(&dp->dp_lock); - if (!ath12k_dp_link_peer_find_by_addr(dp, mgmt->da) && - !ath12k_peer_ml_find(ah, mgmt->da)) { - spin_unlock_bh(&dp->dp_lock); - return false; + if (!ath12k_dp_link_peer_find_by_addr(dp, mgmt->da)) { + spin_lock_bh(&ah->dp_hw.peer_lock); + peer = ath12k_dp_peer_find_by_addr(&ah->dp_hw, mgmt->da); + if (!peer || (peer && !peer->is_mlo)) { + spin_unlock_bh(&ah->dp_hw.peer_lock); + spin_unlock_bh(&dp->dp_lock); + return false; + } + spin_unlock_bh(&ah->dp_hw.peer_lock); } spin_unlock_bh(&dp->dp_lock); From 3fe0e390999402a4f5d29654449d99ffc452dda3 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Fri, 24 Oct 2025 23:45:46 +0530 Subject: [PATCH 080/140] wifi: ath12k: Attach and detach ath12k_dp_link_peer to ath12k_dp_peer Introduce explicit attach/detach of ath12k_dp_link_peer objects to their parent ath12k_dp_peer to formalize the data path station hierarchy: ath12k_dp_peer | |--> ath12k_dp_link_peer | |--> ath12k_dp_link_peer | |--> ath12k_dp_link_peer ath12k_dp_peer maintains an array of RCU-protected pointers "link_peers[ATH12K_NUM_MAX_LINKS]" to ath12k_dp_link_peer indexed by its protocol_link_id, and each ath12k_dp_link_peer holds a back pointer to its parent ath12k_dp_peer. Attach is performed after link peer creation, and detach occurs before link peer deletion. This ensures consistent lifetime management and safe concurrent access. ath12k_dp_peer also maintains an array "hw_links[ATH12K_GROUP_MAX_RADIO]" to store the mapping between hw_link_id and protocol_link_id for each of the ath12k_dp_link_peer. RCU locking/unlocking rules: - Readers must hold rcu_read_lock() and fetch the pointer with rcu_dereference(dp_peer->link[link_id]); drop with rcu_read_unlock() when done. - Writers publish with rcu_assign_pointer() and reclaim only after synchronize_rcu(). Handle the case of detachment of link peer from ath12k_dp_peer in case of core reset. Ensure the following order of locks to be followed for attach and detach: - Lock dp->dp_lock - Lock dp_hw->peer_lock - Unlock dp_hw->peer_lock - Unlock dp->dp_lock Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251024181548.3255166-8-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 1 + drivers/net/wireless/ath/ath12k/dp.h | 1 + drivers/net/wireless/ath/ath12k/dp_cmn.h | 6 +- drivers/net/wireless/ath/ath12k/dp_peer.c | 146 ++++++++++++++++++++-- drivers/net/wireless/ath/ath12k/dp_peer.h | 7 ++ drivers/net/wireless/ath/ath12k/mac.c | 21 +++- drivers/net/wireless/ath/ath12k/peer.c | 17 ++- 7 files changed, 189 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 03bcecd340134..4387c1b42b88f 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -887,6 +887,7 @@ int ath12k_dp_pdev_alloc(struct ath12k_base *ab) dp_pdev->hw = ar->ah->hw; dp_pdev->dp = dp; dp_pdev->hw_link_id = ar->hw_link_id; + dp_pdev->dp_hw = &ar->ah->dp_hw; ret = ath12k_dp_rx_pdev_alloc(ab, i); if (ret) { diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index ca4b99bad16c5..b4ded1e4581b0 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -158,6 +158,7 @@ struct ath12k_pdev_dp { struct ath12k_dp *dp; struct ieee80211_hw *hw; u8 hw_link_id; + struct ath12k_dp_hw *dp_hw; /* Protects ppdu stats */ spinlock_t ppdu_list_lock; diff --git a/drivers/net/wireless/ath/ath12k/dp_cmn.h b/drivers/net/wireless/ath/ath12k/dp_cmn.h index 52b7fa2eb138b..dd10426bd12de 100644 --- a/drivers/net/wireless/ath/ath12k/dp_cmn.h +++ b/drivers/net/wireless/ath/ath12k/dp_cmn.h @@ -86,5 +86,9 @@ void ath12k_dp_cmn_hw_group_unassign(struct ath12k_dp *dp, struct ath12k_hw_group *ag); void ath12k_dp_cmn_hw_group_assign(struct ath12k_dp *dp, struct ath12k_hw_group *ag); - +int ath12k_dp_link_peer_assign(struct ath12k_dp *dp, struct ath12k_dp_hw *dp_hw, + u8 vdev_id, struct ieee80211_sta *sta, u8 *addr, + u8 link_id, u32 hw_link_id); +void ath12k_dp_link_peer_unassign(struct ath12k_dp *dp, struct ath12k_dp_hw *dp_hw, + u8 vdev_id, u8 *addr, u32 hw_link_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index a2834d043dd52..fe4748648a844 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -139,7 +139,6 @@ void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "htt peer unmap vdev %d peer %pM id %d\n", peer->vdev_id, peer->addr, peer_id); - ath12k_dp_link_peer_rhash_delete(dp, peer); list_del(&peer->list); kfree(peer); wake_up(&ab->peer_mapping_wq); @@ -153,7 +152,6 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ { struct ath12k_dp_link_peer *peer; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - int ret; spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, mac_addr); @@ -167,11 +165,7 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ peer->ast_hash = ast_hash; peer->hw_peer_id = hw_peer_id; ether_addr_copy(peer->addr, mac_addr); - ret = ath12k_dp_link_peer_rhash_add(dp, peer); - if (!ret) - list_add(&peer->list, &dp->peers); - else - kfree(peer); + list_add(&peer->list, &dp->peers); wake_up(&ab->peer_mapping_wq); } @@ -377,6 +371,23 @@ static struct ath12k_dp_peer *ath12k_dp_peer_create_find(struct ath12k_dp_hw *dp return NULL; } +/* + * Index of ath12k_dp_peer for MLO client is same as peer id of ath12k_dp_peer, + * while for ath12k_dp_link_peer(mlo and non-mlo) and ath12k_dp_peer for + * Non-MLO client it is derived as ((DEVICE_ID << 10) | (10 bits of peer id)). + * + * This is done because ml_peer_id and peer_id_table are at hw granularity, + * while link_peer_id is at device granularity, hence in order to avoid + * conflict this approach is followed. + */ +#define ATH12K_DP_PEER_TABLE_DEVICE_ID_SHIFT 10 + +u16 ath12k_dp_peer_get_peerid_index(struct ath12k_dp *dp, u16 peer_id) +{ + return (peer_id & ATH12K_PEER_ML_ID_VALID) ? peer_id : + ((dp->device_id << ATH12K_DP_PEER_TABLE_DEVICE_ID_SHIFT) | peer_id); +} + int ath12k_dp_peer_create(struct ath12k_dp_hw *dp_hw, u8 *addr, struct ath12k_dp_peer_create_params *params) { @@ -451,3 +462,124 @@ void ath12k_dp_peer_delete(struct ath12k_dp_hw *dp_hw, u8 *addr, synchronize_rcu(); kfree(dp_peer); } + +int ath12k_dp_link_peer_assign(struct ath12k_dp *dp, struct ath12k_dp_hw *dp_hw, + u8 vdev_id, struct ieee80211_sta *sta, u8 *addr, + u8 link_id, u32 hw_link_id) +{ + struct ath12k_dp_peer *dp_peer; + struct ath12k_dp_link_peer *peer, *temp_peer; + u16 peerid_index; + int ret = -EINVAL; + u8 *dp_peer_mac = !sta ? addr : sta->addr; + + spin_lock_bh(&dp->dp_lock); + + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, addr); + if (!peer) { + ath12k_warn(dp, "failed to find dp_link_peer with mac %pM on vdev %u\n", + addr, vdev_id); + ret = -ENOENT; + goto err_peer; + } + + spin_lock_bh(&dp_hw->peer_lock); + + dp_peer = ath12k_dp_peer_find_by_addr_and_sta(dp_hw, dp_peer_mac, sta); + if (!dp_peer) { + ath12k_warn(dp, "failed to find dp_peer with mac %pM\n", dp_peer_mac); + ret = -ENOENT; + goto err_dp_peer; + } + + /* + * Set peer_id in dp_peer for non-mlo client, peer_id for mlo client is + * set during dp_peer create + */ + if (!dp_peer->is_mlo) + dp_peer->peer_id = peer->peer_id; + + peer->dp_peer = dp_peer; + peer->hw_link_id = hw_link_id; + + dp_peer->hw_links[peer->hw_link_id] = link_id; + + peerid_index = ath12k_dp_peer_get_peerid_index(dp, peer->peer_id); + + rcu_assign_pointer(dp_peer->link_peers[peer->link_id], peer); + + rcu_assign_pointer(dp_hw->dp_peers[peerid_index], dp_peer); + + spin_unlock_bh(&dp_hw->peer_lock); + + /* + * In case of Split PHY and roaming scenario, pdev idx + * might differ but both the pdev will share same rhash + * table. In that case update the rhash table if link_peer is + * already present + */ + temp_peer = ath12k_dp_link_peer_find_by_addr(dp, addr); + if (temp_peer && temp_peer->hw_link_id != hw_link_id) + ath12k_dp_link_peer_rhash_delete(dp, temp_peer); + + ret = ath12k_dp_link_peer_rhash_add(dp, peer); + if (ret) { + /* + * If new entry addition failed, add back old entry + * If old entry addition also fails, then nothing + * can be done, simply proceed + */ + if (temp_peer) + ath12k_dp_link_peer_rhash_add(dp, temp_peer); + } + + spin_unlock_bh(&dp->dp_lock); + + return ret; + +err_dp_peer: + spin_unlock_bh(&dp_hw->peer_lock); + +err_peer: + spin_unlock_bh(&dp->dp_lock); + + return ret; +} + +void ath12k_dp_link_peer_unassign(struct ath12k_dp *dp, struct ath12k_dp_hw *dp_hw, + u8 vdev_id, u8 *addr, u32 hw_link_id) +{ + struct ath12k_dp_peer *dp_peer; + struct ath12k_dp_link_peer *peer, *temp_peer; + u16 peerid_index; + + spin_lock_bh(&dp->dp_lock); + + peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, addr); + if (!peer || !peer->dp_peer) { + spin_unlock_bh(&dp->dp_lock); + return; + } + + spin_lock_bh(&dp_hw->peer_lock); + + dp_peer = peer->dp_peer; + dp_peer->hw_links[peer->hw_link_id] = 0; + + peerid_index = ath12k_dp_peer_get_peerid_index(dp, peer->peer_id); + + rcu_assign_pointer(dp_peer->link_peers[peer->link_id], NULL); + + rcu_assign_pointer(dp_hw->dp_peers[peerid_index], NULL); + + spin_unlock_bh(&dp_hw->peer_lock); + + /* To handle roaming and split phy scenario */ + temp_peer = ath12k_dp_link_peer_find_by_addr(dp, addr); + if (temp_peer && temp_peer->hw_link_id == hw_link_id) + ath12k_dp_link_peer_rhash_delete(dp, peer); + + spin_unlock_bh(&dp->dp_lock); + + synchronize_rcu(); +} diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h index b4aa4f09337e0..36cce66203104 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.h +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h @@ -26,6 +26,7 @@ struct ppdu_user_delayba { struct ath12k_dp_link_peer { struct list_head list; struct ieee80211_sta *sta; + struct ath12k_dp_peer *dp_peer; int vdev_id; u8 addr[ETH_ALEN]; int peer_id; @@ -68,6 +69,8 @@ struct ath12k_dp_link_peer { /* peer addr based rhashtable list pointer */ struct rhash_head rhash_addr; + + u8 hw_link_id; }; void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); @@ -81,10 +84,13 @@ struct ath12k_dp_peer { u8 addr[ETH_ALEN]; bool is_mlo; + struct ath12k_dp_link_peer __rcu *link_peers[ATH12K_NUM_MAX_LINKS]; + u16 sec_type; u16 sec_type_grp; bool ucast_ra_only; + u8 hw_links[ATH12K_GROUP_MAX_RADIO]; }; struct ath12k_dp_link_peer * @@ -116,4 +122,5 @@ struct ath12k_dp_peer *ath12k_dp_peer_find_by_addr(struct ath12k_dp_hw *dp_hw, u struct ath12k_dp_peer *ath12k_dp_peer_find_by_addr_and_sta(struct ath12k_dp_hw *dp_hw, u8 *addr, struct ieee80211_sta *sta); +u16 ath12k_dp_peer_get_peerid_index(struct ath12k_dp *dp, u16 peer_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 286d2b7a7730a..f0cca0494d87c 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1205,6 +1205,11 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_link_vif *arvif, *tmp_vif; struct ath12k_dp_hw *dp_hw = &ar->ah->dp_hw; + struct ath12k_dp_peer *dp_peer = NULL; + u16 peerid_index; + struct list_head peers; + + INIT_LIST_HEAD(&peers); lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -1214,12 +1219,26 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) if (peer->sta) ath12k_dp_rx_peer_tid_cleanup(ar, peer); + /* cleanup dp peer */ + spin_lock_bh(&dp_hw->peer_lock); + dp_peer = peer->dp_peer; + peerid_index = ath12k_dp_peer_get_peerid_index(dp, peer->peer_id); + rcu_assign_pointer(dp_peer->link_peers[peer->link_id], NULL); + rcu_assign_pointer(dp_hw->dp_peers[peerid_index], NULL); + spin_unlock_bh(&dp_hw->peer_lock); + ath12k_dp_link_peer_rhash_delete(dp, peer); + list_move(&peer->list, &peers); + } + spin_unlock_bh(&dp->dp_lock); + + synchronize_rcu(); + + list_for_each_entry_safe(peer, tmp, &peers, list) { list_del(&peer->list); kfree(peer); } - spin_unlock_bh(&dp->dp_lock); ar->num_peers = 0; ar->num_stations = 0; diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index 691314efe23f6..8b6fea685a701 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -110,6 +110,10 @@ int ath12k_peer_delete(struct ath12k *ar, u32 vdev_id, u8 *addr) lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); + ath12k_dp_link_peer_unassign(ath12k_ab_to_dp(ar->ab), + &(ath12k_ar_to_ah(ar)->dp_hw), vdev_id, + addr, ar->hw_link_id); + ret = ath12k_peer_delete_send(ar, vdev_id, addr); if (ret) return ret; @@ -243,7 +247,13 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, spin_unlock_bh(&dp->dp_lock); - return 0; + ret = ath12k_dp_link_peer_assign(ath12k_ab_to_dp(ar->ab), + &(ath12k_ar_to_ah(ar)->dp_hw), + arvif->vdev_id, sta, + (u8 *)arg->peer_addr, link_id, + ar->hw_link_id); + + return ret; } u16 ath12k_peer_ml_alloc(struct ath12k_hw *ah) @@ -298,6 +308,11 @@ int ath12k_peer_mlo_link_peers_delete(struct ath12k_vif *ahvif, struct ath12k_st ath12k_dp_peer_cleanup(ar, arvif->vdev_id, arsta->addr); + ath12k_dp_link_peer_unassign(ath12k_ab_to_dp(ar->ab), + &(ath12k_ar_to_ah(ar)->dp_hw), + arvif->vdev_id, arsta->addr, + ar->hw_link_id); + ret = ath12k_peer_delete_send(ar, arvif->vdev_id, arsta->addr); if (ret) { ath12k_warn(ar->ab, From 99fb9306412b2d1a0830e61f4552111868cebc15 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Fri, 24 Oct 2025 23:45:47 +0530 Subject: [PATCH 081/140] wifi: ath12k: Use ath12k_dp_peer in per packet Tx & Rx paths Move link agnostic data path parameters (keys, rx_tid, reorder buffers, MIC context etc) from ath12k_sta and ath12k_dp_link_peer into ath12k_dp_peer. These parameters are shared across MLO links and should be managed at the peer level. Configure them only when the link peer is primary to avoid redundancy and ensure consistent setup. Switch per-packet Tx/Rx paths and monitor paths to look up ath12k_dp_peer and ath12k_dp_link_peer via peer_id. Helper APIs added: - ath12k_dp_peer_find_by_peerid() - ath12k_dp_link_peer_find_by_peerid() Ensure RCU read lock is held when using these helpers APIs. With the above API ath12k_dp_link_peer_find_by_peerid() being used to find ath12k_dp_link_peer, existing API ath12k_dp_link_peer_find_by_id() is required only at the time of unmap event from firmware since it fetches the ath12k_dp_link_peer from linked list. In order to restrict the usage of API ath12k_dp_link_peer_find_by_id(), make it static and also rename it to ath12k_dp_link_peer_search_by_id(). Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251024181548.3255166-9-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 8 --- drivers/net/wireless/ath/ath12k/dp.c | 6 +- drivers/net/wireless/ath/ath12k/dp_htt.c | 22 ++---- drivers/net/wireless/ath/ath12k/dp_mon.c | 13 ++-- drivers/net/wireless/ath/ath12k/dp_peer.c | 45 +++++++++++- drivers/net/wireless/ath/ath12k/dp_peer.h | 45 ++++++------ drivers/net/wireless/ath/ath12k/dp_rx.c | 69 +++++++++---------- drivers/net/wireless/ath/ath12k/dp_rx.h | 9 ++- drivers/net/wireless/ath/ath12k/mac.c | 54 ++++++++------- drivers/net/wireless/ath/ath12k/peer.c | 6 -- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 30 ++++---- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 2 +- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 23 ++----- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 2 + .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 1 + 15 files changed, 174 insertions(+), 161 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 37e3bf0678a2f..bb2d904dae7cd 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -572,12 +572,6 @@ struct ath12k_link_sta { struct rhash_head rhash_addr; }; -struct ath12k_reoq_buf { - void *vaddr; - dma_addr_t paddr_aligned; - u32 size; -}; - struct ath12k_sta { struct ath12k_vif *ahvif; enum hal_pn_type pn_type; @@ -590,8 +584,6 @@ struct ath12k_sta { u8 num_peer; enum ieee80211_sta_state state; - - struct ath12k_reoq_buf reoq_bufs[IEEE80211_NUM_TIDS + 1]; }; #define ATH12K_HALF_20MHZ_BW 10 diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 4387c1b42b88f..8dd39eaddc6c9 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -30,7 +30,7 @@ void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr) spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, addr); - if (!peer) { + if (!peer || !peer->dp_peer) { ath12k_warn(ab, "failed to lookup peer %pM on vdev %d\n", addr, vdev_id); spin_unlock_bh(&dp->dp_lock); @@ -43,8 +43,8 @@ void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr) } ath12k_dp_rx_peer_tid_cleanup(ar, peer); - crypto_free_shash(peer->tfm_mmic); - peer->dp_setup_done = false; + crypto_free_shash(peer->dp_peer->tfm_mmic); + peer->dp_peer->dp_setup_done = false; spin_unlock_bh(&dp->dp_lock); } diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index f3dca108c614e..db5ac36adf3dd 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -272,18 +272,15 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, } rcu_read_lock(); - spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, usr_stats->peer_id); + peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, usr_stats->peer_id); if (!peer || !peer->sta) { - spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); return; } arsta = ath12k_dp_link_peer_to_link_sta(ab, peer); if (!arsta) { - spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); return; } @@ -357,7 +354,6 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags); } - spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); } @@ -507,17 +503,13 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, ppdu_info->delay_ba) { for (i = 0; i < ppdu_info->ppdu_stats.common.num_users; i++) { peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; - spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); - if (!peer) { - spin_unlock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, peer_id); + if (!peer) continue; - } usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; if (usr_stats->delay_ba) ath12k_copy_to_delay_stats(peer, usr_stats); - spin_unlock_bh(&dp->dp_lock); } } @@ -526,17 +518,13 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON))) { for (i = 0; i < ppdu_info->bar_num_users; i++) { peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id; - spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); - if (!peer) { - spin_unlock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, peer_id); + if (!peer) continue; - } usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; if (peer->delayba_flag) ath12k_copy_to_bar(peer, usr_stats); - spin_unlock_bh(&dp->dp_lock); } } diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index d75edfefa3d4d..132a6d121e80d 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2310,6 +2310,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, bool is_mcbc = rxcb->is_mcbc; bool is_eapol_tkip = rxcb->is_eapol; struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; + u8 addr[ETH_ALEN] = {}; status->link_valid = 0; @@ -2322,11 +2323,13 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, ath12k_wifi7_dp_extract_rx_desc_data(ab, &rx_info, rx_desc, rx_desc); + rcu_read_lock(); spin_lock_bh(&dp->dp_lock); rx_info.addr2_present = false; - peer = ath12k_dp_rx_h_find_link_peer(dp, msdu, &rx_info); + peer = ath12k_dp_rx_h_find_link_peer(dp_pdev, msdu, &rx_info); if (peer && peer->sta) { pubsta = peer->sta; + memcpy(addr, peer->addr, ETH_ALEN); if (pubsta->valid_links) { status->link_valid = 1; status->link_id = peer->link_id; @@ -2334,12 +2337,13 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, } spin_unlock_bh(&dp->dp_lock); + rcu_read_unlock(); ath12k_dbg(ab, ATH12K_DBG_DATA, "rx skb %p len %u peer %pM %u %s %s%s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", msdu, msdu->len, - peer ? peer->addr : NULL, + addr, rxcb->tid, (is_mcbc) ? "mcast" : "ucast", (status->encoding == RX_ENC_LEGACY) ? "legacy" : "", @@ -3920,8 +3924,7 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, goto free_skb; rcu_read_lock(); - spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, ppdu_info->peer_id); + peer = ath12k_dp_link_peer_find_by_peerid(pdev_dp, ppdu_info->peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DATA, "failed to find the peer with monitor peer_id %d\n", @@ -3934,7 +3937,6 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, if (!arsta) { ath12k_warn(ab, "link sta not found on peer %pM id %d\n", peer->addr, peer->peer_id); - spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); dev_kfree_skb_any(skb); continue; @@ -3948,7 +3950,6 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, } next_skb: - spin_unlock_bh(&dp->dp_lock); rcu_read_unlock(); free_skb: dev_kfree_skb_any(skb); diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index fe4748648a844..61478e66d9af5 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -72,8 +72,8 @@ ath12k_dp_link_peer_find_by_ml_id(struct ath12k_dp *dp, int ml_peer_id) return NULL; } -struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_id(struct ath12k_dp *dp, int peer_id) +static struct ath12k_dp_link_peer * +ath12k_dp_link_peer_search_by_id(struct ath12k_dp *dp, int peer_id) { struct ath12k_dp_link_peer *peer; @@ -129,7 +129,7 @@ void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); + peer = ath12k_dp_link_peer_search_by_id(dp, peer_id); if (!peer) { ath12k_warn(ab, "peer-unmap-event: unknown peer id %d\n", peer_id); @@ -388,6 +388,44 @@ u16 ath12k_dp_peer_get_peerid_index(struct ath12k_dp *dp, u16 peer_id) ((dp->device_id << ATH12K_DP_PEER_TABLE_DEVICE_ID_SHIFT) | peer_id); } +struct ath12k_dp_peer *ath12k_dp_peer_find_by_peerid(struct ath12k_pdev_dp *dp_pdev, + u16 peer_id) +{ + u16 index; + struct ath12k_dp *dp = dp_pdev->dp; + + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), + "ath12k dp peer find by peerid index called without rcu lock"); + + if (!peer_id || peer_id >= ATH12K_DP_PEER_ID_INVALID) + return NULL; + + index = ath12k_dp_peer_get_peerid_index(dp, peer_id); + + return rcu_dereference(dp_pdev->dp_hw->dp_peers[index]); +} + +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_peerid(struct ath12k_pdev_dp *dp_pdev, u16 peer_id) +{ + struct ath12k_dp_peer *dp_peer = NULL; + u8 link_id; + + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), + "ath12k dp link peer find by peerid index called without rcu lock"); + + if (dp_pdev->hw_link_id >= ATH12K_GROUP_MAX_RADIO) + return NULL; + + dp_peer = ath12k_dp_peer_find_by_peerid(dp_pdev, peer_id); + if (!dp_peer) + return NULL; + + link_id = dp_peer->hw_links[dp_pdev->hw_link_id]; + + return rcu_dereference(dp_peer->link_peers[link_id]); +} + int ath12k_dp_peer_create(struct ath12k_dp_hw *dp_hw, u8 *addr, struct ath12k_dp_peer_create_params *params) { @@ -419,6 +457,7 @@ int ath12k_dp_peer_create(struct ath12k_dp_hw *dp_hw, u8 *addr, dp_peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; dp_peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; + dp_peer->ucast_ra_only = params->ucast_ra_only; spin_lock_bh(&dp_hw->peer_lock); diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h index 36cce66203104..f7c995e8c4e32 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.h +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h @@ -34,24 +34,11 @@ struct ath12k_dp_link_peer { u8 pdev_idx; u16 hw_peer_id; - /* protected by ab->data_lock */ - struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; - struct ath12k_dp_rx_tid rx_tid[IEEE80211_NUM_TIDS + 1]; - - /* Info used in MMIC verification of - * RX fragments - */ - struct crypto_shash *tfm_mmic; - u8 mcast_keyidx; - u8 ucast_keyidx; - u16 sec_type; - u16 sec_type_grp; struct ppdu_user_delayba ppdu_stats_delayba; bool delayba_flag; bool is_authorized; bool mlo; /* protected by ab->data_lock */ - bool dp_setup_done; u16 ml_id; @@ -65,12 +52,12 @@ struct ath12k_dp_link_peer { /* for reference to ath12k_link_sta */ u8 link_id; - bool ucast_ra_only; /* peer addr based rhashtable list pointer */ struct rhash_head rhash_addr; u8 hw_link_id; + u32 rx_tid_active_bitmask; }; void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); @@ -79,18 +66,28 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ struct ath12k_dp_peer { struct list_head list; - struct ieee80211_sta *sta; - int peer_id; - u8 addr[ETH_ALEN]; bool is_mlo; + bool dp_setup_done; - struct ath12k_dp_link_peer __rcu *link_peers[ATH12K_NUM_MAX_LINKS]; - - u16 sec_type; - u16 sec_type_grp; + u8 ucast_keyidx; + u8 addr[ETH_ALEN]; + u8 mcast_keyidx; bool ucast_ra_only; + int peer_id; + struct ieee80211_sta *sta; + u8 hw_links[ATH12K_GROUP_MAX_RADIO]; + + u16 sec_type_grp; + u16 sec_type; + + /* Info used in MMIC verification of * RX fragments */ + struct crypto_shash *tfm_mmic; + struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; + struct ath12k_dp_link_peer __rcu *link_peers[ATH12K_NUM_MAX_LINKS]; + struct ath12k_reoq_buf reoq_bufs[IEEE80211_NUM_TIDS + 1]; + struct ath12k_dp_rx_tid rx_tid[IEEE80211_NUM_TIDS + 1]; }; struct ath12k_dp_link_peer * @@ -98,8 +95,6 @@ ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_dp *dp, int vdev_id, const u8 *addr); struct ath12k_dp_link_peer * ath12k_dp_link_peer_find_by_addr(struct ath12k_dp *dp, const u8 *addr); -struct ath12k_dp_link_peer * -ath12k_dp_link_peer_find_by_id(struct ath12k_dp *dp, int peer_id); bool ath12k_dp_link_peer_exist_by_vdev_id(struct ath12k_dp *dp, int vdev_id); struct ath12k_dp_link_peer * ath12k_dp_link_peer_find_by_ast(struct ath12k_dp *dp, int ast_hash); @@ -123,4 +118,8 @@ struct ath12k_dp_peer *ath12k_dp_peer_find_by_addr_and_sta(struct ath12k_dp_hw * u8 *addr, struct ieee80211_sta *sta); u16 ath12k_dp_peer_get_peerid_index(struct ath12k_dp *dp, u16 peer_id); +struct ath12k_dp_peer *ath12k_dp_peer_find_by_peerid(struct ath12k_pdev_dp *dp_pdev, + u16 peer_id); +struct ath12k_dp_link_peer * +ath12k_dp_link_peer_find_by_peerid(struct ath12k_pdev_dp *dp_pdev, u16 peer_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 1a8aa7d4ed003..aa7e31b7f9507 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -533,8 +533,11 @@ void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer lockdep_assert_held(&dp->dp_lock); + if (!peer->primary_link) + return; + for (i = 0; i <= IEEE80211_NUM_TIDS; i++) { - rx_tid = &peer->rx_tid[i]; + rx_tid = &peer->dp_peer->rx_tid[i]; ath12k_wifi7_dp_rx_peer_tid_delete(ar, peer, i); ath12k_dp_rx_frags_cleanup(rx_tid, true); @@ -665,7 +668,6 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ struct ath12k_base *ab = ar->ab; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_dp_link_peer *peer; - struct ath12k_sta *ahsta; struct ath12k_dp_rx_tid *rx_tid; dma_addr_t paddr_aligned; int ret; @@ -673,7 +675,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, peer_mac); - if (!peer) { + if (!peer || !peer->dp_peer) { spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "failed to find the peer to set up rx tid\n"); return -ENOENT; @@ -699,9 +701,9 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ return -EINVAL; } - rx_tid = &peer->rx_tid[tid]; + rx_tid = &peer->dp_peer->rx_tid[tid]; /* Update the tid queue if it is already setup */ - if (rx_tid->active) { + if (peer->rx_tid_active_bitmask & (1 << tid)) { ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, rx_tid, ba_win_sz, ssn, true); spin_unlock_bh(&dp->dp_lock); @@ -730,26 +732,14 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ rx_tid->ba_win_sz = ba_win_sz; - ahsta = ath12k_sta_to_ahsta(peer->sta); - ret = ath12k_wifi7_dp_rx_assign_reoq(ab, ahsta, rx_tid, ssn, pn_type); + ret = ath12k_wifi7_dp_rx_assign_reoq(ab, peer->dp_peer, rx_tid, ssn, pn_type); if (ret) { spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "failed to assign reoq buf for rx tid %u\n", tid); return ret; } - /* Pre-allocate the update_rxq_list for the corresponding tid - * This will be used during the tid delete. The reason we are not - * allocating during tid delete is that, if any alloc fail in update_rxq_list - * we may not be able to delete the tid vaddr/paddr and may lead to leak - */ - ret = ath12k_dp_prepare_reo_update_elem(dp, peer, rx_tid); - if (ret) { - ath12k_warn(ab, "failed to alloc update_rxq_list for rx tid %u\n", tid); - ath12k_dp_rx_tid_cleanup(ab, &rx_tid->qbuf); - spin_unlock_bh(&ab->base_lock); - return ret; - } + peer->rx_tid_active_bitmask |= (1 << tid); paddr_aligned = rx_tid->qbuf.paddr_aligned; if (ab->hw_params->reoq_lut_support) { @@ -827,20 +817,26 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, arsta->addr); - if (!peer) { + if (!peer || !peer->dp_peer) { spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "failed to find the peer to stop rx aggregation\n"); return -ENOENT; } - active = peer->rx_tid[params->tid].active; + if (ab->hw_params->dp_primary_link_only && + !peer->primary_link) { + spin_unlock_bh(&dp->dp_lock); + return 0; + } + active = peer->rx_tid_active_bitmask & (1 << params->tid); if (!active) { spin_unlock_bh(&dp->dp_lock); return 0; } - ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, peer->rx_tid, 1, 0, false); + ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, peer->dp_peer->rx_tid, + 1, 0, false); spin_unlock_bh(&dp->dp_lock); if (ret) { ath12k_warn(ab, "failed to update reo for rx tid %d: %d\n", @@ -877,7 +873,7 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, peer_addr); - if (!peer) { + if (!peer || !peer->dp_peer) { spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "failed to find the peer %pM to configure pn replay detection\n", peer_addr); @@ -885,10 +881,11 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, } for (tid = 0; tid <= IEEE80211_NUM_TIDS; tid++) { - rx_tid = &peer->rx_tid[tid]; - if (!rx_tid->active) + if (!(peer->rx_tid_active_bitmask & (1 << tid))) continue; + rx_tid = &peer->dp_peer->rx_tid[tid]; + ath12k_wifi7_dp_setup_pn_check_reo_cmd(&cmd, rx_tid, key->cipher, key_cmd); ret = ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid, @@ -1222,16 +1219,17 @@ void ath12k_dp_rx_h_undecap(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu } struct ath12k_dp_link_peer * -ath12k_dp_rx_h_find_link_peer(struct ath12k_dp *dp, struct sk_buff *msdu, +ath12k_dp_rx_h_find_link_peer(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) { struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); struct ath12k_dp_link_peer *peer = NULL; + struct ath12k_dp *dp = dp_pdev->dp; lockdep_assert_held(&dp->dp_lock); if (rxcb->peer_id) - peer = ath12k_dp_link_peer_find_by_id(dp, rxcb->peer_id); + peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, rxcb->peer_id); if (peer) return peer; @@ -1387,25 +1385,22 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc struct ath12k_base *ab = dp->ab; struct ieee80211_rx_status *rx_status; struct ieee80211_sta *pubsta; - struct ath12k_dp_link_peer *peer; + struct ath12k_dp_peer *peer; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); struct ieee80211_rx_status *status = rx_info->rx_status; u8 decap = rx_info->decap_type; bool is_mcbc = rxcb->is_mcbc; bool is_eapol = rxcb->is_eapol; - spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_rx_h_find_link_peer(dp, msdu, rx_info); + peer = ath12k_dp_peer_find_by_peerid(dp_pdev, rx_info->peer_id); pubsta = peer ? peer->sta : NULL; if (pubsta && pubsta->valid_links) { status->link_valid = 1; - status->link_id = peer->link_id; + status->link_id = peer->hw_links[rxcb->hw_link_id]; } - spin_unlock_bh(&dp->dp_lock); - ath12k_dbg(ab, ATH12K_DBG_DATA, "rx skb %p len %u peer %pM %d %s sn %u %s%s%s%s%s%s%s%s%s%s rate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", msdu, @@ -1528,7 +1523,7 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, peer_mac); - if (!peer) { + if (!peer || !peer->dp_peer) { spin_unlock_bh(&dp->dp_lock); crypto_free_shash(tfm); ath12k_warn(ab, "failed to find the peer to set up fragment info\n"); @@ -1542,14 +1537,14 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev } for (i = 0; i <= IEEE80211_NUM_TIDS; i++) { - rx_tid = &peer->rx_tid[i]; + rx_tid = &peer->dp_peer->rx_tid[i]; rx_tid->dp = dp; timer_setup(&rx_tid->frag_timer, ath12k_dp_rx_frag_timer, 0); skb_queue_head_init(&rx_tid->rx_frags); } - peer->tfm_mmic = tfm; - peer->dp_setup_done = true; + peer->dp_peer->tfm_mmic = tfm; + peer->dp_peer->dp_setup_done = true; spin_unlock_bh(&dp->dp_lock); return 0; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 365f2c6449e42..51bc443f4c7ca 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -12,10 +12,15 @@ #define DP_MAX_NWIFI_HDR_LEN 30 +struct ath12k_reoq_buf { + void *vaddr; + dma_addr_t paddr_aligned; + u32 size; +}; + struct ath12k_dp_rx_tid { u8 tid; u32 ba_win_sz; - bool active; struct ath12k_reoq_buf qbuf; /* Info related to rx fragments */ @@ -244,7 +249,7 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, struct hal_rx_desc *desc); struct ath12k_dp_link_peer * -ath12k_dp_rx_h_find_link_peer(struct ath12k_dp *dp, struct sk_buff *msdu, +ath12k_dp_rx_h_find_link_peer(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info); u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab, struct hal_rx_desc *desc); diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index f0cca0494d87c..5fa8aaea9e321 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1216,7 +1216,7 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) spin_lock_bh(&dp->dp_lock); list_for_each_entry_safe(peer, tmp, &dp->peers, list) { /* Skip Rx TID cleanup for self peer */ - if (peer->sta) + if (peer->sta && peer->dp_peer) ath12k_dp_rx_peer_tid_cleanup(ar, peer); /* cleanup dp peer */ @@ -5763,27 +5763,37 @@ static int ath12k_clear_peer_keys(struct ath12k_link_vif *arvif, struct ath12k_dp_link_peer *peer; int first_errno = 0; int ret; - int i; + int i, len; u32 flags = 0; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1] = {}; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, addr); - if (!peer) { + if (!peer || !peer->dp_peer) { spin_unlock_bh(&dp->dp_lock); return -ENOENT; } + len = ARRAY_SIZE(peer->dp_peer->keys); + for (i = 0; i < len; i++) { + if (!peer->dp_peer->keys[i]) + continue; + + keys[i] = peer->dp_peer->keys[i]; + peer->dp_peer->keys[i] = NULL; + } + spin_unlock_bh(&dp->dp_lock); - for (i = 0; i < ARRAY_SIZE(peer->keys); i++) { - if (!peer->keys[i]) + for (i = 0; i < len; i++) { + if (!keys[i]) continue; /* key flags are not required to delete the key */ - ret = ath12k_install_key(arvif, peer->keys[i], + ret = ath12k_install_key(arvif, keys[i], DISABLE_KEY, addr, flags); if (ret < 0 && first_errno == 0) first_errno = ret; @@ -5791,10 +5801,6 @@ static int ath12k_clear_peer_keys(struct ath12k_link_vif *arvif, if (ret < 0) ath12k_warn(ab, "failed to remove peer key %d: %d\n", i, ret); - - spin_lock_bh(&dp->dp_lock); - peer->keys[i] = NULL; - spin_unlock_bh(&dp->dp_lock); } return first_errno; @@ -5835,7 +5841,7 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, peer_addr); - if (!peer) { + if (!peer || !peer->dp_peer) { spin_unlock_bh(&dp->dp_lock); if (cmd == SET_KEY) { @@ -5872,21 +5878,23 @@ static int ath12k_mac_set_key(struct ath12k *ar, enum set_key_cmd cmd, spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, arvif->vdev_id, peer_addr); - if (peer && cmd == SET_KEY) { - peer->keys[key->keyidx] = key; + if (peer && peer->dp_peer && cmd == SET_KEY) { + peer->dp_peer->keys[key->keyidx] = key; if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { - peer->ucast_keyidx = key->keyidx; - peer->sec_type = ath12k_dp_tx_get_encrypt_type(key->cipher); + peer->dp_peer->ucast_keyidx = key->keyidx; + peer->dp_peer->sec_type = + ath12k_dp_tx_get_encrypt_type(key->cipher); } else { - peer->mcast_keyidx = key->keyidx; - peer->sec_type_grp = ath12k_dp_tx_get_encrypt_type(key->cipher); + peer->dp_peer->mcast_keyidx = key->keyidx; + peer->dp_peer->sec_type_grp = + ath12k_dp_tx_get_encrypt_type(key->cipher); } - } else if (peer && cmd == DISABLE_KEY) { - peer->keys[key->keyidx] = NULL; + } else if (peer && peer->dp_peer && cmd == DISABLE_KEY) { + peer->dp_peer->keys[key->keyidx] = NULL; if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) - peer->ucast_keyidx = 0; + peer->dp_peer->ucast_keyidx = 0; else - peer->mcast_keyidx = 0; + peer->dp_peer->mcast_keyidx = 0; } else if (!peer) /* impossible unless FW goes crazy */ ath12k_warn(ab, "peer %pM disappeared!\n", peer_addr); @@ -9485,7 +9493,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, spin_lock_bh(&tmp_dp->dp_lock); peer = ath12k_dp_link_peer_find_by_addr(tmp_dp, tmp_arvif->bssid); - if (!peer) { + if (!peer || !peer->dp_peer) { spin_unlock_bh(&tmp_dp->dp_lock); ath12k_warn(tmp_ar->ab, "failed to find peer for vdev_id 0x%X addr %pM link_map 0x%X\n", @@ -9495,7 +9503,7 @@ void ath12k_mac_op_tx(struct ieee80211_hw *hw, continue; } - key = peer->keys[peer->mcast_keyidx]; + key = peer->dp_peer->keys[peer->dp_peer->mcast_keyidx]; if (key) { skb_cb->cipher = key->cipher; skb_cb->flags |= ATH12K_SKB_CIPHER_SET; diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index 8b6fea685a701..812247decab43 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -214,9 +214,6 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, dp_link_vif->ast_idx = peer->hw_peer_id; } - if (vif->type == NL80211_IFTYPE_AP) - peer->ucast_ra_only = true; - if (sta) { ahsta = ath12k_sta_to_ahsta(sta); arsta = wiphy_dereference(ath12k_ar_to_hw(ar)->wiphy, @@ -240,9 +237,6 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, } } - peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; - peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; - ar->num_peers++; spin_unlock_bh(&dp->dp_lock); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index da745566aca37..87875486fb4a1 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -72,10 +72,10 @@ void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k *ar, struct ath12k_dp_link_peer *peer, u8 tid) { struct ath12k_hal_reo_cmd cmd = {}; - struct ath12k_dp_rx_tid *rx_tid = &peer->rx_tid[tid]; + struct ath12k_dp_rx_tid *rx_tid = &peer->dp_peer->rx_tid[tid]; int ret; - if (!rx_tid->active) + if (!(peer->rx_tid_active_bitmask & (1 << tid))) return; cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS; @@ -99,7 +99,7 @@ void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k *ar, else ath12k_wifi7_peer_rx_tid_qref_reset(ar->ab, peer->peer_id, tid); - rx_tid->active = false; + peer->rx_tid_active_bitmask &= ~(1 << tid); } int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, @@ -253,7 +253,7 @@ void ath12k_wifi7_dp_reo_cache_flush(struct ath12k_base *ab, } } -int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, +int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_dp_peer *dp_peer, struct ath12k_dp_rx_tid *rx_tid, u16 ssn, enum hal_pn_type pn_type) { @@ -265,7 +265,7 @@ int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ah u32 hw_desc_sz; int ret; - buf = &ahsta->reoq_bufs[tid]; + buf = &dp_peer->reoq_bufs[tid]; if (!buf->vaddr) { /* TODO: Optimize the memory allocation for qos tid based on * the actual BA window size in REO tid update path. @@ -299,7 +299,6 @@ int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ah } rx_tid->qbuf = *buf; - rx_tid->active = true; return 0; } @@ -316,12 +315,11 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_desc *rx_desc, struct hal_rx_desc_data *rx_info) { - struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_skb_rxcb *rxcb; enum hal_encrypt_type enctype; bool is_decrypted = false; struct ieee80211_hdr *hdr; - struct ath12k_dp_link_peer *peer; + struct ath12k_dp_peer *peer; struct ieee80211_rx_status *rx_status = rx_info->rx_status; u32 err_bitmap = rx_info->err_bitmap; @@ -332,8 +330,7 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, if (rxcb->is_mcbc) rxcb->peer_id = rx_info->peer_id; - spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_rx_h_find_link_peer(dp, msdu, rx_info); + peer = ath12k_dp_peer_find_by_peerid(dp_pdev, rxcb->peer_id); if (peer) { /* resetting mcbc bit because mcbc packets are unicast * packets only for AP as STA sends unicast packets. @@ -347,7 +344,6 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, } else { enctype = HAL_ENCRYPT_TYPE_OPEN; } - spin_unlock_bh(&dp->dp_lock); if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap) is_decrypted = rx_info->is_decrypted; @@ -964,7 +960,7 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k_dp *dp, } static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_dp_link_peer *peer, + struct ath12k_dp_peer *peer, enum hal_encrypt_type enctype, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) @@ -1033,7 +1029,7 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, } static int ath12k_wifi7_dp_rx_h_defrag(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_dp_link_peer *peer, + struct ath12k_dp_peer *peer, struct ath12k_dp_rx_tid *rx_tid, struct sk_buff **defrag_skb, enum hal_encrypt_type enctype, @@ -1107,7 +1103,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, { struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_base *ab = dp->ab; - struct ath12k_dp_link_peer *peer; + struct ath12k_dp_peer *peer; struct ath12k_dp_rx_tid *rx_tid; struct sk_buff *defrag_skb = NULL; u32 peer_id = rx_info->peer_id; @@ -1134,7 +1130,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, return -EINVAL; spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); + peer = ath12k_dp_peer_find_by_peerid(dp_pdev, peer_id); if (!peer) { ath12k_warn(ab, "failed to find the peer to de-fragment received fragment peer_id %d\n", peer_id); @@ -1197,7 +1193,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, timer_delete_sync(&rx_tid->frag_timer); spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); + peer = ath12k_dp_peer_find_by_peerid(dp_pdev, peer_id); if (!peer) goto err_frags_cleanup; @@ -1831,6 +1827,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, rxcb->is_last_msdu = err_info.last_msdu; rxcb->is_continuation = err_info.continuation; rxcb->rx_desc = msdu_data; + rxcb->peer_id = ath12k_dp_rx_get_peer_id(ab, dp->peer_metadata_ver, + err_info.peer_metadata); if (err_info.continuation) { __skb_queue_tail(&scatter_msdu_list, msdu); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index f75588519cfff..ba319ff506f28 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -25,7 +25,7 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); void ath12k_wifi7_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, struct ath12k_dp_rx_tid *rx_tid, u32 cipher, enum set_key_cmd key_cmd); -int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta, +int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_dp_peer *dp_peer, struct ath12k_dp_rx_tid *rx_tid, u16 ssn, enum hal_pn_type pn_type); int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 77de02858677a..950614a217a05 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -396,12 +396,13 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, s32 noise_floor; struct ieee80211_tx_status status = {}; struct ath12k_dp_link_peer *peer; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_pdev_dp *dp_pdev; skb_cb = ATH12K_SKB_CB(msdu); info = IEEE80211_SKB_CB(msdu); ar = skb_cb->ar; + dp_pdev = &ar->dp; ab->device_stats.tx_completed[tx_ring->tcl_data_ring_id]++; if (atomic_dec_and_test(&ar->dp.num_tx_pending)) @@ -449,18 +450,15 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, } } rcu_read_lock(); - spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, peer_id); + peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DATA, "dp_tx: failed to find the peer with peer_id %d\n", peer_id); - spin_unlock_bh(&dp->dp_lock); ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu); goto exit; } else { status.sta = peer->sta; } - spin_unlock_bh(&dp->dp_lock); status.info = info; status.skb = msdu; @@ -519,7 +517,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, { struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_base *ab = dp->ab; - struct ath12k_dp_link_peer *peer; + struct ath12k_dp_peer *peer; struct ieee80211_sta *sta; struct ath12k_sta *ahsta; struct ath12k_link_sta *arsta; @@ -528,12 +526,10 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, u8 rate_idx = 0; int ret; - spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, ts->peer_id); + peer = ath12k_dp_peer_find_by_peerid(dp_pdev, ts->peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DP_TX, "failed to find the peer by id %u\n", ts->peer_id); - spin_unlock_bh(&dp->dp_lock); return; } sta = peer->sta; @@ -547,7 +543,6 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, txrate.nss = arsta->last_txrate.nss; else txrate.nss = arsta->peer_nss; - spin_unlock_bh(&dp->dp_lock); switch (ts->pkt_type) { case HAL_TX_RATE_STATS_PKT_TYPE_11A: @@ -650,7 +645,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, s32 noise_floor; struct ieee80211_tx_status status = {}; struct ieee80211_rate_status status_rate = {}; - struct ath12k_dp_link_peer *peer; + struct ath12k_dp_peer *peer; struct ath12k_link_sta *arsta; struct ath12k_sta *ahsta; struct rate_info rate; @@ -747,21 +742,17 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, ath12k_wifi7_dp_tx_update_txcompl(dp_pdev, ts); - spin_lock_bh(&dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_id(dp, ts->peer_id); + peer = ath12k_dp_peer_find_by_peerid(dp_pdev, ts->peer_id); if (!peer || !peer->sta) { ath12k_err(ab, "dp_tx: failed to find the peer with peer_id %d\n", ts->peer_id); - spin_unlock_bh(&dp->dp_lock); ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); goto exit; } ahsta = ath12k_sta_to_ahsta(peer->sta); arsta = &ahsta->deflink; - spin_unlock_bh(&dp->dp_lock); - status.sta = peer->sta; status.info = info; status.skb = msdu; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index 783d3091a7ac3..2eb3789962f37 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -435,6 +435,8 @@ int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, HAL_WBM_RELEASE_INFO0_RXDMA_ERROR_CODE); } + rel_info->peer_metadata = wbm_desc->info2; + return 0; } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index d6f33fcd2e961..5536f5bf2a2bf 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -21,6 +21,7 @@ struct hal_rx_wbm_rel_info { bool continuation; void *rx_desc; bool hw_cc_done; + __le32 peer_metadata; }; #define HAL_RX_MPDU_INFO_PN_GET_BYTE1(__val) \ From afc51ba22bb585ead91851c08adc8ec9d3a416b5 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Fri, 24 Oct 2025 23:45:48 +0530 Subject: [PATCH 082/140] wifi: ath12k: Add lockdep warn for RCU Add RCU_LOCKDEP_WARN() in following functions: - ath12k_dp_link_peer_to_link_sta() - ath12k_wifi7_dp_rx_h_mpdu() Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251024181548.3255166-10-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_peer.c | 3 +++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index 61478e66d9af5..a06113bedf0d7 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -182,6 +182,9 @@ struct ath12k_link_sta *ath12k_dp_link_peer_to_link_sta(struct ath12k_base *ab, struct ath12k_sta *ahsta; struct ath12k_link_sta *arsta; + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), + "ath12k_dp_link_peer to ath12k_link_sta called without rcu lock"); + if (!peer->sta) return NULL; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 87875486fb4a1..d24d0f12742eb 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -323,6 +323,9 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, struct ieee80211_rx_status *rx_status = rx_info->rx_status; u32 err_bitmap = rx_info->err_bitmap; + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), + "dp_rx_h_mpdu called without rcu lock"); + /* PN for multicast packets will be checked in mac80211 */ rxcb = ATH12K_SKB_RXCB(msdu); rxcb->is_mcbc = rx_info->is_mcbc; From 02554223aafecb811fcf24870085ab270e322f5d Mon Sep 17 00:00:00 2001 From: Muna Sinada Date: Thu, 23 Oct 2025 17:19:23 -0700 Subject: [PATCH 083/140] wifi: ath12k: generalize GI and LTF fixed rate functions Currently, functions in mac.c for setting GI and LTF rates are specifically for HE rates. Remove any mention of "HE" in such functions in order to allow for other modes to utilize the functions. The intention is to prepare for the addition of EHT GI and LTF fixed rate settings. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Signed-off-by: Muna Sinada Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251024001928.257356-2-muna.sinada@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/mac.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 5fa8aaea9e321..5ce2a9a8ab3a6 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -12651,11 +12651,10 @@ ath12k_mac_get_single_legacy_rate(struct ath12k *ar, } static int -ath12k_mac_set_fixed_rate_gi_ltf(struct ath12k_link_vif *arvif, u8 gi, u8 ltf, - u32 param) +ath12k_mac_set_fixed_rate_gi_ltf(struct ath12k_link_vif *arvif, u8 gi, u8 ltf) { struct ath12k *ar = arvif->ar; - int ret; + int param, ret; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -12670,16 +12669,11 @@ ath12k_mac_set_fixed_rate_gi_ltf(struct ath12k_link_vif *arvif, u8 gi, u8 ltf, gi, ret); return ret; } + /* start from 1 */ + if (ltf != 0xFF) + ltf += 1; - if (param == WMI_VDEV_PARAM_HE_LTF) { - /* HE values start from 1 */ - if (ltf != 0xFF) - ltf += 1; - } else { - /* EHT values start from 5 */ - if (ltf != 0xFF) - ltf += 4; - } + param = WMI_VDEV_PARAM_HE_LTF; ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param, ltf); @@ -12767,7 +12761,7 @@ static int ath12k_mac_set_rate_params(struct ath12k_link_vif *arvif, { struct ieee80211_bss_conf *link_conf; struct ath12k *ar = arvif->ar; - bool he_support, eht_support, gi_ltf_set = false; + bool he_support, gi_ltf_set = false; u32 vdev_param; u32 param_value; int ret; From 085ded82f4845f93b862cd006b6def967122b875 Mon Sep 17 00:00:00 2001 From: Muna Sinada Date: Thu, 23 Oct 2025 17:19:24 -0700 Subject: [PATCH 084/140] wifi: ath12k: add EHT rate handling to existing set rate functions Add EHT rate handling to the existing rate functions that validate, prepare and set rates. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Co-developed-by: Aloka Dixit Signed-off-by: Aloka Dixit Signed-off-by: Muna Sinada Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251024001928.257356-3-muna.sinada@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/mac.c | 41 ++++----------------------- 1 file changed, 6 insertions(+), 35 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 5ce2a9a8ab3a6..0930505890127 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -547,18 +547,6 @@ ath12k_mac_max_eht_nss(const u16 eht_mcs_mask[NL80211_EHT_NSS_MAX]) return 1; } -static u32 -ath12k_mac_max_eht_mcs_nss(const u8 *eht_mcs, int eht_mcs_set_size) -{ - int i; - u8 nss = 0; - - for (i = 0; i < eht_mcs_set_size; i++) - nss = max(nss, u8_get_bits(eht_mcs[i], IEEE80211_EHT_MCS_NSS_RX)); - - return nss; -} - static u8 ath12k_parse_mpdudensity(u8 mpdudensity) { /* From IEEE Std 802.11-2020 defined values for "Minimum MPDU Start Spacing": @@ -3320,7 +3308,6 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar, { struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta); struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif); - const struct ieee80211_eht_mcs_nss_supp *own_eht_mcs_nss_supp; const struct ieee80211_eht_mcs_nss_supp_20mhz_only *bw_20; const struct ieee80211_sta_eht_cap *eht_cap, *own_eht_cap; const struct ieee80211_sband_iftype_data *iftd; @@ -3329,12 +3316,9 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar, struct ieee80211_link_sta *link_sta; struct ieee80211_bss_conf *link_conf; struct cfg80211_chan_def def; - bool user_rate_valid = true; enum nl80211_band band; - int eht_nss, nss_idx; u32 *rx_mcs, *tx_mcs; u16 *eht_mcs_mask; - u8 max_nss = 0; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -3362,16 +3346,6 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar, band = def.chan->band; eht_mcs_mask = arvif->bitrate_mask.control[band].eht_mcs; - iftd = ieee80211_get_sband_iftype_data(&ar->mac.sbands[band], vif->type); - if (!iftd) { - ath12k_warn(ar->ab, - "unable to access iftype_data in struct ieee80211_supported_band\n"); - return; - } - - own_eht_cap = &iftd->eht_cap; - own_eht_mcs_nss_supp = &own_eht_cap->eht_mcs_nss_supp; - arg->eht_flag = true; if ((eht_cap->eht_cap_elem.phy_cap_info[5] & @@ -12756,12 +12730,11 @@ static u32 ath12k_mac_nlgi_to_wmigi(enum nl80211_txrate_gi gi) static int ath12k_mac_set_rate_params(struct ath12k_link_vif *arvif, u32 rate, u8 nss, u8 sgi, u8 ldpc, u8 he_gi, u8 he_ltf, bool he_fixed_rate, - u8 eht_gi, u8 eht_ltf, bool eht_fixed_rate) { struct ieee80211_bss_conf *link_conf; struct ath12k *ar = arvif->ar; - bool he_support, gi_ltf_set = false; + bool he_support, eht_support, gi_ltf_set = false; u32 vdev_param; u32 param_value; int ret; @@ -12783,9 +12756,8 @@ static int ath12k_mac_set_rate_params(struct ath12k_link_vif *arvif, "he_gi 0x%02x he_ltf 0x%02x he_fixed_rate %d\n", he_gi, he_ltf, he_fixed_rate); - ath12k_dbg(ar->ab, ATH12K_DBG_MAC, - "eht_gi 0x%02x eht_ltf 0x%02x eht_fixed_rate %d\n", - eht_gi, eht_ltf, eht_fixed_rate); + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "eht_fixed_rate %d\n", + eht_fixed_rate); if (!he_support && !eht_support) { vdev_param = WMI_VDEV_PARAM_FIXED_RATE; @@ -12997,8 +12969,8 @@ ath12k_mac_validate_fixed_rate_settings(struct ath12k *ar, enum nl80211_band ban bool eht_fixed_rate = false, he_fixed_rate = false, vht_fixed_rate = false; const u16 *vht_mcs_mask, *he_mcs_mask, *eht_mcs_mask; struct ieee80211_link_sta *link_sta; - struct ath12k_dp_link_peer *peer, *tmp; - u8 vht_nss, he_nss; + struct ath12k_peer *peer, *tmp; + u8 vht_nss, he_nss, eht_nss; int ret = true; struct ath12k_base *ab = ar->ab; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); @@ -13225,8 +13197,7 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, } ret = ath12k_mac_set_rate_params(arvif, rate, nss, sgi, ldpc, he_gi, - he_ltf, he_fixed_rate, eht_gi, eht_ltf, - eht_fixed_rate); + he_ltf, he_fixed_rate, eht_fixed_rate); if (ret) { ath12k_warn(ar->ab, "failed to set rate params on vdev %i: %d\n", arvif->vdev_id, ret); From 3b661184168bfb1e8e8848f15c96dc97e118b8df Mon Sep 17 00:00:00 2001 From: Muna Sinada Date: Thu, 23 Oct 2025 17:19:25 -0700 Subject: [PATCH 085/140] wifi: ath12k: Add EHT MCS/NSS rates to Peer Assoc Add EHT MCS/NSS rate functionality to peer association. As part of ath12k_peer_assoc_h_eht() add the calculation of EHT MCS/NSS using intersection of link_sta and phy capability. ath12k_mac_max_eht_mcs_nss() function is utilized when comparing the max NSS of link STA and phy capability since in split phy case, phy supports max NSS of 2 for 5G band. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Co-developed-by: Vishal Kumar Signed-off-by: Vishal Kumar Co-developed-by: Aloka Dixit Signed-off-by: Aloka Dixit Signed-off-by: Muna Sinada Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251024001928.257356-4-muna.sinada@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/mac.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 0930505890127..a5a67fc3d8b30 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -547,6 +547,18 @@ ath12k_mac_max_eht_nss(const u16 eht_mcs_mask[NL80211_EHT_NSS_MAX]) return 1; } +static u32 +ath12k_mac_max_eht_mcs_nss(const u8 *eht_mcs, int eht_mcs_set_size) +{ + int i; + u8 nss = 0; + + for (i = 0; i < eht_mcs_set_size; i++) + nss = max(nss, u8_get_bits(eht_mcs[i], IEEE80211_EHT_MCS_NSS_RX)); + + return nss; +} + static u8 ath12k_parse_mpdudensity(u8 mpdudensity) { /* From IEEE Std 802.11-2020 defined values for "Minimum MPDU Start Spacing": @@ -3308,6 +3320,7 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar, { struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta); struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif); + const struct ieee80211_eht_mcs_nss_supp *own_eht_mcs_nss_supp; const struct ieee80211_eht_mcs_nss_supp_20mhz_only *bw_20; const struct ieee80211_sta_eht_cap *eht_cap, *own_eht_cap; const struct ieee80211_sband_iftype_data *iftd; @@ -3316,9 +3329,12 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar, struct ieee80211_link_sta *link_sta; struct ieee80211_bss_conf *link_conf; struct cfg80211_chan_def def; + bool user_rate_valid = true; enum nl80211_band band; + int eht_nss, nss_idx; u32 *rx_mcs, *tx_mcs; u16 *eht_mcs_mask; + u8 max_nss = 0; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -3346,6 +3362,16 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar, band = def.chan->band; eht_mcs_mask = arvif->bitrate_mask.control[band].eht_mcs; + iftd = ieee80211_get_sband_iftype_data(&ar->mac.sbands[band], vif->type); + if (!iftd) { + ath12k_warn(ar->ab, + "unable to access iftype_data in struct ieee80211_supported_band\n"); + return; + } + + own_eht_cap = &iftd->eht_cap; + own_eht_mcs_nss_supp = &own_eht_cap->eht_mcs_nss_supp; + arg->eht_flag = true; if ((eht_cap->eht_cap_elem.phy_cap_info[5] & From 3b2803f50c4539890e16edd672dc4a85c91f7f45 Mon Sep 17 00:00:00 2001 From: Muna Sinada Date: Thu, 23 Oct 2025 17:19:26 -0700 Subject: [PATCH 086/140] wifi: ath12k: Add EHT fixed GI/LTF Add EHT functionality to set fixed GI/LTF parameters. Add new wmi vdev parameter id for EHT LTF Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Signed-off-by: Muna Sinada Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251024001928.257356-5-muna.sinada@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/mac.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index a5a67fc3d8b30..86cfb156a2b2c 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -12651,10 +12651,11 @@ ath12k_mac_get_single_legacy_rate(struct ath12k *ar, } static int -ath12k_mac_set_fixed_rate_gi_ltf(struct ath12k_link_vif *arvif, u8 gi, u8 ltf) +ath12k_mac_set_fixed_rate_gi_ltf(struct ath12k_link_vif *arvif, u8 gi, u8 ltf, + u32 param) { struct ath12k *ar = arvif->ar; - int param, ret; + int ret; lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); @@ -12669,11 +12670,16 @@ ath12k_mac_set_fixed_rate_gi_ltf(struct ath12k_link_vif *arvif, u8 gi, u8 ltf) gi, ret); return ret; } - /* start from 1 */ - if (ltf != 0xFF) - ltf += 1; - param = WMI_VDEV_PARAM_HE_LTF; + if (param == WMI_VDEV_PARAM_HE_LTF) { + /* HE values start from 1 */ + if (ltf != 0xFF) + ltf += 1; + } else { + /* EHT values start from 5 */ + if (ltf != 0xFF) + ltf += 4; + } ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param, ltf); @@ -12756,6 +12762,7 @@ static u32 ath12k_mac_nlgi_to_wmigi(enum nl80211_txrate_gi gi) static int ath12k_mac_set_rate_params(struct ath12k_link_vif *arvif, u32 rate, u8 nss, u8 sgi, u8 ldpc, u8 he_gi, u8 he_ltf, bool he_fixed_rate, + u8 eht_gi, u8 eht_ltf, bool eht_fixed_rate) { struct ieee80211_bss_conf *link_conf; @@ -12782,8 +12789,9 @@ static int ath12k_mac_set_rate_params(struct ath12k_link_vif *arvif, "he_gi 0x%02x he_ltf 0x%02x he_fixed_rate %d\n", he_gi, he_ltf, he_fixed_rate); - ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "eht_fixed_rate %d\n", - eht_fixed_rate); + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, + "eht_gi 0x%02x eht_ltf 0x%02x eht_fixed_rate %d\n", + eht_gi, eht_ltf, eht_fixed_rate); if (!he_support && !eht_support) { vdev_param = WMI_VDEV_PARAM_FIXED_RATE; @@ -13223,7 +13231,8 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, } ret = ath12k_mac_set_rate_params(arvif, rate, nss, sgi, ldpc, he_gi, - he_ltf, he_fixed_rate, eht_fixed_rate); + he_ltf, he_fixed_rate, eht_gi, eht_ltf, + eht_fixed_rate); if (ret) { ath12k_warn(ar->ab, "failed to set rate params on vdev %i: %d\n", arvif->vdev_id, ret); From d05a0bd493f1ffa4e17e3ec1ed810e98ef944a3a Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Mon, 3 Nov 2025 16:51:00 +0530 Subject: [PATCH 087/140] wifi: ath12k: Add callbacks in arch_ops for rx APIs Facilitate modular and architecture-agnostic access to Wi-Fi 7 Rx functionality by introducing wrapper APIs in common module for existing RX callbacks already defined in arch_ops. Also remove redundant ar usage in these APIs and registered callbacks definitions, and change the callback names of few of the APIs to remove the redundant usage of "dp". Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-2-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 5 +- drivers/net/wireless/ath/ath12k/dp.h | 102 +++++++++++++++++- drivers/net/wireless/ath/ath12k/dp_rx.c | 38 ++++--- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 10 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 19 ++-- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 4 +- 6 files changed, 141 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 8dd39eaddc6c9..c7f7c04877c4b 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -10,7 +10,6 @@ #include "hif.h" #include "hal.h" #include "debug.h" -#include "wifi7/dp_rx.h" #include "peer.h" #include "dp_mon.h" #include "dp_cmn.h" @@ -99,7 +98,7 @@ int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr) } for (tid--; tid >= 0; tid--) - ath12k_wifi7_dp_rx_peer_tid_delete(ar, peer, tid); + ath12k_dp_arch_rx_peer_tid_delete(dp, peer, tid); spin_unlock_bh(&dp->dp_lock); @@ -345,7 +344,7 @@ static int ath12k_dp_tx_get_bank_profile(struct ath12k_base *ab, bool configure_register = false; /* convert vdev params into hal_tx_bank_config */ - bank_config = dp->ops->dp_tx_get_vdev_bank_config(ab, arvif); + bank_config = ath12k_dp_arch_tx_get_vdev_bank_config(dp, arvif); spin_lock_bh(&dp->tx_bank_lock); /* TODO: implement using idr kernel framework*/ diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index b4ded1e4581b0..9c926bcbd4359 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -21,6 +21,7 @@ struct ath12k_vif; struct ath12k_link_vif; struct hal_tcl_status_ring; struct ath12k_ext_irq_grp; +struct ath12k_dp_rx_tid; #define DP_MON_PURGE_TIMEOUT_MS 100 #define DP_MON_SERVICE_BUDGET 128 @@ -389,8 +390,34 @@ struct ath12k_dp_arch_ops { int (*service_srng)(struct ath12k_dp *dp, struct ath12k_ext_irq_grp *irq_grp, int budget); - u32 (*dp_tx_get_vdev_bank_config)(struct ath12k_base *ab, - struct ath12k_link_vif *arvif); + u32 (*tx_get_vdev_bank_config)(struct ath12k_base *ab, + struct ath12k_link_vif *arvif); + int (*reo_cmd_send)(struct ath12k_base *ab, + struct ath12k_dp_rx_tid *rx_tid, + enum hal_reo_cmd_type type, + struct ath12k_hal_reo_cmd *cmd, + void (*cb)(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status)); + void (*setup_pn_check_reo_cmd)(struct ath12k_hal_reo_cmd *cmd, + struct ath12k_dp_rx_tid *rx_tid, + u32 cipher, enum set_key_cmd key_cmd); + void (*rx_peer_tid_delete)(struct ath12k_base *ab, + struct ath12k_dp_link_peer *peer, u8 tid); + void (*reo_cache_flush)(struct ath12k_base *ab, + struct ath12k_dp_rx_tid *rx_tid); + int (*rx_link_desc_return)(struct ath12k_base *ab, + struct ath12k_buffer_addr *buf_addr_info, + enum hal_wbm_rel_bm_act action); + int (*peer_rx_tid_reo_update)(struct ath12k_dp *dp, + struct ath12k_dp_link_peer *peer, + struct ath12k_dp_rx_tid *rx_tid, + u32 ba_win_sz, u16 ssn, + bool update_ssn); + int (*rx_assign_reoq)(struct ath12k_base *ab, struct ath12k_dp_peer *dp_peer, + struct ath12k_dp_rx_tid *rx_tid, + u16 ssn, enum hal_pn_type pn_type); + void (*peer_rx_tid_qref_setup)(struct ath12k_base *ab, u16 peer_id, u16 tid, + dma_addr_t paddr); }; struct ath12k_dp { @@ -493,6 +520,77 @@ struct ath12k_dp { struct rhashtable_params rhash_peer_addr_param; }; +static inline u32 ath12k_dp_arch_tx_get_vdev_bank_config(struct ath12k_dp *dp, + struct ath12k_link_vif *arvif) +{ + return dp->ops->tx_get_vdev_bank_config(dp->ab, arvif); +} + +static inline int ath12k_dp_arch_reo_cmd_send(struct ath12k_dp *dp, + struct ath12k_dp_rx_tid *rx_tid, + enum hal_reo_cmd_type type, + struct ath12k_hal_reo_cmd *cmd, + void (*cb)(struct ath12k_dp *dp, void *ctx, + enum hal_reo_cmd_status status)) +{ + return dp->ops->reo_cmd_send(dp->ab, rx_tid, type, cmd, cb); +} + +static inline void ath12k_dp_arch_setup_pn_check_reo_cmd(struct ath12k_dp *dp, + struct ath12k_hal_reo_cmd *cmd, + struct ath12k_dp_rx_tid *rx_tid, + u32 cipher, + enum set_key_cmd key_cmd) +{ + dp->ops->setup_pn_check_reo_cmd(cmd, rx_tid, cipher, key_cmd); +} + +static inline void ath12k_dp_arch_rx_peer_tid_delete(struct ath12k_dp *dp, + struct ath12k_dp_link_peer *peer, + u8 tid) +{ + dp->ops->rx_peer_tid_delete(dp->ab, peer, tid); +} + +static inline void ath12k_dp_arch_reo_cache_flush(struct ath12k_dp *dp, + struct ath12k_dp_rx_tid *rx_tid) +{ + dp->ops->reo_cache_flush(dp->ab, rx_tid); +} + +static inline +int ath12k_dp_arch_rx_link_desc_return(struct ath12k_dp *dp, + struct ath12k_buffer_addr *buf_addr_info, + enum hal_wbm_rel_bm_act action) +{ + return dp->ops->rx_link_desc_return(dp->ab, buf_addr_info, action); +} + +static inline int ath12k_dp_arch_peer_rx_tid_reo_update(struct ath12k_dp *dp, + struct ath12k_dp_link_peer *peer, + struct ath12k_dp_rx_tid *rx_tid, + u32 ba_win_sz, u16 ssn, + bool update_ssn) +{ + return dp->ops->peer_rx_tid_reo_update(dp, peer, rx_tid, + ba_win_sz, ssn, update_ssn); +} + +static inline int ath12k_dp_arch_rx_assign_reoq(struct ath12k_dp *dp, + struct ath12k_dp_peer *dp_peer, + struct ath12k_dp_rx_tid *rx_tid, + u16 ssn, enum hal_pn_type pn_type) +{ + return dp->ops->rx_assign_reoq(dp->ab, dp_peer, rx_tid, ssn, pn_type); +} + +static inline void ath12k_dp_arch_peer_rx_tid_qref_setup(struct ath12k_dp *dp, + u16 peer_id, u16 tid, + dma_addr_t paddr) +{ + dp->ops->peer_rx_tid_qref_setup(dp->ab, peer_id, tid, paddr); +} + static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) { memcpy(addr, &addr_l32, 4); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index aa7e31b7f9507..ba94a4f42103e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -470,7 +470,7 @@ void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx, */ spin_unlock_bh(&dp->reo_cmd_lock); - ath12k_wifi7_dp_reo_cache_flush(ab, &elem->data); + ath12k_dp_arch_reo_cache_flush(dp, &elem->data); kfree(elem); } } @@ -501,18 +501,16 @@ static int ath12k_dp_rx_tid_delete_handler(struct ath12k_base *ab, void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, bool rel_link_desc) { + enum hal_wbm_rel_bm_act act = HAL_WBM_REL_BM_ACT_PUT_IN_IDLE; struct ath12k_buffer_addr *buf_addr_info; struct ath12k_dp *dp = rx_tid->dp; - struct ath12k_base *ab = dp->ab; lockdep_assert_held(&dp->dp_lock); if (rx_tid->dst_ring_desc) { if (rel_link_desc) { buf_addr_info = &rx_tid->dst_ring_desc->buf_addr_info; - ath12k_wifi7_dp_rx_link_desc_return - (ab, buf_addr_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + ath12k_dp_arch_rx_link_desc_return(dp, buf_addr_info, act); } kfree(rx_tid->dst_ring_desc); rx_tid->dst_ring_desc = NULL; @@ -539,7 +537,7 @@ void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer for (i = 0; i <= IEEE80211_NUM_TIDS; i++) { rx_tid = &peer->dp_peer->rx_tid[i]; - ath12k_wifi7_dp_rx_peer_tid_delete(ar, peer, i); + ath12k_dp_arch_rx_peer_tid_delete(dp, peer, i); ath12k_dp_rx_frags_cleanup(rx_tid, true); spin_unlock_bh(&dp->dp_lock); @@ -704,8 +702,8 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ rx_tid = &peer->dp_peer->rx_tid[tid]; /* Update the tid queue if it is already setup */ if (peer->rx_tid_active_bitmask & (1 << tid)) { - ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, rx_tid, - ba_win_sz, ssn, true); + ret = ath12k_dp_arch_peer_rx_tid_reo_update(dp, peer, rx_tid, + ba_win_sz, ssn, true); spin_unlock_bh(&dp->dp_lock); if (ret) { ath12k_warn(ab, "failed to update reo for rx tid %d\n", tid); @@ -732,7 +730,7 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ rx_tid->ba_win_sz = ba_win_sz; - ret = ath12k_wifi7_dp_rx_assign_reoq(ab, peer->dp_peer, rx_tid, ssn, pn_type); + ret = ath12k_dp_arch_rx_assign_reoq(dp, peer->dp_peer, rx_tid, ssn, pn_type); if (ret) { spin_unlock_bh(&dp->dp_lock); ath12k_warn(ab, "failed to assign reoq buf for rx tid %u\n", tid); @@ -747,11 +745,11 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_ * and tid with qaddr. */ if (peer->mlo) - ath12k_wifi7_peer_rx_tid_qref_setup(ab, peer->ml_id, tid, - paddr_aligned); + ath12k_dp_arch_peer_rx_tid_qref_setup(dp, peer->ml_id, tid, + paddr_aligned); else - ath12k_wifi7_peer_rx_tid_qref_setup(ab, peer->peer_id, tid, - paddr_aligned); + ath12k_dp_arch_peer_rx_tid_qref_setup(dp, peer->peer_id, tid, + paddr_aligned); spin_unlock_bh(&dp->dp_lock); } else { @@ -835,8 +833,8 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar, return 0; } - ret = ath12k_wifi7_peer_rx_tid_reo_update(ar, peer, peer->dp_peer->rx_tid, - 1, 0, false); + ret = ath12k_dp_arch_peer_rx_tid_reo_update(dp, peer, peer->dp_peer->rx_tid, + 1, 0, false); spin_unlock_bh(&dp->dp_lock); if (ret) { ath12k_warn(ab, "failed to update reo for rx tid %d: %d\n", @@ -886,11 +884,11 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, rx_tid = &peer->dp_peer->rx_tid[tid]; - ath12k_wifi7_dp_setup_pn_check_reo_cmd(&cmd, rx_tid, key->cipher, - key_cmd); - ret = ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid, - HAL_REO_CMD_UPDATE_RX_QUEUE, - &cmd, NULL); + ath12k_dp_arch_setup_pn_check_reo_cmd(dp, &cmd, rx_tid, key->cipher, + key_cmd); + ret = ath12k_dp_arch_reo_cmd_send(dp, rx_tid, + HAL_REO_CMD_UPDATE_RX_QUEUE, + &cmd, NULL); if (ret) { ath12k_warn(ab, "failed to configure rx tid %d queue of peer %pM for pn replay detection %d\n", tid, peer_addr, ret); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 976dfe1b90874..1fd7738a39b57 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -138,7 +138,15 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, static struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = { .service_srng = ath12k_wifi7_dp_service_srng, - .dp_tx_get_vdev_bank_config = ath12k_wifi7_dp_tx_get_vdev_bank_config, + .tx_get_vdev_bank_config = ath12k_wifi7_dp_tx_get_vdev_bank_config, + .reo_cmd_send = ath12k_wifi7_dp_reo_cmd_send, + .setup_pn_check_reo_cmd = ath12k_wifi7_dp_setup_pn_check_reo_cmd, + .rx_peer_tid_delete = ath12k_wifi7_dp_rx_peer_tid_delete, + .reo_cache_flush = ath12k_wifi7_dp_reo_cache_flush, + .rx_link_desc_return = ath12k_wifi7_dp_rx_link_desc_return, + .peer_rx_tid_reo_update = ath12k_wifi7_peer_rx_tid_reo_update, + .rx_assign_reoq = ath12k_wifi7_dp_rx_assign_reoq, + .peer_rx_tid_qref_setup = ath12k_wifi7_peer_rx_tid_qref_setup, }; /* TODO: remove export once this file is built with wifi7 ko */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index d24d0f12742eb..f4855b001fda6 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -68,7 +68,7 @@ static void ath12k_wifi7_peer_rx_tid_qref_reset(struct ath12k_base *ab, u32_encode_bits(tid, DP_REO_QREF_NUM); } -void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k *ar, +void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k_base *ab, struct ath12k_dp_link_peer *peer, u8 tid) { struct ath12k_hal_reo_cmd cmd = {}; @@ -82,22 +82,22 @@ void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k *ar, cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); cmd.upd0 = HAL_REO_CMD_UPD0_VLD; - ret = ath12k_wifi7_dp_reo_cmd_send(ar->ab, rx_tid, + ret = ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid, HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, ath12k_dp_rx_tid_del_func); if (ret) { - ath12k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n", + ath12k_err(ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n", tid, ret); - dma_unmap_single(ar->ab->dev, rx_tid->qbuf.paddr_aligned, + dma_unmap_single(ab->dev, rx_tid->qbuf.paddr_aligned, rx_tid->qbuf.size, DMA_BIDIRECTIONAL); kfree(rx_tid->qbuf.vaddr); rx_tid->qbuf.vaddr = NULL; } if (peer->mlo) - ath12k_wifi7_peer_rx_tid_qref_reset(ar->ab, peer->ml_id, tid); + ath12k_wifi7_peer_rx_tid_qref_reset(ab, peer->ml_id, tid); else - ath12k_wifi7_peer_rx_tid_qref_reset(ar->ab, peer->peer_id, tid); + ath12k_wifi7_peer_rx_tid_qref_reset(ab, peer->peer_id, tid); peer->rx_tid_active_bitmask &= ~(1 << tid); } @@ -179,13 +179,14 @@ int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, return 0; } -int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k *ar, +int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k_dp *dp, struct ath12k_dp_link_peer *peer, struct ath12k_dp_rx_tid *rx_tid, u32 ba_win_sz, u16 ssn, bool update_ssn) { struct ath12k_hal_reo_cmd cmd = {}; + struct ath12k_base *ab = dp->ab; int ret; cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned); @@ -199,11 +200,11 @@ int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k *ar, cmd.upd2 = u32_encode_bits(ssn, HAL_REO_CMD_UPD2_SSN); } - ret = ath12k_wifi7_dp_reo_cmd_send(ar->ab, rx_tid, + ret = ath12k_wifi7_dp_reo_cmd_send(ab, rx_tid, HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, NULL); if (ret) { - ath12k_warn(ar->ab, "failed to update rx tid queue, tid %d (%d)\n", + ath12k_warn(ab, "failed to update rx tid queue, tid %d (%d)\n", rx_tid->tid, ret); return ret; } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index ba319ff506f28..cb72b75526d4a 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -33,7 +33,7 @@ int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, enum hal_wbm_rel_bm_act action); void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, dma_addr_t paddr); -void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k *ar, +void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k_base *ab, struct ath12k_dp_link_peer *peer, u8 tid); int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid, enum hal_reo_cmd_type type, @@ -42,7 +42,7 @@ int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid enum hal_reo_cmd_status status)); void ath12k_wifi7_dp_reo_cache_flush(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid); -int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k *ar, +int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k_dp *dp, struct ath12k_dp_link_peer *peer, struct ath12k_dp_rx_tid *rx_tid, u32 ba_win_sz, u16 ssn, From 9790c08ecf8ca3fed92368bec1fc24c15761abcc Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Mon, 3 Nov 2025 16:51:01 +0530 Subject: [PATCH 088/140] wifi: ath12k: Move DP device stats to ath12k_dp As part of data path modularization of device object framework, the per packet tx/rx operations now use ath12k_dp. Move all the device stats 'device_stats' from ath12k_base to ath12k_dp, consolidating all device stats within ath12k_dp. This would improve the performance by allowing the datapath to reach to the stats counters without to having to reach out to ath12k_base object. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-3-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 27 ------------------- drivers/net/wireless/ath/ath12k/debug.c | 3 ++- drivers/net/wireless/ath/ath12k/debugfs.c | 3 ++- drivers/net/wireless/ath/ath12k/dp.h | 27 +++++++++++++++++++ drivers/net/wireless/ath/ath12k/dp_rx.c | 4 +-- drivers/net/wireless/ath/ath12k/dp_rx.h | 2 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 22 +++++++-------- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 19 ++++++------- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 10 ++++--- 9 files changed, 61 insertions(+), 56 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index bb2d904dae7cd..faae17f321d62 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -908,32 +908,6 @@ struct ath12k_board_data { size_t len; }; -struct ath12k_device_dp_tx_err_stats { - /* TCL Ring Descriptor unavailable */ - u32 desc_na[DP_TCL_NUM_RING_MAX]; - /* Other failures during dp_tx due to mem allocation failure - * idr unavailable etc. - */ - atomic_t misc_fail; -}; - -struct ath12k_device_dp_stats { - u32 err_ring_pkts; - u32 invalid_rbm; - u32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX]; - u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX]; - u32 hal_reo_error[DP_REO_DST_RING_MAX]; - struct ath12k_device_dp_tx_err_stats tx_err; - u32 reo_rx[DP_REO_DST_RING_MAX][ATH12K_MAX_DEVICES]; - u32 rx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX][ATH12K_MAX_DEVICES]; - u32 tqm_rel_reason[MAX_TQM_RELEASE_REASON]; - u32 fw_tx_status[MAX_FW_TX_STATUS]; - u32 tx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX]; - u32 tx_enqueued[DP_TCL_NUM_RING_MAX]; - u32 tx_completed[DP_TCL_NUM_RING_MAX]; - u32 reo_excep_msdu_buf_type; -}; - struct ath12k_reg_freq { u32 start_freq; u32 end_freq; @@ -1112,7 +1086,6 @@ struct ath12k_base { /* Current DFS Regulatory */ enum ath12k_dfs_region dfs_region; - struct ath12k_device_dp_stats device_stats; #ifdef CONFIG_ATH12K_DEBUGFS struct dentry *debugfs_soc; #endif diff --git a/drivers/net/wireless/ath/ath12k/debug.c b/drivers/net/wireless/ath/ath12k/debug.c index 9910c60f30ced..5fe9b2fbf5096 100644 --- a/drivers/net/wireless/ath/ath12k/debug.c +++ b/drivers/net/wireless/ath/ath12k/debug.c @@ -1,7 +1,8 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 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. + * */ #include diff --git a/drivers/net/wireless/ath/ath12k/debugfs.c b/drivers/net/wireless/ath/ath12k/debugfs.c index 19c4fabecff8e..64d89d82332ba 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs.c +++ b/drivers/net/wireless/ath/ath12k/debugfs.c @@ -1027,7 +1027,8 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file, size_t count, loff_t *ppos) { struct ath12k_base *ab = file->private_data; - struct ath12k_device_dp_stats *device_stats = &ab->device_stats; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_device_dp_stats *device_stats = &dp->device_stats; int len = 0, i, j, ret; struct ath12k *ar; const int size = 4096; diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 9c926bcbd4359..1068a130fc82c 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -11,6 +11,7 @@ #include "dp_htt.h" #include "dp_cmn.h" #include +#include "wifi7/hal_desc.h" #define MAX_RXDMA_PER_PDEV 2 @@ -420,6 +421,31 @@ struct ath12k_dp_arch_ops { dma_addr_t paddr); }; +struct ath12k_device_dp_tx_err_stats { + /* TCL Ring Descriptor unavailable */ + u32 desc_na[DP_TCL_NUM_RING_MAX]; + /* Other failures during dp_tx due to mem allocation failure + * idr unavailable etc. + */ + atomic_t misc_fail; +}; + +struct ath12k_device_dp_stats { + u32 err_ring_pkts; + u32 invalid_rbm; + u32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX]; + u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX]; + u32 hal_reo_error[DP_REO_DST_RING_MAX]; + struct ath12k_device_dp_tx_err_stats tx_err; + u32 reo_rx[DP_REO_DST_RING_MAX][ATH12K_MAX_DEVICES]; + u32 rx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX][ATH12K_MAX_DEVICES]; + u32 tqm_rel_reason[MAX_TQM_RELEASE_REASON]; + u32 fw_tx_status[MAX_FW_TX_STATUS]; + u32 tx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX]; + u32 tx_enqueued[DP_TCL_NUM_RING_MAX]; + u32 tx_completed[DP_TCL_NUM_RING_MAX]; +}; + struct ath12k_dp { struct ath12k_base *ab; u32 mon_dest_ring_stuck_cnt; @@ -518,6 +544,7 @@ struct ath12k_dp { /* The rhashtable containing struct ath12k_link_peer keyed by mac addr */ struct rhashtable *rhead_peer_addr; struct rhashtable_params rhash_peer_addr_param; + struct ath12k_device_dp_stats device_stats; }; static inline u32 ath12k_dp_arch_tx_get_vdev_bank_config(struct ath12k_dp *dp, diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index ba94a4f42103e..49c1e35aa0c46 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -1445,7 +1445,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc ieee80211_rx_napi(ath12k_pdev_dp_to_hw(dp_pdev), pubsta, msdu, napi); } -bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, +bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_dp *dp, struct hal_rx_desc *rx_desc, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info) @@ -1462,7 +1462,7 @@ bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, if ((likely(hdr_len <= DP_MAX_NWIFI_HDR_LEN))) return true; - ab->device_stats.invalid_rbm++; + dp->device_stats.invalid_rbm++; WARN_ON_ONCE(1); return false; } diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 51bc443f4c7ca..4a93331dff579 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -197,7 +197,7 @@ void ath12k_dp_rx_h_undecap(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info); -bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab, +bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_dp *dp, struct hal_rx_desc *rx_desc, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index f4855b001fda6..0cf8a8f7b5f6e 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -538,7 +538,7 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k_pdev_dp *dp_pdev, } } - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu, + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(dp, rx_desc, msdu, rx_info))) { ret = -EINVAL; goto free_out; @@ -710,14 +710,14 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, DMA_FROM_DEVICE); num_buffs_reaped[device_id]++; - ab->device_stats.reo_rx[ring_id][ab->device_id]++; + dp->device_stats.reo_rx[ring_id][ab->device_id]++; push_reason = le32_get_bits(desc->info0, HAL_REO_DEST_RING_INFO0_PUSH_REASON); if (push_reason != HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) { dev_kfree_skb_any(msdu); - ab->device_stats.hal_reo_error[ring_id]++; + dp->device_stats.hal_reo_error[ring_id]++; continue; } @@ -1021,7 +1021,7 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED; skb_pull(msdu, hal_rx_desc_sz); - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu, + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(dp, rx_desc, msdu, rx_info))) return -EINVAL; @@ -1357,7 +1357,7 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n while (budget && (reo_desc = ath12k_hal_srng_dst_get_next_entry(ab, srng))) { drop = false; - ab->device_stats.err_ring_pkts++; + dp->device_stats.err_ring_pkts++; ret = ath12k_wifi7_hal_desc_reo_parse_err(ab, reo_desc, &paddr, &desc_bank); @@ -1385,7 +1385,7 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n rbm != HAL_RX_BUF_RBM_SW3_BM && rbm != partner_ab->hal.hal_params->rx_buf_rbm) { act = HAL_WBM_REL_BM_ACT_REL_MSDU; - ab->device_stats.invalid_rbm++; + dp->device_stats.invalid_rbm++; ath12k_warn(ab, "invalid return buffer manager %d\n", rbm); ath12k_wifi7_dp_rx_link_desc_return(partner_ab, &reo_desc->buf_addr_info, @@ -1539,7 +1539,7 @@ static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k_pdev_dp *dp_pdev, skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); } - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu, rx_info))) + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(dp, desc, msdu, rx_info))) return -EINVAL; ath12k_dp_rx_h_ppdu(dp_pdev, rx_info); @@ -1580,7 +1580,7 @@ static bool ath12k_wifi7_dp_rx_h_tkip_mic_err(struct ath12k_pdev_dp *dp_pdev, skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); - if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu, rx_info))) + if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(dp, desc, msdu, rx_info))) return true; ath12k_dp_rx_h_ppdu(dp_pdev, rx_info); @@ -1601,7 +1601,7 @@ static bool ath12k_wifi7_dp_rx_h_rxdma_err(struct ath12k_pdev_dp *dp_pdev, struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); bool drop = false; - dp->ab->device_stats.rxdma_error[rxcb->err_code]++; + dp->device_stats.rxdma_error[rxcb->err_code]++; switch (rxcb->err_code) { case HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR: @@ -1631,7 +1631,7 @@ static bool ath12k_wifi7_dp_rx_h_reo_err(struct ath12k_pdev_dp *dp_pdev, struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); bool drop = false; - dp->ab->device_stats.reo_error[rxcb->err_code]++; + dp->device_stats.reo_error[rxcb->err_code]++; switch (rxcb->err_code) { case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO: @@ -1744,7 +1744,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, int num_buffs_reaped[ATH12K_MAX_DEVICES] = {}; int total_num_buffs_reaped = 0; struct ath12k_rx_desc_info *desc_info; - struct ath12k_device_dp_stats *device_stats = &ab->device_stats; + struct ath12k_device_dp_stats *device_stats = &dp->device_stats; struct ath12k_hw_link *hw_links = ag->hw_links; u8 hw_link_id, device_id; int ret, pdev_idx; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 950614a217a05..454d5a7532cfd 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -205,7 +205,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a default: /* TODO: Take care of other encap modes as well */ ret = -EINVAL; - atomic_inc(&ab->device_stats.tx_err.misc_fail); + atomic_inc(&dp->device_stats.tx_err.misc_fail); goto fail_remove_tx_buf; } @@ -228,7 +228,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a map: ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE); if (dma_mapping_error(ab->dev, ti.paddr)) { - atomic_inc(&ab->device_stats.tx_err.misc_fail); + atomic_inc(&dp->device_stats.tx_err.misc_fail); ath12k_warn(ab, "failed to DMA map data Tx buffer\n"); ret = -ENOMEM; goto fail_remove_tx_buf; @@ -311,7 +311,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a * desc because the desc is directly enqueued onto hw queue. */ ath12k_hal_srng_access_end(ab, tcl_ring); - ab->device_stats.tx_err.desc_na[ti.ring_id]++; + dp->device_stats.tx_err.desc_na[ti.ring_id]++; spin_unlock_bh(&tcl_ring->lock); ret = -ENOMEM; @@ -340,7 +340,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a arvif->link_stats.tx_enqueued++; spin_unlock_bh(&arvif->link_stats_lock); - ab->device_stats.tx_enqueued[ti.ring_id]++; + dp->device_stats.tx_enqueued[ti.ring_id]++; ath12k_wifi7_hal_tx_cmd_desc_setup(ab, hal_tcl_desc, &ti); @@ -403,7 +403,7 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, ar = skb_cb->ar; dp_pdev = &ar->dp; - ab->device_stats.tx_completed[tx_ring->tcl_data_ring_id]++; + ab->dp->device_stats.tx_completed[tx_ring->tcl_data_ring_id]++; if (atomic_dec_and_test(&ar->dp.num_tx_pending)) wake_up(&ar->dp.tx_empty_waitq); @@ -475,13 +475,14 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc, struct htt_tx_wbm_completion *status_desc; struct ath12k_dp_htt_wbm_tx_status ts = {}; enum hal_wbm_htt_tx_comp_status wbm_status; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); u16 peer_id; status_desc = desc; wbm_status = le32_get_bits(status_desc->info0, HTT_TX_WBM_COMP_INFO0_STATUS); - ab->device_stats.fw_tx_status[wbm_status]++; + dp->device_stats.fw_tx_status[wbm_status]++; switch (wbm_status) { case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK: @@ -656,7 +657,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, } skb_cb = ATH12K_SKB_CB(msdu); - ab->device_stats.tx_completed[ring]++; + dp->device_stats.tx_completed[ring]++; dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); if (skb_cb->paddr_ext_desc) { @@ -883,11 +884,11 @@ void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) /* Find the HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE value */ buf_rel_source = le32_get_bits(tx_status->info0, HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE); - ab->device_stats.tx_wbm_rel_source[buf_rel_source]++; + dp->device_stats.tx_wbm_rel_source[buf_rel_source]++; rel_status = le32_get_bits(tx_status->info0, HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON); - ab->device_stats.tqm_rel_reason[rel_status]++; + dp->device_stats.tqm_rel_reason[rel_status]++; /* Release descriptor as soon as extracting necessary info * to reduce contention diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index 2eb3789962f37..185cb9a9544aa 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -329,13 +329,14 @@ int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_base *ab, { enum hal_reo_dest_ring_push_reason push_reason; enum hal_reo_dest_ring_error_code err_code; - u32 cookie; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + u32 cookie, val; push_reason = le32_get_bits(desc->info0, HAL_REO_DEST_RING_INFO0_PUSH_REASON); err_code = le32_get_bits(desc->info0, HAL_REO_DEST_RING_INFO0_ERROR_CODE); - ab->device_stats.reo_error[err_code]++; + dp->device_stats.reo_error[err_code]++; if (push_reason != HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED && push_reason != HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) { @@ -355,6 +356,7 @@ int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, { struct hal_wbm_release_ring *wbm_desc = desc; struct hal_wbm_release_ring_cc_rx *wbm_cc_desc = desc; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); enum hal_wbm_rel_desc_type type; enum hal_wbm_rel_src_module rel_src; bool hw_cc_done; @@ -384,7 +386,7 @@ int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, val = le32_get_bits(wbm_desc->buf_addr_info.info1, BUFFER_ADDR_INFO1_RET_BUF_MGR); if (val != HAL_RX_BUF_RBM_SW3_BM) { - ab->device_stats.invalid_rbm++; + dp->device_stats.invalid_rbm++; return -EINVAL; } @@ -396,7 +398,7 @@ int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, val = le32_get_bits(wbm_cc_desc->info0, HAL_WBM_RELEASE_RX_CC_INFO0_RBM); if (val != HAL_RX_BUF_RBM_SW3_BM) { - ab->device_stats.invalid_rbm++; + dp->device_stats.invalid_rbm++; return -EINVAL; } From 68ae230aada4375b0520c0b77c275e6d1de3903c Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Mon, 3 Nov 2025 16:51:02 +0530 Subject: [PATCH 089/140] wifi: ath12k: Move DP specific link stats to DP link peer As part of peer modularization in the Driver Framework, the station view is as follows: Common Path Data Path ------------------------------------------------------------------- ath12k_sta ath12k_dp_peer | | |-> ath12k_link_sta <----> |-> ath12k_dp_link_peer | | |-> ath12k_link_sta <----> |-> ath12k_dp_link_peer | | |-> ath12k_link_sta <----> |-> ath12k_dp_link_peer Currently ath12k_link_sta has data path stats updated in tx_htt and rx monitor path. Move those stats from ath12_link_sta to ath12k_dp_link_peer to align with peer modularization model as shown above. This allows datapath to use only ath12k_dp_link_peer without having to reach out to other objects for updating stats, thereby improving the cache locality. Add following API to fetch rate info from DP link peer: ath12k_dp_link_peer_get_sta_rate_info_stats() This wrapper API populates link stats in 'struct ath12k_dp_link_peer_rate_info', which can be extended to support out-of-band retrieval of various rate stats. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Harsh Kumar Bijlani Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-4-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 59 --------- drivers/net/wireless/ath/ath12k/debugfs_sta.c | 35 +++-- drivers/net/wireless/ath/ath12k/dp_cmn.h | 12 ++ drivers/net/wireless/ath/ath12k/dp_htt.c | 63 +++++---- drivers/net/wireless/ath/ath12k/dp_mon.c | 41 ++---- drivers/net/wireless/ath/ath12k/dp_peer.c | 58 ++++++++- drivers/net/wireless/ath/ath12k/dp_peer.h | 56 ++++++++ drivers/net/wireless/ath/ath12k/hal.h | 9 ++ drivers/net/wireless/ath/ath12k/mac.c | 120 ++++++++++-------- drivers/net/wireless/ath/ath12k/peer.c | 3 + drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 33 ++--- 11 files changed, 281 insertions(+), 208 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index faae17f321d62..8a1abd5049144 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -400,51 +400,8 @@ struct ath12k_vif_iter { struct ath12k_link_vif *arvif; }; -#define HAL_AST_IDX_INVALID 0xFFFF -#define HAL_RX_MAX_MCS 12 -#define HAL_RX_MAX_MCS_HT 31 -#define HAL_RX_MAX_MCS_VHT 9 -#define HAL_RX_MAX_MCS_HE 11 -#define HAL_RX_MAX_MCS_BE 15 -#define HAL_RX_MAX_NSS 8 -#define HAL_RX_MAX_NUM_LEGACY_RATES 12 - #define ATH12K_SCAN_TIMEOUT_HZ (20 * HZ) -struct ath12k_rx_peer_rate_stats { - u64 ht_mcs_count[HAL_RX_MAX_MCS_HT + 1]; - u64 vht_mcs_count[HAL_RX_MAX_MCS_VHT + 1]; - u64 he_mcs_count[HAL_RX_MAX_MCS_HE + 1]; - u64 be_mcs_count[HAL_RX_MAX_MCS_BE + 1]; - u64 nss_count[HAL_RX_MAX_NSS]; - u64 bw_count[HAL_RX_BW_MAX]; - u64 gi_count[HAL_RX_GI_MAX]; - u64 legacy_count[HAL_RX_MAX_NUM_LEGACY_RATES]; - u64 rx_rate[HAL_RX_BW_MAX][HAL_RX_GI_MAX][HAL_RX_MAX_NSS][HAL_RX_MAX_MCS_HT + 1]; -}; - -struct ath12k_rx_peer_stats { - u64 num_msdu; - u64 num_mpdu_fcs_ok; - u64 num_mpdu_fcs_err; - u64 tcp_msdu_count; - u64 udp_msdu_count; - u64 other_msdu_count; - u64 ampdu_msdu_count; - u64 non_ampdu_msdu_count; - u64 stbc_count; - u64 beamformed_count; - u64 coding_count[HAL_RX_SU_MU_CODING_MAX]; - u64 tid_count[IEEE80211_NUM_TIDS + 1]; - u64 pream_cnt[HAL_RX_PREAMBLE_MAX]; - u64 reception_type[HAL_RX_RECEPTION_TYPE_MAX]; - u64 rx_duration; - u64 dcm_count; - u64 ru_alloc_cnt[HAL_RX_RU_ALLOC_TYPE_MAX]; - struct ath12k_rx_peer_rate_stats pkt_stats; - struct ath12k_rx_peer_rate_stats byte_stats; -}; - #define ATH12K_HE_MCS_NUM 12 #define ATH12K_VHT_MCS_NUM 10 #define ATH12K_BW_NUM 5 @@ -526,12 +483,6 @@ struct ath12k_per_ppdu_tx_stats { u32 retry_bytes; }; -struct ath12k_wbm_tx_stats { - u64 wbm_tx_comp_stats[HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX]; -}; - -DECLARE_EWMA(avg_rssi, 10, 8) - struct ath12k_link_sta { struct ath12k_link_vif *arvif; struct ath12k_sta *ahsta; @@ -546,15 +497,7 @@ struct ath12k_link_sta { u32 smps; struct wiphy_work update_wk; - struct rate_info txrate; - struct rate_info last_txrate; - u64 rx_duration; - u64 tx_duration; - u8 rssi_comb; - struct ewma_avg_rssi avg_rssi; u8 link_id; - struct ath12k_rx_peer_stats *rx_stats; - struct ath12k_wbm_tx_stats *wbm_tx_stats; u32 bw_prev; u32 peer_nss; s8 rssi_beacon; @@ -565,8 +508,6 @@ struct ath12k_link_sta { /* for firmware use only */ u8 link_idx; - u32 tx_retry_failed; - u32 tx_retry_count; /* peer addr based rhashtable list pointer */ struct rhash_head rhash_addr; diff --git a/drivers/net/wireless/ath/ath12k/debugfs_sta.c b/drivers/net/wireless/ath/ath12k/debugfs_sta.c index e6665fd521db8..dde3efed4b60b 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs_sta.c +++ b/drivers/net/wireless/ath/ath12k/debugfs_sta.c @@ -11,6 +11,7 @@ #include "debug.h" #include "debugfs_htt_stats.h" #include "debugfs.h" +#include "dp_cmn.h" static u32 ath12k_dbg_sta_dump_rate_stats(u8 *buf, u32 offset, const int size, @@ -144,9 +145,11 @@ static ssize_t ath12k_dbg_sta_dump_rx_stats(struct file *file, const int size = ATH12K_STA_RX_STATS_BUF_SIZE; struct ath12k_hw *ah = ahsta->ahvif->ah; struct ath12k_rx_peer_stats *rx_stats; + struct ath12k_dp_link_peer *link_peer; struct ath12k_link_sta *arsta; u8 link_id = link_sta->link_id; int len = 0, i, ret = 0; + struct ath12k_dp *dp; bool he_rates_avail; struct ath12k *ar; @@ -171,9 +174,16 @@ static ssize_t ath12k_dbg_sta_dump_rx_stats(struct file *file, goto out; } - spin_lock_bh(&ar->ab->base_lock); + dp = ath12k_ab_to_dp(ar->ab); + spin_lock_bh(&dp->dp_lock); - rx_stats = arsta->rx_stats; + link_peer = ath12k_dp_link_peer_find_by_addr(dp, arsta->addr); + if (!link_peer) { + ret = -ENOENT; + goto unlock; + } + + rx_stats = link_peer->peer_stats.rx_stats; if (!rx_stats) { ret = -ENOENT; goto unlock; @@ -238,7 +248,7 @@ static ssize_t ath12k_dbg_sta_dump_rx_stats(struct file *file, &rx_stats->byte_stats); unlock: - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&dp->dp_lock); if (len) ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); @@ -261,10 +271,9 @@ static ssize_t ath12k_dbg_sta_reset_rx_stats(struct file *file, struct ieee80211_link_sta *link_sta = file->private_data; struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(link_sta->sta); struct ath12k_hw *ah = ahsta->ahvif->ah; - struct ath12k_rx_peer_stats *rx_stats; - struct ath12k_link_sta *arsta; u8 link_id = link_sta->link_id; - struct ath12k *ar; + struct ath12k_link_sta *arsta; + struct ath12k_dp *dp; bool reset; int ret; @@ -288,19 +297,9 @@ static ssize_t ath12k_dbg_sta_reset_rx_stats(struct file *file, goto out; } - ar = arsta->arvif->ar; - - spin_lock_bh(&ar->ab->base_lock); - - rx_stats = arsta->rx_stats; - if (!rx_stats) { - spin_unlock_bh(&ar->ab->base_lock); - ret = -ENOENT; - goto out; - } + dp = ath12k_ab_to_dp(arsta->arvif->ar->ab); - memset(rx_stats, 0, sizeof(*rx_stats)); - spin_unlock_bh(&ar->ab->base_lock); + ath12k_dp_link_peer_reset_rx_stats(dp, arsta->addr); ret = count; out: diff --git a/drivers/net/wireless/ath/ath12k/dp_cmn.h b/drivers/net/wireless/ath/ath12k/dp_cmn.h index dd10426bd12de..e17f044ff8122 100644 --- a/drivers/net/wireless/ath/ath12k/dp_cmn.h +++ b/drivers/net/wireless/ath/ath12k/dp_cmn.h @@ -74,6 +74,14 @@ struct ath12k_dp_peer_create_params { bool ucast_ra_only; }; +struct ath12k_dp_link_peer_rate_info { + struct rate_info txrate; + u64 rx_duration; + u64 tx_duration; + u8 rssi_comb; + s8 signal_avg; +}; + static inline struct ath12k_dp_link_vif * ath12k_dp_vif_to_dp_link_vif(struct ath12k_dp_vif *dp_vif, u8 link_id) { @@ -91,4 +99,8 @@ int ath12k_dp_link_peer_assign(struct ath12k_dp *dp, struct ath12k_dp_hw *dp_hw, u8 link_id, u32 hw_link_id); void ath12k_dp_link_peer_unassign(struct ath12k_dp *dp, struct ath12k_dp_hw *dp_hw, u8 vdev_id, u8 *addr, u32 hw_link_id); +void +ath12k_dp_link_peer_get_sta_rate_info_stats(struct ath12k_dp *dp, const u8 *addr, + struct ath12k_dp_link_peer_rate_info *info); +void ath12k_dp_link_peer_reset_rx_stats(struct ath12k_dp *dp, const u8 *addr); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index db5ac36adf3dd..39f42cd99835b 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -189,7 +189,6 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_base *ab = dp->ab; struct ath12k_dp_link_peer *peer; - struct ath12k_link_sta *arsta; struct htt_ppdu_stats_user_rate *user_rate; struct ath12k_per_peer_tx_stats *peer_stats = &dp_pdev->peer_tx_stats; struct htt_ppdu_user_stats *usr_stats = &ppdu_stats->user_stats[user]; @@ -279,66 +278,64 @@ ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev, return; } - arsta = ath12k_dp_link_peer_to_link_sta(ab, peer); - if (!arsta) { - rcu_read_unlock(); - return; - } + spin_lock_bh(&dp->dp_lock); - memset(&arsta->txrate, 0, sizeof(arsta->txrate)); + memset(&peer->txrate, 0, sizeof(peer->txrate)); - arsta->txrate.bw = ath12k_mac_bw_to_mac80211_bw(bw); + peer->txrate.bw = ath12k_mac_bw_to_mac80211_bw(bw); switch (flags) { case WMI_RATE_PREAMBLE_OFDM: - arsta->txrate.legacy = rate; + peer->txrate.legacy = rate; break; case WMI_RATE_PREAMBLE_CCK: - arsta->txrate.legacy = rate; + peer->txrate.legacy = rate; break; case WMI_RATE_PREAMBLE_HT: - arsta->txrate.mcs = mcs + 8 * (nss - 1); - arsta->txrate.flags = RATE_INFO_FLAGS_MCS; + peer->txrate.mcs = mcs + 8 * (nss - 1); + peer->txrate.flags = RATE_INFO_FLAGS_MCS; if (sgi) - arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + peer->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; break; case WMI_RATE_PREAMBLE_VHT: - arsta->txrate.mcs = mcs; - arsta->txrate.flags = RATE_INFO_FLAGS_VHT_MCS; + peer->txrate.mcs = mcs; + peer->txrate.flags = RATE_INFO_FLAGS_VHT_MCS; if (sgi) - arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + peer->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; break; case WMI_RATE_PREAMBLE_HE: - arsta->txrate.mcs = mcs; - arsta->txrate.flags = RATE_INFO_FLAGS_HE_MCS; - arsta->txrate.he_dcm = dcm; - arsta->txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi); + peer->txrate.mcs = mcs; + peer->txrate.flags = RATE_INFO_FLAGS_HE_MCS; + peer->txrate.he_dcm = dcm; + peer->txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi); tones = le16_to_cpu(user_rate->ru_end) - le16_to_cpu(user_rate->ru_start) + 1; v = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(tones); - arsta->txrate.he_ru_alloc = v; + peer->txrate.he_ru_alloc = v; if (is_ofdma) - arsta->txrate.bw = RATE_INFO_BW_HE_RU; + peer->txrate.bw = RATE_INFO_BW_HE_RU; break; case WMI_RATE_PREAMBLE_EHT: - arsta->txrate.mcs = mcs; - arsta->txrate.flags = RATE_INFO_FLAGS_EHT_MCS; - arsta->txrate.he_dcm = dcm; - arsta->txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(sgi); + peer->txrate.mcs = mcs; + peer->txrate.flags = RATE_INFO_FLAGS_EHT_MCS; + peer->txrate.he_dcm = dcm; + peer->txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(sgi); tones = le16_to_cpu(user_rate->ru_end) - le16_to_cpu(user_rate->ru_start) + 1; v = ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(tones); - arsta->txrate.eht_ru_alloc = v; + peer->txrate.eht_ru_alloc = v; if (is_ofdma) - arsta->txrate.bw = RATE_INFO_BW_EHT_RU; + peer->txrate.bw = RATE_INFO_BW_EHT_RU; break; } - arsta->tx_retry_failed += tx_retry_failed; - arsta->tx_retry_count += tx_retry_count; - arsta->txrate.nss = nss; - arsta->tx_duration += tx_duration; - memcpy(&arsta->last_txrate, &arsta->txrate, sizeof(struct rate_info)); + peer->tx_retry_failed += tx_retry_failed; + peer->tx_retry_count += tx_retry_count; + peer->txrate.nss = nss; + peer->tx_duration += tx_duration; + memcpy(&peer->last_txrate, &peer->txrate, sizeof(struct rate_info)); + + spin_unlock_bh(&dp->dp_lock); /* PPDU stats reported for mgmt packet doesn't have valid tx bytes. * So skip peer stats update for mgmt packets. diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 132a6d121e80d..3b667c8fbe85c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -3491,6 +3491,9 @@ ath12k_dp_mon_rx_update_peer_rate_table_stats(struct ath12k_rx_peer_stats *rx_st u32 gi_idx = ppdu_info->gi; u32 len; + if (!rx_stats) + return; + if (mcs_idx > HAL_RX_MAX_MCS_HT || nss_idx >= HAL_RX_MAX_NSS || bw_idx >= HAL_RX_BW_MAX || gi_idx >= HAL_RX_GI_MAX) { return; @@ -3511,14 +3514,14 @@ ath12k_dp_mon_rx_update_peer_rate_table_stats(struct ath12k_rx_peer_stats *rx_st stats->rx_rate[bw_idx][gi_idx][nss_idx][mcs_idx] += len; } -static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_link_sta *arsta, +static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, struct hal_rx_mon_ppdu_info *ppdu_info) { - struct ath12k_rx_peer_stats *rx_stats = arsta->rx_stats; + struct ath12k_rx_peer_stats *rx_stats = peer->peer_stats.rx_stats; u32 num_msdu; - arsta->rssi_comb = ppdu_info->rssi_comb; - ewma_avg_rssi_add(&arsta->avg_rssi, ppdu_info->rssi_comb); + peer->rssi_comb = ppdu_info->rssi_comb; + ewma_avg_rssi_add(&peer->avg_rssi, ppdu_info->rssi_comb); if (!rx_stats) return; @@ -3566,7 +3569,7 @@ static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_link_sta *arsta, rx_stats->dcm_count += ppdu_info->dcm; rx_stats->rx_duration += ppdu_info->rx_duration; - arsta->rx_duration = rx_stats->rx_duration; + peer->rx_duration = rx_stats->rx_duration; if (ppdu_info->nss > 0 && ppdu_info->nss <= HAL_RX_MAX_NSS) { rx_stats->pkt_stats.nss_count[ppdu_info->nss - 1] += num_msdu; @@ -3673,7 +3676,6 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, struct hal_rx_mon_ppdu_info *ppdu_info, u32 uid) { - struct ath12k_link_sta *arsta; struct ath12k_rx_peer_stats *rx_stats = NULL; struct hal_rx_user_status *user_stats = &ppdu_info->userstats[uid]; struct ath12k_dp_link_peer *peer; @@ -3691,16 +3693,9 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, return; } - arsta = ath12k_dp_link_peer_to_link_sta(ab, peer); - if (!arsta) { - ath12k_warn(ab, "link sta not found on peer %pM id %d\n", - peer->addr, peer->peer_id); - return; - } - - arsta->rssi_comb = ppdu_info->rssi_comb; - ewma_avg_rssi_add(&arsta->avg_rssi, ppdu_info->rssi_comb); - rx_stats = arsta->rx_stats; + peer->rssi_comb = ppdu_info->rssi_comb; + ewma_avg_rssi_add(&peer->avg_rssi, ppdu_info->rssi_comb); + rx_stats = peer->peer_stats.rx_stats; if (!rx_stats) return; @@ -3744,7 +3739,7 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, rx_stats->ru_alloc_cnt[user_stats->ul_ofdma_ru_size] += num_msdu; rx_stats->rx_duration += ppdu_info->rx_duration; - arsta->rx_duration = rx_stats->rx_duration; + peer->rx_duration = rx_stats->rx_duration; if (user_stats->nss > 0 && user_stats->nss <= HAL_RX_MAX_NSS) { rx_stats->pkt_stats.nss_count[user_stats->nss - 1] += num_msdu; @@ -3809,7 +3804,6 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, struct dp_srng *mon_dst_ring; struct hal_srng *srng; struct dp_rxdma_mon_ring *buf_ring; - struct ath12k_link_sta *arsta; struct ath12k_dp_link_peer *peer; struct sk_buff_head skb_list; u64 cookie; @@ -3933,16 +3927,7 @@ int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, } if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) { - arsta = ath12k_dp_link_peer_to_link_sta(ab, peer); - if (!arsta) { - ath12k_warn(ab, "link sta not found on peer %pM id %d\n", - peer->addr, peer->peer_id); - rcu_read_unlock(); - dev_kfree_skb_any(skb); - continue; - } - ath12k_dp_mon_rx_update_peer_su_stats(arsta, - ppdu_info); + ath12k_dp_mon_rx_update_peer_su_stats(peer, ppdu_info); } else if ((ppdu_info->fc_valid) && (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) { ath12k_dp_mon_rx_process_ulofdma(ppdu_info); diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index a06113bedf0d7..8961c4635ed0b 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -7,6 +7,7 @@ #include "core.h" #include "dp_peer.h" #include "debug.h" +#include "debugfs.h" struct ath12k_dp_link_peer * ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_dp *dp, @@ -140,6 +141,8 @@ void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) peer->vdev_id, peer->addr, peer_id); list_del(&peer->list); + + kfree(peer->peer_stats.rx_stats); kfree(peer); wake_up(&ab->peer_mapping_wq); @@ -152,6 +155,7 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ { struct ath12k_dp_link_peer *peer; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k *ar; spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, mac_addr); @@ -165,10 +169,20 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ peer->ast_hash = ast_hash; peer->hw_peer_id = hw_peer_id; ether_addr_copy(peer->addr, mac_addr); + + rcu_read_lock(); + ar = ath12k_mac_get_ar_by_vdev_id(ab, vdev_id); + if (ar && ath12k_debugfs_is_extd_rx_stats_enabled(ar) && + !peer->peer_stats.rx_stats) { + peer->peer_stats.rx_stats = + kzalloc(sizeof(*peer->peer_stats.rx_stats), GFP_ATOMIC); + } + rcu_read_unlock(); + list_add(&peer->list, &dp->peers); wake_up(&ab->peer_mapping_wq); + ewma_avg_rssi_init(&peer->avg_rssi); } - ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "htt peer map vdev %d peer %pM id %d\n", vdev_id, mac_addr, peer_id); @@ -625,3 +639,45 @@ void ath12k_dp_link_peer_unassign(struct ath12k_dp *dp, struct ath12k_dp_hw *dp_ synchronize_rcu(); } + +void +ath12k_dp_link_peer_get_sta_rate_info_stats(struct ath12k_dp *dp, const u8 *addr, + struct ath12k_dp_link_peer_rate_info *info) +{ + struct ath12k_dp_link_peer *link_peer; + + guard(spinlock_bh)(&dp->dp_lock); + + link_peer = ath12k_dp_link_peer_find_by_addr(dp, addr); + if (!link_peer) + return; + + info->rx_duration = link_peer->rx_duration; + info->tx_duration = link_peer->tx_duration; + info->txrate.legacy = link_peer->txrate.legacy; + info->txrate.mcs = link_peer->txrate.mcs; + info->txrate.nss = link_peer->txrate.nss; + info->txrate.bw = link_peer->txrate.bw; + info->txrate.he_gi = link_peer->txrate.he_gi; + info->txrate.he_dcm = link_peer->txrate.he_dcm; + info->txrate.he_ru_alloc = link_peer->txrate.he_ru_alloc; + info->txrate.flags = link_peer->txrate.flags; + info->rssi_comb = link_peer->rssi_comb; + info->signal_avg = ewma_avg_rssi_read(&link_peer->avg_rssi); +} + +void ath12k_dp_link_peer_reset_rx_stats(struct ath12k_dp *dp, const u8 *addr) +{ + struct ath12k_rx_peer_stats *rx_stats; + struct ath12k_dp_link_peer *link_peer; + + guard(spinlock_bh)(&dp->dp_lock); + + link_peer = ath12k_dp_link_peer_find_by_addr(dp, addr); + if (!link_peer || !link_peer->peer_stats.rx_stats) + return; + + rx_stats = link_peer->peer_stats.rx_stats; + if (rx_stats) + memset(rx_stats, 0, sizeof(*rx_stats)); +} diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h index f7c995e8c4e32..f9be27d865453 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.h +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h @@ -23,6 +23,51 @@ struct ppdu_user_delayba { #define ATH12K_PEER_ML_ID_VALID BIT(13) +struct ath12k_rx_peer_rate_stats { + u64 ht_mcs_count[HAL_RX_MAX_MCS_HT + 1]; + u64 vht_mcs_count[HAL_RX_MAX_MCS_VHT + 1]; + u64 he_mcs_count[HAL_RX_MAX_MCS_HE + 1]; + u64 be_mcs_count[HAL_RX_MAX_MCS_BE + 1]; + u64 nss_count[HAL_RX_MAX_NSS]; + u64 bw_count[HAL_RX_BW_MAX]; + u64 gi_count[HAL_RX_GI_MAX]; + u64 legacy_count[HAL_RX_MAX_NUM_LEGACY_RATES]; + u64 rx_rate[HAL_RX_BW_MAX][HAL_RX_GI_MAX][HAL_RX_MAX_NSS][HAL_RX_MAX_MCS_HT + 1]; +}; + +struct ath12k_rx_peer_stats { + u64 num_msdu; + u64 num_mpdu_fcs_ok; + u64 num_mpdu_fcs_err; + u64 tcp_msdu_count; + u64 udp_msdu_count; + u64 other_msdu_count; + u64 ampdu_msdu_count; + u64 non_ampdu_msdu_count; + u64 stbc_count; + u64 beamformed_count; + u64 coding_count[HAL_RX_SU_MU_CODING_MAX]; + u64 tid_count[IEEE80211_NUM_TIDS + 1]; + u64 pream_cnt[HAL_RX_PREAMBLE_MAX]; + u64 reception_type[HAL_RX_RECEPTION_TYPE_MAX]; + u64 rx_duration; + u64 dcm_count; + u64 ru_alloc_cnt[HAL_RX_RU_ALLOC_TYPE_MAX]; + struct ath12k_rx_peer_rate_stats pkt_stats; + struct ath12k_rx_peer_rate_stats byte_stats; +}; + +struct ath12k_wbm_tx_stats { + u64 wbm_tx_comp_stats[HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX]; +}; + +struct ath12k_dp_peer_stats { + struct ath12k_rx_peer_stats *rx_stats; + struct ath12k_wbm_tx_stats *wbm_tx_stats; +}; + +DECLARE_EWMA(avg_rssi, 10, 8) + struct ath12k_dp_link_peer { struct list_head list; struct ieee80211_sta *sta; @@ -58,6 +103,17 @@ struct ath12k_dp_link_peer { u8 hw_link_id; u32 rx_tid_active_bitmask; + + /* link stats */ + struct rate_info txrate; + struct rate_info last_txrate; + u64 rx_duration; + u64 tx_duration; + u8 rssi_comb; + struct ewma_avg_rssi avg_rssi; + struct ath12k_dp_peer_stats peer_stats; + u32 tx_retry_failed; + u32 tx_retry_count; }; void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index dbf07c15481b8..69c2e8b318d5b 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -64,6 +64,15 @@ struct ath12k_base; #define HAL_WBM_IDLE_SCATTER_BUF_SIZE (HAL_WBM_IDLE_SCATTER_BUF_SIZE_MAX - \ HAL_WBM_IDLE_SCATTER_NEXT_PTR_SIZE) +#define HAL_AST_IDX_INVALID 0xFFFF +#define HAL_RX_MAX_MCS 12 +#define HAL_RX_MAX_MCS_HT 31 +#define HAL_RX_MAX_MCS_VHT 9 +#define HAL_RX_MAX_MCS_HE 11 +#define HAL_RX_MAX_MCS_BE 15 +#define HAL_RX_MAX_NSS 8 +#define HAL_RX_MAX_NUM_LEGACY_RATES 12 + enum hal_srng_ring_id { HAL_SRNG_RING_ID_REO2SW0 = 0, HAL_SRNG_RING_ID_REO2SW1, diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 86cfb156a2b2c..4b2213a74f94b 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -23,6 +23,7 @@ #include "wow.h" #include "debugfs_sta.h" #include "dp.h" +#include "dp_cmn.h" #define CHAN2G(_channel, _freq, _flags) { \ .band = NL80211_BAND_2GHZ, \ @@ -1237,6 +1238,8 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) list_for_each_entry_safe(peer, tmp, &peers, list) { list_del(&peer->list); + + kfree(peer->peer_stats.rx_stats); kfree(peer); } @@ -6694,14 +6697,13 @@ static void ath12k_mac_station_post_remove(struct ath12k *ar, vif->addr, arvif->vdev_id); peer->sta = NULL; list_del(&peer->list); + + kfree(peer->peer_stats.rx_stats); kfree(peer); ar->num_peers--; } spin_unlock_bh(&dp->dp_lock); - - kfree(arsta->rx_stats); - arsta->rx_stats = NULL; } static int ath12k_mac_station_unauthorize(struct ath12k *ar, @@ -6846,14 +6848,6 @@ static int ath12k_mac_station_add(struct ath12k *ar, goto exit; } - if (ath12k_debugfs_is_extd_rx_stats_enabled(ar) && !arsta->rx_stats) { - arsta->rx_stats = kzalloc(sizeof(*arsta->rx_stats), GFP_KERNEL); - if (!arsta->rx_stats) { - ret = -ENOMEM; - goto dec_num_station; - } - } - spin_lock_bh(&ab->base_lock); /* @@ -6871,7 +6865,7 @@ static int ath12k_mac_station_add(struct ath12k *ar, if (ret) { ath12k_warn(ab, "Failed to add arsta: %pM to hash table, ret: %d", arsta->addr, ret); - goto free_rx_stats; + goto dec_num_station; } peer_param.vdev_id = arvif->vdev_id; @@ -6917,7 +6911,6 @@ static int ath12k_mac_station_add(struct ath12k *ar, } } - ewma_avg_rssi_init(&arsta->avg_rssi); return 0; free_peer: @@ -6925,9 +6918,6 @@ static int ath12k_mac_station_add(struct ath12k *ar, spin_lock_bh(&ab->base_lock); ath12k_link_sta_rhash_delete(ab, arsta); spin_unlock_bh(&ab->base_lock); -free_rx_stats: - kfree(arsta->rx_stats); - arsta->rx_stats = NULL; dec_num_station: ath12k_mac_dec_num_stations(arvif, arsta); exit: @@ -13421,9 +13411,12 @@ void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, struct station_info *sinfo) { struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta); + struct ath12k_dp_link_peer_rate_info rate_info = {}; struct ath12k_fw_stats_req_params params = {}; + struct ath12k_dp_link_peer *peer; struct ath12k_link_sta *arsta; s8 signal, noise_floor; + struct ath12k_dp *dp; struct ath12k *ar; bool db2dbm; @@ -13434,34 +13427,37 @@ void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, if (!ar) return; + dp = ath12k_ab_to_dp(ar->ab); + ath12k_dp_link_peer_get_sta_rate_info_stats(dp, arsta->addr, &rate_info); + db2dbm = test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, ar->ab->wmi_ab.svc_map); - sinfo->rx_duration = arsta->rx_duration; + sinfo->rx_duration = rate_info.rx_duration; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); - sinfo->tx_duration = arsta->tx_duration; + sinfo->tx_duration = rate_info.tx_duration; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_DURATION); - if (arsta->txrate.legacy || arsta->txrate.nss) { - if (arsta->txrate.legacy) { - sinfo->txrate.legacy = arsta->txrate.legacy; + if (rate_info.txrate.legacy || rate_info.txrate.nss) { + if (rate_info.txrate.legacy) { + sinfo->txrate.legacy = rate_info.txrate.legacy; } else { - sinfo->txrate.mcs = arsta->txrate.mcs; - sinfo->txrate.nss = arsta->txrate.nss; - sinfo->txrate.bw = arsta->txrate.bw; - sinfo->txrate.he_gi = arsta->txrate.he_gi; - sinfo->txrate.he_dcm = arsta->txrate.he_dcm; - sinfo->txrate.he_ru_alloc = arsta->txrate.he_ru_alloc; - sinfo->txrate.eht_gi = arsta->txrate.eht_gi; - sinfo->txrate.eht_ru_alloc = arsta->txrate.eht_ru_alloc; - } - sinfo->txrate.flags = arsta->txrate.flags; + sinfo->txrate.mcs = rate_info.txrate.mcs; + sinfo->txrate.nss = rate_info.txrate.nss; + sinfo->txrate.bw = rate_info.txrate.bw; + sinfo->txrate.he_gi = rate_info.txrate.he_gi; + sinfo->txrate.he_dcm = rate_info.txrate.he_dcm; + sinfo->txrate.he_ru_alloc = rate_info.txrate.he_ru_alloc; + sinfo->txrate.eht_gi = rate_info.txrate.eht_gi; + sinfo->txrate.eht_ru_alloc = rate_info.txrate.eht_ru_alloc; + } + sinfo->txrate.flags = rate_info.txrate.flags; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); } /* TODO: Use real NF instead of default one. */ - signal = arsta->rssi_comb; + signal = rate_info.rssi_comb; params.pdev_id = ar->pdev->pdev_id; params.vdev_id = 0; @@ -13491,17 +13487,26 @@ void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); } - sinfo->signal_avg = ewma_avg_rssi_read(&arsta->avg_rssi); + sinfo->signal_avg = rate_info.signal_avg; if (!db2dbm) sinfo->signal_avg += noise_floor; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); - sinfo->tx_retries = arsta->tx_retry_count; - sinfo->tx_failed = arsta->tx_retry_failed; + spin_lock_bh(&dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_addr(dp, arsta->addr); + if (!peer) { + spin_unlock_bh(&dp->dp_lock); + return; + } + + sinfo->tx_retries = peer->tx_retry_count; + sinfo->tx_failed = peer->tx_retry_failed; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); + + spin_unlock_bh(&dp->dp_lock); } EXPORT_SYMBOL(ath12k_mac_op_sta_statistics); @@ -13512,6 +13517,7 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, { struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(link_sta->sta); struct ath12k_fw_stats_req_params params = {}; + struct ath12k_dp_link_peer *peer; struct ath12k_link_sta *arsta; struct ath12k *ar; s8 signal; @@ -13531,33 +13537,40 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, db2dbm = test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, ar->ab->wmi_ab.svc_map); - link_sinfo->rx_duration = arsta->rx_duration; + spin_lock_bh(&ar->ab->dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_addr(ar->ab->dp, arsta->addr); + if (!peer) { + spin_unlock_bh(&ar->ab->dp->dp_lock); + return; + } + + link_sinfo->rx_duration = peer->rx_duration; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); - link_sinfo->tx_duration = arsta->tx_duration; + link_sinfo->tx_duration = peer->tx_duration; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_DURATION); - if (arsta->txrate.legacy || arsta->txrate.nss) { - if (arsta->txrate.legacy) { - link_sinfo->txrate.legacy = arsta->txrate.legacy; + if (peer->txrate.legacy || peer->txrate.nss) { + if (peer->txrate.legacy) { + link_sinfo->txrate.legacy = peer->txrate.legacy; } else { - link_sinfo->txrate.mcs = arsta->txrate.mcs; - link_sinfo->txrate.nss = arsta->txrate.nss; - link_sinfo->txrate.bw = arsta->txrate.bw; - link_sinfo->txrate.he_gi = arsta->txrate.he_gi; - link_sinfo->txrate.he_dcm = arsta->txrate.he_dcm; + link_sinfo->txrate.mcs = peer->txrate.mcs; + link_sinfo->txrate.nss = peer->txrate.nss; + link_sinfo->txrate.bw = peer->txrate.bw; + link_sinfo->txrate.he_gi = peer->txrate.he_gi; + link_sinfo->txrate.he_dcm = peer->txrate.he_dcm; link_sinfo->txrate.he_ru_alloc = - arsta->txrate.he_ru_alloc; - link_sinfo->txrate.eht_gi = arsta->txrate.eht_gi; + peer->txrate.he_ru_alloc; + link_sinfo->txrate.eht_gi = peer->txrate.eht_gi; link_sinfo->txrate.eht_ru_alloc = - arsta->txrate.eht_ru_alloc; + peer->txrate.eht_ru_alloc; } - link_sinfo->txrate.flags = arsta->txrate.flags; + link_sinfo->txrate.flags = peer->txrate.flags; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); } /* TODO: Use real NF instead of default one. */ - signal = arsta->rssi_comb; + signal = peer->rssi_comb; params.pdev_id = ar->pdev->pdev_id; params.vdev_id = 0; @@ -13576,17 +13589,18 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); } - link_sinfo->signal_avg = ewma_avg_rssi_read(&arsta->avg_rssi); + link_sinfo->signal_avg = ewma_avg_rssi_read(&peer->avg_rssi); if (!db2dbm) link_sinfo->signal_avg += ATH12K_DEFAULT_NOISE_FLOOR; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); - link_sinfo->tx_retries = arsta->tx_retry_count; - link_sinfo->tx_failed = arsta->tx_retry_failed; + link_sinfo->tx_retries = peer->tx_retry_count; + link_sinfo->tx_failed = peer->tx_retry_failed; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); + spin_unlock_bh(&ar->ab->dp->dp_lock); } EXPORT_SYMBOL(ath12k_mac_op_link_sta_statistics); diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index 812247decab43..9c100ecea798e 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -7,6 +7,7 @@ #include "core.h" #include "peer.h" #include "debug.h" +#include "debugfs.h" static int ath12k_wait_for_dp_link_peer_common(struct ath12k_base *ab, int vdev_id, const u8 *addr, bool expect_mapped) @@ -50,6 +51,8 @@ void ath12k_peer_cleanup(struct ath12k *ar, u32 vdev_id) peer->addr, vdev_id); list_del(&peer->list); + + kfree(peer->peer_stats.rx_stats); kfree(peer); ar->num_peers--; } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 454d5a7532cfd..737651341afcd 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -517,31 +517,36 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, struct hal_tx_status *ts) { struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_dp_link_peer *peer; struct ath12k_base *ab = dp->ab; - struct ath12k_dp_peer *peer; - struct ieee80211_sta *sta; - struct ath12k_sta *ahsta; struct ath12k_link_sta *arsta; struct rate_info txrate = {}; + struct ieee80211_sta *sta; + struct ath12k_sta *ahsta; u16 rate, ru_tones; u8 rate_idx = 0; int ret; - peer = ath12k_dp_peer_find_by_peerid(dp_pdev, ts->peer_id); + peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, ts->peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DP_TX, "failed to find the peer by id %u\n", ts->peer_id); return; } + + spin_lock_bh(&dp->dp_lock); + sta = peer->sta; ahsta = ath12k_sta_to_ahsta(sta); arsta = &ahsta->deflink; + spin_unlock_bh(&dp->dp_lock); + /* This is to prefer choose the real NSS value arsta->last_txrate.nss, * if it is invalid, then choose the NSS value while assoc. */ - if (arsta->last_txrate.nss) - txrate.nss = arsta->last_txrate.nss; + if (peer->last_txrate.nss) + txrate.nss = peer->last_txrate.nss; else txrate.nss = arsta->peer_nss; @@ -625,9 +630,9 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(ts->tones); } - spin_lock_bh(&ab->base_lock); - arsta->txrate = txrate; - spin_unlock_bh(&ab->base_lock); + spin_lock_bh(&dp->dp_lock); + peer->txrate = txrate; + spin_unlock_bh(&dp->dp_lock); } static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, @@ -646,9 +651,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, s32 noise_floor; struct ieee80211_tx_status status = {}; struct ieee80211_rate_status status_rate = {}; - struct ath12k_dp_peer *peer; - struct ath12k_link_sta *arsta; - struct ath12k_sta *ahsta; + struct ath12k_dp_link_peer *peer; struct rate_info rate; if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) { @@ -743,7 +746,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, ath12k_wifi7_dp_tx_update_txcompl(dp_pdev, ts); - peer = ath12k_dp_peer_find_by_peerid(dp_pdev, ts->peer_id); + peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, ts->peer_id); if (!peer || !peer->sta) { ath12k_err(ab, "dp_tx: failed to find the peer with peer_id %d\n", @@ -751,13 +754,11 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); goto exit; } - ahsta = ath12k_sta_to_ahsta(peer->sta); - arsta = &ahsta->deflink; status.sta = peer->sta; status.info = info; status.skb = msdu; - rate = arsta->last_txrate; + rate = peer->last_txrate; status_rate.rate_idx = rate; status_rate.try_count = 1; From 0ba892d6ad6846fe6e5747f688cb62de037aef1c Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Mon, 3 Nov 2025 16:51:03 +0530 Subject: [PATCH 090/140] wifi: ath12k: Add helper to free DP link peer Introduce ath12k_dp_link_peer_free() to wrap cleanup steps required before freeing a DP link peer. This avoids code duplication and ensures consistent teardown across multiple call flows. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-5-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_peer.c | 13 +++++++++---- drivers/net/wireless/ath/ath12k/dp_peer.h | 1 + drivers/net/wireless/ath/ath12k/mac.c | 9 ++------- drivers/net/wireless/ath/ath12k/peer.c | 5 +---- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index 8961c4635ed0b..0ad01f7414cd6 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -9,6 +9,14 @@ #include "debug.h" #include "debugfs.h" +void ath12k_dp_link_peer_free(struct ath12k_dp_link_peer *peer) +{ + list_del(&peer->list); + + kfree(peer->peer_stats.rx_stats); + kfree(peer); +} + struct ath12k_dp_link_peer * ath12k_dp_link_peer_find_by_vdev_and_addr(struct ath12k_dp *dp, int vdev_id, const u8 *addr) @@ -140,10 +148,7 @@ void ath12k_dp_link_peer_unmap_event(struct ath12k_base *ab, u16 peer_id) ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "htt peer unmap vdev %d peer %pM id %d\n", peer->vdev_id, peer->addr, peer_id); - list_del(&peer->list); - - kfree(peer->peer_stats.rx_stats); - kfree(peer); + ath12k_dp_link_peer_free(peer); wake_up(&ab->peer_mapping_wq); exit: diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h index f9be27d865453..20294ff095131 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.h +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h @@ -178,4 +178,5 @@ struct ath12k_dp_peer *ath12k_dp_peer_find_by_peerid(struct ath12k_pdev_dp *dp_p u16 peer_id); struct ath12k_dp_link_peer * ath12k_dp_link_peer_find_by_peerid(struct ath12k_pdev_dp *dp_pdev, u16 peer_id); +void ath12k_dp_link_peer_free(struct ath12k_dp_link_peer *peer); #endif diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 4b2213a74f94b..39aa131f17dd4 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1237,10 +1237,7 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) synchronize_rcu(); list_for_each_entry_safe(peer, tmp, &peers, list) { - list_del(&peer->list); - - kfree(peer->peer_stats.rx_stats); - kfree(peer); + ath12k_dp_link_peer_free(peer); } ar->num_peers = 0; @@ -6696,10 +6693,8 @@ static void ath12k_mac_station_post_remove(struct ath12k *ar, ath12k_warn(ar->ab, "Found peer entry %pM n vdev %i after it was supposedly removed\n", vif->addr, arvif->vdev_id); peer->sta = NULL; - list_del(&peer->list); - kfree(peer->peer_stats.rx_stats); - kfree(peer); + ath12k_dp_link_peer_free(peer); ar->num_peers--; } diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index 9c100ecea798e..c2fb5bbd6ceae 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -50,10 +50,7 @@ void ath12k_peer_cleanup(struct ath12k *ar, u32 vdev_id) ath12k_warn(ab, "removing stale peer %pM from vdev_id %d\n", peer->addr, vdev_id); - list_del(&peer->list); - - kfree(peer->peer_stats.rx_stats); - kfree(peer); + ath12k_dp_link_peer_free(peer); ar->num_peers--; } From 6fb8ba44615b691dfc7bf97ada11a7f5bb664e3f Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Mon, 3 Nov 2025 16:51:04 +0530 Subject: [PATCH 091/140] wifi: ath12k: Move ieee80211_ops callback to the arch specific module Move the ieee80211_ops Tx callback to the architecture-specific module to avoid additional indirections caused by the common Tx function calling the architecture-specific Tx functions via ops. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-6-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.c | 1 + drivers/net/wireless/ath/ath12k/mac.c | 231 ++---------------- drivers/net/wireless/ath/ath12k/mac.h | 15 +- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 2 + drivers/net/wireless/ath/ath12k/wifi7/hw.c | 208 +++++++++++++++- 5 files changed, 237 insertions(+), 220 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 0ab9a09d43a89..8f6c537348736 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -28,6 +28,7 @@ unsigned int ath12k_debug_mask; module_param_named(debug_mask, ath12k_debug_mask, uint, 0644); MODULE_PARM_DESC(debug_mask, "Debugging mask"); +EXPORT_SYMBOL(ath12k_debug_mask); bool ath12k_ftm_mode; module_param_named(ftm_mode, ath12k_ftm_mode, bool, 0444); diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 39aa131f17dd4..408cf81c5214c 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -9154,8 +9154,8 @@ static void ath12k_mgmt_over_wmi_tx_work(struct wiphy *wiphy, struct wiphy_work } } -static int ath12k_mac_mgmt_tx(struct ath12k *ar, struct sk_buff *skb, - bool is_prb_rsp) +int ath12k_mac_mgmt_tx(struct ath12k *ar, struct sk_buff *skb, + bool is_prb_rsp) { struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue; @@ -9185,11 +9185,12 @@ static int ath12k_mac_mgmt_tx(struct ath12k *ar, struct sk_buff *skb, return 0; } +EXPORT_SYMBOL(ath12k_mac_mgmt_tx); -static void ath12k_mac_add_p2p_noa_ie(struct ath12k *ar, - struct ieee80211_vif *vif, - struct sk_buff *skb, - bool is_prb_rsp) +void ath12k_mac_add_p2p_noa_ie(struct ath12k *ar, + struct ieee80211_vif *vif, + struct sk_buff *skb, + bool is_prb_rsp) { struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); @@ -9206,11 +9207,12 @@ static void ath12k_mac_add_p2p_noa_ie(struct ath12k *ar, spin_unlock_bh(&ar->data_lock); } +EXPORT_SYMBOL(ath12k_mac_add_p2p_noa_ie); /* Note: called under rcu_read_lock() */ -static void ath12k_mlo_mcast_update_tx_link_address(struct ieee80211_vif *vif, - u8 link_id, struct sk_buff *skb, - u32 info_flags) +void ath12k_mlo_mcast_update_tx_link_address(struct ieee80211_vif *vif, + u8 link_id, struct sk_buff *skb, + u32 info_flags) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_bss_conf *bss_conf; @@ -9222,10 +9224,11 @@ static void ath12k_mlo_mcast_update_tx_link_address(struct ieee80211_vif *vif, if (bss_conf) ether_addr_copy(hdr->addr2, bss_conf->addr); } +EXPORT_SYMBOL(ath12k_mlo_mcast_update_tx_link_address); /* Note: called under rcu_read_lock() */ -static u8 ath12k_mac_get_tx_link(struct ieee80211_sta *sta, struct ieee80211_vif *vif, - u8 link, struct sk_buff *skb, u32 info_flags) +u8 ath12k_mac_get_tx_link(struct ieee80211_sta *sta, struct ieee80211_vif *vif, + u8 link, struct sk_buff *skb, u32 info_flags) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); @@ -9320,211 +9323,7 @@ static u8 ath12k_mac_get_tx_link(struct ieee80211_sta *sta, struct ieee80211_vif return link; } - -/* Note: called under rcu_read_lock() */ -void ath12k_mac_op_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) -{ - struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb); - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_vif *vif = info->control.vif; - struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); - struct ath12k_link_vif *arvif = &ahvif->deflink; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_key_conf *key = info->control.hw_key; - struct ieee80211_sta *sta = control->sta; - struct ath12k_link_vif *tmp_arvif; - u32 info_flags = info->flags; - struct sk_buff *msdu_copied; - struct ath12k *ar, *tmp_ar; - struct ath12k_pdev_dp *dp_pdev, *tmp_dp_pdev; - struct ath12k_dp_link_peer *peer; - unsigned long links_map; - bool is_mcast = false; - bool is_dvlan = false; - struct ethhdr *eth; - bool is_prb_rsp; - u16 mcbc_gsn; - u8 link_id; - int ret; - struct ath12k_dp *tmp_dp; - - if (ahvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { - ieee80211_free_txskb(hw, skb); - return; - } - - link_id = u32_get_bits(info->control.flags, IEEE80211_TX_CTRL_MLO_LINK); - memset(skb_cb, 0, sizeof(*skb_cb)); - skb_cb->vif = vif; - - if (key) { - skb_cb->cipher = key->cipher; - skb_cb->flags |= ATH12K_SKB_CIPHER_SET; - } - - /* handle only for MLO case, use deflink for non MLO case */ - if (ieee80211_vif_is_mld(vif)) { - link_id = ath12k_mac_get_tx_link(sta, vif, link_id, skb, info_flags); - if (link_id >= IEEE80211_MLD_MAX_NUM_LINKS) { - ieee80211_free_txskb(hw, skb); - return; - } - } else { - link_id = 0; - } - - arvif = rcu_dereference(ahvif->link[link_id]); - if (!arvif || !arvif->ar) { - ath12k_warn(ahvif->ah, "failed to find arvif link id %u for frame transmission", - link_id); - ieee80211_free_txskb(hw, skb); - return; - } - - ar = arvif->ar; - skb_cb->link_id = link_id; - /* as skb_cb is common currently for dp and mgmt tx processing - * set this in the common mac op tx function. - */ - skb_cb->ar = ar; - is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); - - if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { - eth = (struct ethhdr *)skb->data; - is_mcast = is_multicast_ether_addr(eth->h_dest); - - skb_cb->flags |= ATH12K_SKB_HW_80211_ENCAP; - } else if (ieee80211_is_mgmt(hdr->frame_control)) { - if (sta && sta->mlo) - skb_cb->flags |= ATH12K_SKB_MLO_STA; - - ret = ath12k_mac_mgmt_tx(ar, skb, is_prb_rsp); - if (ret) { - ath12k_warn(ar->ab, "failed to queue management frame %d\n", - ret); - ieee80211_free_txskb(hw, skb); - } - return; - } - - if (!(info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) - is_mcast = is_multicast_ether_addr(hdr->addr1); - - /* This is case only for P2P_GO */ - if (vif->type == NL80211_IFTYPE_AP && vif->p2p) - ath12k_mac_add_p2p_noa_ie(ar, vif, skb, is_prb_rsp); - - dp_pdev = ath12k_dp_to_pdev_dp(ar->ab->dp, ar->pdev_idx); - if (!dp_pdev) { - ieee80211_free_txskb(hw, skb); - return; - } - - /* Checking if it is a DVLAN frame */ - if (!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && - !(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) && - !(skb_cb->flags & ATH12K_SKB_CIPHER_SET) && - ieee80211_has_protected(hdr->frame_control)) - is_dvlan = true; - - if (!vif->valid_links || !is_mcast || is_dvlan || - (skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) || - test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags)) { - ret = ath12k_wifi7_dp_tx(dp_pdev, arvif, skb, false, 0, is_mcast); - if (unlikely(ret)) { - ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret); - ieee80211_free_txskb(ar->ah->hw, skb); - return; - } - } else { - mcbc_gsn = atomic_inc_return(&ahvif->dp_vif.mcbc_gsn) & 0xfff; - - links_map = ahvif->links_map; - for_each_set_bit(link_id, &links_map, - IEEE80211_MLD_MAX_NUM_LINKS) { - tmp_arvif = rcu_dereference(ahvif->link[link_id]); - if (!tmp_arvif || !tmp_arvif->is_up) - continue; - - tmp_ar = tmp_arvif->ar; - tmp_dp_pdev = ath12k_dp_to_pdev_dp(tmp_ar->ab->dp, - tmp_ar->pdev_idx); - if (!tmp_dp_pdev) - continue; - msdu_copied = skb_copy(skb, GFP_ATOMIC); - if (!msdu_copied) { - ath12k_err(ar->ab, - "skb copy failure link_id 0x%X vdevid 0x%X\n", - link_id, tmp_arvif->vdev_id); - continue; - } - - ath12k_mlo_mcast_update_tx_link_address(vif, link_id, - msdu_copied, - info_flags); - - skb_cb = ATH12K_SKB_CB(msdu_copied); - skb_cb->link_id = link_id; - skb_cb->vif = vif; - skb_cb->ar = tmp_ar; - - /* For open mode, skip peer find logic */ - if (unlikely(!ahvif->dp_vif.key_cipher)) - goto skip_peer_find; - - tmp_dp = ath12k_ab_to_dp(tmp_ar->ab); - spin_lock_bh(&tmp_dp->dp_lock); - peer = ath12k_dp_link_peer_find_by_addr(tmp_dp, - tmp_arvif->bssid); - if (!peer || !peer->dp_peer) { - spin_unlock_bh(&tmp_dp->dp_lock); - ath12k_warn(tmp_ar->ab, - "failed to find peer for vdev_id 0x%X addr %pM link_map 0x%X\n", - tmp_arvif->vdev_id, tmp_arvif->bssid, - ahvif->links_map); - dev_kfree_skb_any(msdu_copied); - continue; - } - - key = peer->dp_peer->keys[peer->dp_peer->mcast_keyidx]; - if (key) { - skb_cb->cipher = key->cipher; - skb_cb->flags |= ATH12K_SKB_CIPHER_SET; - - hdr = (struct ieee80211_hdr *)msdu_copied->data; - if (!ieee80211_has_protected(hdr->frame_control)) - hdr->frame_control |= - cpu_to_le16(IEEE80211_FCTL_PROTECTED); - } - spin_unlock_bh(&tmp_dp->dp_lock); - -skip_peer_find: - ret = ath12k_wifi7_dp_tx(tmp_dp_pdev, tmp_arvif, - msdu_copied, true, mcbc_gsn, is_mcast); - if (unlikely(ret)) { - if (ret == -ENOMEM) { - /* Drops are expected during heavy multicast - * frame flood. Print with debug log - * level to avoid lot of console prints - */ - ath12k_dbg(ar->ab, ATH12K_DBG_MAC, - "failed to transmit frame %d\n", - ret); - } else { - ath12k_warn(ar->ab, - "failed to transmit frame %d\n", - ret); - } - - dev_kfree_skb_any(msdu_copied); - } - } - ieee80211_free_txskb(ar->ah->hw, skb); - } -} -EXPORT_SYMBOL(ath12k_mac_op_tx); +EXPORT_SYMBOL(ath12k_mac_get_tx_link); void ath12k_mac_drain_tx(struct ath12k *ar) { diff --git a/drivers/net/wireless/ath/ath12k/mac.h b/drivers/net/wireless/ath/ath12k/mac.h index ed7ad3ca4f407..422bd3b095cd2 100644 --- a/drivers/net/wireless/ath/ath12k/mac.h +++ b/drivers/net/wireless/ath/ath12k/mac.h @@ -204,9 +204,6 @@ void ath12k_mac_update_freq_range(struct ath12k *ar, void ath12k_mac_fill_reg_tpc_info(struct ath12k *ar, struct ath12k_link_vif *arvif, struct ieee80211_chanctx_conf *ctx); -void ath12k_mac_op_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb); int ath12k_mac_op_start(struct ieee80211_hw *hw); void ath12k_mac_op_stop(struct ieee80211_hw *hw, bool suspend); void @@ -330,4 +327,16 @@ int ath12k_mac_op_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, unsigned int link_id, int *dbm); +int ath12k_mac_mgmt_tx(struct ath12k *ar, struct sk_buff *skb, + bool is_prb_rsp); +void ath12k_mac_add_p2p_noa_ie(struct ath12k *ar, + struct ieee80211_vif *vif, + struct sk_buff *skb, + bool is_prb_rsp); +u8 ath12k_mac_get_tx_link(struct ieee80211_sta *sta, struct ieee80211_vif *vif, + u8 link, struct sk_buff *skb, u32 info_flags); + +void ath12k_mlo_mcast_update_tx_link_address(struct ieee80211_vif *vif, + u8 link_id, struct sk_buff *skb, + u32 info_flags); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 737651341afcd..7e16bc12e36ac 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -57,6 +57,7 @@ static int ath12k_wifi7_dp_prepare_htt_metadata(struct sk_buff *skb) return 0; } +/* TODO: Remove the export once this file is built with wifi7 ko */ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *arvif, struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, bool is_mcast) @@ -378,6 +379,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a return ret; } +EXPORT_SYMBOL(ath12k_wifi7_dp_tx); static void ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 946771b96fb58..1f5dda73230d0 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -24,6 +24,7 @@ #include "../debugfs_sta.h" #include "../testmode.h" #include "hal.h" +#include "dp_tx.h" static const guid_t wcn7850_uuid = GUID_INIT(0xf634f534, 0x6147, 0x11ec, 0x90, 0xd6, 0x02, 0x42, @@ -653,8 +654,213 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { }, }; +/* Note: called under rcu_read_lock() */ +static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw, + struct ieee80211_tx_control *control, + struct sk_buff *skb) +{ + struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb); + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_vif *vif = info->control.vif; + struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); + struct ath12k_link_vif *arvif = &ahvif->deflink; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_key_conf *key = info->control.hw_key; + struct ieee80211_sta *sta = control->sta; + struct ath12k_link_vif *tmp_arvif; + u32 info_flags = info->flags; + struct sk_buff *msdu_copied; + struct ath12k *ar, *tmp_ar; + struct ath12k_pdev_dp *dp_pdev, *tmp_dp_pdev; + struct ath12k_dp_link_peer *peer; + unsigned long links_map; + bool is_mcast = false; + bool is_dvlan = false; + struct ethhdr *eth; + bool is_prb_rsp; + u16 mcbc_gsn; + u8 link_id; + int ret; + struct ath12k_dp *tmp_dp; + + if (ahvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { + ieee80211_free_txskb(hw, skb); + return; + } + + link_id = u32_get_bits(info->control.flags, IEEE80211_TX_CTRL_MLO_LINK); + memset(skb_cb, 0, sizeof(*skb_cb)); + skb_cb->vif = vif; + + if (key) { + skb_cb->cipher = key->cipher; + skb_cb->flags |= ATH12K_SKB_CIPHER_SET; + } + + /* handle only for MLO case, use deflink for non MLO case */ + if (ieee80211_vif_is_mld(vif)) { + link_id = ath12k_mac_get_tx_link(sta, vif, link_id, skb, info_flags); + if (link_id >= IEEE80211_MLD_MAX_NUM_LINKS) { + ieee80211_free_txskb(hw, skb); + return; + } + } else { + link_id = 0; + } + + arvif = rcu_dereference(ahvif->link[link_id]); + if (!arvif || !arvif->ar) { + ath12k_warn(ahvif->ah, "failed to find arvif link id %u for frame transmission", + link_id); + ieee80211_free_txskb(hw, skb); + return; + } + + ar = arvif->ar; + skb_cb->link_id = link_id; + /* + * as skb_cb is common currently for dp and mgmt tx processing + * set this in the common mac op tx function. + */ + skb_cb->ar = ar; + is_prb_rsp = ieee80211_is_probe_resp(hdr->frame_control); + + if (info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { + eth = (struct ethhdr *)skb->data; + is_mcast = is_multicast_ether_addr(eth->h_dest); + + skb_cb->flags |= ATH12K_SKB_HW_80211_ENCAP; + } else if (ieee80211_is_mgmt(hdr->frame_control)) { + if (sta && sta->mlo) + skb_cb->flags |= ATH12K_SKB_MLO_STA; + + ret = ath12k_mac_mgmt_tx(ar, skb, is_prb_rsp); + if (ret) { + ath12k_warn(ar->ab, "failed to queue management frame %d\n", + ret); + ieee80211_free_txskb(hw, skb); + } + return; + } + + if (!(info_flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) + is_mcast = is_multicast_ether_addr(hdr->addr1); + + /* This is case only for P2P_GO */ + if (vif->type == NL80211_IFTYPE_AP && vif->p2p) + ath12k_mac_add_p2p_noa_ie(ar, vif, skb, is_prb_rsp); + + dp_pdev = ath12k_dp_to_pdev_dp(ar->ab->dp, ar->pdev_idx); + if (!dp_pdev) { + ieee80211_free_txskb(hw, skb); + return; + } + + /* Checking if it is a DVLAN frame */ + if (!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) && + !(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) && + !(skb_cb->flags & ATH12K_SKB_CIPHER_SET) && + ieee80211_has_protected(hdr->frame_control)) + is_dvlan = true; + + if (!vif->valid_links || !is_mcast || is_dvlan || + (skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) || + test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags)) { + ret = ath12k_wifi7_dp_tx(dp_pdev, arvif, skb, false, 0, is_mcast); + if (unlikely(ret)) { + ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret); + ieee80211_free_txskb(ar->ah->hw, skb); + return; + } + } else { + mcbc_gsn = atomic_inc_return(&ahvif->dp_vif.mcbc_gsn) & 0xfff; + + links_map = ahvif->links_map; + for_each_set_bit(link_id, &links_map, + IEEE80211_MLD_MAX_NUM_LINKS) { + tmp_arvif = rcu_dereference(ahvif->link[link_id]); + if (!tmp_arvif || !tmp_arvif->is_up) + continue; + + tmp_ar = tmp_arvif->ar; + tmp_dp_pdev = ath12k_dp_to_pdev_dp(tmp_ar->ab->dp, + tmp_ar->pdev_idx); + if (!tmp_dp_pdev) + continue; + msdu_copied = skb_copy(skb, GFP_ATOMIC); + if (!msdu_copied) { + ath12k_err(ar->ab, + "skb copy failure link_id 0x%X vdevid 0x%X\n", + link_id, tmp_arvif->vdev_id); + continue; + } + + ath12k_mlo_mcast_update_tx_link_address(vif, link_id, + msdu_copied, + info_flags); + + skb_cb = ATH12K_SKB_CB(msdu_copied); + skb_cb->link_id = link_id; + skb_cb->vif = vif; + skb_cb->ar = tmp_ar; + + /* For open mode, skip peer find logic */ + if (unlikely(!ahvif->dp_vif.key_cipher)) + goto skip_peer_find; + + tmp_dp = ath12k_ab_to_dp(tmp_ar->ab); + spin_lock_bh(&tmp_dp->dp_lock); + peer = ath12k_dp_link_peer_find_by_addr(tmp_dp, + tmp_arvif->bssid); + if (!peer || !peer->dp_peer) { + spin_unlock_bh(&tmp_dp->dp_lock); + ath12k_warn(tmp_ar->ab, + "failed to find peer for vdev_id 0x%X addr %pM link_map 0x%X\n", + tmp_arvif->vdev_id, tmp_arvif->bssid, + ahvif->links_map); + dev_kfree_skb_any(msdu_copied); + continue; + } + + key = peer->dp_peer->keys[peer->dp_peer->mcast_keyidx]; + if (key) { + skb_cb->cipher = key->cipher; + skb_cb->flags |= ATH12K_SKB_CIPHER_SET; + + hdr = (struct ieee80211_hdr *)msdu_copied->data; + if (!ieee80211_has_protected(hdr->frame_control)) + hdr->frame_control |= + cpu_to_le16(IEEE80211_FCTL_PROTECTED); + } + spin_unlock_bh(&tmp_dp->dp_lock); + +skip_peer_find: + ret = ath12k_wifi7_dp_tx(tmp_dp_pdev, tmp_arvif, + msdu_copied, true, mcbc_gsn, is_mcast); + if (unlikely(ret)) { + if (ret == -ENOMEM) { + /* Drops are expected during heavy multicast + * frame flood. Print with debug log + * level to avoid lot of console prints + */ + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, + "failed to transmit frame %d\n", + ret); + } else { + ath12k_warn(ar->ab, + "failed to transmit frame %d\n", + ret); + } + + dev_kfree_skb_any(msdu_copied); + } + } + ieee80211_free_txskb(ar->ah->hw, skb); + } +} + static const struct ieee80211_ops ath12k_ops_wifi7 = { - .tx = ath12k_mac_op_tx, + .tx = ath12k_wifi7_mac_op_tx, .wake_tx_queue = ieee80211_handle_wake_tx_queue, .start = ath12k_mac_op_start, .stop = ath12k_mac_op_stop, From 83aa9dd228f8253c32cf60d23a1bd3a46752c603 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Mon, 3 Nov 2025 16:51:05 +0530 Subject: [PATCH 092/140] wifi: ath12k: Remove the wifi7 header inclusions in common code As a precursor to the movement of wifi7 specific .c files to ath12k_wifi7.ko module, remove the wifi7 headers included in the common .c files except for dp_mon.c file, as the changes for moving the code from common to wifi7 directory for monitor will be coming incrementally. Since, dp_mon.c continues to be part of ath12k.ko module, add a few callbacks in hal_ops to facilitate calls from dp_mon.c to reach hal APIs present in ath12k_wifi7.ko module Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-7-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/ahb.c | 1 - drivers/net/wireless/ath/ath12k/core.c | 1 - drivers/net/wireless/ath/ath12k/core.h | 1 - drivers/net/wireless/ath/ath12k/dp.h | 1 - drivers/net/wireless/ath/ath12k/dp_mon.c | 45 ++++++++------ drivers/net/wireless/ath/ath12k/dp_rx.c | 1 - drivers/net/wireless/ath/ath12k/dp_rx.h | 14 ----- drivers/net/wireless/ath/ath12k/hal.c | 18 ++++++ drivers/net/wireless/ath/ath12k/hal.h | 60 +++++++++++++++++++ drivers/net/wireless/ath/ath12k/mac.c | 1 - .../net/wireless/ath/ath12k/wifi7/hal_desc.h | 46 -------------- .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 2 + .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 19 +++--- .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 15 ++--- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 2 + 15 files changed, 129 insertions(+), 98 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c index 2628d53845eb8..9a4d34e491044 100644 --- a/drivers/net/wireless/ath/ath12k/ahb.c +++ b/drivers/net/wireless/ath/ath12k/ahb.c @@ -15,7 +15,6 @@ #include "ahb.h" #include "debug.h" #include "hif.h" -#include "wifi7/dp.h" #define ATH12K_IRQ_CE0_OFFSET 4 #define ATH12K_MAX_UPDS 1 diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 8f6c537348736..e4c3fdb504832 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -15,7 +15,6 @@ #include "core.h" #include "dp_tx.h" #include "dp_rx.h" -#include "wifi7/dp_rx.h" #include "debug.h" #include "debugfs.h" #include "fw.h" diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 8a1abd5049144..31d5d10beb85a 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -27,7 +27,6 @@ #include "ce.h" #include "mac.h" #include "hw.h" -#include "wifi7/hal_desc.h" #include "reg.h" #include "dbring.h" #include "fw.h" diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 1068a130fc82c..813a9e2a47ce7 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -11,7 +11,6 @@ #include "dp_htt.h" #include "dp_cmn.h" #include -#include "wifi7/hal_desc.h" #define MAX_RXDMA_PER_PDEV 2 diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 3b667c8fbe85c..eee877e3680b2 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -17,6 +17,16 @@ #define ATH12K_LE64_DEC_ENC(value, dec_bits, enc_bits) \ u32_encode_bits(le64_get_bits(value, dec_bits), enc_bits) +static bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, + struct hal_rx_desc *rx_desc) +{ + u32 tlv_tag; + + tlv_tag = ab->hal.ops->rx_desc_get_mpdu_start_tag(rx_desc); + + return tlv_tag == HAL_RX_MPDU_START; +} + static void ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, struct hal_rx_user_status *rx_user_status) @@ -1842,7 +1852,7 @@ ath12k_dp_rx_mon_buf_done(struct ath12k_base *ab, struct hal_srng *srng, if (!status_desc) return DP_MON_STATUS_NO_DMA; - ath12k_wifi7_hal_rx_buf_addr_info_get(status_desc, &paddr, &cookie, &rbm); + ath12k_hal_rx_buf_addr_info_get(&ab->hal, status_desc, &paddr, &cookie, &rbm); buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); @@ -1886,7 +1896,8 @@ static u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id) } static -void ath12k_dp_mon_next_link_desc_get(struct hal_rx_msdu_link *msdu_link, +void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, + struct hal_rx_msdu_link *msdu_link, dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm, struct ath12k_buffer_addr **pp_buf_addr_info) { @@ -1894,7 +1905,7 @@ void ath12k_dp_mon_next_link_desc_get(struct hal_rx_msdu_link *msdu_link, buf_addr_info = &msdu_link->buf_addr_info; - ath12k_wifi7_hal_rx_buf_addr_info_get(buf_addr_info, paddr, sw_cookie, rbm); + ath12k_hal_rx_buf_addr_info_get(&ab->hal, buf_addr_info, paddr, sw_cookie, rbm); *pp_buf_addr_info = buf_addr_info; } @@ -2781,7 +2792,7 @@ int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, num_remain--; - ath12k_wifi7_hal_rx_buf_addr_info_set(desc, paddr, cookie, mgr); + ath12k_hal_rx_buf_addr_info_set(&ab->hal, desc, paddr, cookie, mgr); } ath12k_hal_srng_access_end(ab, srng); @@ -3982,8 +3993,8 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, pmon->buf_state = DP_MON_STATUS_REPLINISH; break; } - ath12k_wifi7_hal_rx_buf_addr_info_get(rx_mon_status_desc, &paddr, - &cookie, &rbm); + ath12k_hal_rx_buf_addr_info_get(&ab->hal, rx_mon_status_desc, &paddr, + &cookie, &rbm); if (paddr) { buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); @@ -4068,8 +4079,8 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, if (!skb) { ath12k_warn(ab, "failed to alloc buffer for status ring\n"); - ath12k_wifi7_hal_rx_buf_addr_info_set(rx_mon_status_desc, 0, 0, - hal_params->rx_buf_rbm); + ath12k_hal_rx_buf_addr_info_set(&ab->hal, rx_mon_status_desc, + 0, 0, hal_params->rx_buf_rbm); num_buffs_reaped++; break; } @@ -4078,9 +4089,8 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, cookie = u32_encode_bits(mac_id, DP_RXDMA_BUF_COOKIE_PDEV_ID) | u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID); - ath12k_wifi7_hal_rx_buf_addr_info_set(rx_mon_status_desc, rxcb->paddr, - cookie, - hal_params->rx_buf_rbm); + ath12k_hal_rx_buf_addr_info_set(&ab->hal, rx_mon_status_desc, rxcb->paddr, + cookie, hal_params->rx_buf_rbm); ath12k_hal_srng_src_get_next_entry(ab, srng); num_buffs_reaped++; } @@ -4118,7 +4128,7 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, dma_addr_t paddr; u8 rbm; - ath12k_hal_rx_reo_ent_buf_paddr_get(ring_entry, &paddr, + ath12k_hal_rx_reo_ent_buf_paddr_get(&ab->hal, ring_entry, &paddr, &sw_cookie, &p_last_buf_addr_info, &rbm, &msdu_cnt); @@ -4154,7 +4164,7 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, dp->link_desc_banks[desc_bank].vaddr + (paddr - dp->link_desc_banks[desc_bank].paddr); - ath12k_hal_rx_msdu_list_get(ar, msdu_link_desc, &msdu_list, + ath12k_hal_rx_msdu_list_get(&ar->ab->hal, ar, msdu_link_desc, &msdu_list, &num_msdus); desc_info = ath12k_dp_get_rx_desc(ar->ab, msdu_list.sw_cookie[num_msdus - 1]); @@ -4251,14 +4261,15 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, list_add_tail(&desc_info->list, used_list); } - ath12k_wifi7_hal_rx_buf_addr_info_set(&buf_info, paddr, sw_cookie, rbm); + ath12k_hal_rx_buf_addr_info_set(&ab->hal, &buf_info, paddr, + sw_cookie, rbm); - ath12k_dp_mon_next_link_desc_get(msdu_link_desc, &paddr, + ath12k_dp_mon_next_link_desc_get(ab, msdu_link_desc, &paddr, &sw_cookie, &rbm, &p_buf_addr_info); - ath12k_wifi7_dp_rx_link_desc_return(ar->ab, &buf_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + ath12k_dp_arch_rx_link_desc_return(ar->ab->dp, &buf_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); p_last_buf_addr_info = p_buf_addr_info; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 49c1e35aa0c46..129031e6b6484 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -12,7 +12,6 @@ #include "debug.h" #include "hw.h" #include "dp_rx.h" -#include "wifi7/dp_rx.h" #include "dp_tx.h" #include "peer.h" #include "dp_mon.h" diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 4a93331dff579..f413834eff892 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -150,16 +150,6 @@ static inline u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, return ab->hal.ops->rx_desc_get_mpdu_ppdu_id(rx_desc); } -static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, - struct hal_rx_desc *rx_desc) -{ - u32 tlv_tag; - - tlv_tag = ab->hal.ops->rx_desc_get_mpdu_start_tag(rx_desc); - - return tlv_tag == HAL_RX_MPDU_START; -} - static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab, struct hal_rx_desc *desc, struct ieee80211_hdr *hdr) @@ -258,10 +248,6 @@ u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab, int ath12k_dp_rx_crypto_mic_len(struct ath12k_dp *dp, enum hal_encrypt_type enctype); u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); -bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, - struct hal_rx_desc *rx_desc); -bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, - struct hal_rx_desc *rx_desc); void ath12k_dp_rx_h_ppdu(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_desc_data *rx_info); struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 3f9c2183c9a69..08063d1094ae1 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -116,6 +116,24 @@ void ath12k_hal_rx_buf_addr_info_get(struct ath12k_hal *hal, hal->ops->rx_buf_addr_info_get(binfo, paddr, msdu_cookies, rbm); } +void ath12k_hal_rx_msdu_list_get(struct ath12k_hal *hal, struct ath12k *ar, + void *link_desc, + void *msdu_list, + u16 *num_msdus) +{ + hal->ops->rx_msdu_list_get(ar, link_desc, msdu_list, num_msdus); +} + +void ath12k_hal_rx_reo_ent_buf_paddr_get(struct ath12k_hal *hal, void *rx_desc, + dma_addr_t *paddr, + u32 *sw_cookie, + struct ath12k_buffer_addr **pp_buf_addr, + u8 *rbm, u32 *msdu_cnt) +{ + hal->ops->rx_reo_ent_buf_paddr_get(rx_desc, paddr, sw_cookie, + pp_buf_addr, rbm, msdu_cnt); +} + void ath12k_hal_cc_config(struct ath12k_base *ab) { ab->hal.ops->cc_config(ab); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 69c2e8b318d5b..29bcedca0a3b0 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -927,6 +927,51 @@ struct hal_srng { } u; }; +/* hal_wbm_link_desc + * + * Producer: WBM + * Consumer: WBM + * + * buf_addr_info + * Details of the physical address of a buffer or MSDU + * link descriptor. + */ + +enum hal_wbm_rel_src_module { + HAL_WBM_REL_SRC_MODULE_TQM, + HAL_WBM_REL_SRC_MODULE_RXDMA, + HAL_WBM_REL_SRC_MODULE_REO, + HAL_WBM_REL_SRC_MODULE_FW, + HAL_WBM_REL_SRC_MODULE_SW, + HAL_WBM_REL_SRC_MODULE_MAX, +}; + +/* hal_wbm_rel_desc_type + * + * msdu_buffer + * The address points to an MSDU buffer + * + * msdu_link_descriptor + * The address points to an Tx MSDU link descriptor + * + * mpdu_link_descriptor + * The address points to an MPDU link descriptor + * + * msdu_ext_descriptor + * The address points to an MSDU extension descriptor + * + * queue_ext_descriptor + * The address points to an TQM queue extension descriptor. WBM should + * treat this is the same way as a link descriptor. + */ +enum hal_wbm_rel_desc_type { + HAL_WBM_REL_DESC_TYPE_REL_MSDU, + HAL_WBM_REL_DESC_TYPE_MSDU_LINK, + HAL_WBM_REL_DESC_TYPE_MPDU_LINK, + HAL_WBM_REL_DESC_TYPE_MSDU_EXT, + HAL_WBM_REL_DESC_TYPE_QUEUE_EXT, +}; + /* Interrupt mitigation - Batch threshold in terms of number of frames */ #define HAL_SRNG_INT_BATCH_THRESHOLD_TX 256 #define HAL_SRNG_INT_BATCH_THRESHOLD_RX 128 @@ -1335,6 +1380,14 @@ struct hal_ops { void (*cc_config)(struct ath12k_base *ab); enum hal_rx_buf_return_buf_manager (*get_idle_link_rbm)(struct ath12k_hal *hal, u8 device_id); + void (*rx_msdu_list_get)(struct ath12k *ar, + void *link_desc, + void *msdu_list, + u16 *num_msdus); + void (*rx_reo_ent_buf_paddr_get)(void *rx_desc, dma_addr_t *paddr, + u32 *sw_cookie, + struct ath12k_buffer_addr **pp_buf_addr, + u8 *rbm, u32 *msdu_cnt); }; dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab, @@ -1417,4 +1470,11 @@ void ath12k_hal_rx_buf_addr_info_get(struct ath12k_hal *hal, void ath12k_hal_cc_config(struct ath12k_base *ab); enum hal_rx_buf_return_buf_manager ath12k_hal_get_idle_link_rbm(struct ath12k_hal *hal, u8 device_id); +void ath12k_hal_rx_msdu_list_get(struct ath12k_hal *hal, struct ath12k *ar, + void *link_desc, void *msdu_list, + u16 *num_msdus); +void ath12k_hal_rx_reo_ent_buf_paddr_get(struct ath12k_hal *hal, void *rx_desc, + dma_addr_t *paddr, u32 *sw_cookie, + struct ath12k_buffer_addr **pp_buf_addr, + u8 *rbm, u32 *msdu_cnt); #endif diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 408cf81c5214c..ab0e67bca11d8 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -14,7 +14,6 @@ #include "wmi.h" #include "hw.h" #include "dp_tx.h" -#include "wifi7/dp_tx.h" #include "dp_rx.h" #include "testmode.h" #include "peer.h" diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h index 57940d7ffba48..63c62a6de6400 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h @@ -1597,52 +1597,6 @@ struct hal_wbm_link_desc { struct ath12k_buffer_addr buf_addr_info; } __packed; -/* hal_wbm_link_desc - * - * Producer: WBM - * Consumer: WBM - * - * buf_addr_info - * Details of the physical address of a buffer or MSDU - * link descriptor. - */ - -enum hal_wbm_rel_src_module { - HAL_WBM_REL_SRC_MODULE_TQM, - HAL_WBM_REL_SRC_MODULE_RXDMA, - HAL_WBM_REL_SRC_MODULE_REO, - HAL_WBM_REL_SRC_MODULE_FW, - HAL_WBM_REL_SRC_MODULE_SW, - HAL_WBM_REL_SRC_MODULE_MAX, -}; - -enum hal_wbm_rel_desc_type { - HAL_WBM_REL_DESC_TYPE_REL_MSDU, - HAL_WBM_REL_DESC_TYPE_MSDU_LINK, - HAL_WBM_REL_DESC_TYPE_MPDU_LINK, - HAL_WBM_REL_DESC_TYPE_MSDU_EXT, - HAL_WBM_REL_DESC_TYPE_QUEUE_EXT, -}; - -/* hal_wbm_rel_desc_type - * - * msdu_buffer - * The address points to an MSDU buffer - * - * msdu_link_descriptor - * The address points to an Tx MSDU link descriptor - * - * mpdu_link_descriptor - * The address points to an MPDU link descriptor - * - * msdu_ext_descriptor - * The address points to an MSDU extension descriptor - * - * queue_ext_descriptor - * The address points to an TQM queue extension descriptor. WBM should - * treat this is the same way as a link descriptor. - */ - #define HAL_WBM_COMPL_RX_INFO0_REL_SRC_MODULE GENMASK(2, 0) #define HAL_WBM_COMPL_RX_INFO0_BM_ACTION GENMASK(5, 3) #define HAL_WBM_COMPL_RX_INFO0_DESC_TYPE GENMASK(8, 6) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 3ccd689bbf1ca..f13376b7faa1f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1026,5 +1026,7 @@ const struct hal_ops hal_qcn9274_ops = { .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, .cc_config = ath12k_wifi7_hal_cc_config, .get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm, + .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, + .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, }; EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index 185cb9a9544aa..e85da9b1db96e 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -453,10 +453,10 @@ void ath12k_wifi7_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab, *cookie = le32_get_bits(buff_addr->info1, BUFFER_ADDR_INFO1_SW_COOKIE); } -void ath12k_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr, - u32 *sw_cookie, - struct ath12k_buffer_addr **pp_buf_addr, - u8 *rbm, u32 *msdu_cnt) +void ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr, + u32 *sw_cookie, + struct ath12k_buffer_addr **pp_buf_addr, + u8 *rbm, u32 *msdu_cnt) { struct hal_reo_entrance_ring *reo_ent_ring = (struct hal_reo_entrance_ring *)rx_desc; @@ -484,11 +484,14 @@ void ath12k_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr, *pp_buf_addr = (void *)buf_addr_info; } -void ath12k_hal_rx_msdu_list_get(struct ath12k *ar, - struct hal_rx_msdu_link *link_desc, - struct hal_rx_msdu_list *msdu_list, - u16 *num_msdus) +void ath12k_wifi7_hal_rx_msdu_list_get(struct ath12k *ar, + void *link_desc_opaque, + void *msdu_list_opaque, u16 *num_msdus) { + struct hal_rx_msdu_link *link_desc = + (struct hal_rx_msdu_link *)link_desc_opaque; + struct hal_rx_msdu_list *msdu_list = + (struct hal_rx_msdu_list *)msdu_list_opaque; struct hal_rx_msdu_details *msdu_details = NULL; struct rx_msdu_desc *msdu_desc_info = NULL; u32 last = 0, first = 0; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index 5536f5bf2a2bf..a2498c6257268 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -868,13 +868,14 @@ int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, void ath12k_wifi7_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab, struct ath12k_buffer_addr *buff_addr, dma_addr_t *paddr, u32 *cookie); -void ath12k_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr, u32 *sw_cookie, - struct ath12k_buffer_addr **pp_buf_addr, - u8 *rbm, u32 *msdu_cnt); -void ath12k_hal_rx_msdu_list_get(struct ath12k *ar, - struct hal_rx_msdu_link *link_desc, - struct hal_rx_msdu_list *msdu_list, - u16 *num_msdus); +void ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr, + u32 *sw_cookie, + struct ath12k_buffer_addr **pp_buf_addr, + u8 *rbm, u32 *msdu_cnt); +void ath12k_wifi7_hal_rx_msdu_list_get(struct ath12k *ar, + void *link_desc, + void *msdu_list_opaque, + u16 *num_msdus); void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, struct hal_srng *srng); void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 8966de3d64a41..a73e7539a27ab 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -799,5 +799,7 @@ const struct hal_ops hal_wcn7850_ops = { .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, .cc_config = ath12k_wifi7_hal_cc_config, .get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm, + .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, + .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, }; EXPORT_SYMBOL(hal_wcn7850_ops); From b148060a836e0f622788740cff80593c265fcdc0 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Mon, 3 Nov 2025 16:51:06 +0530 Subject: [PATCH 093/140] wifi: ath12k: Move ath12k_dp_rx_frags_cleanup API to Wi-Fi 7 The API ath12k_dp_rx_frags_cleanup uses rx hw structure that is specific to Wi-Fi 7. Hence move the API to Wi-Fi 7 and use ops infra to reach it from the common code. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-8-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.h | 10 +++++++ drivers/net/wireless/ath/ath12k/dp_rx.c | 28 ++--------------- drivers/net/wireless/ath/ath12k/dp_rx.h | 2 -- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 1 + drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 30 +++++++++++++++++-- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 2 ++ 6 files changed, 42 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 813a9e2a47ce7..2c77dc636ecfb 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -408,6 +408,8 @@ struct ath12k_dp_arch_ops { int (*rx_link_desc_return)(struct ath12k_base *ab, struct ath12k_buffer_addr *buf_addr_info, enum hal_wbm_rel_bm_act action); + void (*rx_frags_cleanup)(struct ath12k_dp_rx_tid *rx_tid, + bool rel_link_desc); int (*peer_rx_tid_reo_update)(struct ath12k_dp *dp, struct ath12k_dp_link_peer *peer, struct ath12k_dp_rx_tid *rx_tid, @@ -592,6 +594,14 @@ int ath12k_dp_arch_rx_link_desc_return(struct ath12k_dp *dp, return dp->ops->rx_link_desc_return(dp->ab, buf_addr_info, action); } +static inline +void ath12k_dp_arch_rx_frags_cleanup(struct ath12k_dp *dp, + struct ath12k_dp_rx_tid *rx_tid, + bool rel_link_desc) +{ + dp->ops->rx_frags_cleanup(rx_tid, rel_link_desc); +} + static inline int ath12k_dp_arch_peer_rx_tid_reo_update(struct ath12k_dp *dp, struct ath12k_dp_link_peer *peer, struct ath12k_dp_rx_tid *rx_tid, diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 129031e6b6484..c34de4a390529 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -497,30 +497,6 @@ static int ath12k_dp_rx_tid_delete_handler(struct ath12k_base *ab, ath12k_dp_rx_tid_del_func); } -void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, - bool rel_link_desc) -{ - enum hal_wbm_rel_bm_act act = HAL_WBM_REL_BM_ACT_PUT_IN_IDLE; - struct ath12k_buffer_addr *buf_addr_info; - struct ath12k_dp *dp = rx_tid->dp; - - lockdep_assert_held(&dp->dp_lock); - - if (rx_tid->dst_ring_desc) { - if (rel_link_desc) { - buf_addr_info = &rx_tid->dst_ring_desc->buf_addr_info; - ath12k_dp_arch_rx_link_desc_return(dp, buf_addr_info, act); - } - kfree(rx_tid->dst_ring_desc); - rx_tid->dst_ring_desc = NULL; - } - - rx_tid->cur_sn = 0; - rx_tid->last_frag_no = 0; - rx_tid->rx_frag_bitmap = 0; - __skb_queue_purge(&rx_tid->rx_frags); -} - void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer *peer) { struct ath12k_dp_rx_tid *rx_tid; @@ -537,7 +513,7 @@ void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer rx_tid = &peer->dp_peer->rx_tid[i]; ath12k_dp_arch_rx_peer_tid_delete(dp, peer, i); - ath12k_dp_rx_frags_cleanup(rx_tid, true); + ath12k_dp_arch_rx_frags_cleanup(dp, rx_tid, true); spin_unlock_bh(&dp->dp_lock); timer_delete_sync(&rx_tid->frag_timer); @@ -1500,7 +1476,7 @@ static void ath12k_dp_rx_frag_timer(struct timer_list *timer) spin_unlock_bh(&rx_tid->dp->dp_lock); return; } - ath12k_dp_rx_frags_cleanup(rx_tid, true); + ath12k_dp_arch_rx_frags_cleanup(rx_tid->dp, rx_tid, true); spin_unlock_bh(&rx_tid->dp->dp_lock); } diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index f413834eff892..61d0d8568a748 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -197,8 +197,6 @@ void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, struct sk_buff *cur_frag); void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, enum hal_encrypt_type enctype, u32 flags); -void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, - bool rel_link_desc); int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, struct ieee80211_hdr *hdr, u8 *data, size_t data_len, u8 *mic); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 1fd7738a39b57..b57e8de05c273 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -144,6 +144,7 @@ static struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = { .rx_peer_tid_delete = ath12k_wifi7_dp_rx_peer_tid_delete, .reo_cache_flush = ath12k_wifi7_dp_reo_cache_flush, .rx_link_desc_return = ath12k_wifi7_dp_rx_link_desc_return, + .rx_frags_cleanup = ath12k_wifi7_dp_rx_frags_cleanup, .peer_rx_tid_reo_update = ath12k_wifi7_peer_rx_tid_reo_update, .rx_assign_reoq = ath12k_wifi7_dp_rx_assign_reoq, .peer_rx_tid_qref_setup = ath12k_wifi7_peer_rx_tid_qref_setup, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 0cf8a8f7b5f6e..13cd23d7c7dae 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -1100,6 +1100,30 @@ static int ath12k_wifi7_dp_rx_h_defrag(struct ath12k_pdev_dp *dp_pdev, return 0; } +void ath12k_wifi7_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, + bool rel_link_desc) +{ + enum hal_wbm_rel_bm_act act = HAL_WBM_REL_BM_ACT_PUT_IN_IDLE; + struct ath12k_buffer_addr *buf_addr_info; + struct ath12k_dp *dp = rx_tid->dp; + + lockdep_assert_held(&dp->dp_lock); + + if (rx_tid->dst_ring_desc) { + if (rel_link_desc) { + buf_addr_info = &rx_tid->dst_ring_desc->buf_addr_info; + ath12k_wifi7_dp_rx_link_desc_return(dp->ab, buf_addr_info, act); + } + kfree(rx_tid->dst_ring_desc); + rx_tid->dst_ring_desc = NULL; + } + + rx_tid->cur_sn = 0; + rx_tid->last_frag_no = 0; + rx_tid->rx_frag_bitmap = 0; + __skb_queue_purge(&rx_tid->rx_frags); +} + static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct hal_reo_dest_ring *ring_desc, @@ -1154,7 +1178,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) || skb_queue_empty(&rx_tid->rx_frags)) { /* Flush stored fragments and start a new sequence */ - ath12k_dp_rx_frags_cleanup(rx_tid, true); + ath12k_wifi7_dp_rx_frags_cleanup(rx_tid, true); rx_tid->cur_sn = seqno; } @@ -1214,12 +1238,12 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, if (ath12k_wifi7_dp_rx_h_defrag_reo_reinject(dp, rx_tid, defrag_skb)) goto err_frags_cleanup; - ath12k_dp_rx_frags_cleanup(rx_tid, false); + ath12k_wifi7_dp_rx_frags_cleanup(rx_tid, false); goto out_unlock; err_frags_cleanup: dev_kfree_skb_any(defrag_skb); - ath12k_dp_rx_frags_cleanup(rx_tid, true); + ath12k_wifi7_dp_rx_frags_cleanup(rx_tid, true); out_unlock: spin_unlock_bh(&dp->dp_lock); return ret; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index cb72b75526d4a..85677258b1df1 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -31,6 +31,8 @@ int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_dp_peer int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, struct ath12k_buffer_addr *buf_addr_info, enum hal_wbm_rel_bm_act action); +void ath12k_wifi7_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, + bool rel_link_desc); void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, dma_addr_t paddr); void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k_base *ab, From ebd4b7706ec9f53e3dec7c5282cf7ca26ae676b2 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Mon, 3 Nov 2025 16:51:07 +0530 Subject: [PATCH 094/140] wifi: ath12k: Move ath12k_dp_rx_get_peer_id API to Wi-Fi 7 Move ath12k_dp_rx_get_peer_id() from common to Wi-Fi 7 as it operates on arch specific peer metadata. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-9-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_rx.c | 23 -------------- drivers/net/wireless/ath/ath12k/dp_rx.h | 3 -- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 31 ++++++++++++++++--- 3 files changed, 27 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index c34de4a390529..9a31a73c5f6f9 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -1442,29 +1442,6 @@ bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_dp *dp, return false; } -u16 ath12k_dp_rx_get_peer_id(struct ath12k_base *ab, - enum ath12k_peer_metadata_version ver, - __le32 peer_metadata) -{ - switch (ver) { - default: - ath12k_warn(ab, "Unknown peer metadata version: %d", ver); - fallthrough; - case ATH12K_PEER_METADATA_V0: - return le32_get_bits(peer_metadata, - RX_MPDU_DESC_META_DATA_V0_PEER_ID); - case ATH12K_PEER_METADATA_V1: - return le32_get_bits(peer_metadata, - RX_MPDU_DESC_META_DATA_V1_PEER_ID); - case ATH12K_PEER_METADATA_V1A: - return le32_get_bits(peer_metadata, - RX_MPDU_DESC_META_DATA_V1A_PEER_ID); - case ATH12K_PEER_METADATA_V1B: - return le32_get_bits(peer_metadata, - RX_MPDU_DESC_META_DATA_V1B_PEER_ID); - } -} - static void ath12k_dp_rx_frag_timer(struct timer_list *timer) { struct ath12k_dp_rx_tid *rx_tid = timer_container_of(rx_tid, timer, diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 61d0d8568a748..51e1de59208d6 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -200,9 +200,6 @@ void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, struct ieee80211_hdr *hdr, u8 *data, size_t data_len, u8 *mic); -u16 ath12k_dp_rx_get_peer_id(struct ath12k_base *ab, - enum ath12k_peer_metadata_version ver, - __le32 peer_metadata); int ath12k_dp_rx_ampdu_start(struct ath12k *ar, struct ieee80211_ampdu_params *params, u8 link_id); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 13cd23d7c7dae..5eb62afde4a53 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -10,6 +10,29 @@ #include "hal_qcn9274.h" #include "hal_wcn7850.h" +static u16 ath12k_wifi7_dp_rx_get_peer_id(struct ath12k_dp *dp, + enum ath12k_peer_metadata_version ver, + __le32 peer_metadata) +{ + switch (ver) { + default: + ath12k_warn(dp->ab, "Unknown peer metadata version: %d", ver); + fallthrough; + case ATH12K_PEER_METADATA_V0: + return le32_get_bits(peer_metadata, + RX_MPDU_DESC_META_DATA_V0_PEER_ID); + case ATH12K_PEER_METADATA_V1: + return le32_get_bits(peer_metadata, + RX_MPDU_DESC_META_DATA_V1_PEER_ID); + case ATH12K_PEER_METADATA_V1A: + return le32_get_bits(peer_metadata, + RX_MPDU_DESC_META_DATA_V1A_PEER_ID); + case ATH12K_PEER_METADATA_V1B: + return le32_get_bits(peer_metadata, + RX_MPDU_DESC_META_DATA_V1B_PEER_ID); + } +} + void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, dma_addr_t paddr) { @@ -731,8 +754,8 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, rxcb->is_continuation = !!(le32_to_cpu(msdu_info->info0) & RX_MSDU_DESC_INFO0_MSDU_CONTINUATION); rxcb->hw_link_id = hw_link_id; - rxcb->peer_id = ath12k_dp_rx_get_peer_id(ab, dp->peer_metadata_ver, - mpdu_info->peer_meta_data); + rxcb->peer_id = ath12k_wifi7_dp_rx_get_peer_id(dp, dp->peer_metadata_ver, + mpdu_info->peer_meta_data); rxcb->tid = le32_get_bits(mpdu_info->info0, RX_MPDU_DESC_INFO0_TID); @@ -1855,8 +1878,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, rxcb->is_last_msdu = err_info.last_msdu; rxcb->is_continuation = err_info.continuation; rxcb->rx_desc = msdu_data; - rxcb->peer_id = ath12k_dp_rx_get_peer_id(ab, dp->peer_metadata_ver, - err_info.peer_metadata); + rxcb->peer_id = ath12k_wifi7_dp_rx_get_peer_id(dp, dp->peer_metadata_ver, + err_info.peer_metadata); if (err_info.continuation) { __skb_queue_tail(&scatter_msdu_list, msdu); From 022e8e1bfe0e7fa5f9373e6b3657f2c9069d728b Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Mon, 3 Nov 2025 16:51:08 +0530 Subject: [PATCH 095/140] wifi: ath12k: Remove arch-specific HAL dependencies from common DP Currently common DP includes arch-specific structs from wifi7/hal_desc.h via dp_mon.h. Store hal_wbm_release_ring_tx size in the HAL object and move hal_wbm_link_desc to common HAL for this separation. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-10-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 3 +-- drivers/net/wireless/ath/ath12k/hal.h | 6 +++++- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 1 + drivers/net/wireless/ath/ath12k/wifi7/hal.c | 1 + drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h | 4 ---- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index c7f7c04877c4b..6c5076261eafe 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -11,7 +11,6 @@ #include "hal.h" #include "debug.h" #include "peer.h" -#include "dp_mon.h" #include "dp_cmn.h" enum ath12k_dp_desc_type { @@ -1534,7 +1533,7 @@ static int ath12k_dp_setup(struct ath12k_base *ab) if (ret) goto fail_dp_bank_profiles_cleanup; - size = sizeof(struct hal_wbm_release_ring_tx) * + size = ab->hal.hal_wbm_release_ring_tx_size * DP_TX_COMP_RING_SIZE(ab); ret = ath12k_dp_reoq_lut_setup(ab); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 29bcedca0a3b0..071f4897e4cd0 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -795,7 +795,10 @@ struct ath12k_buffer_addr { struct hal_ce_srng_dest_desc; struct hal_ce_srng_dst_status_desc; struct hal_ce_srng_src_desc; -struct hal_wbm_link_desc; + +struct hal_wbm_link_desc { + struct ath12k_buffer_addr buf_addr_info; +} __packed; /* srng flags */ #define HAL_SRNG_FLAGS_MSI_SWAP 0x00000008 @@ -1202,6 +1205,7 @@ struct ath12k_hal { int num_shadow_reg_configured; u32 hal_desc_sz; + u32 hal_wbm_release_ring_tx_size; const struct ath12k_hal_tcl_to_wbm_rbm_map *tcl_to_wbm_rbm_map; }; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index b57e8de05c273..cf7ede27623af 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -7,6 +7,7 @@ #include "../debug.h" #include "../dp_rx.h" #include "../dp_tx.h" +#include "hal_desc.h" #include "../dp_mon.h" #include "../dp_cmn.h" #include "dp_rx.h" diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 84c0ba2d1fbe9..f48adb83599e8 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -55,6 +55,7 @@ int ath12k_wifi7_hal_init(struct ath12k_base *ab) hal->tcl_to_wbm_rbm_map = ath12k_wifi7_hw_ver_map[ab->hw_rev].tcl_to_wbm_rbm_map; hal->regs = ath12k_wifi7_hw_ver_map[ab->hw_rev].hw_regs; hal->hal_params = ath12k_wifi7_hw_ver_map[ab->hw_rev].hal_params; + hal->hal_wbm_release_ring_tx_size = sizeof(struct hal_wbm_release_ring_tx); return 0; } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h index 63c62a6de6400..4a249ba7357d1 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h @@ -1593,10 +1593,6 @@ struct hal_tx_rate_stats { __le32 tsf; } __packed; -struct hal_wbm_link_desc { - struct ath12k_buffer_addr buf_addr_info; -} __packed; - #define HAL_WBM_COMPL_RX_INFO0_REL_SRC_MODULE GENMASK(2, 0) #define HAL_WBM_COMPL_RX_INFO0_BM_ACTION GENMASK(5, 3) #define HAL_WBM_COMPL_RX_INFO0_DESC_TYPE GENMASK(8, 6) From 0cf167aaee83b73bec85e63a62269806068aff3c Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Mon, 3 Nov 2025 16:51:09 +0530 Subject: [PATCH 096/140] wifi: ath12k: Build all the files in wifi7 directory into ath12k_wifi7.ko Move files built as part of ath12k.ko from wifi7 directory to ath12k_wifi7.ko. Export necessary symbols from ath12k.ko and remove redundant exports from the wifi7 directory, as they are no longer needed. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-11-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/Makefile | 9 --------- drivers/net/wireless/ath/ath12k/core.c | 1 + drivers/net/wireless/ath/ath12k/debug.c | 1 + drivers/net/wireless/ath/ath12k/dp.c | 2 ++ drivers/net/wireless/ath/ath12k/dp_htt.c | 1 + drivers/net/wireless/ath/ath12k/dp_mon.c | 1 + drivers/net/wireless/ath/ath12k/dp_peer.c | 2 ++ drivers/net/wireless/ath/ath12k/dp_rx.c | 12 ++++++++++++ drivers/net/wireless/ath/ath12k/dp_tx.c | 9 +++++++++ drivers/net/wireless/ath/ath12k/hal.c | 8 ++++++++ drivers/net/wireless/ath/ath12k/mac.c | 5 +++++ drivers/net/wireless/ath/ath12k/wifi7/Makefile | 10 +++++++++- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 2 -- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 2 -- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 1 - drivers/net/wireless/ath/ath12k/wifi7/hal.c | 1 - drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c | 1 - drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c | 1 - 18 files changed, 51 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile index d397bc494cf25..3ba1236956cc8 100644 --- a/drivers/net/wireless/ath/ath12k/Makefile +++ b/drivers/net/wireless/ath/ath12k/Makefile @@ -24,15 +24,6 @@ ath12k-y += core.o \ ath12k-$(CONFIG_ATH12K_AHB) += ahb.o -ath12k-y += wifi7/hal_tx.o \ - wifi7/hal_rx.o \ - wifi7/dp_rx.o \ - wifi7/dp_tx.o \ - wifi7/dp.o \ - wifi7/hal.o \ - wifi7/hal_qcn9274.o \ - wifi7/hal_wcn7850.o - obj-$(CONFIG_ATH12K) += wifi7/ ath12k-$(CONFIG_ATH12K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index e4c3fdb504832..9d6c50a94e642 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -32,6 +32,7 @@ EXPORT_SYMBOL(ath12k_debug_mask); bool ath12k_ftm_mode; module_param_named(ftm_mode, ath12k_ftm_mode, bool, 0444); MODULE_PARM_DESC(ftm_mode, "Boots up in factory test mode"); +EXPORT_SYMBOL(ath12k_ftm_mode); /* protected with ath12k_hw_group_mutex */ static struct list_head ath12k_hw_group_list = LIST_HEAD_INIT(ath12k_hw_group_list); diff --git a/drivers/net/wireless/ath/ath12k/debug.c b/drivers/net/wireless/ath/ath12k/debug.c index 5fe9b2fbf5096..34b3b2c920dc7 100644 --- a/drivers/net/wireless/ath/ath12k/debug.c +++ b/drivers/net/wireless/ath/ath12k/debug.c @@ -105,5 +105,6 @@ void ath12k_dbg_dump(struct ath12k_base *ab, } } } +EXPORT_SYMBOL(ath12k_dbg_dump); #endif /* CONFIG_ATH12K_DEBUG */ diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 6c5076261eafe..36a11cb4a9c7f 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1181,6 +1181,7 @@ struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_base *ab, return *desc_addr_ptr; } +EXPORT_SYMBOL(ath12k_dp_get_rx_desc); struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_base *ab, u32 cookie) @@ -1204,6 +1205,7 @@ struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_base *ab, return *desc_addr_ptr; } +EXPORT_SYMBOL(ath12k_dp_get_tx_desc); static int ath12k_dp_cc_desc_init(struct ath12k_base *ab) { diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index 39f42cd99835b..cc71c5c5de5a1 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -1077,6 +1077,7 @@ int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id, return ret; } +EXPORT_SYMBOL(ath12k_dp_tx_htt_rx_filter_setup); int ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type, diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index eee877e3680b2..a60a785b148bc 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -4472,3 +4472,4 @@ int ath12k_dp_mon_process_ring(struct ath12k_base *ab, int mac_id, return num_buffs_reaped; } +EXPORT_SYMBOL(ath12k_dp_mon_process_ring); diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index 0ad01f7414cd6..2e66872b55723 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -426,6 +426,7 @@ struct ath12k_dp_peer *ath12k_dp_peer_find_by_peerid(struct ath12k_pdev_dp *dp_p return rcu_dereference(dp_pdev->dp_hw->dp_peers[index]); } +EXPORT_SYMBOL(ath12k_dp_peer_find_by_peerid); struct ath12k_dp_link_peer * ath12k_dp_link_peer_find_by_peerid(struct ath12k_pdev_dp *dp_pdev, u16 peer_id) @@ -447,6 +448,7 @@ ath12k_dp_link_peer_find_by_peerid(struct ath12k_pdev_dp *dp_pdev, u16 peer_id) return rcu_dereference(dp_peer->link_peers[link_id]); } +EXPORT_SYMBOL(ath12k_dp_link_peer_find_by_peerid); int ath12k_dp_peer_create(struct ath12k_dp_hw *dp_hw, u8 *addr, struct ath12k_dp_peer_create_params *params) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 9a31a73c5f6f9..236997ed53fea 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -163,6 +163,7 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, return req_entries - num_remain; } +EXPORT_SYMBOL(ath12k_dp_rx_bufs_replenish); static int ath12k_dp_rxdma_mon_buf_ring_free(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring) @@ -403,6 +404,7 @@ void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx, ath12k_dp_rx_tid_cleanup(dp->ab, &rx_tid->qbuf); } +EXPORT_SYMBOL(ath12k_dp_reo_cmd_free); void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx, enum hal_reo_cmd_status status) @@ -496,6 +498,7 @@ static int ath12k_dp_rx_tid_delete_handler(struct ath12k_base *ab, HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, ath12k_dp_rx_tid_del_func); } +EXPORT_SYMBOL(ath12k_dp_rx_tid_del_func); void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer *peer) { @@ -875,6 +878,7 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif, return ret; } +EXPORT_SYMBOL(ath12k_dp_rx_get_msdu_last_buf); struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list, struct sk_buff *first) @@ -1190,6 +1194,7 @@ void ath12k_dp_rx_h_undecap(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu break; } } +EXPORT_SYMBOL(ath12k_dp_rx_h_undecap); struct ath12k_dp_link_peer * ath12k_dp_rx_h_find_link_peer(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, @@ -1349,6 +1354,7 @@ void ath12k_dp_rx_h_ppdu(struct ath12k_pdev_dp *dp_pdev, ath12k_dp_rx_h_rate(dp_pdev, rx_info); } +EXPORT_SYMBOL(ath12k_dp_rx_h_ppdu); void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, struct sk_buff *msdu, @@ -1419,6 +1425,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc ieee80211_rx_napi(ath12k_pdev_dp_to_hw(dp_pdev), pubsta, msdu, napi); } +EXPORT_SYMBOL(ath12k_dp_rx_deliver_msdu); bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_dp *dp, struct hal_rx_desc *rx_desc, @@ -1441,6 +1448,7 @@ bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_dp *dp, WARN_ON_ONCE(1); return false; } +EXPORT_SYMBOL(ath12k_dp_rx_check_nwifi_hdr_len_valid); static void ath12k_dp_rx_frag_timer(struct timer_list *timer) { @@ -1540,6 +1548,7 @@ int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key, shash_desc_zero(desc); return ret; } +EXPORT_SYMBOL(ath12k_dp_rx_h_michael_mic); void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, enum hal_encrypt_type enctype, u32 flags) @@ -1572,6 +1581,7 @@ void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff skb_pull(msdu, crypto_len); } } +EXPORT_SYMBOL(ath12k_dp_rx_h_undecap_frag); static int ath12k_dp_rx_h_cmp_frags(struct ath12k_base *ab, struct sk_buff *a, struct sk_buff *b) @@ -1600,6 +1610,7 @@ void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, } __skb_queue_tail(frag_list, cur_frag); } +EXPORT_SYMBOL(ath12k_dp_rx_h_sort_frags); u64 ath12k_dp_rx_h_get_pn(struct ath12k_dp *dp, struct sk_buff *skb) { @@ -1620,6 +1631,7 @@ u64 ath12k_dp_rx_h_get_pn(struct ath12k_dp *dp, struct sk_buff *skb) return pn; } +EXPORT_SYMBOL(ath12k_dp_rx_h_get_pn); static bool ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, struct ath12k_dp_rx_tid *rx_tid) diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c index 8d5e10781377e..bcae34f5db7d6 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/dp_tx.c @@ -25,6 +25,7 @@ ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb) return HAL_TCL_ENCAP_TYPE_NATIVE_WIFI; } +EXPORT_SYMBOL(ath12k_dp_tx_get_encap_type); void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb) { @@ -42,6 +43,7 @@ void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb) hdr = (void *)skb->data; hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA); } +EXPORT_SYMBOL(ath12k_dp_tx_encap_nwifi); u8 ath12k_dp_tx_get_tid(struct sk_buff *skb) { @@ -55,6 +57,7 @@ u8 ath12k_dp_tx_get_tid(struct sk_buff *skb) else return skb->priority & IEEE80211_QOS_CTL_TID_MASK; } +EXPORT_SYMBOL(ath12k_dp_tx_get_tid); enum hal_encrypt_type ath12k_dp_tx_get_encrypt_type(u32 cipher) { @@ -77,6 +80,7 @@ enum hal_encrypt_type ath12k_dp_tx_get_encrypt_type(u32 cipher) return HAL_ENCRYPT_TYPE_OPEN; } } +EXPORT_SYMBOL(ath12k_dp_tx_get_encrypt_type); void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp, struct ath12k_tx_desc_info *tx_desc, @@ -87,6 +91,7 @@ void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp, list_move_tail(&tx_desc->list, &dp->tx_desc_free_list[pool_id]); spin_unlock_bh(&dp->tx_desc_lock[pool_id]); } +EXPORT_SYMBOL(ath12k_dp_tx_release_txbuf); struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp, u8 pool_id) @@ -108,6 +113,7 @@ struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp, return desc; } +EXPORT_SYMBOL(ath12k_dp_tx_assign_buffer); void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len) { @@ -121,6 +127,7 @@ void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len) memset(metadata, 0, tail_len); return metadata; } +EXPORT_SYMBOL(ath12k_dp_metadata_align_skb); static void ath12k_dp_tx_move_payload(struct sk_buff *skb, unsigned long delta, @@ -175,6 +182,7 @@ int ath12k_dp_tx_align_payload(struct ath12k_base *ab, out: return ret; } +EXPORT_SYMBOL(ath12k_dp_tx_align_payload); void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, struct dp_tx_ring *tx_ring, @@ -200,3 +208,4 @@ void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, if (atomic_dec_and_test(&ar->dp.num_tx_pending)) wake_up(&ar->dp.tx_empty_waitq); } +EXPORT_SYMBOL(ath12k_dp_tx_free_txbuf); diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 08063d1094ae1..efa039f6df924 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -217,6 +217,7 @@ int ath12k_hal_srng_get_entrysize(struct ath12k_base *ab, u32 ring_type) return (srng_config->entry_size << 2); } +EXPORT_SYMBOL(ath12k_hal_srng_get_entrysize); int ath12k_hal_srng_get_max_entries(struct ath12k_base *ab, u32 ring_type) { @@ -246,6 +247,7 @@ void ath12k_hal_srng_get_params(struct ath12k_base *ab, struct hal_srng *srng, params->msi2_data = srng->msi2_data; params->flags = srng->flags; } +EXPORT_SYMBOL(ath12k_hal_srng_get_params); dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab, struct hal_srng *srng) @@ -316,6 +318,7 @@ void *ath12k_hal_srng_dst_peek(struct ath12k_base *ab, struct hal_srng *srng) return NULL; } +EXPORT_SYMBOL(ath12k_hal_srng_dst_peek); void *ath12k_hal_srng_dst_get_next_entry(struct ath12k_base *ab, struct hal_srng *srng) @@ -334,6 +337,7 @@ void *ath12k_hal_srng_dst_get_next_entry(struct ath12k_base *ab, return desc; } +EXPORT_SYMBOL(ath12k_hal_srng_dst_get_next_entry); int ath12k_hal_srng_dst_num_free(struct ath12k_base *ab, struct hal_srng *srng, bool sync_hw_ptr) @@ -356,6 +360,7 @@ int ath12k_hal_srng_dst_num_free(struct ath12k_base *ab, struct hal_srng *srng, else return (srng->ring_size - tp + hp) / srng->entry_size; } +EXPORT_SYMBOL(ath12k_hal_srng_dst_num_free); /* Returns number of available entries in src ring */ int ath12k_hal_srng_src_num_free(struct ath12k_base *ab, struct hal_srng *srng, @@ -430,6 +435,7 @@ void *ath12k_hal_srng_src_get_next_entry(struct ath12k_base *ab, return desc; } +EXPORT_SYMBOL(ath12k_hal_srng_src_get_next_entry); void *ath12k_hal_srng_src_peek(struct ath12k_base *ab, struct hal_srng *srng) { @@ -500,6 +506,7 @@ void ath12k_hal_srng_access_begin(struct ath12k_base *ab, struct hal_srng *srng) } } } +EXPORT_SYMBOL(ath12k_hal_srng_access_begin); /* Update cached ring head/tail pointers to HW. ath12k_hal_srng_access_begin() * should have been called before this. @@ -555,6 +562,7 @@ void ath12k_hal_srng_access_end(struct ath12k_base *ab, struct hal_srng *srng) srng->timestamp = jiffies; } +EXPORT_SYMBOL(ath12k_hal_srng_access_end); int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, int ring_num, int mac_id, diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index ab0e67bca11d8..e919c970f339f 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -363,6 +363,7 @@ u16 ath12k_mac_he_convert_tones_to_ru_tones(u16 tones) return RU_26; } } +EXPORT_SYMBOL(ath12k_mac_he_convert_tones_to_ru_tones); enum nl80211_eht_gi ath12k_mac_eht_gi_to_nl80211_eht_gi(u8 sgi) { @@ -377,6 +378,7 @@ enum nl80211_eht_gi ath12k_mac_eht_gi_to_nl80211_eht_gi(u8 sgi) return NL80211_RATE_INFO_EHT_GI_0_8; } } +EXPORT_SYMBOL(ath12k_mac_eht_gi_to_nl80211_eht_gi); enum nl80211_eht_ru_alloc ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(u16 ru_tones) { @@ -417,6 +419,7 @@ enum nl80211_eht_ru_alloc ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(u16 ru return NL80211_RATE_INFO_EHT_RU_ALLOC_26; } } +EXPORT_SYMBOL(ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc); enum rate_info_bw ath12k_mac_bw_to_mac80211_bw(enum ath12k_supported_bw bw) @@ -443,6 +446,7 @@ ath12k_mac_bw_to_mac80211_bw(enum ath12k_supported_bw bw) return ret; } +EXPORT_SYMBOL(ath12k_mac_bw_to_mac80211_bw); enum ath12k_supported_bw ath12k_mac_mac80211_bw_to_ath12k_bw(enum rate_info_bw bw) { @@ -486,6 +490,7 @@ int ath12k_mac_hw_ratecode_to_legacy_rate(u8 hw_rc, u8 preamble, u8 *rateidx, return -EINVAL; } +EXPORT_SYMBOL(ath12k_mac_hw_ratecode_to_legacy_rate); u8 ath12k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband, u32 bitrate) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/Makefile b/drivers/net/wireless/ath/ath12k/wifi7/Makefile index 872ca620a5c50..30258a1b313de 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/Makefile +++ b/drivers/net/wireless/ath/ath12k/wifi7/Makefile @@ -5,6 +5,14 @@ ath12k_wifi7-y += core.o \ wmi.o \ mhi.o \ ce.o \ - hw.o + hw.o \ + hal_tx.o \ + hal_rx.o \ + dp_rx.o \ + dp_tx.o \ + dp.o \ + hal.o \ + hal_qcn9274.o \ + hal_wcn7850.o ath12k_wifi7-$(CONFIG_ATH12K_AHB) += ahb.o diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index cf7ede27623af..433ffdb552647 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -170,10 +170,8 @@ struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab) return dp; } -EXPORT_SYMBOL(ath12k_wifi7_dp_device_alloc); void ath12k_wifi7_dp_device_free(struct ath12k_dp *dp) { kfree(dp); } -EXPORT_SYMBOL(ath12k_wifi7_dp_device_free); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 5eb62afde4a53..d2026082708e4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -2022,7 +2022,6 @@ int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab) return ret; } -EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_qcn9274); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) { @@ -2065,7 +2064,6 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) return ret; } -EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_wcn7850); void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_base *ab) { diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index 7e16bc12e36ac..bb8c2384c13ea 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -379,7 +379,6 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a return ret; } -EXPORT_SYMBOL(ath12k_wifi7_dp_tx); static void ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index f48adb83599e8..03a007dd6857f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -59,7 +59,6 @@ int ath12k_wifi7_hal_init(struct ath12k_base *ab) return 0; } -EXPORT_SYMBOL(ath12k_wifi7_hal_init); static unsigned int ath12k_wifi7_hal_reo1_ring_id_offset(struct ath12k_hal *hal) { diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index f13376b7faa1f..4b6f43389b2d9 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1029,4 +1029,3 @@ const struct hal_ops hal_qcn9274_ops = { .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, }; -EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index a73e7539a27ab..f243bc3ab4097 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -802,4 +802,3 @@ const struct hal_ops hal_wcn7850_ops = { .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, }; -EXPORT_SYMBOL(hal_wcn7850_ops); From da76a6243c48b1ccb61a5519caceb7759df82f52 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Mon, 3 Nov 2025 16:51:10 +0530 Subject: [PATCH 097/140] wifi: ath12k: Use dp objects in performance critical paths Use dp objects in tx and rx data paths in place of other objects to minimize pointer indirections and increase the cache efficiency in the data paths. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-12-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 25 ++- drivers/net/wireless/ath/ath12k/dp.h | 9 +- drivers/net/wireless/ath/ath12k/dp_mon.c | 15 +- drivers/net/wireless/ath/ath12k/dp_mon.h | 2 +- drivers/net/wireless/ath/ath12k/dp_rx.c | 44 +++-- drivers/net/wireless/ath/ath12k/dp_rx.h | 32 ++-- drivers/net/wireless/ath/ath12k/dp_tx.c | 24 +-- drivers/net/wireless/ath/ath12k/dp_tx.h | 5 +- drivers/net/wireless/ath/ath12k/wifi7/dp.c | 66 ++++--- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 166 +++++++++--------- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 14 +- drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 109 ++++++------ drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h | 2 +- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 19 +- .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 7 +- 15 files changed, 269 insertions(+), 270 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 36a11cb4a9c7f..9f05eea6695a5 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1150,26 +1150,23 @@ static u32 ath12k_dp_cc_cookie_gen(u16 ppt_idx, u16 spt_idx) return (u32)ppt_idx << ATH12K_CC_PPT_SHIFT | spt_idx; } -static inline void *ath12k_dp_cc_get_desc_addr_ptr(struct ath12k_base *ab, - u16 ppt_idx, u16 spt_idx) +static void *ath12k_dp_cc_get_desc_addr_ptr(struct ath12k_dp *dp, + u16 ppt_idx, u16 spt_idx) { - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - return dp->spt_info[ppt_idx].vaddr + spt_idx; } -struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_base *ab, +struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_dp *dp, u32 cookie) { - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_rx_desc_info **desc_addr_ptr; u16 start_ppt_idx, end_ppt_idx, ppt_idx, spt_idx; ppt_idx = u32_get_bits(cookie, ATH12K_DP_CC_COOKIE_PPT); spt_idx = u32_get_bits(cookie, ATH12K_DP_CC_COOKIE_SPT); - start_ppt_idx = dp->rx_ppt_base + ATH12K_RX_SPT_PAGE_OFFSET(ab); - end_ppt_idx = start_ppt_idx + ATH12K_NUM_RX_SPT_PAGES(ab); + start_ppt_idx = dp->rx_ppt_base + ATH12K_RX_SPT_PAGE_OFFSET(dp->ab); + end_ppt_idx = start_ppt_idx + ATH12K_NUM_RX_SPT_PAGES(dp->ab); if (ppt_idx < start_ppt_idx || ppt_idx >= end_ppt_idx || @@ -1177,13 +1174,13 @@ struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_base *ab, return NULL; ppt_idx = ppt_idx - dp->rx_ppt_base; - desc_addr_ptr = ath12k_dp_cc_get_desc_addr_ptr(ab, ppt_idx, spt_idx); + desc_addr_ptr = ath12k_dp_cc_get_desc_addr_ptr(dp, ppt_idx, spt_idx); return *desc_addr_ptr; } EXPORT_SYMBOL(ath12k_dp_get_rx_desc); -struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_base *ab, +struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_dp *dp, u32 cookie) { struct ath12k_tx_desc_info **desc_addr_ptr; @@ -1194,14 +1191,14 @@ struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_base *ab, start_ppt_idx = ATH12K_TX_SPT_PAGE_OFFSET; end_ppt_idx = start_ppt_idx + - (ATH12K_TX_SPT_PAGES_PER_POOL(ab) * ATH12K_HW_MAX_QUEUES); + (ATH12K_TX_SPT_PAGES_PER_POOL(dp->ab) * ATH12K_HW_MAX_QUEUES); if (ppt_idx < start_ppt_idx || ppt_idx >= end_ppt_idx || spt_idx > ATH12K_MAX_SPT_ENTRIES) return NULL; - desc_addr_ptr = ath12k_dp_cc_get_desc_addr_ptr(ab, ppt_idx, spt_idx); + desc_addr_ptr = ath12k_dp_cc_get_desc_addr_ptr(dp, ppt_idx, spt_idx); return *desc_addr_ptr; } @@ -1249,7 +1246,7 @@ static int ath12k_dp_cc_desc_init(struct ath12k_base *ab) list_add_tail(&rx_descs[j].list, &dp->rx_desc_free_list); /* Update descriptor VA in SPT */ - rx_desc_addr = ath12k_dp_cc_get_desc_addr_ptr(ab, ppt_idx, j); + rx_desc_addr = ath12k_dp_cc_get_desc_addr_ptr(dp, ppt_idx, j); *rx_desc_addr = &rx_descs[j]; } } @@ -1288,7 +1285,7 @@ static int ath12k_dp_cc_desc_init(struct ath12k_base *ab) /* Update descriptor VA in SPT */ tx_desc_addr = - ath12k_dp_cc_get_desc_addr_ptr(ab, ppt_idx, j); + ath12k_dp_cc_get_desc_addr_ptr(dp, ppt_idx, j); *tx_desc_addr = &tx_descs[j]; } } diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 2c77dc636ecfb..dc18423812ec0 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -19,7 +19,6 @@ struct ath12k_dp_link_peer; struct ath12k_dp; struct ath12k_vif; struct ath12k_link_vif; -struct hal_tcl_status_ring; struct ath12k_ext_irq_grp; struct ath12k_dp_rx_tid; @@ -405,7 +404,7 @@ struct ath12k_dp_arch_ops { struct ath12k_dp_link_peer *peer, u8 tid); void (*reo_cache_flush)(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid); - int (*rx_link_desc_return)(struct ath12k_base *ab, + int (*rx_link_desc_return)(struct ath12k_dp *dp, struct ath12k_buffer_addr *buf_addr_info, enum hal_wbm_rel_bm_act action); void (*rx_frags_cleanup)(struct ath12k_dp_rx_tid *rx_tid, @@ -591,7 +590,7 @@ int ath12k_dp_arch_rx_link_desc_return(struct ath12k_dp *dp, struct ath12k_buffer_addr *buf_addr_info, enum hal_wbm_rel_bm_act action) { - return dp->ops->rx_link_desc_return(dp->ab, buf_addr_info, action); + return dp->ops->rx_link_desc_return(dp, buf_addr_info, action); } static inline @@ -679,8 +678,8 @@ int ath12k_dp_link_desc_setup(struct ath12k_base *ab, struct dp_link_desc_bank *link_desc_banks, u32 ring_type, struct hal_srng *srng, u32 n_link_desc); -struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_base *ab, +struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_dp *dp, u32 cookie); -struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_base *ab, +struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_dp *dp, u32 desc_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index a60a785b148bc..a28939214040e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2332,7 +2332,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, status->flag |= RX_FLAG_RADIOTAP_HE; } - ath12k_wifi7_dp_extract_rx_desc_data(ab, &rx_info, rx_desc, rx_desc); + ath12k_wifi7_dp_extract_rx_desc_data(dp->hal, &rx_info, rx_desc, rx_desc); rcu_read_lock(); spin_lock_bh(&dp->dp_lock); @@ -4166,7 +4166,7 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, ath12k_hal_rx_msdu_list_get(&ar->ab->hal, ar, msdu_link_desc, &msdu_list, &num_msdus); - desc_info = ath12k_dp_get_rx_desc(ar->ab, + desc_info = ath12k_dp_get_rx_desc(ar->ab->dp, msdu_list.sw_cookie[num_msdus - 1]); tail_rx_desc = (struct hal_rx_desc *)(desc_info->skb)->data; @@ -4183,7 +4183,7 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, } desc_info = - ath12k_dp_get_rx_desc(ar->ab, msdu_list.sw_cookie[i]); + ath12k_dp_get_rx_desc(ar->ab->dp, msdu_list.sw_cookie[i]); msdu = desc_info->skb; if (!msdu) { @@ -4390,7 +4390,7 @@ static void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, if (rx_bufs_used) { rx_mon_stats->dest_ppdu_done++; - ath12k_dp_rx_bufs_replenish(ar->ab, + ath12k_dp_rx_bufs_replenish(ar->ab->dp, &dp->rx_refill_buf_ring, &rx_desc_used_list, rx_bufs_used); @@ -4438,12 +4438,11 @@ __ath12k_dp_mon_process_ring(struct ath12k *ar, int mac_id, return num_buffs_reaped; } -int ath12k_dp_mon_process_ring(struct ath12k_base *ab, int mac_id, +int ath12k_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, struct napi_struct *napi, int budget, enum dp_monitor_mode monitor_mode) { - u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id); - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(dp->hw_params, mac_id); struct ath12k_pdev_dp *dp_pdev; struct ath12k *ar; int num_buffs_reaped = 0; @@ -4456,7 +4455,7 @@ int ath12k_dp_mon_process_ring(struct ath12k_base *ab, int mac_id, return 0; } - if (ab->hw_params->rxdma1_enable) { + if (dp->hw_params->rxdma1_enable) { if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE) num_buffs_reaped = ath12k_dp_mon_srng_process(dp_pdev, &budget, napi); diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 6110227a40dd3..3e6ff4b0a6d9e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -89,7 +89,7 @@ int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, int req_entries); -int ath12k_dp_mon_process_ring(struct ath12k_base *ab, int mac_id, +int ath12k_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, struct napi_struct *napi, int budget, enum dp_monitor_mode monitor_mode); struct sk_buff *ath12k_dp_mon_tx_alloc_skb(void); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index 236997ed53fea..7ab8895f6197a 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -61,11 +61,12 @@ static void ath12k_dp_rx_enqueue_free(struct ath12k_dp *dp, } /* Returns number of Rx buffers replenished */ -int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, +int ath12k_dp_rx_bufs_replenish(struct ath12k_dp *dp, struct dp_rxdma_ring *rx_ring, struct list_head *used_list, int req_entries) { + struct ath12k_base *ab = dp->ab; struct ath12k_buffer_addr *desc; struct hal_srng *srng; struct sk_buff *skb; @@ -73,13 +74,12 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, int num_remain; u32 cookie; dma_addr_t paddr; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_rx_desc_info *rx_desc; - enum hal_rx_buf_return_buf_manager mgr = ab->hal.hal_params->rx_buf_rbm; + enum hal_rx_buf_return_buf_manager mgr = dp->hal->hal_params->rx_buf_rbm; req_entries = min(req_entries, rx_ring->bufs_max); - srng = &ab->hal.srng_list[rx_ring->refill_buf_ring.ring_id]; + srng = &dp->hal->srng_list[rx_ring->refill_buf_ring.ring_id]; spin_lock_bh(&srng->lock); @@ -118,10 +118,10 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, skb->data); } - paddr = dma_map_single(ab->dev, skb->data, + paddr = dma_map_single(dp->dev, skb->data, skb->len + skb_tailroom(skb), DMA_FROM_DEVICE); - if (dma_mapping_error(ab->dev, paddr)) + if (dma_mapping_error(dp->dev, paddr)) goto fail_free_skb; rx_desc = list_first_entry_or_null(used_list, @@ -142,14 +142,14 @@ int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, num_remain--; - ath12k_hal_rx_buf_addr_info_set(&ab->hal, desc, paddr, cookie, + ath12k_hal_rx_buf_addr_info_set(dp->hal, desc, paddr, cookie, mgr); } goto out; fail_dma_unmap: - dma_unmap_single(ab->dev, paddr, skb->len + skb_tailroom(skb), + dma_unmap_single(dp->dev, paddr, skb->len + skb_tailroom(skb), DMA_FROM_DEVICE); fail_free_skb: dev_kfree_skb_any(skb); @@ -233,7 +233,7 @@ static int ath12k_dp_rxdma_ring_buf_setup(struct ath12k_base *ab, rx_ring->bufs_max = rx_ring->refill_buf_ring.size / ath12k_hal_srng_get_entrysize(ab, HAL_RXDMA_BUF); - ath12k_dp_rx_bufs_replenish(ab, rx_ring, &list, 0); + ath12k_dp_rx_bufs_replenish(ath12k_ab_to_dp(ab), rx_ring, &list, 0); return 0; } @@ -982,8 +982,6 @@ static void ath12k_dp_rx_h_undecap_nwifi(struct ath12k_pdev_dp *dp_pdev, enum hal_encrypt_type enctype, struct hal_rx_desc_data *rx_info) { - struct ath12k_dp *dp = dp_pdev->dp; - struct ath12k_base *ab = dp->ab; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu); u8 decap_hdr[DP_MAX_NWIFI_HDR_LEN]; struct ieee80211_hdr *hdr; @@ -1016,7 +1014,7 @@ static void ath12k_dp_rx_h_undecap_nwifi(struct ath12k_pdev_dp *dp_pdev, if (!(rx_info->rx_status->flag & RX_FLAG_IV_STRIPPED)) { crypto_hdr = skb_push(msdu, ath12k_dp_rx_crypto_param_len(dp_pdev, enctype)); - ath12k_dp_rx_desc_get_crypto_header(ab, + ath12k_dp_rx_desc_get_crypto_header(dp_pdev->dp->hal, rxcb->rx_desc, crypto_hdr, enctype); } @@ -1095,19 +1093,20 @@ static void ath12k_get_dot11_hdr_from_rx_desc(struct ath12k_pdev_dp *dp_pdev, { struct hal_rx_desc *rx_desc = rxcb->rx_desc; struct ath12k_dp *dp = dp_pdev->dp; - struct ath12k_base *ab = dp->ab; + struct ath12k_hal *hal = dp->hal; size_t hdr_len, crypto_len; struct ieee80211_hdr hdr; __le16 qos_ctl; u8 *crypto_hdr; - ath12k_dp_rx_desc_get_dot11_hdr(ab, rx_desc, &hdr); + ath12k_dp_rx_desc_get_dot11_hdr(hal, rx_desc, &hdr); hdr_len = ieee80211_hdrlen(hdr.frame_control); if (!(rx_info->rx_status->flag & RX_FLAG_IV_STRIPPED)) { crypto_len = ath12k_dp_rx_crypto_param_len(dp_pdev, enctype); crypto_hdr = skb_push(msdu, crypto_len); - ath12k_dp_rx_desc_get_crypto_header(ab, rx_desc, crypto_hdr, enctype); + ath12k_dp_rx_desc_get_crypto_header(dp->hal, rx_desc, crypto_hdr, + enctype); } skb_push(msdu, hdr_len); @@ -1361,7 +1360,6 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc struct hal_rx_desc_data *rx_info) { struct ath12k_dp *dp = dp_pdev->dp; - struct ath12k_base *ab = dp->ab; struct ieee80211_rx_status *rx_status; struct ieee80211_sta *pubsta; struct ath12k_dp_peer *peer; @@ -1380,7 +1378,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc status->link_id = peer->hw_links[rxcb->hw_link_id]; } - ath12k_dbg(ab, ATH12K_DBG_DATA, + ath12k_dbg(dp->ab, ATH12K_DBG_DATA, "rx skb %p len %u peer %pM %d %s sn %u %s%s%s%s%s%s%s%s%s%s rate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", msdu, msdu->len, @@ -1406,7 +1404,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc !!(status->flag & RX_FLAG_MMIC_ERROR), !!(status->flag & RX_FLAG_AMSDU_MORE)); - ath12k_dbg_dump(ab, ATH12K_DBG_DP_RX, NULL, "dp rx msdu: ", + ath12k_dbg_dump(dp->ab, ATH12K_DBG_DP_RX, NULL, "dp rx msdu: ", msdu->data, msdu->len); rx_status = IEEE80211_SKB_RXCB(msdu); @@ -1583,18 +1581,18 @@ void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff } EXPORT_SYMBOL(ath12k_dp_rx_h_undecap_frag); -static int ath12k_dp_rx_h_cmp_frags(struct ath12k_base *ab, +static int ath12k_dp_rx_h_cmp_frags(struct ath12k_hal *hal, struct sk_buff *a, struct sk_buff *b) { int frag1, frag2; - frag1 = ath12k_dp_rx_h_frag_no(ab, a); - frag2 = ath12k_dp_rx_h_frag_no(ab, b); + frag1 = ath12k_dp_rx_h_frag_no(hal, a); + frag2 = ath12k_dp_rx_h_frag_no(hal, b); return frag1 - frag2; } -void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, +void ath12k_dp_rx_h_sort_frags(struct ath12k_hal *hal, struct sk_buff_head *frag_list, struct sk_buff *cur_frag) { @@ -1602,7 +1600,7 @@ void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, int cmp; skb_queue_walk(frag_list, skb) { - cmp = ath12k_dp_rx_h_cmp_frags(ab, skb, cur_frag); + cmp = ath12k_dp_rx_h_cmp_frags(hal, skb, cur_frag); if (cmp < 0) continue; __skb_queue_before(frag_list, skb, cur_frag); diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 51e1de59208d6..916cf41aa5c31 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -106,21 +106,21 @@ static inline u32 ath12k_he_gi_to_nl80211_he_gi(u8 sgi) return ret; } -static inline bool ath12k_dp_rx_h_more_frags(struct ath12k_base *ab, +static inline bool ath12k_dp_rx_h_more_frags(struct ath12k_hal *hal, struct sk_buff *skb) { struct ieee80211_hdr *hdr; - hdr = (struct ieee80211_hdr *)(skb->data + ab->hal.hal_desc_sz); + hdr = (struct ieee80211_hdr *)(skb->data + hal->hal_desc_sz); return ieee80211_has_morefrags(hdr->frame_control); } -static inline u16 ath12k_dp_rx_h_frag_no(struct ath12k_base *ab, +static inline u16 ath12k_dp_rx_h_frag_no(struct ath12k_hal *hal, struct sk_buff *skb) { struct ieee80211_hdr *hdr; - hdr = (struct ieee80211_hdr *)(skb->data + ab->hal.hal_desc_sz); + hdr = (struct ieee80211_hdr *)(skb->data + hal->hal_desc_sz); return le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; } @@ -130,18 +130,18 @@ static inline u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab, return ab->hal.ops->rx_desc_get_l3_pad_bytes(desc); } -static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab, +static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_hal *hal, struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc) { - ab->hal.ops->rx_desc_copy_end_tlv(fdesc, ldesc); + hal->ops->rx_desc_copy_end_tlv(fdesc, ldesc); } -static inline void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab, +static inline void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_hal *hal, struct hal_rx_desc *desc, u16 len) { - ab->hal.ops->rx_desc_set_msdu_len(desc, len); + hal->ops->rx_desc_set_msdu_len(desc, len); } static inline u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, @@ -150,25 +150,25 @@ static inline u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab, return ab->hal.ops->rx_desc_get_mpdu_ppdu_id(rx_desc); } -static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab, +static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_hal *hal, struct hal_rx_desc *desc, struct ieee80211_hdr *hdr) { - ab->hal.ops->rx_desc_get_dot11_hdr(desc, hdr); + hal->ops->rx_desc_get_dot11_hdr(desc, hdr); } -static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab, +static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_hal *hal, struct hal_rx_desc *desc, u8 *crypto_hdr, enum hal_encrypt_type enctype) { - ab->hal.ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); + hal->ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype); } -static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab, +static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_hal *hal, struct hal_rx_desc *desc) { - return ab->hal.ops->rx_desc_get_msdu_src_link_id(desc); + return hal->ops->rx_desc_get_msdu_src_link_id(desc); } static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) @@ -192,7 +192,7 @@ bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_dp *dp, struct sk_buff *msdu, struct hal_rx_desc_data *rx_info); u64 ath12k_dp_rx_h_get_pn(struct ath12k_dp *dp, struct sk_buff *skb); -void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab, +void ath12k_dp_rx_h_sort_frags(struct ath12k_hal *hal, struct sk_buff_head *frag_list, struct sk_buff *cur_frag); void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, @@ -224,7 +224,7 @@ void ath12k_dp_rx_free(struct ath12k_base *ab); int ath12k_dp_rx_pdev_alloc(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int pdev_idx); void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab); -int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab, +int ath12k_dp_rx_bufs_replenish(struct ath12k_dp *dp, struct dp_rxdma_ring *rx_ring, struct list_head *used_list, int req_entries); diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c index bcae34f5db7d6..1d4444f3936ff 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/dp_tx.c @@ -146,10 +146,9 @@ static void ath12k_dp_tx_move_payload(struct sk_buff *skb, } } -int ath12k_dp_tx_align_payload(struct ath12k_base *ab, - struct sk_buff **pskb) +int ath12k_dp_tx_align_payload(struct ath12k_dp *dp, struct sk_buff **pskb) { - u32 iova_mask = ab->hw_params->iova_mask; + u32 iova_mask = dp->hw_params->iova_mask; unsigned long offset, delta1, delta2; struct sk_buff *skb2, *skb = *pskb; unsigned int headroom = skb_headroom(skb); @@ -184,28 +183,29 @@ int ath12k_dp_tx_align_payload(struct ath12k_base *ab, } EXPORT_SYMBOL(ath12k_dp_tx_align_payload); -void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, +void ath12k_dp_tx_free_txbuf(struct ath12k_dp *dp, struct dp_tx_ring *tx_ring, struct ath12k_tx_desc_params *desc_params) { - struct ath12k *ar; + struct ath12k_pdev_dp *dp_pdev; struct sk_buff *msdu = desc_params->skb; struct ath12k_skb_cb *skb_cb; - u8 pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, desc_params->mac_id); + u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(dp->hw_params, desc_params->mac_id); skb_cb = ATH12K_SKB_CB(msdu); - ar = ab->pdevs[pdev_id].ar; - dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); + + dma_unmap_single(dp->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); if (skb_cb->paddr_ext_desc) { - dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, + dma_unmap_single(dp->dev, skb_cb->paddr_ext_desc, desc_params->skb_ext_desc->len, DMA_TO_DEVICE); dev_kfree_skb_any(desc_params->skb_ext_desc); } - ieee80211_free_txskb(ar->ah->hw, msdu); + ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); - if (atomic_dec_and_test(&ar->dp.num_tx_pending)) - wake_up(&ar->dp.tx_empty_waitq); + if (atomic_dec_and_test(&dp_pdev->num_tx_pending)) + wake_up(&dp_pdev->tx_empty_waitq); } EXPORT_SYMBOL(ath12k_dp_tx_free_txbuf); diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.h b/drivers/net/wireless/ath/ath12k/dp_tx.h index 147409f9ac408..7cef20540179f 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/dp_tx.h @@ -20,14 +20,13 @@ ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb); void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb); u8 ath12k_dp_tx_get_tid(struct sk_buff *skb); void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len); -int ath12k_dp_tx_align_payload(struct ath12k_base *ab, - struct sk_buff **pskb); +int ath12k_dp_tx_align_payload(struct ath12k_dp *dp, struct sk_buff **pskb); void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp, struct ath12k_tx_desc_info *tx_desc, u8 pool_id); struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp, u8 pool_id); -void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab, +void ath12k_dp_tx_free_txbuf(struct ath12k_dp *dp, struct dp_tx_ring *tx_ring, struct ath12k_tx_desc_params *desc_params); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 433ffdb552647..30c27e005ed8f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -19,7 +19,6 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, struct ath12k_ext_irq_grp *irq_grp, int budget) { - struct ath12k_base *ab = dp->ab; struct napi_struct *napi = &irq_grp->napi; int grp_id = irq_grp->grp_id; int work_done = 0; @@ -28,21 +27,21 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, enum dp_monitor_mode monitor_mode; u8 ring_mask; - if (ab->hw_params->ring_mask->tx[grp_id]) { - i = fls(ab->hw_params->ring_mask->tx[grp_id]) - 1; - ath12k_wifi7_dp_tx_completion_handler(ab, i); + if (dp->hw_params->ring_mask->tx[grp_id]) { + i = fls(dp->hw_params->ring_mask->tx[grp_id]) - 1; + ath12k_wifi7_dp_tx_completion_handler(dp, i); } - if (ab->hw_params->ring_mask->rx_err[grp_id]) { - work_done = ath12k_wifi7_dp_rx_process_err(ab, napi, budget); + if (dp->hw_params->ring_mask->rx_err[grp_id]) { + work_done = ath12k_wifi7_dp_rx_process_err(dp, napi, budget); budget -= work_done; tot_work_done += work_done; if (budget <= 0) goto done; } - if (ab->hw_params->ring_mask->rx_wbm_rel[grp_id]) { - work_done = ath12k_wifi7_dp_rx_process_wbm_err(ab, napi, budget); + if (dp->hw_params->ring_mask->rx_wbm_rel[grp_id]) { + work_done = ath12k_wifi7_dp_rx_process_wbm_err(dp, napi, budget); budget -= work_done; tot_work_done += work_done; @@ -50,24 +49,24 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, goto done; } - if (ab->hw_params->ring_mask->rx[grp_id]) { - i = fls(ab->hw_params->ring_mask->rx[grp_id]) - 1; - work_done = ath12k_wifi7_dp_rx_process(ab, i, napi, budget); + if (dp->hw_params->ring_mask->rx[grp_id]) { + i = fls(dp->hw_params->ring_mask->rx[grp_id]) - 1; + work_done = ath12k_wifi7_dp_rx_process(dp, i, napi, budget); budget -= work_done; tot_work_done += work_done; if (budget <= 0) goto done; } - if (ab->hw_params->ring_mask->rx_mon_status[grp_id]) { - ring_mask = ab->hw_params->ring_mask->rx_mon_status[grp_id]; - for (i = 0; i < ab->num_radios; i++) { - for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { - int id = i * ab->hw_params->num_rxdma_per_pdev + j; + if (dp->hw_params->ring_mask->rx_mon_status[grp_id]) { + ring_mask = dp->hw_params->ring_mask->rx_mon_status[grp_id]; + for (i = 0; i < dp->ab->num_radios; i++) { + for (j = 0; j < dp->hw_params->num_rxdma_per_pdev; j++) { + int id = i * dp->hw_params->num_rxdma_per_pdev + j; if (ring_mask & BIT(id)) { work_done = - ath12k_dp_mon_process_ring(ab, id, napi, budget, + ath12k_dp_mon_process_ring(dp, id, napi, budget, 0); budget -= work_done; tot_work_done += work_done; @@ -78,16 +77,16 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, } } - if (ab->hw_params->ring_mask->rx_mon_dest[grp_id]) { + if (dp->hw_params->ring_mask->rx_mon_dest[grp_id]) { monitor_mode = ATH12K_DP_RX_MONITOR_MODE; - ring_mask = ab->hw_params->ring_mask->rx_mon_dest[grp_id]; - for (i = 0; i < ab->num_radios; i++) { - for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { - int id = i * ab->hw_params->num_rxdma_per_pdev + j; + ring_mask = dp->hw_params->ring_mask->rx_mon_dest[grp_id]; + for (i = 0; i < dp->ab->num_radios; i++) { + for (j = 0; j < dp->hw_params->num_rxdma_per_pdev; j++) { + int id = i * dp->hw_params->num_rxdma_per_pdev + j; if (ring_mask & BIT(id)) { work_done = - ath12k_dp_mon_process_ring(ab, id, napi, budget, + ath12k_dp_mon_process_ring(dp, id, napi, budget, monitor_mode); budget -= work_done; tot_work_done += work_done; @@ -99,16 +98,16 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, } } - if (ab->hw_params->ring_mask->tx_mon_dest[grp_id]) { + if (dp->hw_params->ring_mask->tx_mon_dest[grp_id]) { monitor_mode = ATH12K_DP_TX_MONITOR_MODE; - ring_mask = ab->hw_params->ring_mask->tx_mon_dest[grp_id]; - for (i = 0; i < ab->num_radios; i++) { - for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) { - int id = i * ab->hw_params->num_rxdma_per_pdev + j; + ring_mask = dp->hw_params->ring_mask->tx_mon_dest[grp_id]; + for (i = 0; i < dp->ab->num_radios; i++) { + for (j = 0; j < dp->hw_params->num_rxdma_per_pdev; j++) { + int id = i * dp->hw_params->num_rxdma_per_pdev + j; if (ring_mask & BIT(id)) { work_done = - ath12k_dp_mon_process_ring(ab, id, napi, budget, + ath12k_dp_mon_process_ring(dp, id, napi, budget, monitor_mode); budget -= work_done; tot_work_done += work_done; @@ -120,15 +119,14 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, } } - if (ab->hw_params->ring_mask->reo_status[grp_id]) - ath12k_wifi7_dp_rx_process_reo_status(ab); + if (dp->hw_params->ring_mask->reo_status[grp_id]) + ath12k_wifi7_dp_rx_process_reo_status(dp); - if (ab->hw_params->ring_mask->host2rxdma[grp_id]) { - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + if (dp->hw_params->ring_mask->host2rxdma[grp_id]) { struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; LIST_HEAD(list); - ath12k_dp_rx_bufs_replenish(ab, rx_ring, &list, 0); + ath12k_dp_rx_bufs_replenish(dp, rx_ring, &list, 0); } /* TODO: Implement handler for other interrupts */ diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index d2026082708e4..2138b20a04d57 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -125,16 +125,16 @@ void ath12k_wifi7_dp_rx_peer_tid_delete(struct ath12k_base *ab, peer->rx_tid_active_bitmask &= ~(1 << tid); } -int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, +int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_dp *dp, struct ath12k_buffer_addr *buf_addr_info, enum hal_wbm_rel_bm_act action) { + struct ath12k_base *ab = dp->ab; struct hal_wbm_release_ring *desc; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct hal_srng *srng; int ret = 0; - srng = &ab->hal.srng_list[dp->wbm_desc_rel_ring.ring_id]; + srng = &dp->hal->srng_list[dp->wbm_desc_rel_ring.ring_id]; spin_lock_bh(&srng->lock); @@ -411,19 +411,18 @@ static void ath12k_wifi7_dp_rx_h_mpdu(struct ath12k_pdev_dp *dp_pdev, } } -static int ath12k_wifi7_dp_rx_msdu_coalesce(struct ath12k_dp *dp, +static int ath12k_wifi7_dp_rx_msdu_coalesce(struct ath12k_hal *hal, struct sk_buff_head *msdu_list, struct sk_buff *first, struct sk_buff *last, u8 l3pad_bytes, int msdu_len, struct hal_rx_desc_data *rx_info) { - struct ath12k_base *ab = dp->ab; struct sk_buff *skb; struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(first); int buf_first_hdr_len, buf_first_len; struct hal_rx_desc *ldesc; int space_extra, rem_len, buf_len; - u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; + u32 hal_rx_desc_sz = hal->hal_desc_sz; bool is_continuation; /* As the msdu is spread across multiple rx buffers, @@ -453,7 +452,7 @@ static int ath12k_wifi7_dp_rx_msdu_coalesce(struct ath12k_dp *dp, /* When an MSDU spread over multiple buffers MSDU_END * tlvs are valid only in the last buffer. Copy those tlvs. */ - ath12k_dp_rx_desc_end_tlv_copy(ab, rxcb->rx_desc, ldesc); + ath12k_dp_rx_desc_end_tlv_copy(hal, rxcb->rx_desc, ldesc); space_extra = msdu_len - (buf_first_len + skb_tailroom(first)); if (space_extra > 0 && @@ -505,18 +504,18 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_desc_data *rx_info) { struct ath12k_dp *dp = dp_pdev->dp; - struct ath12k_base *ab = dp->ab; struct hal_rx_desc *rx_desc, *lrx_desc; struct ath12k_skb_rxcb *rxcb; struct sk_buff *last_buf; + struct ath12k_hal *hal = dp->hal; u8 l3_pad_bytes; u16 msdu_len; int ret; - u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; + u32 hal_rx_desc_sz = hal->hal_desc_sz; last_buf = ath12k_dp_rx_get_msdu_last_buf(msdu_list, msdu); if (!last_buf) { - ath12k_warn(ab, + ath12k_warn(dp->ab, "No valid Rx buffer to access MSDU_END tlv\n"); ret = -EIO; goto free_out; @@ -525,9 +524,9 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k_pdev_dp *dp_pdev, rx_desc = (struct hal_rx_desc *)msdu->data; lrx_desc = (struct hal_rx_desc *)last_buf->data; - ath12k_wifi7_dp_extract_rx_desc_data(ab, rx_info, rx_desc, lrx_desc); + ath12k_wifi7_dp_extract_rx_desc_data(hal, rx_info, rx_desc, lrx_desc); if (!rx_info->msdu_done) { - ath12k_warn(ab, "msdu_done bit in msdu_end is not set\n"); + ath12k_warn(dp->ab, "msdu_done bit in msdu_end is not set\n"); ret = -EIO; goto free_out; } @@ -542,20 +541,20 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k_pdev_dp *dp_pdev, } else if (!rxcb->is_continuation) { if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { ret = -EINVAL; - ath12k_warn(ab, "invalid msdu len %u\n", msdu_len); - ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", rx_desc, + ath12k_warn(dp->ab, "invalid msdu len %u\n", msdu_len); + ath12k_dbg_dump(dp->ab, ATH12K_DBG_DATA, NULL, "", rx_desc, sizeof(*rx_desc)); goto free_out; } skb_put(msdu, hal_rx_desc_sz + l3_pad_bytes + msdu_len); skb_pull(msdu, hal_rx_desc_sz + l3_pad_bytes); } else { - ret = ath12k_wifi7_dp_rx_msdu_coalesce(dp, msdu_list, + ret = ath12k_wifi7_dp_rx_msdu_coalesce(hal, msdu_list, msdu, last_buf, l3_pad_bytes, msdu_len, rx_info); if (ret) { - ath12k_warn(ab, + ath12k_warn(dp->ab, "failed to coalesce msdu rx buffer%d\n", ret); goto free_out; } @@ -579,12 +578,11 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k_pdev_dp *dp_pdev, } static void -ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, +ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_dp *dp, struct napi_struct *napi, struct sk_buff_head *msdu_list, int ring_id) { - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_hw_group *ag = dp->ag; struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct ieee80211_rx_status rx_status = {}; @@ -634,7 +632,7 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, ret = ath12k_wifi7_dp_rx_process_msdu(dp_pdev, msdu, msdu_list, &rx_info); if (ret) { - ath12k_dbg(ab, ATH12K_DBG_DATA, + ath12k_dbg(dp->ab, ATH12K_DBG_DATA, "Unable to process msdu %d", ret); dev_kfree_skb_any(msdu); continue; @@ -646,11 +644,12 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, rcu_read_unlock(); } -int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, +int ath12k_wifi7_dp_rx_process(struct ath12k_dp *dp, int ring_id, struct napi_struct *napi, int budget) { - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_hw_group *ag = dp->ag; + struct ath12k_base *ab = dp->ab; + struct ath12k_hal *hal = dp->hal; struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; struct ath12k_hw_link *hw_links = ag->hw_links; @@ -659,7 +658,6 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; struct hal_reo_dest_ring *desc; struct ath12k_dp *partner_dp; - struct ath12k_base *partner_ab; struct sk_buff_head msdu_list; struct ath12k_skb_rxcb *rxcb; int total_msdu_reaped = 0; @@ -674,7 +672,7 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) INIT_LIST_HEAD(&rx_desc_used_list[device_id]); - srng = &ab->hal.srng_list[dp->reo_dst_ring[ring_id].ring_id]; + srng = &hal->srng_list[dp->reo_dst_ring[ring_id].ring_id]; spin_lock_bh(&srng->lock); @@ -707,13 +705,12 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, continue; } - partner_ab = partner_dp->ab; /* retry manual desc retrieval */ if (!desc_info) { - desc_info = ath12k_dp_get_rx_desc(partner_ab, cookie); + desc_info = ath12k_dp_get_rx_desc(partner_dp, cookie); if (!desc_info) { - ath12k_warn(partner_ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n", + ath12k_warn(partner_dp->ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n", cookie); continue; } @@ -728,12 +725,12 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]); rxcb = ATH12K_SKB_RXCB(msdu); - dma_unmap_single(partner_ab->dev, rxcb->paddr, + dma_unmap_single(partner_dp->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), DMA_FROM_DEVICE); num_buffs_reaped[device_id]++; - dp->device_stats.reo_rx[ring_id][ab->device_id]++; + dp->device_stats.reo_rx[ring_id][dp->device_id]++; push_reason = le32_get_bits(desc->info0, HAL_REO_DEST_RING_INFO0_PUSH_REASON); @@ -795,15 +792,14 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, continue; partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); - partner_ab = partner_dp->ab; rx_ring = &partner_dp->rx_refill_buf_ring; - ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, + ath12k_dp_rx_bufs_replenish(partner_dp, rx_ring, &rx_desc_used_list[device_id], num_buffs_reaped[device_id]); } - ath12k_wifi7_dp_rx_process_received_packets(ab, napi, &msdu_list, + ath12k_wifi7_dp_rx_process_received_packets(dp, napi, &msdu_list, ring_id); exit: @@ -846,6 +842,7 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k_dp *dp, struct sk_buff *defrag_skb) { struct ath12k_base *ab = dp->ab; + struct ath12k_hal *hal = dp->hal; struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)defrag_skb->data; struct hal_reo_entrance_ring *reo_ent_ring; struct hal_reo_dest_ring *reo_dest_ring; @@ -861,11 +858,11 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k_dp *dp, enum hal_rx_buf_return_buf_manager idle_link_rbm = dp->idle_link_rbm; u8 dst_ind; - hal_rx_desc_sz = ab->hal.hal_desc_sz; + hal_rx_desc_sz = hal->hal_desc_sz; link_desc_banks = dp->link_desc_banks; reo_dest_ring = rx_tid->dst_ring_desc; - ath12k_wifi7_hal_rx_reo_ent_paddr_get(ab, &reo_dest_ring->buf_addr_info, + ath12k_wifi7_hal_rx_reo_ent_paddr_get(&reo_dest_ring->buf_addr_info, &link_paddr, &cookie); desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK); @@ -888,12 +885,12 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k_dp *dp, msdu0->rx_msdu_ext_info.info0 = cpu_to_le32(msdu_ext_info); /* change msdu len in hal rx desc */ - ath12k_dp_rxdesc_set_msdu_len(ab, rx_desc, defrag_skb->len - hal_rx_desc_sz); + ath12k_dp_rxdesc_set_msdu_len(hal, rx_desc, defrag_skb->len - hal_rx_desc_sz); - buf_paddr = dma_map_single(ab->dev, defrag_skb->data, + buf_paddr = dma_map_single(dp->dev, defrag_skb->data, defrag_skb->len + skb_tailroom(defrag_skb), DMA_TO_DEVICE); - if (dma_mapping_error(ab->dev, buf_paddr)) + if (dma_mapping_error(dp->dev, buf_paddr)) return -ENOMEM; spin_lock_bh(&dp->rx_desc_lock); @@ -920,7 +917,7 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k_dp *dp, HAL_RX_BUF_RBM_SW3_BM); /* Fill mpdu details into reo entrance ring */ - srng = &ab->hal.srng_list[dp->reo_reinject_ring.ring_id]; + srng = &hal->srng_list[dp->reo_reinject_ring.ring_id]; spin_lock_bh(&srng->lock); ath12k_hal_srng_access_begin(ab, srng); @@ -947,7 +944,7 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k_dp *dp, reo_ent_ring->rx_mpdu_info.peer_meta_data = reo_dest_ring->rx_mpdu_info.peer_meta_data; - if (ab->hw_params->reoq_lut_support) { + if (dp->hw_params->reoq_lut_support) { reo_ent_ring->queue_addr_lo = reo_dest_ring->rx_mpdu_info.peer_meta_data; queue_addr_hi = 0; } else { @@ -981,7 +978,7 @@ static int ath12k_wifi7_dp_rx_h_defrag_reo_reinject(struct ath12k_dp *dp, list_add_tail(&desc_info->list, &dp->rx_desc_free_list); spin_unlock_bh(&dp->rx_desc_lock); err_unmap_dma: - dma_unmap_single(ab->dev, buf_paddr, defrag_skb->len + skb_tailroom(defrag_skb), + dma_unmap_single(dp->dev, buf_paddr, defrag_skb->len + skb_tailroom(defrag_skb), DMA_TO_DEVICE); return ret; } @@ -993,7 +990,7 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_desc_data *rx_info) { struct ath12k_dp *dp = dp_pdev->dp; - struct ath12k_base *ab = dp->ab; + struct ath12k_hal *hal = dp->hal; struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data; struct ieee80211_rx_status *rxs = IEEE80211_SKB_RXCB(msdu); struct ieee80211_key_conf *key_conf; @@ -1001,7 +998,7 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, u8 mic[IEEE80211_CCMP_MIC_LEN]; int head_len, tail_len, ret; size_t data_len; - u32 hdr_len, hal_rx_desc_sz = ab->hal.hal_desc_sz; + u32 hdr_len, hal_rx_desc_sz = hal->hal_desc_sz; u8 *key, *data; u8 key_idx; @@ -1038,7 +1035,7 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, (ATH12K_SKB_RXCB(msdu))->is_first_msdu = true; (ATH12K_SKB_RXCB(msdu))->is_last_msdu = true; - ath12k_wifi7_dp_extract_rx_desc_data(ab, rx_info, rx_desc, rx_desc); + ath12k_wifi7_dp_extract_rx_desc_data(hal, rx_info, rx_desc, rx_desc); rxs->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_MMIC_STRIPPED | RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED; @@ -1135,7 +1132,7 @@ void ath12k_wifi7_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, if (rx_tid->dst_ring_desc) { if (rel_link_desc) { buf_addr_info = &rx_tid->dst_ring_desc->buf_addr_info; - ath12k_wifi7_dp_rx_link_desc_return(dp->ab, buf_addr_info, act); + ath12k_wifi7_dp_rx_link_desc_return(dp, buf_addr_info, act); } kfree(rx_tid->dst_ring_desc); rx_tid->dst_ring_desc = NULL; @@ -1153,6 +1150,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_desc_data *rx_info) { struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_hal *hal = dp->hal; struct ath12k_base *ab = dp->ab; struct ath12k_dp_peer *peer; struct ath12k_dp_rx_tid *rx_tid; @@ -1164,8 +1162,8 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, bool more_frags; enum hal_encrypt_type enctype = rx_info->enctype; - frag_no = ath12k_dp_rx_h_frag_no(ab, msdu); - more_frags = ath12k_dp_rx_h_more_frags(ab, msdu); + frag_no = ath12k_dp_rx_h_frag_no(hal, msdu); + more_frags = ath12k_dp_rx_h_more_frags(hal, msdu); seqno = rx_info->seq_no; if (!rx_info->seq_ctl_valid || !rx_info->fc_valid || @@ -1214,7 +1212,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, if ((!rx_tid->rx_frag_bitmap || frag_no > __fls(rx_tid->rx_frag_bitmap))) __skb_queue_tail(&rx_tid->rx_frags, msdu); else - ath12k_dp_rx_h_sort_frags(ab, &rx_tid->rx_frags, msdu); + ath12k_dp_rx_h_sort_frags(hal, &rx_tid->rx_frags, msdu); rx_tid->rx_frag_bitmap |= BIT(frag_no); if (!more_frags) @@ -1229,7 +1227,7 @@ static int ath12k_wifi7_dp_rx_frag_h_mpdu(struct ath12k_pdev_dp *dp_pdev, goto out_unlock; } } else { - ath12k_wifi7_dp_rx_link_desc_return(ab, &ring_desc->buf_addr_info, + ath12k_wifi7_dp_rx_link_desc_return(dp, &ring_desc->buf_addr_info, HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); } @@ -1280,13 +1278,13 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, { struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); struct ath12k_dp *dp = dp_pdev->dp; - struct ath12k_base *ab = dp->ab; + struct ath12k_hal *hal = dp->hal; struct sk_buff *msdu; struct ath12k_skb_rxcb *rxcb; struct hal_rx_desc_data rx_info; struct hal_rx_desc *rx_desc; u16 msdu_len; - u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; + u32 hal_rx_desc_sz = hal->hal_desc_sz; struct ath12k_rx_desc_info *desc_info; u64 desc_va; @@ -1296,16 +1294,17 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, /* retry manual desc retrieval */ if (!desc_info) { - desc_info = ath12k_dp_get_rx_desc(ab, cookie); + desc_info = ath12k_dp_get_rx_desc(dp, cookie); if (!desc_info) { - ath12k_warn(ab, "Invalid cookie in DP rx error descriptor retrieval: 0x%x\n", + ath12k_warn(dp->ab, + "Invalid cookie in DP rx error descriptor retrieval: 0x%x\n", cookie); return -EINVAL; } } if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) - ath12k_warn(ab, " RX Exception, Check HW CC implementation"); + ath12k_warn(dp->ab, "RX Exception, Check HW CC implementation"); msdu = desc_info->skb; desc_info->skb = NULL; @@ -1313,7 +1312,7 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, list_add_tail(&desc_info->list, used_list); rxcb = ATH12K_SKB_RXCB(msdu); - dma_unmap_single(ab->dev, rxcb->paddr, + dma_unmap_single(dp->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), DMA_FROM_DEVICE); @@ -1334,12 +1333,12 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, } rx_desc = (struct hal_rx_desc *)msdu->data; - ath12k_wifi7_dp_extract_rx_desc_data(ab, &rx_info, rx_desc, rx_desc); + ath12k_wifi7_dp_extract_rx_desc_data(hal, &rx_info, rx_desc, rx_desc); msdu_len = rx_info.msdu_len; if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { - ath12k_warn(ab, "invalid msdu leng %u", msdu_len); - ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", rx_desc, + ath12k_warn(dp->ab, "invalid msdu leng %u", msdu_len); + ath12k_dbg_dump(dp->ab, ATH12K_DBG_DATA, NULL, "", rx_desc, sizeof(*rx_desc)); dev_kfree_skb_any(msdu); goto exit; @@ -1349,7 +1348,7 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, if (ath12k_wifi7_dp_rx_frag_h_mpdu(dp_pdev, msdu, desc, &rx_info)) { dev_kfree_skb_any(msdu); - ath12k_wifi7_dp_rx_link_desc_return(ar->ab, &desc->buf_addr_info, + ath12k_wifi7_dp_rx_link_desc_return(dp, &desc->buf_addr_info, HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); } exit: @@ -1357,10 +1356,11 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, return 0; } -int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, +int ath12k_wifi7_dp_rx_process_err(struct ath12k_dp *dp, struct napi_struct *napi, int budget) { - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_base *ab = dp->ab; + struct ath12k_hal *hal = dp->hal; struct ath12k_hw_group *ag = dp->ag; struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct ath12k_dp *partner_dp; @@ -1375,7 +1375,6 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n struct dp_rxdma_ring *rx_ring; struct dp_srng *reo_except; struct ath12k_hw_link *hw_links = ag->hw_links; - struct ath12k_base *partner_ab; struct ath12k_pdev_dp *dp_pdev; u8 hw_link_id, device_id; u32 desc_bank, num_msdus; @@ -1395,7 +1394,7 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n reo_except = &dp->reo_except_ring; - srng = &ab->hal.srng_list[reo_except->ring_id]; + srng = &hal->srng_list[reo_except->ring_id]; spin_lock_bh(&srng->lock); @@ -1406,7 +1405,7 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n drop = false; dp->device_stats.err_ring_pkts++; - ret = ath12k_wifi7_hal_desc_reo_parse_err(ab, reo_desc, &paddr, + ret = ath12k_wifi7_hal_desc_reo_parse_err(dp, reo_desc, &paddr, &desc_bank); if (ret) { ath12k_warn(ab, "failed to parse error reo desc %d\n", @@ -1418,9 +1417,8 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); device_id = hw_links[hw_link_id].device_id; partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); - partner_ab = partner_dp->ab; - pdev_idx = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + pdev_idx = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params, hw_links[hw_link_id].pdev_idx); link_desc_banks = partner_dp->link_desc_banks; @@ -1430,11 +1428,11 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n msdu_cookies, &rbm); if (rbm != partner_dp->idle_link_rbm && rbm != HAL_RX_BUF_RBM_SW3_BM && - rbm != partner_ab->hal.hal_params->rx_buf_rbm) { + rbm != partner_dp->hal->hal_params->rx_buf_rbm) { act = HAL_WBM_REL_BM_ACT_REL_MSDU; dp->device_stats.invalid_rbm++; ath12k_warn(ab, "invalid return buffer manager %d\n", rbm); - ath12k_wifi7_dp_rx_link_desc_return(partner_ab, + ath12k_wifi7_dp_rx_link_desc_return(partner_dp, &reo_desc->buf_addr_info, act); continue; @@ -1449,12 +1447,12 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n * partner device buffers. */ if (!is_frag || num_msdus > 1 || - partner_ab->device_id != ab->device_id) { + partner_dp->device_id != dp->device_id) { drop = true; act = HAL_WBM_REL_BM_ACT_PUT_IN_IDLE; /* Return the link desc back to wbm idle list */ - ath12k_wifi7_dp_rx_link_desc_return(partner_ab, + ath12k_wifi7_dp_rx_link_desc_return(partner_dp, &reo_desc->buf_addr_info, act); } @@ -1499,10 +1497,9 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n continue; partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); - partner_ab = partner_dp->ab; rx_ring = &partner_dp->rx_refill_buf_ring; - ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, + ath12k_dp_rx_bufs_replenish(partner_dp, rx_ring, &rx_desc_used_list[device_id], num_buffs_reaped[device_id]); } @@ -1717,7 +1714,7 @@ static void ath12k_wifi7_dp_rx_wbm_err(struct ath12k_pdev_dp *dp_pdev, rx_info.addr2_present = false; rx_info.rx_status = &rxs; - ath12k_wifi7_dp_extract_rx_desc_data(dp->ab, &rx_info, rx_desc, rx_desc); + ath12k_wifi7_dp_extract_rx_desc_data(dp->hal, &rx_info, rx_desc, rx_desc); switch (rxcb->err_rel_src) { case HAL_WBM_REL_SRC_MODULE_REO: @@ -1771,13 +1768,14 @@ void ath12k_wifi7_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, cmd->addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned); } -int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, +int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp, struct napi_struct *napi, int budget) { struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; + struct ath12k_base *ab = dp->ab; + struct ath12k_hal *hal = dp->hal; struct ath12k *ar; struct ath12k_pdev_dp *dp_pdev; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); struct ath12k_hw_group *ag = dp->ag; struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct ath12k_dp *partner_dp; @@ -1803,7 +1801,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) INIT_LIST_HEAD(&rx_desc_used_list[device_id]); - srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id]; + srng = &hal->srng_list[dp->rx_rel_ring.ring_id]; spin_lock_bh(&srng->lock); ath12k_hal_srng_access_begin(ab, srng); @@ -1813,11 +1811,10 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, if (!rx_desc) break; - ret = ath12k_wifi7_hal_wbm_desc_parse_err(ab, rx_desc, + ret = ath12k_wifi7_hal_wbm_desc_parse_err(dp, rx_desc, &err_info); if (ret) { - ath12k_warn(ab, - "failed to parse rx error in wbm_rel ring desc %d\n", + ath12k_warn(ab, "failed to parse rx error in wbm_rel ring desc %d\n", ret); continue; } @@ -1826,7 +1823,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, /* retry manual desc retrieval if hw cc is not done */ if (!desc_info) { - desc_info = ath12k_dp_get_rx_desc(ab, err_info.cookie); + desc_info = ath12k_dp_get_rx_desc(dp, err_info.cookie); if (!desc_info) { ath12k_warn(ab, "Invalid cookie in DP WBM rx error descriptor retrieval: 0x%x\n", err_info.cookie); @@ -1886,7 +1883,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, continue; } - hw_link_id = ath12k_dp_rx_get_msdu_src_link(partner_dp->ab, + hw_link_id = ath12k_dp_rx_get_msdu_src_link(partner_dp->hal, msdu_data); if (hw_link_id >= ATH12K_GROUP_MAX_RADIO) { dev_kfree_skb_any(msdu); @@ -1934,7 +1931,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); rx_ring = &partner_dp->rx_refill_buf_ring; - ath12k_dp_rx_bufs_replenish(ab, rx_ring, + ath12k_dp_rx_bufs_replenish(dp, rx_ring, &rx_desc_used_list[device_id], num_buffs_reaped[device_id]); } @@ -1975,7 +1972,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, } if (rxcb->err_rel_src < HAL_WBM_REL_SRC_MODULE_MAX) { - device_id = ar->ab->device_id; + device_id = dp_pdev->dp->device_id; device_stats->rx_wbm_rel_source[rxcb->err_rel_src][device_id]++; } @@ -2065,9 +2062,10 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) return ret; } -void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_base *ab) +void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_dp *dp) { - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_base *ab = dp->ab; + struct ath12k_hal *hal = dp->hal; struct hal_tlv_64_hdr *hdr; struct hal_srng *srng; struct ath12k_dp_rx_reo_cmd *cmd, *tmp; @@ -2075,7 +2073,7 @@ void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_base *ab) u16 tag; struct hal_reo_status reo_status; - srng = &ab->hal.srng_list[dp->reo_status_ring.ring_id]; + srng = &hal->srng_list[dp->reo_status_ring.ring_id]; memset(&reo_status, 0, sizeof(reo_status)); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 85677258b1df1..b92f9cf173dc8 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -12,14 +12,14 @@ struct ath12k_hal_reo_cmd; -int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, +int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp, struct napi_struct *napi, int budget); -int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, +int ath12k_wifi7_dp_rx_process_err(struct ath12k_dp *dp, struct napi_struct *napi, int budget); -int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int mac_id, +int ath12k_wifi7_dp_rx_process(struct ath12k_dp *dp, int mac_id, struct napi_struct *napi, int budget); -void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_base *ab); +void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_dp *dp); int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); void ath12k_wifi7_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, @@ -28,7 +28,7 @@ void ath12k_wifi7_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, int ath12k_wifi7_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_dp_peer *dp_peer, struct ath12k_dp_rx_tid *rx_tid, u16 ssn, enum hal_pn_type pn_type); -int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_base *ab, +int ath12k_wifi7_dp_rx_link_desc_return(struct ath12k_dp *dp, struct ath12k_buffer_addr *buf_addr_info, enum hal_wbm_rel_bm_act action); void ath12k_wifi7_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid, @@ -50,11 +50,11 @@ int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k_dp *dp, u32 ba_win_sz, u16 ssn, bool update_ssn); static inline -void ath12k_wifi7_dp_extract_rx_desc_data(struct ath12k_base *ab, +void ath12k_wifi7_dp_extract_rx_desc_data(struct ath12k_hal *hal, struct hal_rx_desc_data *rx_info, struct hal_rx_desc *rx_desc, struct hal_rx_desc *ldesc) { - ab->hal.ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); + hal->ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); } #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c index bb8c2384c13ea..629084aa36d85 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c @@ -63,6 +63,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a bool is_mcast) { struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_hal *hal = dp->hal; struct ath12k_base *ab = dp->ab; struct hal_tx_info ti = {}; struct ath12k_tx_desc_info *tx_desc; @@ -84,7 +85,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a bool tcl_ring_retry; bool msdu_ext_desc = false; bool add_htt_metadata = false; - u32 iova_mask = ab->hw_params->iova_mask; + u32 iova_mask = dp->hw_params->iova_mask; bool is_diff_encap = false; bool is_null_frame = false; @@ -104,14 +105,14 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a * If all rings are full, we drop the packet. * TODO: Add throttling logic when all rings are full */ - ring_selector = ab->hw_params->hw_ops->get_ring_selector(skb); + ring_selector = dp->hw_params->hw_ops->get_ring_selector(skb); tcl_ring_sel: tcl_ring_retry = false; - ti.ring_id = ring_selector % ab->hw_params->max_tx_ring; + ti.ring_id = ring_selector % dp->hw_params->max_tx_ring; ring_map |= BIT(ti.ring_id); - ti.rbm_id = ab->hal.tcl_to_wbm_rbm_map[ti.ring_id].rbm_id; + ti.rbm_id = hal->tcl_to_wbm_rbm_map[ti.ring_id].rbm_id; tx_ring = &dp->tx_ring[ti.ring_id]; @@ -212,7 +213,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a if (iova_mask && (unsigned long)skb->data & iova_mask) { - ret = ath12k_dp_tx_align_payload(ab, &skb); + ret = ath12k_dp_tx_align_payload(dp, &skb); if (ret) { ath12k_warn(ab, "failed to align TX buffer %d\n", ret); /* don't bail out, give original buffer @@ -227,8 +228,8 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a hdr = (void *)skb->data; } map: - ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE); - if (dma_mapping_error(ab->dev, ti.paddr)) { + ti.paddr = dma_map_single(dp->dev, skb->data, skb->len, DMA_TO_DEVICE); + if (dma_mapping_error(dp->dev, ti.paddr)) { atomic_inc(&dp->device_stats.tx_err.misc_fail); ath12k_warn(ab, "failed to DMA map data Tx buffer\n"); ret = -ENOMEM; @@ -286,9 +287,9 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a } } - ti.paddr = dma_map_single(ab->dev, skb_ext_desc->data, + ti.paddr = dma_map_single(dp->dev, skb_ext_desc->data, skb_ext_desc->len, DMA_TO_DEVICE); - ret = dma_mapping_error(ab->dev, ti.paddr); + ret = dma_mapping_error(dp->dev, ti.paddr); if (ret) goto fail_free_ext_skb; @@ -300,7 +301,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a } hal_ring_id = tx_ring->tcl_data_ring.ring_id; - tcl_ring = &ab->hal.srng_list[hal_ring_id]; + tcl_ring = &hal->srng_list[hal_ring_id]; spin_lock_bh(&tcl_ring->lock); @@ -321,8 +322,8 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a * checking this ring earlier for each pkt tx. * Restart ring selection if some rings are not checked yet. */ - if (ring_map != (BIT(ab->hw_params->max_tx_ring) - 1) && - ab->hw_params->tcl_ring_retry) { + if (ring_map != (BIT(dp->hw_params->max_tx_ring) - 1) && + dp->hw_params->tcl_ring_retry) { tcl_ring_retry = true; ring_selector++; } @@ -358,14 +359,14 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a fail_unmap_dma_ext: if (skb_cb->paddr_ext_desc) - dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, + dma_unmap_single(dp->dev, skb_cb->paddr_ext_desc, skb_ext_desc->len, DMA_TO_DEVICE); fail_free_ext_skb: kfree_skb(skb_ext_desc); fail_unmap_dma: - dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE); + dma_unmap_single(dp->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE); fail_remove_tx_buf: ath12k_dp_tx_release_txbuf(dp, tx_desc, pool_id); @@ -381,37 +382,45 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *a } static void -ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, +ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_dp *dp, struct ath12k_tx_desc_params *desc_params, struct dp_tx_ring *tx_ring, struct ath12k_dp_htt_wbm_tx_status *ts, u16 peer_id) { + struct ath12k_base *ab = dp->ab; struct ieee80211_tx_info *info; struct ath12k_link_vif *arvif; struct ath12k_skb_cb *skb_cb; struct ieee80211_vif *vif; struct ath12k_vif *ahvif; - struct ath12k *ar; struct sk_buff *msdu = desc_params->skb; s32 noise_floor; struct ieee80211_tx_status status = {}; struct ath12k_dp_link_peer *peer; struct ath12k_pdev_dp *dp_pdev; + u8 pdev_id; skb_cb = ATH12K_SKB_CB(msdu); info = IEEE80211_SKB_CB(msdu); - ar = skb_cb->ar; - dp_pdev = &ar->dp; - ab->dp->device_stats.tx_completed[tx_ring->tcl_data_ring_id]++; + pdev_id = ath12k_hw_mac_id_to_pdev_id(dp->hw_params, desc_params->mac_id); - if (atomic_dec_and_test(&ar->dp.num_tx_pending)) - wake_up(&ar->dp.tx_empty_waitq); + rcu_read_lock(); + dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_id); + if (!dp_pdev) { + rcu_read_unlock(); + return; + } - dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + dp->device_stats.tx_completed[tx_ring->tcl_data_ring_id]++; + + if (atomic_dec_and_test(&dp_pdev->num_tx_pending)) + wake_up(&dp_pdev->tx_empty_waitq); + + dma_unmap_single(dp->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); if (skb_cb->paddr_ext_desc) { - dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, + dma_unmap_single(dp->dev, skb_cb->paddr_ext_desc, desc_params->skb_ext_desc->len, DMA_TO_DEVICE); dev_kfree_skb_any(desc_params->skb_ext_desc); } @@ -419,14 +428,12 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, vif = skb_cb->vif; if (vif) { ahvif = ath12k_vif_to_ahvif(vif); - rcu_read_lock(); arvif = rcu_dereference(ahvif->link[skb_cb->link_id]); if (arvif) { spin_lock_bh(&arvif->link_stats_lock); arvif->link_stats.tx_completed++; spin_unlock_bh(&arvif->link_stats_lock); } - rcu_read_unlock(); } memset(&info->status, 0, sizeof(info->status)); @@ -438,6 +445,8 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, if (!test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, ab->wmi_ab.svc_map)) { + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); + spin_lock_bh(&ar->data_lock); noise_floor = ath12k_pdev_get_noise_floor(ar); spin_unlock_bh(&ar->data_lock); @@ -450,12 +459,12 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; } } - rcu_read_lock(); + peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, peer_id); if (!peer || !peer->sta) { ath12k_dbg(ab, ATH12K_DBG_DATA, "dp_tx: failed to find the peer with peer_id %d\n", peer_id); - ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu); + ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); goto exit; } else { status.sta = peer->sta; @@ -463,20 +472,19 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab, status.info = info; status.skb = msdu; - ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status); + ieee80211_tx_status_ext(ath12k_pdev_dp_to_hw(dp_pdev), &status); exit: rcu_read_unlock(); } static void -ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc, +ath12k_dp_tx_process_htt_tx_complete(struct ath12k_dp *dp, void *desc, struct dp_tx_ring *tx_ring, struct ath12k_tx_desc_params *desc_params) { struct htt_tx_wbm_completion *status_desc; struct ath12k_dp_htt_wbm_tx_status ts = {}; enum hal_wbm_htt_tx_comp_status wbm_status; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); u16 peer_id; status_desc = desc; @@ -494,14 +502,14 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc, peer_id = le32_get_bits(((struct hal_wbm_completion_ring_tx *)desc)-> info3, HAL_WBM_COMPL_TX_INFO3_PEER_ID); - ath12k_dp_tx_htt_tx_complete_buf(ab, desc_params, tx_ring, &ts, peer_id); + ath12k_dp_tx_htt_tx_complete_buf(dp, desc_params, tx_ring, &ts, peer_id); break; case HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP: case HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL: case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ: case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT: case HAL_WBM_REL_HTT_TX_COMP_STATUS_VDEVID_MISMATCH: - ath12k_dp_tx_free_txbuf(ab, tx_ring, desc_params); + ath12k_dp_tx_free_txbuf(dp, tx_ring, desc_params); break; case HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY: /* This event is to be handled only when the driver decides to @@ -509,7 +517,7 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc, */ break; default: - ath12k_warn(ab, "Unknown htt wbm tx status %d\n", wbm_status); + ath12k_warn(dp->ab, "Unknown htt wbm tx status %d\n", wbm_status); break; } } @@ -519,7 +527,6 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, { struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_dp_link_peer *peer; - struct ath12k_base *ab = dp->ab; struct ath12k_link_sta *arsta; struct rate_info txrate = {}; struct ieee80211_sta *sta; @@ -530,7 +537,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, ts->peer_id); if (!peer || !peer->sta) { - ath12k_dbg(ab, ATH12K_DBG_DP_TX, + ath12k_dbg(dp->ab, ATH12K_DBG_DP_TX, "failed to find the peer by id %u\n", ts->peer_id); return; } @@ -559,7 +566,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, &rate_idx, &rate); if (ret < 0) { - ath12k_warn(ab, "Invalid tx legacy rate %d\n", ret); + ath12k_warn(dp->ab, "Invalid tx legacy rate %d\n", ret); return; } @@ -567,7 +574,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, break; case HAL_TX_RATE_STATS_PKT_TYPE_11N: if (ts->mcs > ATH12K_HT_MCS_MAX) { - ath12k_warn(ab, "Invalid HT mcs index %d\n", ts->mcs); + ath12k_warn(dp->ab, "Invalid HT mcs index %d\n", ts->mcs); return; } @@ -581,7 +588,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, break; case HAL_TX_RATE_STATS_PKT_TYPE_11AC: if (ts->mcs > ATH12K_VHT_MCS_MAX) { - ath12k_warn(ab, "Invalid VHT mcs index %d\n", ts->mcs); + ath12k_warn(dp->ab, "Invalid VHT mcs index %d\n", ts->mcs); return; } @@ -593,7 +600,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, break; case HAL_TX_RATE_STATS_PKT_TYPE_11AX: if (ts->mcs > ATH12K_HE_MCS_MAX) { - ath12k_warn(ab, "Invalid HE mcs index %d\n", ts->mcs); + ath12k_warn(dp->ab, "Invalid HE mcs index %d\n", ts->mcs); return; } @@ -603,7 +610,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, break; case HAL_TX_RATE_STATS_PKT_TYPE_11BE: if (ts->mcs > ATH12K_EHT_MCS_MAX) { - ath12k_warn(ab, "Invalid EHT mcs index %d\n", ts->mcs); + ath12k_warn(dp->ab, "Invalid EHT mcs index %d\n", ts->mcs); return; } @@ -612,7 +619,7 @@ static void ath12k_wifi7_dp_tx_update_txcompl(struct ath12k_pdev_dp *dp_pdev, txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(ts->sgi); break; default: - ath12k_warn(ab, "Invalid tx pkt type: %d\n", ts->pkt_type); + ath12k_warn(dp->ab, "Invalid tx pkt type: %d\n", ts->pkt_type); return; } @@ -663,9 +670,9 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, skb_cb = ATH12K_SKB_CB(msdu); dp->device_stats.tx_completed[ring]++; - dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + dma_unmap_single(dp->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); if (skb_cb->paddr_ext_desc) { - dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc, + dma_unmap_single(dp->dev, skb_cb->paddr_ext_desc, desc_params->skb_ext_desc->len, DMA_TO_DEVICE); dev_kfree_skb_any(desc_params->skb_ext_desc); } @@ -773,7 +780,7 @@ static void ath12k_wifi7_dp_tx_complete_msdu(struct ath12k_pdev_dp *dp_pdev, } static void -ath12k_wifi7_dp_tx_status_parse(struct ath12k_base *ab, +ath12k_wifi7_dp_tx_status_parse(struct ath12k_dp *dp, struct hal_wbm_completion_ring_tx *desc, struct hal_tx_status *ts) { @@ -809,12 +816,12 @@ ath12k_wifi7_dp_tx_status_parse(struct ath12k_base *ab, } } -void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) +void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_dp *dp, int ring_id) { + struct ath12k_base *ab = dp->ab; struct ath12k_pdev_dp *dp_pdev; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id; - struct hal_srng *status_ring = &ab->hal.srng_list[hal_ring_id]; + struct hal_srng *status_ring = &dp->hal->srng_list[hal_ring_id]; struct ath12k_tx_desc_info *tx_desc = NULL; struct hal_tx_status ts = {}; struct ath12k_tx_desc_params desc_params; @@ -860,7 +867,7 @@ void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) tx_ring->tx_status_tail = ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_tail); tx_status = &tx_ring->tx_status[tx_ring->tx_status_tail]; - ath12k_wifi7_dp_tx_status_parse(ab, tx_status, &ts); + ath12k_wifi7_dp_tx_status_parse(dp, tx_status, &ts); if (le32_get_bits(tx_status->info0, HAL_WBM_COMPL_TX_INFO0_CC_DONE)) { /* HW done cookie conversion */ @@ -872,7 +879,7 @@ void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) desc_id = le32_get_bits(tx_status->buf_va_hi, BUFFER_ADDR_INFO1_SW_COOKIE); - tx_desc = ath12k_dp_get_tx_desc(ab, desc_id); + tx_desc = ath12k_dp_get_tx_desc(dp, desc_id); } if (!tx_desc) { ath12k_warn(ab, "unable to retrieve tx_desc!"); @@ -897,12 +904,12 @@ void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id) */ ath12k_dp_tx_release_txbuf(dp, tx_desc, tx_desc->pool_id); if (ts.buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW) { - ath12k_dp_tx_process_htt_tx_complete(ab, (void *)tx_status, + ath12k_dp_tx_process_htt_tx_complete(dp, (void *)tx_status, tx_ring, &desc_params); continue; } - pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, desc_params.mac_id); + pdev_idx = ath12k_hw_mac_id_to_pdev_id(dp->hw_params, desc_params.mac_id); rcu_read_lock(); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h index 94a5c59289cca..24cf7972d41ba 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h @@ -10,7 +10,7 @@ int ath12k_wifi7_dp_tx(struct ath12k_pdev_dp *dp_pdev, struct ath12k_link_vif *arvif, struct sk_buff *skb, bool gsn_valid, int mcbc_gsn, bool is_mcast); -void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id); +void ath12k_wifi7_dp_tx_completion_handler(struct ath12k_dp *dp, int ring_id); u32 ath12k_wifi7_dp_tx_get_vdev_bank_config(struct ath12k_base *ab, struct ath12k_link_vif *arvif); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index e85da9b1db96e..b7e930e12b84d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -323,13 +323,13 @@ ath12k_wifi7_hal_rx_msdu_link_info_get(struct hal_rx_msdu_link *link, } } -int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_base *ab, +int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_dp *dp, struct hal_reo_dest_ring *desc, dma_addr_t *paddr, u32 *desc_bank) { + struct ath12k_base *ab = dp->ab; enum hal_reo_dest_ring_push_reason push_reason; enum hal_reo_dest_ring_error_code err_code; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); u32 cookie, val; push_reason = le32_get_bits(desc->info0, @@ -345,18 +345,24 @@ int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_base *ab, return -EINVAL; } - ath12k_hal_rx_reo_ent_paddr_get(ab, &desc->buf_addr_info, paddr, &cookie); + val = le32_get_bits(desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE); + if (val != HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC) { + ath12k_warn(ab, "expected buffer type link_desc"); + return -EINVAL; + } + + ath12k_wifi7_hal_rx_reo_ent_paddr_get(&desc->buf_addr_info, paddr, + &cookie); *desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK); return 0; } -int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, +int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_dp *dp, void *desc, struct hal_rx_wbm_rel_info *rel_info) { struct hal_wbm_release_ring *wbm_desc = desc; struct hal_wbm_release_ring_cc_rx *wbm_cc_desc = desc; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); enum hal_wbm_rel_desc_type type; enum hal_wbm_rel_src_module rel_src; bool hw_cc_done; @@ -442,8 +448,7 @@ int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, return 0; } -void ath12k_wifi7_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab, - struct ath12k_buffer_addr *buff_addr, +void ath12k_wifi7_hal_rx_reo_ent_paddr_get(struct ath12k_buffer_addr *buff_addr, dma_addr_t *paddr, u32 *cookie) { *paddr = ((u64)(le32_get_bits(buff_addr->info1, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index a2498c6257268..c0d57d9b1009d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -860,13 +860,12 @@ void ath12k_wifi7_hal_rx_buf_addr_info_set(struct ath12k_buffer_addr *binfo, void ath12k_wifi7_hal_rx_buf_addr_info_get(struct ath12k_buffer_addr *binfo, dma_addr_t *paddr, u32 *cookie, u8 *rbm); -int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_base *ab, +int ath12k_wifi7_hal_desc_reo_parse_err(struct ath12k_dp *dp, struct hal_reo_dest_ring *desc, dma_addr_t *paddr, u32 *desc_bank); -int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, +int ath12k_wifi7_hal_wbm_desc_parse_err(struct ath12k_dp *dp, void *desc, struct hal_rx_wbm_rel_info *rel_info); -void ath12k_wifi7_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab, - struct ath12k_buffer_addr *buff_addr, +void ath12k_wifi7_hal_rx_reo_ent_paddr_get(struct ath12k_buffer_addr *buff_addr, dma_addr_t *paddr, u32 *cookie); void ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr, u32 *sw_cookie, From 0b1d1129a7627a351f1c9006cc0352f20b95a85e Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Mon, 3 Nov 2025 16:51:11 +0530 Subject: [PATCH 098/140] wifi: ath12k: Replace lock/unlock with guard() Use guard(wiphy)(...) and guard(spinlock_bh)(...) in: ath12k_dbg_sta_dump_rx_stats() ath12k_mac_op_link_sta_statistics() The guard() API ensures locks are automatically released when the scope exits, reducing the risk of missing unlocks in error paths and improving code readability. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri Reviewed-by: Karthikeyan Periyasamy Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251103112111.2260639-13-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/debugfs_sta.c | 36 ++++++------------- drivers/net/wireless/ath/ath12k/mac.c | 7 ++-- 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/debugfs_sta.c b/drivers/net/wireless/ath/ath12k/debugfs_sta.c index dde3efed4b60b..585c40bd29517 100644 --- a/drivers/net/wireless/ath/ath12k/debugfs_sta.c +++ b/drivers/net/wireless/ath/ath12k/debugfs_sta.c @@ -153,41 +153,32 @@ static ssize_t ath12k_dbg_sta_dump_rx_stats(struct file *file, bool he_rates_avail; struct ath12k *ar; - wiphy_lock(ah->hw->wiphy); + guard(wiphy)(ah->hw->wiphy); - if (!(BIT(link_id) & ahsta->links_map)) { - wiphy_unlock(ah->hw->wiphy); + if (!(BIT(link_id) & ahsta->links_map)) return -ENOENT; - } arsta = wiphy_dereference(ah->hw->wiphy, ahsta->link[link_id]); - if (!arsta || !arsta->arvif->ar) { - wiphy_unlock(ah->hw->wiphy); + if (!arsta || !arsta->arvif->ar) return -ENOENT; - } ar = arsta->arvif->ar; u8 *buf __free(kfree) = kzalloc(size, GFP_KERNEL); - if (!buf) { - ret = -ENOENT; - goto out; - } + if (!buf) + return -ENOMEM; dp = ath12k_ab_to_dp(ar->ab); - spin_lock_bh(&dp->dp_lock); + + guard(spinlock_bh)(&dp->dp_lock); link_peer = ath12k_dp_link_peer_find_by_addr(dp, arsta->addr); - if (!link_peer) { - ret = -ENOENT; - goto unlock; - } + if (!link_peer) + return -ENOENT; rx_stats = link_peer->peer_stats.rx_stats; - if (!rx_stats) { - ret = -ENOENT; - goto unlock; - } + if (!rx_stats) + return -ENOENT; len += scnprintf(buf + len, size - len, "RX peer stats:\n\n"); len += scnprintf(buf + len, size - len, "Num of MSDUs: %llu\n", @@ -247,13 +238,8 @@ static ssize_t ath12k_dbg_sta_dump_rx_stats(struct file *file, len += ath12k_dbg_sta_dump_rate_stats(buf, len, size, he_rates_avail, &rx_stats->byte_stats); -unlock: - spin_unlock_bh(&dp->dp_lock); - if (len) ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); -out: - wiphy_unlock(ah->hw->wiphy); return ret; } diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index e919c970f339f..e87f2daa984d7 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -13335,12 +13335,10 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, db2dbm = test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, ar->ab->wmi_ab.svc_map); - spin_lock_bh(&ar->ab->dp->dp_lock); + guard(spinlock_bh)(&ar->ab->dp->dp_lock); peer = ath12k_dp_link_peer_find_by_addr(ar->ab->dp, arsta->addr); - if (!peer) { - spin_unlock_bh(&ar->ab->dp->dp_lock); + if (!peer) return; - } link_sinfo->rx_duration = peer->rx_duration; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); @@ -13398,7 +13396,6 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, link_sinfo->tx_failed = peer->tx_retry_failed; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); - spin_unlock_bh(&ar->ab->dp->dp_lock); } EXPORT_SYMBOL(ath12k_mac_op_link_sta_statistics); From 47c72c4c7382e7c4cf4d4cc8b461426a6f37cf8c Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:02 +0530 Subject: [PATCH 099/140] wifi: ath12k: Move monitor ring processing to Wi-Fi 7 module Separate Wi-Fi 7-specific monitor-mode processing from common ath12k data path code to improve modularity. Move monitor status ring processing to wifi7/dp_mon.c: - ath12k_dp_mon_srng_process() - __ath12k_dp_mon_process_ring() - ath12k_dp_mon_process_ring() Rename the above to use the ath12k_wifi7_ prefix and export helper functions required by the ath12k_wifi7 module. Update the Wi-Fi 7 module Makefile to build dp_mon.o. No functional changes are intended; this is preparatory refactoring to isolate Wi-Fi 7 monitor-mode code from shared ath12k code. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-2-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 256 ++---------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 19 +- .../net/wireless/ath/ath12k/wifi7/Makefile | 1 + drivers/net/wireless/ath/ath12k/wifi7/dp.c | 16 +- drivers/net/wireless/ath/ath12k/wifi7/dp.h | 1 + .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 244 +++++++++++++++++ .../net/wireless/ath/ath12k/wifi7/dp_mon.h | 17 ++ 7 files changed, 305 insertions(+), 249 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index a28939214040e..007cea38d65d3 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2576,7 +2576,7 @@ ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, return 0; } -static enum hal_rx_mon_status +enum hal_rx_mon_status ath12k_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, struct sk_buff *skb) { @@ -2627,6 +2627,7 @@ ath12k_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_da return hal_status; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_rx_dest); enum hal_rx_mon_status ath12k_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, @@ -2654,6 +2655,7 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, return hal_status; } +EXPORT_SYMBOL(ath12k_dp_mon_rx_parse_mon_status); int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *buf_ring, @@ -2729,6 +2731,7 @@ int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, spin_unlock_bh(&srng->lock); return -ENOMEM; } +EXPORT_SYMBOL(ath12k_dp_mon_buf_replenish); int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, @@ -3525,8 +3528,8 @@ ath12k_dp_mon_rx_update_peer_rate_table_stats(struct ath12k_rx_peer_stats *rx_st stats->rx_rate[bw_idx][gi_idx][nss_idx][mcs_idx] += len; } -static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, - struct hal_rx_mon_ppdu_info *ppdu_info) +void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, + struct hal_rx_mon_ppdu_info *ppdu_info) { struct ath12k_rx_peer_stats *rx_stats = peer->peer_stats.rx_stats; u32 num_msdu; @@ -3633,6 +3636,7 @@ static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *pe ath12k_dp_mon_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, NULL, num_msdu); } +EXPORT_SYMBOL(ath12k_dp_mon_rx_update_peer_su_stats); void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -3681,6 +3685,7 @@ void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info) } ppdu_info->ldpc = 1; } +EXPORT_SYMBOL(ath12k_dp_mon_rx_process_ulofdma); static void ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, @@ -3781,7 +3786,7 @@ ath12k_dp_mon_rx_update_user_stats(struct ath12k_base *ab, user_stats, num_msdu); } -static void +void ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -3794,169 +3799,18 @@ ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, for (i = 0; i < num_users; i++) ath12k_dp_mon_rx_update_user_stats(ab, ppdu_info, i); } +EXPORT_SYMBOL(ath12k_dp_mon_rx_update_peer_mu_stats); -static void +void ath12k_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) { memset(ppdu_info, 0, sizeof(*ppdu_info)); ppdu_info->peer_id = HAL_INVALID_PEERID; } +EXPORT_SYMBOL(ath12k_dp_mon_rx_memset_ppdu_info); -int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, - struct napi_struct *napi) -{ - struct ath12k_dp *dp = pdev_dp->dp; - struct ath12k_base *ab = dp->ab; - struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&pdev_dp->mon_data; - struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; - struct hal_mon_dest_desc *mon_dst_desc; - struct sk_buff *skb; - struct ath12k_skb_rxcb *rxcb; - struct dp_srng *mon_dst_ring; - struct hal_srng *srng; - struct dp_rxdma_mon_ring *buf_ring; - struct ath12k_dp_link_peer *peer; - struct sk_buff_head skb_list; - u64 cookie; - int num_buffs_reaped = 0, srng_id, buf_id; - u32 hal_status, end_offset, info0, end_reason; - u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, pdev_dp->mac_id); - - __skb_queue_head_init(&skb_list); - srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, pdev_idx); - mon_dst_ring = &pdev_dp->rxdma_mon_dst_ring[srng_id]; - buf_ring = &dp->rxdma_mon_buf_ring; - - srng = &ab->hal.srng_list[mon_dst_ring->ring_id]; - spin_lock_bh(&srng->lock); - ath12k_hal_srng_access_begin(ab, srng); - - while (likely(*budget)) { - mon_dst_desc = ath12k_hal_srng_dst_peek(ab, srng); - if (unlikely(!mon_dst_desc)) - break; - - /* In case of empty descriptor, the cookie in the ring descriptor - * is invalid. Therefore, this entry is skipped, and ring processing - * continues. - */ - info0 = le32_to_cpu(mon_dst_desc->info0); - if (u32_get_bits(info0, HAL_MON_DEST_INFO0_EMPTY_DESC)) - goto move_next; - - cookie = le32_to_cpu(mon_dst_desc->cookie); - buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); - - spin_lock_bh(&buf_ring->idr_lock); - skb = idr_remove(&buf_ring->bufs_idr, buf_id); - spin_unlock_bh(&buf_ring->idr_lock); - - if (unlikely(!skb)) { - ath12k_warn(ab, "monitor destination with invalid buf_id %d\n", - buf_id); - goto move_next; - } - - rxcb = ATH12K_SKB_RXCB(skb); - dma_unmap_single(ab->dev, rxcb->paddr, - skb->len + skb_tailroom(skb), - DMA_FROM_DEVICE); - - end_reason = u32_get_bits(info0, HAL_MON_DEST_INFO0_END_REASON); - - /* HAL_MON_FLUSH_DETECTED implies that an rx flush received at the end of - * rx PPDU and HAL_MON_PPDU_TRUNCATED implies that the PPDU got - * truncated due to a system level error. In both the cases, buffer data - * can be discarded - */ - if ((end_reason == HAL_MON_FLUSH_DETECTED) || - (end_reason == HAL_MON_PPDU_TRUNCATED)) { - ath12k_dbg(ab, ATH12K_DBG_DATA, - "Monitor dest descriptor end reason %d", end_reason); - dev_kfree_skb_any(skb); - goto move_next; - } - - /* Calculate the budget when the ring descriptor with the - * HAL_MON_END_OF_PPDU to ensure that one PPDU worth of data is always - * reaped. This helps to efficiently utilize the NAPI budget. - */ - if (end_reason == HAL_MON_END_OF_PPDU) { - *budget -= 1; - rxcb->is_end_of_ppdu = true; - } - - end_offset = u32_get_bits(info0, HAL_MON_DEST_INFO0_END_OFFSET); - if (likely(end_offset <= DP_RX_BUFFER_SIZE)) { - skb_put(skb, end_offset); - } else { - ath12k_warn(ab, - "invalid offset on mon stats destination %u\n", - end_offset); - skb_put(skb, DP_RX_BUFFER_SIZE); - } - - __skb_queue_tail(&skb_list, skb); - -move_next: - ath12k_dp_mon_buf_replenish(ab, buf_ring, 1); - ath12k_hal_srng_dst_get_next_entry(ab, srng); - num_buffs_reaped++; - } - - ath12k_hal_srng_access_end(ab, srng); - spin_unlock_bh(&srng->lock); - - if (!num_buffs_reaped) - return 0; - - /* In some cases, one PPDU worth of data can be spread across multiple NAPI - * schedules, To avoid losing existing parsed ppdu_info information, skip - * the memset of the ppdu_info structure and continue processing it. - */ - if (!ppdu_info->ppdu_continuation) - ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); - - while ((skb = __skb_dequeue(&skb_list))) { - hal_status = ath12k_dp_mon_rx_parse_mon_status(pdev_dp, pmon, skb, napi); - if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) { - ppdu_info->ppdu_continuation = true; - dev_kfree_skb_any(skb); - continue; - } - - if (ppdu_info->peer_id == HAL_INVALID_PEERID) - goto free_skb; - - rcu_read_lock(); - peer = ath12k_dp_link_peer_find_by_peerid(pdev_dp, ppdu_info->peer_id); - if (!peer || !peer->sta) { - ath12k_dbg(ab, ATH12K_DBG_DATA, - "failed to find the peer with monitor peer_id %d\n", - ppdu_info->peer_id); - goto next_skb; - } - - if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) { - ath12k_dp_mon_rx_update_peer_su_stats(peer, ppdu_info); - } else if ((ppdu_info->fc_valid) && - (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) { - ath12k_dp_mon_rx_process_ulofdma(ppdu_info); - ath12k_dp_mon_rx_update_peer_mu_stats(ab, ppdu_info); - } - -next_skb: - rcu_read_unlock(); -free_skb: - dev_kfree_skb_any(skb); - ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); - } - - return num_buffs_reaped; -} - -static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, - int *budget, struct sk_buff_head *skb_list) +int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, + int *budget, struct sk_buff_head *skb_list) { const struct ath12k_hw_hal_params *hal_params; int buf_id, srng_id, num_buffs_reaped = 0; @@ -4099,6 +3953,7 @@ static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, return num_buffs_reaped; } +EXPORT_SYMBOL(ath12k_dp_rx_reap_mon_status_ring); static u32 ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, @@ -4294,8 +4149,8 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, */ #define MON_DEST_RING_STUCK_MAX_CNT 16 -static void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, - u32 quota, struct napi_struct *napi) +void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, + u32 quota, struct napi_struct *napi) { struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; struct ath12k_pdev_mon_stats *rx_mon_stats; @@ -4396,79 +4251,4 @@ static void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, rx_bufs_used); } } - -static int -__ath12k_dp_mon_process_ring(struct ath12k *ar, int mac_id, - struct napi_struct *napi, int *budget) -{ - struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; - struct ath12k_pdev_mon_stats *rx_mon_stats = &pmon->rx_mon_stats; - struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; - enum hal_rx_mon_status hal_status; - struct sk_buff_head skb_list; - int num_buffs_reaped; - struct sk_buff *skb; - - __skb_queue_head_init(&skb_list); - - num_buffs_reaped = ath12k_dp_rx_reap_mon_status_ring(ar->ab, mac_id, - budget, &skb_list); - if (!num_buffs_reaped) - goto exit; - - while ((skb = __skb_dequeue(&skb_list))) { - memset(ppdu_info, 0, sizeof(*ppdu_info)); - ppdu_info->peer_id = HAL_INVALID_PEERID; - - hal_status = ath12k_dp_mon_parse_rx_dest(&ar->dp, pmon, skb); - - if (ar->monitor_started && - pmon->mon_ppdu_status == DP_PPDU_STATUS_START && - hal_status == HAL_TLV_STATUS_PPDU_DONE) { - rx_mon_stats->status_ppdu_done++; - pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE; - ath12k_dp_rx_mon_dest_process(ar, mac_id, *budget, napi); - pmon->mon_ppdu_status = DP_PPDU_STATUS_START; - } - - dev_kfree_skb_any(skb); - } - -exit: - return num_buffs_reaped; -} - -int ath12k_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, - struct napi_struct *napi, int budget, - enum dp_monitor_mode monitor_mode) -{ - u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(dp->hw_params, mac_id); - struct ath12k_pdev_dp *dp_pdev; - struct ath12k *ar; - int num_buffs_reaped = 0; - - rcu_read_lock(); - - dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); - if (!dp_pdev) { - rcu_read_unlock(); - return 0; - } - - if (dp->hw_params->rxdma1_enable) { - if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE) - num_buffs_reaped = ath12k_dp_mon_srng_process(dp_pdev, &budget, - napi); - } else { - ar = ath12k_pdev_dp_to_ar(dp_pdev); - - if (ar->monitor_started) - num_buffs_reaped = - __ath12k_dp_mon_process_ring(ar, mac_id, napi, &budget); - } - - rcu_read_unlock(); - - return num_buffs_reaped; -} -EXPORT_SYMBOL(ath12k_dp_mon_process_ring); +EXPORT_SYMBOL(ath12k_dp_rx_mon_dest_process); diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 3e6ff4b0a6d9e..689d7a0fff5c1 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -89,9 +89,6 @@ int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, int req_entries); -int ath12k_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, - struct napi_struct *napi, int budget, - enum dp_monitor_mode monitor_mode); struct sk_buff *ath12k_dp_mon_tx_alloc_skb(void); enum dp_mon_tx_tlv_status ath12k_dp_mon_tx_status_get_num_user(u16 tlv_tag, @@ -104,6 +101,18 @@ ath12k_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, u32 ppdu_id); void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info); -int ath12k_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, - struct napi_struct *napi); +enum hal_rx_mon_status +ath12k_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, + struct sk_buff *skb); +int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, + int *budget, struct sk_buff_head *skb_list); +void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, + u32 quota, struct napi_struct *napi); +void +ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, + struct hal_rx_mon_ppdu_info *ppdu_info); +void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/Makefile b/drivers/net/wireless/ath/ath12k/wifi7/Makefile index 30258a1b313de..dcfa732bb95bc 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/Makefile +++ b/drivers/net/wireless/ath/ath12k/wifi7/Makefile @@ -11,6 +11,7 @@ ath12k_wifi7-y += core.o \ dp_rx.o \ dp_tx.o \ dp.o \ + dp_mon.o \ hal.o \ hal_qcn9274.o \ hal_wcn7850.o diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 30c27e005ed8f..0b2c7f37c7566 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -9,6 +9,7 @@ #include "../dp_tx.h" #include "hal_desc.h" #include "../dp_mon.h" +#include "dp_mon.h" #include "../dp_cmn.h" #include "dp_rx.h" #include "dp.h" @@ -66,8 +67,9 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, if (ring_mask & BIT(id)) { work_done = - ath12k_dp_mon_process_ring(dp, id, napi, budget, - 0); + ath12k_wifi7_dp_mon_process_ring(dp, id, napi, + budget, + 0); budget -= work_done; tot_work_done += work_done; if (budget <= 0) @@ -86,8 +88,9 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, if (ring_mask & BIT(id)) { work_done = - ath12k_dp_mon_process_ring(dp, id, napi, budget, - monitor_mode); + ath12k_wifi7_dp_mon_process_ring(dp, id, napi, + budget, + monitor_mode); budget -= work_done; tot_work_done += work_done; @@ -107,8 +110,9 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp, if (ring_mask & BIT(id)) { work_done = - ath12k_dp_mon_process_ring(dp, id, napi, budget, - monitor_mode); + ath12k_wifi7_dp_mon_process_ring(dp, id, + napi, budget, + monitor_mode); budget -= work_done; tot_work_done += work_done; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.h b/drivers/net/wireless/ath/ath12k/wifi7/dp.h index 72fdfb368c994..a5f0941d34e2f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.h @@ -12,6 +12,7 @@ struct ath12k_base; struct ath12k_dp; +enum dp_monitor_mode; struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab); void ath12k_wifi7_dp_device_free(struct ath12k_dp *dp); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c new file mode 100644 index 0000000000000..4135ff5e87590 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "hal_desc.h" +#include "../dp_mon.h" +#include "dp_mon.h" +#include "../debug.h" +#include "hal_qcn9274.h" +#include "dp_rx.h" +#include "../peer.h" + +static int +__ath12k_wifi7_dp_mon_process_ring(struct ath12k *ar, int mac_id, + struct napi_struct *napi, int *budget) +{ + struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; + struct ath12k_pdev_mon_stats *rx_mon_stats = &pmon->rx_mon_stats; + struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; + enum hal_rx_mon_status hal_status; + struct sk_buff_head skb_list; + int num_buffs_reaped; + struct sk_buff *skb; + + __skb_queue_head_init(&skb_list); + + num_buffs_reaped = ath12k_dp_rx_reap_mon_status_ring(ar->ab, mac_id, + budget, &skb_list); + if (!num_buffs_reaped) + goto exit; + + while ((skb = __skb_dequeue(&skb_list))) { + memset(ppdu_info, 0, sizeof(*ppdu_info)); + ppdu_info->peer_id = HAL_INVALID_PEERID; + + hal_status = ath12k_dp_mon_parse_rx_dest(&ar->dp, pmon, skb); + + if (ar->monitor_started && + pmon->mon_ppdu_status == DP_PPDU_STATUS_START && + hal_status == HAL_TLV_STATUS_PPDU_DONE) { + rx_mon_stats->status_ppdu_done++; + pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE; + ath12k_dp_rx_mon_dest_process(ar, mac_id, *budget, napi); + pmon->mon_ppdu_status = DP_PPDU_STATUS_START; + } + + dev_kfree_skb_any(skb); + } + +exit: + return num_buffs_reaped; +} + +static int +ath12k_wifi7_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, + struct napi_struct *napi) +{ + struct ath12k_dp *dp = pdev_dp->dp; + struct ath12k_base *ab = dp->ab; + struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&pdev_dp->mon_data; + struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; + struct hal_mon_dest_desc *mon_dst_desc; + struct sk_buff *skb; + struct ath12k_skb_rxcb *rxcb; + struct dp_srng *mon_dst_ring; + struct hal_srng *srng; + struct dp_rxdma_mon_ring *buf_ring; + struct ath12k_dp_link_peer *peer; + struct sk_buff_head skb_list; + u64 cookie; + int num_buffs_reaped = 0, srng_id, buf_id; + u32 hal_status, end_offset, info0, end_reason; + u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, pdev_dp->mac_id); + + __skb_queue_head_init(&skb_list); + srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, pdev_idx); + mon_dst_ring = &pdev_dp->rxdma_mon_dst_ring[srng_id]; + buf_ring = &dp->rxdma_mon_buf_ring; + + srng = &ab->hal.srng_list[mon_dst_ring->ring_id]; + spin_lock_bh(&srng->lock); + ath12k_hal_srng_access_begin(ab, srng); + + while (likely(*budget)) { + mon_dst_desc = ath12k_hal_srng_dst_peek(ab, srng); + if (unlikely(!mon_dst_desc)) + break; + + /* In case of empty descriptor, the cookie in the ring descriptor + * is invalid. Therefore, this entry is skipped, and ring processing + * continues. + */ + info0 = le32_to_cpu(mon_dst_desc->info0); + if (u32_get_bits(info0, HAL_MON_DEST_INFO0_EMPTY_DESC)) + goto move_next; + + cookie = le32_to_cpu(mon_dst_desc->cookie); + buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); + + spin_lock_bh(&buf_ring->idr_lock); + skb = idr_remove(&buf_ring->bufs_idr, buf_id); + spin_unlock_bh(&buf_ring->idr_lock); + + if (unlikely(!skb)) { + ath12k_warn(ab, "monitor destination with invalid buf_id %d\n", + buf_id); + goto move_next; + } + + rxcb = ATH12K_SKB_RXCB(skb); + dma_unmap_single(ab->dev, rxcb->paddr, + skb->len + skb_tailroom(skb), + DMA_FROM_DEVICE); + + end_reason = u32_get_bits(info0, HAL_MON_DEST_INFO0_END_REASON); + + /* HAL_MON_FLUSH_DETECTED implies that an rx flush received at the end of + * rx PPDU and HAL_MON_PPDU_TRUNCATED implies that the PPDU got + * truncated due to a system level error. In both the cases, buffer data + * can be discarded + */ + if ((end_reason == HAL_MON_FLUSH_DETECTED) || + (end_reason == HAL_MON_PPDU_TRUNCATED)) { + ath12k_dbg(ab, ATH12K_DBG_DATA, + "Monitor dest descriptor end reason %d", end_reason); + dev_kfree_skb_any(skb); + goto move_next; + } + + /* Calculate the budget when the ring descriptor with the + * HAL_MON_END_OF_PPDU to ensure that one PPDU worth of data is always + * reaped. This helps to efficiently utilize the NAPI budget. + */ + if (end_reason == HAL_MON_END_OF_PPDU) { + *budget -= 1; + rxcb->is_end_of_ppdu = true; + } + + end_offset = u32_get_bits(info0, HAL_MON_DEST_INFO0_END_OFFSET); + if (likely(end_offset <= DP_RX_BUFFER_SIZE)) { + skb_put(skb, end_offset); + } else { + ath12k_warn(ab, + "invalid offset on mon stats destination %u\n", + end_offset); + skb_put(skb, DP_RX_BUFFER_SIZE); + } + + __skb_queue_tail(&skb_list, skb); + +move_next: + ath12k_dp_mon_buf_replenish(ab, buf_ring, 1); + ath12k_hal_srng_dst_get_next_entry(ab, srng); + num_buffs_reaped++; + } + + ath12k_hal_srng_access_end(ab, srng); + spin_unlock_bh(&srng->lock); + + if (!num_buffs_reaped) + return 0; + + /* In some cases, one PPDU worth of data can be spread across multiple NAPI + * schedules, To avoid losing existing parsed ppdu_info information, skip + * the memset of the ppdu_info structure and continue processing it. + */ + if (!ppdu_info->ppdu_continuation) + ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); + + while ((skb = __skb_dequeue(&skb_list))) { + hal_status = ath12k_dp_mon_rx_parse_mon_status(pdev_dp, pmon, skb, napi); + if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) { + ppdu_info->ppdu_continuation = true; + dev_kfree_skb_any(skb); + continue; + } + + if (ppdu_info->peer_id == HAL_INVALID_PEERID) + goto free_skb; + + rcu_read_lock(); + peer = ath12k_dp_link_peer_find_by_peerid(pdev_dp, ppdu_info->peer_id); + if (!peer || !peer->sta) { + ath12k_dbg(ab, ATH12K_DBG_DATA, + "failed to find the peer with monitor peer_id %d\n", + ppdu_info->peer_id); + goto next_skb; + } + + if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) { + ath12k_dp_mon_rx_update_peer_su_stats(peer, ppdu_info); + } else if ((ppdu_info->fc_valid) && + (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) { + ath12k_dp_mon_rx_process_ulofdma(ppdu_info); + ath12k_dp_mon_rx_update_peer_mu_stats(ab, ppdu_info); + } + +next_skb: + rcu_read_unlock(); +free_skb: + dev_kfree_skb_any(skb); + ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); + } + + return num_buffs_reaped; +} + +int ath12k_wifi7_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, + struct napi_struct *napi, int budget, + enum dp_monitor_mode monitor_mode) +{ + u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(dp->hw_params, mac_id); + struct ath12k_pdev_dp *dp_pdev; + struct ath12k *ar; + int num_buffs_reaped = 0; + + rcu_read_lock(); + + dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); + if (!dp_pdev) { + rcu_read_unlock(); + return 0; + } + + if (dp->hw_params->rxdma1_enable) { + if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE) + num_buffs_reaped = ath12k_wifi7_dp_mon_srng_process(dp_pdev, + &budget, + napi); + } else { + ar = ath12k_pdev_dp_to_ar(dp_pdev); + + if (ar->monitor_started) + num_buffs_reaped = + __ath12k_wifi7_dp_mon_process_ring(ar, mac_id, napi, + &budget); + } + + rcu_read_unlock(); + + return num_buffs_reaped; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h new file mode 100644 index 0000000000000..3cf82864c41cd --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_DP_MON_WIFI7_H +#define ATH12K_DP_MON_WIFI7_H + +#include "hw.h" + +enum dp_monitor_mode; + +int ath12k_wifi7_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, + struct napi_struct *napi, int budget, + enum dp_monitor_mode monitor_mode); +#endif From 8fa4454806ab981f73e38c7b50467ba123dcb5d0 Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:03 +0530 Subject: [PATCH 100/140] wifi: ath12k: Move monitor status processing to Wi-Fi 7 module Split Wi-Fi 7-specific monitor status processing out of ath12k common code and into the Wi-Fi 7 module to improve modularity. Move the following functions to wifi7/dp_mon.c and rename them with the ath12k_wifi7_ prefix: - ath12k_dp_mon_rx_parse_mon_status() - ath12k_dp_rx_reap_mon_status_ring() - ath12k_dp_mon_parse_rx_dest() - ath12k_dp_rx_mon_buf_done() - ath12k_dp_rx_mon_dest_process() - ath12k_dp_mon_rx_memset_ppdu_info() Export helper functions required by the Wi-Fi 7 monitor path. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-3-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 409 +----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 38 +- drivers/net/wireless/ath/ath12k/hal.c | 2 + .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 399 ++++++++++++++++- 4 files changed, 433 insertions(+), 415 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 007cea38d65d3..9ef439d690a27 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -1494,7 +1494,7 @@ ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, RX_MSDU_END_INFO11_DECAP_FORMAT); } -static enum hal_rx_mon_status +enum hal_rx_mon_status ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct hal_tlv_64_hdr *tlv) @@ -1763,6 +1763,7 @@ ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, return HAL_RX_MON_STATUS_PPDU_NOT_DONE; } +EXPORT_SYMBOL(ath12k_dp_mon_rx_parse_status_tlv); static void ath12k_dp_mon_fill_rx_stats_info(struct hal_rx_mon_ppdu_info *ppdu_info, @@ -1791,7 +1792,7 @@ ath12k_dp_mon_fill_rx_stats_info(struct hal_rx_mon_ppdu_info *ppdu_info, } } -static struct sk_buff +struct sk_buff *ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, int *buf_id) @@ -1834,46 +1835,7 @@ static struct sk_buff fail_alloc_skb: return NULL; } - -static enum dp_mon_status_buf_state -ath12k_dp_rx_mon_buf_done(struct ath12k_base *ab, struct hal_srng *srng, - struct dp_rxdma_mon_ring *rx_ring) -{ - struct ath12k_skb_rxcb *rxcb; - struct hal_tlv_64_hdr *tlv; - struct sk_buff *skb; - void *status_desc; - dma_addr_t paddr; - u32 cookie; - int buf_id; - u8 rbm; - - status_desc = ath12k_hal_srng_src_next_peek(ab, srng); - if (!status_desc) - return DP_MON_STATUS_NO_DMA; - - ath12k_hal_rx_buf_addr_info_get(&ab->hal, status_desc, &paddr, &cookie, &rbm); - - buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); - - spin_lock_bh(&rx_ring->idr_lock); - skb = idr_find(&rx_ring->bufs_idr, buf_id); - spin_unlock_bh(&rx_ring->idr_lock); - - if (!skb) - return DP_MON_STATUS_NO_DMA; - - rxcb = ATH12K_SKB_RXCB(skb); - dma_sync_single_for_cpu(ab->dev, rxcb->paddr, - skb->len + skb_tailroom(skb), - DMA_FROM_DEVICE); - - tlv = (struct hal_tlv_64_hdr *)skb->data; - if (le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG) != HAL_RX_STATUS_BUFFER_DONE) - return DP_MON_STATUS_NO_DMA; - - return DP_MON_STATUS_REPLINISH; -} +EXPORT_SYMBOL(ath12k_dp_rx_alloc_mon_status_buf); static u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id) { @@ -2393,10 +2355,10 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, ieee80211_rx_napi(ath12k_pdev_dp_to_hw(dp_pdev), pubsta, msdu, napi); } -static int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, - struct dp_mon_mpdu *mon_mpdu, - struct hal_rx_mon_ppdu_info *ppduinfo, - struct napi_struct *napi) +int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, + struct dp_mon_mpdu *mon_mpdu, + struct hal_rx_mon_ppdu_info *ppduinfo, + struct napi_struct *napi) { struct sk_buff *mon_skb, *skb_next, *header; struct ieee80211_rx_status *rxs = &dp_pdev->rx_status; @@ -2447,8 +2409,9 @@ static int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, } return -EINVAL; } +EXPORT_SYMBOL(ath12k_dp_mon_rx_deliver); -static int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len) +int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len) { if (skb->len > len) { skb_trim(skb, len); @@ -2465,6 +2428,7 @@ static int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len) return 0; } +EXPORT_SYMBOL(ath12k_dp_pkt_set_pktlen); /* Hardware fill buffer with 128 bytes aligned. So need to reap it * with 128 bytes aligned. @@ -2538,7 +2502,7 @@ ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, return 0; } -static int +int ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, enum hal_rx_mon_status hal_status, @@ -2575,87 +2539,7 @@ ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, return 0; } - -enum hal_rx_mon_status -ath12k_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, - struct sk_buff *skb) -{ - struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); - struct hal_tlv_64_hdr *tlv; - struct ath12k_skb_rxcb *rxcb; - enum hal_rx_mon_status hal_status; - u16 tlv_tag, tlv_len; - u8 *ptr = skb->data; - - do { - tlv = (struct hal_tlv_64_hdr *)ptr; - tlv_tag = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_TAG); - - /* The actual length of PPDU_END is the combined length of many PHY - * TLVs that follow. Skip the TLV header and - * rx_rxpcu_classification_overview that follows the header to get to - * next TLV. - */ - - if (tlv_tag == HAL_RX_PPDU_END) - tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview); - else - tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN); - - hal_status = ath12k_dp_mon_rx_parse_status_tlv(dp_pdev, pmon, tlv); - - if (ar->monitor_started && ar->ab->hw_params->rxdma1_enable && - ath12k_dp_mon_parse_rx_dest_tlv(dp_pdev, pmon, hal_status, - tlv->value)) - return HAL_RX_MON_STATUS_PPDU_DONE; - - ptr += sizeof(*tlv) + tlv_len; - ptr = PTR_ALIGN(ptr, HAL_TLV_64_ALIGN); - - if ((ptr - skb->data) > skb->len) - break; - - } while ((hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE) || - (hal_status == HAL_RX_MON_STATUS_BUF_ADDR) || - (hal_status == HAL_RX_MON_STATUS_MPDU_START) || - (hal_status == HAL_RX_MON_STATUS_MPDU_END) || - (hal_status == HAL_RX_MON_STATUS_MSDU_END)); - - rxcb = ATH12K_SKB_RXCB(skb); - if (rxcb->is_end_of_ppdu) - hal_status = HAL_RX_MON_STATUS_PPDU_DONE; - - return hal_status; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_rx_dest); - -enum hal_rx_mon_status -ath12k_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - struct sk_buff *skb, - struct napi_struct *napi) -{ - struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; - struct dp_mon_mpdu *tmp; - struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu; - enum hal_rx_mon_status hal_status; - - hal_status = ath12k_dp_mon_parse_rx_dest(dp_pdev, pmon, skb); - if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) - return hal_status; - - list_for_each_entry_safe(mon_mpdu, tmp, &pmon->dp_rx_mon_mpdu_list, list) { - list_del(&mon_mpdu->list); - - if (mon_mpdu->head && mon_mpdu->tail) - ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, ppdu_info, napi); - - kfree(mon_mpdu); - } - - return hal_status; -} -EXPORT_SYMBOL(ath12k_dp_mon_rx_parse_mon_status); +EXPORT_SYMBOL(ath12k_dp_mon_parse_rx_dest_tlv); int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *buf_ring, @@ -3801,161 +3685,7 @@ ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, } EXPORT_SYMBOL(ath12k_dp_mon_rx_update_peer_mu_stats); -void -ath12k_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) -{ - memset(ppdu_info, 0, sizeof(*ppdu_info)); - ppdu_info->peer_id = HAL_INVALID_PEERID; -} -EXPORT_SYMBOL(ath12k_dp_mon_rx_memset_ppdu_info); - -int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, - int *budget, struct sk_buff_head *skb_list) -{ - const struct ath12k_hw_hal_params *hal_params; - int buf_id, srng_id, num_buffs_reaped = 0; - enum dp_mon_status_buf_state reap_status; - struct dp_rxdma_mon_ring *rx_ring; - struct ath12k_mon_data *pmon; - struct ath12k_skb_rxcb *rxcb; - struct hal_tlv_64_hdr *tlv; - void *rx_mon_status_desc; - struct hal_srng *srng; - struct ath12k_dp *dp; - struct sk_buff *skb; - struct ath12k *ar; - dma_addr_t paddr; - u32 cookie; - u8 rbm; - - ar = ab->pdevs[ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id)].ar; - dp = ath12k_ab_to_dp(ab); - pmon = &ar->dp.mon_data; - srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, mac_id); - rx_ring = &dp->rx_mon_status_refill_ring[srng_id]; - - srng = &ab->hal.srng_list[rx_ring->refill_buf_ring.ring_id]; - - spin_lock_bh(&srng->lock); - - ath12k_hal_srng_access_begin(ab, srng); - - while (*budget) { - *budget -= 1; - rx_mon_status_desc = ath12k_hal_srng_src_peek(ab, srng); - if (!rx_mon_status_desc) { - pmon->buf_state = DP_MON_STATUS_REPLINISH; - break; - } - ath12k_hal_rx_buf_addr_info_get(&ab->hal, rx_mon_status_desc, &paddr, - &cookie, &rbm); - if (paddr) { - buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); - - spin_lock_bh(&rx_ring->idr_lock); - skb = idr_find(&rx_ring->bufs_idr, buf_id); - spin_unlock_bh(&rx_ring->idr_lock); - - if (!skb) { - ath12k_warn(ab, "rx monitor status with invalid buf_id %d\n", - buf_id); - pmon->buf_state = DP_MON_STATUS_REPLINISH; - goto move_next; - } - - rxcb = ATH12K_SKB_RXCB(skb); - - dma_sync_single_for_cpu(ab->dev, rxcb->paddr, - skb->len + skb_tailroom(skb), - DMA_FROM_DEVICE); - - tlv = (struct hal_tlv_64_hdr *)skb->data; - if (le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG) != - HAL_RX_STATUS_BUFFER_DONE) { - pmon->buf_state = DP_MON_STATUS_NO_DMA; - ath12k_warn(ab, - "mon status DONE not set %llx, buf_id %d\n", - le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG), - buf_id); - /* RxDMA status done bit might not be set even - * though tp is moved by HW. - */ - - /* If done status is missing: - * 1. As per MAC team's suggestion, - * when HP + 1 entry is peeked and if DMA - * is not done and if HP + 2 entry's DMA done - * is set. skip HP + 1 entry and - * start processing in next interrupt. - * 2. If HP + 2 entry's DMA done is not set, - * poll onto HP + 1 entry DMA done to be set. - * Check status for same buffer for next time - * dp_rx_mon_status_srng_process - */ - reap_status = ath12k_dp_rx_mon_buf_done(ab, srng, - rx_ring); - if (reap_status == DP_MON_STATUS_NO_DMA) - continue; - - spin_lock_bh(&rx_ring->idr_lock); - idr_remove(&rx_ring->bufs_idr, buf_id); - spin_unlock_bh(&rx_ring->idr_lock); - - dma_unmap_single(ab->dev, rxcb->paddr, - skb->len + skb_tailroom(skb), - DMA_FROM_DEVICE); - - dev_kfree_skb_any(skb); - pmon->buf_state = DP_MON_STATUS_REPLINISH; - goto move_next; - } - - spin_lock_bh(&rx_ring->idr_lock); - idr_remove(&rx_ring->bufs_idr, buf_id); - spin_unlock_bh(&rx_ring->idr_lock); - - dma_unmap_single(ab->dev, rxcb->paddr, - skb->len + skb_tailroom(skb), - DMA_FROM_DEVICE); - - if (ath12k_dp_pkt_set_pktlen(skb, RX_MON_STATUS_BUF_SIZE)) { - dev_kfree_skb_any(skb); - goto move_next; - } - __skb_queue_tail(skb_list, skb); - } else { - pmon->buf_state = DP_MON_STATUS_REPLINISH; - } -move_next: - skb = ath12k_dp_rx_alloc_mon_status_buf(ab, rx_ring, - &buf_id); - hal_params = ab->hal.hal_params; - - if (!skb) { - ath12k_warn(ab, "failed to alloc buffer for status ring\n"); - ath12k_hal_rx_buf_addr_info_set(&ab->hal, rx_mon_status_desc, - 0, 0, hal_params->rx_buf_rbm); - num_buffs_reaped++; - break; - } - rxcb = ATH12K_SKB_RXCB(skb); - - cookie = u32_encode_bits(mac_id, DP_RXDMA_BUF_COOKIE_PDEV_ID) | - u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID); - - ath12k_hal_rx_buf_addr_info_set(&ab->hal, rx_mon_status_desc, rxcb->paddr, - cookie, hal_params->rx_buf_rbm); - ath12k_hal_srng_src_get_next_entry(ab, srng); - num_buffs_reaped++; - } - ath12k_hal_srng_access_end(ab, srng); - spin_unlock_bh(&srng->lock); - - return num_buffs_reaped; -} -EXPORT_SYMBOL(ath12k_dp_rx_reap_mon_status_ring); - -static u32 +u32 ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, void *ring_entry, struct sk_buff **head_msdu, struct sk_buff **tail_msdu, @@ -4142,113 +3872,4 @@ ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, return rx_bufs_used; } - -/* The destination ring processing is stuck if the destination is not - * moving while status ring moves 16 PPDU. The destination ring processing - * skips this destination ring PPDU as a workaround. - */ -#define MON_DEST_RING_STUCK_MAX_CNT 16 - -void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, - u32 quota, struct napi_struct *napi) -{ - struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; - struct ath12k_pdev_mon_stats *rx_mon_stats; - u32 ppdu_id, rx_bufs_used = 0, ring_id; - u32 mpdu_rx_bufs_used, npackets = 0; - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - void *ring_entry, *mon_dst_srng; - struct dp_mon_mpdu *tmp_mpdu; - LIST_HEAD(rx_desc_used_list); - struct hal_srng *srng; - - ring_id = dp->rxdma_err_dst_ring[mac_id].ring_id; - srng = &ab->hal.srng_list[ring_id]; - - mon_dst_srng = &ab->hal.srng_list[ring_id]; - - spin_lock_bh(&srng->lock); - - ath12k_hal_srng_access_begin(ab, mon_dst_srng); - - ppdu_id = pmon->mon_ppdu_info.ppdu_id; - rx_mon_stats = &pmon->rx_mon_stats; - - while ((ring_entry = ath12k_hal_srng_dst_peek(ar->ab, mon_dst_srng))) { - struct sk_buff *head_msdu, *tail_msdu; - - head_msdu = NULL; - tail_msdu = NULL; - - mpdu_rx_bufs_used = ath12k_dp_rx_mon_mpdu_pop(ar, mac_id, ring_entry, - &head_msdu, &tail_msdu, - &rx_desc_used_list, - &npackets, &ppdu_id); - - rx_bufs_used += mpdu_rx_bufs_used; - - if (mpdu_rx_bufs_used) { - dp->mon_dest_ring_stuck_cnt = 0; - } else { - dp->mon_dest_ring_stuck_cnt++; - rx_mon_stats->dest_mon_not_reaped++; - } - - if (dp->mon_dest_ring_stuck_cnt > MON_DEST_RING_STUCK_MAX_CNT) { - rx_mon_stats->dest_mon_stuck++; - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, - "status ring ppdu_id=%d dest ring ppdu_id=%d mon_dest_ring_stuck_cnt=%d dest_mon_not_reaped=%u dest_mon_stuck=%u\n", - pmon->mon_ppdu_info.ppdu_id, ppdu_id, - dp->mon_dest_ring_stuck_cnt, - rx_mon_stats->dest_mon_not_reaped, - rx_mon_stats->dest_mon_stuck); - spin_lock_bh(&pmon->mon_lock); - pmon->mon_ppdu_info.ppdu_id = ppdu_id; - spin_unlock_bh(&pmon->mon_lock); - continue; - } - - if (ppdu_id != pmon->mon_ppdu_info.ppdu_id) { - spin_lock_bh(&pmon->mon_lock); - pmon->mon_ppdu_status = DP_PPDU_STATUS_START; - spin_unlock_bh(&pmon->mon_lock); - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, - "dest_rx: new ppdu_id %x != status ppdu_id %x dest_mon_not_reaped = %u dest_mon_stuck = %u\n", - ppdu_id, pmon->mon_ppdu_info.ppdu_id, - rx_mon_stats->dest_mon_not_reaped, - rx_mon_stats->dest_mon_stuck); - break; - } - - if (head_msdu && tail_msdu) { - tmp_mpdu = kzalloc(sizeof(*tmp_mpdu), GFP_ATOMIC); - if (!tmp_mpdu) - break; - - tmp_mpdu->head = head_msdu; - tmp_mpdu->tail = tail_msdu; - tmp_mpdu->err_bitmap = pmon->err_bitmap; - tmp_mpdu->decap_format = pmon->decap_format; - ath12k_dp_mon_rx_deliver(&ar->dp, tmp_mpdu, - &pmon->mon_ppdu_info, napi); - rx_mon_stats->dest_mpdu_done++; - kfree(tmp_mpdu); - } - - ring_entry = ath12k_hal_srng_dst_get_next_entry(ar->ab, - mon_dst_srng); - } - ath12k_hal_srng_access_end(ar->ab, mon_dst_srng); - - spin_unlock_bh(&srng->lock); - - if (rx_bufs_used) { - rx_mon_stats->dest_ppdu_done++; - ath12k_dp_rx_bufs_replenish(ar->ab->dp, - &dp->rx_refill_buf_ring, - &rx_desc_used_list, - rx_bufs_used); - } -} -EXPORT_SYMBOL(ath12k_dp_rx_mon_dest_process); +EXPORT_SYMBOL(ath12k_dp_rx_mon_mpdu_pop); diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 689d7a0fff5c1..726434ab74aca 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -78,11 +78,6 @@ struct dp_mon_tx_ppdu_info { struct dp_mon_mpdu *tx_mon_mpdu; }; -enum hal_rx_mon_status -ath12k_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - struct sk_buff *skb, - struct napi_struct *napi); int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *buf_ring, int req_entries); @@ -101,18 +96,33 @@ ath12k_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, u32 ppdu_id); void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info); -enum hal_rx_mon_status -ath12k_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, - struct sk_buff *skb); -int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, - int *budget, struct sk_buff_head *skb_list); -void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, - u32 quota, struct napi_struct *napi); void ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, struct hal_rx_mon_ppdu_info *ppdu_info); void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, struct hal_rx_mon_ppdu_info *ppdu_info); -void -ath12k_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info); +u32 +ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, + void *ring_entry, struct sk_buff **head_msdu, + struct sk_buff **tail_msdu, + struct list_head *used_list, + u32 *npackets, u32 *ppdu_id); +int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len); +int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, + struct dp_mon_mpdu *mon_mpdu, + struct hal_rx_mon_ppdu_info *ppduinfo, + struct napi_struct *napi); +int +ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + enum hal_rx_mon_status hal_status, + const void *tlv_data); +enum hal_rx_mon_status +ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + const struct hal_tlv_64_hdr *tlv); +struct sk_buff +*ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab, + struct dp_rxdma_mon_ring *rx_ring, + int *buf_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index efa039f6df924..91d697ad1799d 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -402,6 +402,7 @@ void *ath12k_hal_srng_src_next_peek(struct ath12k_base *ab, return desc; } +EXPORT_SYMBOL(ath12k_hal_srng_src_next_peek); void *ath12k_hal_srng_src_get_next_entry(struct ath12k_base *ab, struct hal_srng *srng) @@ -447,6 +448,7 @@ void *ath12k_hal_srng_src_peek(struct ath12k_base *ab, struct hal_srng *srng) return srng->ring_base_vaddr + srng->u.src_ring.hp; } +EXPORT_SYMBOL(ath12k_hal_srng_src_peek); void *ath12k_hal_srng_src_reap_next(struct ath12k_base *ab, struct hal_srng *srng) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 4135ff5e87590..ffebeb1652e7b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -12,6 +12,390 @@ #include "dp_rx.h" #include "../peer.h" +static void +ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) +{ + memset(ppdu_info, 0, sizeof(*ppdu_info)); + ppdu_info->peer_id = HAL_INVALID_PEERID; +} + +/* The destination ring processing is stuck if the destination is not + * moving while status ring moves 16 PPDU. The destination ring processing + * skips this destination ring PPDU as a workaround. + */ +#define MON_DEST_RING_STUCK_MAX_CNT 16 + +static void +ath12k_wifi7_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, + u32 quota, struct napi_struct *napi) +{ + struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; + struct ath12k_pdev_mon_stats *rx_mon_stats; + u32 ppdu_id, rx_bufs_used = 0, ring_id; + u32 mpdu_rx_bufs_used, npackets = 0; + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + void *ring_entry, *mon_dst_srng; + struct dp_mon_mpdu *tmp_mpdu; + LIST_HEAD(rx_desc_used_list); + struct hal_srng *srng; + + ring_id = dp->rxdma_err_dst_ring[mac_id].ring_id; + srng = &ab->hal.srng_list[ring_id]; + + mon_dst_srng = &ab->hal.srng_list[ring_id]; + + spin_lock_bh(&srng->lock); + + ath12k_hal_srng_access_begin(ab, mon_dst_srng); + + ppdu_id = pmon->mon_ppdu_info.ppdu_id; + rx_mon_stats = &pmon->rx_mon_stats; + + while ((ring_entry = ath12k_hal_srng_dst_peek(ar->ab, mon_dst_srng))) { + struct sk_buff *head_msdu, *tail_msdu; + + head_msdu = NULL; + tail_msdu = NULL; + + mpdu_rx_bufs_used = ath12k_dp_rx_mon_mpdu_pop(ar, mac_id, ring_entry, + &head_msdu, &tail_msdu, + &rx_desc_used_list, + &npackets, &ppdu_id); + + rx_bufs_used += mpdu_rx_bufs_used; + + if (mpdu_rx_bufs_used) { + dp->mon_dest_ring_stuck_cnt = 0; + } else { + dp->mon_dest_ring_stuck_cnt++; + rx_mon_stats->dest_mon_not_reaped++; + } + + if (dp->mon_dest_ring_stuck_cnt > MON_DEST_RING_STUCK_MAX_CNT) { + rx_mon_stats->dest_mon_stuck++; + ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + "status ring ppdu_id=%d dest ring ppdu_id=%d mon_dest_ring_stuck_cnt=%d dest_mon_not_reaped=%u dest_mon_stuck=%u\n", + pmon->mon_ppdu_info.ppdu_id, ppdu_id, + dp->mon_dest_ring_stuck_cnt, + rx_mon_stats->dest_mon_not_reaped, + rx_mon_stats->dest_mon_stuck); + spin_lock_bh(&pmon->mon_lock); + pmon->mon_ppdu_info.ppdu_id = ppdu_id; + spin_unlock_bh(&pmon->mon_lock); + continue; + } + + if (ppdu_id != pmon->mon_ppdu_info.ppdu_id) { + spin_lock_bh(&pmon->mon_lock); + pmon->mon_ppdu_status = DP_PPDU_STATUS_START; + spin_unlock_bh(&pmon->mon_lock); + ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + "dest_rx: new ppdu_id %x != status ppdu_id %x dest_mon_not_reaped = %u dest_mon_stuck = %u\n", + ppdu_id, pmon->mon_ppdu_info.ppdu_id, + rx_mon_stats->dest_mon_not_reaped, + rx_mon_stats->dest_mon_stuck); + break; + } + + if (head_msdu && tail_msdu) { + tmp_mpdu = kzalloc(sizeof(*tmp_mpdu), GFP_ATOMIC); + if (!tmp_mpdu) + break; + + tmp_mpdu->head = head_msdu; + tmp_mpdu->tail = tail_msdu; + tmp_mpdu->err_bitmap = pmon->err_bitmap; + tmp_mpdu->decap_format = pmon->decap_format; + ath12k_dp_mon_rx_deliver(&ar->dp, tmp_mpdu, + &pmon->mon_ppdu_info, napi); + rx_mon_stats->dest_mpdu_done++; + kfree(tmp_mpdu); + } + + ring_entry = ath12k_hal_srng_dst_get_next_entry(ar->ab, + mon_dst_srng); + } + ath12k_hal_srng_access_end(ar->ab, mon_dst_srng); + + spin_unlock_bh(&srng->lock); + + if (rx_bufs_used) { + rx_mon_stats->dest_ppdu_done++; + ath12k_dp_rx_bufs_replenish(ar->ab->dp, + &dp->rx_refill_buf_ring, + &rx_desc_used_list, + rx_bufs_used); + } +} + +static enum dp_mon_status_buf_state +ath12k_wifi7_dp_rx_mon_buf_done(struct ath12k_base *ab, struct hal_srng *srng, + struct dp_rxdma_mon_ring *rx_ring) +{ + struct ath12k_skb_rxcb *rxcb; + struct hal_tlv_64_hdr *tlv; + struct sk_buff *skb; + void *status_desc; + dma_addr_t paddr; + u32 cookie; + int buf_id; + u8 rbm; + + status_desc = ath12k_hal_srng_src_next_peek(ab, srng); + if (!status_desc) + return DP_MON_STATUS_NO_DMA; + + ath12k_wifi7_hal_rx_buf_addr_info_get(status_desc, &paddr, &cookie, &rbm); + + buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); + + spin_lock_bh(&rx_ring->idr_lock); + skb = idr_find(&rx_ring->bufs_idr, buf_id); + spin_unlock_bh(&rx_ring->idr_lock); + + if (!skb) + return DP_MON_STATUS_NO_DMA; + + rxcb = ATH12K_SKB_RXCB(skb); + dma_sync_single_for_cpu(ab->dev, rxcb->paddr, + skb->len + skb_tailroom(skb), + DMA_FROM_DEVICE); + + tlv = (struct hal_tlv_64_hdr *)skb->data; + if (le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG) != HAL_RX_STATUS_BUFFER_DONE) + return DP_MON_STATUS_NO_DMA; + + return DP_MON_STATUS_REPLINISH; +} + +static enum hal_rx_mon_status +ath12k_wifi7_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + struct sk_buff *skb) +{ + struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); + struct hal_tlv_64_hdr *tlv; + struct ath12k_skb_rxcb *rxcb; + enum hal_rx_mon_status hal_status; + u16 tlv_tag, tlv_len; + u8 *ptr = skb->data; + + do { + tlv = (struct hal_tlv_64_hdr *)ptr; + tlv_tag = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_TAG); + + /* The actual length of PPDU_END is the combined length of many PHY + * TLVs that follow. Skip the TLV header and + * rx_rxpcu_classification_overview that follows the header to get to + * next TLV. + */ + + if (tlv_tag == HAL_RX_PPDU_END) + tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview); + else + tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN); + + hal_status = ath12k_dp_mon_rx_parse_status_tlv(dp_pdev, pmon, tlv); + + if (ar->monitor_started && ar->ab->hw_params->rxdma1_enable && + ath12k_dp_mon_parse_rx_dest_tlv(dp_pdev, pmon, hal_status, + tlv->value)) + return HAL_RX_MON_STATUS_PPDU_DONE; + + ptr += sizeof(*tlv) + tlv_len; + ptr = PTR_ALIGN(ptr, HAL_TLV_64_ALIGN); + + if ((ptr - skb->data) > skb->len) + break; + + } while ((hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE) || + (hal_status == HAL_RX_MON_STATUS_BUF_ADDR) || + (hal_status == HAL_RX_MON_STATUS_MPDU_START) || + (hal_status == HAL_RX_MON_STATUS_MPDU_END) || + (hal_status == HAL_RX_MON_STATUS_MSDU_END)); + + rxcb = ATH12K_SKB_RXCB(skb); + if (rxcb->is_end_of_ppdu) + hal_status = HAL_RX_MON_STATUS_PPDU_DONE; + + return hal_status; +} + +static enum hal_rx_mon_status +ath12k_wifi7_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + struct sk_buff *skb, + struct napi_struct *napi) +{ + struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; + struct dp_mon_mpdu *tmp; + struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu; + enum hal_rx_mon_status hal_status; + + hal_status = ath12k_wifi7_dp_mon_parse_rx_dest(dp_pdev, pmon, skb); + if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) + return hal_status; + + list_for_each_entry_safe(mon_mpdu, tmp, &pmon->dp_rx_mon_mpdu_list, list) { + list_del(&mon_mpdu->list); + + if (mon_mpdu->head && mon_mpdu->tail) + ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, ppdu_info, napi); + + kfree(mon_mpdu); + } + + return hal_status; +} + +static int +ath12k_wifi7_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id, + int *budget, struct sk_buff_head *skb_list) +{ + const struct ath12k_hw_hal_params *hal_params; + int buf_id, srng_id, num_buffs_reaped = 0; + enum dp_mon_status_buf_state reap_status; + struct dp_rxdma_mon_ring *rx_ring; + struct ath12k_mon_data *pmon; + struct ath12k_skb_rxcb *rxcb; + struct hal_tlv_64_hdr *tlv; + void *rx_mon_status_desc; + struct hal_srng *srng; + struct ath12k_dp *dp; + struct sk_buff *skb; + struct ath12k *ar; + dma_addr_t paddr; + u32 cookie; + u8 rbm; + + ar = ab->pdevs[ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id)].ar; + dp = ath12k_ab_to_dp(ab); + pmon = &ar->dp.mon_data; + srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, mac_id); + rx_ring = &dp->rx_mon_status_refill_ring[srng_id]; + + srng = &ab->hal.srng_list[rx_ring->refill_buf_ring.ring_id]; + + spin_lock_bh(&srng->lock); + + ath12k_hal_srng_access_begin(ab, srng); + + while (*budget) { + *budget -= 1; + rx_mon_status_desc = ath12k_hal_srng_src_peek(ab, srng); + if (!rx_mon_status_desc) { + pmon->buf_state = DP_MON_STATUS_REPLINISH; + break; + } + ath12k_wifi7_hal_rx_buf_addr_info_get(rx_mon_status_desc, &paddr, + &cookie, &rbm); + if (paddr) { + buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID); + + spin_lock_bh(&rx_ring->idr_lock); + skb = idr_find(&rx_ring->bufs_idr, buf_id); + spin_unlock_bh(&rx_ring->idr_lock); + + if (!skb) { + ath12k_warn(ab, "rx monitor status with invalid buf_id %d\n", + buf_id); + pmon->buf_state = DP_MON_STATUS_REPLINISH; + goto move_next; + } + + rxcb = ATH12K_SKB_RXCB(skb); + + dma_sync_single_for_cpu(ab->dev, rxcb->paddr, + skb->len + skb_tailroom(skb), + DMA_FROM_DEVICE); + + tlv = (struct hal_tlv_64_hdr *)skb->data; + if (le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG) != + HAL_RX_STATUS_BUFFER_DONE) { + pmon->buf_state = DP_MON_STATUS_NO_DMA; + ath12k_warn(ab, + "mon status DONE not set %llx, buf_id %d\n", + le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG), + buf_id); + /* RxDMA status done bit might not be set even + * though tp is moved by HW. + */ + + /* If done status is missing: + * 1. As per MAC team's suggestion, + * when HP + 1 entry is peeked and if DMA + * is not done and if HP + 2 entry's DMA done + * is set. skip HP + 1 entry and + * start processing in next interrupt. + * 2. If HP + 2 entry's DMA done is not set, + * poll onto HP + 1 entry DMA done to be set. + * Check status for same buffer for next time + * dp_rx_mon_status_srng_process + */ + reap_status = ath12k_wifi7_dp_rx_mon_buf_done(ab, srng, + rx_ring); + if (reap_status == DP_MON_STATUS_NO_DMA) + continue; + + spin_lock_bh(&rx_ring->idr_lock); + idr_remove(&rx_ring->bufs_idr, buf_id); + spin_unlock_bh(&rx_ring->idr_lock); + + dma_unmap_single(ab->dev, rxcb->paddr, + skb->len + skb_tailroom(skb), + DMA_FROM_DEVICE); + + dev_kfree_skb_any(skb); + pmon->buf_state = DP_MON_STATUS_REPLINISH; + goto move_next; + } + + spin_lock_bh(&rx_ring->idr_lock); + idr_remove(&rx_ring->bufs_idr, buf_id); + spin_unlock_bh(&rx_ring->idr_lock); + + dma_unmap_single(ab->dev, rxcb->paddr, + skb->len + skb_tailroom(skb), + DMA_FROM_DEVICE); + + if (ath12k_dp_pkt_set_pktlen(skb, RX_MON_STATUS_BUF_SIZE)) { + dev_kfree_skb_any(skb); + goto move_next; + } + __skb_queue_tail(skb_list, skb); + } else { + pmon->buf_state = DP_MON_STATUS_REPLINISH; + } +move_next: + skb = ath12k_dp_rx_alloc_mon_status_buf(ab, rx_ring, + &buf_id); + hal_params = ab->hal.hal_params; + + if (!skb) { + ath12k_warn(ab, "failed to alloc buffer for status ring\n"); + ath12k_wifi7_hal_rx_buf_addr_info_set(rx_mon_status_desc, + 0, 0, + hal_params->rx_buf_rbm); + num_buffs_reaped++; + break; + } + rxcb = ATH12K_SKB_RXCB(skb); + + cookie = u32_encode_bits(mac_id, DP_RXDMA_BUF_COOKIE_PDEV_ID) | + u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID); + + ath12k_wifi7_hal_rx_buf_addr_info_set(rx_mon_status_desc, rxcb->paddr, + cookie, hal_params->rx_buf_rbm); + ath12k_hal_srng_src_get_next_entry(ab, srng); + num_buffs_reaped++; + } + ath12k_hal_srng_access_end(ab, srng); + spin_unlock_bh(&srng->lock); + + return num_buffs_reaped; +} + static int __ath12k_wifi7_dp_mon_process_ring(struct ath12k *ar, int mac_id, struct napi_struct *napi, int *budget) @@ -26,8 +410,8 @@ __ath12k_wifi7_dp_mon_process_ring(struct ath12k *ar, int mac_id, __skb_queue_head_init(&skb_list); - num_buffs_reaped = ath12k_dp_rx_reap_mon_status_ring(ar->ab, mac_id, - budget, &skb_list); + num_buffs_reaped = ath12k_wifi7_dp_rx_reap_mon_status_ring(ar->ab, mac_id, + budget, &skb_list); if (!num_buffs_reaped) goto exit; @@ -35,14 +419,14 @@ __ath12k_wifi7_dp_mon_process_ring(struct ath12k *ar, int mac_id, memset(ppdu_info, 0, sizeof(*ppdu_info)); ppdu_info->peer_id = HAL_INVALID_PEERID; - hal_status = ath12k_dp_mon_parse_rx_dest(&ar->dp, pmon, skb); + hal_status = ath12k_wifi7_dp_mon_parse_rx_dest(&ar->dp, pmon, skb); if (ar->monitor_started && pmon->mon_ppdu_status == DP_PPDU_STATUS_START && hal_status == HAL_TLV_STATUS_PPDU_DONE) { rx_mon_stats->status_ppdu_done++; pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE; - ath12k_dp_rx_mon_dest_process(ar, mac_id, *budget, napi); + ath12k_wifi7_dp_rx_mon_dest_process(ar, mac_id, *budget, napi); pmon->mon_ppdu_status = DP_PPDU_STATUS_START; } @@ -167,10 +551,11 @@ ath12k_wifi7_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, * the memset of the ppdu_info structure and continue processing it. */ if (!ppdu_info->ppdu_continuation) - ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); + ath12k_wifi7_dp_mon_rx_memset_ppdu_info(ppdu_info); while ((skb = __skb_dequeue(&skb_list))) { - hal_status = ath12k_dp_mon_rx_parse_mon_status(pdev_dp, pmon, skb, napi); + hal_status = ath12k_wifi7_dp_mon_rx_parse_mon_status(pdev_dp, pmon, + skb, napi); if (hal_status != HAL_RX_MON_STATUS_PPDU_DONE) { ppdu_info->ppdu_continuation = true; dev_kfree_skb_any(skb); @@ -201,7 +586,7 @@ ath12k_wifi7_dp_mon_srng_process(struct ath12k_pdev_dp *pdev_dp, int *budget, rcu_read_unlock(); free_skb: dev_kfree_skb_any(skb); - ath12k_dp_mon_rx_memset_ppdu_info(ppdu_info); + ath12k_wifi7_dp_mon_rx_memset_ppdu_info(ppdu_info); } return num_buffs_reaped; From 9488c32ea3d1b8ecc89e0d9b6afab8ce4f658313 Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:04 +0530 Subject: [PATCH 101/140] wifi: ath12k: Move MPDU pop functionality to Wi-Fi 7 module Separate Wi-Fi 7-specific monitor code from ath12k common code to improve modularity. Move the following monitor MPDU pop function to the new file wifi7/dp_mon.c and rename them with the ath12k_wifi7_ prefix: - ath12k_dp_rx_mon_mpdu_pop() Export helper functions required by the ath12k_wifi7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-4-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 207 +----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 15 +- drivers/net/wireless/ath/ath12k/hal.h | 5 + .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 201 ++++++++++++++++- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 11 + drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 3 + .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 5 - 7 files changed, 230 insertions(+), 217 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 9ef439d690a27..09aa615769b4c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -17,16 +17,6 @@ #define ATH12K_LE64_DEC_ENC(value, dec_bits, enc_bits) \ u32_encode_bits(le64_get_bits(value, dec_bits), enc_bits) -static bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, - struct hal_rx_desc *rx_desc) -{ - u32 tlv_tag; - - tlv_tag = ab->hal.ops->rx_desc_get_mpdu_start_tag(rx_desc); - - return tlv_tag == HAL_RX_MPDU_START; -} - static void ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, struct hal_rx_user_status *rx_user_status) @@ -1837,7 +1827,7 @@ struct sk_buff } EXPORT_SYMBOL(ath12k_dp_rx_alloc_mon_status_buf); -static u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id) +u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id) { u32 ret = 0; @@ -1856,8 +1846,8 @@ static u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id) } return ret; } +EXPORT_SYMBOL(ath12k_dp_mon_comp_ppduid); -static void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, struct hal_rx_msdu_link *msdu_link, dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm, @@ -1871,6 +1861,7 @@ void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, *pp_buf_addr_info = buf_addr_info; } +EXPORT_SYMBOL(ath12k_dp_mon_next_link_desc_get); static void ath12k_dp_mon_fill_rx_rate(struct ath12k_pdev_dp *dp_pdev, @@ -2435,7 +2426,7 @@ EXPORT_SYMBOL(ath12k_dp_pkt_set_pktlen); */ #define RXDMA_DATA_DMA_BLOCK_SIZE 128 -static void +void ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, bool *is_frag, u32 *total_len, u32 *frag_len, u32 *msdu_cnt) @@ -2455,6 +2446,7 @@ ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, *msdu_cnt -= 1; } } +EXPORT_SYMBOL(ath12k_dp_mon_get_buf_len); static int ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, @@ -3684,192 +3676,3 @@ ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, ath12k_dp_mon_rx_update_user_stats(ab, ppdu_info, i); } EXPORT_SYMBOL(ath12k_dp_mon_rx_update_peer_mu_stats); - -u32 -ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, - void *ring_entry, struct sk_buff **head_msdu, - struct sk_buff **tail_msdu, - struct list_head *used_list, - u32 *npackets, u32 *ppdu_id) -{ - struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; - struct ath12k_base *ab = ar->ab; - struct ath12k_dp *dp = ath12k_ab_to_dp(ab); - struct ath12k_buffer_addr *p_buf_addr_info, *p_last_buf_addr_info; - u32 msdu_ppdu_id = 0, msdu_cnt = 0, total_len = 0, frag_len = 0; - u32 rx_buf_size, rx_pkt_offset, sw_cookie; - bool is_frag, is_first_msdu, drop_mpdu = false; - struct hal_reo_entrance_ring *ent_desc = - (struct hal_reo_entrance_ring *)ring_entry; - u32 rx_bufs_used = 0, i = 0, desc_bank = 0; - struct hal_rx_desc *rx_desc, *tail_rx_desc; - struct hal_rx_msdu_link *msdu_link_desc; - struct sk_buff *msdu = NULL, *last = NULL; - struct ath12k_rx_desc_info *desc_info; - struct ath12k_buffer_addr buf_info; - struct hal_rx_msdu_list msdu_list; - struct ath12k_skb_rxcb *rxcb; - u16 num_msdus = 0; - dma_addr_t paddr; - u8 rbm; - - ath12k_hal_rx_reo_ent_buf_paddr_get(&ab->hal, ring_entry, &paddr, - &sw_cookie, - &p_last_buf_addr_info, &rbm, - &msdu_cnt); - - spin_lock_bh(&pmon->mon_lock); - - if (le32_get_bits(ent_desc->info1, - HAL_REO_ENTR_RING_INFO1_RXDMA_PUSH_REASON) == - HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED) { - u8 rxdma_err = le32_get_bits(ent_desc->info1, - HAL_REO_ENTR_RING_INFO1_RXDMA_ERROR_CODE); - if (rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR || - rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR || - rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR) { - drop_mpdu = true; - pmon->rx_mon_stats.dest_mpdu_drop++; - } - } - - is_frag = false; - is_first_msdu = true; - rx_pkt_offset = sizeof(struct hal_rx_desc); - - do { - if (pmon->mon_last_linkdesc_paddr == paddr) { - pmon->rx_mon_stats.dup_mon_linkdesc_cnt++; - spin_unlock_bh(&pmon->mon_lock); - return rx_bufs_used; - } - - desc_bank = u32_get_bits(sw_cookie, DP_LINK_DESC_BANK_MASK); - msdu_link_desc = - dp->link_desc_banks[desc_bank].vaddr + - (paddr - dp->link_desc_banks[desc_bank].paddr); - - ath12k_hal_rx_msdu_list_get(&ar->ab->hal, ar, msdu_link_desc, &msdu_list, - &num_msdus); - desc_info = ath12k_dp_get_rx_desc(ar->ab->dp, - msdu_list.sw_cookie[num_msdus - 1]); - tail_rx_desc = (struct hal_rx_desc *)(desc_info->skb)->data; - - for (i = 0; i < num_msdus; i++) { - u32 l2_hdr_offset; - - if (pmon->mon_last_buf_cookie == msdu_list.sw_cookie[i]) { - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, - "i %d last_cookie %d is same\n", - i, pmon->mon_last_buf_cookie); - drop_mpdu = true; - pmon->rx_mon_stats.dup_mon_buf_cnt++; - continue; - } - - desc_info = - ath12k_dp_get_rx_desc(ar->ab->dp, msdu_list.sw_cookie[i]); - msdu = desc_info->skb; - - if (!msdu) { - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, - "msdu_pop: invalid msdu (%d/%d)\n", - i + 1, num_msdus); - goto next_msdu; - } - rxcb = ATH12K_SKB_RXCB(msdu); - if (rxcb->paddr != msdu_list.paddr[i]) { - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, - "i %d paddr %lx != %lx\n", - i, (unsigned long)rxcb->paddr, - (unsigned long)msdu_list.paddr[i]); - drop_mpdu = true; - continue; - } - if (!rxcb->unmapped) { - dma_unmap_single(ar->ab->dev, rxcb->paddr, - msdu->len + - skb_tailroom(msdu), - DMA_FROM_DEVICE); - rxcb->unmapped = 1; - } - if (drop_mpdu) { - ath12k_dbg(ar->ab, ATH12K_DBG_DATA, - "i %d drop msdu %p *ppdu_id %x\n", - i, msdu, *ppdu_id); - dev_kfree_skb_any(msdu); - msdu = NULL; - goto next_msdu; - } - - rx_desc = (struct hal_rx_desc *)msdu->data; - l2_hdr_offset = ath12k_dp_rx_h_l3pad(ar->ab, tail_rx_desc); - if (is_first_msdu) { - if (!ath12k_dp_rxdesc_mpdu_valid(ar->ab, rx_desc)) { - drop_mpdu = true; - dev_kfree_skb_any(msdu); - msdu = NULL; - pmon->mon_last_linkdesc_paddr = paddr; - goto next_msdu; - } - msdu_ppdu_id = - ath12k_dp_rxdesc_get_ppduid(ar->ab, rx_desc); - - if (ath12k_dp_mon_comp_ppduid(msdu_ppdu_id, - ppdu_id)) { - spin_unlock_bh(&pmon->mon_lock); - return rx_bufs_used; - } - pmon->mon_last_linkdesc_paddr = paddr; - is_first_msdu = false; - } - ath12k_dp_mon_get_buf_len(&msdu_list.msdu_info[i], - &is_frag, &total_len, - &frag_len, &msdu_cnt); - rx_buf_size = rx_pkt_offset + l2_hdr_offset + frag_len; - - if (ath12k_dp_pkt_set_pktlen(msdu, rx_buf_size)) { - dev_kfree_skb_any(msdu); - goto next_msdu; - } - - if (!(*head_msdu)) - *head_msdu = msdu; - else if (last) - last->next = msdu; - - last = msdu; -next_msdu: - pmon->mon_last_buf_cookie = msdu_list.sw_cookie[i]; - rx_bufs_used++; - desc_info->skb = NULL; - list_add_tail(&desc_info->list, used_list); - } - - ath12k_hal_rx_buf_addr_info_set(&ab->hal, &buf_info, paddr, - sw_cookie, rbm); - - ath12k_dp_mon_next_link_desc_get(ab, msdu_link_desc, &paddr, - &sw_cookie, &rbm, - &p_buf_addr_info); - - ath12k_dp_arch_rx_link_desc_return(ar->ab->dp, &buf_info, - HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); - - p_last_buf_addr_info = p_buf_addr_info; - - } while (paddr && msdu_cnt); - - spin_unlock_bh(&pmon->mon_lock); - - if (last) - last->next = NULL; - - *tail_msdu = msdu; - - if (msdu_cnt == 0) - *npackets = 1; - - return rx_bufs_used; -} -EXPORT_SYMBOL(ath12k_dp_rx_mon_mpdu_pop); diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 726434ab74aca..425bec6f0f3ca 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -101,12 +101,6 @@ ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, struct hal_rx_mon_ppdu_info *ppdu_info); void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, struct hal_rx_mon_ppdu_info *ppdu_info); -u32 -ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, - void *ring_entry, struct sk_buff **head_msdu, - struct sk_buff **tail_msdu, - struct list_head *used_list, - u32 *npackets, u32 *ppdu_id); int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len); int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, struct dp_mon_mpdu *mon_mpdu, @@ -125,4 +119,13 @@ struct sk_buff *ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, int *buf_id); +void +ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, + bool *is_frag, u32 *total_len, + u32 *frag_len, u32 *msdu_cnt); +void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, + struct hal_rx_msdu_link *msdu_link, + dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm, + struct ath12k_buffer_addr **pp_buf_addr_info); +u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id); #endif diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 071f4897e4cd0..1d22173975f0f 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -592,6 +592,11 @@ struct hal_rx_eht_info { u32 user_info[EHT_MAX_USER_INFO]; }; +struct hal_rx_msdu_desc_info { + u32 msdu_flags; + u16 msdu_len; /* 14 bits for length */ +}; + struct hal_rx_mon_ppdu_info { u32 ppdu_id; u32 last_ppdu_id; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index ffebeb1652e7b..dae3f262cc507 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -19,6 +19,196 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } +static u32 +ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, + void *ring_entry, struct sk_buff **head_msdu, + struct sk_buff **tail_msdu, + struct list_head *used_list, + u32 *npackets, u32 *ppdu_id) +{ + struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data; + struct ath12k_base *ab = ar->ab; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_buffer_addr *p_buf_addr_info, *p_last_buf_addr_info; + u32 msdu_ppdu_id = 0, msdu_cnt = 0, total_len = 0, frag_len = 0; + u32 rx_buf_size, rx_pkt_offset, sw_cookie; + bool is_frag, is_first_msdu, drop_mpdu = false; + struct hal_reo_entrance_ring *ent_desc = + (struct hal_reo_entrance_ring *)ring_entry; + u32 rx_bufs_used = 0, i = 0, desc_bank = 0; + struct hal_rx_desc *rx_desc, *tail_rx_desc; + struct hal_rx_msdu_link *msdu_link_desc; + struct sk_buff *msdu = NULL, *last = NULL; + struct ath12k_rx_desc_info *desc_info; + struct ath12k_buffer_addr buf_info; + struct hal_rx_msdu_list msdu_list; + struct ath12k_skb_rxcb *rxcb; + u16 num_msdus = 0; + dma_addr_t paddr; + u8 rbm; + + ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get(ring_entry, &paddr, + &sw_cookie, + &p_last_buf_addr_info, + &rbm, + &msdu_cnt); + + spin_lock_bh(&pmon->mon_lock); + + if (le32_get_bits(ent_desc->info1, + HAL_REO_ENTR_RING_INFO1_RXDMA_PUSH_REASON) == + HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED) { + u8 rxdma_err = le32_get_bits(ent_desc->info1, + HAL_REO_ENTR_RING_INFO1_RXDMA_ERROR_CODE); + if (rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR || + rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR || + rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR) { + drop_mpdu = true; + pmon->rx_mon_stats.dest_mpdu_drop++; + } + } + + is_frag = false; + is_first_msdu = true; + rx_pkt_offset = sizeof(struct hal_rx_desc); + + do { + if (pmon->mon_last_linkdesc_paddr == paddr) { + pmon->rx_mon_stats.dup_mon_linkdesc_cnt++; + spin_unlock_bh(&pmon->mon_lock); + return rx_bufs_used; + } + + desc_bank = u32_get_bits(sw_cookie, DP_LINK_DESC_BANK_MASK); + msdu_link_desc = + dp->link_desc_banks[desc_bank].vaddr + + (paddr - dp->link_desc_banks[desc_bank].paddr); + + ath12k_wifi7_hal_rx_msdu_list_get(ar, msdu_link_desc, &msdu_list, + &num_msdus); + desc_info = ath12k_dp_get_rx_desc(ar->ab->dp, + msdu_list.sw_cookie[num_msdus - 1]); + tail_rx_desc = (struct hal_rx_desc *)(desc_info->skb)->data; + + for (i = 0; i < num_msdus; i++) { + u32 l2_hdr_offset; + + if (pmon->mon_last_buf_cookie == msdu_list.sw_cookie[i]) { + ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + "i %d last_cookie %d is same\n", + i, pmon->mon_last_buf_cookie); + drop_mpdu = true; + pmon->rx_mon_stats.dup_mon_buf_cnt++; + continue; + } + + desc_info = + ath12k_dp_get_rx_desc(ar->ab->dp, msdu_list.sw_cookie[i]); + msdu = desc_info->skb; + + if (!msdu) { + ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + "msdu_pop: invalid msdu (%d/%d)\n", + i + 1, num_msdus); + goto next_msdu; + } + rxcb = ATH12K_SKB_RXCB(msdu); + if (rxcb->paddr != msdu_list.paddr[i]) { + ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + "i %d paddr %lx != %lx\n", + i, (unsigned long)rxcb->paddr, + (unsigned long)msdu_list.paddr[i]); + drop_mpdu = true; + continue; + } + if (!rxcb->unmapped) { + dma_unmap_single(ar->ab->dev, rxcb->paddr, + msdu->len + + skb_tailroom(msdu), + DMA_FROM_DEVICE); + rxcb->unmapped = 1; + } + if (drop_mpdu) { + ath12k_dbg(ar->ab, ATH12K_DBG_DATA, + "i %d drop msdu %p *ppdu_id %x\n", + i, msdu, *ppdu_id); + dev_kfree_skb_any(msdu); + msdu = NULL; + goto next_msdu; + } + + rx_desc = (struct hal_rx_desc *)msdu->data; + l2_hdr_offset = ath12k_dp_rx_h_l3pad(ar->ab, tail_rx_desc); + if (is_first_msdu) { + if (!ath12k_wifi7_dp_rxdesc_mpdu_valid(ar->ab, + rx_desc)) { + drop_mpdu = true; + dev_kfree_skb_any(msdu); + msdu = NULL; + pmon->mon_last_linkdesc_paddr = paddr; + goto next_msdu; + } + msdu_ppdu_id = + ath12k_dp_rxdesc_get_ppduid(ar->ab, rx_desc); + + if (ath12k_dp_mon_comp_ppduid(msdu_ppdu_id, + ppdu_id)) { + spin_unlock_bh(&pmon->mon_lock); + return rx_bufs_used; + } + pmon->mon_last_linkdesc_paddr = paddr; + is_first_msdu = false; + } + ath12k_dp_mon_get_buf_len(&msdu_list.msdu_info[i], + &is_frag, &total_len, + &frag_len, &msdu_cnt); + rx_buf_size = rx_pkt_offset + l2_hdr_offset + frag_len; + + if (ath12k_dp_pkt_set_pktlen(msdu, rx_buf_size)) { + dev_kfree_skb_any(msdu); + goto next_msdu; + } + + if (!(*head_msdu)) + *head_msdu = msdu; + else if (last) + last->next = msdu; + + last = msdu; +next_msdu: + pmon->mon_last_buf_cookie = msdu_list.sw_cookie[i]; + rx_bufs_used++; + desc_info->skb = NULL; + list_add_tail(&desc_info->list, used_list); + } + + ath12k_wifi7_hal_rx_buf_addr_info_set(&buf_info, paddr, + sw_cookie, rbm); + + ath12k_dp_mon_next_link_desc_get(ab, msdu_link_desc, &paddr, + &sw_cookie, &rbm, + &p_buf_addr_info); + + ath12k_dp_arch_rx_link_desc_return(ar->ab->dp, &buf_info, + HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); + + p_last_buf_addr_info = p_buf_addr_info; + + } while (paddr && msdu_cnt); + + spin_unlock_bh(&pmon->mon_lock); + + if (last) + last->next = NULL; + + *tail_msdu = msdu; + + if (msdu_cnt == 0) + *npackets = 1; + + return rx_bufs_used; +} + /* The destination ring processing is stuck if the destination is not * moving while status ring moves 16 PPDU. The destination ring processing * skips this destination ring PPDU as a workaround. @@ -58,10 +248,13 @@ ath12k_wifi7_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, head_msdu = NULL; tail_msdu = NULL; - mpdu_rx_bufs_used = ath12k_dp_rx_mon_mpdu_pop(ar, mac_id, ring_entry, - &head_msdu, &tail_msdu, - &rx_desc_used_list, - &npackets, &ppdu_id); + mpdu_rx_bufs_used = ath12k_wifi7_dp_rx_mon_mpdu_pop(ar, mac_id, + ring_entry, + &head_msdu, + &tail_msdu, + &rx_desc_used_list, + &npackets, + &ppdu_id); rx_bufs_used += mpdu_rx_bufs_used; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 2138b20a04d57..08dcf170b801d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -2141,3 +2141,14 @@ void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_dp *dp) spin_unlock_bh(&srng->lock); } + +bool +ath12k_wifi7_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, + struct hal_rx_desc *rx_desc) +{ + u32 tlv_tag; + + tlv_tag = ab->hal.ops->rx_desc_get_mpdu_start_tag(rx_desc); + + return tlv_tag == HAL_RX_MPDU_START; +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index b92f9cf173dc8..2d3eb2313b2f7 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -49,6 +49,9 @@ int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k_dp *dp, struct ath12k_dp_rx_tid *rx_tid, u32 ba_win_sz, u16 ssn, bool update_ssn); +bool +ath12k_wifi7_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, + struct hal_rx_desc *rx_desc); static inline void ath12k_wifi7_dp_extract_rx_desc_data(struct ath12k_hal *hal, struct hal_rx_desc_data *rx_info, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index c0d57d9b1009d..4a0beb4d192ef 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -314,11 +314,6 @@ struct hal_rx_rxpcu_classification_overview { u32 rsvd0; } __packed; -struct hal_rx_msdu_desc_info { - u32 msdu_flags; - u16 msdu_len; /* 14 bits for length */ -}; - #define HAL_RX_NUM_MSDU_DESC 6 struct hal_rx_msdu_list { struct hal_rx_msdu_desc_info msdu_info[HAL_RX_NUM_MSDU_DESC]; From c1c3df48f4bb74950e7abda161bf0b8b588675c6 Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:05 +0530 Subject: [PATCH 102/140] wifi: ath12k: Move RX status TLV parsing to Wi-Fi 7 module Split Wi-Fi 7-specific monitor code out of ath12k common code to improve modularity. Move following RX status TLV parsing functions to the new file wifi7/dp_mon.c and rename the helpers with the ath12k_wifi7_ prefix: - ath12k_dp_mon_rx_parse_status_tlv() - ath12k_dp_mon_parse_rx_dest_tlv() Export helper functions required by the Wi-Fi 7 module. Temporarily include wifi7/hal_rx.h from dp_mon.h to provide HAL structure definitions; remove this dependency in a later patch. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-5-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 399 ++---------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 59 ++- .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 319 +++++++++++++- 3 files changed, 405 insertions(+), 372 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 09aa615769b4c..8792fa2cf29fd 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -17,7 +17,7 @@ #define ATH12K_LE64_DEC_ENC(value, dec_bits, enc_bits) \ u32_encode_bits(le64_get_bits(value, dec_bits), enc_bits) -static void +void ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, struct hal_rx_user_status *rx_user_status) { @@ -26,6 +26,7 @@ ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu rx_user_status->ul_ofdma_user_v0_word1 = __le32_to_cpu(ppdu_end_user->usr_resp_ref_ext); } +EXPORT_SYMBOL(ath12k_dp_mon_rx_handle_ofdma_info); static void ath12k_dp_mon_rx_populate_byte_count(const struct hal_rx_ppdu_end_user_stats *stats, @@ -40,7 +41,7 @@ ath12k_dp_mon_rx_populate_byte_count(const struct hal_rx_ppdu_end_user_stats *st HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_ERR_BYTE_COUNT); } -static void +void ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats *rx_tlv, struct hal_rx_mon_ppdu_info *ppdu_info, struct hal_rx_user_status *rx_user_status) @@ -78,9 +79,10 @@ ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats * ath12k_dp_mon_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status); } +EXPORT_SYMBOL(ath12k_dp_mon_rx_populate_mu_user_info); -static void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, - struct hal_rx_mon_ppdu_info *ppdu_info) +void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, + struct hal_rx_mon_ppdu_info *ppdu_info) { u32 nsts, info0, info1; u8 gi_setting; @@ -118,9 +120,10 @@ static void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vh ppdu_info->vht_flag_values4 = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING); } +EXPORT_SYMBOL(ath12k_dp_mon_parse_vht_sig_a); -static void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, - struct hal_rx_mon_ppdu_info *ppdu_info) +void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, + struct hal_rx_mon_ppdu_info *ppdu_info) { u32 info0 = __le32_to_cpu(ht_sig->info0); u32 info1 = __le32_to_cpu(ht_sig->info1); @@ -132,9 +135,10 @@ static void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, ppdu_info->gi = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_GI); ppdu_info->nss = (ppdu_info->mcs >> 3) + 1; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_ht_sig); -static void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, - struct hal_rx_mon_ppdu_info *ppdu_info) +void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, + struct hal_rx_mon_ppdu_info *ppdu_info) { u32 info0 = __le32_to_cpu(lsigb->info0); u8 rate; @@ -163,9 +167,10 @@ static void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, ppdu_info->rate = rate; ppdu_info->cck_flag = 1; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_l_sig_b); -static void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, - struct hal_rx_mon_ppdu_info *ppdu_info) +void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, + struct hal_rx_mon_ppdu_info *ppdu_info) { u32 info0 = __le32_to_cpu(lsiga->info0); u8 rate; @@ -202,8 +207,9 @@ static void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, ppdu_info->rate = rate; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_l_sig_a); -static void +void ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *ofdma, struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -240,8 +246,9 @@ ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *of ppdu_info->beamformed = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF); } +EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_b2_ofdma); -static void +void ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu, struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -268,8 +275,9 @@ ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS) + 1; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_b2_mu); -static void +void ath12k_dp_mon_parse_he_sig_b1_mu(const struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu, struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -281,8 +289,9 @@ ath12k_dp_mon_parse_he_sig_b1_mu(const struct hal_rx_he_sig_b1_mu_info *he_sig_b ppdu_info->ru_alloc = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones); ppdu_info->he_RU[0] = ru_tones; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_b1_mu); -static void +void ath12k_dp_mon_parse_he_sig_mu(const struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl, struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -414,9 +423,10 @@ ath12k_dp_mon_parse_he_sig_mu(const struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_ ppdu_info->is_stbc = info1 & HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_mu); -static void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a, - struct hal_rx_mon_ppdu_info *ppdu_info) +void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a, + struct hal_rx_mon_ppdu_info *ppdu_info) { u32 info0, info1, value; u32 dcm; @@ -562,6 +572,7 @@ static void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info * HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS) + 1; ppdu_info->dcm = dcm; } +EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_su); static void ath12k_dp_mon_hal_rx_parse_u_sig_cmn(const struct hal_mon_usig_cmn *cmn, @@ -736,7 +747,7 @@ ath12k_dp_mon_hal_rx_parse_u_sig_mu(const struct hal_mon_usig_mu *usig_mu, usig->mask = cpu_to_le32(mask); } -static void +void ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -754,8 +765,9 @@ ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, else ath12k_dp_mon_hal_rx_parse_u_sig_mu(&usig->non_cmn.mu, ppdu_info); } +EXPORT_SYMBOL(ath12k_dp_mon_hal_rx_parse_u_sig_hdr); -static void +void ath12k_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info, u16 tlv_len, const void *tlv_data) { @@ -765,6 +777,7 @@ ath12k_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info, ppdu_info->tlv_aggr.cur_len += tlv_len; } } +EXPORT_SYMBOL(ath12k_dp_mon_hal_aggr_tlv); static inline bool ath12k_dp_mon_hal_rx_is_frame_type_ndp(const struct hal_rx_u_sig_info *usig_info) @@ -1122,7 +1135,7 @@ ath12k_dp_mon_hal_rx_parse_eht_sig_ofdma(const void *tlv, ppdu_info); } -static void +void ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, const void *tlv_data) { @@ -1135,6 +1148,7 @@ ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, else if (ath12k_dp_mon_hal_rx_is_ofdma(&ppdu_info->u_sig_info)) ath12k_dp_mon_hal_rx_parse_eht_sig_ofdma(tlv_data, ppdu_info); } +EXPORT_SYMBOL(ath12k_dp_mon_parse_eht_sig_hdr); static inline enum ath12k_eht_ru_size hal_rx_mon_hal_ru_size_to_ath12k_ru_size(u32 hal_ru_size) @@ -1220,7 +1234,7 @@ hal_rx_ul_ofdma_ru_size_to_width(enum ath12k_eht_ru_size ru_size) } } -static void +void ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info, u16 user_id, struct hal_rx_mon_ppdu_info *ppdu_info) @@ -1421,6 +1435,7 @@ ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_ mon_rx_user_status->ofdma_info_valid = 1; } } +EXPORT_SYMBOL(ath12k_dp_mon_hal_rx_parse_user_info); static void ath12k_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap) { @@ -1446,35 +1461,7 @@ static void ath12k_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap) *errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; } -static void -ath12k_parse_cmn_usr_info(const struct hal_phyrx_common_user_info *cmn_usr_info, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; - u32 known, data, cp_setting, ltf_size; - - known = __le32_to_cpu(eht->known); - known |= IEEE80211_RADIOTAP_EHT_KNOWN_GI | - IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF; - eht->known = cpu_to_le32(known); - - cp_setting = le32_get_bits(cmn_usr_info->info0, - HAL_RX_CMN_USR_INFO0_CP_SETTING); - ltf_size = le32_get_bits(cmn_usr_info->info0, - HAL_RX_CMN_USR_INFO0_LTF_SIZE); - - data = __le32_to_cpu(eht->data[0]); - data |= u32_encode_bits(cp_setting, IEEE80211_RADIOTAP_EHT_DATA0_GI); - data |= u32_encode_bits(ltf_size, IEEE80211_RADIOTAP_EHT_DATA0_LTF); - eht->data[0] = cpu_to_le32(data); - - if (!ppdu_info->ltf_size) - ppdu_info->ltf_size = ltf_size; - if (!ppdu_info->gi) - ppdu_info->gi = cp_setting; -} - -static void +void ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, const struct hal_rx_msdu_end *msdu_end) { @@ -1483,277 +1470,7 @@ ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, pmon->decap_format = le32_get_bits(msdu_end->info1, RX_MSDU_END_INFO11_DECAP_FORMAT); } - -enum hal_rx_mon_status -ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - const struct hal_tlv_64_hdr *tlv) -{ - struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; - const void *tlv_data = tlv->value; - u32 info[7], userid; - u16 tlv_tag, tlv_len; - - tlv_tag = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_TAG); - tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN); - userid = le64_get_bits(tlv->tl, HAL_TLV_64_USR_ID); - - if (ppdu_info->tlv_aggr.in_progress && ppdu_info->tlv_aggr.tlv_tag != tlv_tag) { - ath12k_dp_mon_parse_eht_sig_hdr(ppdu_info, ppdu_info->tlv_aggr.buf); - - ppdu_info->tlv_aggr.in_progress = false; - ppdu_info->tlv_aggr.cur_len = 0; - } - - switch (tlv_tag) { - case HAL_RX_PPDU_START: { - const struct hal_rx_ppdu_start *ppdu_start = tlv_data; - - u64 ppdu_ts = ath12k_le32hilo_to_u64(ppdu_start->ppdu_start_ts_63_32, - ppdu_start->ppdu_start_ts_31_0); - - info[0] = __le32_to_cpu(ppdu_start->info0); - - ppdu_info->ppdu_id = u32_get_bits(info[0], - HAL_RX_PPDU_START_INFO0_PPDU_ID); - - info[1] = __le32_to_cpu(ppdu_start->info1); - ppdu_info->chan_num = u32_get_bits(info[1], - HAL_RX_PPDU_START_INFO1_CHAN_NUM); - ppdu_info->freq = u32_get_bits(info[1], - HAL_RX_PPDU_START_INFO1_CHAN_FREQ); - ppdu_info->ppdu_ts = ppdu_ts; - - if (ppdu_info->ppdu_id != ppdu_info->last_ppdu_id) { - ppdu_info->last_ppdu_id = ppdu_info->ppdu_id; - ppdu_info->num_users = 0; - memset(&ppdu_info->mpdu_fcs_ok_bitmap, 0, - HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * - sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); - } - break; - } - case HAL_RX_PPDU_END_USER_STATS: { - const struct hal_rx_ppdu_end_user_stats *eu_stats = tlv_data; - u32 tid_bitmap; - - info[0] = __le32_to_cpu(eu_stats->info0); - info[1] = __le32_to_cpu(eu_stats->info1); - info[2] = __le32_to_cpu(eu_stats->info2); - info[4] = __le32_to_cpu(eu_stats->info4); - info[5] = __le32_to_cpu(eu_stats->info5); - info[6] = __le32_to_cpu(eu_stats->info6); - - ppdu_info->ast_index = - u32_get_bits(info[2], HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX); - ppdu_info->fc_valid = - u32_get_bits(info[1], HAL_RX_PPDU_END_USER_STATS_INFO1_FC_VALID); - tid_bitmap = u32_get_bits(info[6], - HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP); - ppdu_info->tid = ffs(tid_bitmap) - 1; - ppdu_info->tcp_msdu_count = - u32_get_bits(info[4], - HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT); - ppdu_info->udp_msdu_count = - u32_get_bits(info[4], - HAL_RX_PPDU_END_USER_STATS_INFO4_UDP_MSDU_CNT); - ppdu_info->other_msdu_count = - u32_get_bits(info[5], - HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT); - ppdu_info->tcp_ack_msdu_count = - u32_get_bits(info[5], - HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT); - ppdu_info->preamble_type = - u32_get_bits(info[1], - HAL_RX_PPDU_END_USER_STATS_INFO1_PKT_TYPE); - ppdu_info->num_mpdu_fcs_ok = - u32_get_bits(info[1], - HAL_RX_PPDU_END_USER_STATS_INFO1_MPDU_CNT_FCS_OK); - ppdu_info->num_mpdu_fcs_err = - u32_get_bits(info[0], - HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR); - ppdu_info->peer_id = - u32_get_bits(info[0], HAL_RX_PPDU_END_USER_STATS_INFO0_PEER_ID); - - switch (ppdu_info->preamble_type) { - case HAL_RX_PREAMBLE_11N: - ppdu_info->ht_flags = 1; - break; - case HAL_RX_PREAMBLE_11AC: - ppdu_info->vht_flags = 1; - break; - case HAL_RX_PREAMBLE_11AX: - ppdu_info->he_flags = 1; - break; - case HAL_RX_PREAMBLE_11BE: - ppdu_info->is_eht = true; - break; - default: - break; - } - - if (userid < HAL_MAX_UL_MU_USERS) { - struct hal_rx_user_status *rxuser_stats = - &ppdu_info->userstats[userid]; - - if (ppdu_info->num_mpdu_fcs_ok > 1 || - ppdu_info->num_mpdu_fcs_err > 1) - ppdu_info->userstats[userid].ampdu_present = true; - - ppdu_info->num_users += 1; - - ath12k_dp_mon_rx_handle_ofdma_info(eu_stats, rxuser_stats); - ath12k_dp_mon_rx_populate_mu_user_info(eu_stats, ppdu_info, - rxuser_stats); - } - ppdu_info->mpdu_fcs_ok_bitmap[0] = __le32_to_cpu(eu_stats->rsvd1[0]); - ppdu_info->mpdu_fcs_ok_bitmap[1] = __le32_to_cpu(eu_stats->rsvd1[1]); - break; - } - case HAL_RX_PPDU_END_USER_STATS_EXT: { - const struct hal_rx_ppdu_end_user_stats_ext *eu_stats = tlv_data; - - ppdu_info->mpdu_fcs_ok_bitmap[2] = __le32_to_cpu(eu_stats->info1); - ppdu_info->mpdu_fcs_ok_bitmap[3] = __le32_to_cpu(eu_stats->info2); - ppdu_info->mpdu_fcs_ok_bitmap[4] = __le32_to_cpu(eu_stats->info3); - ppdu_info->mpdu_fcs_ok_bitmap[5] = __le32_to_cpu(eu_stats->info4); - ppdu_info->mpdu_fcs_ok_bitmap[6] = __le32_to_cpu(eu_stats->info5); - ppdu_info->mpdu_fcs_ok_bitmap[7] = __le32_to_cpu(eu_stats->info6); - break; - } - case HAL_PHYRX_HT_SIG: - ath12k_dp_mon_parse_ht_sig(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_L_SIG_B: - ath12k_dp_mon_parse_l_sig_b(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_L_SIG_A: - ath12k_dp_mon_parse_l_sig_a(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_VHT_SIG_A: - ath12k_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_HE_SIG_A_SU: - ath12k_dp_mon_parse_he_sig_su(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_HE_SIG_A_MU_DL: - ath12k_dp_mon_parse_he_sig_mu(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_HE_SIG_B1_MU: - ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_HE_SIG_B2_MU: - ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_HE_SIG_B2_OFDMA: - ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, ppdu_info); - break; - - case HAL_PHYRX_RSSI_LEGACY: { - const struct hal_rx_phyrx_rssi_legacy_info *rssi = tlv_data; - - info[0] = __le32_to_cpu(rssi->info0); - info[2] = __le32_to_cpu(rssi->info2); - - /* TODO: Please note that the combined rssi will not be accurate - * in MU case. Rssi in MU needs to be retrieved from - * PHYRX_OTHER_RECEIVE_INFO TLV. - */ - ppdu_info->rssi_comb = - u32_get_bits(info[2], - HAL_RX_RSSI_LEGACY_INFO_INFO2_RSSI_COMB_PPDU); - - ppdu_info->bw = u32_get_bits(info[0], - HAL_RX_RSSI_LEGACY_INFO_INFO0_RX_BW); - break; - } - case HAL_PHYRX_COMMON_USER_INFO: { - ath12k_parse_cmn_usr_info(tlv_data, ppdu_info); - break; - } - case HAL_RX_PPDU_START_USER_INFO: - ath12k_dp_mon_hal_rx_parse_user_info(tlv_data, userid, ppdu_info); - break; - - case HAL_RXPCU_PPDU_END_INFO: { - const struct hal_rx_ppdu_end_duration *ppdu_rx_duration = tlv_data; - - info[0] = __le32_to_cpu(ppdu_rx_duration->info0); - ppdu_info->rx_duration = - u32_get_bits(info[0], HAL_RX_PPDU_END_DURATION); - ppdu_info->tsft = __le32_to_cpu(ppdu_rx_duration->rsvd0[1]); - ppdu_info->tsft = (ppdu_info->tsft << 32) | - __le32_to_cpu(ppdu_rx_duration->rsvd0[0]); - break; - } - case HAL_RX_MPDU_START: { - const struct hal_rx_mpdu_start *mpdu_start = tlv_data; - u16 peer_id; - - info[1] = __le32_to_cpu(mpdu_start->info1); - peer_id = u32_get_bits(info[1], HAL_RX_MPDU_START_INFO1_PEERID); - if (peer_id) - ppdu_info->peer_id = peer_id; - - ppdu_info->mpdu_len += u32_get_bits(info[1], - HAL_RX_MPDU_START_INFO2_MPDU_LEN); - if (userid < HAL_MAX_UL_MU_USERS) { - info[0] = __le32_to_cpu(mpdu_start->info0); - ppdu_info->userid = userid; - ppdu_info->userstats[userid].ampdu_id = - u32_get_bits(info[0], HAL_RX_MPDU_START_INFO0_PPDU_ID); - } - - return HAL_RX_MON_STATUS_MPDU_START; - } - case HAL_RX_MSDU_START: - /* TODO: add msdu start parsing logic */ - break; - case HAL_MON_BUF_ADDR: - return HAL_RX_MON_STATUS_BUF_ADDR; - case HAL_RX_MSDU_END: - ath12k_dp_mon_parse_status_msdu_end(pmon, tlv_data); - return HAL_RX_MON_STATUS_MSDU_END; - case HAL_RX_MPDU_END: - return HAL_RX_MON_STATUS_MPDU_END; - case HAL_PHYRX_GENERIC_U_SIG: - ath12k_dp_mon_hal_rx_parse_u_sig_hdr(tlv_data, ppdu_info); - break; - case HAL_PHYRX_GENERIC_EHT_SIG: - /* Handle the case where aggregation is in progress - * or the current TLV is one of the TLVs which should be - * aggregated - */ - if (!ppdu_info->tlv_aggr.in_progress) { - ppdu_info->tlv_aggr.in_progress = true; - ppdu_info->tlv_aggr.tlv_tag = tlv_tag; - ppdu_info->tlv_aggr.cur_len = 0; - } - - ppdu_info->is_eht = true; - - ath12k_dp_mon_hal_aggr_tlv(ppdu_info, tlv_len, tlv_data); - break; - case HAL_DUMMY: - return HAL_RX_MON_STATUS_BUF_DONE; - case HAL_RX_PPDU_END_STATUS_DONE: - case 0: - return HAL_RX_MON_STATUS_PPDU_DONE; - default: - break; - } - - return HAL_RX_MON_STATUS_PPDU_NOT_DONE; -} -EXPORT_SYMBOL(ath12k_dp_mon_rx_parse_status_tlv); +EXPORT_SYMBOL(ath12k_dp_mon_parse_status_msdu_end); static void ath12k_dp_mon_fill_rx_stats_info(struct hal_rx_mon_ppdu_info *ppdu_info, @@ -2448,7 +2165,7 @@ ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, } EXPORT_SYMBOL(ath12k_dp_mon_get_buf_len); -static int +int ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct dp_mon_packet_info *packet_info) @@ -2493,45 +2210,7 @@ ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, return 0; } - -int -ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - enum hal_rx_mon_status hal_status, - const void *tlv_data) -{ - switch (hal_status) { - case HAL_RX_MON_STATUS_MPDU_START: - if (WARN_ON_ONCE(pmon->mon_mpdu)) - break; - - pmon->mon_mpdu = kzalloc(sizeof(*pmon->mon_mpdu), GFP_ATOMIC); - if (!pmon->mon_mpdu) - return -ENOMEM; - break; - case HAL_RX_MON_STATUS_BUF_ADDR: - return ath12k_dp_mon_parse_status_buf(dp_pdev, pmon, tlv_data); - case HAL_RX_MON_STATUS_MPDU_END: - /* If no MSDU then free empty MPDU */ - if (pmon->mon_mpdu->tail) { - pmon->mon_mpdu->tail->next = NULL; - list_add_tail(&pmon->mon_mpdu->list, &pmon->dp_rx_mon_mpdu_list); - } else { - kfree(pmon->mon_mpdu); - } - pmon->mon_mpdu = NULL; - break; - case HAL_RX_MON_STATUS_MSDU_END: - pmon->mon_mpdu->decap_format = pmon->decap_format; - pmon->mon_mpdu->err_bitmap = pmon->err_bitmap; - break; - default: - break; - } - - return 0; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_rx_dest_tlv); +EXPORT_SYMBOL(ath12k_dp_mon_parse_status_buf); int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *buf_ring, diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 425bec6f0f3ca..bfea7d4041cb9 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -9,6 +9,7 @@ #include "core.h" #include "wifi7/hal_desc.h" +#include "wifi7/hal_rx.h" #define ATH12K_MON_RX_DOT11_OFFSET 5 #define ATH12K_MON_RX_PKT_OFFSET 8 @@ -106,15 +107,6 @@ int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, struct dp_mon_mpdu *mon_mpdu, struct hal_rx_mon_ppdu_info *ppduinfo, struct napi_struct *napi); -int -ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - enum hal_rx_mon_status hal_status, - const void *tlv_data); -enum hal_rx_mon_status -ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - const struct hal_tlv_64_hdr *tlv); struct sk_buff *ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, @@ -128,4 +120,53 @@ void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm, struct ath12k_buffer_addr **pp_buf_addr_info); u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id); +int +ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + const struct dp_mon_packet_info *packet_info); +void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, + const void *tlv_data); +void +ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, + struct hal_rx_user_status *rx_user_status); +void +ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats *rx_tlv, + struct hal_rx_mon_ppdu_info *ppdu_info, + struct hal_rx_user_status *rx_user_status); +void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, + struct hal_rx_mon_ppdu_info *ppdu_info); +void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *ofdma, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu, + struct hal_rx_mon_ppdu_info *ppdu_info); +void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, + struct hal_rx_mon_ppdu_info *ppdu_info); +void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_parse_he_sig_b1_mu(const struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_parse_he_sig_mu(const struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info, + u16 user_id, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, + const struct hal_rx_msdu_end *msdu_end); +void +ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, + struct hal_rx_mon_ppdu_info *ppdu_info); +void +ath12k_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info, + u16 tlv_len, const void *tlv_data); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index dae3f262cc507..076fb75a101f1 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -10,6 +10,7 @@ #include "../debug.h" #include "hal_qcn9274.h" #include "dp_rx.h" +#include "../dp_tx.h" #include "../peer.h" static void @@ -19,6 +20,317 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } +static enum hal_rx_mon_status +ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + const struct hal_tlv_64_hdr *tlv) +{ + struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info; + const void *tlv_data = tlv->value; + u32 info[7], userid; + u16 tlv_tag, tlv_len; + + tlv_tag = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_TAG); + tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN); + userid = le64_get_bits(tlv->tl, HAL_TLV_64_USR_ID); + + if (ppdu_info->tlv_aggr.in_progress && ppdu_info->tlv_aggr.tlv_tag != tlv_tag) { + ath12k_dp_mon_parse_eht_sig_hdr(ppdu_info, ppdu_info->tlv_aggr.buf); + + ppdu_info->tlv_aggr.in_progress = false; + ppdu_info->tlv_aggr.cur_len = 0; + } + + switch (tlv_tag) { + case HAL_RX_PPDU_START: { + const struct hal_rx_ppdu_start *ppdu_start = tlv_data; + + u64 ppdu_ts = ath12k_le32hilo_to_u64(ppdu_start->ppdu_start_ts_63_32, + ppdu_start->ppdu_start_ts_31_0); + + info[0] = __le32_to_cpu(ppdu_start->info0); + + ppdu_info->ppdu_id = u32_get_bits(info[0], + HAL_RX_PPDU_START_INFO0_PPDU_ID); + + info[1] = __le32_to_cpu(ppdu_start->info1); + ppdu_info->chan_num = u32_get_bits(info[1], + HAL_RX_PPDU_START_INFO1_CHAN_NUM); + ppdu_info->freq = u32_get_bits(info[1], + HAL_RX_PPDU_START_INFO1_CHAN_FREQ); + ppdu_info->ppdu_ts = ppdu_ts; + + if (ppdu_info->ppdu_id != ppdu_info->last_ppdu_id) { + ppdu_info->last_ppdu_id = ppdu_info->ppdu_id; + ppdu_info->num_users = 0; + memset(&ppdu_info->mpdu_fcs_ok_bitmap, 0, + HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * + sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); + } + break; + } + case HAL_RX_PPDU_END_USER_STATS: { + const struct hal_rx_ppdu_end_user_stats *eu_stats = tlv_data; + u32 tid_bitmap; + + info[0] = __le32_to_cpu(eu_stats->info0); + info[1] = __le32_to_cpu(eu_stats->info1); + info[2] = __le32_to_cpu(eu_stats->info2); + info[4] = __le32_to_cpu(eu_stats->info4); + info[5] = __le32_to_cpu(eu_stats->info5); + info[6] = __le32_to_cpu(eu_stats->info6); + + ppdu_info->ast_index = + u32_get_bits(info[2], HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX); + ppdu_info->fc_valid = + u32_get_bits(info[1], HAL_RX_PPDU_END_USER_STATS_INFO1_FC_VALID); + tid_bitmap = u32_get_bits(info[6], + HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP); + ppdu_info->tid = ffs(tid_bitmap) - 1; + ppdu_info->tcp_msdu_count = + u32_get_bits(info[4], + HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT); + ppdu_info->udp_msdu_count = + u32_get_bits(info[4], + HAL_RX_PPDU_END_USER_STATS_INFO4_UDP_MSDU_CNT); + ppdu_info->other_msdu_count = + u32_get_bits(info[5], + HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT); + ppdu_info->tcp_ack_msdu_count = + u32_get_bits(info[5], + HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT); + ppdu_info->preamble_type = + u32_get_bits(info[1], + HAL_RX_PPDU_END_USER_STATS_INFO1_PKT_TYPE); + ppdu_info->num_mpdu_fcs_ok = + u32_get_bits(info[1], + HAL_RX_PPDU_END_USER_STATS_INFO1_MPDU_CNT_FCS_OK); + ppdu_info->num_mpdu_fcs_err = + u32_get_bits(info[0], + HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR); + ppdu_info->peer_id = + u32_get_bits(info[0], HAL_RX_PPDU_END_USER_STATS_INFO0_PEER_ID); + + switch (ppdu_info->preamble_type) { + case HAL_RX_PREAMBLE_11N: + ppdu_info->ht_flags = 1; + break; + case HAL_RX_PREAMBLE_11AC: + ppdu_info->vht_flags = 1; + break; + case HAL_RX_PREAMBLE_11AX: + ppdu_info->he_flags = 1; + break; + case HAL_RX_PREAMBLE_11BE: + ppdu_info->is_eht = true; + break; + default: + break; + } + + if (userid < HAL_MAX_UL_MU_USERS) { + struct hal_rx_user_status *rxuser_stats = + &ppdu_info->userstats[userid]; + + if (ppdu_info->num_mpdu_fcs_ok > 1 || + ppdu_info->num_mpdu_fcs_err > 1) + ppdu_info->userstats[userid].ampdu_present = true; + + ppdu_info->num_users += 1; + + ath12k_dp_mon_rx_handle_ofdma_info(eu_stats, rxuser_stats); + ath12k_dp_mon_rx_populate_mu_user_info(eu_stats, ppdu_info, + rxuser_stats); + } + ppdu_info->mpdu_fcs_ok_bitmap[0] = __le32_to_cpu(eu_stats->rsvd1[0]); + ppdu_info->mpdu_fcs_ok_bitmap[1] = __le32_to_cpu(eu_stats->rsvd1[1]); + break; + } + case HAL_RX_PPDU_END_USER_STATS_EXT: { + const struct hal_rx_ppdu_end_user_stats_ext *eu_stats = tlv_data; + + ppdu_info->mpdu_fcs_ok_bitmap[2] = __le32_to_cpu(eu_stats->info1); + ppdu_info->mpdu_fcs_ok_bitmap[3] = __le32_to_cpu(eu_stats->info2); + ppdu_info->mpdu_fcs_ok_bitmap[4] = __le32_to_cpu(eu_stats->info3); + ppdu_info->mpdu_fcs_ok_bitmap[5] = __le32_to_cpu(eu_stats->info4); + ppdu_info->mpdu_fcs_ok_bitmap[6] = __le32_to_cpu(eu_stats->info5); + ppdu_info->mpdu_fcs_ok_bitmap[7] = __le32_to_cpu(eu_stats->info6); + break; + } + case HAL_PHYRX_HT_SIG: + ath12k_dp_mon_parse_ht_sig(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_L_SIG_B: + ath12k_dp_mon_parse_l_sig_b(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_L_SIG_A: + ath12k_dp_mon_parse_l_sig_a(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_VHT_SIG_A: + ath12k_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_HE_SIG_A_SU: + ath12k_dp_mon_parse_he_sig_su(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_HE_SIG_A_MU_DL: + ath12k_dp_mon_parse_he_sig_mu(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_HE_SIG_B1_MU: + ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_HE_SIG_B2_MU: + ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_HE_SIG_B2_OFDMA: + ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, ppdu_info); + break; + + case HAL_PHYRX_RSSI_LEGACY: { + const struct hal_rx_phyrx_rssi_legacy_info *rssi = tlv_data; + + info[0] = __le32_to_cpu(rssi->info0); + info[1] = __le32_to_cpu(rssi->info1); + + /* TODO: Please note that the combined rssi will not be accurate + * in MU case. Rssi in MU needs to be retrieved from + * PHYRX_OTHER_RECEIVE_INFO TLV. + */ + ppdu_info->rssi_comb = + u32_get_bits(info[1], + HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO1_RSSI_COMB); + + ppdu_info->bw = u32_get_bits(info[0], + HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RX_BW); + break; + } + case HAL_PHYRX_OTHER_RECEIVE_INFO: { + const struct hal_phyrx_common_user_info *cmn_usr_info = tlv_data; + + ppdu_info->gi = le32_get_bits(cmn_usr_info->info0, + HAL_RX_PHY_CMN_USER_INFO0_GI); + break; + } + case HAL_RX_PPDU_START_USER_INFO: + ath12k_dp_mon_hal_rx_parse_user_info(tlv_data, userid, ppdu_info); + break; + + case HAL_RXPCU_PPDU_END_INFO: { + const struct hal_rx_ppdu_end_duration *ppdu_rx_duration = tlv_data; + + info[0] = __le32_to_cpu(ppdu_rx_duration->info0); + ppdu_info->rx_duration = + u32_get_bits(info[0], HAL_RX_PPDU_END_DURATION); + ppdu_info->tsft = __le32_to_cpu(ppdu_rx_duration->rsvd0[1]); + ppdu_info->tsft = (ppdu_info->tsft << 32) | + __le32_to_cpu(ppdu_rx_duration->rsvd0[0]); + break; + } + case HAL_RX_MPDU_START: { + const struct hal_rx_mpdu_start *mpdu_start = tlv_data; + u16 peer_id; + + info[1] = __le32_to_cpu(mpdu_start->info1); + peer_id = u32_get_bits(info[1], HAL_RX_MPDU_START_INFO1_PEERID); + if (peer_id) + ppdu_info->peer_id = peer_id; + + ppdu_info->mpdu_len += u32_get_bits(info[1], + HAL_RX_MPDU_START_INFO2_MPDU_LEN); + if (userid < HAL_MAX_UL_MU_USERS) { + info[0] = __le32_to_cpu(mpdu_start->info0); + ppdu_info->userid = userid; + ppdu_info->userstats[userid].ampdu_id = + u32_get_bits(info[0], HAL_RX_MPDU_START_INFO0_PPDU_ID); + } + + return HAL_RX_MON_STATUS_MPDU_START; + } + case HAL_RX_MSDU_START: + /* TODO: add msdu start parsing logic */ + break; + case HAL_MON_BUF_ADDR: + return HAL_RX_MON_STATUS_BUF_ADDR; + case HAL_RX_MSDU_END: + ath12k_dp_mon_parse_status_msdu_end(pmon, tlv_data); + return HAL_RX_MON_STATUS_MSDU_END; + case HAL_RX_MPDU_END: + return HAL_RX_MON_STATUS_MPDU_END; + case HAL_PHYRX_GENERIC_U_SIG: + ath12k_dp_mon_hal_rx_parse_u_sig_hdr(tlv_data, ppdu_info); + break; + case HAL_PHYRX_GENERIC_EHT_SIG: + /* Handle the case where aggregation is in progress + * or the current TLV is one of the TLVs which should be + * aggregated + */ + if (!ppdu_info->tlv_aggr.in_progress) { + ppdu_info->tlv_aggr.in_progress = true; + ppdu_info->tlv_aggr.tlv_tag = tlv_tag; + ppdu_info->tlv_aggr.cur_len = 0; + } + + ppdu_info->is_eht = true; + + ath12k_dp_mon_hal_aggr_tlv(ppdu_info, tlv_len, tlv_data); + break; + case HAL_DUMMY: + return HAL_RX_MON_STATUS_BUF_DONE; + case HAL_RX_PPDU_END_STATUS_DONE: + case 0: + return HAL_RX_MON_STATUS_PPDU_DONE; + default: + break; + } + + return HAL_RX_MON_STATUS_PPDU_NOT_DONE; +} + +static int +ath12k_wifi7_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + enum hal_rx_mon_status hal_status, + const void *tlv_data) +{ + switch (hal_status) { + case HAL_RX_MON_STATUS_MPDU_START: + if (WARN_ON_ONCE(pmon->mon_mpdu)) + break; + + pmon->mon_mpdu = kzalloc(sizeof(*pmon->mon_mpdu), GFP_ATOMIC); + if (!pmon->mon_mpdu) + return -ENOMEM; + break; + case HAL_RX_MON_STATUS_BUF_ADDR: + return ath12k_dp_mon_parse_status_buf(dp_pdev, pmon, tlv_data); + case HAL_RX_MON_STATUS_MPDU_END: + /* If no MSDU then free empty MPDU */ + if (pmon->mon_mpdu->tail) { + pmon->mon_mpdu->tail->next = NULL; + list_add_tail(&pmon->mon_mpdu->list, &pmon->dp_rx_mon_mpdu_list); + } else { + kfree(pmon->mon_mpdu); + } + pmon->mon_mpdu = NULL; + break; + case HAL_RX_MON_STATUS_MSDU_END: + pmon->mon_mpdu->decap_format = pmon->decap_format; + pmon->mon_mpdu->err_bitmap = pmon->err_bitmap; + break; + default: + break; + } + + return 0; +} + static u32 ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, void *ring_entry, struct sk_buff **head_msdu, @@ -389,11 +701,12 @@ ath12k_wifi7_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev, else tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN); - hal_status = ath12k_dp_mon_rx_parse_status_tlv(dp_pdev, pmon, tlv); + hal_status = ath12k_wifi7_dp_mon_rx_parse_status_tlv(dp_pdev, pmon, + tlv); if (ar->monitor_started && ar->ab->hw_params->rxdma1_enable && - ath12k_dp_mon_parse_rx_dest_tlv(dp_pdev, pmon, hal_status, - tlv->value)) + ath12k_wifi7_dp_mon_parse_rx_dest_tlv(dp_pdev, pmon, hal_status, + tlv->value)) return HAL_RX_MON_STATUS_PPDU_DONE; ptr += sizeof(*tlv) + tlv_len; From fc379aa65fc9651a8d6a31902242731b1651fc0c Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:06 +0530 Subject: [PATCH 103/140] wifi: ath12k: Move TX monitor functionality to Wi-Fi 7 module Separate Wi-Fi 7-specific TX monitor functionality from ath12k common code to improve modularity and maintainability. Move following TX monitor processing functions to wifi7/dp_mon.c and rename the functions with the ath12k_wifi7_ prefix: - ath12k_dp_mon_tx_get_ppdu_info() - ath12k_dp_mon_hal_tx_ppdu_info() - ath12k_dp_mon_tx_alloc_skb() - ath12k_dp_mon_tx_gen_cts2self_frame() - ath12k_dp_mon_tx_gen_rts_frame() - ath12k_dp_mon_tx_gen_3addr_qos_null_frame() - ath12k_dp_mon_tx_gen_4addr_qos_null_frame() - ath12k_dp_mon_tx_gen_ack_frame() - ath12k_dp_mon_tx_gen_prot_frame() - ath12k_dp_mon_tx_parse_status_tlv() - ath12k_dp_mon_tx_status_get_num_user() - ath12k_dp_mon_tx_process_ppdu_info() - ath12k_dp_mon_tx_parse_mon_status() Export helper functions required by the ath12k_wifi7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-6-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 671 ----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 11 - .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 676 ++++++++++++++++++ .../net/wireless/ath/ath12k/wifi7/dp_mon.h | 6 + 4 files changed, 682 insertions(+), 682 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 8792fa2cf29fd..06f1045ee5f3c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2376,677 +2376,6 @@ int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, return req_entries - num_remain; } -static struct dp_mon_tx_ppdu_info * -ath12k_dp_mon_tx_get_ppdu_info(struct ath12k_mon_data *pmon, - unsigned int ppdu_id, - enum dp_mon_tx_ppdu_info_type type) -{ - struct dp_mon_tx_ppdu_info *tx_ppdu_info; - - if (type == DP_MON_TX_PROT_PPDU_INFO) { - tx_ppdu_info = pmon->tx_prot_ppdu_info; - - if (tx_ppdu_info && !tx_ppdu_info->is_used) - return tx_ppdu_info; - kfree(tx_ppdu_info); - } else { - tx_ppdu_info = pmon->tx_data_ppdu_info; - - if (tx_ppdu_info && !tx_ppdu_info->is_used) - return tx_ppdu_info; - kfree(tx_ppdu_info); - } - - /* allocate new tx_ppdu_info */ - tx_ppdu_info = kzalloc(sizeof(*tx_ppdu_info), GFP_ATOMIC); - if (!tx_ppdu_info) - return NULL; - - tx_ppdu_info->is_used = 0; - tx_ppdu_info->ppdu_id = ppdu_id; - - if (type == DP_MON_TX_PROT_PPDU_INFO) - pmon->tx_prot_ppdu_info = tx_ppdu_info; - else - pmon->tx_data_ppdu_info = tx_ppdu_info; - - return tx_ppdu_info; -} - -static struct dp_mon_tx_ppdu_info * -ath12k_dp_mon_hal_tx_ppdu_info(struct ath12k_mon_data *pmon, - u16 tlv_tag) -{ - switch (tlv_tag) { - case HAL_TX_FES_SETUP: - case HAL_TX_FLUSH: - case HAL_PCU_PPDU_SETUP_INIT: - case HAL_TX_PEER_ENTRY: - case HAL_TX_QUEUE_EXTENSION: - case HAL_TX_MPDU_START: - case HAL_TX_MSDU_START: - case HAL_TX_DATA: - case HAL_MON_BUF_ADDR: - case HAL_TX_MPDU_END: - case HAL_TX_LAST_MPDU_FETCHED: - case HAL_TX_LAST_MPDU_END: - case HAL_COEX_TX_REQ: - case HAL_TX_RAW_OR_NATIVE_FRAME_SETUP: - case HAL_SCH_CRITICAL_TLV_REFERENCE: - case HAL_TX_FES_SETUP_COMPLETE: - case HAL_TQM_MPDU_GLOBAL_START: - case HAL_SCHEDULER_END: - case HAL_TX_FES_STATUS_USER_PPDU: - break; - case HAL_TX_FES_STATUS_PROT: { - if (!pmon->tx_prot_ppdu_info->is_used) - pmon->tx_prot_ppdu_info->is_used = true; - - return pmon->tx_prot_ppdu_info; - } - } - - if (!pmon->tx_data_ppdu_info->is_used) - pmon->tx_data_ppdu_info->is_used = true; - - return pmon->tx_data_ppdu_info; -} - -#define MAX_MONITOR_HEADER 512 -#define MAX_DUMMY_FRM_BODY 128 - -struct sk_buff *ath12k_dp_mon_tx_alloc_skb(void) -{ - struct sk_buff *skb; - - skb = dev_alloc_skb(MAX_MONITOR_HEADER + MAX_DUMMY_FRM_BODY); - if (!skb) - return NULL; - - skb_reserve(skb, MAX_MONITOR_HEADER); - - if (!IS_ALIGNED((unsigned long)skb->data, 4)) - skb_pull(skb, PTR_ALIGN(skb->data, 4) - skb->data); - - return skb; -} - -static int -ath12k_dp_mon_tx_gen_cts2self_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - struct sk_buff *skb; - struct ieee80211_cts *cts; - - skb = ath12k_dp_mon_tx_alloc_skb(); - if (!skb) - return -ENOMEM; - - cts = (struct ieee80211_cts *)skb->data; - memset(cts, 0, MAX_DUMMY_FRM_BODY); - cts->frame_control = - cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); - cts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); - memcpy(cts->ra, tx_ppdu_info->rx_status.addr1, sizeof(cts->ra)); - - skb_put(skb, sizeof(*cts)); - tx_ppdu_info->tx_mon_mpdu->head = skb; - tx_ppdu_info->tx_mon_mpdu->tail = NULL; - list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, - &tx_ppdu_info->dp_tx_mon_mpdu_list); - - return 0; -} - -static int -ath12k_dp_mon_tx_gen_rts_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - struct sk_buff *skb; - struct ieee80211_rts *rts; - - skb = ath12k_dp_mon_tx_alloc_skb(); - if (!skb) - return -ENOMEM; - - rts = (struct ieee80211_rts *)skb->data; - memset(rts, 0, MAX_DUMMY_FRM_BODY); - rts->frame_control = - cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); - rts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); - memcpy(rts->ra, tx_ppdu_info->rx_status.addr1, sizeof(rts->ra)); - memcpy(rts->ta, tx_ppdu_info->rx_status.addr2, sizeof(rts->ta)); - - skb_put(skb, sizeof(*rts)); - tx_ppdu_info->tx_mon_mpdu->head = skb; - tx_ppdu_info->tx_mon_mpdu->tail = NULL; - list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, - &tx_ppdu_info->dp_tx_mon_mpdu_list); - - return 0; -} - -static int -ath12k_dp_mon_tx_gen_3addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - struct sk_buff *skb; - struct ieee80211_qos_hdr *qhdr; - - skb = ath12k_dp_mon_tx_alloc_skb(); - if (!skb) - return -ENOMEM; - - qhdr = (struct ieee80211_qos_hdr *)skb->data; - memset(qhdr, 0, MAX_DUMMY_FRM_BODY); - qhdr->frame_control = - cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC); - qhdr->duration_id = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); - memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); - memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN); - memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN); - - skb_put(skb, sizeof(*qhdr)); - tx_ppdu_info->tx_mon_mpdu->head = skb; - tx_ppdu_info->tx_mon_mpdu->tail = NULL; - list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, - &tx_ppdu_info->dp_tx_mon_mpdu_list); - - return 0; -} - -static int -ath12k_dp_mon_tx_gen_4addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - struct sk_buff *skb; - struct dp_mon_qosframe_addr4 *qhdr; - - skb = ath12k_dp_mon_tx_alloc_skb(); - if (!skb) - return -ENOMEM; - - qhdr = (struct dp_mon_qosframe_addr4 *)skb->data; - memset(qhdr, 0, MAX_DUMMY_FRM_BODY); - qhdr->frame_control = - cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC); - qhdr->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); - memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); - memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN); - memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN); - memcpy(qhdr->addr4, tx_ppdu_info->rx_status.addr4, ETH_ALEN); - - skb_put(skb, sizeof(*qhdr)); - tx_ppdu_info->tx_mon_mpdu->head = skb; - tx_ppdu_info->tx_mon_mpdu->tail = NULL; - list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, - &tx_ppdu_info->dp_tx_mon_mpdu_list); - - return 0; -} - -static int -ath12k_dp_mon_tx_gen_ack_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - struct sk_buff *skb; - struct dp_mon_frame_min_one *fbmhdr; - - skb = ath12k_dp_mon_tx_alloc_skb(); - if (!skb) - return -ENOMEM; - - fbmhdr = (struct dp_mon_frame_min_one *)skb->data; - memset(fbmhdr, 0, MAX_DUMMY_FRM_BODY); - fbmhdr->frame_control = - cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_CFACK); - memcpy(fbmhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); - - /* set duration zero for ack frame */ - fbmhdr->duration = 0; - - skb_put(skb, sizeof(*fbmhdr)); - tx_ppdu_info->tx_mon_mpdu->head = skb; - tx_ppdu_info->tx_mon_mpdu->tail = NULL; - list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, - &tx_ppdu_info->dp_tx_mon_mpdu_list); - - return 0; -} - -static int -ath12k_dp_mon_tx_gen_prot_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - int ret = 0; - - switch (tx_ppdu_info->rx_status.medium_prot_type) { - case DP_MON_TX_MEDIUM_RTS_LEGACY: - case DP_MON_TX_MEDIUM_RTS_11AC_STATIC_BW: - case DP_MON_TX_MEDIUM_RTS_11AC_DYNAMIC_BW: - ret = ath12k_dp_mon_tx_gen_rts_frame(tx_ppdu_info); - break; - case DP_MON_TX_MEDIUM_CTS2SELF: - ret = ath12k_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info); - break; - case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_3ADDR: - ret = ath12k_dp_mon_tx_gen_3addr_qos_null_frame(tx_ppdu_info); - break; - case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_4ADDR: - ret = ath12k_dp_mon_tx_gen_4addr_qos_null_frame(tx_ppdu_info); - break; - } - - return ret; -} - -static enum dp_mon_tx_tlv_status -ath12k_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab, - struct ath12k_mon_data *pmon, - u16 tlv_tag, const void *tlv_data, u32 userid) -{ - struct dp_mon_tx_ppdu_info *tx_ppdu_info; - enum dp_mon_tx_tlv_status status = DP_MON_TX_STATUS_PPDU_NOT_DONE; - u32 info[7]; - - tx_ppdu_info = ath12k_dp_mon_hal_tx_ppdu_info(pmon, tlv_tag); - - switch (tlv_tag) { - case HAL_TX_FES_SETUP: { - const struct hal_tx_fes_setup *tx_fes_setup = tlv_data; - - info[0] = __le32_to_cpu(tx_fes_setup->info0); - tx_ppdu_info->ppdu_id = __le32_to_cpu(tx_fes_setup->schedule_id); - tx_ppdu_info->num_users = - u32_get_bits(info[0], HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS); - status = DP_MON_TX_FES_SETUP; - break; - } - - case HAL_TX_FES_STATUS_END: { - const struct hal_tx_fes_status_end *tx_fes_status_end = tlv_data; - u32 tst_15_0, tst_31_16; - - info[0] = __le32_to_cpu(tx_fes_status_end->info0); - tst_15_0 = - u32_get_bits(info[0], - HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_15_0); - tst_31_16 = - u32_get_bits(info[0], - HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_31_16); - - tx_ppdu_info->rx_status.ppdu_ts = (tst_15_0 | (tst_31_16 << 16)); - status = DP_MON_TX_FES_STATUS_END; - break; - } - - case HAL_RX_RESPONSE_REQUIRED_INFO: { - const struct hal_rx_resp_req_info *rx_resp_req_info = tlv_data; - u32 addr_32; - u16 addr_16; - - info[0] = __le32_to_cpu(rx_resp_req_info->info0); - info[1] = __le32_to_cpu(rx_resp_req_info->info1); - info[2] = __le32_to_cpu(rx_resp_req_info->info2); - info[3] = __le32_to_cpu(rx_resp_req_info->info3); - info[4] = __le32_to_cpu(rx_resp_req_info->info4); - info[5] = __le32_to_cpu(rx_resp_req_info->info5); - - tx_ppdu_info->rx_status.ppdu_id = - u32_get_bits(info[0], HAL_RX_RESP_REQ_INFO0_PPDU_ID); - tx_ppdu_info->rx_status.reception_type = - u32_get_bits(info[0], HAL_RX_RESP_REQ_INFO0_RECEPTION_TYPE); - tx_ppdu_info->rx_status.rx_duration = - u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_DURATION); - tx_ppdu_info->rx_status.mcs = - u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_RATE_MCS); - tx_ppdu_info->rx_status.sgi = - u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_SGI); - tx_ppdu_info->rx_status.is_stbc = - u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_STBC); - tx_ppdu_info->rx_status.ldpc = - u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_LDPC); - tx_ppdu_info->rx_status.is_ampdu = - u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_IS_AMPDU); - tx_ppdu_info->rx_status.num_users = - u32_get_bits(info[2], HAL_RX_RESP_REQ_INFO2_NUM_USER); - - addr_32 = u32_get_bits(info[3], HAL_RX_RESP_REQ_INFO3_ADDR1_31_0); - addr_16 = u32_get_bits(info[3], HAL_RX_RESP_REQ_INFO4_ADDR1_47_32); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1); - - addr_16 = u32_get_bits(info[4], HAL_RX_RESP_REQ_INFO4_ADDR1_15_0); - addr_32 = u32_get_bits(info[5], HAL_RX_RESP_REQ_INFO5_ADDR1_47_16); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr2); - - if (tx_ppdu_info->rx_status.reception_type == 0) - ath12k_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info); - status = DP_MON_RX_RESPONSE_REQUIRED_INFO; - break; - } - - case HAL_PCU_PPDU_SETUP_INIT: { - const struct hal_tx_pcu_ppdu_setup_init *ppdu_setup = tlv_data; - u32 addr_32; - u16 addr_16; - - info[0] = __le32_to_cpu(ppdu_setup->info0); - info[1] = __le32_to_cpu(ppdu_setup->info1); - info[2] = __le32_to_cpu(ppdu_setup->info2); - info[3] = __le32_to_cpu(ppdu_setup->info3); - info[4] = __le32_to_cpu(ppdu_setup->info4); - info[5] = __le32_to_cpu(ppdu_setup->info5); - info[6] = __le32_to_cpu(ppdu_setup->info6); - - /* protection frame address 1 */ - addr_32 = u32_get_bits(info[1], - HAL_TX_PPDU_SETUP_INFO1_PROT_FRAME_ADDR1_31_0); - addr_16 = u32_get_bits(info[2], - HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR1_47_32); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1); - - /* protection frame address 2 */ - addr_16 = u32_get_bits(info[2], - HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR2_15_0); - addr_32 = u32_get_bits(info[3], - HAL_TX_PPDU_SETUP_INFO3_PROT_FRAME_ADDR2_47_16); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr2); - - /* protection frame address 3 */ - addr_32 = u32_get_bits(info[4], - HAL_TX_PPDU_SETUP_INFO4_PROT_FRAME_ADDR3_31_0); - addr_16 = u32_get_bits(info[5], - HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR3_47_32); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr3); - - /* protection frame address 4 */ - addr_16 = u32_get_bits(info[5], - HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR4_15_0); - addr_32 = u32_get_bits(info[6], - HAL_TX_PPDU_SETUP_INFO6_PROT_FRAME_ADDR4_47_16); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr4); - - status = u32_get_bits(info[0], - HAL_TX_PPDU_SETUP_INFO0_MEDIUM_PROT_TYPE); - break; - } - - case HAL_TX_QUEUE_EXTENSION: { - const struct hal_tx_queue_exten *tx_q_exten = tlv_data; - - info[0] = __le32_to_cpu(tx_q_exten->info0); - - tx_ppdu_info->rx_status.frame_control = - u32_get_bits(info[0], - HAL_TX_Q_EXT_INFO0_FRAME_CTRL); - tx_ppdu_info->rx_status.fc_valid = true; - break; - } - - case HAL_TX_FES_STATUS_START: { - const struct hal_tx_fes_status_start *tx_fes_start = tlv_data; - - info[0] = __le32_to_cpu(tx_fes_start->info0); - - tx_ppdu_info->rx_status.medium_prot_type = - u32_get_bits(info[0], - HAL_TX_FES_STATUS_START_INFO0_MEDIUM_PROT_TYPE); - break; - } - - case HAL_TX_FES_STATUS_PROT: { - const struct hal_tx_fes_status_prot *tx_fes_status = tlv_data; - u32 start_timestamp; - u32 end_timestamp; - - info[0] = __le32_to_cpu(tx_fes_status->info0); - info[1] = __le32_to_cpu(tx_fes_status->info1); - - start_timestamp = - u32_get_bits(info[0], - HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_15_0); - start_timestamp |= - u32_get_bits(info[0], - HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_31_16) << 15; - end_timestamp = - u32_get_bits(info[1], - HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_15_0); - end_timestamp |= - u32_get_bits(info[1], - HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_31_16) << 15; - tx_ppdu_info->rx_status.rx_duration = end_timestamp - start_timestamp; - - ath12k_dp_mon_tx_gen_prot_frame(tx_ppdu_info); - break; - } - - case HAL_TX_FES_STATUS_START_PPDU: - case HAL_TX_FES_STATUS_START_PROT: { - const struct hal_tx_fes_status_start_prot *tx_fes_stat_start = tlv_data; - u64 ppdu_ts; - - info[0] = __le32_to_cpu(tx_fes_stat_start->info0); - - tx_ppdu_info->rx_status.ppdu_ts = - u32_get_bits(info[0], - HAL_TX_FES_STAT_STRT_INFO0_PROT_TS_LOWER_32); - ppdu_ts = (u32_get_bits(info[1], - HAL_TX_FES_STAT_STRT_INFO1_PROT_TS_UPPER_32)); - tx_ppdu_info->rx_status.ppdu_ts |= ppdu_ts << 32; - break; - } - - case HAL_TX_FES_STATUS_USER_PPDU: { - const struct hal_tx_fes_status_user_ppdu *tx_fes_usr_ppdu = tlv_data; - - info[0] = __le32_to_cpu(tx_fes_usr_ppdu->info0); - - tx_ppdu_info->rx_status.rx_duration = - u32_get_bits(info[0], - HAL_TX_FES_STAT_USR_PPDU_INFO0_DURATION); - break; - } - - case HAL_MACTX_HE_SIG_A_SU: - ath12k_dp_mon_parse_he_sig_su(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_HE_SIG_A_MU_DL: - ath12k_dp_mon_parse_he_sig_mu(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_HE_SIG_B1_MU: - ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_HE_SIG_B2_MU: - ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_HE_SIG_B2_OFDMA: - ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_VHT_SIG_A: - ath12k_dp_mon_parse_vht_sig_a(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_L_SIG_A: - ath12k_dp_mon_parse_l_sig_a(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_MACTX_L_SIG_B: - ath12k_dp_mon_parse_l_sig_b(tlv_data, &tx_ppdu_info->rx_status); - break; - - case HAL_RX_FRAME_BITMAP_ACK: { - const struct hal_rx_frame_bitmap_ack *fbm_ack = tlv_data; - u32 addr_32; - u16 addr_16; - - info[0] = __le32_to_cpu(fbm_ack->info0); - info[1] = __le32_to_cpu(fbm_ack->info1); - - addr_32 = u32_get_bits(info[0], - HAL_RX_FBM_ACK_INFO0_ADDR1_31_0); - addr_16 = u32_get_bits(info[1], - HAL_RX_FBM_ACK_INFO1_ADDR1_47_32); - ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1); - - ath12k_dp_mon_tx_gen_ack_frame(tx_ppdu_info); - break; - } - - case HAL_MACTX_PHY_DESC: { - const struct hal_tx_phy_desc *tx_phy_desc = tlv_data; - - info[0] = __le32_to_cpu(tx_phy_desc->info0); - info[1] = __le32_to_cpu(tx_phy_desc->info1); - info[2] = __le32_to_cpu(tx_phy_desc->info2); - info[3] = __le32_to_cpu(tx_phy_desc->info3); - - tx_ppdu_info->rx_status.beamformed = - u32_get_bits(info[0], - HAL_TX_PHY_DESC_INFO0_BF_TYPE); - tx_ppdu_info->rx_status.preamble_type = - u32_get_bits(info[0], - HAL_TX_PHY_DESC_INFO0_PREAMBLE_11B); - tx_ppdu_info->rx_status.mcs = - u32_get_bits(info[1], - HAL_TX_PHY_DESC_INFO1_MCS); - tx_ppdu_info->rx_status.ltf_size = - u32_get_bits(info[3], - HAL_TX_PHY_DESC_INFO3_LTF_SIZE); - tx_ppdu_info->rx_status.nss = - u32_get_bits(info[2], - HAL_TX_PHY_DESC_INFO2_NSS); - tx_ppdu_info->rx_status.chan_num = - u32_get_bits(info[3], - HAL_TX_PHY_DESC_INFO3_ACTIVE_CHANNEL); - tx_ppdu_info->rx_status.bw = - u32_get_bits(info[0], - HAL_TX_PHY_DESC_INFO0_BANDWIDTH); - break; - } - - case HAL_TX_MPDU_START: { - struct dp_mon_mpdu *mon_mpdu = tx_ppdu_info->tx_mon_mpdu; - - mon_mpdu = kzalloc(sizeof(*mon_mpdu), GFP_ATOMIC); - if (!mon_mpdu) - return DP_MON_TX_STATUS_PPDU_NOT_DONE; - status = DP_MON_TX_MPDU_START; - break; - } - - case HAL_TX_MPDU_END: - list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, - &tx_ppdu_info->dp_tx_mon_mpdu_list); - break; - } - - return status; -} - -enum dp_mon_tx_tlv_status -ath12k_dp_mon_tx_status_get_num_user(u16 tlv_tag, - struct hal_tlv_hdr *tx_tlv, - u8 *num_users) -{ - u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE; - u32 info0; - - switch (tlv_tag) { - case HAL_TX_FES_SETUP: { - struct hal_tx_fes_setup *tx_fes_setup = - (struct hal_tx_fes_setup *)tx_tlv; - - info0 = __le32_to_cpu(tx_fes_setup->info0); - - *num_users = u32_get_bits(info0, HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS); - tlv_status = DP_MON_TX_FES_SETUP; - break; - } - - case HAL_RX_RESPONSE_REQUIRED_INFO: { - /* TODO: need to update *num_users */ - tlv_status = DP_MON_RX_RESPONSE_REQUIRED_INFO; - break; - } - } - - return tlv_status; -} - -static void -ath12k_dp_mon_tx_process_ppdu_info(struct ath12k_pdev_dp *dp_pdev, - struct napi_struct *napi, - struct dp_mon_tx_ppdu_info *tx_ppdu_info) -{ - struct dp_mon_mpdu *tmp, *mon_mpdu; - - list_for_each_entry_safe(mon_mpdu, tmp, - &tx_ppdu_info->dp_tx_mon_mpdu_list, list) { - list_del(&mon_mpdu->list); - - if (mon_mpdu->head) - ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, - &tx_ppdu_info->rx_status, napi); - - kfree(mon_mpdu); - } -} - -enum hal_rx_mon_status -ath12k_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - struct sk_buff *skb, - struct napi_struct *napi, - u32 ppdu_id) -{ - struct ath12k_dp *dp = dp_pdev->dp; - struct ath12k_base *ab = dp->ab; - struct dp_mon_tx_ppdu_info *tx_prot_ppdu_info, *tx_data_ppdu_info; - struct hal_tlv_hdr *tlv; - u8 *ptr = skb->data; - u16 tlv_tag; - u16 tlv_len; - u32 tlv_userid = 0; - u8 num_user; - u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE; - - tx_prot_ppdu_info = ath12k_dp_mon_tx_get_ppdu_info(pmon, ppdu_id, - DP_MON_TX_PROT_PPDU_INFO); - if (!tx_prot_ppdu_info) - return -ENOMEM; - - tlv = (struct hal_tlv_hdr *)ptr; - tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG); - - tlv_status = ath12k_dp_mon_tx_status_get_num_user(tlv_tag, tlv, &num_user); - if (tlv_status == DP_MON_TX_STATUS_PPDU_NOT_DONE || !num_user) - return -EINVAL; - - tx_data_ppdu_info = ath12k_dp_mon_tx_get_ppdu_info(pmon, ppdu_id, - DP_MON_TX_DATA_PPDU_INFO); - if (!tx_data_ppdu_info) - return -ENOMEM; - - do { - tlv = (struct hal_tlv_hdr *)ptr; - tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG); - tlv_len = le32_get_bits(tlv->tl, HAL_TLV_HDR_LEN); - tlv_userid = le32_get_bits(tlv->tl, HAL_TLV_USR_ID); - - tlv_status = ath12k_dp_mon_tx_parse_status_tlv(ab, pmon, - tlv_tag, ptr, - tlv_userid); - ptr += tlv_len; - ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN); - if ((ptr - skb->data) >= DP_TX_MONITOR_BUF_SIZE) - break; - } while (tlv_status != DP_MON_TX_FES_STATUS_END); - - ath12k_dp_mon_tx_process_ppdu_info(dp_pdev, napi, tx_data_ppdu_info); - ath12k_dp_mon_tx_process_ppdu_info(dp_pdev, napi, tx_prot_ppdu_info); - - return tlv_status; -} - static void ath12k_dp_mon_rx_update_peer_rate_table_stats(struct ath12k_rx_peer_stats *rx_stats, struct hal_rx_mon_ppdu_info *ppdu_info, diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index bfea7d4041cb9..1d2ec4072a83c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -85,17 +85,6 @@ int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab, int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, int req_entries); -struct sk_buff *ath12k_dp_mon_tx_alloc_skb(void); -enum dp_mon_tx_tlv_status -ath12k_dp_mon_tx_status_get_num_user(u16 tlv_tag, - struct hal_tlv_hdr *tx_tlv, - u8 *num_users); -enum hal_rx_mon_status -ath12k_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, - struct ath12k_mon_data *pmon, - struct sk_buff *skb, - struct napi_struct *napi, - u32 ppdu_id); void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info); void ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 076fb75a101f1..abdfd3cfd0e48 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -331,6 +331,682 @@ ath12k_wifi7_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, return 0; } +static struct dp_mon_tx_ppdu_info * +ath12k_wifi7_dp_mon_tx_get_ppdu_info(struct ath12k_mon_data *pmon, + unsigned int ppdu_id, + enum dp_mon_tx_ppdu_info_type type) +{ + struct dp_mon_tx_ppdu_info *tx_ppdu_info; + + if (type == DP_MON_TX_PROT_PPDU_INFO) { + tx_ppdu_info = pmon->tx_prot_ppdu_info; + + if (tx_ppdu_info && !tx_ppdu_info->is_used) + return tx_ppdu_info; + kfree(tx_ppdu_info); + } else { + tx_ppdu_info = pmon->tx_data_ppdu_info; + + if (tx_ppdu_info && !tx_ppdu_info->is_used) + return tx_ppdu_info; + kfree(tx_ppdu_info); + } + + /* allocate new tx_ppdu_info */ + tx_ppdu_info = kzalloc(sizeof(*tx_ppdu_info), GFP_ATOMIC); + if (!tx_ppdu_info) + return NULL; + + tx_ppdu_info->is_used = 0; + tx_ppdu_info->ppdu_id = ppdu_id; + + if (type == DP_MON_TX_PROT_PPDU_INFO) + pmon->tx_prot_ppdu_info = tx_ppdu_info; + else + pmon->tx_data_ppdu_info = tx_ppdu_info; + + return tx_ppdu_info; +} + +static struct dp_mon_tx_ppdu_info * +ath12k_wifi7_dp_mon_hal_tx_ppdu_info(struct ath12k_mon_data *pmon, + u16 tlv_tag) +{ + switch (tlv_tag) { + case HAL_TX_FES_SETUP: + case HAL_TX_FLUSH: + case HAL_PCU_PPDU_SETUP_INIT: + case HAL_TX_PEER_ENTRY: + case HAL_TX_QUEUE_EXTENSION: + case HAL_TX_MPDU_START: + case HAL_TX_MSDU_START: + case HAL_TX_DATA: + case HAL_MON_BUF_ADDR: + case HAL_TX_MPDU_END: + case HAL_TX_LAST_MPDU_FETCHED: + case HAL_TX_LAST_MPDU_END: + case HAL_COEX_TX_REQ: + case HAL_TX_RAW_OR_NATIVE_FRAME_SETUP: + case HAL_SCH_CRITICAL_TLV_REFERENCE: + case HAL_TX_FES_SETUP_COMPLETE: + case HAL_TQM_MPDU_GLOBAL_START: + case HAL_SCHEDULER_END: + case HAL_TX_FES_STATUS_USER_PPDU: + break; + case HAL_TX_FES_STATUS_PROT: { + if (!pmon->tx_prot_ppdu_info->is_used) + pmon->tx_prot_ppdu_info->is_used = true; + + return pmon->tx_prot_ppdu_info; + } + } + + if (!pmon->tx_data_ppdu_info->is_used) + pmon->tx_data_ppdu_info->is_used = true; + + return pmon->tx_data_ppdu_info; +} + +#define MAX_MONITOR_HEADER 512 +#define MAX_DUMMY_FRM_BODY 128 + +static struct +sk_buff *ath12k_wifi7_dp_mon_tx_alloc_skb(void) +{ + struct sk_buff *skb; + + skb = dev_alloc_skb(MAX_MONITOR_HEADER + MAX_DUMMY_FRM_BODY); + if (!skb) + return NULL; + + skb_reserve(skb, MAX_MONITOR_HEADER); + + if (!IS_ALIGNED((unsigned long)skb->data, 4)) + skb_pull(skb, PTR_ALIGN(skb->data, 4) - skb->data); + + return skb; +} + +static int +ath12k_wifi7_dp_mon_tx_gen_cts2self_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + struct sk_buff *skb; + struct ieee80211_cts *cts; + + skb = ath12k_wifi7_dp_mon_tx_alloc_skb(); + if (!skb) + return -ENOMEM; + + cts = (struct ieee80211_cts *)skb->data; + memset(cts, 0, MAX_DUMMY_FRM_BODY); + cts->frame_control = + cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); + cts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); + memcpy(cts->ra, tx_ppdu_info->rx_status.addr1, sizeof(cts->ra)); + + skb_put(skb, sizeof(*cts)); + tx_ppdu_info->tx_mon_mpdu->head = skb; + tx_ppdu_info->tx_mon_mpdu->tail = NULL; + list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, + &tx_ppdu_info->dp_tx_mon_mpdu_list); + + return 0; +} + +static int +ath12k_wifi7_dp_mon_tx_gen_rts_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + struct sk_buff *skb; + struct ieee80211_rts *rts; + + skb = ath12k_wifi7_dp_mon_tx_alloc_skb(); + if (!skb) + return -ENOMEM; + + rts = (struct ieee80211_rts *)skb->data; + memset(rts, 0, MAX_DUMMY_FRM_BODY); + rts->frame_control = + cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); + rts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); + memcpy(rts->ra, tx_ppdu_info->rx_status.addr1, sizeof(rts->ra)); + memcpy(rts->ta, tx_ppdu_info->rx_status.addr2, sizeof(rts->ta)); + + skb_put(skb, sizeof(*rts)); + tx_ppdu_info->tx_mon_mpdu->head = skb; + tx_ppdu_info->tx_mon_mpdu->tail = NULL; + list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, + &tx_ppdu_info->dp_tx_mon_mpdu_list); + + return 0; +} + +static int +ath12k_wifi7_dp_mon_tx_gen_3addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + struct sk_buff *skb; + struct ieee80211_qos_hdr *qhdr; + + skb = ath12k_wifi7_dp_mon_tx_alloc_skb(); + if (!skb) + return -ENOMEM; + + qhdr = (struct ieee80211_qos_hdr *)skb->data; + memset(qhdr, 0, MAX_DUMMY_FRM_BODY); + qhdr->frame_control = + cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC); + qhdr->duration_id = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); + memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); + memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN); + memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN); + + skb_put(skb, sizeof(*qhdr)); + tx_ppdu_info->tx_mon_mpdu->head = skb; + tx_ppdu_info->tx_mon_mpdu->tail = NULL; + list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, + &tx_ppdu_info->dp_tx_mon_mpdu_list); + + return 0; +} + +static int +ath12k_wifi7_dp_mon_tx_gen_4addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + struct sk_buff *skb; + struct dp_mon_qosframe_addr4 *qhdr; + + skb = ath12k_wifi7_dp_mon_tx_alloc_skb(); + if (!skb) + return -ENOMEM; + + qhdr = (struct dp_mon_qosframe_addr4 *)skb->data; + memset(qhdr, 0, MAX_DUMMY_FRM_BODY); + qhdr->frame_control = + cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC); + qhdr->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration); + memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); + memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN); + memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN); + memcpy(qhdr->addr4, tx_ppdu_info->rx_status.addr4, ETH_ALEN); + + skb_put(skb, sizeof(*qhdr)); + tx_ppdu_info->tx_mon_mpdu->head = skb; + tx_ppdu_info->tx_mon_mpdu->tail = NULL; + list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, + &tx_ppdu_info->dp_tx_mon_mpdu_list); + + return 0; +} + +static int +ath12k_wifi7_dp_mon_tx_gen_ack_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + struct sk_buff *skb; + struct dp_mon_frame_min_one *fbmhdr; + + skb = ath12k_wifi7_dp_mon_tx_alloc_skb(); + if (!skb) + return -ENOMEM; + + fbmhdr = (struct dp_mon_frame_min_one *)skb->data; + memset(fbmhdr, 0, MAX_DUMMY_FRM_BODY); + fbmhdr->frame_control = + cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_CFACK); + memcpy(fbmhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN); + + /* set duration zero for ack frame */ + fbmhdr->duration = 0; + + skb_put(skb, sizeof(*fbmhdr)); + tx_ppdu_info->tx_mon_mpdu->head = skb; + tx_ppdu_info->tx_mon_mpdu->tail = NULL; + list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, + &tx_ppdu_info->dp_tx_mon_mpdu_list); + + return 0; +} + +static int +ath12k_wifi7_dp_mon_tx_gen_prot_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + int ret = 0; + + switch (tx_ppdu_info->rx_status.medium_prot_type) { + case DP_MON_TX_MEDIUM_RTS_LEGACY: + case DP_MON_TX_MEDIUM_RTS_11AC_STATIC_BW: + case DP_MON_TX_MEDIUM_RTS_11AC_DYNAMIC_BW: + ret = ath12k_wifi7_dp_mon_tx_gen_rts_frame(tx_ppdu_info); + break; + case DP_MON_TX_MEDIUM_CTS2SELF: + ret = ath12k_wifi7_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info); + break; + case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_3ADDR: + ret = ath12k_wifi7_dp_mon_tx_gen_3addr_qos_null_frame(tx_ppdu_info); + break; + case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_4ADDR: + ret = ath12k_wifi7_dp_mon_tx_gen_4addr_qos_null_frame(tx_ppdu_info); + break; + } + + return ret; +} + +static enum dp_mon_tx_tlv_status +ath12k_wifi7_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab, + struct ath12k_mon_data *pmon, + u16 tlv_tag, const void *tlv_data, + u32 userid) +{ + struct dp_mon_tx_ppdu_info *tx_ppdu_info; + enum dp_mon_tx_tlv_status status = DP_MON_TX_STATUS_PPDU_NOT_DONE; + u32 info[7]; + + tx_ppdu_info = ath12k_wifi7_dp_mon_hal_tx_ppdu_info(pmon, tlv_tag); + + switch (tlv_tag) { + case HAL_TX_FES_SETUP: { + const struct hal_tx_fes_setup *tx_fes_setup = tlv_data; + + info[0] = __le32_to_cpu(tx_fes_setup->info0); + tx_ppdu_info->ppdu_id = __le32_to_cpu(tx_fes_setup->schedule_id); + tx_ppdu_info->num_users = + u32_get_bits(info[0], HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS); + status = DP_MON_TX_FES_SETUP; + break; + } + + case HAL_TX_FES_STATUS_END: { + const struct hal_tx_fes_status_end *tx_fes_status_end = tlv_data; + u32 tst_15_0, tst_31_16; + + info[0] = __le32_to_cpu(tx_fes_status_end->info0); + tst_15_0 = + u32_get_bits(info[0], + HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_15_0); + tst_31_16 = + u32_get_bits(info[0], + HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_31_16); + + tx_ppdu_info->rx_status.ppdu_ts = (tst_15_0 | (tst_31_16 << 16)); + status = DP_MON_TX_FES_STATUS_END; + break; + } + + case HAL_RX_RESPONSE_REQUIRED_INFO: { + const struct hal_rx_resp_req_info *rx_resp_req_info = tlv_data; + u32 addr_32; + u16 addr_16; + + info[0] = __le32_to_cpu(rx_resp_req_info->info0); + info[1] = __le32_to_cpu(rx_resp_req_info->info1); + info[2] = __le32_to_cpu(rx_resp_req_info->info2); + info[3] = __le32_to_cpu(rx_resp_req_info->info3); + info[4] = __le32_to_cpu(rx_resp_req_info->info4); + info[5] = __le32_to_cpu(rx_resp_req_info->info5); + + tx_ppdu_info->rx_status.ppdu_id = + u32_get_bits(info[0], HAL_RX_RESP_REQ_INFO0_PPDU_ID); + tx_ppdu_info->rx_status.reception_type = + u32_get_bits(info[0], HAL_RX_RESP_REQ_INFO0_RECEPTION_TYPE); + tx_ppdu_info->rx_status.rx_duration = + u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_DURATION); + tx_ppdu_info->rx_status.mcs = + u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_RATE_MCS); + tx_ppdu_info->rx_status.sgi = + u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_SGI); + tx_ppdu_info->rx_status.is_stbc = + u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_STBC); + tx_ppdu_info->rx_status.ldpc = + u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_LDPC); + tx_ppdu_info->rx_status.is_ampdu = + u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_IS_AMPDU); + tx_ppdu_info->rx_status.num_users = + u32_get_bits(info[2], HAL_RX_RESP_REQ_INFO2_NUM_USER); + + addr_32 = u32_get_bits(info[3], HAL_RX_RESP_REQ_INFO3_ADDR1_31_0); + addr_16 = u32_get_bits(info[3], HAL_RX_RESP_REQ_INFO4_ADDR1_47_32); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1); + + addr_16 = u32_get_bits(info[4], HAL_RX_RESP_REQ_INFO4_ADDR1_15_0); + addr_32 = u32_get_bits(info[5], HAL_RX_RESP_REQ_INFO5_ADDR1_47_16); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr2); + + if (tx_ppdu_info->rx_status.reception_type == 0) + ath12k_wifi7_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info); + status = DP_MON_RX_RESPONSE_REQUIRED_INFO; + break; + } + + case HAL_PCU_PPDU_SETUP_INIT: { + const struct hal_tx_pcu_ppdu_setup_init *ppdu_setup = tlv_data; + u32 addr_32; + u16 addr_16; + + info[0] = __le32_to_cpu(ppdu_setup->info0); + info[1] = __le32_to_cpu(ppdu_setup->info1); + info[2] = __le32_to_cpu(ppdu_setup->info2); + info[3] = __le32_to_cpu(ppdu_setup->info3); + info[4] = __le32_to_cpu(ppdu_setup->info4); + info[5] = __le32_to_cpu(ppdu_setup->info5); + info[6] = __le32_to_cpu(ppdu_setup->info6); + + /* protection frame address 1 */ + addr_32 = u32_get_bits(info[1], + HAL_TX_PPDU_SETUP_INFO1_PROT_FRAME_ADDR1_31_0); + addr_16 = u32_get_bits(info[2], + HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR1_47_32); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1); + + /* protection frame address 2 */ + addr_16 = u32_get_bits(info[2], + HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR2_15_0); + addr_32 = u32_get_bits(info[3], + HAL_TX_PPDU_SETUP_INFO3_PROT_FRAME_ADDR2_47_16); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr2); + + /* protection frame address 3 */ + addr_32 = u32_get_bits(info[4], + HAL_TX_PPDU_SETUP_INFO4_PROT_FRAME_ADDR3_31_0); + addr_16 = u32_get_bits(info[5], + HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR3_47_32); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr3); + + /* protection frame address 4 */ + addr_16 = u32_get_bits(info[5], + HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR4_15_0); + addr_32 = u32_get_bits(info[6], + HAL_TX_PPDU_SETUP_INFO6_PROT_FRAME_ADDR4_47_16); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr4); + + status = u32_get_bits(info[0], + HAL_TX_PPDU_SETUP_INFO0_MEDIUM_PROT_TYPE); + break; + } + + case HAL_TX_QUEUE_EXTENSION: { + const struct hal_tx_queue_exten *tx_q_exten = tlv_data; + + info[0] = __le32_to_cpu(tx_q_exten->info0); + + tx_ppdu_info->rx_status.frame_control = + u32_get_bits(info[0], + HAL_TX_Q_EXT_INFO0_FRAME_CTRL); + tx_ppdu_info->rx_status.fc_valid = true; + break; + } + + case HAL_TX_FES_STATUS_START: { + const struct hal_tx_fes_status_start *tx_fes_start = tlv_data; + + info[0] = __le32_to_cpu(tx_fes_start->info0); + + tx_ppdu_info->rx_status.medium_prot_type = + u32_get_bits(info[0], + HAL_TX_FES_STATUS_START_INFO0_MEDIUM_PROT_TYPE); + break; + } + + case HAL_TX_FES_STATUS_PROT: { + const struct hal_tx_fes_status_prot *tx_fes_status = tlv_data; + u32 start_timestamp; + u32 end_timestamp; + + info[0] = __le32_to_cpu(tx_fes_status->info0); + info[1] = __le32_to_cpu(tx_fes_status->info1); + + start_timestamp = + u32_get_bits(info[0], + HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_15_0); + start_timestamp |= + u32_get_bits(info[0], + HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_31_16) << 15; + end_timestamp = + u32_get_bits(info[1], + HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_15_0); + end_timestamp |= + u32_get_bits(info[1], + HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_31_16) << 15; + tx_ppdu_info->rx_status.rx_duration = end_timestamp - start_timestamp; + + ath12k_wifi7_dp_mon_tx_gen_prot_frame(tx_ppdu_info); + break; + } + + case HAL_TX_FES_STATUS_START_PPDU: + case HAL_TX_FES_STATUS_START_PROT: { + const struct hal_tx_fes_status_start_prot *tx_fes_stat_start = tlv_data; + u64 ppdu_ts; + + info[0] = __le32_to_cpu(tx_fes_stat_start->info0); + + tx_ppdu_info->rx_status.ppdu_ts = + u32_get_bits(info[0], + HAL_TX_FES_STAT_STRT_INFO0_PROT_TS_LOWER_32); + ppdu_ts = (u32_get_bits(info[1], + HAL_TX_FES_STAT_STRT_INFO1_PROT_TS_UPPER_32)); + tx_ppdu_info->rx_status.ppdu_ts |= ppdu_ts << 32; + break; + } + + case HAL_TX_FES_STATUS_USER_PPDU: { + const struct hal_tx_fes_status_user_ppdu *tx_fes_usr_ppdu = tlv_data; + + info[0] = __le32_to_cpu(tx_fes_usr_ppdu->info0); + + tx_ppdu_info->rx_status.rx_duration = + u32_get_bits(info[0], + HAL_TX_FES_STAT_USR_PPDU_INFO0_DURATION); + break; + } + + case HAL_MACTX_HE_SIG_A_SU: + ath12k_dp_mon_parse_he_sig_su(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_HE_SIG_A_MU_DL: + ath12k_dp_mon_parse_he_sig_mu(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_HE_SIG_B1_MU: + ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_HE_SIG_B2_MU: + ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_HE_SIG_B2_OFDMA: + ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_VHT_SIG_A: + ath12k_dp_mon_parse_vht_sig_a(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_L_SIG_A: + ath12k_dp_mon_parse_l_sig_a(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_MACTX_L_SIG_B: + ath12k_dp_mon_parse_l_sig_b(tlv_data, &tx_ppdu_info->rx_status); + break; + + case HAL_RX_FRAME_BITMAP_ACK: { + const struct hal_rx_frame_bitmap_ack *fbm_ack = tlv_data; + u32 addr_32; + u16 addr_16; + + info[0] = __le32_to_cpu(fbm_ack->info0); + info[1] = __le32_to_cpu(fbm_ack->info1); + + addr_32 = u32_get_bits(info[0], + HAL_RX_FBM_ACK_INFO0_ADDR1_31_0); + addr_16 = u32_get_bits(info[1], + HAL_RX_FBM_ACK_INFO1_ADDR1_47_32); + ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1); + + ath12k_wifi7_dp_mon_tx_gen_ack_frame(tx_ppdu_info); + break; + } + + case HAL_MACTX_PHY_DESC: { + const struct hal_tx_phy_desc *tx_phy_desc = tlv_data; + + info[0] = __le32_to_cpu(tx_phy_desc->info0); + info[1] = __le32_to_cpu(tx_phy_desc->info1); + info[2] = __le32_to_cpu(tx_phy_desc->info2); + info[3] = __le32_to_cpu(tx_phy_desc->info3); + + tx_ppdu_info->rx_status.beamformed = + u32_get_bits(info[0], + HAL_TX_PHY_DESC_INFO0_BF_TYPE); + tx_ppdu_info->rx_status.preamble_type = + u32_get_bits(info[0], + HAL_TX_PHY_DESC_INFO0_PREAMBLE_11B); + tx_ppdu_info->rx_status.mcs = + u32_get_bits(info[1], + HAL_TX_PHY_DESC_INFO1_MCS); + tx_ppdu_info->rx_status.ltf_size = + u32_get_bits(info[3], + HAL_TX_PHY_DESC_INFO3_LTF_SIZE); + tx_ppdu_info->rx_status.nss = + u32_get_bits(info[2], + HAL_TX_PHY_DESC_INFO2_NSS); + tx_ppdu_info->rx_status.chan_num = + u32_get_bits(info[3], + HAL_TX_PHY_DESC_INFO3_ACTIVE_CHANNEL); + tx_ppdu_info->rx_status.bw = + u32_get_bits(info[0], + HAL_TX_PHY_DESC_INFO0_BANDWIDTH); + break; + } + + case HAL_TX_MPDU_START: { + struct dp_mon_mpdu *mon_mpdu = tx_ppdu_info->tx_mon_mpdu; + + mon_mpdu = kzalloc(sizeof(*mon_mpdu), GFP_ATOMIC); + if (!mon_mpdu) + return DP_MON_TX_STATUS_PPDU_NOT_DONE; + status = DP_MON_TX_MPDU_START; + break; + } + + case HAL_TX_MPDU_END: + list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list, + &tx_ppdu_info->dp_tx_mon_mpdu_list); + break; + } + + return status; +} + +static enum dp_mon_tx_tlv_status +ath12k_wifi7_dp_mon_tx_status_get_num_user(u16 tlv_tag, + struct hal_tlv_hdr *tx_tlv, + u8 *num_users) +{ + u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE; + u32 info0; + + switch (tlv_tag) { + case HAL_TX_FES_SETUP: { + struct hal_tx_fes_setup *tx_fes_setup = + (struct hal_tx_fes_setup *)tx_tlv; + + info0 = __le32_to_cpu(tx_fes_setup->info0); + + *num_users = u32_get_bits(info0, HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS); + tlv_status = DP_MON_TX_FES_SETUP; + break; + } + + case HAL_RX_RESPONSE_REQUIRED_INFO: { + /* TODO: need to update *num_users */ + tlv_status = DP_MON_RX_RESPONSE_REQUIRED_INFO; + break; + } + } + + return tlv_status; +} + +static void +ath12k_wifi7_dp_mon_tx_process_ppdu_info(struct ath12k_pdev_dp *dp_pdev, + struct napi_struct *napi, + struct dp_mon_tx_ppdu_info *tx_ppdu_info) +{ + struct dp_mon_mpdu *tmp, *mon_mpdu; + + list_for_each_entry_safe(mon_mpdu, tmp, + &tx_ppdu_info->dp_tx_mon_mpdu_list, list) { + list_del(&mon_mpdu->list); + + if (mon_mpdu->head) + ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, + &tx_ppdu_info->rx_status, napi); + + kfree(mon_mpdu); + } +} + +enum hal_rx_mon_status +ath12k_wifi7_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + struct sk_buff *skb, + struct napi_struct *napi, + u32 ppdu_id) +{ + struct ath12k_dp *dp = dp_pdev->dp; + struct ath12k_base *ab = dp->ab; + struct dp_mon_tx_ppdu_info *tx_prot_ppdu_info, *tx_data_ppdu_info; + struct hal_tlv_hdr *tlv; + u8 *ptr = skb->data; + u16 tlv_tag; + u16 tlv_len; + u32 tlv_userid = 0; + u8 num_user; + u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE; + + tx_prot_ppdu_info = + ath12k_wifi7_dp_mon_tx_get_ppdu_info(pmon, ppdu_id, + DP_MON_TX_PROT_PPDU_INFO); + if (!tx_prot_ppdu_info) + return -ENOMEM; + + tlv = (struct hal_tlv_hdr *)ptr; + tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG); + + tlv_status = ath12k_wifi7_dp_mon_tx_status_get_num_user(tlv_tag, tlv, + &num_user); + if (tlv_status == DP_MON_TX_STATUS_PPDU_NOT_DONE || !num_user) + return -EINVAL; + + tx_data_ppdu_info = + ath12k_wifi7_dp_mon_tx_get_ppdu_info(pmon, ppdu_id, + DP_MON_TX_DATA_PPDU_INFO); + if (!tx_data_ppdu_info) + return -ENOMEM; + + do { + tlv = (struct hal_tlv_hdr *)ptr; + tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG); + tlv_len = le32_get_bits(tlv->tl, HAL_TLV_HDR_LEN); + tlv_userid = le32_get_bits(tlv->tl, HAL_TLV_USR_ID); + + tlv_status = ath12k_wifi7_dp_mon_tx_parse_status_tlv(ab, pmon, + tlv_tag, ptr, + tlv_userid); + ptr += tlv_len; + ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN); + if ((ptr - skb->data) >= DP_TX_MONITOR_BUF_SIZE) + break; + } while (tlv_status != DP_MON_TX_FES_STATUS_END); + + ath12k_wifi7_dp_mon_tx_process_ppdu_info(dp_pdev, napi, tx_data_ppdu_info); + ath12k_wifi7_dp_mon_tx_process_ppdu_info(dp_pdev, napi, tx_prot_ppdu_info); + + return tlv_status; +} + static u32 ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, void *ring_entry, struct sk_buff **head_msdu, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h index 3cf82864c41cd..148d1e0b70fe8 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.h @@ -14,4 +14,10 @@ enum dp_monitor_mode; int ath12k_wifi7_dp_mon_process_ring(struct ath12k_dp *dp, int mac_id, struct napi_struct *napi, int budget, enum dp_monitor_mode monitor_mode); +enum hal_rx_mon_status +ath12k_wifi7_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, + struct ath12k_mon_data *pmon, + struct sk_buff *skb, + struct napi_struct *napi, + u32 ppdu_id); #endif From 90c3840a0a50561dcee44d3c30ce3ba0575525d9 Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:07 +0530 Subject: [PATCH 104/140] wifi: ath12k: Move HT/VHT SIG processing to Wi-Fi 7 module Separate Wi-Fi 7-specific monitor parsing from ath12k common code to improve modularity and keep Wi-Fi 7 logic within the Wi-Fi 7 module. Move following HT/VHT SIG parsing functions to wifi7/dp_mon.c and rename the functions with the ath12k_wifi7 prefix: - ath12k_dp_mon_parse_vht_sig_a() - ath12k_dp_mon_parse_ht_sig() Export helper functions required by the ath12k_wifi7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-7-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 56 ----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 4 -- .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 62 ++++++++++++++++++- 3 files changed, 59 insertions(+), 63 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 06f1045ee5f3c..fab7950ee78cc 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -81,62 +81,6 @@ ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats * } EXPORT_SYMBOL(ath12k_dp_mon_rx_populate_mu_user_info); -void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 nsts, info0, info1; - u8 gi_setting; - - info0 = __le32_to_cpu(vht_sig->info0); - info1 = __le32_to_cpu(vht_sig->info1); - - ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING); - ppdu_info->mcs = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_MCS); - gi_setting = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_GI_SETTING); - switch (gi_setting) { - case HAL_RX_VHT_SIG_A_NORMAL_GI: - ppdu_info->gi = HAL_RX_GI_0_8_US; - break; - case HAL_RX_VHT_SIG_A_SHORT_GI: - case HAL_RX_VHT_SIG_A_SHORT_GI_AMBIGUITY: - ppdu_info->gi = HAL_RX_GI_0_4_US; - break; - } - - ppdu_info->is_stbc = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_STBC); - nsts = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_NSTS); - if (ppdu_info->is_stbc && nsts > 0) - nsts = ((nsts + 1) >> 1) - 1; - - ppdu_info->nss = u32_get_bits(nsts, VHT_SIG_SU_NSS_MASK) + 1; - ppdu_info->bw = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_BW); - ppdu_info->beamformed = u32_get_bits(info1, - HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED); - ppdu_info->vht_flag_values5 = u32_get_bits(info0, - HAL_RX_VHT_SIG_A_INFO_INFO0_GROUP_ID); - ppdu_info->vht_flag_values3[0] = (((ppdu_info->mcs) << 4) | - ppdu_info->nss); - ppdu_info->vht_flag_values2 = ppdu_info->bw; - ppdu_info->vht_flag_values4 = - u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING); -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_vht_sig_a); - -void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 info0 = __le32_to_cpu(ht_sig->info0); - u32 info1 = __le32_to_cpu(ht_sig->info1); - - ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HT_SIG_INFO_INFO0_MCS); - ppdu_info->bw = u32_get_bits(info0, HAL_RX_HT_SIG_INFO_INFO0_BW); - ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_STBC); - ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING); - ppdu_info->gi = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_GI); - ppdu_info->nss = (ppdu_info->mcs >> 3) + 1; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_ht_sig); - void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, struct hal_rx_mon_ppdu_info *ppdu_info) { diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 1d2ec4072a83c..86d0c18d8c07c 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -113,8 +113,6 @@ int ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct dp_mon_packet_info *packet_info); -void ath12k_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, - struct hal_rx_mon_ppdu_info *ppdu_info); void ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, const void *tlv_data); @@ -135,8 +133,6 @@ ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *of void ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu, struct hal_rx_mon_ppdu_info *ppdu_info); -void ath12k_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, - struct hal_rx_mon_ppdu_info *ppdu_info); void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a, struct hal_rx_mon_ppdu_info *ppdu_info); void diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index abdfd3cfd0e48..0c83df4be9daf 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -20,6 +20,62 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } +static void +ath12k_wifi7_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 nsts, info0, info1; + u8 gi_setting; + + info0 = __le32_to_cpu(vht_sig->info0); + info1 = __le32_to_cpu(vht_sig->info1); + + ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING); + ppdu_info->mcs = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_MCS); + gi_setting = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_GI_SETTING); + switch (gi_setting) { + case HAL_RX_VHT_SIG_A_NORMAL_GI: + ppdu_info->gi = HAL_RX_GI_0_8_US; + break; + case HAL_RX_VHT_SIG_A_SHORT_GI: + case HAL_RX_VHT_SIG_A_SHORT_GI_AMBIGUITY: + ppdu_info->gi = HAL_RX_GI_0_4_US; + break; + } + + ppdu_info->is_stbc = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_STBC); + nsts = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_NSTS); + if (ppdu_info->is_stbc && nsts > 0) + nsts = ((nsts + 1) >> 1) - 1; + + ppdu_info->nss = u32_get_bits(nsts, VHT_SIG_SU_NSS_MASK); + ppdu_info->bw = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_BW); + ppdu_info->beamformed = u32_get_bits(info1, + HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED); + ppdu_info->vht_flag_values5 = u32_get_bits(info0, + HAL_RX_VHT_SIG_A_INFO_INFO0_GROUP_ID); + ppdu_info->vht_flag_values3[0] = (((ppdu_info->mcs) << 4) | + ppdu_info->nss); + ppdu_info->vht_flag_values2 = ppdu_info->bw; + ppdu_info->vht_flag_values4 = + u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING); +} + +static void +ath12k_wifi7_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 info0 = __le32_to_cpu(ht_sig->info0); + u32 info1 = __le32_to_cpu(ht_sig->info1); + + ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HT_SIG_INFO_INFO0_MCS); + ppdu_info->bw = u32_get_bits(info0, HAL_RX_HT_SIG_INFO_INFO0_BW); + ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_STBC); + ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING); + ppdu_info->gi = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_GI); + ppdu_info->nss = (ppdu_info->mcs >> 3); +} + static enum hal_rx_mon_status ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, @@ -158,7 +214,7 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, break; } case HAL_PHYRX_HT_SIG: - ath12k_dp_mon_parse_ht_sig(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_ht_sig(tlv_data, ppdu_info); break; case HAL_PHYRX_L_SIG_B: @@ -170,7 +226,7 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, break; case HAL_PHYRX_VHT_SIG_A: - ath12k_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info); break; case HAL_PHYRX_HE_SIG_A_SU: @@ -819,7 +875,7 @@ ath12k_wifi7_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab, break; case HAL_MACTX_VHT_SIG_A: - ath12k_dp_mon_parse_vht_sig_a(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_vht_sig_a(tlv_data, &tx_ppdu_info->rx_status); break; case HAL_MACTX_L_SIG_A: From 141f437d770009919517ff16527d8655f87576f2 Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:08 +0530 Subject: [PATCH 105/140] wifi: ath12k: Move HE SIG processing to Wi-Fi 7 module Separate Wi-Fi 7-specific monitor code from ath12k common code to improve modularity. Move following HE SIG processing functions to the wifi7/dp_mon.c and rename the relocated functions with the ath12k_wifi7 prefix: - ath12k_dp_mon_parse_he_sig_b2_ofdma() - ath12k_dp_mon_parse_he_sig_b2_mu() - ath12k_dp_mon_parse_he_sig_b1_mu() - ath12k_dp_mon_parse_he_sig_mu() - ath12k_dp_mon_parse_he_sig_su() Export helper functions required by the ath12k_wifi7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-8-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 365 ----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 14 - .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 380 +++++++++++++++++- 3 files changed, 370 insertions(+), 389 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index fab7950ee78cc..2b5f96f2a4b3b 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -153,371 +153,6 @@ void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, } EXPORT_SYMBOL(ath12k_dp_mon_parse_l_sig_a); -void -ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *ofdma, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 info0, value; - - info0 = __le32_to_cpu(ofdma->info0); - - ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_DCM_KNOWN | HE_CODING_KNOWN; - - /* HE-data2 */ - ppdu_info->he_data2 |= HE_TXBF_KNOWN; - - ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS); - value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_DCM); - value = value << HE_DCM_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING); - ppdu_info->ldpc = value; - value = value << HE_CODING_SHIFT; - ppdu_info->he_data3 |= value; - - /* HE-data4 */ - value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_ID); - value = value << HE_STA_ID_SHIFT; - ppdu_info->he_data4 |= value; - - ppdu_info->nss = - u32_get_bits(info0, - HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS) + 1; - ppdu_info->beamformed = u32_get_bits(info0, - HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF); -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_b2_ofdma); - -void -ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 info0, value; - - info0 = __le32_to_cpu(he_sig_b2_mu->info0); - - ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_CODING_KNOWN; - - ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS); - value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING); - ppdu_info->ldpc = value; - value = value << HE_CODING_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_ID); - value = value << HE_STA_ID_SHIFT; - ppdu_info->he_data4 |= value; - - ppdu_info->nss = - u32_get_bits(info0, - HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS) + 1; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_b2_mu); - -void -ath12k_dp_mon_parse_he_sig_b1_mu(const struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 info0 = __le32_to_cpu(he_sig_b1_mu->info0); - u16 ru_tones; - - ru_tones = u32_get_bits(info0, - HAL_RX_HE_SIG_B1_MU_INFO_INFO0_RU_ALLOCATION); - ppdu_info->ru_alloc = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones); - ppdu_info->he_RU[0] = ru_tones; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_b1_mu); - -void -ath12k_dp_mon_parse_he_sig_mu(const struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 info0, info1, value; - u16 he_gi = 0, he_ltf = 0; - - info0 = __le32_to_cpu(he_sig_a_mu_dl->info0); - info1 = __le32_to_cpu(he_sig_a_mu_dl->info1); - - ppdu_info->he_mu_flags = 1; - - ppdu_info->he_data1 = HE_MU_FORMAT_TYPE; - ppdu_info->he_data1 |= - HE_BSS_COLOR_KNOWN | - HE_DL_UL_KNOWN | - HE_LDPC_EXTRA_SYMBOL_KNOWN | - HE_STBC_KNOWN | - HE_DATA_BW_RU_KNOWN | - HE_DOPPLER_KNOWN; - - ppdu_info->he_data2 = - HE_GI_KNOWN | - HE_LTF_SYMBOLS_KNOWN | - HE_PRE_FEC_PADDING_KNOWN | - HE_PE_DISAMBIGUITY_KNOWN | - HE_TXOP_KNOWN | - HE_MIDABLE_PERIODICITY_KNOWN; - - /* data3 */ - ppdu_info->he_data3 = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_BSS_COLOR); - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_UL_FLAG); - value = value << HE_DL_UL_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_LDPC_EXTRA); - value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC); - value = value << HE_STBC_SHIFT; - ppdu_info->he_data3 |= value; - - /* data4 */ - ppdu_info->he_data4 = u32_get_bits(info0, - HAL_RX_HE_SIG_A_MU_DL_INFO0_SPATIAL_REUSE); - ppdu_info->he_data4 = value; - - /* data5 */ - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW); - ppdu_info->he_data5 = value; - ppdu_info->bw = value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_CP_LTF_SIZE); - switch (value) { - case 0: - he_gi = HE_GI_0_8; - he_ltf = HE_LTF_4_X; - break; - case 1: - he_gi = HE_GI_0_8; - he_ltf = HE_LTF_2_X; - break; - case 2: - he_gi = HE_GI_1_6; - he_ltf = HE_LTF_2_X; - break; - case 3: - he_gi = HE_GI_3_2; - he_ltf = HE_LTF_4_X; - break; - } - - ppdu_info->gi = he_gi; - value = he_gi << HE_GI_SHIFT; - ppdu_info->he_data5 |= value; - - value = he_ltf << HE_LTF_SIZE_SHIFT; - ppdu_info->he_data5 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_NUM_LTF_SYMB); - value = (value << HE_LTF_SYM_SHIFT); - ppdu_info->he_data5 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_FACTOR); - value = value << HE_PRE_FEC_PAD_SHIFT; - ppdu_info->he_data5 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_PE_DISAM); - value = value << HE_PE_DISAMBIGUITY_SHIFT; - ppdu_info->he_data5 |= value; - - /*data6*/ - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DOPPLER_INDICATION); - value = value << HE_DOPPLER_SHIFT; - ppdu_info->he_data6 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_TXOP_DURATION); - value = value << HE_TXOP_SHIFT; - ppdu_info->he_data6 |= value; - - /* HE-MU Flags */ - /* HE-MU-flags1 */ - ppdu_info->he_flags1 = - HE_SIG_B_MCS_KNOWN | - HE_SIG_B_DCM_KNOWN | - HE_SIG_B_COMPRESSION_FLAG_1_KNOWN | - HE_SIG_B_SYM_NUM_KNOWN | - HE_RU_0_KNOWN; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_MCS_OF_SIGB); - ppdu_info->he_flags1 |= value; - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DCM_OF_SIGB); - value = value << HE_DCM_FLAG_1_SHIFT; - ppdu_info->he_flags1 |= value; - - /* HE-MU-flags2 */ - ppdu_info->he_flags2 = HE_BW_KNOWN; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW); - ppdu_info->he_flags2 |= value; - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_COMP_MODE_SIGB); - value = value << HE_SIG_B_COMPRESSION_FLAG_2_SHIFT; - ppdu_info->he_flags2 |= value; - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_NUM_SIGB_SYMB); - value = value - 1; - value = value << HE_NUM_SIG_B_SYMBOLS_SHIFT; - ppdu_info->he_flags2 |= value; - - ppdu_info->is_stbc = info1 & - HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_mu); - -void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 info0, info1, value; - u32 dcm; - u8 he_dcm = 0, he_stbc = 0; - u16 he_gi = 0, he_ltf = 0; - - ppdu_info->he_flags = 1; - - info0 = __le32_to_cpu(he_sig_a->info0); - info1 = __le32_to_cpu(he_sig_a->info1); - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_FORMAT_IND); - if (value == 0) - ppdu_info->he_data1 = HE_TRIG_FORMAT_TYPE; - else - ppdu_info->he_data1 = HE_SU_FORMAT_TYPE; - - ppdu_info->he_data1 |= - HE_BSS_COLOR_KNOWN | - HE_BEAM_CHANGE_KNOWN | - HE_DL_UL_KNOWN | - HE_MCS_KNOWN | - HE_DCM_KNOWN | - HE_CODING_KNOWN | - HE_LDPC_EXTRA_SYMBOL_KNOWN | - HE_STBC_KNOWN | - HE_DATA_BW_RU_KNOWN | - HE_DOPPLER_KNOWN; - - ppdu_info->he_data2 |= - HE_GI_KNOWN | - HE_TXBF_KNOWN | - HE_PE_DISAMBIGUITY_KNOWN | - HE_TXOP_KNOWN | - HE_LTF_SYMBOLS_KNOWN | - HE_PRE_FEC_PADDING_KNOWN | - HE_MIDABLE_PERIODICITY_KNOWN; - - ppdu_info->he_data3 = u32_get_bits(info0, - HAL_RX_HE_SIG_A_SU_INFO_INFO0_BSS_COLOR); - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_BEAM_CHANGE); - value = value << HE_BEAM_CHANGE_SHIFT; - ppdu_info->he_data3 |= value; - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DL_UL_FLAG); - value = value << HE_DL_UL_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS); - ppdu_info->mcs = value; - value = value << HE_TRANSMIT_MCS_SHIFT; - ppdu_info->he_data3 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM); - he_dcm = value; - value = value << HE_DCM_SHIFT; - ppdu_info->he_data3 |= value; - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING); - value = value << HE_CODING_SHIFT; - ppdu_info->he_data3 |= value; - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_LDPC_EXTRA); - value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT; - ppdu_info->he_data3 |= value; - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC); - he_stbc = value; - value = value << HE_STBC_SHIFT; - ppdu_info->he_data3 |= value; - - /* data4 */ - ppdu_info->he_data4 = u32_get_bits(info0, - HAL_RX_HE_SIG_A_SU_INFO_INFO0_SPATIAL_REUSE); - - /* data5 */ - value = u32_get_bits(info0, - HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW); - ppdu_info->he_data5 = value; - ppdu_info->bw = value; - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE); - switch (value) { - case 0: - he_gi = HE_GI_0_8; - he_ltf = HE_LTF_1_X; - break; - case 1: - he_gi = HE_GI_0_8; - he_ltf = HE_LTF_2_X; - break; - case 2: - he_gi = HE_GI_1_6; - he_ltf = HE_LTF_2_X; - break; - case 3: - if (he_dcm && he_stbc) { - he_gi = HE_GI_0_8; - he_ltf = HE_LTF_4_X; - } else { - he_gi = HE_GI_3_2; - he_ltf = HE_LTF_4_X; - } - break; - } - ppdu_info->gi = he_gi; - value = he_gi << HE_GI_SHIFT; - ppdu_info->he_data5 |= value; - value = he_ltf << HE_LTF_SIZE_SHIFT; - ppdu_info->ltf_size = he_ltf; - ppdu_info->he_data5 |= value; - - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); - value = (value << HE_LTF_SYM_SHIFT); - ppdu_info->he_data5 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_FACTOR); - value = value << HE_PRE_FEC_PAD_SHIFT; - ppdu_info->he_data5 |= value; - - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF); - value = value << HE_TXBF_SHIFT; - ppdu_info->he_data5 |= value; - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_PE_DISAM); - value = value << HE_PE_DISAMBIGUITY_SHIFT; - ppdu_info->he_data5 |= value; - - /* data6 */ - value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); - value++; - ppdu_info->he_data6 = value; - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_DOPPLER_IND); - value = value << HE_DOPPLER_SHIFT; - ppdu_info->he_data6 |= value; - value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXOP_DURATION); - value = value << HE_TXOP_SHIFT; - ppdu_info->he_data6 |= value; - - ppdu_info->mcs = - u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS); - ppdu_info->bw = - u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW); - ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING); - ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC); - ppdu_info->beamformed = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF); - dcm = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM); - ppdu_info->nss = u32_get_bits(info0, - HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS) + 1; - ppdu_info->dcm = dcm; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_he_sig_su); - static void ath12k_dp_mon_hal_rx_parse_u_sig_cmn(const struct hal_mon_usig_cmn *cmn, struct hal_rx_mon_ppdu_info *ppdu_info) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 86d0c18d8c07c..90811a2f75a73 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -128,20 +128,6 @@ void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, struct hal_rx_mon_ppdu_info *ppdu_info); void -ath12k_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *ofdma, - struct hal_rx_mon_ppdu_info *ppdu_info); -void -ath12k_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu, - struct hal_rx_mon_ppdu_info *ppdu_info); -void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a, - struct hal_rx_mon_ppdu_info *ppdu_info); -void -ath12k_dp_mon_parse_he_sig_b1_mu(const struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu, - struct hal_rx_mon_ppdu_info *ppdu_info); -void -ath12k_dp_mon_parse_he_sig_mu(const struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl, - struct hal_rx_mon_ppdu_info *ppdu_info); -void ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info, u16 user_id, struct hal_rx_mon_ppdu_info *ppdu_info); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 0c83df4be9daf..f6d41ded57150 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -76,6 +76,362 @@ ath12k_wifi7_dp_mon_parse_ht_sig(const struct hal_rx_ht_sig_info *ht_sig, ppdu_info->nss = (ppdu_info->mcs >> 3); } +static void +ath12k_wifi7_dp_mon_parse_he_sig_b2_ofdma(const struct hal_rx_he_sig_b2_ofdma_info *ofdma, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 info0, value; + + info0 = __le32_to_cpu(ofdma->info0); + + ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_DCM_KNOWN | HE_CODING_KNOWN; + + /* HE-data2 */ + ppdu_info->he_data2 |= HE_TXBF_KNOWN; + + ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS); + value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_DCM); + value = value << HE_DCM_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING); + ppdu_info->ldpc = value; + value = value << HE_CODING_SHIFT; + ppdu_info->he_data3 |= value; + + /* HE-data4 */ + value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_ID); + value = value << HE_STA_ID_SHIFT; + ppdu_info->he_data4 |= value; + + ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS); + ppdu_info->beamformed = u32_get_bits(info0, + HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF); +} + +static void +ath12k_wifi7_dp_mon_parse_he_sig_b2_mu(const struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 info0, value; + + info0 = __le32_to_cpu(he_sig_b2_mu->info0); + + ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_CODING_KNOWN; + + ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS); + value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING); + ppdu_info->ldpc = value; + value = value << HE_CODING_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_ID); + value = value << HE_STA_ID_SHIFT; + ppdu_info->he_data4 |= value; + + ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS); +} + +static void +ath12k_wifi7_dp_mon_parse_he_sig_b1_mu(const struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 info0 = __le32_to_cpu(he_sig_b1_mu->info0); + u16 ru_tones; + + ru_tones = u32_get_bits(info0, + HAL_RX_HE_SIG_B1_MU_INFO_INFO0_RU_ALLOCATION); + ppdu_info->ru_alloc = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones); + ppdu_info->he_RU[0] = ru_tones; +} + +static void +ath12k_wifi7_dp_mon_parse_he_sig_mu(const struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 info0, info1, value; + u16 he_gi = 0, he_ltf = 0; + + info0 = __le32_to_cpu(he_sig_a_mu_dl->info0); + info1 = __le32_to_cpu(he_sig_a_mu_dl->info1); + + ppdu_info->he_mu_flags = 1; + + ppdu_info->he_data1 = HE_MU_FORMAT_TYPE; + ppdu_info->he_data1 |= + HE_BSS_COLOR_KNOWN | + HE_DL_UL_KNOWN | + HE_LDPC_EXTRA_SYMBOL_KNOWN | + HE_STBC_KNOWN | + HE_DATA_BW_RU_KNOWN | + HE_DOPPLER_KNOWN; + + ppdu_info->he_data2 = + HE_GI_KNOWN | + HE_LTF_SYMBOLS_KNOWN | + HE_PRE_FEC_PADDING_KNOWN | + HE_PE_DISAMBIGUITY_KNOWN | + HE_TXOP_KNOWN | + HE_MIDABLE_PERIODICITY_KNOWN; + + /* data3 */ + ppdu_info->he_data3 = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_BSS_COLOR); + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_UL_FLAG); + value = value << HE_DL_UL_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_LDPC_EXTRA); + value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC); + value = value << HE_STBC_SHIFT; + ppdu_info->he_data3 |= value; + + /* data4 */ + ppdu_info->he_data4 = u32_get_bits(info0, + HAL_RX_HE_SIG_A_MU_DL_INFO0_SPATIAL_REUSE); + ppdu_info->he_data4 = value; + + /* data5 */ + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW); + ppdu_info->he_data5 = value; + ppdu_info->bw = value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_CP_LTF_SIZE); + switch (value) { + case 0: + he_gi = HE_GI_0_8; + he_ltf = HE_LTF_4_X; + break; + case 1: + he_gi = HE_GI_0_8; + he_ltf = HE_LTF_2_X; + break; + case 2: + he_gi = HE_GI_1_6; + he_ltf = HE_LTF_2_X; + break; + case 3: + he_gi = HE_GI_3_2; + he_ltf = HE_LTF_4_X; + break; + } + + ppdu_info->gi = he_gi; + value = he_gi << HE_GI_SHIFT; + ppdu_info->he_data5 |= value; + + value = he_ltf << HE_LTF_SIZE_SHIFT; + ppdu_info->he_data5 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_NUM_LTF_SYMB); + value = (value << HE_LTF_SYM_SHIFT); + ppdu_info->he_data5 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_FACTOR); + value = value << HE_PRE_FEC_PAD_SHIFT; + ppdu_info->he_data5 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_PE_DISAM); + value = value << HE_PE_DISAMBIGUITY_SHIFT; + ppdu_info->he_data5 |= value; + + /*data6*/ + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DOPPLER_INDICATION); + value = value << HE_DOPPLER_SHIFT; + ppdu_info->he_data6 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_TXOP_DURATION); + value = value << HE_TXOP_SHIFT; + ppdu_info->he_data6 |= value; + + /* HE-MU Flags */ + /* HE-MU-flags1 */ + ppdu_info->he_flags1 = + HE_SIG_B_MCS_KNOWN | + HE_SIG_B_DCM_KNOWN | + HE_SIG_B_COMPRESSION_FLAG_1_KNOWN | + HE_SIG_B_SYM_NUM_KNOWN | + HE_RU_0_KNOWN; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_MCS_OF_SIGB); + ppdu_info->he_flags1 |= value; + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DCM_OF_SIGB); + value = value << HE_DCM_FLAG_1_SHIFT; + ppdu_info->he_flags1 |= value; + + /* HE-MU-flags2 */ + ppdu_info->he_flags2 = HE_BW_KNOWN; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW); + ppdu_info->he_flags2 |= value; + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_COMP_MODE_SIGB); + value = value << HE_SIG_B_COMPRESSION_FLAG_2_SHIFT; + ppdu_info->he_flags2 |= value; + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_NUM_SIGB_SYMB); + value = value - 1; + value = value << HE_NUM_SIG_B_SYMBOLS_SHIFT; + ppdu_info->he_flags2 |= value; + + ppdu_info->is_stbc = info1 & + HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC; +} + +static void +ath12k_wifi7_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig_a, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 info0, info1, value; + u32 dcm; + u8 he_dcm = 0, he_stbc = 0; + u16 he_gi = 0, he_ltf = 0; + + ppdu_info->he_flags = 1; + + info0 = __le32_to_cpu(he_sig_a->info0); + info1 = __le32_to_cpu(he_sig_a->info1); + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_FORMAT_IND); + if (value == 0) + ppdu_info->he_data1 = HE_TRIG_FORMAT_TYPE; + else + ppdu_info->he_data1 = HE_SU_FORMAT_TYPE; + + ppdu_info->he_data1 |= + HE_BSS_COLOR_KNOWN | + HE_BEAM_CHANGE_KNOWN | + HE_DL_UL_KNOWN | + HE_MCS_KNOWN | + HE_DCM_KNOWN | + HE_CODING_KNOWN | + HE_LDPC_EXTRA_SYMBOL_KNOWN | + HE_STBC_KNOWN | + HE_DATA_BW_RU_KNOWN | + HE_DOPPLER_KNOWN; + + ppdu_info->he_data2 |= + HE_GI_KNOWN | + HE_TXBF_KNOWN | + HE_PE_DISAMBIGUITY_KNOWN | + HE_TXOP_KNOWN | + HE_LTF_SYMBOLS_KNOWN | + HE_PRE_FEC_PADDING_KNOWN | + HE_MIDABLE_PERIODICITY_KNOWN; + + ppdu_info->he_data3 = u32_get_bits(info0, + HAL_RX_HE_SIG_A_SU_INFO_INFO0_BSS_COLOR); + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_BEAM_CHANGE); + value = value << HE_BEAM_CHANGE_SHIFT; + ppdu_info->he_data3 |= value; + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DL_UL_FLAG); + value = value << HE_DL_UL_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS); + ppdu_info->mcs = value; + value = value << HE_TRANSMIT_MCS_SHIFT; + ppdu_info->he_data3 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM); + he_dcm = value; + value = value << HE_DCM_SHIFT; + ppdu_info->he_data3 |= value; + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING); + value = value << HE_CODING_SHIFT; + ppdu_info->he_data3 |= value; + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_LDPC_EXTRA); + value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT; + ppdu_info->he_data3 |= value; + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC); + he_stbc = value; + value = value << HE_STBC_SHIFT; + ppdu_info->he_data3 |= value; + + /* data4 */ + ppdu_info->he_data4 = u32_get_bits(info0, + HAL_RX_HE_SIG_A_SU_INFO_INFO0_SPATIAL_REUSE); + + /* data5 */ + value = u32_get_bits(info0, + HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW); + ppdu_info->he_data5 = value; + ppdu_info->bw = value; + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE); + switch (value) { + case 0: + he_gi = HE_GI_0_8; + he_ltf = HE_LTF_1_X; + break; + case 1: + he_gi = HE_GI_0_8; + he_ltf = HE_LTF_2_X; + break; + case 2: + he_gi = HE_GI_1_6; + he_ltf = HE_LTF_2_X; + break; + case 3: + if (he_dcm && he_stbc) { + he_gi = HE_GI_0_8; + he_ltf = HE_LTF_4_X; + } else { + he_gi = HE_GI_3_2; + he_ltf = HE_LTF_4_X; + } + break; + } + ppdu_info->gi = he_gi; + value = he_gi << HE_GI_SHIFT; + ppdu_info->he_data5 |= value; + value = he_ltf << HE_LTF_SIZE_SHIFT; + ppdu_info->ltf_size = he_ltf; + ppdu_info->he_data5 |= value; + + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); + value = (value << HE_LTF_SYM_SHIFT); + ppdu_info->he_data5 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_FACTOR); + value = value << HE_PRE_FEC_PAD_SHIFT; + ppdu_info->he_data5 |= value; + + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF); + value = value << HE_TXBF_SHIFT; + ppdu_info->he_data5 |= value; + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_PE_DISAM); + value = value << HE_PE_DISAMBIGUITY_SHIFT; + ppdu_info->he_data5 |= value; + + /* data6 */ + value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); + value++; + ppdu_info->he_data6 = value; + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_DOPPLER_IND); + value = value << HE_DOPPLER_SHIFT; + ppdu_info->he_data6 |= value; + value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXOP_DURATION); + value = value << HE_TXOP_SHIFT; + ppdu_info->he_data6 |= value; + + ppdu_info->mcs = + u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS); + ppdu_info->bw = + u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW); + ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING); + ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC); + ppdu_info->beamformed = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF); + dcm = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM); + ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS); + ppdu_info->dcm = dcm; +} + static enum hal_rx_mon_status ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, @@ -230,23 +586,23 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, break; case HAL_PHYRX_HE_SIG_A_SU: - ath12k_dp_mon_parse_he_sig_su(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_he_sig_su(tlv_data, ppdu_info); break; case HAL_PHYRX_HE_SIG_A_MU_DL: - ath12k_dp_mon_parse_he_sig_mu(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_he_sig_mu(tlv_data, ppdu_info); break; case HAL_PHYRX_HE_SIG_B1_MU: - ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_he_sig_b1_mu(tlv_data, ppdu_info); break; case HAL_PHYRX_HE_SIG_B2_MU: - ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_he_sig_b2_mu(tlv_data, ppdu_info); break; case HAL_PHYRX_HE_SIG_B2_OFDMA: - ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_he_sig_b2_ofdma(tlv_data, ppdu_info); break; case HAL_PHYRX_RSSI_LEGACY: { @@ -855,23 +1211,27 @@ ath12k_wifi7_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab, } case HAL_MACTX_HE_SIG_A_SU: - ath12k_dp_mon_parse_he_sig_su(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_he_sig_su(tlv_data, + &tx_ppdu_info->rx_status); break; case HAL_MACTX_HE_SIG_A_MU_DL: - ath12k_dp_mon_parse_he_sig_mu(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_he_sig_mu(tlv_data, &tx_ppdu_info->rx_status); break; case HAL_MACTX_HE_SIG_B1_MU: - ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_he_sig_b1_mu(tlv_data, + &tx_ppdu_info->rx_status); break; case HAL_MACTX_HE_SIG_B2_MU: - ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_he_sig_b2_mu(tlv_data, + &tx_ppdu_info->rx_status); break; case HAL_MACTX_HE_SIG_B2_OFDMA: - ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_he_sig_b2_ofdma(tlv_data, + &tx_ppdu_info->rx_status); break; case HAL_MACTX_VHT_SIG_A: From 1ce5061ca5556a987fcc477a70f4cd644203d008 Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:09 +0530 Subject: [PATCH 106/140] wifi: ath12k: Move EHT SIG processing to Wi-Fi 7 module Split Wi-Fi 7 specific EHT SIG parsing out of ath12k common code into the Wi-Fi 7 module to improve modularity. Move the following EHT SIG processing functions to wifi7/dp_mon.c and add the ath12k_wifi7 prefix to each relocated function. - ath12k_dp_mon_hal_aggr_tlv() - ath12k_dp_mon_hal_rx_is_frame_type_ndp() - ath12k_dp_mon_hal_rx_is_non_ofdma() - ath12k_dp_mon_hal_rx_is_ofdma() - ath12k_dp_mon_hal_rx_parse_eht_sig_ndp() - ath12k_dp_mon_hal_rx_parse_usig_overflow() - ath12k_dp_mon_hal_rx_parse_non_ofdma_users() - ath12k_dp_mon_hal_rx_parse_eht_mumimo_user() - ath12k_dp_mon_hal_rx_parse_eht_non_mumimo_user() - ath12k_dp_mon_hal_rx_is_mu_mimo_user() - ath12k_dp_mon_hal_rx_parse_eht_sig_non_ofdma() - ath12k_dp_mon_hal_rx_parse_ru_allocation() - ath12k_dp_mon_hal_rx_parse_eht_sig_ofdma() - ath12k_dp_mon_parse_eht_sig_hdr() Export helper functions needed by the ath12k_wifi7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-9-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 389 ------------------ drivers/net/wireless/ath/ath12k/dp_mon.h | 12 +- .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 386 ++++++++++++++++- 3 files changed, 390 insertions(+), 397 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index 2b5f96f2a4b3b..f28e3c2cc1cb8 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -11,12 +11,6 @@ #include "dp_tx.h" #include "peer.h" -#define ATH12K_LE32_DEC_ENC(value, dec_bits, enc_bits) \ - u32_encode_bits(le32_get_bits(value, dec_bits), enc_bits) - -#define ATH12K_LE64_DEC_ENC(value, dec_bits, enc_bits) \ - u32_encode_bits(le64_get_bits(value, dec_bits), enc_bits) - void ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, struct hal_rx_user_status *rx_user_status) @@ -346,389 +340,6 @@ ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, } EXPORT_SYMBOL(ath12k_dp_mon_hal_rx_parse_u_sig_hdr); -void -ath12k_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info, - u16 tlv_len, const void *tlv_data) -{ - if (tlv_len <= HAL_RX_MON_MAX_AGGR_SIZE - ppdu_info->tlv_aggr.cur_len) { - memcpy(ppdu_info->tlv_aggr.buf + ppdu_info->tlv_aggr.cur_len, - tlv_data, tlv_len); - ppdu_info->tlv_aggr.cur_len += tlv_len; - } -} -EXPORT_SYMBOL(ath12k_dp_mon_hal_aggr_tlv); - -static inline bool -ath12k_dp_mon_hal_rx_is_frame_type_ndp(const struct hal_rx_u_sig_info *usig_info) -{ - if (usig_info->ppdu_type_comp_mode == 1 && - usig_info->eht_sig_mcs == 0 && - usig_info->num_eht_sig_sym == 0) - return true; - - return false; -} - -static inline bool -ath12k_dp_mon_hal_rx_is_non_ofdma(const struct hal_rx_u_sig_info *usig_info) -{ - u32 ppdu_type_comp_mode = usig_info->ppdu_type_comp_mode; - u32 ul_dl = usig_info->ul_dl; - - if ((ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_MU_MIMO && ul_dl == 0) || - (ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_MU_OFDMA && ul_dl == 0) || - (ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_MU_MIMO && ul_dl == 1)) - return true; - - return false; -} - -static inline bool -ath12k_dp_mon_hal_rx_is_ofdma(const struct hal_rx_u_sig_info *usig_info) -{ - if (usig_info->ppdu_type_comp_mode == 0 && usig_info->ul_dl == 0) - return true; - - return false; -} - -static void -ath12k_dp_mon_hal_rx_parse_eht_sig_ndp(const struct hal_eht_sig_ndp_cmn_eb *eht_sig_ndp, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; - u32 known, data; - - known = __le32_to_cpu(eht->known); - known |= IEEE80211_RADIOTAP_EHT_KNOWN_SPATIAL_REUSE | - IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF | - IEEE80211_RADIOTAP_EHT_KNOWN_NSS_S | - IEEE80211_RADIOTAP_EHT_KNOWN_BEAMFORMED_S | - IEEE80211_RADIOTAP_EHT_KNOWN_DISREGARD_S | - IEEE80211_RADIOTAP_EHT_KNOWN_CRC1 | - IEEE80211_RADIOTAP_EHT_KNOWN_TAIL1; - eht->known = cpu_to_le32(known); - - data = __le32_to_cpu(eht->data[0]); - data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, - HAL_RX_EHT_SIG_NDP_CMN_INFO0_SPATIAL_REUSE, - IEEE80211_RADIOTAP_EHT_DATA0_SPATIAL_REUSE); - /* GI and LTF size are separately indicated in radiotap header - * and hence will be parsed from other TLV - */ - data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, - HAL_RX_EHT_SIG_NDP_CMN_INFO0_NUM_LTF_SYM, - IEEE80211_RADIOTAP_EHT_DATA0_EHT_LTF); - - data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, - HAL_RX_EHT_SIG_NDP_CMN_INFO0_CRC, - IEEE80211_RADIOTAP_EHT_DATA0_CRC1_O); - - data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, - HAL_RX_EHT_SIG_NDP_CMN_INFO0_DISREGARD, - IEEE80211_RADIOTAP_EHT_DATA0_DISREGARD_S); - eht->data[0] = cpu_to_le32(data); - - data = __le32_to_cpu(eht->data[7]); - data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, - HAL_RX_EHT_SIG_NDP_CMN_INFO0_NSS, - IEEE80211_RADIOTAP_EHT_DATA7_NSS_S); - - data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, - HAL_RX_EHT_SIG_NDP_CMN_INFO0_BEAMFORMED, - IEEE80211_RADIOTAP_EHT_DATA7_BEAMFORMED_S); - eht->data[7] = cpu_to_le32(data); -} - -static void -ath12k_dp_mon_hal_rx_parse_usig_overflow(const struct hal_eht_sig_usig_overflow *ovflow, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; - u32 known, data; - - known = __le32_to_cpu(eht->known); - known |= IEEE80211_RADIOTAP_EHT_KNOWN_SPATIAL_REUSE | - IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF | - IEEE80211_RADIOTAP_EHT_KNOWN_LDPC_EXTRA_SYM_OM | - IEEE80211_RADIOTAP_EHT_KNOWN_PRE_PADD_FACOR_OM | - IEEE80211_RADIOTAP_EHT_KNOWN_PE_DISAMBIGUITY_OM | - IEEE80211_RADIOTAP_EHT_KNOWN_DISREGARD_O; - eht->known = cpu_to_le32(known); - - data = __le32_to_cpu(eht->data[0]); - data |= ATH12K_LE32_DEC_ENC(ovflow->info0, - HAL_RX_EHT_SIG_OVERFLOW_INFO0_SPATIAL_REUSE, - IEEE80211_RADIOTAP_EHT_DATA0_SPATIAL_REUSE); - - /* GI and LTF size are separately indicated in radiotap header - * and hence will be parsed from other TLV - */ - data |= ATH12K_LE32_DEC_ENC(ovflow->info0, - HAL_RX_EHT_SIG_OVERFLOW_INFO0_NUM_LTF_SYM, - IEEE80211_RADIOTAP_EHT_DATA0_EHT_LTF); - - data |= ATH12K_LE32_DEC_ENC(ovflow->info0, - HAL_RX_EHT_SIG_OVERFLOW_INFO0_LDPC_EXTA_SYM, - IEEE80211_RADIOTAP_EHT_DATA0_LDPC_EXTRA_SYM_OM); - - data |= ATH12K_LE32_DEC_ENC(ovflow->info0, - HAL_RX_EHT_SIG_OVERFLOW_INFO0_PRE_FEC_PAD_FACTOR, - IEEE80211_RADIOTAP_EHT_DATA0_PRE_PADD_FACOR_OM); - - data |= ATH12K_LE32_DEC_ENC(ovflow->info0, - HAL_RX_EHT_SIG_OVERFLOW_INFO0_DISAMBIGUITY, - IEEE80211_RADIOTAP_EHT_DATA0_PE_DISAMBIGUITY_OM); - - data |= ATH12K_LE32_DEC_ENC(ovflow->info0, - HAL_RX_EHT_SIG_OVERFLOW_INFO0_DISREGARD, - IEEE80211_RADIOTAP_EHT_DATA0_DISREGARD_O); - eht->data[0] = cpu_to_le32(data); -} - -static void -ath12k_dp_mon_hal_rx_parse_non_ofdma_users(const struct hal_eht_sig_non_ofdma_cmn_eb *eb, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; - u32 known, data; - - known = __le32_to_cpu(eht->known); - known |= IEEE80211_RADIOTAP_EHT_KNOWN_NR_NON_OFDMA_USERS_M; - eht->known = cpu_to_le32(known); - - data = __le32_to_cpu(eht->data[7]); - data |= ATH12K_LE32_DEC_ENC(eb->info0, - HAL_RX_EHT_SIG_NON_OFDMA_INFO0_NUM_USERS, - IEEE80211_RADIOTAP_EHT_DATA7_NUM_OF_NON_OFDMA_USERS); - eht->data[7] = cpu_to_le32(data); -} - -static void -ath12k_dp_mon_hal_rx_parse_eht_mumimo_user(const struct hal_eht_sig_mu_mimo *user, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_eht_info *eht_info = &ppdu_info->eht_info; - u32 user_idx; - - if (eht_info->num_user_info >= ARRAY_SIZE(eht_info->user_info)) - return; - - user_idx = eht_info->num_user_info++; - - eht_info->user_info[user_idx] |= - IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN | - IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN | - IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN | - IEEE80211_RADIOTAP_EHT_USER_INFO_SPATIAL_CONFIG_KNOWN_M | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_STA_ID, - IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_CODING, - IEEE80211_RADIOTAP_EHT_USER_INFO_CODING) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_MCS, - IEEE80211_RADIOTAP_EHT_USER_INFO_MCS) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_SPATIAL_CODING, - IEEE80211_RADIOTAP_EHT_USER_INFO_SPATIAL_CONFIG_M); - - ppdu_info->mcs = le32_get_bits(user->info0, - HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_MCS); -} - -static void -ath12k_dp_mon_hal_rx_parse_eht_non_mumimo_user(const struct hal_eht_sig_non_mu_mimo *user, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_eht_info *eht_info = &ppdu_info->eht_info; - u32 user_idx; - - if (eht_info->num_user_info >= ARRAY_SIZE(eht_info->user_info)) - return; - - user_idx = eht_info->num_user_info++; - - eht_info->user_info[user_idx] |= - IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN | - IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN | - IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN | - IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_KNOWN_O | - IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_KNOWN_O | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_STA_ID, - IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_CODING, - IEEE80211_RADIOTAP_EHT_USER_INFO_CODING) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_MCS, - IEEE80211_RADIOTAP_EHT_USER_INFO_MCS) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_NSS, - IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_O) | - ATH12K_LE32_DEC_ENC(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_BEAMFORMED, - IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_O); - - ppdu_info->mcs = le32_get_bits(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_MCS); - - ppdu_info->nss = le32_get_bits(user->info0, - HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_NSS) + 1; -} - -static inline bool -ath12k_dp_mon_hal_rx_is_mu_mimo_user(const struct hal_rx_u_sig_info *usig_info) -{ - if (usig_info->ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_SU && - usig_info->ul_dl == 1) - return true; - - return false; -} - -static void -ath12k_dp_mon_hal_rx_parse_eht_sig_non_ofdma(const void *tlv, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - const struct hal_eht_sig_non_ofdma_cmn_eb *eb = tlv; - - ath12k_dp_mon_hal_rx_parse_usig_overflow(tlv, ppdu_info); - ath12k_dp_mon_hal_rx_parse_non_ofdma_users(eb, ppdu_info); - - if (ath12k_dp_mon_hal_rx_is_mu_mimo_user(&ppdu_info->u_sig_info)) - ath12k_dp_mon_hal_rx_parse_eht_mumimo_user(&eb->user_field.mu_mimo, - ppdu_info); - else - ath12k_dp_mon_hal_rx_parse_eht_non_mumimo_user(&eb->user_field.n_mu_mimo, - ppdu_info); -} - -static void -ath12k_dp_mon_hal_rx_parse_ru_allocation(const struct hal_eht_sig_ofdma_cmn_eb *eb, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - const struct hal_eht_sig_ofdma_cmn_eb1 *ofdma_cmn_eb1 = &eb->eb1; - const struct hal_eht_sig_ofdma_cmn_eb2 *ofdma_cmn_eb2 = &eb->eb2; - struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; - enum ieee80211_radiotap_eht_data ru_123, ru_124, ru_125, ru_126; - enum ieee80211_radiotap_eht_data ru_121, ru_122, ru_112, ru_111; - u32 data; - - ru_123 = IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_1_2_3; - ru_124 = IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_4; - ru_125 = IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_5; - ru_126 = IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_1_2_6; - ru_121 = IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_1; - ru_122 = IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_2; - ru_112 = IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_1_1_2; - ru_111 = IEEE80211_RADIOTAP_EHT_DATA1_RU_ALLOC_CC_1_1_1; - - switch (ppdu_info->u_sig_info.bw) { - case HAL_EHT_BW_320_2: - case HAL_EHT_BW_320_1: - data = __le32_to_cpu(eht->data[4]); - /* CC1 2::3 */ - data |= IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_1_2_3_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, - HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_3, - ru_123); - eht->data[4] = cpu_to_le32(data); - - data = __le32_to_cpu(eht->data[5]); - /* CC1 2::4 */ - data |= IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_4_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, - HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_4, - ru_124); - - /* CC1 2::5 */ - data |= IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_5_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, - HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_5, - ru_125); - eht->data[5] = cpu_to_le32(data); - - data = __le32_to_cpu(eht->data[6]); - /* CC1 2::6 */ - data |= IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_1_2_6_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, - HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_6, - ru_126); - eht->data[6] = cpu_to_le32(data); - - fallthrough; - case HAL_EHT_BW_160: - data = __le32_to_cpu(eht->data[3]); - /* CC1 2::1 */ - data |= IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_1_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, - HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_1, - ru_121); - /* CC1 2::2 */ - data |= IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_2_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, - HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_2, - ru_122); - eht->data[3] = cpu_to_le32(data); - - fallthrough; - case HAL_EHT_BW_80: - data = __le32_to_cpu(eht->data[2]); - /* CC1 1::2 */ - data |= IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_1_1_2_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb1->info0, - HAL_RX_EHT_SIG_OFDMA_EB1_RU_ALLOC_1_2, - ru_112); - eht->data[2] = cpu_to_le32(data); - - fallthrough; - case HAL_EHT_BW_40: - fallthrough; - case HAL_EHT_BW_20: - data = __le32_to_cpu(eht->data[1]); - /* CC1 1::1 */ - data |= IEEE80211_RADIOTAP_EHT_DATA1_RU_ALLOC_CC_1_1_1_KNOWN | - ATH12K_LE64_DEC_ENC(ofdma_cmn_eb1->info0, - HAL_RX_EHT_SIG_OFDMA_EB1_RU_ALLOC_1_1, - ru_111); - eht->data[1] = cpu_to_le32(data); - break; - default: - break; - } -} - -static void -ath12k_dp_mon_hal_rx_parse_eht_sig_ofdma(const void *tlv, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - const struct hal_eht_sig_ofdma_cmn_eb *ofdma = tlv; - - ath12k_dp_mon_hal_rx_parse_usig_overflow(tlv, ppdu_info); - ath12k_dp_mon_hal_rx_parse_ru_allocation(ofdma, ppdu_info); - - ath12k_dp_mon_hal_rx_parse_eht_non_mumimo_user(&ofdma->user_field.n_mu_mimo, - ppdu_info); -} - -void -ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, - const void *tlv_data) -{ - ppdu_info->is_eht = true; - - if (ath12k_dp_mon_hal_rx_is_frame_type_ndp(&ppdu_info->u_sig_info)) - ath12k_dp_mon_hal_rx_parse_eht_sig_ndp(tlv_data, ppdu_info); - else if (ath12k_dp_mon_hal_rx_is_non_ofdma(&ppdu_info->u_sig_info)) - ath12k_dp_mon_hal_rx_parse_eht_sig_non_ofdma(tlv_data, ppdu_info); - else if (ath12k_dp_mon_hal_rx_is_ofdma(&ppdu_info->u_sig_info)) - ath12k_dp_mon_hal_rx_parse_eht_sig_ofdma(tlv_data, ppdu_info); -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_eht_sig_hdr); - static inline enum ath12k_eht_ru_size hal_rx_mon_hal_ru_size_to_ath12k_ru_size(u32 hal_ru_size) { diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 90811a2f75a73..d2bee88f561f4 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -14,6 +14,12 @@ #define ATH12K_MON_RX_DOT11_OFFSET 5 #define ATH12K_MON_RX_PKT_OFFSET 8 +#define ATH12K_LE32_DEC_ENC(value, dec_bits, enc_bits) \ + u32_encode_bits(le32_get_bits(value, dec_bits), enc_bits) + +#define ATH12K_LE64_DEC_ENC(value, dec_bits, enc_bits) \ + u32_encode_bits(le64_get_bits(value, dec_bits), enc_bits) + enum dp_monitor_mode { ATH12K_DP_TX_MONITOR_MODE, ATH12K_DP_RX_MONITOR_MODE @@ -114,9 +120,6 @@ ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct dp_mon_packet_info *packet_info); void -ath12k_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, - const void *tlv_data); -void ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, struct hal_rx_user_status *rx_user_status); void @@ -137,7 +140,4 @@ ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, void ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, struct hal_rx_mon_ppdu_info *ppdu_info); -void -ath12k_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info, - u16 tlv_len, const void *tlv_data); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index f6d41ded57150..b924180007c53 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -13,6 +13,17 @@ #include "../dp_tx.h" #include "../peer.h" +static void +ath12k_wifi7_dp_mon_hal_aggr_tlv(struct hal_rx_mon_ppdu_info *ppdu_info, + u16 tlv_len, const void *tlv_data) +{ + if (tlv_len <= HAL_RX_MON_MAX_AGGR_SIZE - ppdu_info->tlv_aggr.cur_len) { + memcpy(ppdu_info->tlv_aggr.buf + ppdu_info->tlv_aggr.cur_len, + tlv_data, tlv_len); + ppdu_info->tlv_aggr.cur_len += tlv_len; + } +} + static void ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) { @@ -432,6 +443,376 @@ ath12k_wifi7_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *he_sig ppdu_info->dcm = dcm; } +static inline bool +ath12k_wifi7_dp_mon_hal_rx_is_non_ofdma(const struct hal_rx_u_sig_info *usig_info) +{ + u32 ppdu_type_comp_mode = usig_info->ppdu_type_comp_mode; + u32 ul_dl = usig_info->ul_dl; + + if ((ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_MU_MIMO && ul_dl == 0) || + (ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_MU_OFDMA && ul_dl == 0) || + (ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_MU_MIMO && ul_dl == 1)) + return true; + + return false; +} + +static inline bool +ath12k_wifi7_dp_mon_hal_rx_is_ofdma(const struct hal_rx_u_sig_info *usig_info) +{ + if (usig_info->ppdu_type_comp_mode == 0 && usig_info->ul_dl == 0) + return true; + + return false; +} + +static inline bool +ath12k_wifi7_dp_mon_hal_rx_is_frame_type_ndp(const struct hal_rx_u_sig_info *usig_info) +{ + if (usig_info->ppdu_type_comp_mode == 1 && + usig_info->eht_sig_mcs == 0 && + usig_info->num_eht_sig_sym == 0) + return true; + + return false; +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_ndp(const struct hal_eht_sig_ndp_cmn_eb *eht_sig_ndp, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; + u32 known, data; + + known = __le32_to_cpu(eht->known); + known |= IEEE80211_RADIOTAP_EHT_KNOWN_SPATIAL_REUSE | + IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF | + IEEE80211_RADIOTAP_EHT_KNOWN_NSS_S | + IEEE80211_RADIOTAP_EHT_KNOWN_BEAMFORMED_S | + IEEE80211_RADIOTAP_EHT_KNOWN_DISREGARD_S | + IEEE80211_RADIOTAP_EHT_KNOWN_CRC1 | + IEEE80211_RADIOTAP_EHT_KNOWN_TAIL1; + eht->known = cpu_to_le32(known); + + data = __le32_to_cpu(eht->data[0]); + data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, + HAL_RX_EHT_SIG_NDP_CMN_INFO0_SPATIAL_REUSE, + IEEE80211_RADIOTAP_EHT_DATA0_SPATIAL_REUSE); + /* GI and LTF size are separately indicated in radiotap header + * and hence will be parsed from other TLV + */ + data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, + HAL_RX_EHT_SIG_NDP_CMN_INFO0_NUM_LTF_SYM, + IEEE80211_RADIOTAP_EHT_DATA0_EHT_LTF); + + data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, + HAL_RX_EHT_SIG_NDP_CMN_INFO0_CRC, + IEEE80211_RADIOTAP_EHT_DATA0_CRC1_O); + + data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, + HAL_RX_EHT_SIG_NDP_CMN_INFO0_DISREGARD, + IEEE80211_RADIOTAP_EHT_DATA0_DISREGARD_S); + eht->data[0] = cpu_to_le32(data); + + data = __le32_to_cpu(eht->data[7]); + data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, + HAL_RX_EHT_SIG_NDP_CMN_INFO0_NSS, + IEEE80211_RADIOTAP_EHT_DATA7_NSS_S); + + data |= ATH12K_LE32_DEC_ENC(eht_sig_ndp->info0, + HAL_RX_EHT_SIG_NDP_CMN_INFO0_BEAMFORMED, + IEEE80211_RADIOTAP_EHT_DATA7_BEAMFORMED_S); + eht->data[7] = cpu_to_le32(data); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_usig_overflow(const struct hal_eht_sig_usig_overflow *ovflow, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; + u32 known, data; + + known = __le32_to_cpu(eht->known); + known |= IEEE80211_RADIOTAP_EHT_KNOWN_SPATIAL_REUSE | + IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF | + IEEE80211_RADIOTAP_EHT_KNOWN_LDPC_EXTRA_SYM_OM | + IEEE80211_RADIOTAP_EHT_KNOWN_PRE_PADD_FACOR_OM | + IEEE80211_RADIOTAP_EHT_KNOWN_PE_DISAMBIGUITY_OM | + IEEE80211_RADIOTAP_EHT_KNOWN_DISREGARD_O; + eht->known = cpu_to_le32(known); + + data = __le32_to_cpu(eht->data[0]); + data |= ATH12K_LE32_DEC_ENC(ovflow->info0, + HAL_RX_EHT_SIG_OVERFLOW_INFO0_SPATIAL_REUSE, + IEEE80211_RADIOTAP_EHT_DATA0_SPATIAL_REUSE); + + /* GI and LTF size are separately indicated in radiotap header + * and hence will be parsed from other TLV + */ + data |= ATH12K_LE32_DEC_ENC(ovflow->info0, + HAL_RX_EHT_SIG_OVERFLOW_INFO0_NUM_LTF_SYM, + IEEE80211_RADIOTAP_EHT_DATA0_EHT_LTF); + + data |= ATH12K_LE32_DEC_ENC(ovflow->info0, + HAL_RX_EHT_SIG_OVERFLOW_INFO0_LDPC_EXTA_SYM, + IEEE80211_RADIOTAP_EHT_DATA0_LDPC_EXTRA_SYM_OM); + + data |= ATH12K_LE32_DEC_ENC(ovflow->info0, + HAL_RX_EHT_SIG_OVERFLOW_INFO0_PRE_FEC_PAD_FACTOR, + IEEE80211_RADIOTAP_EHT_DATA0_PRE_PADD_FACOR_OM); + + data |= ATH12K_LE32_DEC_ENC(ovflow->info0, + HAL_RX_EHT_SIG_OVERFLOW_INFO0_DISAMBIGUITY, + IEEE80211_RADIOTAP_EHT_DATA0_PE_DISAMBIGUITY_OM); + + data |= ATH12K_LE32_DEC_ENC(ovflow->info0, + HAL_RX_EHT_SIG_OVERFLOW_INFO0_DISREGARD, + IEEE80211_RADIOTAP_EHT_DATA0_DISREGARD_O); + eht->data[0] = cpu_to_le32(data); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_non_ofdma_users(const struct hal_eht_sig_non_ofdma_cmn_eb *eb, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; + u32 known, data; + + known = __le32_to_cpu(eht->known); + known |= IEEE80211_RADIOTAP_EHT_KNOWN_NR_NON_OFDMA_USERS_M; + eht->known = cpu_to_le32(known); + + data = __le32_to_cpu(eht->data[7]); + data |= ATH12K_LE32_DEC_ENC(eb->info0, + HAL_RX_EHT_SIG_NON_OFDMA_INFO0_NUM_USERS, + IEEE80211_RADIOTAP_EHT_DATA7_NUM_OF_NON_OFDMA_USERS); + eht->data[7] = cpu_to_le32(data); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_eht_mumimo_user(const struct hal_eht_sig_mu_mimo *user, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct hal_rx_eht_info *eht_info = &ppdu_info->eht_info; + u32 user_idx; + + if (eht_info->num_user_info >= ARRAY_SIZE(eht_info->user_info)) + return; + + user_idx = eht_info->num_user_info++; + + eht_info->user_info[user_idx] |= + IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_SPATIAL_CONFIG_KNOWN_M | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_STA_ID, + IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_CODING, + IEEE80211_RADIOTAP_EHT_USER_INFO_CODING) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_MCS, + IEEE80211_RADIOTAP_EHT_USER_INFO_MCS) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_SPATIAL_CODING, + IEEE80211_RADIOTAP_EHT_USER_INFO_SPATIAL_CONFIG_M); + + ppdu_info->mcs = le32_get_bits(user->info0, + HAL_RX_EHT_SIG_MUMIMO_USER_INFO0_MCS); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_eht_non_mumimo_user(const struct hal_eht_sig_non_mu_mimo *user, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct hal_rx_eht_info *eht_info = &ppdu_info->eht_info; + u32 user_idx; + + if (eht_info->num_user_info >= ARRAY_SIZE(eht_info->user_info)) + return; + + user_idx = eht_info->num_user_info++; + + eht_info->user_info[user_idx] |= + IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN | + IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_KNOWN_O | + IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_KNOWN_O | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_STA_ID, + IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_CODING, + IEEE80211_RADIOTAP_EHT_USER_INFO_CODING) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_MCS, + IEEE80211_RADIOTAP_EHT_USER_INFO_MCS) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_NSS, + IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_O) | + ATH12K_LE32_DEC_ENC(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_BEAMFORMED, + IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_O); + + ppdu_info->mcs = le32_get_bits(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_MCS); + + ppdu_info->nss = le32_get_bits(user->info0, + HAL_RX_EHT_SIG_NON_MUMIMO_USER_INFO0_NSS) + 1; +} + +static inline bool +ath12k_wifi7_dp_mon_hal_rx_is_mu_mimo_user(const struct hal_rx_u_sig_info *usig_info) +{ + if (usig_info->ppdu_type_comp_mode == HAL_RX_RECEPTION_TYPE_SU && + usig_info->ul_dl == 1) + return true; + + return false; +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_non_ofdma(const void *tlv, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + const struct hal_eht_sig_non_ofdma_cmn_eb *eb = tlv; + + ath12k_wifi7_dp_mon_hal_rx_parse_usig_overflow(tlv, ppdu_info); + ath12k_wifi7_dp_mon_hal_rx_parse_non_ofdma_users(eb, ppdu_info); + + if (ath12k_wifi7_dp_mon_hal_rx_is_mu_mimo_user(&ppdu_info->u_sig_info)) + ath12k_wifi7_dp_mon_hal_rx_parse_eht_mumimo_user(&eb->user_field.mu_mimo, + ppdu_info); + else + ath12k_wifi7_dp_mon_hal_rx_parse_eht_non_mumimo_user(&eb->user_field.n_mu_mimo, + ppdu_info); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_ru_allocation(const struct hal_eht_sig_ofdma_cmn_eb *eb, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + const struct hal_eht_sig_ofdma_cmn_eb1 *ofdma_cmn_eb1 = &eb->eb1; + const struct hal_eht_sig_ofdma_cmn_eb2 *ofdma_cmn_eb2 = &eb->eb2; + struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; + enum ieee80211_radiotap_eht_data ru_123, ru_124, ru_125, ru_126; + enum ieee80211_radiotap_eht_data ru_121, ru_122, ru_112, ru_111; + u32 data; + + ru_123 = IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_1_2_3; + ru_124 = IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_4; + ru_125 = IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_5; + ru_126 = IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_1_2_6; + ru_121 = IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_1; + ru_122 = IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_2; + ru_112 = IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_1_1_2; + ru_111 = IEEE80211_RADIOTAP_EHT_DATA1_RU_ALLOC_CC_1_1_1; + + switch (ppdu_info->u_sig_info.bw) { + case HAL_EHT_BW_320_2: + case HAL_EHT_BW_320_1: + data = __le32_to_cpu(eht->data[4]); + /* CC1 2::3 */ + data |= IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_1_2_3_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, + HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_3, + ru_123); + eht->data[4] = cpu_to_le32(data); + + data = __le32_to_cpu(eht->data[5]); + /* CC1 2::4 */ + data |= IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_4_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, + HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_4, + ru_124); + + /* CC1 2::5 */ + data |= IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_5_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, + HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_5, + ru_125); + eht->data[5] = cpu_to_le32(data); + + data = __le32_to_cpu(eht->data[6]); + /* CC1 2::6 */ + data |= IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_1_2_6_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, + HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_6, + ru_126); + eht->data[6] = cpu_to_le32(data); + + fallthrough; + case HAL_EHT_BW_160: + data = __le32_to_cpu(eht->data[3]); + /* CC1 2::1 */ + data |= IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_1_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, + HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_1, + ru_121); + /* CC1 2::2 */ + data |= IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_2_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb2->info0, + HAL_RX_EHT_SIG_OFDMA_EB2_RU_ALLOC_2_2, + ru_122); + eht->data[3] = cpu_to_le32(data); + + fallthrough; + case HAL_EHT_BW_80: + data = __le32_to_cpu(eht->data[2]); + /* CC1 1::2 */ + data |= IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_1_1_2_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb1->info0, + HAL_RX_EHT_SIG_OFDMA_EB1_RU_ALLOC_1_2, + ru_112); + eht->data[2] = cpu_to_le32(data); + + fallthrough; + case HAL_EHT_BW_40: + fallthrough; + case HAL_EHT_BW_20: + data = __le32_to_cpu(eht->data[1]); + /* CC1 1::1 */ + data |= IEEE80211_RADIOTAP_EHT_DATA1_RU_ALLOC_CC_1_1_1_KNOWN | + ATH12K_LE64_DEC_ENC(ofdma_cmn_eb1->info0, + HAL_RX_EHT_SIG_OFDMA_EB1_RU_ALLOC_1_1, + ru_111); + eht->data[1] = cpu_to_le32(data); + break; + default: + break; + } +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_ofdma(const void *tlv, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + const struct hal_eht_sig_ofdma_cmn_eb *ofdma = tlv; + + ath12k_wifi7_dp_mon_hal_rx_parse_usig_overflow(tlv, ppdu_info); + ath12k_wifi7_dp_mon_hal_rx_parse_ru_allocation(ofdma, ppdu_info); + + ath12k_wifi7_dp_mon_hal_rx_parse_eht_non_mumimo_user(&ofdma->user_field.n_mu_mimo, + ppdu_info); +} + +static void +ath12k_wifi7_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, + const void *tlv_data) +{ + ppdu_info->is_eht = true; + + if (ath12k_wifi7_dp_mon_hal_rx_is_frame_type_ndp(&ppdu_info->u_sig_info)) + ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_ndp(tlv_data, ppdu_info); + else if (ath12k_wifi7_dp_mon_hal_rx_is_non_ofdma(&ppdu_info->u_sig_info)) + ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_non_ofdma(tlv_data, ppdu_info); + else if (ath12k_wifi7_dp_mon_hal_rx_is_ofdma(&ppdu_info->u_sig_info)) + ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_ofdma(tlv_data, ppdu_info); +} + static enum hal_rx_mon_status ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, @@ -447,7 +828,8 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, userid = le64_get_bits(tlv->tl, HAL_TLV_64_USR_ID); if (ppdu_info->tlv_aggr.in_progress && ppdu_info->tlv_aggr.tlv_tag != tlv_tag) { - ath12k_dp_mon_parse_eht_sig_hdr(ppdu_info, ppdu_info->tlv_aggr.buf); + ath12k_wifi7_dp_mon_parse_eht_sig_hdr(ppdu_info, + ppdu_info->tlv_aggr.buf); ppdu_info->tlv_aggr.in_progress = false; ppdu_info->tlv_aggr.cur_len = 0; @@ -691,7 +1073,7 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, ppdu_info->is_eht = true; - ath12k_dp_mon_hal_aggr_tlv(ppdu_info, tlv_len, tlv_data); + ath12k_wifi7_dp_mon_hal_aggr_tlv(ppdu_info, tlv_len, tlv_data); break; case HAL_DUMMY: return HAL_RX_MON_STATUS_BUF_DONE; From 99144cf383b4a66cbb32c24a2451c355d37ca9e2 Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:10 +0530 Subject: [PATCH 107/140] wifi: ath12k: Move remaining SIG TLV parsing to Wi-Fi 7 module The ath12k common monitor path still contains Wi-Fi 7 specific SIG TLV parsing. Move these SIG TLV parsing to the Wi-Fi 7 module to improve modularity. Relocate the following functions into wifi7/dp_mon.c and rename them with the ath12k_wifi7_ prefix: - ath12k_dp_mon_parse_l_sig_b() - ath12k_dp_mon_parse_l_sig_a() - ath12k_dp_mon_hal_rx_parse_u_sig_cmn() - ath12k_dp_mon_hal_rx_parse_u_sig_tb() - ath12k_dp_mon_hal_rx_parse_u_sig_mu() - ath12k_dp_mon_hal_rx_parse_u_sig_hdr() Export the helper symbols needed by the Wi-Fi 7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-10-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 265 ----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 7 - .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 274 +++++++++++++++++- 3 files changed, 269 insertions(+), 277 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index f28e3c2cc1cb8..ffaf25df36719 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -75,271 +75,6 @@ ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats * } EXPORT_SYMBOL(ath12k_dp_mon_rx_populate_mu_user_info); -void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 info0 = __le32_to_cpu(lsigb->info0); - u8 rate; - - rate = u32_get_bits(info0, HAL_RX_LSIG_B_INFO_INFO0_RATE); - switch (rate) { - case 1: - rate = HAL_RX_LEGACY_RATE_1_MBPS; - break; - case 2: - case 5: - rate = HAL_RX_LEGACY_RATE_2_MBPS; - break; - case 3: - case 6: - rate = HAL_RX_LEGACY_RATE_5_5_MBPS; - break; - case 4: - case 7: - rate = HAL_RX_LEGACY_RATE_11_MBPS; - break; - default: - rate = HAL_RX_LEGACY_RATE_INVALID; - } - - ppdu_info->rate = rate; - ppdu_info->cck_flag = 1; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_l_sig_b); - -void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 info0 = __le32_to_cpu(lsiga->info0); - u8 rate; - - rate = u32_get_bits(info0, HAL_RX_LSIG_A_INFO_INFO0_RATE); - switch (rate) { - case 8: - rate = HAL_RX_LEGACY_RATE_48_MBPS; - break; - case 9: - rate = HAL_RX_LEGACY_RATE_24_MBPS; - break; - case 10: - rate = HAL_RX_LEGACY_RATE_12_MBPS; - break; - case 11: - rate = HAL_RX_LEGACY_RATE_6_MBPS; - break; - case 12: - rate = HAL_RX_LEGACY_RATE_54_MBPS; - break; - case 13: - rate = HAL_RX_LEGACY_RATE_36_MBPS; - break; - case 14: - rate = HAL_RX_LEGACY_RATE_18_MBPS; - break; - case 15: - rate = HAL_RX_LEGACY_RATE_9_MBPS; - break; - default: - rate = HAL_RX_LEGACY_RATE_INVALID; - } - - ppdu_info->rate = rate; -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_l_sig_a); - -static void -ath12k_dp_mon_hal_rx_parse_u_sig_cmn(const struct hal_mon_usig_cmn *cmn, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u32 common; - - ppdu_info->u_sig_info.bw = le32_get_bits(cmn->info0, - HAL_RX_USIG_CMN_INFO0_BW); - ppdu_info->u_sig_info.ul_dl = le32_get_bits(cmn->info0, - HAL_RX_USIG_CMN_INFO0_UL_DL); - - common = __le32_to_cpu(ppdu_info->u_sig_info.usig.common); - common |= IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER_KNOWN | - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_KNOWN | - IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL_KNOWN | - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR_KNOWN | - IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP_KNOWN | - ATH12K_LE32_DEC_ENC(cmn->info0, - HAL_RX_USIG_CMN_INFO0_PHY_VERSION, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER) | - u32_encode_bits(ppdu_info->u_sig_info.bw, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW) | - u32_encode_bits(ppdu_info->u_sig_info.ul_dl, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL) | - ATH12K_LE32_DEC_ENC(cmn->info0, - HAL_RX_USIG_CMN_INFO0_BSS_COLOR, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR) | - ATH12K_LE32_DEC_ENC(cmn->info0, - HAL_RX_USIG_CMN_INFO0_TXOP, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP); - ppdu_info->u_sig_info.usig.common = cpu_to_le32(common); - - switch (ppdu_info->u_sig_info.bw) { - default: - fallthrough; - case HAL_EHT_BW_20: - ppdu_info->bw = HAL_RX_BW_20MHZ; - break; - case HAL_EHT_BW_40: - ppdu_info->bw = HAL_RX_BW_40MHZ; - break; - case HAL_EHT_BW_80: - ppdu_info->bw = HAL_RX_BW_80MHZ; - break; - case HAL_EHT_BW_160: - ppdu_info->bw = HAL_RX_BW_160MHZ; - break; - case HAL_EHT_BW_320_1: - case HAL_EHT_BW_320_2: - ppdu_info->bw = HAL_RX_BW_320MHZ; - break; - } -} - -static void -ath12k_dp_mon_hal_rx_parse_u_sig_tb(const struct hal_mon_usig_tb *usig_tb, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct ieee80211_radiotap_eht_usig *usig = &ppdu_info->u_sig_info.usig; - enum ieee80211_radiotap_eht_usig_tb spatial_reuse1, spatial_reuse2; - u32 common, value, mask; - - spatial_reuse1 = IEEE80211_RADIOTAP_EHT_USIG2_TB_B3_B6_SPATIAL_REUSE_1; - spatial_reuse2 = IEEE80211_RADIOTAP_EHT_USIG2_TB_B7_B10_SPATIAL_REUSE_2; - - common = __le32_to_cpu(usig->common); - value = __le32_to_cpu(usig->value); - mask = __le32_to_cpu(usig->mask); - - ppdu_info->u_sig_info.ppdu_type_comp_mode = - le32_get_bits(usig_tb->info0, - HAL_RX_USIG_TB_INFO0_PPDU_TYPE_COMP_MODE); - - common |= ATH12K_LE32_DEC_ENC(usig_tb->info0, - HAL_RX_USIG_TB_INFO0_RX_INTEG_CHECK_PASS, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC); - - value |= IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD | - u32_encode_bits(ppdu_info->u_sig_info.ppdu_type_comp_mode, - IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE) | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B2_VALIDATE | - ATH12K_LE32_DEC_ENC(usig_tb->info0, - HAL_RX_USIG_TB_INFO0_SPATIAL_REUSE_1, - spatial_reuse1) | - ATH12K_LE32_DEC_ENC(usig_tb->info0, - HAL_RX_USIG_TB_INFO0_SPATIAL_REUSE_2, - spatial_reuse2) | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B11_B15_DISREGARD | - ATH12K_LE32_DEC_ENC(usig_tb->info0, - HAL_RX_USIG_TB_INFO0_CRC, - IEEE80211_RADIOTAP_EHT_USIG2_TB_B16_B19_CRC) | - ATH12K_LE32_DEC_ENC(usig_tb->info0, - HAL_RX_USIG_TB_INFO0_TAIL, - IEEE80211_RADIOTAP_EHT_USIG2_TB_B20_B25_TAIL); - - mask |= IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B2_VALIDATE | - spatial_reuse1 | spatial_reuse2 | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B11_B15_DISREGARD | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B16_B19_CRC | - IEEE80211_RADIOTAP_EHT_USIG2_TB_B20_B25_TAIL; - - usig->common = cpu_to_le32(common); - usig->value = cpu_to_le32(value); - usig->mask = cpu_to_le32(mask); -} - -static void -ath12k_dp_mon_hal_rx_parse_u_sig_mu(const struct hal_mon_usig_mu *usig_mu, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct ieee80211_radiotap_eht_usig *usig = &ppdu_info->u_sig_info.usig; - enum ieee80211_radiotap_eht_usig_mu sig_symb, punc; - u32 common, value, mask; - - sig_symb = IEEE80211_RADIOTAP_EHT_USIG2_MU_B11_B15_EHT_SIG_SYMBOLS; - punc = IEEE80211_RADIOTAP_EHT_USIG2_MU_B3_B7_PUNCTURED_INFO; - - common = __le32_to_cpu(usig->common); - value = __le32_to_cpu(usig->value); - mask = __le32_to_cpu(usig->mask); - - ppdu_info->u_sig_info.ppdu_type_comp_mode = - le32_get_bits(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_PPDU_TYPE_COMP_MODE); - ppdu_info->u_sig_info.eht_sig_mcs = - le32_get_bits(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_EHT_SIG_MCS); - ppdu_info->u_sig_info.num_eht_sig_sym = - le32_get_bits(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_NUM_EHT_SIG_SYM); - - common |= ATH12K_LE32_DEC_ENC(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_RX_INTEG_CHECK_PASS, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC); - - value |= IEEE80211_RADIOTAP_EHT_USIG1_MU_B20_B24_DISREGARD | - IEEE80211_RADIOTAP_EHT_USIG1_MU_B25_VALIDATE | - u32_encode_bits(ppdu_info->u_sig_info.ppdu_type_comp_mode, - IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE) | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B2_VALIDATE | - ATH12K_LE32_DEC_ENC(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_PUNC_CH_INFO, - punc) | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B8_VALIDATE | - u32_encode_bits(ppdu_info->u_sig_info.eht_sig_mcs, - IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS) | - u32_encode_bits(ppdu_info->u_sig_info.num_eht_sig_sym, - sig_symb) | - ATH12K_LE32_DEC_ENC(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_CRC, - IEEE80211_RADIOTAP_EHT_USIG2_MU_B16_B19_CRC) | - ATH12K_LE32_DEC_ENC(usig_mu->info0, - HAL_RX_USIG_MU_INFO0_TAIL, - IEEE80211_RADIOTAP_EHT_USIG2_MU_B20_B25_TAIL); - - mask |= IEEE80211_RADIOTAP_EHT_USIG1_MU_B20_B24_DISREGARD | - IEEE80211_RADIOTAP_EHT_USIG1_MU_B25_VALIDATE | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B2_VALIDATE | - punc | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B8_VALIDATE | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS | - sig_symb | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B16_B19_CRC | - IEEE80211_RADIOTAP_EHT_USIG2_MU_B20_B25_TAIL; - - usig->common = cpu_to_le32(common); - usig->value = cpu_to_le32(value); - usig->mask = cpu_to_le32(mask); -} - -void -ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - u8 comp_mode; - - ppdu_info->eht_usig = true; - - ath12k_dp_mon_hal_rx_parse_u_sig_cmn(&usig->cmn, ppdu_info); - - comp_mode = le32_get_bits(usig->non_cmn.mu.info0, - HAL_RX_USIG_MU_INFO0_PPDU_TYPE_COMP_MODE); - - if (comp_mode == 0 && ppdu_info->u_sig_info.ul_dl) - ath12k_dp_mon_hal_rx_parse_u_sig_tb(&usig->non_cmn.tb, ppdu_info); - else - ath12k_dp_mon_hal_rx_parse_u_sig_mu(&usig->non_cmn.mu, ppdu_info); -} -EXPORT_SYMBOL(ath12k_dp_mon_hal_rx_parse_u_sig_hdr); - static inline enum ath12k_eht_ru_size hal_rx_mon_hal_ru_size_to_ath12k_ru_size(u32 hal_ru_size) { diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index d2bee88f561f4..063d57512db70 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -126,10 +126,6 @@ void ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats *rx_tlv, struct hal_rx_mon_ppdu_info *ppdu_info, struct hal_rx_user_status *rx_user_status); -void ath12k_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, - struct hal_rx_mon_ppdu_info *ppdu_info); -void ath12k_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, - struct hal_rx_mon_ppdu_info *ppdu_info); void ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info, u16 user_id, @@ -137,7 +133,4 @@ ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_ void ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, const struct hal_rx_msdu_end *msdu_end); -void -ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, - struct hal_rx_mon_ppdu_info *ppdu_info); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index b924180007c53..2d67fd553776f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -31,6 +31,270 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } +static void +ath12k_wifi7_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 info0 = __le32_to_cpu(lsigb->info0); + u8 rate; + + rate = u32_get_bits(info0, HAL_RX_LSIG_B_INFO_INFO0_RATE); + switch (rate) { + case 1: + rate = HAL_RX_LEGACY_RATE_1_MBPS; + break; + case 2: + case 5: + rate = HAL_RX_LEGACY_RATE_2_MBPS; + break; + case 3: + case 6: + rate = HAL_RX_LEGACY_RATE_5_5_MBPS; + break; + case 4: + case 7: + rate = HAL_RX_LEGACY_RATE_11_MBPS; + break; + default: + rate = HAL_RX_LEGACY_RATE_INVALID; + } + + ppdu_info->rate = rate; + ppdu_info->cck_flag = 1; +} + +static void +ath12k_wifi7_dp_mon_parse_l_sig_a(const struct hal_rx_lsig_a_info *lsiga, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 info0 = __le32_to_cpu(lsiga->info0); + u8 rate; + + rate = u32_get_bits(info0, HAL_RX_LSIG_A_INFO_INFO0_RATE); + switch (rate) { + case 8: + rate = HAL_RX_LEGACY_RATE_48_MBPS; + break; + case 9: + rate = HAL_RX_LEGACY_RATE_24_MBPS; + break; + case 10: + rate = HAL_RX_LEGACY_RATE_12_MBPS; + break; + case 11: + rate = HAL_RX_LEGACY_RATE_6_MBPS; + break; + case 12: + rate = HAL_RX_LEGACY_RATE_54_MBPS; + break; + case 13: + rate = HAL_RX_LEGACY_RATE_36_MBPS; + break; + case 14: + rate = HAL_RX_LEGACY_RATE_18_MBPS; + break; + case 15: + rate = HAL_RX_LEGACY_RATE_9_MBPS; + break; + default: + rate = HAL_RX_LEGACY_RATE_INVALID; + } + + ppdu_info->rate = rate; +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_cmn(const struct hal_mon_usig_cmn *cmn, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u32 common; + + ppdu_info->u_sig_info.bw = le32_get_bits(cmn->info0, + HAL_RX_USIG_CMN_INFO0_BW); + ppdu_info->u_sig_info.ul_dl = le32_get_bits(cmn->info0, + HAL_RX_USIG_CMN_INFO0_UL_DL); + + common = __le32_to_cpu(ppdu_info->u_sig_info.usig.common); + common |= IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER_KNOWN | + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_KNOWN | + IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL_KNOWN | + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR_KNOWN | + IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP_KNOWN | + ATH12K_LE32_DEC_ENC(cmn->info0, + HAL_RX_USIG_CMN_INFO0_PHY_VERSION, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER) | + u32_encode_bits(ppdu_info->u_sig_info.bw, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW) | + u32_encode_bits(ppdu_info->u_sig_info.ul_dl, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL) | + ATH12K_LE32_DEC_ENC(cmn->info0, + HAL_RX_USIG_CMN_INFO0_BSS_COLOR, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR) | + ATH12K_LE32_DEC_ENC(cmn->info0, + HAL_RX_USIG_CMN_INFO0_TXOP, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP); + ppdu_info->u_sig_info.usig.common = cpu_to_le32(common); + + switch (ppdu_info->u_sig_info.bw) { + default: + fallthrough; + case HAL_EHT_BW_20: + ppdu_info->bw = HAL_RX_BW_20MHZ; + break; + case HAL_EHT_BW_40: + ppdu_info->bw = HAL_RX_BW_40MHZ; + break; + case HAL_EHT_BW_80: + ppdu_info->bw = HAL_RX_BW_80MHZ; + break; + case HAL_EHT_BW_160: + ppdu_info->bw = HAL_RX_BW_160MHZ; + break; + case HAL_EHT_BW_320_1: + case HAL_EHT_BW_320_2: + ppdu_info->bw = HAL_RX_BW_320MHZ; + break; + } +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_tb(const struct hal_mon_usig_tb *usig_tb, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct ieee80211_radiotap_eht_usig *usig = &ppdu_info->u_sig_info.usig; + enum ieee80211_radiotap_eht_usig_tb spatial_reuse1, spatial_reuse2; + u32 common, value, mask; + + spatial_reuse1 = IEEE80211_RADIOTAP_EHT_USIG2_TB_B3_B6_SPATIAL_REUSE_1; + spatial_reuse2 = IEEE80211_RADIOTAP_EHT_USIG2_TB_B7_B10_SPATIAL_REUSE_2; + + common = __le32_to_cpu(usig->common); + value = __le32_to_cpu(usig->value); + mask = __le32_to_cpu(usig->mask); + + ppdu_info->u_sig_info.ppdu_type_comp_mode = + le32_get_bits(usig_tb->info0, + HAL_RX_USIG_TB_INFO0_PPDU_TYPE_COMP_MODE); + + common |= ATH12K_LE32_DEC_ENC(usig_tb->info0, + HAL_RX_USIG_TB_INFO0_RX_INTEG_CHECK_PASS, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC); + + value |= IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD | + u32_encode_bits(ppdu_info->u_sig_info.ppdu_type_comp_mode, + IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE) | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B2_VALIDATE | + ATH12K_LE32_DEC_ENC(usig_tb->info0, + HAL_RX_USIG_TB_INFO0_SPATIAL_REUSE_1, + spatial_reuse1) | + ATH12K_LE32_DEC_ENC(usig_tb->info0, + HAL_RX_USIG_TB_INFO0_SPATIAL_REUSE_2, + spatial_reuse2) | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B11_B15_DISREGARD | + ATH12K_LE32_DEC_ENC(usig_tb->info0, + HAL_RX_USIG_TB_INFO0_CRC, + IEEE80211_RADIOTAP_EHT_USIG2_TB_B16_B19_CRC) | + ATH12K_LE32_DEC_ENC(usig_tb->info0, + HAL_RX_USIG_TB_INFO0_TAIL, + IEEE80211_RADIOTAP_EHT_USIG2_TB_B20_B25_TAIL); + + mask |= IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B2_VALIDATE | + spatial_reuse1 | spatial_reuse2 | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B11_B15_DISREGARD | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B16_B19_CRC | + IEEE80211_RADIOTAP_EHT_USIG2_TB_B20_B25_TAIL; + + usig->common = cpu_to_le32(common); + usig->value = cpu_to_le32(value); + usig->mask = cpu_to_le32(mask); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_mu(const struct hal_mon_usig_mu *usig_mu, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct ieee80211_radiotap_eht_usig *usig = &ppdu_info->u_sig_info.usig; + enum ieee80211_radiotap_eht_usig_mu sig_symb, punc; + u32 common, value, mask; + + sig_symb = IEEE80211_RADIOTAP_EHT_USIG2_MU_B11_B15_EHT_SIG_SYMBOLS; + punc = IEEE80211_RADIOTAP_EHT_USIG2_MU_B3_B7_PUNCTURED_INFO; + + common = __le32_to_cpu(usig->common); + value = __le32_to_cpu(usig->value); + mask = __le32_to_cpu(usig->mask); + + ppdu_info->u_sig_info.ppdu_type_comp_mode = + le32_get_bits(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_PPDU_TYPE_COMP_MODE); + ppdu_info->u_sig_info.eht_sig_mcs = + le32_get_bits(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_EHT_SIG_MCS); + ppdu_info->u_sig_info.num_eht_sig_sym = + le32_get_bits(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_NUM_EHT_SIG_SYM); + + common |= ATH12K_LE32_DEC_ENC(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_RX_INTEG_CHECK_PASS, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC); + + value |= IEEE80211_RADIOTAP_EHT_USIG1_MU_B20_B24_DISREGARD | + IEEE80211_RADIOTAP_EHT_USIG1_MU_B25_VALIDATE | + u32_encode_bits(ppdu_info->u_sig_info.ppdu_type_comp_mode, + IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE) | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B2_VALIDATE | + ATH12K_LE32_DEC_ENC(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_PUNC_CH_INFO, + punc) | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B8_VALIDATE | + u32_encode_bits(ppdu_info->u_sig_info.eht_sig_mcs, + IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS) | + u32_encode_bits(ppdu_info->u_sig_info.num_eht_sig_sym, + sig_symb) | + ATH12K_LE32_DEC_ENC(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_CRC, + IEEE80211_RADIOTAP_EHT_USIG2_MU_B16_B19_CRC) | + ATH12K_LE32_DEC_ENC(usig_mu->info0, + HAL_RX_USIG_MU_INFO0_TAIL, + IEEE80211_RADIOTAP_EHT_USIG2_MU_B20_B25_TAIL); + + mask |= IEEE80211_RADIOTAP_EHT_USIG1_MU_B20_B24_DISREGARD | + IEEE80211_RADIOTAP_EHT_USIG1_MU_B25_VALIDATE | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B2_VALIDATE | + punc | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B8_VALIDATE | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS | + sig_symb | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B16_B19_CRC | + IEEE80211_RADIOTAP_EHT_USIG2_MU_B20_B25_TAIL; + + usig->common = cpu_to_le32(common); + usig->value = cpu_to_le32(value); + usig->mask = cpu_to_le32(mask); +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + u8 comp_mode; + + ppdu_info->eht_usig = true; + + ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_cmn(&usig->cmn, ppdu_info); + + comp_mode = le32_get_bits(usig->non_cmn.mu.info0, + HAL_RX_USIG_MU_INFO0_PPDU_TYPE_COMP_MODE); + + if (comp_mode == 0 && ppdu_info->u_sig_info.ul_dl) + ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_tb(&usig->non_cmn.tb, ppdu_info); + else + ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_mu(&usig->non_cmn.mu, ppdu_info); +} + static void ath12k_wifi7_dp_mon_parse_vht_sig_a(const struct hal_rx_vht_sig_a_info *vht_sig, struct hal_rx_mon_ppdu_info *ppdu_info) @@ -956,11 +1220,11 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, break; case HAL_PHYRX_L_SIG_B: - ath12k_dp_mon_parse_l_sig_b(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_l_sig_b(tlv_data, ppdu_info); break; case HAL_PHYRX_L_SIG_A: - ath12k_dp_mon_parse_l_sig_a(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_parse_l_sig_a(tlv_data, ppdu_info); break; case HAL_PHYRX_VHT_SIG_A: @@ -1058,7 +1322,7 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, case HAL_RX_MPDU_END: return HAL_RX_MON_STATUS_MPDU_END; case HAL_PHYRX_GENERIC_U_SIG: - ath12k_dp_mon_hal_rx_parse_u_sig_hdr(tlv_data, ppdu_info); + ath12k_wifi7_dp_mon_hal_rx_parse_u_sig_hdr(tlv_data, ppdu_info); break; case HAL_PHYRX_GENERIC_EHT_SIG: /* Handle the case where aggregation is in progress @@ -1621,11 +1885,11 @@ ath12k_wifi7_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab, break; case HAL_MACTX_L_SIG_A: - ath12k_dp_mon_parse_l_sig_a(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_l_sig_a(tlv_data, &tx_ppdu_info->rx_status); break; case HAL_MACTX_L_SIG_B: - ath12k_dp_mon_parse_l_sig_b(tlv_data, &tx_ppdu_info->rx_status); + ath12k_wifi7_dp_mon_parse_l_sig_b(tlv_data, &tx_ppdu_info->rx_status); break; case HAL_RX_FRAME_BITMAP_ACK: { From a1adc2d62dab60db4fc30a8906f3e965e52276cc Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:11 +0530 Subject: [PATCH 108/140] wifi: ath12k: Move MU user processing to Wi-Fi 7 module Move Wi-Fi 7-specific monitor functionality out of ath12k common code into the Wi-Fi 7 module to improve modularity. Move and rename the following MU user processing functions to wifi7/dp_mon.c with the ath12k_wifi7_ prefix: - ath12k_dp_mon_rx_handle_ofdma_info() - ath12k_dp_mon_rx_populate_mu_user_info() - ath12k_dp_mon_hal_rx_parse_user_info() Move the helper functions hal_rx_mon_hal_ru_size_to_ath12k_ru_size and hal_rx_ul_ofdma_ru_size_to_width to the Wi-Fi 7 module, and export the helpers required by the ath12k_wifi7 code. Isolate the parsing of MU-specific user information within the Wi-Fi 7 module to keep common code generic. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-11-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 351 ----------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 11 - .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 356 +++++++++++++++++- 3 files changed, 352 insertions(+), 366 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index ffaf25df36719..c5c1f4b19b513 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -11,357 +11,6 @@ #include "dp_tx.h" #include "peer.h" -void -ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, - struct hal_rx_user_status *rx_user_status) -{ - rx_user_status->ul_ofdma_user_v0_word0 = - __le32_to_cpu(ppdu_end_user->usr_resp_ref); - rx_user_status->ul_ofdma_user_v0_word1 = - __le32_to_cpu(ppdu_end_user->usr_resp_ref_ext); -} -EXPORT_SYMBOL(ath12k_dp_mon_rx_handle_ofdma_info); - -static void -ath12k_dp_mon_rx_populate_byte_count(const struct hal_rx_ppdu_end_user_stats *stats, - void *ppduinfo, - struct hal_rx_user_status *rx_user_status) -{ - rx_user_status->mpdu_ok_byte_count = - le32_get_bits(stats->info7, - HAL_RX_PPDU_END_USER_STATS_INFO7_MPDU_OK_BYTE_COUNT); - rx_user_status->mpdu_err_byte_count = - le32_get_bits(stats->info8, - HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_ERR_BYTE_COUNT); -} - -void -ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats *rx_tlv, - struct hal_rx_mon_ppdu_info *ppdu_info, - struct hal_rx_user_status *rx_user_status) -{ - rx_user_status->ast_index = ppdu_info->ast_index; - rx_user_status->tid = ppdu_info->tid; - rx_user_status->tcp_ack_msdu_count = - ppdu_info->tcp_ack_msdu_count; - rx_user_status->tcp_msdu_count = - ppdu_info->tcp_msdu_count; - rx_user_status->udp_msdu_count = - ppdu_info->udp_msdu_count; - rx_user_status->other_msdu_count = - ppdu_info->other_msdu_count; - rx_user_status->frame_control = ppdu_info->frame_control; - rx_user_status->frame_control_info_valid = - ppdu_info->frame_control_info_valid; - rx_user_status->data_sequence_control_info_valid = - ppdu_info->data_sequence_control_info_valid; - rx_user_status->first_data_seq_ctrl = - ppdu_info->first_data_seq_ctrl; - rx_user_status->preamble_type = ppdu_info->preamble_type; - rx_user_status->ht_flags = ppdu_info->ht_flags; - rx_user_status->vht_flags = ppdu_info->vht_flags; - rx_user_status->he_flags = ppdu_info->he_flags; - rx_user_status->rs_flags = ppdu_info->rs_flags; - - rx_user_status->mpdu_cnt_fcs_ok = - ppdu_info->num_mpdu_fcs_ok; - rx_user_status->mpdu_cnt_fcs_err = - ppdu_info->num_mpdu_fcs_err; - memcpy(&rx_user_status->mpdu_fcs_ok_bitmap[0], &ppdu_info->mpdu_fcs_ok_bitmap[0], - HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * - sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); - - ath12k_dp_mon_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status); -} -EXPORT_SYMBOL(ath12k_dp_mon_rx_populate_mu_user_info); - -static inline enum ath12k_eht_ru_size -hal_rx_mon_hal_ru_size_to_ath12k_ru_size(u32 hal_ru_size) -{ - switch (hal_ru_size) { - case HAL_EHT_RU_26: - return ATH12K_EHT_RU_26; - case HAL_EHT_RU_52: - return ATH12K_EHT_RU_52; - case HAL_EHT_RU_78: - return ATH12K_EHT_RU_52_26; - case HAL_EHT_RU_106: - return ATH12K_EHT_RU_106; - case HAL_EHT_RU_132: - return ATH12K_EHT_RU_106_26; - case HAL_EHT_RU_242: - return ATH12K_EHT_RU_242; - case HAL_EHT_RU_484: - return ATH12K_EHT_RU_484; - case HAL_EHT_RU_726: - return ATH12K_EHT_RU_484_242; - case HAL_EHT_RU_996: - return ATH12K_EHT_RU_996; - case HAL_EHT_RU_996x2: - return ATH12K_EHT_RU_996x2; - case HAL_EHT_RU_996x3: - return ATH12K_EHT_RU_996x3; - case HAL_EHT_RU_996x4: - return ATH12K_EHT_RU_996x4; - case HAL_EHT_RU_NONE: - return ATH12K_EHT_RU_INVALID; - case HAL_EHT_RU_996_484: - return ATH12K_EHT_RU_996_484; - case HAL_EHT_RU_996x2_484: - return ATH12K_EHT_RU_996x2_484; - case HAL_EHT_RU_996x3_484: - return ATH12K_EHT_RU_996x3_484; - case HAL_EHT_RU_996_484_242: - return ATH12K_EHT_RU_996_484_242; - default: - return ATH12K_EHT_RU_INVALID; - } -} - -static inline u32 -hal_rx_ul_ofdma_ru_size_to_width(enum ath12k_eht_ru_size ru_size) -{ - switch (ru_size) { - case ATH12K_EHT_RU_26: - return RU_26; - case ATH12K_EHT_RU_52: - return RU_52; - case ATH12K_EHT_RU_52_26: - return RU_52_26; - case ATH12K_EHT_RU_106: - return RU_106; - case ATH12K_EHT_RU_106_26: - return RU_106_26; - case ATH12K_EHT_RU_242: - return RU_242; - case ATH12K_EHT_RU_484: - return RU_484; - case ATH12K_EHT_RU_484_242: - return RU_484_242; - case ATH12K_EHT_RU_996: - return RU_996; - case ATH12K_EHT_RU_996_484: - return RU_996_484; - case ATH12K_EHT_RU_996_484_242: - return RU_996_484_242; - case ATH12K_EHT_RU_996x2: - return RU_2X996; - case ATH12K_EHT_RU_996x2_484: - return RU_2X996_484; - case ATH12K_EHT_RU_996x3: - return RU_3X996; - case ATH12K_EHT_RU_996x3_484: - return RU_3X996_484; - case ATH12K_EHT_RU_996x4: - return RU_4X996; - default: - return RU_INVALID; - } -} - -void -ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info, - u16 user_id, - struct hal_rx_mon_ppdu_info *ppdu_info) -{ - struct hal_rx_user_status *mon_rx_user_status = NULL; - struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; - enum ath12k_eht_ru_size rtap_ru_size = ATH12K_EHT_RU_INVALID; - u32 ru_width, reception_type, ru_index = HAL_EHT_RU_INVALID; - u32 ru_type_80_0, ru_start_index_80_0; - u32 ru_type_80_1, ru_start_index_80_1; - u32 ru_type_80_2, ru_start_index_80_2; - u32 ru_type_80_3, ru_start_index_80_3; - u32 ru_size = 0, num_80mhz_with_ru = 0; - u64 ru_index_320mhz = 0; - u32 ru_index_per80mhz; - - reception_type = le32_get_bits(rx_usr_info->info0, - HAL_RX_USR_INFO0_RECEPTION_TYPE); - - switch (reception_type) { - case HAL_RECEPTION_TYPE_SU: - ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; - break; - case HAL_RECEPTION_TYPE_DL_MU_MIMO: - case HAL_RECEPTION_TYPE_UL_MU_MIMO: - ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO; - break; - case HAL_RECEPTION_TYPE_DL_MU_OFMA: - case HAL_RECEPTION_TYPE_UL_MU_OFDMA: - ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA; - break; - case HAL_RECEPTION_TYPE_DL_MU_OFDMA_MIMO: - case HAL_RECEPTION_TYPE_UL_MU_OFDMA_MIMO: - ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO; - } - - ppdu_info->is_stbc = le32_get_bits(rx_usr_info->info0, HAL_RX_USR_INFO0_STBC); - ppdu_info->ldpc = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_LDPC); - ppdu_info->dcm = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_STA_DCM); - ppdu_info->bw = le32_get_bits(rx_usr_info->info1, HAL_RX_USR_INFO1_RX_BW); - ppdu_info->mcs = le32_get_bits(rx_usr_info->info1, HAL_RX_USR_INFO1_MCS); - ppdu_info->nss = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_NSS) + 1; - - if (user_id < HAL_MAX_UL_MU_USERS) { - mon_rx_user_status = &ppdu_info->userstats[user_id]; - mon_rx_user_status->mcs = ppdu_info->mcs; - mon_rx_user_status->nss = ppdu_info->nss; - } - - if (!(ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_MIMO || - ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA || - ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO)) - return; - - /* RU allocation present only for OFDMA reception */ - ru_type_80_0 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_0); - ru_start_index_80_0 = le32_get_bits(rx_usr_info->info3, - HAL_RX_USR_INFO3_RU_START_IDX_80_0); - if (ru_type_80_0 != HAL_EHT_RU_NONE) { - ru_size += ru_type_80_0; - ru_index_per80mhz = ru_start_index_80_0; - ru_index = ru_index_per80mhz; - ru_index_320mhz |= HAL_RU_PER80(ru_type_80_0, 0, ru_index_per80mhz); - num_80mhz_with_ru++; - } - - ru_type_80_1 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_1); - ru_start_index_80_1 = le32_get_bits(rx_usr_info->info3, - HAL_RX_USR_INFO3_RU_START_IDX_80_1); - if (ru_type_80_1 != HAL_EHT_RU_NONE) { - ru_size += ru_type_80_1; - ru_index_per80mhz = ru_start_index_80_1; - ru_index = ru_index_per80mhz; - ru_index_320mhz |= HAL_RU_PER80(ru_type_80_1, 1, ru_index_per80mhz); - num_80mhz_with_ru++; - } - - ru_type_80_2 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_2); - ru_start_index_80_2 = le32_get_bits(rx_usr_info->info3, - HAL_RX_USR_INFO3_RU_START_IDX_80_2); - if (ru_type_80_2 != HAL_EHT_RU_NONE) { - ru_size += ru_type_80_2; - ru_index_per80mhz = ru_start_index_80_2; - ru_index = ru_index_per80mhz; - ru_index_320mhz |= HAL_RU_PER80(ru_type_80_2, 2, ru_index_per80mhz); - num_80mhz_with_ru++; - } - - ru_type_80_3 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_3); - ru_start_index_80_3 = le32_get_bits(rx_usr_info->info2, - HAL_RX_USR_INFO3_RU_START_IDX_80_3); - if (ru_type_80_3 != HAL_EHT_RU_NONE) { - ru_size += ru_type_80_3; - ru_index_per80mhz = ru_start_index_80_3; - ru_index = ru_index_per80mhz; - ru_index_320mhz |= HAL_RU_PER80(ru_type_80_3, 3, ru_index_per80mhz); - num_80mhz_with_ru++; - } - - if (num_80mhz_with_ru > 1) { - /* Calculate the MRU index */ - switch (ru_index_320mhz) { - case HAL_EHT_RU_996_484_0: - case HAL_EHT_RU_996x2_484_0: - case HAL_EHT_RU_996x3_484_0: - ru_index = 0; - break; - case HAL_EHT_RU_996_484_1: - case HAL_EHT_RU_996x2_484_1: - case HAL_EHT_RU_996x3_484_1: - ru_index = 1; - break; - case HAL_EHT_RU_996_484_2: - case HAL_EHT_RU_996x2_484_2: - case HAL_EHT_RU_996x3_484_2: - ru_index = 2; - break; - case HAL_EHT_RU_996_484_3: - case HAL_EHT_RU_996x2_484_3: - case HAL_EHT_RU_996x3_484_3: - ru_index = 3; - break; - case HAL_EHT_RU_996_484_4: - case HAL_EHT_RU_996x2_484_4: - case HAL_EHT_RU_996x3_484_4: - ru_index = 4; - break; - case HAL_EHT_RU_996_484_5: - case HAL_EHT_RU_996x2_484_5: - case HAL_EHT_RU_996x3_484_5: - ru_index = 5; - break; - case HAL_EHT_RU_996_484_6: - case HAL_EHT_RU_996x2_484_6: - case HAL_EHT_RU_996x3_484_6: - ru_index = 6; - break; - case HAL_EHT_RU_996_484_7: - case HAL_EHT_RU_996x2_484_7: - case HAL_EHT_RU_996x3_484_7: - ru_index = 7; - break; - case HAL_EHT_RU_996x2_484_8: - ru_index = 8; - break; - case HAL_EHT_RU_996x2_484_9: - ru_index = 9; - break; - case HAL_EHT_RU_996x2_484_10: - ru_index = 10; - break; - case HAL_EHT_RU_996x2_484_11: - ru_index = 11; - break; - default: - ru_index = HAL_EHT_RU_INVALID; - break; - } - - ru_size += 4; - } - - rtap_ru_size = hal_rx_mon_hal_ru_size_to_ath12k_ru_size(ru_size); - if (rtap_ru_size != ATH12K_EHT_RU_INVALID) { - u32 known, data; - - known = __le32_to_cpu(eht->known); - known |= IEEE80211_RADIOTAP_EHT_KNOWN_RU_MRU_SIZE_OM; - eht->known = cpu_to_le32(known); - - data = __le32_to_cpu(eht->data[1]); - data |= u32_encode_bits(rtap_ru_size, - IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE); - eht->data[1] = cpu_to_le32(data); - } - - if (ru_index != HAL_EHT_RU_INVALID) { - u32 known, data; - - known = __le32_to_cpu(eht->known); - known |= IEEE80211_RADIOTAP_EHT_KNOWN_RU_MRU_INDEX_OM; - eht->known = cpu_to_le32(known); - - data = __le32_to_cpu(eht->data[1]); - data |= u32_encode_bits(rtap_ru_size, - IEEE80211_RADIOTAP_EHT_DATA1_RU_INDEX); - eht->data[1] = cpu_to_le32(data); - } - - if (mon_rx_user_status && ru_index != HAL_EHT_RU_INVALID && - rtap_ru_size != ATH12K_EHT_RU_INVALID) { - mon_rx_user_status->ul_ofdma_ru_start_index = ru_index; - mon_rx_user_status->ul_ofdma_ru_size = rtap_ru_size; - - ru_width = hal_rx_ul_ofdma_ru_size_to_width(rtap_ru_size); - - mon_rx_user_status->ul_ofdma_ru_width = ru_width; - mon_rx_user_status->ofdma_info_valid = 1; - } -} -EXPORT_SYMBOL(ath12k_dp_mon_hal_rx_parse_user_info); - static void ath12k_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap) { if (info & RX_MSDU_END_INFO13_FCS_ERR) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 063d57512db70..6dac4e9569b6e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -120,17 +120,6 @@ ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct dp_mon_packet_info *packet_info); void -ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, - struct hal_rx_user_status *rx_user_status); -void -ath12k_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats *rx_tlv, - struct hal_rx_mon_ppdu_info *ppdu_info, - struct hal_rx_user_status *rx_user_status); -void -ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info, - u16 user_id, - struct hal_rx_mon_ppdu_info *ppdu_info); -void ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, const struct hal_rx_msdu_end *msdu_end); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 2d67fd553776f..8d913d09f8826 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -31,6 +31,354 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } +static void +ath12k_wifi7_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, + struct hal_rx_user_status *rx_user_status) +{ + rx_user_status->ul_ofdma_user_v0_word0 = + __le32_to_cpu(ppdu_end_user->usr_resp_ref); + rx_user_status->ul_ofdma_user_v0_word1 = + __le32_to_cpu(ppdu_end_user->usr_resp_ref_ext); +} + +static void +ath12k_wifi7_dp_mon_rx_populate_byte_count(const struct hal_rx_ppdu_end_user_stats *stats, + void *ppduinfo, + struct hal_rx_user_status *rx_user_status) +{ + rx_user_status->mpdu_ok_byte_count = + le32_get_bits(stats->info7, + HAL_RX_PPDU_END_USER_STATS_INFO7_MPDU_OK_BYTE_COUNT); + rx_user_status->mpdu_err_byte_count = + le32_get_bits(stats->info8, + HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_ERR_BYTE_COUNT); +} + +static void +ath12k_wifi7_dp_mon_rx_populate_mu_user_info(const struct hal_rx_ppdu_end_user_stats *rx_tlv, + struct hal_rx_mon_ppdu_info *ppdu_info, + struct hal_rx_user_status *rx_user_status) +{ + rx_user_status->ast_index = ppdu_info->ast_index; + rx_user_status->tid = ppdu_info->tid; + rx_user_status->tcp_ack_msdu_count = + ppdu_info->tcp_ack_msdu_count; + rx_user_status->tcp_msdu_count = + ppdu_info->tcp_msdu_count; + rx_user_status->udp_msdu_count = + ppdu_info->udp_msdu_count; + rx_user_status->other_msdu_count = + ppdu_info->other_msdu_count; + rx_user_status->frame_control = ppdu_info->frame_control; + rx_user_status->frame_control_info_valid = + ppdu_info->frame_control_info_valid; + rx_user_status->data_sequence_control_info_valid = + ppdu_info->data_sequence_control_info_valid; + rx_user_status->first_data_seq_ctrl = + ppdu_info->first_data_seq_ctrl; + rx_user_status->preamble_type = ppdu_info->preamble_type; + rx_user_status->ht_flags = ppdu_info->ht_flags; + rx_user_status->vht_flags = ppdu_info->vht_flags; + rx_user_status->he_flags = ppdu_info->he_flags; + rx_user_status->rs_flags = ppdu_info->rs_flags; + + rx_user_status->mpdu_cnt_fcs_ok = + ppdu_info->num_mpdu_fcs_ok; + rx_user_status->mpdu_cnt_fcs_err = + ppdu_info->num_mpdu_fcs_err; + memcpy(&rx_user_status->mpdu_fcs_ok_bitmap[0], &ppdu_info->mpdu_fcs_ok_bitmap[0], + HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * + sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0])); + + ath12k_wifi7_dp_mon_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status); +} + +static inline enum ath12k_eht_ru_size +hal_rx_mon_hal_ru_size_to_ath12k_ru_size(u32 hal_ru_size) +{ + switch (hal_ru_size) { + case HAL_EHT_RU_26: + return ATH12K_EHT_RU_26; + case HAL_EHT_RU_52: + return ATH12K_EHT_RU_52; + case HAL_EHT_RU_78: + return ATH12K_EHT_RU_52_26; + case HAL_EHT_RU_106: + return ATH12K_EHT_RU_106; + case HAL_EHT_RU_132: + return ATH12K_EHT_RU_106_26; + case HAL_EHT_RU_242: + return ATH12K_EHT_RU_242; + case HAL_EHT_RU_484: + return ATH12K_EHT_RU_484; + case HAL_EHT_RU_726: + return ATH12K_EHT_RU_484_242; + case HAL_EHT_RU_996: + return ATH12K_EHT_RU_996; + case HAL_EHT_RU_996x2: + return ATH12K_EHT_RU_996x2; + case HAL_EHT_RU_996x3: + return ATH12K_EHT_RU_996x3; + case HAL_EHT_RU_996x4: + return ATH12K_EHT_RU_996x4; + case HAL_EHT_RU_NONE: + return ATH12K_EHT_RU_INVALID; + case HAL_EHT_RU_996_484: + return ATH12K_EHT_RU_996_484; + case HAL_EHT_RU_996x2_484: + return ATH12K_EHT_RU_996x2_484; + case HAL_EHT_RU_996x3_484: + return ATH12K_EHT_RU_996x3_484; + case HAL_EHT_RU_996_484_242: + return ATH12K_EHT_RU_996_484_242; + default: + return ATH12K_EHT_RU_INVALID; + } +} + +static inline u32 +hal_rx_ul_ofdma_ru_size_to_width(enum ath12k_eht_ru_size ru_size) +{ + switch (ru_size) { + case ATH12K_EHT_RU_26: + return RU_26; + case ATH12K_EHT_RU_52: + return RU_52; + case ATH12K_EHT_RU_52_26: + return RU_52_26; + case ATH12K_EHT_RU_106: + return RU_106; + case ATH12K_EHT_RU_106_26: + return RU_106_26; + case ATH12K_EHT_RU_242: + return RU_242; + case ATH12K_EHT_RU_484: + return RU_484; + case ATH12K_EHT_RU_484_242: + return RU_484_242; + case ATH12K_EHT_RU_996: + return RU_996; + case ATH12K_EHT_RU_996_484: + return RU_996_484; + case ATH12K_EHT_RU_996_484_242: + return RU_996_484_242; + case ATH12K_EHT_RU_996x2: + return RU_2X996; + case ATH12K_EHT_RU_996x2_484: + return RU_2X996_484; + case ATH12K_EHT_RU_996x3: + return RU_3X996; + case ATH12K_EHT_RU_996x3_484: + return RU_3X996_484; + case ATH12K_EHT_RU_996x4: + return RU_4X996; + default: + return RU_INVALID; + } +} + +static void +ath12k_wifi7_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_info, + u16 user_id, + struct hal_rx_mon_ppdu_info *ppdu_info) +{ + struct hal_rx_user_status *mon_rx_user_status = NULL; + struct hal_rx_radiotap_eht *eht = &ppdu_info->eht_info.eht; + enum ath12k_eht_ru_size rtap_ru_size = ATH12K_EHT_RU_INVALID; + u32 ru_width, reception_type, ru_index = HAL_EHT_RU_INVALID; + u32 ru_type_80_0, ru_start_index_80_0; + u32 ru_type_80_1, ru_start_index_80_1; + u32 ru_type_80_2, ru_start_index_80_2; + u32 ru_type_80_3, ru_start_index_80_3; + u32 ru_size = 0, num_80mhz_with_ru = 0; + u64 ru_index_320mhz = 0; + u32 ru_index_per80mhz; + + reception_type = le32_get_bits(rx_usr_info->info0, + HAL_RX_USR_INFO0_RECEPTION_TYPE); + + switch (reception_type) { + case HAL_RECEPTION_TYPE_SU: + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; + break; + case HAL_RECEPTION_TYPE_DL_MU_MIMO: + case HAL_RECEPTION_TYPE_UL_MU_MIMO: + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO; + break; + case HAL_RECEPTION_TYPE_DL_MU_OFMA: + case HAL_RECEPTION_TYPE_UL_MU_OFDMA: + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA; + break; + case HAL_RECEPTION_TYPE_DL_MU_OFDMA_MIMO: + case HAL_RECEPTION_TYPE_UL_MU_OFDMA_MIMO: + ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO; + } + + ppdu_info->is_stbc = le32_get_bits(rx_usr_info->info0, HAL_RX_USR_INFO0_STBC); + ppdu_info->ldpc = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_LDPC); + ppdu_info->dcm = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_STA_DCM); + ppdu_info->bw = le32_get_bits(rx_usr_info->info1, HAL_RX_USR_INFO1_RX_BW); + ppdu_info->mcs = le32_get_bits(rx_usr_info->info1, HAL_RX_USR_INFO1_MCS); + ppdu_info->nss = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_NSS) + 1; + + if (user_id < HAL_MAX_UL_MU_USERS) { + mon_rx_user_status = &ppdu_info->userstats[user_id]; + mon_rx_user_status->mcs = ppdu_info->mcs; + mon_rx_user_status->nss = ppdu_info->nss; + } + + if (!(ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_MIMO || + ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA || + ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO)) + return; + + /* RU allocation present only for OFDMA reception */ + ru_type_80_0 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_0); + ru_start_index_80_0 = le32_get_bits(rx_usr_info->info3, + HAL_RX_USR_INFO3_RU_START_IDX_80_0); + if (ru_type_80_0 != HAL_EHT_RU_NONE) { + ru_size += ru_type_80_0; + ru_index_per80mhz = ru_start_index_80_0; + ru_index = ru_index_per80mhz; + ru_index_320mhz |= HAL_RU_PER80(ru_type_80_0, 0, ru_index_per80mhz); + num_80mhz_with_ru++; + } + + ru_type_80_1 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_1); + ru_start_index_80_1 = le32_get_bits(rx_usr_info->info3, + HAL_RX_USR_INFO3_RU_START_IDX_80_1); + if (ru_type_80_1 != HAL_EHT_RU_NONE) { + ru_size += ru_type_80_1; + ru_index_per80mhz = ru_start_index_80_1; + ru_index = ru_index_per80mhz; + ru_index_320mhz |= HAL_RU_PER80(ru_type_80_1, 1, ru_index_per80mhz); + num_80mhz_with_ru++; + } + + ru_type_80_2 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_2); + ru_start_index_80_2 = le32_get_bits(rx_usr_info->info3, + HAL_RX_USR_INFO3_RU_START_IDX_80_2); + if (ru_type_80_2 != HAL_EHT_RU_NONE) { + ru_size += ru_type_80_2; + ru_index_per80mhz = ru_start_index_80_2; + ru_index = ru_index_per80mhz; + ru_index_320mhz |= HAL_RU_PER80(ru_type_80_2, 2, ru_index_per80mhz); + num_80mhz_with_ru++; + } + + ru_type_80_3 = le32_get_bits(rx_usr_info->info2, HAL_RX_USR_INFO2_RU_TYPE_80_3); + ru_start_index_80_3 = le32_get_bits(rx_usr_info->info2, + HAL_RX_USR_INFO3_RU_START_IDX_80_3); + if (ru_type_80_3 != HAL_EHT_RU_NONE) { + ru_size += ru_type_80_3; + ru_index_per80mhz = ru_start_index_80_3; + ru_index = ru_index_per80mhz; + ru_index_320mhz |= HAL_RU_PER80(ru_type_80_3, 3, ru_index_per80mhz); + num_80mhz_with_ru++; + } + + if (num_80mhz_with_ru > 1) { + /* Calculate the MRU index */ + switch (ru_index_320mhz) { + case HAL_EHT_RU_996_484_0: + case HAL_EHT_RU_996x2_484_0: + case HAL_EHT_RU_996x3_484_0: + ru_index = 0; + break; + case HAL_EHT_RU_996_484_1: + case HAL_EHT_RU_996x2_484_1: + case HAL_EHT_RU_996x3_484_1: + ru_index = 1; + break; + case HAL_EHT_RU_996_484_2: + case HAL_EHT_RU_996x2_484_2: + case HAL_EHT_RU_996x3_484_2: + ru_index = 2; + break; + case HAL_EHT_RU_996_484_3: + case HAL_EHT_RU_996x2_484_3: + case HAL_EHT_RU_996x3_484_3: + ru_index = 3; + break; + case HAL_EHT_RU_996_484_4: + case HAL_EHT_RU_996x2_484_4: + case HAL_EHT_RU_996x3_484_4: + ru_index = 4; + break; + case HAL_EHT_RU_996_484_5: + case HAL_EHT_RU_996x2_484_5: + case HAL_EHT_RU_996x3_484_5: + ru_index = 5; + break; + case HAL_EHT_RU_996_484_6: + case HAL_EHT_RU_996x2_484_6: + case HAL_EHT_RU_996x3_484_6: + ru_index = 6; + break; + case HAL_EHT_RU_996_484_7: + case HAL_EHT_RU_996x2_484_7: + case HAL_EHT_RU_996x3_484_7: + ru_index = 7; + break; + case HAL_EHT_RU_996x2_484_8: + ru_index = 8; + break; + case HAL_EHT_RU_996x2_484_9: + ru_index = 9; + break; + case HAL_EHT_RU_996x2_484_10: + ru_index = 10; + break; + case HAL_EHT_RU_996x2_484_11: + ru_index = 11; + break; + default: + ru_index = HAL_EHT_RU_INVALID; + break; + } + + ru_size += 4; + } + + rtap_ru_size = hal_rx_mon_hal_ru_size_to_ath12k_ru_size(ru_size); + if (rtap_ru_size != ATH12K_EHT_RU_INVALID) { + u32 known, data; + + known = __le32_to_cpu(eht->known); + known |= IEEE80211_RADIOTAP_EHT_KNOWN_RU_MRU_SIZE_OM; + eht->known = cpu_to_le32(known); + + data = __le32_to_cpu(eht->data[1]); + data |= u32_encode_bits(rtap_ru_size, + IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE); + eht->data[1] = cpu_to_le32(data); + } + + if (ru_index != HAL_EHT_RU_INVALID) { + u32 known, data; + + known = __le32_to_cpu(eht->known); + known |= IEEE80211_RADIOTAP_EHT_KNOWN_RU_MRU_INDEX_OM; + eht->known = cpu_to_le32(known); + + data = __le32_to_cpu(eht->data[1]); + data |= u32_encode_bits(rtap_ru_size, + IEEE80211_RADIOTAP_EHT_DATA1_RU_INDEX); + eht->data[1] = cpu_to_le32(data); + } + + if (mon_rx_user_status && ru_index != HAL_EHT_RU_INVALID && + rtap_ru_size != ATH12K_EHT_RU_INVALID) { + mon_rx_user_status->ul_ofdma_ru_start_index = ru_index; + mon_rx_user_status->ul_ofdma_ru_size = rtap_ru_size; + + ru_width = hal_rx_ul_ofdma_ru_size_to_width(rtap_ru_size); + + mon_rx_user_status->ul_ofdma_ru_width = ru_width; + mon_rx_user_status->ofdma_info_valid = 1; + } +} + static void ath12k_wifi7_dp_mon_parse_l_sig_b(const struct hal_rx_lsig_b_info *lsigb, struct hal_rx_mon_ppdu_info *ppdu_info) @@ -1196,9 +1544,9 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, ppdu_info->num_users += 1; - ath12k_dp_mon_rx_handle_ofdma_info(eu_stats, rxuser_stats); - ath12k_dp_mon_rx_populate_mu_user_info(eu_stats, ppdu_info, - rxuser_stats); + ath12k_wifi7_dp_mon_rx_handle_ofdma_info(eu_stats, rxuser_stats); + ath12k_wifi7_dp_mon_rx_populate_mu_user_info(eu_stats, ppdu_info, + rxuser_stats); } ppdu_info->mpdu_fcs_ok_bitmap[0] = __le32_to_cpu(eu_stats->rsvd1[0]); ppdu_info->mpdu_fcs_ok_bitmap[1] = __le32_to_cpu(eu_stats->rsvd1[1]); @@ -1277,7 +1625,7 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, break; } case HAL_RX_PPDU_START_USER_INFO: - ath12k_dp_mon_hal_rx_parse_user_info(tlv_data, userid, ppdu_info); + ath12k_wifi7_dp_mon_hal_rx_parse_user_info(tlv_data, userid, ppdu_info); break; case HAL_RXPCU_PPDU_END_INFO: { From f34f5df209af5d8a3240bc9de8c21d1f0374578c Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:12 +0530 Subject: [PATCH 109/140] wifi: ath12k: Move MSDU END TLV processing to Wi-Fi 7 module Separate Wi-Fi 7-specific monitor handling from ath12k common code to improve modularity. Move the following MSDU END TLV processing functions into wifi7/dp_mon.c and rename them with the ath12k_wifi7_ prefix: - ath12k_dp_mon_parse_rx_msdu_end_err() - ath12k_dp_mon_parse_status_msdu_end() - ath12k_dp_mon_next_link_desc_get() Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-12-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 50 ---------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 9 --- .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 58 +++++++++++++++++-- 3 files changed, 54 insertions(+), 63 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index c5c1f4b19b513..e96a9bbd857b3 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -11,41 +11,6 @@ #include "dp_tx.h" #include "peer.h" -static void ath12k_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap) -{ - if (info & RX_MSDU_END_INFO13_FCS_ERR) - *errmap |= HAL_RX_MPDU_ERR_FCS; - - if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) - *errmap |= HAL_RX_MPDU_ERR_DECRYPT; - - if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) - *errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; - - if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) - *errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; - - if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) - *errmap |= HAL_RX_MPDU_ERR_OVERFLOW; - - if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) - *errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; - - if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) - *errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; -} - -void -ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, - const struct hal_rx_msdu_end *msdu_end) -{ - ath12k_dp_mon_parse_rx_msdu_end_err(__le32_to_cpu(msdu_end->info2), - &pmon->err_bitmap); - pmon->decap_format = le32_get_bits(msdu_end->info1, - RX_MSDU_END_INFO11_DECAP_FORMAT); -} -EXPORT_SYMBOL(ath12k_dp_mon_parse_status_msdu_end); - static void ath12k_dp_mon_fill_rx_stats_info(struct hal_rx_mon_ppdu_info *ppdu_info, struct ieee80211_rx_status *rx_status) @@ -139,21 +104,6 @@ u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id) } EXPORT_SYMBOL(ath12k_dp_mon_comp_ppduid); -void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, - struct hal_rx_msdu_link *msdu_link, - dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm, - struct ath12k_buffer_addr **pp_buf_addr_info) -{ - struct ath12k_buffer_addr *buf_addr_info; - - buf_addr_info = &msdu_link->buf_addr_info; - - ath12k_hal_rx_buf_addr_info_get(&ab->hal, buf_addr_info, paddr, sw_cookie, rbm); - - *pp_buf_addr_info = buf_addr_info; -} -EXPORT_SYMBOL(ath12k_dp_mon_next_link_desc_get); - static void ath12k_dp_mon_fill_rx_rate(struct ath12k_pdev_dp *dp_pdev, struct hal_rx_mon_ppdu_info *ppdu_info, diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index 6dac4e9569b6e..f5debe947ad69 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -8,8 +8,6 @@ #define ATH12K_DP_MON_H #include "core.h" -#include "wifi7/hal_desc.h" -#include "wifi7/hal_rx.h" #define ATH12K_MON_RX_DOT11_OFFSET 5 #define ATH12K_MON_RX_PKT_OFFSET 8 @@ -110,16 +108,9 @@ void ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, bool *is_frag, u32 *total_len, u32 *frag_len, u32 *msdu_cnt); -void ath12k_dp_mon_next_link_desc_get(struct ath12k_base *ab, - struct hal_rx_msdu_link *msdu_link, - dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm, - struct ath12k_buffer_addr **pp_buf_addr_info); u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id); int ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct dp_mon_packet_info *packet_info); -void -ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, - const struct hal_rx_msdu_end *msdu_end); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 8d913d09f8826..6d829d3e1b0c9 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -1425,6 +1425,40 @@ ath12k_wifi7_dp_mon_parse_eht_sig_hdr(struct hal_rx_mon_ppdu_info *ppdu_info, ath12k_wifi7_dp_mon_hal_rx_parse_eht_sig_ofdma(tlv_data, ppdu_info); } +static void ath12k_wifi7_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap) +{ + if (info & RX_MSDU_END_INFO13_FCS_ERR) + *errmap |= HAL_RX_MPDU_ERR_FCS; + + if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) + *errmap |= HAL_RX_MPDU_ERR_DECRYPT; + + if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) + *errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; + + if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) + *errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; + + if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) + *errmap |= HAL_RX_MPDU_ERR_OVERFLOW; + + if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) + *errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; + + if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) + *errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; +} + +static void +ath12k_wifi7_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon, + const struct hal_rx_msdu_end *msdu_end) +{ + ath12k_wifi7_dp_mon_parse_rx_msdu_end_err(__le32_to_cpu(msdu_end->info2), + &pmon->err_bitmap); + pmon->decap_format = le32_get_bits(msdu_end->info1, + RX_MSDU_END_INFO11_DECAP_FORMAT); +} + static enum hal_rx_mon_status ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, @@ -1665,7 +1699,7 @@ ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev, case HAL_MON_BUF_ADDR: return HAL_RX_MON_STATUS_BUF_ADDR; case HAL_RX_MSDU_END: - ath12k_dp_mon_parse_status_msdu_end(pmon, tlv_data); + ath12k_wifi7_dp_mon_parse_status_msdu_end(pmon, tlv_data); return HAL_RX_MON_STATUS_MSDU_END; case HAL_RX_MPDU_END: return HAL_RX_MON_STATUS_MPDU_END; @@ -2417,6 +2451,21 @@ ath12k_wifi7_dp_mon_tx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, return tlv_status; } +static void +ath12k_wifi7_dp_mon_next_link_desc_get(struct ath12k_base *ab, + struct hal_rx_msdu_link *msdu_link, + dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm, + struct ath12k_buffer_addr **pp_buf_addr_info) +{ + struct ath12k_buffer_addr *buf_addr_info; + + buf_addr_info = &msdu_link->buf_addr_info; + + ath12k_wifi7_hal_rx_buf_addr_info_get(buf_addr_info, paddr, sw_cookie, rbm); + + *pp_buf_addr_info = buf_addr_info; +} + static u32 ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, void *ring_entry, struct sk_buff **head_msdu, @@ -2583,9 +2632,10 @@ ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, ath12k_wifi7_hal_rx_buf_addr_info_set(&buf_info, paddr, sw_cookie, rbm); - ath12k_dp_mon_next_link_desc_get(ab, msdu_link_desc, &paddr, - &sw_cookie, &rbm, - &p_buf_addr_info); + ath12k_wifi7_dp_mon_next_link_desc_get(ab, + msdu_link_desc, &paddr, + &sw_cookie, &rbm, + &p_buf_addr_info); ath12k_dp_arch_rx_link_desc_return(ar->ab->dp, &buf_info, HAL_WBM_REL_BM_ACT_PUT_IN_IDLE); From a6ae2f08e65de7fee5e893a637075ebddaf1e993 Mon Sep 17 00:00:00 2001 From: Alok Singh Date: Mon, 10 Nov 2025 16:07:13 +0530 Subject: [PATCH 110/140] wifi: ath12k: Remove Wi-Fi 7 header dependencies from common ath12k module Remove all remaining Wi-Fi 7 header dependencies from dp_mon.c to finalize separation of Wi-Fi 7 specific monitor mode functionality. Remove these includes from dp_mon.c: - wifi7/hal_desc.h - wifi7/hal_qcn9274.h - wifi7/dp_rx.h Relocate hal_mon_buf_ring from wifi7/hal_desc.h to hal.h. Relocate HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID and HAL_RX_FCS_LEN macros from wifi7/hal_rx.h to hal.h or dp_rx.h as appropriate. Move the following functions to the new file wifi7/dp_mon.c and add the ath12k_wifi7 prefix: - ath12k_dp_mon_rx_merg_msdus() - ath12k_dp_mon_update_radiotap() - ath12k_dp_mon_rx_deliver_msdu() - ath12k_dp_mon_get_buf_len() - ath12k_dp_mon_rx_deliver() Export several helper functions needed by the ath12k_wifi7 module. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Alok Singh Reviewed-by: Vasanthakumar Thiagarajan Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20251110103713.3484779-13-quic_aloksing@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_mon.c | 111 +++--------------- drivers/net/wireless/ath/ath12k/dp_mon.h | 27 +++-- drivers/net/wireless/ath/ath12k/dp_rx.h | 9 ++ drivers/net/wireless/ath/ath12k/hal.h | 28 +++++ .../net/wireless/ath/ath12k/wifi7/dp_mon.c | 99 ++++++++++++++-- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 8 +- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 8 -- .../net/wireless/ath/ath12k/wifi7/hal_desc.h | 19 --- .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 10 -- 9 files changed, 165 insertions(+), 154 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index e96a9bbd857b3..91c800ad51dfc 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -6,8 +6,6 @@ #include "dp_mon.h" #include "debug.h" -#include "wifi7/hal_qcn9274.h" -#include "wifi7/dp_rx.h" #include "dp_tx.h" #include "peer.h" @@ -205,7 +203,7 @@ static void ath12k_dp_mon_rx_msdus_set_payload(struct ath12k_base *ab, skb_pull(head_msdu, total_offset); } -static struct sk_buff * +struct sk_buff * ath12k_dp_mon_rx_merg_msdus(struct ath12k_pdev_dp *dp_pdev, struct dp_mon_mpdu *mon_mpdu, struct hal_rx_mon_ppdu_info *ppdu_info, @@ -333,6 +331,7 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k_pdev_dp *dp_pdev, } return NULL; } +EXPORT_SYMBOL(ath12k_dp_mon_rx_merg_msdus); static void ath12k_dp_mon_rx_update_radiotap_he(struct hal_rx_mon_ppdu_info *rx_status, @@ -382,10 +381,10 @@ ath12k_dp_mon_rx_update_radiotap_he_mu(struct hal_rx_mon_ppdu_info *rx_status, rtap_buf[rtap_len] = rx_status->he_RU[3]; } -static void ath12k_dp_mon_update_radiotap(struct ath12k_pdev_dp *dp_pdev, - struct hal_rx_mon_ppdu_info *ppduinfo, - struct sk_buff *mon_skb, - struct ieee80211_rx_status *rxs) +void ath12k_dp_mon_update_radiotap(struct ath12k_pdev_dp *dp_pdev, + struct hal_rx_mon_ppdu_info *ppduinfo, + struct sk_buff *mon_skb, + struct ieee80211_rx_status *rxs) { struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev); struct ieee80211_supported_band *sband; @@ -491,13 +490,13 @@ static void ath12k_dp_mon_update_radiotap(struct ath12k_pdev_dp *dp_pdev, rxs->mactime = ppduinfo->tsft; } +EXPORT_SYMBOL(ath12k_dp_mon_update_radiotap); -static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, - struct napi_struct *napi, - struct sk_buff *msdu, - const struct hal_rx_mon_ppdu_info *ppduinfo, - struct ieee80211_rx_status *status, - u8 decap) +void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, + struct napi_struct *napi, + struct sk_buff *msdu, + struct ieee80211_rx_status *status, + u8 decap) { struct ath12k_dp *dp = dp_pdev->dp; struct ath12k_base *ab = dp->ab; @@ -526,7 +525,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, status->flag |= RX_FLAG_RADIOTAP_HE; } - ath12k_wifi7_dp_extract_rx_desc_data(dp->hal, &rx_info, rx_desc, rx_desc); + ath12k_dp_extract_rx_desc_data(dp->hal, &rx_info, rx_desc, rx_desc); rcu_read_lock(); spin_lock_bh(&dp->dp_lock); @@ -586,62 +585,7 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, ieee80211_rx_napi(ath12k_pdev_dp_to_hw(dp_pdev), pubsta, msdu, napi); } - -int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, - struct dp_mon_mpdu *mon_mpdu, - struct hal_rx_mon_ppdu_info *ppduinfo, - struct napi_struct *napi) -{ - struct sk_buff *mon_skb, *skb_next, *header; - struct ieee80211_rx_status *rxs = &dp_pdev->rx_status; - u8 decap = DP_RX_DECAP_TYPE_RAW; - - mon_skb = ath12k_dp_mon_rx_merg_msdus(dp_pdev, mon_mpdu, ppduinfo, rxs); - if (!mon_skb) - goto mon_deliver_fail; - - header = mon_skb; - rxs->flag = 0; - - if (mon_mpdu->err_bitmap & HAL_RX_MPDU_ERR_FCS) - rxs->flag = RX_FLAG_FAILED_FCS_CRC; - - do { - skb_next = mon_skb->next; - if (!skb_next) - rxs->flag &= ~RX_FLAG_AMSDU_MORE; - else - rxs->flag |= RX_FLAG_AMSDU_MORE; - - if (mon_skb == header) { - header = NULL; - rxs->flag &= ~RX_FLAG_ALLOW_SAME_PN; - } else { - rxs->flag |= RX_FLAG_ALLOW_SAME_PN; - } - rxs->flag |= RX_FLAG_ONLY_MONITOR; - - if (!(rxs->flag & RX_FLAG_ONLY_MONITOR)) - decap = mon_mpdu->decap_format; - - ath12k_dp_mon_update_radiotap(dp_pdev, ppduinfo, mon_skb, rxs); - ath12k_dp_mon_rx_deliver_msdu(dp_pdev, napi, mon_skb, rxs, decap); - mon_skb = skb_next; - } while (mon_skb); - rxs->flag = 0; - - return 0; - -mon_deliver_fail: - mon_skb = mon_mpdu->head; - while (mon_skb) { - skb_next = mon_skb->next; - dev_kfree_skb_any(mon_skb); - mon_skb = skb_next; - } - return -EINVAL; -} -EXPORT_SYMBOL(ath12k_dp_mon_rx_deliver); +EXPORT_SYMBOL(ath12k_dp_mon_rx_deliver_msdu); int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len) { @@ -662,33 +606,6 @@ int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len) } EXPORT_SYMBOL(ath12k_dp_pkt_set_pktlen); -/* Hardware fill buffer with 128 bytes aligned. So need to reap it - * with 128 bytes aligned. - */ -#define RXDMA_DATA_DMA_BLOCK_SIZE 128 - -void -ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, - bool *is_frag, u32 *total_len, - u32 *frag_len, u32 *msdu_cnt) -{ - if (info->msdu_flags & RX_MSDU_DESC_INFO0_MSDU_CONTINUATION) { - *is_frag = true; - *frag_len = (RX_MON_STATUS_BASE_BUF_SIZE - - sizeof(struct hal_rx_desc)) & - ~(RXDMA_DATA_DMA_BLOCK_SIZE - 1); - *total_len += *frag_len; - } else { - if (*is_frag) - *frag_len = info->msdu_len - *total_len; - else - *frag_len = info->msdu_len; - - *msdu_cnt -= 1; - } -} -EXPORT_SYMBOL(ath12k_dp_mon_get_buf_len); - int ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.h b/drivers/net/wireless/ath/ath12k/dp_mon.h index f5debe947ad69..394463ea19e0b 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.h +++ b/drivers/net/wireless/ath/ath12k/dp_mon.h @@ -96,21 +96,32 @@ ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k_base *ab, void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k_dp_link_peer *peer, struct hal_rx_mon_ppdu_info *ppdu_info); int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len); -int ath12k_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, - struct dp_mon_mpdu *mon_mpdu, - struct hal_rx_mon_ppdu_info *ppduinfo, - struct napi_struct *napi); struct sk_buff *ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab, struct dp_rxdma_mon_ring *rx_ring, int *buf_id); -void -ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, - bool *is_frag, u32 *total_len, - u32 *frag_len, u32 *msdu_cnt); u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id); int ath12k_dp_mon_parse_status_buf(struct ath12k_pdev_dp *dp_pdev, struct ath12k_mon_data *pmon, const struct dp_mon_packet_info *packet_info); +void ath12k_dp_mon_update_radiotap(struct ath12k_pdev_dp *dp_pdev, + struct hal_rx_mon_ppdu_info *ppduinfo, + struct sk_buff *mon_skb, + struct ieee80211_rx_status *rxs); +void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, + struct napi_struct *napi, + struct sk_buff *msdu, + struct ieee80211_rx_status *status, + u8 decap); +void ath12k_dp_mon_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, + struct napi_struct *napi, + struct sk_buff *msdu, + struct ieee80211_rx_status *status, + u8 decap); +struct sk_buff * +ath12k_dp_mon_rx_merg_msdus(struct ath12k_pdev_dp *dp_pdev, + struct dp_mon_mpdu *mon_mpdu, + struct hal_rx_mon_ppdu_info *ppdu_info, + struct ieee80211_rx_status *rxs); #endif diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 916cf41aa5c31..8d045f71e955e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -179,6 +179,15 @@ static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) dev_kfree_skb_any(skb); } +static inline +void ath12k_dp_extract_rx_desc_data(struct ath12k_hal *hal, + struct hal_rx_desc_data *rx_info, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc *ldesc) +{ + hal->ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); +} + void ath12k_dp_rx_h_undecap(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu, struct hal_rx_desc *rx_desc, enum hal_encrypt_type enctype, diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 1d22173975f0f..ce038906bd069 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -73,6 +73,16 @@ struct ath12k_base; #define HAL_RX_MAX_NSS 8 #define HAL_RX_MAX_NUM_LEGACY_RATES 12 +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID BIT(30) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER BIT(31) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS GENMASK(2, 0) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS GENMASK(6, 3) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_LDPC BIT(7) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_DCM BIT(8) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START GENMASK(15, 9) +#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE GENMASK(18, 16) +#define HAL_RX_FCS_LEN 4 + enum hal_srng_ring_id { HAL_SRNG_RING_ID_REO2SW0 = 0, HAL_SRNG_RING_ID_REO2SW1, @@ -597,6 +607,24 @@ struct hal_rx_msdu_desc_info { u16 msdu_len; /* 14 bits for length */ }; +/* hal_mon_buf_ring + * Producer : SW + * Consumer : Monitor + * + * paddr_lo + * Lower 32-bit physical address of the buffer pointer from the source ring. + * paddr_hi + * bit range 7-0 : upper 8 bit of the physical address. + * bit range 31-8 : reserved. + * cookie + * Consumer: RxMon/TxMon 64 bit cookie of the buffers. + */ +struct hal_mon_buf_ring { + __le32 paddr_lo; + __le32 paddr_hi; + __le64 cookie; +}; + struct hal_rx_mon_ppdu_info { u32 ppdu_id; u32 last_ppdu_id; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index 6d829d3e1b0c9..9878553289c47 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -31,6 +31,32 @@ ath12k_wifi7_dp_mon_rx_memset_ppdu_info(struct hal_rx_mon_ppdu_info *ppdu_info) ppdu_info->peer_id = HAL_INVALID_PEERID; } +/* Hardware fill buffer with 128 bytes aligned. So need to reap it + * with 128 bytes aligned. + */ +#define RXDMA_DATA_DMA_BLOCK_SIZE 128 + +static void +ath12k_wifi7_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info, + bool *is_frag, u32 *total_len, + u32 *frag_len, u32 *msdu_cnt) +{ + if (info->msdu_flags & RX_MSDU_DESC_INFO0_MSDU_CONTINUATION) { + *is_frag = true; + *frag_len = (RX_MON_STATUS_BASE_BUF_SIZE - + sizeof(struct hal_rx_desc)) & + ~(RXDMA_DATA_DMA_BLOCK_SIZE - 1); + *total_len += *frag_len; + } else { + if (*is_frag) + *frag_len = info->msdu_len - *total_len; + else + *frag_len = info->msdu_len; + + *msdu_cnt -= 1; + } +} + static void ath12k_wifi7_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user, struct hal_rx_user_status *rx_user_status) @@ -2373,6 +2399,62 @@ ath12k_wifi7_dp_mon_tx_status_get_num_user(u16 tlv_tag, return tlv_status; } +static int +ath12k_wifi7_dp_mon_rx_deliver(struct ath12k_pdev_dp *dp_pdev, + struct dp_mon_mpdu *mon_mpdu, + struct hal_rx_mon_ppdu_info *ppduinfo, + struct napi_struct *napi) +{ + struct sk_buff *mon_skb, *skb_next, *header; + struct ieee80211_rx_status *rxs = &dp_pdev->rx_status; + u8 decap = DP_RX_DECAP_TYPE_RAW; + + mon_skb = ath12k_dp_mon_rx_merg_msdus(dp_pdev, mon_mpdu, ppduinfo, rxs); + if (!mon_skb) + goto mon_deliver_fail; + + header = mon_skb; + rxs->flag = 0; + + if (mon_mpdu->err_bitmap & HAL_RX_MPDU_ERR_FCS) + rxs->flag = RX_FLAG_FAILED_FCS_CRC; + + do { + skb_next = mon_skb->next; + if (!skb_next) + rxs->flag &= ~RX_FLAG_AMSDU_MORE; + else + rxs->flag |= RX_FLAG_AMSDU_MORE; + + if (mon_skb == header) { + header = NULL; + rxs->flag &= ~RX_FLAG_ALLOW_SAME_PN; + } else { + rxs->flag |= RX_FLAG_ALLOW_SAME_PN; + } + rxs->flag |= RX_FLAG_ONLY_MONITOR; + + if (!(rxs->flag & RX_FLAG_ONLY_MONITOR)) + decap = mon_mpdu->decap_format; + + ath12k_dp_mon_update_radiotap(dp_pdev, ppduinfo, mon_skb, rxs); + ath12k_dp_mon_rx_deliver_msdu(dp_pdev, napi, mon_skb, rxs, decap); + mon_skb = skb_next; + } while (mon_skb); + rxs->flag = 0; + + return 0; + +mon_deliver_fail: + mon_skb = mon_mpdu->head; + while (mon_skb) { + skb_next = mon_skb->next; + dev_kfree_skb_any(mon_skb); + mon_skb = skb_next; + } + return -EINVAL; +} + static void ath12k_wifi7_dp_mon_tx_process_ppdu_info(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi, @@ -2385,8 +2467,8 @@ ath12k_wifi7_dp_mon_tx_process_ppdu_info(struct ath12k_pdev_dp *dp_pdev, list_del(&mon_mpdu->list); if (mon_mpdu->head) - ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, - &tx_ppdu_info->rx_status, napi); + ath12k_wifi7_dp_mon_rx_deliver(dp_pdev, mon_mpdu, + &tx_ppdu_info->rx_status, napi); kfree(mon_mpdu); } @@ -2606,9 +2688,9 @@ ath12k_wifi7_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id, pmon->mon_last_linkdesc_paddr = paddr; is_first_msdu = false; } - ath12k_dp_mon_get_buf_len(&msdu_list.msdu_info[i], - &is_frag, &total_len, - &frag_len, &msdu_cnt); + ath12k_wifi7_dp_mon_get_buf_len(&msdu_list.msdu_info[i], + &is_frag, &total_len, + &frag_len, &msdu_cnt); rx_buf_size = rx_pkt_offset + l2_hdr_offset + frag_len; if (ath12k_dp_pkt_set_pktlen(msdu, rx_buf_size)) { @@ -2748,8 +2830,8 @@ ath12k_wifi7_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, tmp_mpdu->tail = tail_msdu; tmp_mpdu->err_bitmap = pmon->err_bitmap; tmp_mpdu->decap_format = pmon->decap_format; - ath12k_dp_mon_rx_deliver(&ar->dp, tmp_mpdu, - &pmon->mon_ppdu_info, napi); + ath12k_wifi7_dp_mon_rx_deliver(&ar->dp, tmp_mpdu, + &pmon->mon_ppdu_info, napi); rx_mon_stats->dest_mpdu_done++; kfree(tmp_mpdu); } @@ -2883,7 +2965,8 @@ ath12k_wifi7_dp_mon_rx_parse_mon_status(struct ath12k_pdev_dp *dp_pdev, list_del(&mon_mpdu->list); if (mon_mpdu->head && mon_mpdu->tail) - ath12k_dp_mon_rx_deliver(dp_pdev, mon_mpdu, ppdu_info, napi); + ath12k_wifi7_dp_mon_rx_deliver(dp_pdev, mon_mpdu, + ppdu_info, napi); kfree(mon_mpdu); } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 08dcf170b801d..af50dafc03499 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -524,7 +524,7 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k_pdev_dp *dp_pdev, rx_desc = (struct hal_rx_desc *)msdu->data; lrx_desc = (struct hal_rx_desc *)last_buf->data; - ath12k_wifi7_dp_extract_rx_desc_data(hal, rx_info, rx_desc, lrx_desc); + ath12k_dp_extract_rx_desc_data(hal, rx_info, rx_desc, lrx_desc); if (!rx_info->msdu_done) { ath12k_warn(dp->ab, "msdu_done bit in msdu_end is not set\n"); ret = -EIO; @@ -1035,7 +1035,7 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev, (ATH12K_SKB_RXCB(msdu))->is_first_msdu = true; (ATH12K_SKB_RXCB(msdu))->is_last_msdu = true; - ath12k_wifi7_dp_extract_rx_desc_data(hal, rx_info, rx_desc, rx_desc); + ath12k_dp_extract_rx_desc_data(hal, rx_info, rx_desc, rx_desc); rxs->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_MMIC_STRIPPED | RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED; @@ -1333,7 +1333,7 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, } rx_desc = (struct hal_rx_desc *)msdu->data; - ath12k_wifi7_dp_extract_rx_desc_data(hal, &rx_info, rx_desc, rx_desc); + ath12k_dp_extract_rx_desc_data(hal, &rx_info, rx_desc, rx_desc); msdu_len = rx_info.msdu_len; if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { @@ -1714,7 +1714,7 @@ static void ath12k_wifi7_dp_rx_wbm_err(struct ath12k_pdev_dp *dp_pdev, rx_info.addr2_present = false; rx_info.rx_status = &rxs; - ath12k_wifi7_dp_extract_rx_desc_data(dp->hal, &rx_info, rx_desc, rx_desc); + ath12k_dp_extract_rx_desc_data(dp->hal, &rx_info, rx_desc, rx_desc); switch (rxcb->err_rel_src) { case HAL_WBM_REL_SRC_MODULE_REO: diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index 2d3eb2313b2f7..d15bffe223c7d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -52,12 +52,4 @@ int ath12k_wifi7_peer_rx_tid_reo_update(struct ath12k_dp *dp, bool ath12k_wifi7_dp_rxdesc_mpdu_valid(struct ath12k_base *ab, struct hal_rx_desc *rx_desc); -static inline -void ath12k_wifi7_dp_extract_rx_desc_data(struct ath12k_hal *hal, - struct hal_rx_desc_data *rx_info, - struct hal_rx_desc *rx_desc, - struct hal_rx_desc *ldesc) -{ - hal->ops->extract_rx_desc_data(rx_info, rx_desc, ldesc); -} #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h index 4a249ba7357d1..9dad8f7ca9f21 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h @@ -2682,25 +2682,6 @@ struct hal_tcl_entrance_from_ppe_ring { __le32 info0; } __packed; -struct hal_mon_buf_ring { - __le32 paddr_lo; - __le32 paddr_hi; - __le64 cookie; -}; - -/* hal_mon_buf_ring - * Producer : SW - * Consumer : Monitor - * - * paddr_lo - * Lower 32-bit physical address of the buffer pointer from the source ring. - * paddr_hi - * bit range 7-0 : upper 8 bit of the physical address. - * bit range 31-8 : reserved. - * cookie - * Consumer: RxMon/TxMon 64 bit cookie of the buffers. - */ - #define HAL_MON_DEST_COOKIE_BUF_ID GENMASK(17, 0) #define HAL_MON_DEST_INFO0_END_OFFSET GENMASK(11, 0) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index 4a0beb4d192ef..1f2cfba3aac1c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -45,7 +45,6 @@ struct hal_rx_mon_status_tlv_hdr { #define HAL_TLV_STATUS_PPDU_DONE 1 #define HAL_TLV_STATUS_BUF_DONE 2 #define HAL_TLV_STATUS_PPDU_NON_STD_DONE 3 -#define HAL_RX_FCS_LEN 4 enum hal_rx_mon_status { HAL_RX_MON_STATUS_PPDU_NOT_DONE, @@ -366,15 +365,6 @@ struct hal_rx_resp_req_info { #define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2 0xBDBEEF #define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3 0xCDBEEF -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID BIT(30) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER BIT(31) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS GENMASK(2, 0) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS GENMASK(6, 3) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_LDPC BIT(7) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_DCM BIT(8) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START GENMASK(15, 9) -#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE GENMASK(18, 16) - /* HE Radiotap data1 Mask */ #define HE_SU_FORMAT_TYPE 0x0000 #define HE_EXT_SU_FORMAT_TYPE 0x0001 From 3aed1364d677d62c7056213ced230d80dec496d4 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Wed, 19 Nov 2025 10:15:57 +0800 Subject: [PATCH 111/140] wifi: ath12k: add the missing RCU lock in ath12k_dp_tx_free_txbuf() RCU read lock is missing in ath12k_dp_tx_free_txbuf() before calling ath12k_dp_to_pdev_dp(), causing below warning: WARNING: suspicious RCU usage ----------------------------- drivers/net/wireless/ath/ath12k/dp.h:653 ath12k dp to dp pdev called without rcu lock! Call Trace: show_stack dump_stack_lvl dump_stack lockdep_rcu_suspicious.cold ath12k_dp_tx_free_txbuf ath12k_wifi7_dp_tx_completion_handler ath12k_wifi7_dp_service_srng ath12k_pci_ext_grp_napi_poll [...] Invoke guard(rcu) to fix it. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251119-ath12k-fix-missing-rcu-lock-v1-1-8155de1dc4fc@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp_tx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c index 1d4444f3936ff..c10da6195c9c3 100644 --- a/drivers/net/wireless/ath/ath12k/dp_tx.c +++ b/drivers/net/wireless/ath/ath12k/dp_tx.c @@ -194,8 +194,6 @@ void ath12k_dp_tx_free_txbuf(struct ath12k_dp *dp, skb_cb = ATH12K_SKB_CB(msdu); - dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); - dma_unmap_single(dp->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); if (skb_cb->paddr_ext_desc) { dma_unmap_single(dp->dev, skb_cb->paddr_ext_desc, @@ -203,6 +201,10 @@ void ath12k_dp_tx_free_txbuf(struct ath12k_dp *dp, dev_kfree_skb_any(desc_params->skb_ext_desc); } + guard(rcu)(); + + dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx); + ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu); if (atomic_dec_and_test(&dp_pdev->num_tx_pending)) From 13d907ae210156598b9396e8b0f9339d781ccb5f Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Wed, 19 Nov 2025 10:24:47 +0800 Subject: [PATCH 112/140] wifi: ath12k: move firmware stats request outside of atomic context In ath12k_mac_op_link_sta_statistics(), the atomic context scope introduced by dp_lock also covers firmware stats request. Since that request could block, below issue is hit: BUG: sleeping function called from invalid context at kernel/locking/mutex.c:575 in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 6866, name: iw preempt_count: 201, expected: 0 RCU nest depth: 0, expected: 0 3 locks held by iw/6866: #0:[...] #1:[...] #2: ffff9748f43230c8 (&dp->dp_lock){+.-.}-{3:3}, at: ath12k_mac_op_link_sta_statistics+0xc6/0x380 [ath12k] Preemption disabled at: [] ath12k_mac_op_link_sta_statistics+0xc6/0x380 [ath12k] Call Trace: show_stack dump_stack_lvl dump_stack __might_resched.cold __might_sleep __mutex_lock mutex_lock_nested ath12k_mac_get_fw_stats ath12k_mac_op_link_sta_statistics Since firmware stats request doesn't require protection from dp_lock, move it outside to fix this issue. While moving, also refine that code hunk to make function parameters get populated when really necessary. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251119-ath12k-ng-sleep-in-atomic-v1-1-5d1a726597db@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/mac.c | 44 +++++++++++++-------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index e87f2daa984d7..c1d0e353d1772 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -13335,10 +13335,12 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, db2dbm = test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, ar->ab->wmi_ab.svc_map); - guard(spinlock_bh)(&ar->ab->dp->dp_lock); + spin_lock_bh(&ar->ab->dp->dp_lock); peer = ath12k_dp_link_peer_find_by_addr(ar->ab->dp, arsta->addr); - if (!peer) + if (!peer) { + spin_unlock_bh(&ar->ab->dp->dp_lock); return; + } link_sinfo->rx_duration = peer->rx_duration; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); @@ -13365,18 +13367,28 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); } + link_sinfo->signal_avg = ewma_avg_rssi_read(&peer->avg_rssi); + if (!db2dbm) + link_sinfo->signal_avg += ATH12K_DEFAULT_NOISE_FLOOR; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); + + link_sinfo->tx_retries = peer->tx_retry_count; + link_sinfo->tx_failed = peer->tx_retry_failed; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); + /* TODO: Use real NF instead of default one. */ signal = peer->rssi_comb; - params.pdev_id = ar->pdev->pdev_id; - params.vdev_id = 0; - params.stats_id = WMI_REQUEST_VDEV_STAT; + spin_unlock_bh(&ar->ab->dp->dp_lock); - if (!signal && - ahsta->ahvif->vdev_type == WMI_VDEV_TYPE_STA && - !(ath12k_mac_get_fw_stats(ar, ¶ms))) { - signal = arsta->rssi_beacon; - ath12k_fw_stats_reset(ar); + if (!signal && ahsta->ahvif->vdev_type == WMI_VDEV_TYPE_STA) { + params.pdev_id = ar->pdev->pdev_id; + params.vdev_id = 0; + params.stats_id = WMI_REQUEST_VDEV_STAT; + + if (!ath12k_mac_get_fw_stats(ar, ¶ms)) + signal = arsta->rssi_beacon; } if (signal) { @@ -13384,18 +13396,6 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, db2dbm ? signal : signal + ATH12K_DEFAULT_NOISE_FLOOR; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); } - - link_sinfo->signal_avg = ewma_avg_rssi_read(&peer->avg_rssi); - - if (!db2dbm) - link_sinfo->signal_avg += ATH12K_DEFAULT_NOISE_FLOOR; - - link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); - - link_sinfo->tx_retries = peer->tx_retry_count; - link_sinfo->tx_failed = peer->tx_retry_failed; - link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); - link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); } EXPORT_SYMBOL(ath12k_mac_op_link_sta_statistics); From af456d155379a79abeac72b5b65b7c3031aff390 Mon Sep 17 00:00:00 2001 From: Ripan Deuri Date: Sun, 7 Dec 2025 12:57:17 +0530 Subject: [PATCH 113/140] wifi: ath12k: Skip DP peer creation for scan vdev Consider a multi-link AP configuration: MLD vif (MAC addr: aa:bb) |-- 2.4 GHz link (BSSID: aa:bb) |-- 5 GHz link (BSSID: cc:dd) For AP vdevs, ath12k creates a DP peer using the arvif's BSSID and stores it in dp_hw->dp_peers_list. During scan operations, the driver assigns an arvif to the scan vdev and uses the vif's MAC address as its BSSID. In the above scenario, the scan vdev MAC address (aa:bb) matches the BSSID of the 2.4 GHz AP link, causing a duplicate entry in dp_hw->dp_peers_list and leading to scan vdev creation failure. Failure in vif bringup sequence: 1. Create AP vdev for 2.4 GHz link: - Assign arvif with BSSID = aa:bb and link_id = 0. - Create DP peer with address aa:bb and add to dp_hw->dp_peers_list. 2. Create scan vdev for 5 GHz link: - Assign arvif with BSSID = aa:bb (same as vif MAC address) and link_id = 15. - Attempt to create another DP peer with address aa:bb. - Operation fails because aa:bb already exists in dp_hw->dp_peers_list, resulting in duplicate entry conflict. 3. Delete scan vdev for 5 GHz link. 4. Create AP vdev for 5 GHz link. Since DP peer is not needed for scan operations, identify scan vdev using arvif->link_id >= IEEE80211_MLD_MAX_NUM_LINKS and skip DP peer creation and deletion. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1 Signed-off-by: Ripan Deuri Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251207072717.95542-1-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/mac.c | 22 ++++++++++++++-------- drivers/net/wireless/ath/ath12k/peer.c | 12 +++++++----- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index c1d0e353d1772..8bedd5781d1b0 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1253,7 +1253,8 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar) /* Delete all the self dp_peers on asserted radio */ list_for_each_entry_safe_reverse(arvif, tmp_vif, &ar->arvifs, list) { - if (arvif->ahvif->vdev_type == WMI_VDEV_TYPE_AP) { + if ((arvif->ahvif->vdev_type == WMI_VDEV_TYPE_AP) && + (arvif->link_id < IEEE80211_MLD_MAX_NUM_LINKS)) { ath12k_dp_peer_delete(dp_hw, arvif->bssid, NULL); arvif->num_stations = 0; } @@ -4188,7 +4189,8 @@ static void ath12k_mac_remove_link_interface(struct ieee80211_hw *hw, ath12k_warn(ar->ab, "failed to submit AP self-peer removal on vdev %d link id %d: %d", arvif->vdev_id, arvif->link_id, ret); - ath12k_dp_peer_delete(&ah->dp_hw, arvif->bssid, NULL); + if (arvif->link_id < IEEE80211_MLD_MAX_NUM_LINKS) + ath12k_dp_peer_delete(&ah->dp_hw, arvif->bssid, NULL); } ath12k_mac_vdev_delete(ar, arvif); } @@ -10041,6 +10043,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) u8 link_id; struct ath12k_dp_link_vif *dp_link_vif = NULL; struct ath12k_dp_peer_create_params params = {}; + bool dp_peer_created = false; lockdep_assert_wiphy(hw->wiphy); @@ -10132,11 +10135,14 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) case WMI_VDEV_TYPE_AP: params.ucast_ra_only = true; - ret = ath12k_dp_peer_create(&ah->dp_hw, arvif->bssid, ¶ms); - if (ret) { - ath12k_warn(ab, "failed to vdev %d create dp_peer for AP: %d\n", - arvif->vdev_id, ret); - goto err_vdev_del; + if (arvif->link_id < IEEE80211_MLD_MAX_NUM_LINKS) { + ret = ath12k_dp_peer_create(&ah->dp_hw, arvif->bssid, ¶ms); + if (ret) { + ath12k_warn(ab, "failed to vdev %d create dp_peer for AP: %d\n", + arvif->vdev_id, ret); + goto err_vdev_del; + } + dp_peer_created = true; } peer_param.vdev_id = arvif->vdev_id; @@ -10253,7 +10259,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) } err_dp_peer_del: - if (ahvif->vdev_type == WMI_VDEV_TYPE_AP) + if (dp_peer_created) ath12k_dp_peer_delete(&ah->dp_hw, arvif->bssid, NULL); err_vdev_del: diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index c2fb5bbd6ceae..5f3bd3b9a3e97 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -241,11 +241,13 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, spin_unlock_bh(&dp->dp_lock); - ret = ath12k_dp_link_peer_assign(ath12k_ab_to_dp(ar->ab), - &(ath12k_ar_to_ah(ar)->dp_hw), - arvif->vdev_id, sta, - (u8 *)arg->peer_addr, link_id, - ar->hw_link_id); + if (arvif->link_id < IEEE80211_MLD_MAX_NUM_LINKS) { + ret = ath12k_dp_link_peer_assign(ath12k_ab_to_dp(ar->ab), + &(ath12k_ar_to_ah(ar)->dp_hw), + arvif->vdev_id, sta, + (u8 *)arg->peer_addr, link_id, + ar->hw_link_id); + } return ret; } From 358181ccb588b3e1bbea94f1a7bedc536131829d Mon Sep 17 00:00:00 2001 From: Chien Wong Date: Thu, 30 Oct 2025 22:30:41 +0800 Subject: [PATCH 114/140] wifi: ath11k: fix comment typo in monitor mode handling Correct a typo in the monitor mode comment where "it make" was mistakenly used instead of "it doesn't make". The comment explains that the brief period where monitor mode appears enabled before being removed is harmless in practice. Also, use more common phrase "in practice" instead of "in practise". Signed-off-by: Chien Wong Link: https://patch.msgid.link/20251030143041.12027-1-m@xv97.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath11k/mac.c | 2 +- drivers/net/wireless/ath/ath12k/mac.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 3276fe443502f..668307f28038e 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -10640,7 +10640,7 @@ static int __ath11k_mac_register(struct ath11k *ar) if (!ab->hw_params.supports_monitor) /* There's a race between calling ieee80211_register_hw() * and here where the monitor mode is enabled for a little - * while. But that time is so short and in practise it make + * while. But that time is so short and in practice it doesn't make * a difference in real life. */ ar->hw->wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR); diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 8bedd5781d1b0..6d3664fe4f0f1 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -14504,7 +14504,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah) if (is_monitor_disable) /* There's a race between calling ieee80211_register_hw() * and here where the monitor mode is enabled for a little - * while. But that time is so short and in practise it make + * while. But that time is so short and in practice it doesn't make * a difference in real life. */ wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR); From 8a756da7f95696e50357a7a09686866b01067df6 Mon Sep 17 00:00:00 2001 From: Alexander Minchev Date: Thu, 27 Nov 2025 07:29:37 +0000 Subject: [PATCH 115/140] wifi: ath12k: remove redundant pci_set_drvdata() call pci_set_drvdata() is called twice in ath12k_pci_probe() with the same pointer. Remove the earlier call so drvdata is set after ath12k_base and ath12k_pci initialization is complete. Having two calls might suggest that drvdata needs to be set early for some reason, even though it is not used until after the 'ab' struct ath12k_base is fully populated. Even though exact placement is not critical, keeping a single pci_set_drvdata() at the end of the initialization makes it clearer that drvdata points to a fully initialized structure and avoids confusion for future changes. Tested on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Reviewed-by: Baochen Qiang Signed-off-by: Alexander Minchev Link: https://patch.msgid.link/20251127072839.14167-2-adminchev@proton.me Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/pci.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index fd4c25ad8f07d..7422a4c4ed7ec 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -1541,7 +1541,6 @@ static int ath12k_pci_probe(struct pci_dev *pdev, } ab->dev = &pdev->dev; - pci_set_drvdata(pdev, ab); ab_pci = ath12k_pci_priv(ab); ab_pci->dev_id = pci_dev->device; ab_pci->ab = ab; From 8c7310bb5408385d7a6a175b44a9ee8a58407cd2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 18 Dec 2025 10:44:20 +0300 Subject: [PATCH 116/140] wifi: ath12k: clean up on error in ath12k_dp_setup() Destroy the rhash_tbl before returning the error code. Fixes: a88cf5f71adf ("wifi: ath12k: Add hash table for ath12k_dp_link_peer") Signed-off-by: Dan Carpenter Reviewed-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/aUOw1J0TU4VgeXj6@stanley.mountain Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index 9f05eea6695a5..ab54c8a84d3e0 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1513,7 +1513,7 @@ static int ath12k_dp_setup(struct ath12k_base *ab) HAL_WBM_IDLE_LINK, srng, n_link_desc); if (ret) { ath12k_warn(ab, "failed to setup link desc: %d\n", ret); - return ret; + goto rhash_destroy; } ret = ath12k_dp_cc_init(ab); From 820504b5f2eee52a7c9c30fe75d242944ab61b1d Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 3 Nov 2025 10:44:49 +0800 Subject: [PATCH 117/140] wifi: ath12k: do WoW offloads only on primary link In case of multi-link connection, WCN7850 firmware crashes due to WoW offloads enabled on both primary and secondary links. Change to do it only on primary link to fix it. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00284-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1 Fixes: 32f7b19668bd ("wifi: ath12k: support MLO as well if single_chip_mlo_support flag is set") Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251103-ath12-primary-link-wow-v1-1-3cf523dc09f0@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wow.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/wow.c b/drivers/net/wireless/ath/ath12k/wow.c index f56ec44a16361..bb08e17405825 100644 --- a/drivers/net/wireless/ath/ath12k/wow.c +++ b/drivers/net/wireless/ath/ath12k/wow.c @@ -135,6 +135,9 @@ static int ath12k_wow_cleanup(struct ath12k *ar) lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); list_for_each_entry(arvif, &ar->arvifs, list) { + if (arvif != &arvif->ahvif->deflink) + continue; + ret = ath12k_wow_vif_cleanup(arvif); if (ret) { ath12k_warn(ar->ab, "failed to clean wow wakeups on vdev %i: %d\n", @@ -479,8 +482,12 @@ static int ath12k_wow_set_wakeups(struct ath12k *ar, lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); list_for_each_entry(arvif, &ar->arvifs, list) { + if (arvif != &arvif->ahvif->deflink) + continue; + if (ath12k_wow_is_p2p_vdev(arvif->ahvif)) continue; + ret = ath12k_wow_vif_set_wakeups(arvif, wowlan); if (ret) { ath12k_warn(ar->ab, "failed to set wow wakeups on vdev %i: %d\n", @@ -538,6 +545,9 @@ static int ath12k_wow_nlo_cleanup(struct ath12k *ar) lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); list_for_each_entry(arvif, &ar->arvifs, list) { + if (arvif != &arvif->ahvif->deflink) + continue; + if (ath12k_wow_is_p2p_vdev(arvif->ahvif)) continue; @@ -745,6 +755,9 @@ static int ath12k_wow_arp_ns_offload(struct ath12k *ar, bool enable) list_for_each_entry(arvif, &ar->arvifs, list) { ahvif = arvif->ahvif; + if (arvif != &ahvif->deflink) + continue; + if (ahvif->vdev_type != WMI_VDEV_TYPE_STA) continue; @@ -776,6 +789,9 @@ static int ath12k_gtk_rekey_offload(struct ath12k *ar, bool enable) lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); list_for_each_entry(arvif, &ar->arvifs, list) { + if (arvif != &arvif->ahvif->deflink) + continue; + if (arvif->ahvif->vdev_type != WMI_VDEV_TYPE_STA || !arvif->is_up || !arvif->rekey_data.enable_offload) From fbf1f9104325784551d3b66a96f6e37fd091dfa2 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:21 +0800 Subject: [PATCH 118/140] wifi: ath12k: refactor PCI window register access Currently offset of PCI window register address is defined as 0x310c which is same across existing chips. However QCC2072 has a different offset 0x3278. In order to make the window selection logic work for QCC2072 as well, change to initialize this parameter per device at the probe time. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-1-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/pci.c | 11 +++++------ drivers/net/wireless/ath/ath12k/pci.h | 2 ++ drivers/net/wireless/ath/ath12k/wifi7/pci.c | 12 ++++++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 7422a4c4ed7ec..31eb59e69a8a4 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -23,7 +23,6 @@ #define ATH12K_PCI_IRQ_CE0_OFFSET 3 #define WINDOW_ENABLE_BIT 0x40000000 -#define WINDOW_REG_ADDRESS 0x310c #define WINDOW_VALUE_MASK GENMASK(24, 19) #define WINDOW_START 0x80000 #define WINDOW_RANGE_MASK GENMASK(18, 0) @@ -125,8 +124,8 @@ static void ath12k_pci_select_window(struct ath12k_pci *ab_pci, u32 offset) if (window != ab_pci->register_window) { iowrite32(WINDOW_ENABLE_BIT | window, - ab->mem + WINDOW_REG_ADDRESS); - ioread32(ab->mem + WINDOW_REG_ADDRESS); + ab->mem + ab_pci->window_reg_addr); + ioread32(ab->mem + ab_pci->window_reg_addr); ab_pci->register_window = window; } } @@ -145,7 +144,7 @@ static void ath12k_pci_select_static_window(struct ath12k_pci *ab_pci) ab_pci->register_window = window; spin_unlock_bh(&ab_pci->window_lock); - iowrite32(WINDOW_ENABLE_BIT | window, ab_pci->ab->mem + WINDOW_REG_ADDRESS); + iowrite32(WINDOW_ENABLE_BIT | window, ab_pci->ab->mem + ab_pci->window_reg_addr); } static u32 ath12k_pci_get_window_start(struct ath12k_base *ab, @@ -178,8 +177,8 @@ static void ath12k_pci_restore_window(struct ath12k_base *ab) spin_lock_bh(&ab_pci->window_lock); iowrite32(WINDOW_ENABLE_BIT | ab_pci->register_window, - ab->mem + WINDOW_REG_ADDRESS); - ioread32(ab->mem + WINDOW_REG_ADDRESS); + ab->mem + ab_pci->window_reg_addr); + ioread32(ab->mem + ab_pci->window_reg_addr); spin_unlock_bh(&ab_pci->window_lock); } diff --git a/drivers/net/wireless/ath/ath12k/pci.h b/drivers/net/wireless/ath/ath12k/pci.h index 1cc4f0e050f95..a74b09d23a6a1 100644 --- a/drivers/net/wireless/ath/ath12k/pci.h +++ b/drivers/net/wireless/ath/ath12k/pci.h @@ -130,6 +130,8 @@ struct ath12k_pci { u64 dma_mask; const struct ath12k_pci_device_family_ops *device_family_ops; const struct ath12k_pci_reg_base *reg_base; + + u32 window_reg_addr; }; struct ath12k_pci_driver { diff --git a/drivers/net/wireless/ath/ath12k/wifi7/pci.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c index dedc88858bb0f..6c477fe97298f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/pci.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -27,6 +27,8 @@ #define TCSR_SOC_HW_VERSION_MAJOR_MASK GENMASK(11, 8) #define TCSR_SOC_HW_VERSION_MINOR_MASK GENMASK(7, 4) +#define WINDOW_REG_ADDRESS 0x310c + static const struct pci_device_id ath12k_wifi7_pci_id_table[] = { { PCI_VDEVICE(QCOM, QCN9274_DEVICE_ID) }, { PCI_VDEVICE(QCOM, WCN7850_DEVICE_ID) }, @@ -104,6 +106,11 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; ab->static_window_map = true; ab_pci->pci_ops = &ath12k_wifi7_pci_ops_qcn9274; + /* + * init window reg addr before reading hardware version + * as it will be used there + */ + ab_pci->window_reg_addr = WINDOW_REG_ADDRESS; ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major, &soc_hw_version_minor); ab->target_mem_mode = ath12k_core_get_memory_mode(ab); @@ -126,6 +133,11 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; ab->static_window_map = false; ab_pci->pci_ops = &ath12k_wifi7_pci_ops_wcn7850; + /* + * init window reg addr before reading hardware version + * as it will be used there + */ + ab_pci->window_reg_addr = WINDOW_REG_ADDRESS; ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major, &soc_hw_version_minor); ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT; From ec35df1eb3c8ac171506e04fcf72c84c8eb2b071 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:22 +0800 Subject: [PATCH 119/140] wifi: ath12k: refactor REO CMD ring handling The entry of REO CMD ring of existing chips has a 64 bit TLV header, hence below functions take a 64 bit TLV assumption by default ath12k_wifi7_hal_reo_init_cmd_ring() ath12k_wifi7_hal_reo_cmd_queue_stats() ath12k_wifi7_hal_reo_cmd_flush_cache() ath12k_wifi7_hal_reo_cmd_update_rx_queue() However this is not the case for QCC2072 of which the TLV is 32 bit, meaning above functions don't work for it. Rename/refactor above functions to prepare for QCC2072 support: Rename the first one to ath12k_wifi7_hal_reo_init_cmd_ring_tlv64() to better reflect what it is doing. There will be a 32 bit variant when QCC2072 support is in place. For the last ones, remove TLV length assumption and offload TLV encoding work to a newly added callback _reo_cmd_enc_tlv_hdr. This way each chip can register its own handler hence can do the work accordingly. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-2-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.c | 11 ++++++ drivers/net/wireless/ath/ath12k/hal.h | 23 +++++++++++ .../net/wireless/ath/ath12k/wifi7/hal_desc.h | 21 ---------- .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 3 +- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 39 ++++++++----------- .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 5 ++- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 4 +- 7 files changed, 58 insertions(+), 48 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 91d697ad1799d..95fbff4d825db 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -817,3 +817,14 @@ void ath12k_hal_dump_srng_stats(struct ath12k_base *ab) jiffies_to_msecs(jiffies - srng->timestamp)); } } + +void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len) +{ + struct hal_tlv_64_hdr *tlv64 = tlv; + + tlv64->tl = le64_encode_bits(tag, HAL_TLV_HDR_TAG) | + le64_encode_bits(len, HAL_TLV_HDR_LEN); + + return tlv64->value; +} +EXPORT_SYMBOL(ath12k_hal_encode_tlv64_hdr); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index ce038906bd069..5c5bbcbf329a4 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1425,8 +1425,30 @@ struct hal_ops { u32 *sw_cookie, struct ath12k_buffer_addr **pp_buf_addr, u8 *rbm, u32 *msdu_cnt); + void *(*reo_cmd_enc_tlv_hdr)(void *tlv, u64 tag, u64 len); }; +#define HAL_TLV_HDR_TAG GENMASK(9, 1) +#define HAL_TLV_HDR_LEN GENMASK(25, 10) +#define HAL_TLV_USR_ID GENMASK(31, 26) + +#define HAL_TLV_ALIGN 4 + +struct hal_tlv_hdr { + __le32 tl; + u8 value[]; +} __packed; + +#define HAL_TLV_64_HDR_TAG GENMASK(9, 1) +#define HAL_TLV_64_HDR_LEN GENMASK(21, 10) +#define HAL_TLV_64_USR_ID GENMASK(31, 26) +#define HAL_TLV_64_ALIGN 8 + +struct hal_tlv_64_hdr { + __le64 tl; + u8 value[]; +} __packed; + dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab, struct hal_srng *srng); dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab, @@ -1514,4 +1536,5 @@ void ath12k_hal_rx_reo_ent_buf_paddr_get(struct ath12k_hal *hal, void *rx_desc, dma_addr_t *paddr, u32 *sw_cookie, struct ath12k_buffer_addr **pp_buf_addr, u8 *rbm, u32 *msdu_cnt); +void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h index 9dad8f7ca9f21..cdcf24b1d6eba 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h @@ -487,27 +487,6 @@ enum hal_tlv_tag { HAL_TLV_BASE = 511 /* 0x1ff */, }; -#define HAL_TLV_HDR_TAG GENMASK(9, 1) -#define HAL_TLV_HDR_LEN GENMASK(25, 10) -#define HAL_TLV_USR_ID GENMASK(31, 26) - -#define HAL_TLV_ALIGN 4 - -struct hal_tlv_hdr { - __le32 tl; - u8 value[]; -} __packed; - -#define HAL_TLV_64_HDR_TAG GENMASK(9, 1) -#define HAL_TLV_64_HDR_LEN GENMASK(21, 10) -#define HAL_TLV_64_USR_ID GENMASK(31, 26) -#define HAL_TLV_64_ALIGN 8 - -struct hal_tlv_64_hdr { - __le64 tl; - u8 value[]; -} __packed; - #define RX_MPDU_DESC_INFO0_MSDU_COUNT GENMASK(7, 0) #define RX_MPDU_DESC_INFO0_FRAG_FLAG BIT(8) #define RX_MPDU_DESC_INFO0_MPDU_RETRY BIT(9) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 4b6f43389b2d9..449bd6a99096f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1020,7 +1020,7 @@ const struct hal_ops hal_qcn9274_ops = { .write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr, .write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr, .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list, - .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring, + .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring_tlv64, .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup, .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set, .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, @@ -1028,4 +1028,5 @@ const struct hal_ops hal_qcn9274_ops = { .get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm, .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, + .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr, }; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index b7e930e12b84d..f040bd1c4e4fc 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -23,15 +23,13 @@ void ath12k_wifi7_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, hdr->info0 |= le32_encode_bits(magic, HAL_DESC_HDR_INFO0_DBG_RESERVED); } -static int ath12k_wifi7_hal_reo_cmd_queue_stats(struct hal_tlv_64_hdr *tlv, +static int ath12k_wifi7_hal_reo_cmd_queue_stats(struct ath12k_hal *hal, void *tlv, struct ath12k_hal_reo_cmd *cmd) { struct hal_reo_get_queue_stats *desc; - tlv->tl = le64_encode_bits(HAL_REO_GET_QUEUE_STATS, HAL_TLV_HDR_TAG) | - le64_encode_bits(sizeof(*desc), HAL_TLV_HDR_LEN); - - desc = (struct hal_reo_get_queue_stats *)tlv->value; + desc = hal->ops->reo_cmd_enc_tlv_hdr(tlv, HAL_REO_GET_QUEUE_STATS, + sizeof(*desc)); memset_startat(desc, 0, queue_addr_lo); desc->cmd.info0 &= ~cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED); @@ -47,8 +45,7 @@ static int ath12k_wifi7_hal_reo_cmd_queue_stats(struct hal_tlv_64_hdr *tlv, return le32_get_bits(desc->cmd.info0, HAL_REO_CMD_HDR_INFO0_CMD_NUMBER); } -static int ath12k_wifi7_hal_reo_cmd_flush_cache(struct ath12k_hal *hal, - struct hal_tlv_64_hdr *tlv, +static int ath12k_wifi7_hal_reo_cmd_flush_cache(struct ath12k_hal *hal, void *tlv, struct ath12k_hal_reo_cmd *cmd) { struct hal_reo_flush_cache *desc; @@ -61,10 +58,8 @@ static int ath12k_wifi7_hal_reo_cmd_flush_cache(struct ath12k_hal *hal, hal->current_blk_index = avail_slot; } - tlv->tl = le64_encode_bits(HAL_REO_FLUSH_CACHE, HAL_TLV_HDR_TAG) | - le64_encode_bits(sizeof(*desc), HAL_TLV_HDR_LEN); - - desc = (struct hal_reo_flush_cache *)tlv->value; + desc = hal->ops->reo_cmd_enc_tlv_hdr(tlv, HAL_REO_FLUSH_CACHE, + sizeof(*desc)); memset_startat(desc, 0, cache_addr_lo); desc->cmd.info0 &= ~cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED); @@ -98,15 +93,13 @@ static int ath12k_wifi7_hal_reo_cmd_flush_cache(struct ath12k_hal *hal, } static int -ath12k_wifi7_hal_reo_cmd_update_rx_queue(struct hal_tlv_64_hdr *tlv, +ath12k_wifi7_hal_reo_cmd_update_rx_queue(struct ath12k_hal *hal, void *tlv, struct ath12k_hal_reo_cmd *cmd) { struct hal_reo_update_rx_queue *desc; - tlv->tl = le64_encode_bits(HAL_REO_UPDATE_RX_REO_QUEUE, HAL_TLV_HDR_TAG) | - le64_encode_bits(sizeof(*desc), HAL_TLV_HDR_LEN); - - desc = (struct hal_reo_update_rx_queue *)tlv->value; + desc = hal->ops->reo_cmd_enc_tlv_hdr(tlv, HAL_REO_UPDATE_RX_REO_QUEUE, + sizeof(*desc)); memset_startat(desc, 0, queue_addr_lo); desc->cmd.info0 &= ~cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED); @@ -227,7 +220,8 @@ int ath12k_wifi7_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, enum hal_reo_cmd_type type, struct ath12k_hal_reo_cmd *cmd) { - struct hal_tlv_64_hdr *reo_desc; + struct ath12k_hal *hal = &ab->hal; + void *reo_desc; int ret; spin_lock_bh(&srng->lock); @@ -241,14 +235,13 @@ int ath12k_wifi7_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, switch (type) { case HAL_REO_CMD_GET_QUEUE_STATS: - ret = ath12k_wifi7_hal_reo_cmd_queue_stats(reo_desc, cmd); + ret = ath12k_wifi7_hal_reo_cmd_queue_stats(hal, reo_desc, cmd); break; case HAL_REO_CMD_FLUSH_CACHE: - ret = ath12k_wifi7_hal_reo_cmd_flush_cache(&ab->hal, reo_desc, - cmd); + ret = ath12k_wifi7_hal_reo_cmd_flush_cache(hal, reo_desc, cmd); break; case HAL_REO_CMD_UPDATE_RX_QUEUE: - ret = ath12k_wifi7_hal_reo_cmd_update_rx_queue(reo_desc, cmd); + ret = ath12k_wifi7_hal_reo_cmd_update_rx_queue(hal, reo_desc, cmd); break; case HAL_REO_CMD_FLUSH_QUEUE: case HAL_REO_CMD_UNBLOCK_CACHE: @@ -897,8 +890,8 @@ void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3); } -void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, - struct hal_srng *srng) +void ath12k_wifi7_hal_reo_init_cmd_ring_tlv64(struct ath12k_base *ab, + struct hal_srng *srng) { struct hal_srng_params params; struct hal_tlv_64_hdr *tlv; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index 1f2cfba3aac1c..aa1bca8139557 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -860,8 +860,9 @@ void ath12k_wifi7_hal_rx_msdu_list_get(struct ath12k *ar, void *link_desc, void *msdu_list_opaque, u16 *num_msdus); -void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab, - struct hal_srng *srng); +void ath12k_wifi7_hal_reo_init_cmd_ring_tlv64(struct ath12k_base *ab, + struct hal_srng *srng); +void ath12k_wifi7_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab); void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, int tid, u32 ba_window_size, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index f243bc3ab4097..49c45431c0c79 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -793,7 +793,8 @@ const struct hal_ops hal_wcn7850_ops = { .write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr, .write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr, .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list, - .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring, + .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring_tlv64, + .reo_shared_qaddr_cache_clear = ath12k_wifi7_hal_reo_shared_qaddr_cache_clear, .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup, .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set, .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, @@ -801,4 +802,5 @@ const struct hal_ops hal_wcn7850_ops = { .get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm, .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, + .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr, }; From e52c657058f4ff8b8687150cc96529b6c1357547 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:23 +0800 Subject: [PATCH 120/140] wifi: ath12k: refactor REO status ring handling The entry of REO status ring of existing chips has a 64 bit TLV header, hence below functions take a 64 bit TLV assumption by default ath12k_wifi7_dp_rx_process_reo_status() ath12k_wifi7_hal_reo_status_queue_stats() ath12k_wifi7_hal_reo_flush_queue_status() ath12k_wifi7_hal_reo_flush_cache_status() ath12k_wifi7_hal_reo_unblk_cache_status() ath12k_wifi7_hal_reo_flush_timeout_list_status() ath12k_wifi7_hal_reo_desc_thresh_reached_status() ath12k_wifi7_hal_reo_update_rx_reo_queue_status() However this is not the case for QCC2072 of which the TLV is 32 bit. Refactor above functions to prepare for QCC2072 support, this is done by removing TLV length assumption and offloading TLV decoding work to a newly added callback _reo_status_dec_tlv_hdr. This way each chip can register its own handler hence can do the work accordingly. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-3-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.c | 12 +++++++ drivers/net/wireless/ath/ath12k/hal.h | 5 +++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 18 +++++----- drivers/net/wireless/ath/ath12k/wifi7/hal.h | 3 -- .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 1 + .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 33 ++++--------------- .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 24 +++++++------- .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 1 + 8 files changed, 48 insertions(+), 49 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 95fbff4d825db..847482fd8c6b1 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -828,3 +828,15 @@ void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len) return tlv64->value; } EXPORT_SYMBOL(ath12k_hal_encode_tlv64_hdr); + +u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc) +{ + struct hal_tlv_64_hdr *tlv64 = tlv; + u16 tag; + + tag = le64_get_bits(tlv64->tl, HAL_SRNG_TLV_HDR_TAG); + *desc = tlv64->value; + + return tag; +} +EXPORT_SYMBOL(ath12k_hal_decode_tlv64_hdr); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 5c5bbcbf329a4..3575bb85f83cc 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1426,6 +1426,7 @@ struct hal_ops { struct ath12k_buffer_addr **pp_buf_addr, u8 *rbm, u32 *msdu_cnt); void *(*reo_cmd_enc_tlv_hdr)(void *tlv, u64 tag, u64 len); + u16 (*reo_status_dec_tlv_hdr)(void *tlv, void **desc); }; #define HAL_TLV_HDR_TAG GENMASK(9, 1) @@ -1449,6 +1450,9 @@ struct hal_tlv_64_hdr { u8 value[]; } __packed; +#define HAL_SRNG_TLV_HDR_TAG GENMASK(9, 1) +#define HAL_SRNG_TLV_HDR_LEN GENMASK(25, 10) + dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab, struct hal_srng *srng); dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab, @@ -1537,4 +1541,5 @@ void ath12k_hal_rx_reo_ent_buf_paddr_get(struct ath12k_hal *hal, void *rx_desc, struct ath12k_buffer_addr **pp_buf_addr, u8 *rbm, u32 *msdu_cnt); void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len); +u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index af50dafc03499..635e812bf4f4a 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -2066,12 +2066,12 @@ void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_dp *dp) { struct ath12k_base *ab = dp->ab; struct ath12k_hal *hal = dp->hal; - struct hal_tlv_64_hdr *hdr; struct hal_srng *srng; struct ath12k_dp_rx_reo_cmd *cmd, *tmp; bool found = false; u16 tag; struct hal_reo_status reo_status; + void *hdr, *desc; srng = &hal->srng_list[dp->reo_status_ring.ring_id]; @@ -2082,35 +2082,35 @@ void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_dp *dp) ath12k_hal_srng_access_begin(ab, srng); while ((hdr = ath12k_hal_srng_dst_get_next_entry(ab, srng))) { - tag = le64_get_bits(hdr->tl, HAL_SRNG_TLV_HDR_TAG); + tag = hal->ops->reo_status_dec_tlv_hdr(hdr, &desc); switch (tag) { case HAL_REO_GET_QUEUE_STATS_STATUS: - ath12k_wifi7_hal_reo_status_queue_stats(ab, hdr, + ath12k_wifi7_hal_reo_status_queue_stats(ab, desc, &reo_status); break; case HAL_REO_FLUSH_QUEUE_STATUS: - ath12k_wifi7_hal_reo_flush_queue_status(ab, hdr, + ath12k_wifi7_hal_reo_flush_queue_status(ab, desc, &reo_status); break; case HAL_REO_FLUSH_CACHE_STATUS: - ath12k_wifi7_hal_reo_flush_cache_status(ab, hdr, + ath12k_wifi7_hal_reo_flush_cache_status(ab, desc, &reo_status); break; case HAL_REO_UNBLOCK_CACHE_STATUS: - ath12k_wifi7_hal_reo_unblk_cache_status(ab, hdr, + ath12k_wifi7_hal_reo_unblk_cache_status(ab, desc, &reo_status); break; case HAL_REO_FLUSH_TIMEOUT_LIST_STATUS: - ath12k_wifi7_hal_reo_flush_timeout_list_status(ab, hdr, + ath12k_wifi7_hal_reo_flush_timeout_list_status(ab, desc, &reo_status); break; case HAL_REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS: - ath12k_wifi7_hal_reo_desc_thresh_reached_status(ab, hdr, + ath12k_wifi7_hal_reo_desc_thresh_reached_status(ab, desc, &reo_status); break; case HAL_REO_UPDATE_RX_REO_QUEUE_STATUS: - ath12k_wifi7_hal_reo_update_rx_reo_queue_status(ab, hdr, + ath12k_wifi7_hal_reo_update_rx_reo_queue_status(ab, desc, &reo_status); break; default: diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index 0a39862d07c45..961dadd5633e8 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -369,9 +369,6 @@ #define HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC (100 * 1000) #define HAL_DEFAULT_VO_REO_TIMEOUT_USEC (40 * 1000) -#define HAL_SRNG_TLV_HDR_TAG GENMASK(9, 1) -#define HAL_SRNG_TLV_HDR_LEN GENMASK(25, 10) - #define HAL_SRNG_DESC_LOOP_CNT 0xf0000000 #define HAL_REO_CMD_FLG_NEED_STATUS BIT(0) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 449bd6a99096f..253729fcf0a3f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1029,4 +1029,5 @@ const struct hal_ops hal_qcn9274_ops = { .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr, + .reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr, }; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index f040bd1c4e4fc..84b714b8992ff 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -549,12 +549,9 @@ ath12k_wifi7_hal_rx_msdu_link_desc_set(struct ath12k_base *ab, } void ath12k_wifi7_hal_reo_status_queue_stats(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_get_queue_stats_status *desc, struct hal_reo_status *status) { - struct hal_reo_get_queue_stats_status *desc = - (struct hal_reo_get_queue_stats_status *)tlv->value; - status->uniform_hdr.cmd_num = le32_get_bits(desc->hdr.info0, HAL_REO_STATUS_HDR_INFO0_STATUS_NUM); @@ -613,12 +610,9 @@ void ath12k_wifi7_hal_reo_status_queue_stats(struct ath12k_base *ab, } void ath12k_wifi7_hal_reo_flush_queue_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_flush_queue_status *desc, struct hal_reo_status *status) { - struct hal_reo_flush_queue_status *desc = - (struct hal_reo_flush_queue_status *)tlv->value; - status->uniform_hdr.cmd_num = le32_get_bits(desc->hdr.info0, HAL_REO_STATUS_HDR_INFO0_STATUS_NUM); @@ -632,12 +626,10 @@ void ath12k_wifi7_hal_reo_flush_queue_status(struct ath12k_base *ab, void ath12k_wifi7_hal_reo_flush_cache_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_flush_cache_status *desc, struct hal_reo_status *status) { struct ath12k_hal *hal = &ab->hal; - struct hal_reo_flush_cache_status *desc = - (struct hal_reo_flush_cache_status *)tlv->value; status->uniform_hdr.cmd_num = le32_get_bits(desc->hdr.info0, @@ -674,12 +666,10 @@ ath12k_wifi7_hal_reo_flush_cache_status(struct ath12k_base *ab, } void ath12k_wifi7_hal_reo_unblk_cache_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_unblock_cache_status *desc, struct hal_reo_status *status) { struct ath12k_hal *hal = &ab->hal; - struct hal_reo_unblock_cache_status *desc = - (struct hal_reo_unblock_cache_status *)tlv->value; status->uniform_hdr.cmd_num = le32_get_bits(desc->hdr.info0, @@ -703,12 +693,9 @@ void ath12k_wifi7_hal_reo_unblk_cache_status(struct ath12k_base *ab, void ath12k_wifi7_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_flush_timeout_list_status *desc, struct hal_reo_status *status) { - struct hal_reo_flush_timeout_list_status *desc = - (struct hal_reo_flush_timeout_list_status *)tlv->value; - status->uniform_hdr.cmd_num = le32_get_bits(desc->hdr.info0, HAL_REO_STATUS_HDR_INFO0_STATUS_NUM); @@ -733,12 +720,9 @@ ath12k_wifi7_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, void ath12k_wifi7_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_desc_thresh_reached_status *desc, struct hal_reo_status *status) { - struct hal_reo_desc_thresh_reached_status *desc = - (struct hal_reo_desc_thresh_reached_status *)tlv->value; - status->uniform_hdr.cmd_num = le32_get_bits(desc->hdr.info0, HAL_REO_STATUS_HDR_INFO0_STATUS_NUM); @@ -768,12 +752,9 @@ ath12k_wifi7_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, } void ath12k_wifi7_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_status_hdr *desc, struct hal_reo_status *status) { - struct hal_reo_status_hdr *desc = - (struct hal_reo_status_hdr *)tlv->value; - status->uniform_hdr.cmd_num = le32_get_bits(desc->info0, HAL_REO_STATUS_HDR_INFO0_STATUS_NUM); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index aa1bca8139557..95f5595b30ad1 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -813,25 +813,27 @@ enum hal_mon_reception_type { (HAL_RU(ru_per80, num_80mhz, ru_idx_per80mhz)) void ath12k_wifi7_hal_reo_status_queue_stats(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_get_queue_stats_status *desc, struct hal_reo_status *status); void ath12k_wifi7_hal_reo_flush_queue_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_flush_queue_status *desc, struct hal_reo_status *status); void ath12k_wifi7_hal_reo_flush_cache_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_flush_cache_status *desc, struct hal_reo_status *status); void ath12k_wifi7_hal_reo_unblk_cache_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_unblock_cache_status *desc, struct hal_reo_status *status); -void ath12k_wifi7_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status); -void ath12k_wifi7_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, - struct hal_reo_status *status); +void +ath12k_wifi7_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, + struct hal_reo_flush_timeout_list_status *desc, + struct hal_reo_status *status); +void +ath12k_wifi7_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, + struct hal_reo_desc_thresh_reached_status *desc, + struct hal_reo_status *status); void ath12k_wifi7_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab, - struct hal_tlv_64_hdr *tlv, + struct hal_reo_status_hdr *desc, struct hal_reo_status *status); void ath12k_wifi7_hal_rx_msdu_link_info_get(struct hal_rx_msdu_link *link, u32 *num_msdus, u32 *msdu_cookies, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 49c45431c0c79..c3093c01af878 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -803,4 +803,5 @@ const struct hal_ops hal_wcn7850_ops = { .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr, + .reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr, }; From 282b550b7a18c9c785c1ab470001ee33f27c4cf2 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:24 +0800 Subject: [PATCH 121/140] wifi: ath12k: fix preferred hardware mode calculation For single pdev device like WCN7850/QCC2072, preferred_hw_mode is initialized to WMI_HOST_HW_MODE_SINGLE. Later when firmware sends supported modes to host, each mode is compared with the initial one and if the priority of the new mode is higher, update the parameter and store mode capability. For WCN7850, this does not result in issue, as one of the supported mode indeed has a higher priority. However the only available mode of QCC2072 at this stage is WMI_HOST_HW_MODE_SINGLE, which fails the comparison, hence mode capability is not stored. Subsequently driver initialization fails. Fix it by accepting a mode with the same priority. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-4-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index dce9417918eeb..14d50d595b426 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -4449,7 +4449,7 @@ static int ath12k_wmi_hw_mode_caps(struct ath12k_base *soc, pref = soc->wmi_ab.preferred_hw_mode; - if (ath12k_hw_mode_pri_map[mode] < ath12k_hw_mode_pri_map[pref]) { + if (ath12k_hw_mode_pri_map[mode] <= ath12k_hw_mode_pri_map[pref]) { svc_rdy_ext->pref_hw_mode_caps = *hw_mode_caps; soc->wmi_ab.preferred_hw_mode = mode; } From 0f6229e218c70f97a96db0e6621f190d1a8e4d2d Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:25 +0800 Subject: [PATCH 122/140] wifi: ath12k: refactor 320 MHz bandwidth support parsing For single pdev device, 320 MHz bandwidth support is reported only in capability of WMI_HOST_HW_MODE_SINGLE mode, hence commit d4e244c85e45 ("wifi: ath12k: enable 320 MHz bandwidth for 6 GHz band in EHT PHY capability for WCN7850") relaxed the condition check in ath12k_wmi_tlv_mac_phy_caps_ext() to allow SINGLE mode getting parsed in ath12k_wmi_tlv_mac_phy_caps_ext_parse(). Since SINGLE mode is not assumed to be preferred, the function returns unconditionally after parsing 320 MHz support. This works for WCN7850 because it prefers another mode indeed, while it breaks QCC2072 since it prefers SINGLE mode. Due to the unconditional return, the subsequent EHT parsing is skipped. Consequently EHT related features are disabled. Refactor it by moving 320 MHz parsing to ath12k_wmi_tlv_mac_phy_caps_ext(), before the mode checking. This makes the code more straightforward, and work for both WCN7850 and QCC2072. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-5-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wmi.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 14d50d595b426..8baed3c5401df 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -4918,19 +4918,10 @@ ath12k_wmi_tlv_mac_phy_caps_ext_parse(struct ath12k_base *ab, const struct ath12k_wmi_caps_ext_params *caps, struct ath12k_pdev *pdev) { - struct ath12k_band_cap *cap_band; - u32 bands, support_320mhz; + u32 bands; int i; if (ab->hw_params->single_pdev_only) { - if (caps->hw_mode_id == WMI_HOST_HW_MODE_SINGLE) { - support_320mhz = le32_to_cpu(caps->eht_cap_phy_info_5ghz[0]) & - IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ; - cap_band = &pdev->cap.band[NL80211_BAND_6GHZ]; - cap_band->eht_cap_phy_info[0] |= support_320mhz; - return 0; - } - for (i = 0; i < ab->fw_pdev_count; i++) { struct ath12k_fw_pdev *fw_pdev = &ab->fw_pdev[i]; @@ -4983,14 +4974,22 @@ static int ath12k_wmi_tlv_mac_phy_caps_ext(struct ath12k_base *ab, u16 tag, void *data) { const struct ath12k_wmi_caps_ext_params *caps = ptr; + struct ath12k_band_cap *cap_band; + u32 support_320mhz; int i = 0, ret; if (tag != WMI_TAG_MAC_PHY_CAPABILITIES_EXT) return -EPROTO; if (ab->hw_params->single_pdev_only) { - if (ab->wmi_ab.preferred_hw_mode != le32_to_cpu(caps->hw_mode_id) && - caps->hw_mode_id != WMI_HOST_HW_MODE_SINGLE) + if (caps->hw_mode_id == WMI_HOST_HW_MODE_SINGLE) { + support_320mhz = le32_to_cpu(caps->eht_cap_phy_info_5ghz[0]) & + IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ; + cap_band = &ab->pdevs[0].cap.band[NL80211_BAND_6GHZ]; + cap_band->eht_cap_phy_info[0] |= support_320mhz; + } + + if (ab->wmi_ab.preferred_hw_mode != le32_to_cpu(caps->hw_mode_id)) return 0; } else { for (i = 0; i < ab->num_radios; i++) { From f9d76a28d51a09225faaca0d69301f63ad258d71 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:26 +0800 Subject: [PATCH 123/140] wifi: ath12k: fix mac phy capability parsing Currently ath12k_pull_mac_phy_cap_svc_ready_ext() assumes only one band supported in each phy, hence it skips 5 GHz band if 2 GHz band support is detected. This does not work for device which gets only one phy but has both bands supported, such as QCC2072. Change to check each band individually to fix this issue. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-6-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wmi.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 8baed3c5401df..1785adbaff12a 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -399,6 +399,7 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle, struct ath12k_band_cap *cap_band; struct ath12k_pdev_cap *pdev_cap = &pdev->cap; struct ath12k_fw_pdev *fw_pdev; + u32 supported_bands; u32 phy_map; u32 hw_idx, phy_idx = 0; int i; @@ -422,14 +423,19 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle, return -EINVAL; mac_caps = wmi_mac_phy_caps + phy_idx; + supported_bands = le32_to_cpu(mac_caps->supported_bands); + + if (!(supported_bands & WMI_HOST_WLAN_2GHZ_CAP) && + !(supported_bands & WMI_HOST_WLAN_5GHZ_CAP)) + return -EINVAL; pdev->pdev_id = ath12k_wmi_mac_phy_get_pdev_id(mac_caps); pdev->hw_link_id = ath12k_wmi_mac_phy_get_hw_link_id(mac_caps); - pdev_cap->supported_bands |= le32_to_cpu(mac_caps->supported_bands); + pdev_cap->supported_bands |= supported_bands; pdev_cap->ampdu_density = le32_to_cpu(mac_caps->ampdu_density); fw_pdev = &ab->fw_pdev[ab->fw_pdev_count]; - fw_pdev->supported_bands = le32_to_cpu(mac_caps->supported_bands); + fw_pdev->supported_bands = supported_bands; fw_pdev->pdev_id = ath12k_wmi_mac_phy_get_pdev_id(mac_caps); fw_pdev->phy_id = le32_to_cpu(mac_caps->phy_id); ab->fw_pdev_count++; @@ -438,10 +444,12 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle, * band to band for a single radio, need to see how this should be * handled. */ - if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_2GHZ_CAP) { + if (supported_bands & WMI_HOST_WLAN_2GHZ_CAP) { pdev_cap->tx_chain_mask = le32_to_cpu(mac_caps->tx_chain_mask_2g); pdev_cap->rx_chain_mask = le32_to_cpu(mac_caps->rx_chain_mask_2g); - } else if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_5GHZ_CAP) { + } + + if (supported_bands & WMI_HOST_WLAN_5GHZ_CAP) { pdev_cap->vht_cap = le32_to_cpu(mac_caps->vht_cap_info_5g); pdev_cap->vht_mcs = le32_to_cpu(mac_caps->vht_supp_mcs_5g); pdev_cap->he_mcs = le32_to_cpu(mac_caps->he_supp_mcs_5g); @@ -451,8 +459,6 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle, WMI_NSS_RATIO_EN_DIS_GET(mac_caps->nss_ratio); pdev_cap->nss_ratio_info = WMI_NSS_RATIO_INFO_GET(mac_caps->nss_ratio); - } else { - return -EINVAL; } /* tx/rx chainmask reported from fw depends on the actual hw chains used, @@ -468,7 +474,7 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle, pdev_cap->rx_chain_mask_shift = find_first_bit((unsigned long *)&pdev_cap->rx_chain_mask, 32); - if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_2GHZ_CAP) { + if (supported_bands & WMI_HOST_WLAN_2GHZ_CAP) { cap_band = &pdev_cap->band[NL80211_BAND_2GHZ]; cap_band->phy_id = le32_to_cpu(mac_caps->phy_id); cap_band->max_bw_supported = le32_to_cpu(mac_caps->max_bw_supported_2g); @@ -488,7 +494,7 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle, le32_to_cpu(mac_caps->he_ppet2g.ppet16_ppet8_ru3_ru0[i]); } - if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_5GHZ_CAP) { + if (supported_bands & WMI_HOST_WLAN_5GHZ_CAP) { cap_band = &pdev_cap->band[NL80211_BAND_5GHZ]; cap_band->phy_id = le32_to_cpu(mac_caps->phy_id); cap_band->max_bw_supported = From fd8b81feaa65de632e035b39bf768032315f541f Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:27 +0800 Subject: [PATCH 124/140] wifi: ath12k: add hardware registers for QCC2072 Add hardware registers and populate hw_regs field in ath12k_wifi7_hw_ver_map for QCC2072. Note for some registers not defined and not used by QCC2072, a magic value is assigned. Also populate other fields to be the same with WCN7850. Among them, however, QCC2072 requires different HAL ops and descriptor size, both will be updated in upcoming patches. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-7-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 1 + drivers/net/wireless/ath/ath12k/hal.h | 2 + .../net/wireless/ath/ath12k/wifi7/Makefile | 3 +- drivers/net/wireless/ath/ath12k/wifi7/hal.c | 8 ++ .../wireless/ath/ath12k/wifi7/hal_qcc2072.c | 94 +++++++++++++++++++ .../wireless/ath/ath12k/wifi7/hal_qcc2072.h | 8 ++ 6 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 31d5d10beb85a..667cf5993cf15 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -155,6 +155,7 @@ enum ath12k_hw_rev { ATH12K_HW_QCN9274_HW20, ATH12K_HW_WCN7850_HW20, ATH12K_HW_IPQ5332_HW10, + ATH12K_HW_QCC2072_HW10, }; enum ath12k_firmware_mode { diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 3575bb85f83cc..ef480de97fbe9 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1121,6 +1121,8 @@ struct ath12k_hw_hal_params { u32 wbm2sw_cc_enable; }; +#define ATH12K_HW_REG_UNDEFINED 0xdeadbeaf + struct ath12k_hw_regs { u32 tcl1_ring_id; u32 tcl1_ring_misc; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/Makefile b/drivers/net/wireless/ath/ath12k/wifi7/Makefile index dcfa732bb95bc..45b561cdba4b1 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/Makefile +++ b/drivers/net/wireless/ath/ath12k/wifi7/Makefile @@ -14,6 +14,7 @@ ath12k_wifi7-y += core.o \ dp_mon.o \ hal.o \ hal_qcn9274.o \ - hal_wcn7850.o + hal_wcn7850.o \ + hal_qcc2072.o ath12k_wifi7-$(CONFIG_ATH12K_AHB) += ahb.o diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 03a007dd6857f..b957ebc9b7c5c 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -12,6 +12,7 @@ #include "../hif.h" #include "hal_qcn9274.h" #include "hal_wcn7850.h" +#include "hal_qcc2072.h" static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = { [ATH12K_HW_QCN9274_HW10] = { @@ -42,6 +43,13 @@ static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = { .hal_params = &ath12k_hw_hal_params_ipq5332, .hw_regs = &ipq5332_regs, }, + [ATH12K_HW_QCC2072_HW10] = { + .hal_ops = &hal_wcn7850_ops, + .hal_desc_sz = sizeof(struct hal_rx_desc_wcn7850), + .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_wcn7850, + .hal_params = &ath12k_hw_hal_params_wcn7850, + .hw_regs = &qcc2072_regs, + }, }; int ath12k_wifi7_hal_init(struct ath12k_base *ab) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c new file mode 100644 index 0000000000000..6c4986050bc6a --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "hal_qcc2072.h" + +const struct ath12k_hw_regs qcc2072_regs = { + /* SW2TCL(x) R0 ring configuration address */ + .tcl1_ring_id = 0x00000920, + .tcl1_ring_misc = 0x00000928, + .tcl1_ring_tp_addr_lsb = 0x00000934, + .tcl1_ring_tp_addr_msb = 0x00000938, + .tcl1_ring_consumer_int_setup_ix0 = 0x00000948, + .tcl1_ring_consumer_int_setup_ix1 = 0x0000094c, + .tcl1_ring_msi1_base_lsb = 0x00000960, + .tcl1_ring_msi1_base_msb = 0x00000964, + .tcl1_ring_msi1_data = 0x00000968, + .tcl_ring_base_lsb = 0x00000b70, + .tcl1_ring_base_lsb = 0x00000918, + .tcl1_ring_base_msb = 0x0000091c, + .tcl2_ring_base_lsb = 0x00000990, + + /* TCL STATUS ring address */ + .tcl_status_ring_base_lsb = 0x00000d50, + + .wbm_idle_ring_base_lsb = 0x00000d3c, + .wbm_idle_ring_misc_addr = 0x00000d4c, + .wbm_r0_idle_list_cntl_addr = 0x00000240, + .wbm_r0_idle_list_size_addr = 0x00000244, + .wbm_scattered_ring_base_lsb = 0x00000250, + .wbm_scattered_ring_base_msb = 0x00000254, + .wbm_scattered_desc_head_info_ix0 = 0x00000260, + .wbm_scattered_desc_head_info_ix1 = 0x00000264, + .wbm_scattered_desc_tail_info_ix0 = 0x00000270, + .wbm_scattered_desc_tail_info_ix1 = 0x00000274, + .wbm_scattered_desc_ptr_hp_addr = 0x00000027c, + + .wbm_sw_release_ring_base_lsb = 0x0000037c, + .wbm_sw1_release_ring_base_lsb = ATH12K_HW_REG_UNDEFINED, + .wbm0_release_ring_base_lsb = 0x00000e08, + .wbm1_release_ring_base_lsb = 0x00000e80, + + /* PCIe base address */ + .pcie_qserdes_sysclk_en_sel = 0x01e0c0ac, + .pcie_pcs_osc_dtct_config_base = 0x01e0cc58, + + /* PPE release ring address */ + .ppe_rel_ring_base = 0x0000046c, + + /* REO DEST ring address */ + .reo2_ring_base = 0x00000578, + .reo1_misc_ctrl_addr = 0x00000ba0, + .reo1_sw_cookie_cfg0 = 0x0000006c, + .reo1_sw_cookie_cfg1 = 0x00000070, + .reo1_qdesc_lut_base0 = ATH12K_HW_REG_UNDEFINED, + .reo1_qdesc_lut_base1 = ATH12K_HW_REG_UNDEFINED, + + .reo1_ring_base_lsb = 0x00000500, + .reo1_ring_base_msb = 0x00000504, + .reo1_ring_id = 0x00000508, + .reo1_ring_misc = 0x00000510, + .reo1_ring_hp_addr_lsb = 0x00000514, + .reo1_ring_hp_addr_msb = 0x00000518, + .reo1_ring_producer_int_setup = 0x00000524, + .reo1_ring_msi1_base_lsb = 0x00000548, + .reo1_ring_msi1_base_msb = 0x0000054c, + .reo1_ring_msi1_data = 0x00000550, + .reo1_aging_thres_ix0 = 0x00000b2c, + .reo1_aging_thres_ix1 = 0x00000b30, + .reo1_aging_thres_ix2 = 0x00000b34, + .reo1_aging_thres_ix3 = 0x00000b38, + + /* REO Exception ring address */ + .reo2_sw0_ring_base = 0x000008c0, + + /* REO Reinject ring address */ + .sw2reo_ring_base = 0x00000320, + .sw2reo1_ring_base = 0x00000398, + + /* REO cmd ring address */ + .reo_cmd_ring_base = 0x000002a8, + + /* REO status ring address */ + .reo_status_ring_base = 0x00000aa0, + + /* CE base address */ + .umac_ce0_src_reg_base = 0x01b80000, + .umac_ce0_dest_reg_base = 0x01b81000, + .umac_ce1_src_reg_base = 0x01b82000, + .umac_ce1_dest_reg_base = 0x01b83000, + + .gcc_gcc_pcie_hot_rst = 0x1e65304, +}; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h new file mode 100644 index 0000000000000..744d7e02b46e6 --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "../hal.h" + +extern const struct ath12k_hw_regs qcc2072_regs; From f2a2ea0b35ea7bf1dfb2ada51cf4484be99b1a42 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:28 +0800 Subject: [PATCH 125/140] wifi: ath12k: add hardware parameters for QCC2072 Add hardware parameters for QCC2072, these parameters are directly taken from WCN7850, with exceptions to hardware name, revision, firmware directory, iova_mask and RFKILL parameter set. Compared to WCN7850, QCC2072 doesn't require aligned IOVA when transmitting packets, hence iova_mask is set to zero. Besides, WCN7850 has a dedicated GPIO for RFKILL purpose, however QCC2072 has it coupled with WLAN_EN pin. For QCC2072, host is not allowed to send any RFKILL configuration info to firmware, or firmware crashes. Hence those parameters are all cleared to skip configuring command. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-8-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wifi7/hw.c | 85 ++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 1f5dda73230d0..ef0a59f6339cf 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -652,6 +652,91 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .dp_primary_link_only = true, }, + { + .name = "qcc2072 hw1.0", + .hw_rev = ATH12K_HW_QCC2072_HW10, + + .fw = { + .dir = "QCC2072/hw1.0", + .board_size = 256 * 1024, + .cal_offset = 256 * 1024, + .m3_loader = ath12k_m3_fw_loader_driver, + }, + + .max_radios = 1, + .single_pdev_only = true, + .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_WCN7850, + .internal_sleep_clock = true, + + .hw_ops = &wcn7850_ops, + .ring_mask = &ath12k_wifi7_hw_ring_mask_wcn7850, + + .host_ce_config = ath12k_wifi7_host_ce_config_wcn7850, + .ce_count = 9, + .target_ce_config = ath12k_wifi7_target_ce_config_wlan_wcn7850, + .target_ce_count = 9, + .svc_to_ce_map = + ath12k_wifi7_target_service_to_ce_map_wlan_wcn7850, + .svc_to_ce_map_len = 14, + + .rxdma1_enable = false, + .num_rxdma_per_pdev = 2, + .num_rxdma_dst_ring = 1, + .rx_mac_buf_ring = true, + .vdev_start_delay = true, + + .interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_DEVICE) | + BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO), + .supports_monitor = true, + + .idle_ps = true, + .download_calib = false, + .supports_suspend = true, + .tcl_ring_retry = false, + .reoq_lut_support = false, + .supports_shadow_regs = true, + + .num_tcl_banks = 7, + .max_tx_ring = 3, + + .mhi_config = &ath12k_wifi7_mhi_config_wcn7850, + + .wmi_init = ath12k_wifi7_wmi_init_wcn7850, + + .qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01) | + BIT(CNSS_PCIE_PERST_NO_PULL_V01), + + .rfkill_pin = 0, + .rfkill_cfg = 0, + .rfkill_on_level = 0, + + .rddm_size = 0x780000, + + .def_num_link = 2, + .max_mlo_peer = 32, + + .otp_board_id_register = 0, + + .supports_sta_ps = true, + + .acpi_guid = &wcn7850_uuid, + .supports_dynamic_smps_6ghz = false, + + .iova_mask = 0, + + .supports_aspm = true, + + .ce_ie_addr = NULL, + .ce_remap = NULL, + .bdf_addr_offset = 0, + + .current_cc_support = true, + + .dp_primary_link_only = false, + }, }; /* Note: called under rcu_read_lock() */ From 63c38cc811130620a5757beba1d4e053a42d9003 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:29 +0800 Subject: [PATCH 126/140] wifi: ath12k: support LPASS_SHARED target memory type QCC2072 requires a new type of QMI target memory named LPASS_SHARED_V01, add support for it. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-9-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/qmi.c | 1 + drivers/net/wireless/ath/ath12k/qmi.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c index b7c48b6706dfc..4966697f4e625 100644 --- a/drivers/net/wireless/ath/ath12k/qmi.c +++ b/drivers/net/wireless/ath/ath12k/qmi.c @@ -2609,6 +2609,7 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab) case M3_DUMP_REGION_TYPE: case PAGEABLE_MEM_REGION_TYPE: case CALDB_MEM_REGION_TYPE: + case LPASS_SHARED_V01_REGION_TYPE: ret = ath12k_qmi_alloc_chunk(ab, chunk); if (ret) goto err; diff --git a/drivers/net/wireless/ath/ath12k/qmi.h b/drivers/net/wireless/ath/ath12k/qmi.h index 7a88268aa1e9e..050dcaca1cb75 100644 --- a/drivers/net/wireless/ath/ath12k/qmi.h +++ b/drivers/net/wireless/ath/ath12k/qmi.h @@ -178,6 +178,7 @@ enum ath12k_qmi_target_mem { CALDB_MEM_REGION_TYPE = 0x4, MLO_GLOBAL_MEM_REGION_TYPE = 0x8, PAGEABLE_MEM_REGION_TYPE = 0x9, + LPASS_SHARED_V01_REGION_TYPE = 0xb, }; enum qmi_wlanfw_host_build_type { From 83c5316835bbaeacc8e573ac1758b5823f7f440b Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:30 +0800 Subject: [PATCH 127/140] wifi: ath12k: support downloading auxiliary ucode image for QCC2072 QCC2072 requires another firmware image named aux_ucode.bin, add support to download it. Add a new hardware parameter download_aux_ucode to make sure other chips are not affected. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-10-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/core.h | 2 + drivers/net/wireless/ath/ath12k/fw.c | 10 +- drivers/net/wireless/ath/ath12k/fw.h | 3 +- drivers/net/wireless/ath/ath12k/hw.h | 2 + drivers/net/wireless/ath/ath12k/qmi.c | 179 ++++++++++++++++++++- drivers/net/wireless/ath/ath12k/qmi.h | 15 ++ drivers/net/wireless/ath/ath12k/wifi7/hw.c | 8 +- 7 files changed, 215 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 667cf5993cf15..990934ec92fca 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -1082,6 +1082,8 @@ struct ath12k_base { size_t amss_dualmac_len; const u8 *m3_data; size_t m3_len; + const u8 *aux_uc_data; + size_t aux_uc_len; DECLARE_BITMAP(fw_features, ATH12K_FW_FEATURE_COUNT); bool fw_features_valid; diff --git a/drivers/net/wireless/ath/ath12k/fw.c b/drivers/net/wireless/ath/ath12k/fw.c index 5ac497f80cad8..22074653cbb82 100644 --- a/drivers/net/wireless/ath/ath12k/fw.c +++ b/drivers/net/wireless/ath/ath12k/fw.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* - * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include "core.h" @@ -121,6 +121,14 @@ static int ath12k_fw_request_firmware_api_n(struct ath12k_base *ab, ab->fw.m3_data = data; ab->fw.m3_len = ie_len; break; + case ATH12K_FW_IE_AUX_UC_IMAGE: + ath12k_dbg(ab, ATH12K_DBG_BOOT, + "found aux_uc image ie (%zd B)\n", + ie_len); + + ab->fw.aux_uc_data = data; + ab->fw.aux_uc_len = ie_len; + break; case ATH12K_FW_IE_AMSS_DUALMAC_IMAGE: ath12k_dbg(ab, ATH12K_DBG_BOOT, "found dualmac fw image ie (%zd B)\n", diff --git a/drivers/net/wireless/ath/ath12k/fw.h b/drivers/net/wireless/ath/ath12k/fw.h index 7afaefed5086f..e146d24dfea4d 100644 --- a/drivers/net/wireless/ath/ath12k/fw.h +++ b/drivers/net/wireless/ath/ath12k/fw.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* - * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_FW_H @@ -15,6 +15,7 @@ enum ath12k_fw_ie_type { ATH12K_FW_IE_AMSS_IMAGE = 2, ATH12K_FW_IE_M3_IMAGE = 3, ATH12K_FW_IE_AMSS_DUALMAC_IMAGE = 4, + ATH12K_FW_IE_AUX_UC_IMAGE = 5, }; enum ath12k_fw_features { diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h index 655753d0413ae..a9888e0521a1d 100644 --- a/drivers/net/wireless/ath/ath12k/hw.h +++ b/drivers/net/wireless/ath/ath12k/hw.h @@ -78,6 +78,7 @@ #define ATH12K_DEFAULT_CAL_FILE "caldata.bin" #define ATH12K_AMSS_FILE "amss.bin" #define ATH12K_M3_FILE "m3.bin" +#define ATH12K_AUX_UC_FILE "aux_ucode.bin" #define ATH12K_REGDB_FILE_NAME "regdb.bin" #define ATH12K_PCIE_MAX_PAYLOAD_SIZE 128 @@ -142,6 +143,7 @@ struct ath12k_hw_params { size_t board_size; size_t cal_offset; enum ath12k_m3_fw_loaders m3_loader; + bool download_aux_ucode:1; } fw; u8 max_radios; diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c index 4966697f4e625..cfde4147c8fc9 100644 --- a/drivers/net/wireless/ath/ath12k/qmi.c +++ b/drivers/net/wireless/ath/ath12k/qmi.c @@ -1623,6 +1623,47 @@ static const struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = { }, }; +static const struct qmi_elem_info qmi_wlanfw_aux_uc_info_req_msg_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_8_BYTE, + .elem_len = 1, + .elem_size = sizeof(u64), + .array_type = NO_ARRAY, + .tlv_type = 0x01, + .offset = offsetof(struct qmi_wlanfw_aux_uc_info_req_msg_v01, addr), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .array_type = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct qmi_wlanfw_aux_uc_info_req_msg_v01, size), + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + +static const struct qmi_elem_info qmi_wlanfw_aux_uc_info_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct qmi_wlanfw_aux_uc_info_resp_msg_v01, resp), + .ei_array = qmi_response_type_v01_ei, + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + static const struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = { { .data_type = QMI_UNSIGNED_4_BYTE, @@ -3237,6 +3278,131 @@ int ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base *ab) return ret; } +static void ath12k_qmi_aux_uc_free(struct ath12k_base *ab) +{ + struct m3_mem_region *aux_uc_mem = &ab->qmi.aux_uc_mem; + + if (!aux_uc_mem->vaddr) + return; + + dma_free_coherent(ab->dev, aux_uc_mem->total_size, + aux_uc_mem->vaddr, aux_uc_mem->paddr); + aux_uc_mem->vaddr = NULL; + aux_uc_mem->total_size = 0; + aux_uc_mem->size = 0; +} + +static int ath12k_qmi_aux_uc_load(struct ath12k_base *ab) +{ + struct m3_mem_region *aux_uc_mem = &ab->qmi.aux_uc_mem; + const struct firmware *fw = NULL; + const void *aux_uc_data; + char path[100]; + size_t aux_uc_len; + int ret; + + if (ab->fw.aux_uc_data && ab->fw.aux_uc_len > 0) { + /* firmware-N.bin had a aux_uc firmware file so use that */ + aux_uc_data = ab->fw.aux_uc_data; + aux_uc_len = ab->fw.aux_uc_len; + } else { + /* + * No aux_uc file in firmware-N.bin so try to request old + * separate aux_ucode.bin. + */ + fw = ath12k_core_firmware_request(ab, ATH12K_AUX_UC_FILE); + if (IS_ERR(fw)) { + ret = PTR_ERR(fw); + ath12k_core_create_firmware_path(ab, ATH12K_AUX_UC_FILE, + path, sizeof(path)); + ath12k_err(ab, "failed to load %s: %d\n", path, ret); + return ret; + } + + aux_uc_data = fw->data; + aux_uc_len = fw->size; + } + + /* In recovery/resume cases, AUX_UC buffer is not freed, try to reuse that */ + if (aux_uc_mem->vaddr) { + if (aux_uc_mem->total_size >= aux_uc_len) + goto copy; + + /* Old buffer is too small, free and reallocate */ + ath12k_qmi_aux_uc_free(ab); + } + + aux_uc_mem->vaddr = dma_alloc_coherent(ab->dev, aux_uc_len, + &aux_uc_mem->paddr, GFP_KERNEL); + if (!aux_uc_mem->vaddr) { + ret = -ENOMEM; + goto out; + } + + aux_uc_mem->total_size = aux_uc_len; + +copy: + memcpy(aux_uc_mem->vaddr, aux_uc_data, aux_uc_len); + aux_uc_mem->size = aux_uc_len; + + ret = 0; + +out: + release_firmware(fw); + + return ret; +} + +static noinline_for_stack +int ath12k_qmi_wlanfw_aux_uc_info_send(struct ath12k_base *ab) +{ + struct m3_mem_region *aux_uc_mem = &ab->qmi.aux_uc_mem; + struct qmi_wlanfw_aux_uc_info_req_msg_v01 req = {}; + struct qmi_wlanfw_aux_uc_info_resp_msg_v01 resp = {}; + struct qmi_txn txn; + int ret = 0; + + ret = ath12k_qmi_aux_uc_load(ab); + if (ret) { + ath12k_err(ab, "failed to load aux_uc firmware: %d", ret); + return ret; + } + + req.addr = aux_uc_mem->paddr; + req.size = aux_uc_mem->size; + + ret = qmi_txn_init(&ab->qmi.handle, &txn, + qmi_wlanfw_aux_uc_info_resp_msg_v01_ei, &resp); + if (ret < 0) + goto out; + + ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, + QMI_WLANFW_AUX_UC_INFO_REQ_V01, + QMI_WLANFW_AUX_UC_INFO_REQ_MSG_V01_MAX_MSG_LEN, + qmi_wlanfw_aux_uc_info_req_msg_v01_ei, &req); + if (ret < 0) { + qmi_txn_cancel(&txn); + ath12k_warn(ab, "qmi failed to send AUX_UC information request, err = %d\n", + ret); + goto out; + } + + ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS)); + if (ret < 0) { + ath12k_warn(ab, "qmi failed AUX_UC information request %d\n", ret); + goto out; + } + + if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { + ath12k_warn(ab, "qmi AUX_UC info request failed, result: %d, err: %d\n", + resp.resp.result, resp.resp.error); + ret = -EINVAL; + goto out; + } +out: + return ret; +} + static int ath12k_qmi_wlanfw_mode_send(struct ath12k_base *ab, u32 mode) { @@ -3601,6 +3767,7 @@ static noinline_for_stack int ath12k_qmi_event_load_bdf(struct ath12k_qmi *qmi) { struct ath12k_base *ab = qmi->ab; + const struct ath12k_hw_params *hw_params = ab->hw_params; int ret; ret = ath12k_qmi_request_target_cap(ab); @@ -3621,7 +3788,7 @@ int ath12k_qmi_event_load_bdf(struct ath12k_qmi *qmi) return ret; } - if (ab->hw_params->download_calib) { + if (hw_params->download_calib) { ret = ath12k_qmi_load_bdf_qmi(ab, ATH12K_QMI_BDF_TYPE_CALIBRATION); if (ret < 0) ath12k_warn(ab, "qmi failed to load calibrated data :%d\n", ret); @@ -3633,6 +3800,14 @@ int ath12k_qmi_event_load_bdf(struct ath12k_qmi *qmi) return ret; } + if (hw_params->fw.download_aux_ucode) { + ret = ath12k_qmi_wlanfw_aux_uc_info_send(ab); + if (ret < 0) { + ath12k_warn(ab, "qmi failed to send aux_uc info req: %d\n", ret); + return ret; + } + } + return ret; } @@ -3906,6 +4081,7 @@ void ath12k_qmi_deinit_service(struct ath12k_base *ab) qmi_handle_release(&ab->qmi.handle); cancel_work_sync(&ab->qmi.event_work); destroy_workqueue(ab->qmi.event_wq); + ath12k_qmi_aux_uc_free(ab); ath12k_qmi_m3_free(ab); ath12k_qmi_free_target_mem_chunk(ab); ab->qmi.ab = NULL; @@ -3914,5 +4090,6 @@ void ath12k_qmi_deinit_service(struct ath12k_base *ab) void ath12k_qmi_free_resource(struct ath12k_base *ab) { ath12k_qmi_free_target_mem_chunk(ab); + ath12k_qmi_aux_uc_free(ab); ath12k_qmi_m3_free(ab); } diff --git a/drivers/net/wireless/ath/ath12k/qmi.h b/drivers/net/wireless/ath/ath12k/qmi.h index 050dcaca1cb75..b5a4a01391cba 100644 --- a/drivers/net/wireless/ath/ath12k/qmi.h +++ b/drivers/net/wireless/ath/ath12k/qmi.h @@ -154,6 +154,7 @@ struct ath12k_qmi { u8 num_radios; struct target_info target; struct m3_mem_region m3_mem; + struct m3_mem_region aux_uc_mem; unsigned int service_ins_id; struct dev_mem_info dev_mem[ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01]; }; @@ -203,6 +204,7 @@ enum ath12k_qmi_cnss_feature { CNSS_FEATURE_MIN_ENUM_VAL_V01 = INT_MIN, CNSS_QDSS_CFG_MISS_V01 = 3, CNSS_PCIE_PERST_NO_PULL_V01 = 4, + CNSS_AUX_UC_SUPPORT_V01 = 6, CNSS_MAX_FEATURE_V01 = 64, CNSS_FEATURE_MAX_ENUM_VAL_V01 = INT_MAX, }; @@ -541,6 +543,19 @@ struct qmi_wlanfw_m3_info_resp_msg_v01 { struct qmi_response_type_v01 resp; }; +#define QMI_WLANFW_AUX_UC_INFO_REQ_MSG_V01_MAX_MSG_LEN 18 +#define QMI_WLANFW_AUX_UC_INFO_RESP_MSG_V01_MAX_MSG_LEN 7 +#define QMI_WLANFW_AUX_UC_INFO_REQ_V01 0x005A + +struct qmi_wlanfw_aux_uc_info_req_msg_v01 { + u64 addr; + u32 size; +}; + +struct qmi_wlanfw_aux_uc_info_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; + #define QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN 11 #define QMI_WLANFW_WLAN_MODE_RESP_MSG_V01_MAX_LEN 7 #define QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN 803 diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index ef0a59f6339cf..38c388319e008 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -339,6 +339,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .board_size = 256 * 1024, .cal_offset = 128 * 1024, .m3_loader = ath12k_m3_fw_loader_driver, + .download_aux_ucode = false, }, .max_radios = 1, .single_pdev_only = false, @@ -421,6 +422,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .board_size = 256 * 1024, .cal_offset = 256 * 1024, .m3_loader = ath12k_m3_fw_loader_driver, + .download_aux_ucode = false, }, .max_radios = 1, @@ -505,6 +507,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .board_size = 256 * 1024, .cal_offset = 128 * 1024, .m3_loader = ath12k_m3_fw_loader_driver, + .download_aux_ucode = false, }, .max_radios = 2, .single_pdev_only = false, @@ -586,6 +589,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .board_size = 256 * 1024, .cal_offset = 128 * 1024, .m3_loader = ath12k_m3_fw_loader_remoteproc, + .download_aux_ucode = false, }, .max_radios = 1, .single_pdev_only = false, @@ -661,6 +665,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .board_size = 256 * 1024, .cal_offset = 256 * 1024, .m3_loader = ath12k_m3_fw_loader_driver, + .download_aux_ucode = true, }, .max_radios = 1, @@ -707,7 +712,8 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .wmi_init = ath12k_wifi7_wmi_init_wcn7850, .qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01) | - BIT(CNSS_PCIE_PERST_NO_PULL_V01), + BIT(CNSS_PCIE_PERST_NO_PULL_V01) | + BIT(CNSS_AUX_UC_SUPPORT_V01), .rfkill_pin = 0, .rfkill_cfg = 0, From 118c0f59f5f0ad2a1ef15c3e158c1116dd90a081 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:31 +0800 Subject: [PATCH 128/140] wifi: ath12k: add HAL descriptor and ops for QCC2072 QCC2072 has different HAL descriptors hence require different HAL handling, compared to other chips. Add support for this. REO CMD/status ring handling is currently using the 64 bit ops .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring_tlv64, .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr, .reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr, these will be updated to use 32 bit variants in upcoming patches. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-11-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wifi7/hal.c | 4 +- .../wireless/ath/ath12k/wifi7/hal_qcc2072.c | 362 ++++++++++++++++++ .../wireless/ath/ath12k/wifi7/hal_qcc2072.h | 2 + .../wireless/ath/ath12k/wifi7/hal_rx_desc.h | 17 + .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 2 +- .../wireless/ath/ath12k/wifi7/hal_wcn7850.h | 1 + 6 files changed, 385 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index b957ebc9b7c5c..bd1753ca0db67 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -44,8 +44,8 @@ static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = { .hw_regs = &ipq5332_regs, }, [ATH12K_HW_QCC2072_HW10] = { - .hal_ops = &hal_wcn7850_ops, - .hal_desc_sz = sizeof(struct hal_rx_desc_wcn7850), + .hal_ops = &hal_qcc2072_ops, + .hal_desc_sz = sizeof(struct hal_rx_desc_qcc2072), .tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_wcn7850, .hal_params = &ath12k_hw_hal_params_wcn7850, .hw_regs = &qcc2072_regs, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c index 6c4986050bc6a..847484ece2044 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c @@ -4,6 +4,7 @@ */ #include "hal_qcc2072.h" +#include "hal_wcn7850.h" const struct ath12k_hw_regs qcc2072_regs = { /* SW2TCL(x) R0 ring configuration address */ @@ -92,3 +93,364 @@ const struct ath12k_hw_regs qcc2072_regs = { .gcc_gcc_pcie_hot_rst = 0x1e65304, }; + +static void ath12k_hal_rx_desc_set_msdu_len_qcc2072(struct hal_rx_desc *desc, u16 len) +{ + u32 info = __le32_to_cpu(desc->u.qcc2072.msdu_end.info10); + + info &= ~RX_MSDU_END_INFO10_MSDU_LENGTH; + info |= u32_encode_bits(len, RX_MSDU_END_INFO10_MSDU_LENGTH); + + desc->u.qcc2072.msdu_end.info10 = __cpu_to_le32(info); +} + +static void ath12k_hal_rx_desc_get_dot11_hdr_qcc2072(struct hal_rx_desc *desc, + struct ieee80211_hdr *hdr) +{ + hdr->frame_control = desc->u.qcc2072.mpdu_start.frame_ctrl; + hdr->duration_id = desc->u.qcc2072.mpdu_start.duration; + ether_addr_copy(hdr->addr1, desc->u.qcc2072.mpdu_start.addr1); + ether_addr_copy(hdr->addr2, desc->u.qcc2072.mpdu_start.addr2); + ether_addr_copy(hdr->addr3, desc->u.qcc2072.mpdu_start.addr3); + + if (__le32_to_cpu(desc->u.qcc2072.mpdu_start.info4) & + RX_MPDU_START_INFO4_MAC_ADDR4_VALID) + ether_addr_copy(hdr->addr4, desc->u.qcc2072.mpdu_start.addr4); + + hdr->seq_ctrl = desc->u.qcc2072.mpdu_start.seq_ctrl; +} + +static void ath12k_hal_rx_desc_get_crypto_hdr_qcc2072(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype) +{ + unsigned int key_id; + + switch (enctype) { + case HAL_ENCRYPT_TYPE_OPEN: + return; + case HAL_ENCRYPT_TYPE_TKIP_NO_MIC: + case HAL_ENCRYPT_TYPE_TKIP_MIC: + crypto_hdr[0] = + HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcc2072.mpdu_start.pn[0]); + crypto_hdr[1] = 0; + crypto_hdr[2] = + HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcc2072.mpdu_start.pn[0]); + break; + case HAL_ENCRYPT_TYPE_CCMP_128: + case HAL_ENCRYPT_TYPE_CCMP_256: + case HAL_ENCRYPT_TYPE_GCMP_128: + case HAL_ENCRYPT_TYPE_AES_GCMP_256: + crypto_hdr[0] = + HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcc2072.mpdu_start.pn[0]); + crypto_hdr[1] = + HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcc2072.mpdu_start.pn[0]); + crypto_hdr[2] = 0; + break; + case HAL_ENCRYPT_TYPE_WEP_40: + case HAL_ENCRYPT_TYPE_WEP_104: + case HAL_ENCRYPT_TYPE_WEP_128: + case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4: + case HAL_ENCRYPT_TYPE_WAPI: + return; + } + + key_id = u32_get_bits(__le32_to_cpu(desc->u.qcc2072.mpdu_start.info5), + RX_MPDU_START_INFO5_KEY_ID); + crypto_hdr[3] = 0x20 | (key_id << 6); + crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.qcc2072.mpdu_start.pn[0]); + crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.qcc2072.mpdu_start.pn[0]); + crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcc2072.mpdu_start.pn[1]); + crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcc2072.mpdu_start.pn[1]); +} + +static void ath12k_hal_rx_desc_copy_end_tlv_qcc2072(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc) +{ + memcpy(&fdesc->u.qcc2072.msdu_end, &ldesc->u.qcc2072.msdu_end, + sizeof(struct rx_msdu_end_qcn9274)); +} + +static u8 ath12k_hal_rx_desc_get_msdu_src_link_qcc2072(struct hal_rx_desc *desc) +{ + return 0; +} + +static u8 ath12k_hal_rx_desc_get_l3_pad_bytes_qcc2072(struct hal_rx_desc *desc) +{ + return le16_get_bits(desc->u.qcc2072.msdu_end.info5, + RX_MSDU_END_INFO5_L3_HDR_PADDING); +} + +static u32 ath12k_hal_rx_desc_get_mpdu_start_tag_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.mpdu_start_tag, + HAL_TLV_HDR_TAG); +} + +static u32 ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcc2072(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->u.qcc2072.mpdu_start.phy_ppdu_id); +} + +static u8 *ath12k_hal_rx_desc_get_msdu_payload_qcc2072(struct hal_rx_desc *desc) +{ + return &desc->u.qcc2072.msdu_payload[0]; +} + +static bool ath12k_hal_rx_desc_get_first_msdu_qcc2072(struct hal_rx_desc *desc) +{ + return !!le16_get_bits(desc->u.qcc2072.msdu_end.info5, + RX_MSDU_END_INFO5_FIRST_MSDU); +} + +static bool ath12k_hal_rx_desc_get_last_msdu_qcc2072(struct hal_rx_desc *desc) +{ + return !!le16_get_bits(desc->u.qcc2072.msdu_end.info5, + RX_MSDU_END_INFO5_LAST_MSDU); +} + +static bool ath12k_hal_rx_desc_encrypt_valid_qcc2072(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcc2072.mpdu_start.info4, + RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); +} + +static u32 ath12k_hal_rx_desc_get_encrypt_type_qcc2072(struct hal_rx_desc *desc) +{ + if (!ath12k_hal_rx_desc_encrypt_valid_qcc2072(desc)) + return HAL_ENCRYPT_TYPE_OPEN; + + return le32_get_bits(desc->u.qcc2072.mpdu_start.info2, + RX_MPDU_START_INFO2_ENC_TYPE); +} + +static u8 ath12k_hal_rx_desc_get_decap_type_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.msdu_end.info11, + RX_MSDU_END_INFO11_DECAP_FORMAT); +} + +static u8 ath12k_hal_rx_desc_get_mesh_ctl_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.msdu_end.info11, + RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); +} + +static bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcc2072(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcc2072.mpdu_start.info4, + RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); +} + +static bool ath12k_hal_rx_desc_get_mpdu_fc_valid_qcc2072(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcc2072.mpdu_start.info4, + RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); +} + +static u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.mpdu_start.info4, + RX_MPDU_START_INFO4_MPDU_SEQ_NUM); +} + +static u16 ath12k_hal_rx_desc_get_msdu_len_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.msdu_end.info10, + RX_MSDU_END_INFO10_MSDU_LENGTH); +} + +static u8 ath12k_hal_rx_desc_get_msdu_sgi_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.msdu_end.info12, + RX_MSDU_END_INFO12_SGI); +} + +static u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.msdu_end.info12, + RX_MSDU_END_INFO12_RATE_MCS); +} + +static u8 ath12k_hal_rx_desc_get_msdu_rx_bw_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.msdu_end.info12, + RX_MSDU_END_INFO12_RECV_BW); +} + +static u32 ath12k_hal_rx_desc_get_msdu_freq_qcc2072(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.qcc2072.msdu_end.phy_meta_data); +} + +static u8 ath12k_hal_rx_desc_get_msdu_pkt_type_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.msdu_end.info12, + RX_MSDU_END_INFO12_PKT_TYPE); +} + +static u8 ath12k_hal_rx_desc_get_msdu_nss_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.msdu_end.info12, + RX_MSDU_END_INFO12_MIMO_SS_BITMAP); +} + +static u8 ath12k_hal_rx_desc_get_mpdu_tid_qcc2072(struct hal_rx_desc *desc) +{ + return le32_get_bits(desc->u.qcc2072.mpdu_start.info2, + RX_MPDU_START_INFO2_TID); +} + +static u16 ath12k_hal_rx_desc_get_mpdu_peer_id_qcc2072(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->u.qcc2072.mpdu_start.sw_peer_id); +} + +static bool ath12k_hal_rx_desc_mac_addr2_valid_qcc2072(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.qcc2072.mpdu_start.info4) & + RX_MPDU_START_INFO4_MAC_ADDR2_VALID; +} + +static u8 *ath12k_hal_rx_desc_mpdu_start_addr2_qcc2072(struct hal_rx_desc *desc) +{ + return desc->u.qcc2072.mpdu_start.addr2; +} + +static bool ath12k_hal_rx_desc_is_da_mcbc_qcc2072(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.qcc2072.msdu_end.info13) & + RX_MSDU_END_INFO13_MCAST_BCAST; +} + +static bool ath12k_hal_rx_h_msdu_done_qcc2072(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcc2072.msdu_end.info14, + RX_MSDU_END_INFO14_MSDU_DONE); +} + +static bool ath12k_hal_rx_h_l4_cksum_fail_qcc2072(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcc2072.msdu_end.info13, + RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); +} + +static bool ath12k_hal_rx_h_ip_cksum_fail_qcc2072(struct hal_rx_desc *desc) +{ + return !!le32_get_bits(desc->u.qcc2072.msdu_end.info13, + RX_MSDU_END_INFO13_IP_CKSUM_FAIL); +} + +static bool ath12k_hal_rx_h_is_decrypted_qcc2072(struct hal_rx_desc *desc) +{ + return (le32_get_bits(desc->u.qcc2072.msdu_end.info14, + RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == + RX_DESC_DECRYPT_STATUS_CODE_OK); +} + +static u32 ath12k_hal_rx_h_mpdu_err_qcc2072(struct hal_rx_desc *desc) +{ + u32 info = __le32_to_cpu(desc->u.qcc2072.msdu_end.info13); + u32 errmap = 0; + + if (info & RX_MSDU_END_INFO13_FCS_ERR) + errmap |= HAL_RX_MPDU_ERR_FCS; + + if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) + errmap |= HAL_RX_MPDU_ERR_DECRYPT; + + if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) + errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; + + if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) + errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; + + if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) + errmap |= HAL_RX_MPDU_ERR_OVERFLOW; + + if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) + errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; + + if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) + errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; + + return errmap; +} + +static void ath12k_hal_extract_rx_desc_data_qcc2072(struct hal_rx_desc_data *rx_desc_data, + struct hal_rx_desc *rx_desc, + struct hal_rx_desc *ldesc) +{ + rx_desc_data->is_first_msdu = ath12k_hal_rx_desc_get_first_msdu_qcc2072(ldesc); + rx_desc_data->is_last_msdu = ath12k_hal_rx_desc_get_last_msdu_qcc2072(ldesc); + rx_desc_data->l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcc2072(ldesc); + rx_desc_data->enctype = ath12k_hal_rx_desc_get_encrypt_type_qcc2072(rx_desc); + rx_desc_data->decap_type = ath12k_hal_rx_desc_get_decap_type_qcc2072(rx_desc); + rx_desc_data->mesh_ctrl_present = + ath12k_hal_rx_desc_get_mesh_ctl_qcc2072(rx_desc); + rx_desc_data->seq_ctl_valid = + ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcc2072(rx_desc); + rx_desc_data->fc_valid = ath12k_hal_rx_desc_get_mpdu_fc_valid_qcc2072(rx_desc); + rx_desc_data->seq_no = ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcc2072(rx_desc); + rx_desc_data->msdu_len = ath12k_hal_rx_desc_get_msdu_len_qcc2072(ldesc); + rx_desc_data->sgi = ath12k_hal_rx_desc_get_msdu_sgi_qcc2072(rx_desc); + rx_desc_data->rate_mcs = ath12k_hal_rx_desc_get_msdu_rate_mcs_qcc2072(rx_desc); + rx_desc_data->bw = ath12k_hal_rx_desc_get_msdu_rx_bw_qcc2072(rx_desc); + rx_desc_data->phy_meta_data = ath12k_hal_rx_desc_get_msdu_freq_qcc2072(rx_desc); + rx_desc_data->pkt_type = ath12k_hal_rx_desc_get_msdu_pkt_type_qcc2072(rx_desc); + rx_desc_data->nss = hweight8(ath12k_hal_rx_desc_get_msdu_nss_qcc2072(rx_desc)); + rx_desc_data->tid = ath12k_hal_rx_desc_get_mpdu_tid_qcc2072(rx_desc); + rx_desc_data->peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_qcc2072(rx_desc); + rx_desc_data->addr2_present = ath12k_hal_rx_desc_mac_addr2_valid_qcc2072(rx_desc); + rx_desc_data->addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_qcc2072(rx_desc); + rx_desc_data->is_mcbc = ath12k_hal_rx_desc_is_da_mcbc_qcc2072(rx_desc); + rx_desc_data->msdu_done = ath12k_hal_rx_h_msdu_done_qcc2072(ldesc); + rx_desc_data->l4_csum_fail = ath12k_hal_rx_h_l4_cksum_fail_qcc2072(rx_desc); + rx_desc_data->ip_csum_fail = ath12k_hal_rx_h_ip_cksum_fail_qcc2072(rx_desc); + rx_desc_data->is_decrypted = ath12k_hal_rx_h_is_decrypted_qcc2072(rx_desc); + rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_qcc2072(rx_desc); +} + +const struct hal_ops hal_qcc2072_ops = { + .create_srng_config = ath12k_hal_srng_create_config_wcn7850, + .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcc2072, + .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_qcc2072, + .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcc2072, + .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcc2072, + .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_qcc2072, + .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_qcc2072, + .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcc2072, + .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_qcc2072, + .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcc2072, + .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcc2072, + .ce_dst_setup = ath12k_wifi7_hal_ce_dst_setup, + .srng_src_hw_init = ath12k_wifi7_hal_srng_src_hw_init, + .srng_dst_hw_init = ath12k_wifi7_hal_srng_dst_hw_init, + .set_umac_srng_ptr_addr = ath12k_wifi7_hal_set_umac_srng_ptr_addr, + .srng_update_shadow_config = ath12k_wifi7_hal_srng_update_shadow_config, + .srng_get_ring_id = ath12k_wifi7_hal_srng_get_ring_id, + .ce_get_desc_size = ath12k_wifi7_hal_ce_get_desc_size, + .ce_src_set_desc = ath12k_wifi7_hal_ce_src_set_desc, + .ce_dst_set_desc = ath12k_wifi7_hal_ce_dst_set_desc, + .ce_dst_status_get_length = ath12k_wifi7_hal_ce_dst_status_get_length, + .set_link_desc_addr = ath12k_wifi7_hal_set_link_desc_addr, + .tx_set_dscp_tid_map = ath12k_wifi7_hal_tx_set_dscp_tid_map, + .tx_configure_bank_register = + ath12k_wifi7_hal_tx_configure_bank_register, + .reoq_lut_addr_read_enable = ath12k_wifi7_hal_reoq_lut_addr_read_enable, + .reoq_lut_set_max_peerid = ath12k_wifi7_hal_reoq_lut_set_max_peerid, + .write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr, + .write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr, + .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list, + .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring_tlv64, + .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup, + .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set, + .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, + .cc_config = ath12k_wifi7_hal_cc_config, + .get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm, + .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, + .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, + .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr, + .reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr, +}; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h index 744d7e02b46e6..392bfbb6a4124 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h @@ -4,5 +4,7 @@ */ #include "../hal.h" +#include "hal.h" extern const struct ath12k_hw_regs qcc2072_regs; +extern const struct hal_ops hal_qcc2072_ops; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h index cc5e1d336376a..0d19a9cbb68ce 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h @@ -1481,10 +1481,27 @@ struct hal_rx_desc_wcn7850 { u8 msdu_payload[]; }; +struct rx_pkt_hdr_tlv_qcc2072 { + __le32 tag; + __le64 phy_ppdu_id; + u8 rx_pkt_hdr[HAL_RX_BE_PKT_HDR_TLV_LEN]; +}; + +struct hal_rx_desc_qcc2072 { + __le32 msdu_end_tag; + struct rx_msdu_end_qcn9274 msdu_end; + u8 rx_padding0[RX_BE_PADDING0_BYTES]; + __le32 mpdu_start_tag; + struct rx_mpdu_start_qcn9274 mpdu_start; + struct rx_pkt_hdr_tlv_qcc2072 pkt_hdr_tlv; + u8 msdu_payload[]; +}; + struct hal_rx_desc { union { struct hal_rx_desc_qcn9274_compact qcn9274_compact; struct hal_rx_desc_wcn7850 wcn7850; + struct hal_rx_desc_qcc2072 qcc2072; } u; } __packed; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index c3093c01af878..88f51a3828aac 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -614,7 +614,7 @@ void ath12k_hal_extract_rx_desc_data_wcn7850(struct hal_rx_desc_data *rx_desc_da rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_wcn7850(rx_desc); } -static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_hal *hal) +int ath12k_hal_srng_create_config_wcn7850(struct ath12k_hal *hal) { struct hal_srng_config *s; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h index 46047fd6a3127..a56ca9fd3de4e 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -36,4 +36,5 @@ void ath12k_hal_rx_desc_get_dot11_hdr_wcn7850(struct hal_rx_desc *desc, void ath12k_hal_extract_rx_desc_data_wcn7850(struct hal_rx_desc_data *rx_desc_data, struct hal_rx_desc *rx_desc, struct hal_rx_desc *ldesc); +int ath12k_hal_srng_create_config_wcn7850(struct ath12k_hal *hal); #endif From 086d928703f8f20d0c71ba3d9f40981e6d4aedcd Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:32 +0800 Subject: [PATCH 129/140] wifi: ath12k: add hardware ops support for QCC2072 Due to HAL descriptors, QCC2027 has different offsets of MPDU start tag and MSDU end tag, compared with other chips. Hence add new hardware ops structure for QCC2072. All ops are directly taken from WCN7850, with the exception to rxdma_ring_sel_config, which needs a new function ath12k_dp_rxdma_ring_sel_config_qcc2072() to handle the difference mentioned above. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-12-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 44 +++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 1 + .../wireless/ath/ath12k/wifi7/hal_qcc2072.c | 10 +++++ .../wireless/ath/ath12k/wifi7/hal_qcc2072.h | 3 ++ drivers/net/wireless/ath/ath12k/wifi7/hw.c | 12 ++++- 5 files changed, 69 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 635e812bf4f4a..2a473ac671d25 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -9,6 +9,7 @@ #include "../peer.h" #include "hal_qcn9274.h" #include "hal_wcn7850.h" +#include "hal_qcc2072.h" static u16 ath12k_wifi7_dp_rx_get_peer_id(struct ath12k_dp *dp, enum ath12k_peer_metadata_version ver, @@ -2062,6 +2063,49 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab) return ret; } +int ath12k_dp_rxdma_ring_sel_config_qcc2072(struct ath12k_base *ab) +{ + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct htt_rx_ring_tlv_filter tlv_filter = {}; + u32 ring_id; + int ret = 0; + u32 hal_rx_desc_sz = ab->hal.hal_desc_sz; + int i; + + ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id; + + tlv_filter.rx_filter = HTT_RX_TLV_FLAGS_RXDMA_RING; + tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR; + tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST | + HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST | + HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA; + tlv_filter.offset_valid = true; + tlv_filter.rx_packet_offset = hal_rx_desc_sz; + + tlv_filter.rx_header_offset = offsetof(struct hal_rx_desc_qcc2072, pkt_hdr_tlv); + + tlv_filter.rx_mpdu_start_offset = + ath12k_hal_rx_desc_get_mpdu_start_offset_qcc2072(); + tlv_filter.rx_msdu_end_offset = + ath12k_hal_rx_desc_get_msdu_end_offset_qcc2072(); + + /* + * TODO: Selectively subscribe to required qwords within msdu_end + * and mpdu_start and setup the mask in below msg + * and modify the rx_desc struct + */ + + for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) { + ring_id = dp->rx_mac_buf_ring[i].ring_id; + ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, i, + HAL_RXDMA_BUF, + DP_RXDMA_REFILL_RING_SIZE, + &tlv_filter); + } + + return ret; +} + void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_dp *dp) { struct ath12k_base *ab = dp->ab; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index d15bffe223c7d..89c889fd5d040 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -22,6 +22,7 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_dp *dp, int mac_id, void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_dp *dp); int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab); int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab); +int ath12k_dp_rxdma_ring_sel_config_qcc2072(struct ath12k_base *ab); void ath12k_wifi7_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd, struct ath12k_dp_rx_tid *rx_tid, u32 cipher, enum set_key_cmd key_cmd); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c index 847484ece2044..522b94b04f9f4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c @@ -454,3 +454,13 @@ const struct hal_ops hal_qcc2072_ops = { .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr, .reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr, }; + +u32 ath12k_hal_rx_desc_get_mpdu_start_offset_qcc2072(void) +{ + return offsetof(struct hal_rx_desc_qcc2072, mpdu_start_tag); +} + +u32 ath12k_hal_rx_desc_get_msdu_end_offset_qcc2072(void) +{ + return offsetof(struct hal_rx_desc_qcc2072, msdu_end_tag); +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h index 392bfbb6a4124..6de943df77864 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h @@ -8,3 +8,6 @@ extern const struct ath12k_hw_regs qcc2072_regs; extern const struct hal_ops hal_qcc2072_ops; + +u32 ath12k_hal_rx_desc_get_mpdu_start_offset_qcc2072(void); +u32 ath12k_hal_rx_desc_get_msdu_end_offset_qcc2072(void); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 38c388319e008..f75690f586cd9 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -170,6 +170,16 @@ static const struct ath12k_hw_ops wcn7850_ops = { .is_frame_link_agnostic = ath12k_wifi7_is_frame_link_agnostic_wcn7850, }; +static const struct ath12k_hw_ops qcc2072_ops = { + .get_hw_mac_from_pdev_id = ath12k_wifi7_hw_qcn9274_mac_from_pdev_id, + .mac_id_to_pdev_id = ath12k_wifi7_hw_mac_id_to_pdev_id_wcn7850, + .mac_id_to_srng_id = ath12k_wifi7_hw_mac_id_to_srng_id_wcn7850, + .rxdma_ring_sel_config = ath12k_dp_rxdma_ring_sel_config_qcc2072, + .get_ring_selector = ath12k_wifi7_hw_get_ring_selector_wcn7850, + .dp_srng_is_tx_comp_ring = ath12k_wifi7_dp_srng_is_comp_ring_wcn7850, + .is_frame_link_agnostic = ath12k_wifi7_is_frame_link_agnostic_wcn7850, +}; + #define ATH12K_TX_RING_MASK_0 0x1 #define ATH12K_TX_RING_MASK_1 0x2 #define ATH12K_TX_RING_MASK_2 0x4 @@ -673,7 +683,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_WCN7850, .internal_sleep_clock = true, - .hw_ops = &wcn7850_ops, + .hw_ops = &qcc2072_ops, .ring_mask = &ath12k_wifi7_hw_ring_mask_wcn7850, .host_ce_config = ath12k_wifi7_host_ce_config_wcn7850, From 851bfa3b97c341f83585097dc494dcbadcb01a38 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:33 +0800 Subject: [PATCH 130/140] wifi: ath12k: handle REO CMD ring for QCC2072 As far as REO CMD ring is concerned, there are two differences between QCC2072 and the existing chips: For the first, the TLV header of ring descriptor for QCC2072 is 32 bits while 64 bits for existing chips. For the second, QCC2072 has different hal_reo_get_queue_stats, hal_reo_flush_cache and hal_reo_update_rx_queue structures. Take hal_reo_get_queue_stats as an example: QCC2072: struct hal_reo_get_queue_stats_qcc2072 { struct hal_reo_cmd_hdr cmd; [...] __le32 rsvd0[6]; } __packed; QCN9274/WCN7850: struct hal_reo_get_queue_stats { struct hal_reo_cmd_hdr cmd; [...] __le32 rsvd0[6]; __le32 tlv64_pad; } __packed; Note there is no tlv64_pad at the end for QCC2072, but all other former fields share the same layout. These make different ring entry size, so that parameter has to be updated with respect to existing chips. This is done in the newly introduced ath12k_hal_srng_create_config_qcc2072() function, which first creates all ring configs by utilizing ath12k_hal_srng_create_config_wcn7850() and then updates the individual field. Besides, the REO command TLV encoding also need to be corrected because of the different TLV bits. This is done by introducing a 32 bit variant for each of the existing 64 bit callback. Note the hal_reo_get_queue_stats_qcc2072 structure is introduced for the purpose of calculating ring entry size. Existing hal_reo_get_queue_stats structure gets used elsewhere even for QCC2072. This is working because the only difference is the tlv64_pad field that is located at the end and not getting used, hence can be ignored. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-13-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.c | 11 ++++++++ drivers/net/wireless/ath/ath12k/hal.h | 1 + .../net/wireless/ath/ath12k/wifi7/hal_desc.h | 7 ++++++ .../wireless/ath/ath12k/wifi7/hal_qcc2072.c | 22 +++++++++++++--- .../net/wireless/ath/ath12k/wifi7/hal_rx.c | 25 +++++++++++++++++++ .../net/wireless/ath/ath12k/wifi7/hal_rx.h | 2 ++ 6 files changed, 65 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index 847482fd8c6b1..dca5af804e181 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -829,6 +829,17 @@ void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len) } EXPORT_SYMBOL(ath12k_hal_encode_tlv64_hdr); +void *ath12k_hal_encode_tlv32_hdr(void *tlv, u64 tag, u64 len) +{ + struct hal_tlv_hdr *tlv32 = tlv; + + tlv32->tl = le32_encode_bits(tag, HAL_TLV_HDR_TAG) | + le32_encode_bits(len, HAL_TLV_HDR_LEN); + + return tlv32->value; +} +EXPORT_SYMBOL(ath12k_hal_encode_tlv32_hdr); + u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc) { struct hal_tlv_64_hdr *tlv64 = tlv; diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index ef480de97fbe9..a8768a80fa497 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1543,5 +1543,6 @@ void ath12k_hal_rx_reo_ent_buf_paddr_get(struct ath12k_hal *hal, void *rx_desc, struct ath12k_buffer_addr **pp_buf_addr, u8 *rbm, u32 *msdu_cnt); void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len); +void *ath12k_hal_encode_tlv32_hdr(void *tlv, u64 tag, u64 len); u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h index cdcf24b1d6eba..c4c7ca9ee827a 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h @@ -1049,6 +1049,13 @@ struct hal_reo_get_queue_stats { * Hole_count */ +struct hal_reo_get_queue_stats_qcc2072 { + struct hal_reo_cmd_hdr cmd; + __le32 queue_addr_lo; + __le32 info0; + __le32 rsvd0[6]; +} __packed; + #define HAL_REO_FLUSH_QUEUE_INFO0_DESC_ADDR_HI GENMASK(7, 0) #define HAL_REO_FLUSH_QUEUE_INFO0_BLOCK_DESC_ADDR BIT(8) #define HAL_REO_FLUSH_QUEUE_INFO0_BLOCK_RESRC_IDX GENMASK(10, 9) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c index 522b94b04f9f4..0ae5b073287ab 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c @@ -412,8 +412,24 @@ static void ath12k_hal_extract_rx_desc_data_qcc2072(struct hal_rx_desc_data *rx_ rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_qcc2072(rx_desc); } +static int ath12k_hal_srng_create_config_qcc2072(struct ath12k_hal *hal) +{ + struct hal_srng_config *s; + int ret; + + ret = ath12k_hal_srng_create_config_wcn7850(hal); + if (ret) + return ret; + + s = &hal->srng_config[HAL_REO_CMD]; + s->entry_size = (sizeof(struct hal_tlv_hdr) + + sizeof(struct hal_reo_get_queue_stats_qcc2072)) >> 2; + + return 0; +} + const struct hal_ops hal_qcc2072_ops = { - .create_srng_config = ath12k_hal_srng_create_config_wcn7850, + .create_srng_config = ath12k_hal_srng_create_config_qcc2072, .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcc2072, .rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_qcc2072, .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcc2072, @@ -443,7 +459,7 @@ const struct hal_ops hal_qcc2072_ops = { .write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr, .write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr, .setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list, - .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring_tlv64, + .reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring_tlv32, .reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup, .rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set, .rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get, @@ -451,7 +467,7 @@ const struct hal_ops hal_qcc2072_ops = { .get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm, .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, - .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr, + .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv32_hdr, .reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr, }; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c index 84b714b8992ff..7948a550cd8ef 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c @@ -896,6 +896,31 @@ void ath12k_wifi7_hal_reo_init_cmd_ring_tlv64(struct ath12k_base *ab, } } +void ath12k_wifi7_hal_reo_init_cmd_ring_tlv32(struct ath12k_base *ab, + struct hal_srng *srng) +{ + struct hal_reo_get_queue_stats *desc; + struct hal_srng_params params; + struct hal_tlv_hdr *tlv; + int i, cmd_num = 1; + int entry_size; + u8 *entry; + + memset(¶ms, 0, sizeof(params)); + + entry_size = ath12k_hal_srng_get_entrysize(ab, HAL_REO_CMD); + ath12k_hal_srng_get_params(ab, srng, ¶ms); + entry = (u8 *)params.ring_base_vaddr; + + for (i = 0; i < params.num_entries; i++) { + tlv = (struct hal_tlv_hdr *)entry; + desc = (struct hal_reo_get_queue_stats *)tlv->value; + desc->cmd.info0 = le32_encode_bits(cmd_num++, + HAL_REO_CMD_HDR_INFO0_CMD_NUMBER); + entry += entry_size; + } +} + void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) { struct ath12k_hal *hal = &ab->hal; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h index 95f5595b30ad1..ac2a8ac03288f 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h @@ -864,6 +864,8 @@ void ath12k_wifi7_hal_rx_msdu_list_get(struct ath12k *ar, u16 *num_msdus); void ath12k_wifi7_hal_reo_init_cmd_ring_tlv64(struct ath12k_base *ab, struct hal_srng *srng); +void ath12k_wifi7_hal_reo_init_cmd_ring_tlv32(struct ath12k_base *ab, + struct hal_srng *srng); void ath12k_wifi7_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab); void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map); void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, From 82da8e7d30a3af618780d6ecaf90706b8d8e03d0 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:34 +0800 Subject: [PATCH 131/140] wifi: ath12k: handle REO status ring for QCC2072 For QCC2072 below REO status descriptors are different compared with QCN9274/WCN7850: hal_reo_get_queue_stats_status hal_reo_flush_queue_status hal_reo_flush_cache_status hal_reo_unblock_cache_status hal_reo_flush_timeout_list_status hal_reo_desc_thresh_reached_status Take hal_reo_get_queue_stats_status as an example: QCC2072: struct hal_reo_get_queue_stats_status_qcc2072 { __le32 tlv32_padding; struct hal_reo_get_queue_stats_status status; } __packed; QCN9274/WCN7850: struct hal_reo_get_queue_stats_status; Besides, QCC2072 has a 32 bits TLV header while QCN9274/WCN7850 has 64. This means that there is no difference between these 3 devices in layout of actual fields, because they all start after a 8 bytes offset QCC2072: { struct hal_tlv_hdr tlv; __le32 tlv32_padding; struct hal_reo_get_queue_stats_status status; } QCN9274/WCN7850: { struct hal_tlv_64_hdr tlv; struct hal_reo_get_queue_stats_status status; } Therefore current implementation luckily works for QCC2072 as well. However it leads to misunderstanding, which should be avoided. So add individual REO status ring handling for QCC2072. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-14-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.c | 12 +++++++++++ drivers/net/wireless/ath/ath12k/hal.h | 1 + .../net/wireless/ath/ath12k/wifi7/hal_desc.h | 5 +++++ .../wireless/ath/ath12k/wifi7/hal_qcc2072.c | 21 ++++++++++++++++++- 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index dca5af804e181..4fe64aac4d3ad 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -851,3 +851,15 @@ u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc) return tag; } EXPORT_SYMBOL(ath12k_hal_decode_tlv64_hdr); + +u16 ath12k_hal_decode_tlv32_hdr(void *tlv, void **desc) +{ + struct hal_tlv_hdr *tlv32 = tlv; + u16 tag; + + tag = le32_get_bits(tlv32->tl, HAL_SRNG_TLV_HDR_TAG); + *desc = tlv32->value; + + return tag; +} +EXPORT_SYMBOL(ath12k_hal_decode_tlv32_hdr); diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index a8768a80fa497..32b3420008517 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1545,4 +1545,5 @@ void ath12k_hal_rx_reo_ent_buf_paddr_get(struct ath12k_hal *hal, void *rx_desc, void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len); void *ath12k_hal_encode_tlv32_hdr(void *tlv, u64 tag, u64 len); u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc); +u16 ath12k_hal_decode_tlv32_hdr(void *tlv, void **desc); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h index c4c7ca9ee827a..e1ab47b44433d 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h @@ -2439,6 +2439,11 @@ struct hal_reo_get_queue_stats_status { * entries into this Ring has looped around the ring. */ +struct hal_reo_get_queue_stats_status_qcc2072 { + __le32 tlv32_padding; + struct hal_reo_get_queue_stats_status status; +} __packed; + #define HAL_REO_STATUS_LOOP_CNT GENMASK(31, 28) #define HAL_REO_FLUSH_QUEUE_INFO0_ERR_DETECTED BIT(0) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c index 0ae5b073287ab..ee2427fadfc14 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c @@ -425,9 +425,28 @@ static int ath12k_hal_srng_create_config_qcc2072(struct ath12k_hal *hal) s->entry_size = (sizeof(struct hal_tlv_hdr) + sizeof(struct hal_reo_get_queue_stats_qcc2072)) >> 2; + s = &hal->srng_config[HAL_REO_STATUS]; + s->entry_size = (sizeof(struct hal_tlv_hdr) + + sizeof(struct hal_reo_get_queue_stats_status_qcc2072)) >> 2; + return 0; } +static u16 ath12k_hal_reo_status_dec_tlv_hdr_qcc2072(void *tlv, void **desc) +{ + struct hal_reo_get_queue_stats_status_qcc2072 *status_tlv; + u16 tag; + + tag = ath12k_hal_decode_tlv32_hdr(tlv, (void **)&status_tlv); + /* + * actual desc of REO status entry starts after tlv32_padding, + * see hal_reo_get_queue_stats_status_qcc2072 + */ + *desc = &status_tlv->status; + + return tag; +} + const struct hal_ops hal_qcc2072_ops = { .create_srng_config = ath12k_hal_srng_create_config_qcc2072, .rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcc2072, @@ -468,7 +487,7 @@ const struct hal_ops hal_qcc2072_ops = { .rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get, .rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get, .reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv32_hdr, - .reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr, + .reo_status_dec_tlv_hdr = ath12k_hal_reo_status_dec_tlv_hdr_qcc2072, }; u32 ath12k_hal_rx_desc_get_mpdu_start_offset_qcc2072(void) From ecad5cc288a5f62baf5c3cb6a4aa4b7dd3bcf217 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:35 +0800 Subject: [PATCH 132/140] wifi: ath12k: limit number of channels per WMI command Currently the number of channels can be sent in a single WMI command is calculated based on the maximum message length of the target, this results in WMI exchange hang for QCC2072 as its firmware can not support those many channels in a single command. Add a limit to avoid this issue. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-15-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wmi.c | 3 ++- drivers/net/wireless/ath/ath12k/wmi.h | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 1785adbaff12a..b4721393eef31 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -2806,7 +2806,8 @@ int ath12k_wmi_send_scan_chan_list_cmd(struct ath12k *ar, max_chan_limit = (wmi->wmi_ab->max_msg_len[ar->pdev_idx] - len) / sizeof(*chan_info); - num_send_chans = min(arg->nallchans, max_chan_limit); + num_send_chans = min3(arg->nallchans, max_chan_limit, + ATH12K_WMI_MAX_NUM_CHAN_PER_CMD); arg->nallchans -= num_send_chans; len += sizeof(*chan_info) * num_send_chans; diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index 65f0d7ed4178d..daee2787cdfd6 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -6322,6 +6322,9 @@ struct ath12k_wmi_rssi_dbm_conv_info_arg { s8 min_nf_dbm; }; +/* each WMI cmd can hold 58 channel entries at most */ +#define ATH12K_WMI_MAX_NUM_CHAN_PER_CMD 58 + int ath12k_wmi_cmd_send(struct ath12k_wmi_pdev *wmi, struct sk_buff *skb, u32 cmd_id); struct sk_buff *ath12k_wmi_alloc_skb(struct ath12k_wmi_base *wmi_sc, u32 len); From 35babc73804f512d980e6561e21596eb7bbb3fd2 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:36 +0800 Subject: [PATCH 133/140] wifi: ath12k: send peer meta data version to firmware Peer meta data version is currently not delivered to firmware, resulting in QCC2072 data path issues. Parse it from service ready ext2 event and send to firmware in WMI init command. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-16-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wifi7/wmi.c | 5 +++++ drivers/net/wireless/ath/ath12k/wmi.c | 4 ++++ drivers/net/wireless/ath/ath12k/wmi.h | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/wmi.c b/drivers/net/wireless/ath/ath12k/wifi7/wmi.c index c575b44a33f3b..ed538d20d324a 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/wmi.c @@ -102,4 +102,9 @@ void ath12k_wifi7_wmi_init_wcn7850(struct ath12k_base *ab, config->num_multicast_filter_entries = 0x20; config->num_wow_filters = 0x16; config->num_keep_alive_pattern = 0; + + if (test_bit(WMI_TLV_SERVICE_PEER_METADATA_V1A_V1B_SUPPORT, ab->wmi_ab.svc_map)) + config->peer_metadata_ver = ATH12K_PEER_METADATA_V1A; + else + config->peer_metadata_ver = ab->wmi_ab.dp_peer_meta_data_ver; } diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index b4721393eef31..35af3c0b2896f 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -5477,6 +5477,10 @@ static int ath12k_wmi_svc_rdy_ext2_parse(struct ath12k_base *ab, ret); return ret; } + + ab->wmi_ab.dp_peer_meta_data_ver = + u32_get_bits(parse->arg.target_cap_flags, + WMI_TARGET_CAP_FLAGS_RX_PEER_METADATA_VERSION); break; case WMI_TAG_ARRAY_STRUCT: diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index daee2787cdfd6..fdc203fdba0a0 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -2783,6 +2783,8 @@ enum wmi_channel_width { #define WMI_EHT_MCS_NSS_10_11 GENMASK(11, 8) #define WMI_EHT_MCS_NSS_12_13 GENMASK(15, 12) +#define WMI_TARGET_CAP_FLAGS_RX_PEER_METADATA_VERSION GENMASK(1, 0) + struct wmi_service_ready_ext2_event { __le32 reg_db_version; __le32 hw_min_max_tx_power_2ghz; @@ -5230,6 +5232,8 @@ struct ath12k_wmi_base { struct ath12k_svc_ext_info svc_ext_info; u32 sbs_lower_band_end_freq; struct ath12k_hw_mode_info hw_mode_info; + + u8 dp_peer_meta_data_ver; }; struct wmi_pdev_set_bios_interface_cmd { From d21d0508b42cc72c2579ff47e341db82d2c3b9be Mon Sep 17 00:00:00 2001 From: Miaoqing Pan Date: Mon, 12 Jan 2026 15:36:37 +0800 Subject: [PATCH 134/140] wifi: ath12k: fix PCIE_LOCAL_REG_QRTR_NODE_ID definition for QCC2072 The definition of PCIE_LOCAL_REG_QRTR_NODE_ID in QCC2072 is incorrect, which causes the QMI connection to fail when ATH12K_FW_FEATURE_MULTI_QRTR_ID is enabled. To resolve this issue, move it to the hardware register table. Note IPQ5332 is not affected as it is not PCIe based device. Tested-on: QCC2072 hw1.0 PCI CI_WLAN.COL.1.0-01668.1-QCACOLSWPL_V1_TO_SILICONZ-9 Signed-off-by: Miaoqing Pan Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-17-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/hal.h | 2 ++ drivers/net/wireless/ath/ath12k/pci.c | 6 +----- drivers/net/wireless/ath/ath12k/pci.h | 5 +++++ drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c | 2 ++ drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c | 4 ++++ drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c | 2 ++ 6 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 32b3420008517..42db1f784772a 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1201,6 +1201,8 @@ struct ath12k_hw_regs { u32 reo_status_ring_base; u32 gcc_gcc_pcie_hot_rst; + + u32 qrtr_node_id; }; /* HAL context to be used to access SRNG APIs (currently used by data path diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c index 31eb59e69a8a4..1018465c58431 100644 --- a/drivers/net/wireless/ath/ath12k/pci.c +++ b/drivers/net/wireless/ath/ath12k/pci.c @@ -34,10 +34,6 @@ */ #define ACCESS_ALWAYS_OFF 0xFE0 -#define PCIE_LOCAL_REG_QRTR_NODE_ID 0x1E03164 -#define DOMAIN_NUMBER_MASK GENMASK(7, 4) -#define BUS_NUMBER_MASK GENMASK(3, 0) - static struct ath12k_pci_driver *ath12k_pci_family_drivers[ATH12K_DEVICE_FAMILY_MAX]; static const struct ath12k_msi_config msi_config_one_msi = { .total_vectors = 1, @@ -918,7 +914,7 @@ static void ath12k_pci_update_qrtr_node_id(struct ath12k_base *ab) * writes to the given register, it is available for firmware when the QMI service * is spawned. */ - reg = PCIE_LOCAL_REG_QRTR_NODE_ID & WINDOW_RANGE_MASK; + reg = PCIE_LOCAL_REG_QRTR_NODE_ID(ab) & WINDOW_RANGE_MASK; ath12k_pci_write32(ab, reg, ab_pci->qmi_instance); ath12k_dbg(ab, ATH12K_DBG_PCI, "pci reg 0x%x instance 0x%x read val 0x%x\n", diff --git a/drivers/net/wireless/ath/ath12k/pci.h b/drivers/net/wireless/ath/ath12k/pci.h index a74b09d23a6a1..0e0e2020c6ae5 100644 --- a/drivers/net/wireless/ath/ath12k/pci.h +++ b/drivers/net/wireless/ath/ath12k/pci.h @@ -59,6 +59,11 @@ #define QCN9274_QFPROM_RAW_RFA_PDET_ROW13_LSB 0x1E20338 #define OTP_BOARD_ID_MASK GENMASK(15, 0) +#define PCIE_LOCAL_REG_QRTR_NODE_ID(ab) \ + ((ab)->hal.regs->qrtr_node_id) +#define DOMAIN_NUMBER_MASK GENMASK(7, 4) +#define BUS_NUMBER_MASK GENMASK(3, 0) + #define PCI_BAR_WINDOW0_BASE 0x1E00000 #define PCI_BAR_WINDOW0_END 0x1E7FFFC #define PCI_SOC_RANGE_MASK 0x3FFF diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c index ee2427fadfc14..1eefb931a853e 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c @@ -92,6 +92,8 @@ const struct ath12k_hw_regs qcc2072_regs = { .umac_ce1_dest_reg_base = 0x01b83000, .gcc_gcc_pcie_hot_rst = 0x1e65304, + + .qrtr_node_id = 0x1e03300, }; static void ath12k_hal_rx_desc_set_msdu_len_qcc2072(struct hal_rx_desc *desc, u16 len) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 253729fcf0a3f..05348e50b57a1 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -297,6 +297,8 @@ const struct ath12k_hw_regs qcn9274_v1_regs = { .umac_ce1_dest_reg_base = 0x01b83000, .gcc_gcc_pcie_hot_rst = 0x1e38338, + + .qrtr_node_id = 0x1e03164, }; const struct ath12k_hw_regs qcn9274_v2_regs = { @@ -390,6 +392,8 @@ const struct ath12k_hw_regs qcn9274_v2_regs = { .umac_ce1_dest_reg_base = 0x01b83000, .gcc_gcc_pcie_hot_rst = 0x1e38338, + + .qrtr_node_id = 0x1e03164, }; const struct ath12k_hw_regs ipq5332_regs = { diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 88f51a3828aac..e64e512cac7df 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -256,6 +256,8 @@ const struct ath12k_hw_regs wcn7850_regs = { .umac_ce1_dest_reg_base = 0x01b83000, .gcc_gcc_pcie_hot_rst = 0x1e40304, + + .qrtr_node_id = 0x1e03164, }; static inline From e43405a86ad4b50b7875115c08faf4709c0c1181 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 12 Jan 2026 15:36:38 +0800 Subject: [PATCH 135/140] wifi: ath12k: enable QCC2072 support QCC2072 is a PCI based device that is very much like WCN7850, the major difference is that QCC2072 has only one phy hence does not support DBS. With previous patches handling such similarity and difference, it is now ready to finally enable supporting this device. Add QCC2072's ID to the PCI device ID table, to allow it getting probed hence enable support. Also populate some necessary parameters when probing. Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0-01560-QCACOLSWPL_V1_TO_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20260112-ath12k-support-qcc2072-v2-18-fc8ce1e43969@oss.qualcomm.com Signed-off-by: Jeff Johnson --- drivers/net/wireless/ath/ath12k/wifi7/pci.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/pci.c b/drivers/net/wireless/ath/ath12k/wifi7/pci.c index 6c477fe97298f..6c96b52dec131 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/pci.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/pci.c @@ -19,6 +19,7 @@ #define QCN9274_DEVICE_ID 0x1109 #define WCN7850_DEVICE_ID 0x1107 +#define QCC2072_DEVICE_ID 0x1112 #define ATH12K_PCI_W7_SOC_HW_VERSION_1 1 #define ATH12K_PCI_W7_SOC_HW_VERSION_2 2 @@ -28,10 +29,12 @@ #define TCSR_SOC_HW_VERSION_MINOR_MASK GENMASK(7, 4) #define WINDOW_REG_ADDRESS 0x310c +#define WINDOW_REG_ADDRESS_QCC2072 0x3278 static const struct pci_device_id ath12k_wifi7_pci_id_table[] = { { PCI_VDEVICE(QCOM, QCN9274_DEVICE_ID) }, { PCI_VDEVICE(QCOM, WCN7850_DEVICE_ID) }, + { PCI_VDEVICE(QCOM, QCC2072_DEVICE_ID) }, {} }; @@ -152,7 +155,16 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev, return -EOPNOTSUPP; } break; - + case QCC2072_DEVICE_ID: + ab->id.bdf_search = ATH12K_BDF_SEARCH_BUS_AND_BOARD; + ab_pci->msi_config = &ath12k_wifi7_msi_config[0]; + ab->static_window_map = false; + ab_pci->pci_ops = &ath12k_wifi7_pci_ops_wcn7850; + ab_pci->window_reg_addr = WINDOW_REG_ADDRESS_QCC2072; + ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT; + /* there is only one version till now */ + ab->hw_rev = ATH12K_HW_QCC2072_HW10; + break; default: dev_err(&pdev->dev, "Unknown Wi-Fi 7 PCI device found: 0x%x\n", pci_dev->device); From 0e87abb1be556a87dc20fbe1f3ba7ed22322f33e Mon Sep 17 00:00:00 2001 From: Miaoqing Pan Date: Fri, 14 Nov 2025 12:10:22 +0800 Subject: [PATCH 136/140] FROMLIST: wifi: ath11k: add usecase firmware handling based on device compatible For M.2 WLAN chips, there is no suitable DTS node to specify the firmware-name property. In addition, assigning firmware for the M.2 PCIe interface causes chips that do not use usecase specific firmware to fail. Therefore, abandoning the approach of specifying firmware in DTS. As an alternative, propose a static lookup table mapping device compatible to firmware names. Currently, only WCN6855 HW2.1 requires this. However, support for the firmware-name property is retained to keep the ABI backwards compatible. For details on usecase specific firmware, see: https://lore.kernel.org/all/20250522013444.1301330-3-miaoqing.pan@oss.qualcomm.com/. Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-04685-QCAHSPSWPL_V1_V2_SILICONZ_IOE-1 Fixes: edbbc647c4f3 ("wifi: ath11k: support usercase-specific firmware overrides") Signed-off-by: Miaoqing Pan Link: https://lore.kernel.org/linux-wireless/20260121095055.3683957-2-miaoqing.pan@oss.qualcomm.com/ --- drivers/net/wireless/ath/ath11k/core.c | 27 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/core.h | 4 ++++ 2 files changed, 31 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 812686173ac8a..06b4df2370e95 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -997,6 +997,33 @@ static const struct dmi_system_id ath11k_pm_quirk_table[] = { {} }; +static const struct __ath11k_core_usecase_firmware_table { + u32 hw_rev; + const char *compatible; + const char *firmware_name; +} ath11k_core_usecase_firmware_table[] = { + { ATH11K_HW_WCN6855_HW21, "qcom,lemans-evk", "nfa765"}, + { ATH11K_HW_WCN6855_HW21, "qcom,monaco-evk", "nfa765"}, + { ATH11K_HW_WCN6855_HW21, "qcom,hamoa-iot-evk", "nfa765"}, + { /* Sentinel */ } +}; + +const char *ath11k_core_get_usecase_firmware(struct ath11k_base *ab) +{ + const struct __ath11k_core_usecase_firmware_table *entry = NULL; + + entry = ath11k_core_usecase_firmware_table; + while (entry->compatible) { + if (ab->hw_rev == entry->hw_rev && + of_machine_is_compatible(entry->compatible)) + return entry->firmware_name; + entry++; + } + + return NULL; +} +EXPORT_SYMBOL(ath11k_core_get_usecase_firmware); + void ath11k_fw_stats_pdevs_free(struct list_head *head) { struct ath11k_fw_stats_pdev *i, *tmp; diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index e8780b05ce11e..834988dad591c 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -1275,6 +1275,7 @@ bool ath11k_core_coldboot_cal_support(struct ath11k_base *ab); const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab, const char *filename); +const char *ath11k_core_get_usecase_firmware(struct ath11k_base *ab); static inline const char *ath11k_scan_state_str(enum ath11k_scan_state state) { @@ -1329,6 +1330,9 @@ static inline void ath11k_core_create_firmware_path(struct ath11k_base *ab, of_property_read_string(ab->dev->of_node, "firmware-name", &fw_name); + if (!fw_name) + fw_name = ath11k_core_get_usecase_firmware(ab); + if (fw_name && strncmp(filename, "board", 5)) snprintf(buf, buf_len, "%s/%s/%s/%s", ATH11K_FW_DIR, ab->hw_params.fw.dir, fw_name, filename); From 38d8868deb11c996f14657e549e6e87550004984 Mon Sep 17 00:00:00 2001 From: Mayank Rana Date: Mon, 1 Dec 2025 18:33:15 -0800 Subject: [PATCH 137/140] FROMLIST: mhi: host: Add standard elf image download functionality Currently, the FBC image is a non-standard ELF file that contains a single ELF header, followed by segments for SBL, and WLAN FW. However, TME-L (Trust Management Engine Lite) supported devices (eg. QCC2072) requires separate ELF headers for SBL and WLAN FW segments due to TME-L image authentication requirement. Current image format contains two sections in a single binary: - First 512KB: ELF header + SBL segments - Remaining: WLAN FW segments The TME-L supported image format contains two sections with two elf headers in a single binary: - First 512KB: First ELF header + SBL segments - Remaining: Second ELF header + WLAN FW segments Download behavior: - Legacy: 1. First 512KB via BHI (ELF header + SBL) 2. Full image via BHIe - TME-L: 1. First 512KB via BHI (First ELF header + SBL) 2. Remaining via BHIe (Second ELF header + WLAN FW segments) Add standard_elf_image flag to mhi_controller_config to indicate TME-L supported image format. When set, MHI skips the first 512KB during WLAN FW download over BHIe as it is loaded in BHI phase. Reviewed-by: Baochen Qiang Signed-off-by: Mayank Rana Co-developed-by: Qiang Yu Signed-off-by: Qiang Yu Link: https://lore.kernel.org/mhi/20251201-wlan_image_load_skip_512k-v3-1-bedb5498a58a@oss.qualcomm.com/ Signed-off-by: Miaoqing Pan --- drivers/bus/mhi/host/boot.c | 7 +++++++ include/linux/mhi.h | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index 205d83ac069f1..64fb7a257d352 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -584,6 +584,13 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl) * device transitioning into MHI READY state */ if (fw_load_type == MHI_FW_LOAD_FBC) { + dev_dbg(dev, "standard_elf_image:%s\n", + (mhi_cntrl->standard_elf_image ? "True" : "False")); + if (mhi_cntrl->standard_elf_image) { + fw_data += mhi_cntrl->sbl_size; + fw_sz -= mhi_cntrl->sbl_size; + } + ret = mhi_alloc_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image, fw_sz); if (ret) { release_firmware(firmware); diff --git a/include/linux/mhi.h b/include/linux/mhi.h index dd372b0123a6d..a13106bb234d2 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -360,6 +360,9 @@ struct mhi_controller_config { * @bounce_buf: Use of bounce buffer * @fbc_download: MHI host needs to do complete image transfer (optional) * @wake_set: Device wakeup set flag + * @standard_elf_image: Flag to determine whether the first 512 KB of the FBC + * image need to be skipped when loading WLAN FW over + * BHIe interface (optional) * @irq_flags: irq flags passed to request_irq (optional) * @mru: the default MRU for the MHI device * @@ -445,6 +448,7 @@ struct mhi_controller { bool bounce_buf; bool fbc_download; bool wake_set; + bool standard_elf_image; unsigned long irq_flags; u32 mru; }; From b0edc118d1cda3ce47a41cd80f35c0a72ae3e59e Mon Sep 17 00:00:00 2001 From: Qian Zhang Date: Thu, 8 Jan 2026 11:46:07 +0800 Subject: [PATCH 138/140] FROMLIST: wifi: ath11k: Fix failure to connect to a 6 GHz AP STA fails to connect to a 6 GHz AP with the following errors: ath11k_pci 0000:01:00.0: failed to handle chan list with power type 1 wlp1s0: deauthenticating from c8:a3:e8:dd:41:e3 by local choice (Reason: 3=DEAUTH_LEAVING) ath11k_reg_handle_chan_list() treats the update as redundant and returns -EINVAL. That causes the connection attempt to fail. Avoid unnecessary validation during association. Apply the regulatory redundant check only when the power type is IEEE80211_REG_UNSET_AP, which only occurs during core initialization. Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41 Signed-off-by: Qian Zhang Reviewed-by: Baochen Qiang Link: https://lore.kernel.org/all/20260108034607.812885-1-qian.zhang@oss.qualcomm.com/ --- drivers/net/wireless/ath/ath11k/reg.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c index d62a2014315a0..49b79648752cf 100644 --- a/drivers/net/wireless/ath/ath11k/reg.c +++ b/drivers/net/wireless/ath/ath11k/reg.c @@ -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. */ #include @@ -926,8 +926,11 @@ int ath11k_reg_handle_chan_list(struct ath11k_base *ab, */ if (ab->default_regd[pdev_idx] && !ab->new_regd[pdev_idx] && !memcmp((char *)ab->default_regd[pdev_idx]->alpha2, - (char *)reg_info->alpha2, 2)) - goto retfail; + (char *)reg_info->alpha2, 2) && + power_type == IEEE80211_REG_UNSET_AP) { + ath11k_reg_reset_info(reg_info); + return 0; + } /* Intersect new rules with default regd if a new country setting was * requested, i.e a default regd was already set during initialization From 82f600510af9dcb7d867375d58eb56363b31cbbd Mon Sep 17 00:00:00 2001 From: Miaoqing Pan Date: Mon, 26 Jan 2026 12:15:58 +0800 Subject: [PATCH 139/140] BACKPORT: FROMLIST: wifi: ath12k: Fix wrong P2P device link id issue Wrong P2P device link id value of 0 was introduced in ath12k_mac_op_tx() by [1]. During the P2P negotiation process, there is only one scan vdev with link ID 15. Currently, the device link ID is incorrectly set to 0 in ath12k_mac_op_tx() during the P2P negotiation process, which leads to TX failures. Set the correct P2P device link ID to 15 to fix the TX failure issue. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Fixes: 648a121bafa3 ("wifi: ath12k: ath12k_mac_op_tx(): MLO support") # [1] Signed-off-by: Yingying Tang Link: https://lore.kernel.org/linux-wireless/20260113054636.2620035-1-yingying.tang@oss.qualcomm.com/ --- drivers/net/wireless/ath/ath12k/wifi7/hw.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index f75690f586cd9..df045ddf42da9 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -806,7 +806,10 @@ static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw, return; } } else { - link_id = 0; + if (vif->type == NL80211_IFTYPE_P2P_DEVICE) + link_id = ATH12K_FIRST_SCAN_LINK; + else + link_id = 0; } arvif = rcu_dereference(ahvif->link[link_id]); From 18a508a1e4488e4b30f5c5879b7822a52001b78c Mon Sep 17 00:00:00 2001 From: Yingying Tang Date: Thu, 25 Dec 2025 16:02:41 +0800 Subject: [PATCH 140/140] FROMLIST: wifi: ath12k: Fix scan state stuck in ABORTING Scan finish workqueue was introduced in __ath12k_mac_scan_finish() by [1]. During ath12k_mac_op_cancel_remain_on_channel(), scan state is set to ABORTING and should be reset to IDLE in the queued work. However, wiphy_work_cancel() is called before exiting ath12k_mac_op_cancel_remain_on_channel(), which prevents the work from running and leaves the state in ABORTING. This blocks all subsequent scan requests. Replace wiphy_work_cancel() with wiphy_work_flush() to ensure the queued work runs and scan state is reset to IDLE. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Fixes: 3863f014ad23 ("wifi: ath12k: symmetrize scan vdev creation and deletion during HW scan") # [1] Signed-off-by: Yingying Tang Link: https://lore.kernel.org/linux-wireless/20260112115516.2144219-1-yingying.tang@oss.qualcomm.com/ --- drivers/net/wireless/ath/ath12k/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 6d3664fe4f0f1..807a1d907829e 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -13422,7 +13422,7 @@ int ath12k_mac_op_cancel_remain_on_channel(struct ieee80211_hw *hw, ath12k_scan_abort(ar); cancel_delayed_work_sync(&ar->scan.timeout); - wiphy_work_cancel(hw->wiphy, &ar->scan.vdev_clean_wk); + wiphy_work_flush(hw->wiphy, &ar->scan.vdev_clean_wk); return 0; }