mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge branch 'ath12k-ng' into ath-next
As originally proposed in [1], the ath12k driver was re-architected in the ath12k-ng branch to separate the logic specific to 802.11be (Wi-Fi 7) from the core logic. This separation will allow ath12k to also support 802.11bn (Wi-Fi 8) in the future. Now merge this into ath-next. Many thanks to everyone who worked on this re-architecture. Special thanks to Vasanthakumar Thiagarajan and Baochen Qiang who reviewed every patch, and to Ripan Deuri for the ath12k-ng => ath-next merge conflict resolution. Link: https://lore.kernel.org/all/4a17d730-ede8-463e-98d8-9b0291d0ca45@oss.qualcomm.com/ # [1] Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
This commit is contained in:
@@ -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 \
|
||||
@@ -12,11 +10,12 @@ ath12k-y += core.o \
|
||||
dp.o \
|
||||
dp_tx.o \
|
||||
dp_rx.o \
|
||||
dp_htt.o \
|
||||
dp_peer.o \
|
||||
debug.o \
|
||||
ce.o \
|
||||
peer.o \
|
||||
dbring.o \
|
||||
hw.o \
|
||||
mhi.o \
|
||||
pci.o \
|
||||
dp_mon.o \
|
||||
@@ -24,6 +23,9 @@ ath12k-y += core.o \
|
||||
p2p.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
|
||||
|
||||
@@ -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 <linux/dma-mapping.h>
|
||||
@@ -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"};
|
||||
@@ -130,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);
|
||||
}
|
||||
@@ -138,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);
|
||||
@@ -531,9 +524,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_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);
|
||||
@@ -563,12 +557,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->hw_params->hal_ops;
|
||||
for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) {
|
||||
irq_grp = &ab->ext_irq_grp[i];
|
||||
num_irq = 0;
|
||||
@@ -588,7 +580,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;
|
||||
}
|
||||
@@ -698,7 +690,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,
|
||||
@@ -935,7 +927,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");
|
||||
@@ -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_ipq5332;
|
||||
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
|
||||
@@ -1065,14 +1086,26 @@ static int ath12k_ahb_probe(struct platform_device *pdev)
|
||||
goto err_rproc_deconfigure;
|
||||
}
|
||||
|
||||
ret = ath12k_core_init(ab);
|
||||
/* 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, "failed to init core: %d\n", 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_deinit_arch;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_deinit_arch:
|
||||
ab_ahb->device_family_ops->arch_deinit(ab);
|
||||
|
||||
err_rproc_deconfigure:
|
||||
ath12k_ahb_deconfigure_rproc(ab);
|
||||
|
||||
@@ -1111,11 +1144,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);
|
||||
}
|
||||
@@ -1136,21 +1171,47 @@ qmi_fail:
|
||||
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;
|
||||
|
||||
void ath12k_ahb_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ath12k_ahb_driver);
|
||||
if (device_id >= ATH12K_DEVICE_FAMILY_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
if (!driver || !driver->ops.probe ||
|
||||
!driver->ops.arch_init || !driver->ops.arch_deinit)
|
||||
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);
|
||||
}
|
||||
EXPORT_SYMBOL(ath12k_ahb_register_driver);
|
||||
|
||||
void ath12k_ahb_unregister_driver(const enum ath12k_device_family device_id)
|
||||
{
|
||||
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;
|
||||
}
|
||||
EXPORT_SYMBOL(ath12k_ahb_unregister_driver);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
/* 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
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/remoteproc/qcom_rproc.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include "core.h"
|
||||
|
||||
#define ATH12K_AHB_RECOVERY_TIMEOUT (3 * HZ)
|
||||
@@ -43,6 +44,12 @@ enum ath12k_ahb_userpd_irq {
|
||||
|
||||
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 {
|
||||
struct ath12k_base *ab;
|
||||
struct rproc *tgt_rproc;
|
||||
@@ -59,6 +66,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 +82,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
|
||||
|
||||
@@ -1,314 +1,13 @@
|
||||
// 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"
|
||||
#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)
|
||||
{
|
||||
@@ -341,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);
|
||||
@@ -434,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;
|
||||
@@ -666,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;
|
||||
@@ -677,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);
|
||||
@@ -687,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);
|
||||
@@ -786,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;
|
||||
@@ -972,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;
|
||||
@@ -980,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,
|
||||
@@ -991,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,
|
||||
@@ -1003,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,
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
#ifndef ATH12K_CE_H
|
||||
@@ -85,6 +85,7 @@ struct ce_ie_addr {
|
||||
struct ce_remap {
|
||||
u32 base;
|
||||
u32 size;
|
||||
u32 cmem_offset;
|
||||
};
|
||||
|
||||
struct ce_attr {
|
||||
@@ -173,10 +174,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);
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/* 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
|
||||
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#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)
|
||||
|
||||
#define MAX_MU_GROUP_ID 64
|
||||
#endif
|
||||
@@ -21,15 +21,18 @@
|
||||
#include "hif.h"
|
||||
#include "pci.h"
|
||||
#include "wow.h"
|
||||
#include "dp_cmn.h"
|
||||
#include "peer.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");
|
||||
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);
|
||||
@@ -632,6 +635,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)
|
||||
@@ -700,6 +704,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))
|
||||
@@ -710,7 +716,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 */
|
||||
}
|
||||
@@ -895,7 +901,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;
|
||||
@@ -920,7 +926,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) {
|
||||
@@ -928,8 +934,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);
|
||||
@@ -964,6 +968,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:
|
||||
@@ -1288,7 +1298,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;
|
||||
@@ -1300,7 +1310,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);
|
||||
@@ -1333,8 +1343,8 @@ err_core_stop:
|
||||
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);
|
||||
|
||||
@@ -1350,13 +1360,14 @@ 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);
|
||||
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;
|
||||
@@ -1565,6 +1576,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,
|
||||
@@ -1739,17 +1751,11 @@ 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)
|
||||
{
|
||||
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;
|
||||
@@ -1996,6 +2002,8 @@ exit:
|
||||
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);
|
||||
|
||||
@@ -2023,6 +2031,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;
|
||||
@@ -2253,7 +2263,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);
|
||||
@@ -2291,31 +2300,5 @@ err_sc_free:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ath12k_init(void)
|
||||
{
|
||||
ahb_err = ath12k_ahb_init();
|
||||
if (ahb_err)
|
||||
pr_warn("Failed to initialize ath12k AHB device: %d\n", ahb_err);
|
||||
|
||||
pci_err = ath12k_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_pci_exit();
|
||||
|
||||
if (!ahb_err)
|
||||
ath12k_ahb_exit();
|
||||
}
|
||||
|
||||
module_init(ath12k_init);
|
||||
module_exit(ath12k_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Driver support for Qualcomm Technologies 802.11be WLAN devices");
|
||||
MODULE_DESCRIPTION("Driver support for Qualcomm Technologies WLAN devices");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <linux/panic_notifier.h>
|
||||
#include <linux/average.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/rhashtable.h>
|
||||
#include "qmi.h"
|
||||
#include "htc.h"
|
||||
#include "wmi.h"
|
||||
@@ -26,7 +27,6 @@
|
||||
#include "ce.h"
|
||||
#include "mac.h"
|
||||
#include "hw.h"
|
||||
#include "hal_rx.h"
|
||||
#include "reg.h"
|
||||
#include "dbring.h"
|
||||
#include "fw.h"
|
||||
@@ -34,6 +34,8 @@
|
||||
#include "wow.h"
|
||||
#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)
|
||||
|
||||
@@ -64,8 +66,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
|
||||
|
||||
@@ -310,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;
|
||||
@@ -360,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;
|
||||
@@ -383,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];
|
||||
@@ -407,51 +399,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
|
||||
@@ -533,12 +482,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;
|
||||
@@ -553,15 +496,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;
|
||||
@@ -572,14 +507,9 @@ struct ath12k_link_sta {
|
||||
|
||||
/* for firmware use only */
|
||||
u8 link_idx;
|
||||
u32 tx_retry_failed;
|
||||
u32 tx_retry_count;
|
||||
};
|
||||
|
||||
struct ath12k_reoq_buf {
|
||||
void *vaddr;
|
||||
dma_addr_t paddr_aligned;
|
||||
u32 size;
|
||||
/* peer addr based rhashtable list pointer */
|
||||
struct rhash_head rhash_addr;
|
||||
};
|
||||
|
||||
struct ath12k_sta {
|
||||
@@ -594,8 +524,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
|
||||
@@ -667,23 +595,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;
|
||||
@@ -809,9 +720,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;
|
||||
@@ -866,8 +774,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 *));
|
||||
@@ -941,32 +848,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;
|
||||
@@ -987,6 +868,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 +895,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;
|
||||
};
|
||||
|
||||
@@ -1035,6 +920,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;
|
||||
@@ -1054,13 +945,14 @@ struct ath12k_base {
|
||||
|
||||
struct ath12k_htc htc;
|
||||
|
||||
struct ath12k_dp dp;
|
||||
struct ath12k_dp *dp;
|
||||
|
||||
void __iomem *mem;
|
||||
unsigned long mem_len;
|
||||
|
||||
void __iomem *mem_ce;
|
||||
u32 ce_remap_base_addr;
|
||||
u32 cmem_offset;
|
||||
bool ce_remap;
|
||||
|
||||
struct {
|
||||
@@ -1105,7 +997,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;
|
||||
@@ -1135,7 +1026,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
|
||||
@@ -1196,8 +1086,6 @@ struct ath12k_base {
|
||||
bool fw_features_valid;
|
||||
} fw;
|
||||
|
||||
const struct hal_rx_ops *hal_rx_ops;
|
||||
|
||||
struct completion restart_completed;
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
@@ -1241,6 +1129,14 @@ 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;
|
||||
|
||||
struct rhashtable *rhead_sta_addr;
|
||||
struct rhashtable_params rhash_sta_addr_param;
|
||||
|
||||
/* must be last */
|
||||
u8 drv_priv[] __aligned(sizeof(void *));
|
||||
};
|
||||
@@ -1516,4 +1412,18 @@ 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;
|
||||
}
|
||||
|
||||
static inline struct ath12k *ath12k_pdev_dp_to_ar(struct ath12k_pdev_dp *dp)
|
||||
{
|
||||
return container_of(dp, struct ath12k, dp);
|
||||
}
|
||||
#endif /* _CORE_H_ */
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// 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.
|
||||
*/
|
||||
|
||||
#include "core.h"
|
||||
#include "debug.h"
|
||||
#include "hal.h"
|
||||
|
||||
static int ath12k_dbring_bufs_replenish(struct ath12k *ar,
|
||||
struct ath12k_dbring *ring,
|
||||
@@ -55,7 +55,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_hal_rx_buf_addr_info_set(&ab->hal, desc, paddr, cookie, 0);
|
||||
|
||||
ath12k_hal_srng_access_end(ab, srng);
|
||||
|
||||
@@ -298,7 +298,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_hal_rx_buf_addr_info_get(&ab->hal, &desc, &paddr, &cookie, &rbm);
|
||||
|
||||
buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID);
|
||||
|
||||
|
||||
@@ -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 <linux/vmalloc.h>
|
||||
@@ -21,6 +22,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 +37,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 +52,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 +76,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,
|
||||
@@ -100,5 +105,6 @@ void ath12k_dbg_dump(struct ath12k_base *ab,
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(ath12k_dbg_dump);
|
||||
|
||||
#endif /* CONFIG_ATH12K_DEBUG */
|
||||
|
||||
@@ -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]);
|
||||
@@ -1020,13 +1020,15 @@ 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,
|
||||
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;
|
||||
@@ -1155,6 +1157,7 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\n");
|
||||
|
||||
rcu_read_lock();
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
ar = ath12k_mac_get_ar_by_pdev_id(ab, DP_SW2HW_MACID(i));
|
||||
if (ar) {
|
||||
@@ -1163,6 +1166,7 @@ static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
|
||||
atomic_read(&ar->dp.num_tx_pending));
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\nREO Rx Received:\n");
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 <linux/vmalloc.h>
|
||||
@@ -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,40 +145,40 @@ 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;
|
||||
|
||||
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;
|
||||
|
||||
spin_lock_bh(&ar->ab->base_lock);
|
||||
dp = ath12k_ab_to_dp(ar->ab);
|
||||
|
||||
rx_stats = arsta->rx_stats;
|
||||
if (!rx_stats) {
|
||||
ret = -ENOENT;
|
||||
goto unlock;
|
||||
}
|
||||
guard(spinlock_bh)(&dp->dp_lock);
|
||||
|
||||
link_peer = ath12k_dp_link_peer_find_by_addr(dp, arsta->addr);
|
||||
if (!link_peer)
|
||||
return -ENOENT;
|
||||
|
||||
rx_stats = link_peer->peer_stats.rx_stats;
|
||||
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",
|
||||
@@ -237,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(&ar->ab->base_lock);
|
||||
|
||||
if (len)
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
out:
|
||||
wiphy_unlock(ah->hw->wiphy);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -261,10 +257,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 +283,9 @@ static ssize_t ath12k_dbg_sta_reset_rx_stats(struct file *file,
|
||||
goto out;
|
||||
}
|
||||
|
||||
ar = arsta->arvif->ar;
|
||||
dp = ath12k_ab_to_dp(arsta->arvif->ar->ab);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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:
|
||||
@@ -335,3 +320,4 @@ void ath12k_debugfs_link_sta_op_add(struct ieee80211_hw *hw,
|
||||
&fops_reset_rx_stats);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(ath12k_debugfs_link_sta_op_add);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+240
-1512
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,106 @@
|
||||
/* 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
|
||||
|
||||
#include "cmn_defs.h"
|
||||
|
||||
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];
|
||||
};
|
||||
|
||||
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];
|
||||
};
|
||||
|
||||
/* 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;
|
||||
};
|
||||
|
||||
struct ath12k_dp_peer_create_params {
|
||||
struct ieee80211_sta *sta;
|
||||
bool is_mlo;
|
||||
u16 peer_id;
|
||||
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)
|
||||
{
|
||||
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,
|
||||
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);
|
||||
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
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -12,6 +12,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
|
||||
@@ -77,31 +83,41 @@ 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 *ar,
|
||||
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);
|
||||
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,
|
||||
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,
|
||||
struct hal_tlv_hdr *tx_tlv,
|
||||
u8 *num_users);
|
||||
enum hal_rx_mon_status
|
||||
ath12k_dp_mon_tx_parse_mon_status(struct ath12k *ar,
|
||||
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);
|
||||
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);
|
||||
int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len);
|
||||
struct sk_buff
|
||||
*ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab,
|
||||
struct dp_rxdma_mon_ring *rx_ring,
|
||||
int *buf_id);
|
||||
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,
|
||||
const struct hal_rx_mon_ppdu_info *ppduinfo,
|
||||
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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user