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>master
commit
631ee338f0
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -1,63 +1,58 @@
|
|||
// 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 <crypto/hash.h>
|
||||
#include "core.h"
|
||||
#include "dp_tx.h"
|
||||
#include "hal_tx.h"
|
||||
#include "hif.h"
|
||||
#include "hal.h"
|
||||
#include "debug.h"
|
||||
#include "dp_rx.h"
|
||||
#include "peer.h"
|
||||
#include "dp_mon.h"
|
||||
#include "dp_cmn.h"
|
||||
|
||||
enum ath12k_dp_desc_type {
|
||||
ATH12K_DP_TX_DESC,
|
||||
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;
|
||||
struct ath12k_peer *peer;
|
||||
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_peer_find(ab, vdev_id, addr);
|
||||
if (!peer) {
|
||||
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) {
|
||||
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);
|
||||
crypto_free_shash(peer->dp_peer->tfm_mmic);
|
||||
peer->dp_peer->dp_setup_done = false;
|
||||
spin_unlock_bh(&dp->dp_lock);
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
|
|
@ -92,19 +87,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_peer_find(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_dp_rx_peer_tid_delete(ar, peer, tid);
|
||||
ath12k_dp_arch_rx_peer_tid_delete(dp, peer, tid);
|
||||
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
spin_unlock_bh(&dp->dp_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -147,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.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;
|
||||
|
|
@ -338,50 +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;
|
||||
struct ath12k_vif *ahvif = arvif->ahvif;
|
||||
|
||||
/* 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 &&
|
||||
test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags))
|
||||
bank_config |=
|
||||
u32_encode_bits(ath12k_dp_tx_get_encrypt_type(ahvif->key_cipher),
|
||||
HAL_TX_BANK_CONFIG_ENCRYPT_TYPE);
|
||||
|
||||
bank_config |= u32_encode_bits(ahvif->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(arvif->hal_addr_search_flags & HAL_TX_ADDRX_EN,
|
||||
HAL_TX_BANK_CONFIG_ADDRX_EN) |
|
||||
u32_encode_bits(!!(arvif->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,
|
||||
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)
|
||||
|
|
@ -392,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 = ath12k_dp_arch_tx_get_vdev_bank_config(dp, arvif);
|
||||
|
||||
spin_lock_bh(&dp->tx_bank_lock);
|
||||
/* TODO: implement using idr kernel framework*/
|
||||
|
|
@ -424,7 +375,8 @@ inc_ref_and_return:
|
|||
spin_unlock_bh(&dp->tx_bank_lock);
|
||||
|
||||
if (configure_register)
|
||||
ath12k_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,
|
||||
|
|
@ -442,7 +394,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;
|
||||
|
|
@ -450,7 +402,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;
|
||||
|
||||
|
|
@ -473,7 +425,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);
|
||||
|
|
@ -490,7 +442,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;
|
||||
|
|
@ -506,7 +458,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.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,
|
||||
|
|
@ -596,7 +548,7 @@ err:
|
|||
|
||||
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;
|
||||
|
||||
|
|
@ -616,7 +568,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;
|
||||
|
|
@ -659,7 +611,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;
|
||||
|
|
@ -710,7 +662,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;
|
||||
|
|
@ -758,7 +710,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;
|
||||
|
|
@ -797,6 +749,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;
|
||||
|
|
@ -804,7 +757,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;
|
||||
|
|
@ -865,7 +818,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;
|
||||
}
|
||||
|
|
@ -883,134 +837,19 @@ fail_desc_bank_free:
|
|||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
|
@ -1025,31 +864,10 @@ 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();
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
@ -1061,6 +879,14 @@ 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;
|
||||
dp_pdev->dp_hw = &ar->ah->dp_hw;
|
||||
|
||||
ret = ath12k_dp_rx_pdev_alloc(ab, i);
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "failed to allocate pdev rx for pdev_id :%d\n",
|
||||
|
|
@ -1074,6 +900,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);
|
||||
|
|
@ -1081,40 +912,23 @@ out:
|
|||
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)
|
||||
{
|
||||
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:
|
||||
|
|
@ -1125,22 +939,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;
|
||||
|
||||
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 = ath12k_dp_vif_to_dp_link_vif(&ahvif->dp_vif, link_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, &ab->dp);
|
||||
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;
|
||||
}
|
||||
|
|
@ -1150,7 +971,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;
|
||||
|
|
@ -1273,15 +1094,13 @@ 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;
|
||||
|
||||
if (dp->reoq_lut.vaddr_unaligned) {
|
||||
ath12k_hif_write32(ab,
|
||||
HAL_SEQ_WCSS_UMAC_REO_REG +
|
||||
HAL_REO1_QDESC_LUT_BASE0(ab), 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);
|
||||
|
|
@ -1289,9 +1108,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);
|
||||
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);
|
||||
|
|
@ -1299,11 +1116,13 @@ 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 = &ab->dp;
|
||||
struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
|
||||
int i;
|
||||
|
||||
ath12k_dp_link_peer_rhash_tbl_destroy(dp);
|
||||
|
||||
if (!dp->ab)
|
||||
return;
|
||||
|
||||
|
|
@ -1324,60 +1143,6 @@ void ath12k_dp_free(struct ath12k_base *ab)
|
|||
|
||||
ath12k_dp_rx_free(ab);
|
||||
/* Deinit any SOC level resource */
|
||||
dp->ab = NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (ath12k_ftm_mode)
|
||||
return;
|
||||
|
||||
ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG0(ab), 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(ab), 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) |
|
||||
ab->hw_params->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)
|
||||
|
|
@ -1385,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 = &ab->dp;
|
||||
|
||||
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 = &ab->dp;
|
||||
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 ||
|
||||
|
|
@ -1412,12 +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;
|
||||
|
|
@ -1428,21 +1191,22 @@ 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;
|
||||
}
|
||||
EXPORT_SYMBOL(ath12k_dp_get_tx_desc);
|
||||
|
||||
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);
|
||||
|
|
@ -1482,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];
|
||||
}
|
||||
}
|
||||
|
|
@ -1521,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];
|
||||
}
|
||||
}
|
||||
|
|
@ -1571,7 +1335,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1582,7 +1346,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);
|
||||
|
|
@ -1668,8 +1432,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;
|
||||
u32 val;
|
||||
struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
|
||||
int ret;
|
||||
|
||||
if (!ab->hw_params->reoq_lut_support)
|
||||
|
|
@ -1697,50 +1460,24 @@ 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),
|
||||
dp->reoq_lut.paddr >> 8);
|
||||
|
||||
ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_LUT_BASE1(ab),
|
||||
dp->ml_reoq_lut.paddr >> 8);
|
||||
|
||||
val = ath12k_hif_read32(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(ab),
|
||||
val | HAL_REO_QDESC_ADDR_READ_LUT_ENABLE);
|
||||
|
||||
ath12k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_QDESC_MAX_PEERID(ab),
|
||||
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;
|
||||
}
|
||||
|
||||
static enum hal_rx_buf_return_buf_manager
|
||||
ath12k_dp_get_idle_link_rbm(struct ath12k_base *ab)
|
||||
static int ath12k_dp_setup(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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
dp = ath12k_ab_to_dp(ab);
|
||||
dp->ab = ab;
|
||||
|
||||
INIT_LIST_HEAD(&dp->reo_cmd_list);
|
||||
|
|
@ -1749,13 +1486,25 @@ int ath12k_dp_alloc(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);
|
||||
|
||||
mutex_init(&dp->link_peer_rhash_tbl_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_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];
|
||||
|
|
@ -1783,7 +1532,7 @@ int ath12k_dp_alloc(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);
|
||||
|
|
@ -1836,6 +1585,48 @@ fail_hw_cc_cleanup:
|
|||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,690 @@
|
|||
// 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"
|
||||
#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)
|
||||
{
|
||||
struct ath12k_dp_link_peer *peer;
|
||||
|
||||
lockdep_assert_held(&dp->dp_lock);
|
||||
|
||||
list_for_each_entry(peer, &dp->peers, list) {
|
||||
if (peer->vdev_id != vdev_id)
|
||||
continue;
|
||||
if (!ether_addr_equal(peer->addr, addr))
|
||||
continue;
|
||||
|
||||
return peer;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ath12k_dp_link_peer *
|
||||
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(&dp->dp_lock);
|
||||
|
||||
list_for_each_entry(peer, &dp->peers, list) {
|
||||
if (peer->pdev_idx != pdev_idx)
|
||||
continue;
|
||||
if (!ether_addr_equal(peer->addr, addr))
|
||||
continue;
|
||||
|
||||
return peer;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ath12k_dp_link_peer *
|
||||
ath12k_dp_link_peer_find_by_addr(struct ath12k_dp *dp, const u8 *addr)
|
||||
{
|
||||
lockdep_assert_held(&dp->dp_lock);
|
||||
|
||||
return rhashtable_lookup_fast(dp->rhead_peer_addr, addr,
|
||||
dp->rhash_peer_addr_param);
|
||||
}
|
||||
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_dp *dp, int ml_peer_id)
|
||||
{
|
||||
struct ath12k_dp_link_peer *peer;
|
||||
|
||||
lockdep_assert_held(&dp->dp_lock);
|
||||
|
||||
list_for_each_entry(peer, &dp->peers, list)
|
||||
if (ml_peer_id == peer->ml_id)
|
||||
return peer;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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(dp, peer_id);
|
||||
|
||||
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_dp *dp, int vdev_id)
|
||||
{
|
||||
struct ath12k_dp_link_peer *peer;
|
||||
|
||||
spin_lock_bh(&dp->dp_lock);
|
||||
|
||||
list_for_each_entry(peer, &dp->peers, list) {
|
||||
if (vdev_id == peer->vdev_id) {
|
||||
spin_unlock_bh(&dp->dp_lock);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&dp->dp_lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct ath12k_dp_link_peer *
|
||||
ath12k_dp_link_peer_find_by_ast(struct ath12k_dp *dp, int ast_hash)
|
||||
{
|
||||
struct ath12k_dp_link_peer *peer;
|
||||
|
||||
lockdep_assert_held(&dp->dp_lock);
|
||||
|
||||
list_for_each_entry(peer, &dp->peers, list)
|
||||
if (ast_hash == peer->ast_hash)
|
||||
return peer;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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(&dp->dp_lock);
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
ath12k_dp_link_peer_free(peer);
|
||||
wake_up(&ab->peer_mapping_wq);
|
||||
|
||||
exit:
|
||||
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);
|
||||
struct ath12k *ar;
|
||||
|
||||
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)
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
exit:
|
||||
spin_unlock_bh(&dp->dp_lock);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
|
||||
"ath12k_dp_link_peer to ath12k_link_sta called without rcu lock");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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]);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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;
|
||||
dp_peer->ucast_ra_only = params->ucast_ra_only;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
/* 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"
|
||||
|
||||
#define ATH12K_DP_PEER_ID_INVALID 0x3FFF
|
||||
|
||||
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_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;
|
||||
struct ath12k_dp_peer *dp_peer;
|
||||
int vdev_id;
|
||||
u8 addr[ETH_ALEN];
|
||||
int peer_id;
|
||||
u16 ast_hash;
|
||||
u8 pdev_idx;
|
||||
u16 hw_peer_id;
|
||||
|
||||
struct ppdu_user_delayba ppdu_stats_delayba;
|
||||
bool delayba_flag;
|
||||
bool is_authorized;
|
||||
bool mlo;
|
||||
/* protected by ab->data_lock */
|
||||
|
||||
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;
|
||||
|
||||
/* peer addr based rhashtable list pointer */
|
||||
struct rhash_head rhash_addr;
|
||||
|
||||
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);
|
||||
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;
|
||||
bool is_mlo;
|
||||
bool dp_setup_done;
|
||||
|
||||
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 *
|
||||
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);
|
||||
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);
|
||||
struct ath12k_dp_link_peer *
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
void ath12k_dp_link_peer_free(struct ath12k_dp_link_peer *peer);
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,21 +1,26 @@
|
|||
/* 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
|
||||
|
||||
#include <crypto/hash.h>
|
||||
#include "core.h"
|
||||
#include "rx_desc.h"
|
||||
#include "debug.h"
|
||||
|
||||
#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 */
|
||||
|
|
@ -28,7 +33,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 {
|
||||
|
|
@ -59,6 +64,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
|
||||
|
||||
|
|
@ -77,24 +84,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;
|
||||
|
|
@ -117,6 +106,109 @@ 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_hal *hal,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
|
||||
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_hal *hal,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)(skb->data + hal->hal_desc_sz);
|
||||
return le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;
|
||||
}
|
||||
|
||||
static inline u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab,
|
||||
struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hal.ops->rx_desc_get_l3_pad_bytes(desc);
|
||||
}
|
||||
|
||||
static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_hal *hal,
|
||||
struct hal_rx_desc *fdesc,
|
||||
struct hal_rx_desc *ldesc)
|
||||
{
|
||||
hal->ops->rx_desc_copy_end_tlv(fdesc, ldesc);
|
||||
}
|
||||
|
||||
static inline void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_hal *hal,
|
||||
struct hal_rx_desc *desc,
|
||||
u16 len)
|
||||
{
|
||||
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.ops->rx_desc_get_mpdu_ppdu_id(rx_desc);
|
||||
}
|
||||
|
||||
static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_hal *hal,
|
||||
struct hal_rx_desc *desc,
|
||||
struct ieee80211_hdr *hdr)
|
||||
{
|
||||
hal->ops->rx_desc_get_dot11_hdr(desc, hdr);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
hal->ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype);
|
||||
}
|
||||
|
||||
static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_hal *hal,
|
||||
struct hal_rx_desc *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)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
while ((skb = __skb_dequeue(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,
|
||||
bool decrypted,
|
||||
struct hal_rx_desc_data *rx_info);
|
||||
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_dp *dp,
|
||||
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_dp *dp, struct sk_buff *skb);
|
||||
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,
|
||||
enum hal_encrypt_type enctype, u32 flags);
|
||||
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_ampdu_start(struct ath12k *ar,
|
||||
struct ieee80211_ampdu_params *params,
|
||||
u8 link_id);
|
||||
|
|
@ -127,14 +219,12 @@ 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);
|
||||
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);
|
||||
|
|
@ -143,15 +233,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);
|
||||
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,
|
||||
struct napi_struct *napi,
|
||||
int budget);
|
||||
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);
|
||||
|
|
@ -160,32 +242,27 @@ 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 ath12k_dp_rx_info *rx_info);
|
||||
struct ath12k_dp_link_peer *
|
||||
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);
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
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_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,
|
||||
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);
|
||||
void ath12k_dp_rx_process_reo_cmd_update_rx_queue_list(struct ath12k_dp *dp);
|
||||
void ath12k_dp_init_rx_tid_rxq(struct ath12k_dp_rx_tid_rxq *rx_tid_rxq,
|
||||
struct ath12k_dp_rx_tid *rx_tid,
|
||||
bool active);
|
||||
void ath12k_dp_mark_tid_as_inactive(struct ath12k_dp *dp, int peer_id, u8 tid);
|
||||
#endif /* ATH12K_DP_RX_H */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,41 +1,32 @@
|
|||
/* 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"
|
||||
|
||||
struct ath12k_dp_htt_wbm_tx_status {
|
||||
bool acked;
|
||||
s8 ack_rssi;
|
||||
};
|
||||
|
||||
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,
|
||||
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);
|
||||
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_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_dp *dp,
|
||||
struct dp_tx_ring *tx_ring,
|
||||
struct ath12k_tx_desc_params *desc_params);
|
||||
#endif
|
||||
|
|
|
|||
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) 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 <linux/skbuff.h>
|
||||
#include <linux/ctype.h>
|
||||
|
|
@ -376,6 +376,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)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -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;
|
||||
|
|
@ -193,8 +185,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;
|
||||
|
|
@ -285,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) {
|
||||
|
|
@ -377,6 +287,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
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
@ -172,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);
|
||||
|
|
@ -206,4 +204,139 @@ 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);
|
||||
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);
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2020-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/msi.h>
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* 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 +31,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);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "hif.h"
|
||||
#include "mhi.h"
|
||||
#include "debug.h"
|
||||
#include "hal.h"
|
||||
|
||||
#define ATH12K_PCI_BAR_NUM 0
|
||||
#define ATH12K_PCI_DMA_MASK 36
|
||||
|
|
@ -28,44 +29,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 +110,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;
|
||||
|
|
@ -183,10 +133,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);
|
||||
|
|
@ -199,13 +151,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;
|
||||
|
|
@ -544,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_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++)
|
||||
|
|
@ -1244,6 +1198,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)
|
||||
{
|
||||
|
|
@ -1549,28 +1504,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;
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_PCI,
|
||||
"pci tcsr_soc_hw_version major %d minor %d\n",
|
||||
*major, *minor);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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 +1566,25 @@ 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;
|
||||
}
|
||||
|
||||
default:
|
||||
dev_err(&pdev->dev, "Unknown PCI device found: 0x%x\n",
|
||||
pci_dev->device);
|
||||
ret = -EOPNOTSUPP;
|
||||
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
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
|
@ -1709,13 +1639,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);
|
||||
|
|
@ -1774,6 +1716,9 @@ qmi_fail:
|
|||
|
||||
ath12k_hal_srng_deinit(ab);
|
||||
ath12k_ce_free_pipes(ab);
|
||||
|
||||
ab_pci->device_family_ops->arch_deinit(ab);
|
||||
|
||||
ath12k_core_free(ab);
|
||||
}
|
||||
|
||||
|
|
@ -1862,33 +1807,47 @@ 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 ||
|
||||
!driver->ops.arch_init || !driver->ops.arch_deinit)
|
||||
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;
|
||||
|
||||
void ath12k_pci_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&ath12k_pci_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);
|
||||
}
|
||||
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/*");
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
/* 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
|
||||
|
||||
#include <linux/mhi.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include "core.h"
|
||||
|
||||
|
|
@ -29,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
|
||||
|
||||
|
|
@ -38,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
|
||||
|
||||
|
|
@ -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,17 @@ 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);
|
||||
int (*arch_init)(struct ath12k_base *ab);
|
||||
void (*arch_deinit)(struct ath12k_base *ab);
|
||||
};
|
||||
|
||||
struct ath12k_pci_reg_base {
|
||||
u32 umac_base;
|
||||
u32 ce_reg_base;
|
||||
};
|
||||
|
||||
struct ath12k_pci {
|
||||
struct pci_dev *pdev;
|
||||
struct ath12k_base *ab;
|
||||
|
|
@ -119,6 +128,16 @@ 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;
|
||||
const struct ath12k_pci_reg_base *reg_base;
|
||||
};
|
||||
|
||||
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;
|
||||
const struct ath12k_pci_reg_base *reg_base;
|
||||
};
|
||||
|
||||
static inline struct ath12k_pci *ath12k_pci_priv(struct ath12k_base *ab)
|
||||
|
|
@ -148,6 +167,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 */
|
||||
|
|
|
|||
|
|
@ -1,211 +1,28 @@
|
|||
// 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 "peer.h"
|
||||
#include "debug.h"
|
||||
#include "debugfs.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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
static int ath12k_wait_for_dp_link_peer_common(struct ath12k_base *ab, int vdev_id,
|
||||
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_peer_find(ab, vdev_id, addr);
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
spin_lock_bh(&dp->dp_lock);
|
||||
mapped = !!ath12k_dp_link_peer_find_by_vdev_and_addr(dp,
|
||||
vdev_id,
|
||||
addr);
|
||||
spin_unlock_bh(&dp->dp_lock);
|
||||
|
||||
(mapped == expect_mapped ||
|
||||
test_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags));
|
||||
|
|
@ -219,30 +36,30 @@ 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;
|
||||
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;
|
||||
|
||||
ath12k_warn(ab, "removing stale peer %pM from vdev_id %d\n",
|
||||
peer->addr, vdev_id);
|
||||
|
||||
list_del(&peer->list);
|
||||
kfree(peer);
|
||||
ath12k_dp_link_peer_free(peer);
|
||||
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)
|
||||
{
|
||||
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,
|
||||
|
|
@ -293,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;
|
||||
|
|
@ -308,7 +129,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,
|
||||
|
|
@ -316,28 +137,34 @@ 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;
|
||||
struct ath12k_dp_link_peer *peer;
|
||||
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);
|
||||
|
||||
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");
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
spin_lock_bh(&ar->ab->base_lock);
|
||||
peer = ath12k_peer_find_by_pdev_idx(ar->ab, ar->pdev_idx, arg->peer_addr);
|
||||
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) {
|
||||
|
|
@ -352,11 +179,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_peer_find(ar->ab, arg->vdev_id, arg->peer_addr);
|
||||
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);
|
||||
|
||||
|
|
@ -382,13 +210,10 @@ 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)
|
||||
peer->ucast_ra_only = true;
|
||||
|
||||
if (sta) {
|
||||
ahsta = ath12k_sta_to_ahsta(sta);
|
||||
arsta = wiphy_dereference(ath12k_ar_to_hw(ar)->wiphy,
|
||||
|
|
@ -412,17 +237,22 @@ 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(&ar->ab->base_lock);
|
||||
spin_unlock_bh(&dp->dp_lock);
|
||||
|
||||
return 0;
|
||||
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;
|
||||
}
|
||||
|
||||
static u16 ath12k_peer_ml_alloc(struct ath12k_hw *ah)
|
||||
u16 ath12k_peer_ml_alloc(struct ath12k_hw *ah)
|
||||
{
|
||||
u16 ml_peer_id;
|
||||
|
||||
|
|
@ -442,68 +272,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);
|
||||
|
|
@ -536,6 +304,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,
|
||||
|
|
@ -568,3 +341,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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,84 +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_PEER_H
|
||||
#define ATH12K_PEER_H
|
||||
|
||||
#include "dp_rx.h"
|
||||
#include "dp_peer.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;
|
||||
};
|
||||
|
||||
struct ath12k_ml_peer {
|
||||
struct list_head list;
|
||||
u8 addr[ETH_ALEN];
|
||||
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 +16,14 @@ 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;
|
||||
}
|
||||
|
||||
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);
|
||||
u16 ath12k_peer_ml_alloc(struct ath12k_hw *ah);
|
||||
#endif /* _PEER_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.
|
||||
*/
|
||||
|
||||
#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);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
# 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 \
|
||||
hal_tx.o \
|
||||
hal_rx.o \
|
||||
dp_rx.o \
|
||||
dp_tx.o \
|
||||
dp.o \
|
||||
dp_mon.o \
|
||||
hal.o \
|
||||
hal_qcn9274.o \
|
||||
hal_wcn7850.o
|
||||
|
||||
ath12k_wifi7-$(CONFIG_ATH12K_AHB) += ahb.o
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
// 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 <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/soc/qcom/mdt_loader.h>
|
||||
#include "../ahb.h"
|
||||
#include "ahb.h"
|
||||
#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",
|
||||
.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;
|
||||
int ret;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
|
@ -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 */
|
||||
|
|
@ -0,0 +1,973 @@
|
|||
// 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 <linux/types.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/bitfield.h>
|
||||
|
||||
#include "../core.h"
|
||||
#include "../ce.h"
|
||||
#include "ce.h"
|
||||
#include "../dp_rx.h"
|
||||
|
||||
/* Copy Engine (CE) configs for QCN9274 */
|
||||
/* Target firmware's Copy Engine configuration. */
|
||||
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),
|
||||
.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_wifi7_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_wifi7_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_wifi7_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_wifi7_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_wifi7_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_wifi7_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_wifi7_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_wifi7_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,
|
||||
},
|
||||
};
|
||||
|
|
@ -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_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_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_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 */
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
// 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 <linux/module.h>
|
||||
#include "../ahb.h"
|
||||
#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();
|
||||
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");
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
// 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 "hal_desc.h"
|
||||
#include "../dp_mon.h"
|
||||
#include "dp_mon.h"
|
||||
#include "../dp_cmn.h"
|
||||
#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,
|
||||
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 (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 (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 (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;
|
||||
|
||||
if (budget <= 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
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 (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_wifi7_dp_mon_process_ring(dp, id, napi,
|
||||
budget,
|
||||
0);
|
||||
budget -= work_done;
|
||||
tot_work_done += work_done;
|
||||
if (budget <= 0)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dp->hw_params->ring_mask->rx_mon_dest[grp_id]) {
|
||||
monitor_mode = ATH12K_DP_RX_MONITOR_MODE;
|
||||
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_wifi7_dp_mon_process_ring(dp, id, napi,
|
||||
budget,
|
||||
monitor_mode);
|
||||
budget -= work_done;
|
||||
tot_work_done += work_done;
|
||||
|
||||
if (budget <= 0)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dp->hw_params->ring_mask->tx_mon_dest[grp_id]) {
|
||||
monitor_mode = ATH12K_DP_TX_MONITOR_MODE;
|
||||
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_wifi7_dp_mon_process_ring(dp, id,
|
||||
napi, budget,
|
||||
monitor_mode);
|
||||
budget -= work_done;
|
||||
tot_work_done += work_done;
|
||||
|
||||
if (budget <= 0)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dp->hw_params->ring_mask->reo_status[grp_id])
|
||||
ath12k_wifi7_dp_rx_process_reo_status(dp);
|
||||
|
||||
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(dp, rx_ring, &list, 0);
|
||||
}
|
||||
|
||||
/* TODO: Implement handler for other interrupts */
|
||||
|
||||
done:
|
||||
return tot_work_done;
|
||||
}
|
||||
|
||||
static struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = {
|
||||
.service_srng = ath12k_wifi7_dp_service_srng,
|
||||
.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,
|
||||
.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,
|
||||
.peer_rx_tid_qref_reset = ath12k_wifi7_peer_rx_tid_qref_reset,
|
||||
.rx_tid_delete_handler = ath12k_wifi7_dp_rx_tid_delete_handler,
|
||||
};
|
||||
|
||||
/* 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;
|
||||
dp->hal = &ab->hal;
|
||||
|
||||
dp->ops = &ath12k_wifi7_dp_arch_ops;
|
||||
|
||||
return dp;
|
||||
}
|
||||
|
||||
void ath12k_wifi7_dp_device_free(struct ath12k_dp *dp)
|
||||
{
|
||||
kfree(dp);
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/* 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 "../dp_cmn.h"
|
||||
#include "hw.h"
|
||||
|
||||
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);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,23 @@
|
|||
/* 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);
|
||||
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
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,59 @@
|
|||
/* 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"
|
||||
#include "hal_rx_desc.h"
|
||||
|
||||
struct ath12k_hal_reo_cmd;
|
||||
|
||||
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_dp *dp, struct napi_struct *napi,
|
||||
int budget);
|
||||
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_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,
|
||||
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_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_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,
|
||||
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,
|
||||
struct ath12k_dp_link_peer *peer, u8 tid);
|
||||
int ath12k_wifi7_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));
|
||||
int ath12k_wifi7_dp_reo_cache_flush(struct ath12k_base *ab,
|
||||
struct ath12k_dp_rx_tid_rxq *rx_tid);
|
||||
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);
|
||||
void ath12k_wifi7_peer_rx_tid_qref_reset(struct ath12k_base *ab, u16 peer_id, u16 tid);
|
||||
bool
|
||||
ath12k_wifi7_dp_rxdesc_mpdu_valid(struct ath12k_base *ab,
|
||||
struct hal_rx_desc *rx_desc);
|
||||
int ath12k_wifi7_dp_rx_tid_delete_handler(struct ath12k_base *ab,
|
||||
struct ath12k_dp_rx_tid_rxq *rx_tid);
|
||||
#endif
|
||||
|
|
@ -0,0 +1,978 @@
|
|||
// 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"
|
||||
#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,
|
||||
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_wifi7_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;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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;
|
||||
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 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;
|
||||
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 = dp->hw_params->iova_mask;
|
||||
bool is_diff_encap = false;
|
||||
bool is_null_frame = false;
|
||||
|
||||
if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &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 = dp->hw_params->hw_ops->get_ring_selector(skb);
|
||||
|
||||
tcl_ring_sel:
|
||||
tcl_ring_retry = false;
|
||||
ti.ring_id = ring_selector % dp->hw_params->max_tx_ring;
|
||||
|
||||
ring_map |= BIT(ti.ring_id);
|
||||
ti.rbm_id = hal->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;
|
||||
|
||||
dp_link_vif = ath12k_dp_vif_to_dp_link_vif(&ahvif->dp_vif, arvif->link_id);
|
||||
|
||||
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, &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 = 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 = dp_link_vif->lmac_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 = 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 &&
|
||||
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(&dp->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(dp, &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(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;
|
||||
goto fail_remove_tx_buf;
|
||||
}
|
||||
|
||||
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)) ||
|
||||
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 = dp_link_vif->pdev_idx;
|
||||
ti.desc_id = tx_desc->desc_id;
|
||||
ti.data_len = skb->len;
|
||||
skb_cb->paddr = ti.paddr;
|
||||
|
||||
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_wifi7_hal_tx_cmd_ext_desc_setup(ab, msg, &ti);
|
||||
|
||||
if (add_htt_metadata) {
|
||||
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");
|
||||
goto fail_free_ext_skb;
|
||||
}
|
||||
}
|
||||
|
||||
ti.paddr = dma_map_single(dp->dev, skb_ext_desc->data,
|
||||
skb_ext_desc->len, DMA_TO_DEVICE);
|
||||
ret = dma_mapping_error(dp->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 = &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);
|
||||
dp->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(dp->hw_params->max_tx_ring) - 1) &&
|
||||
dp->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);
|
||||
|
||||
dp->device_stats.tx_enqueued[ti.ring_id]++;
|
||||
|
||||
ath12k_wifi7_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(&dp_pdev->num_tx_pending);
|
||||
|
||||
return 0;
|
||||
|
||||
fail_unmap_dma_ext:
|
||||
if (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(dp->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_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 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);
|
||||
|
||||
pdev_id = ath12k_hw_mac_id_to_pdev_id(dp->hw_params, desc_params->mac_id);
|
||||
|
||||
rcu_read_lock();
|
||||
dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_id);
|
||||
if (!dp_pdev) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
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(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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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)) {
|
||||
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);
|
||||
|
||||
info->status.ack_signal += noise_floor;
|
||||
}
|
||||
|
||||
info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID;
|
||||
} else {
|
||||
info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
|
||||
}
|
||||
}
|
||||
|
||||
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_pdev_dp_to_hw(dp_pdev), msdu);
|
||||
goto exit;
|
||||
} else {
|
||||
status.sta = peer->sta;
|
||||
}
|
||||
|
||||
status.info = info;
|
||||
status.skb = msdu;
|
||||
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_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;
|
||||
u16 peer_id;
|
||||
|
||||
status_desc = desc;
|
||||
|
||||
wbm_status = le32_get_bits(status_desc->info0,
|
||||
HTT_TX_WBM_COMP_INFO0_STATUS);
|
||||
dp->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(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(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
|
||||
* use WDS offload functionality.
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
ath12k_warn(dp->ab, "Unknown htt wbm tx status %d\n", wbm_status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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_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_link_peer_find_by_peerid(dp_pdev, ts->peer_id);
|
||||
if (!peer || !peer->sta) {
|
||||
ath12k_dbg(dp->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 (peer->last_txrate.nss)
|
||||
txrate.nss = peer->last_txrate.nss;
|
||||
else
|
||||
txrate.nss = arsta->peer_nss;
|
||||
|
||||
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(dp->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(dp->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(dp->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(dp->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(dp->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(dp->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(&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,
|
||||
struct ath12k_tx_desc_params *desc_params,
|
||||
struct hal_tx_status *ts,
|
||||
int ring)
|
||||
{
|
||||
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;
|
||||
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_dp_link_peer *peer;
|
||||
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);
|
||||
dp->device_stats.tx_completed[ring]++;
|
||||
|
||||
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,
|
||||
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[dp_pdev->mac_id])) {
|
||||
ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!skb_cb->vif) {
|
||||
ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), 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)) {
|
||||
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);
|
||||
|
||||
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(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",
|
||||
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_wifi7_dp_tx_update_txcompl(dp_pdev, ts);
|
||||
|
||||
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",
|
||||
ts->peer_id);
|
||||
ieee80211_free_txskb(ath12k_pdev_dp_to_hw(dp_pdev), msdu);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status.sta = peer->sta;
|
||||
status.info = info;
|
||||
status.skb = msdu;
|
||||
rate = peer->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_pdev_dp_to_hw(dp_pdev), &status);
|
||||
|
||||
exit:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static void
|
||||
ath12k_wifi7_dp_tx_status_parse(struct ath12k_dp *dp,
|
||||
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_wifi7_dp_tx_completion_handler(struct ath12k_dp *dp, int ring_id)
|
||||
{
|
||||
struct ath12k_base *ab = dp->ab;
|
||||
struct ath12k_pdev_dp *dp_pdev;
|
||||
int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.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;
|
||||
struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id];
|
||||
struct hal_wbm_release_ring *desc;
|
||||
u8 pdev_idx;
|
||||
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_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 */
|
||||
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(dp, 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);
|
||||
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);
|
||||
dp->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(dp, (void *)tx_status,
|
||||
tx_ring, &desc_params);
|
||||
continue;
|
||||
}
|
||||
|
||||
pdev_idx = ath12k_hw_mac_id_to_pdev_id(dp->hw_params, desc_params.mac_id);
|
||||
|
||||
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(dp_pdev, &desc_params, &ts,
|
||||
tx_ring->tcl_data_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;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/* 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
|
||||
|
||||
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_dp *dp, int ring_id);
|
||||
u32 ath12k_wifi7_dp_tx_get_vdev_bank_config(struct ath12k_base *ab,
|
||||
struct ath12k_link_vif *arvif);
|
||||
#endif
|
||||
|
|
@ -0,0 +1,705 @@
|
|||
// 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"
|
||||
#include "hal_tx.h"
|
||||
#include "../debug.h"
|
||||
#include "../hif.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),
|
||||
.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,
|
||||
},
|
||||
};
|
||||
|
||||
int ath12k_wifi7_hal_init(struct ath12k_base *ab)
|
||||
{
|
||||
struct ath12k_hal *hal = &ab->hal;
|
||||
|
||||
memset(hal, 0, sizeof(*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;
|
||||
hal->hal_wbm_release_ring_tx_size = sizeof(struct hal_wbm_release_ring_tx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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_MAX)
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,564 @@
|
|||
/* 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
|
||||
|
||||
#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->umac_ce0_src_reg_base)
|
||||
#define HAL_SEQ_WCSS_UMAC_CE0_DST_REG(hal) \
|
||||
((hal)->regs->umac_ce0_dest_reg_base)
|
||||
#define HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(hal) \
|
||||
((hal)->regs->umac_ce1_src_reg_base)
|
||||
#define HAL_SEQ_WCSS_UMAC_CE1_DST_REG(hal) \
|
||||
((hal)->regs->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->tcl1_ring_base_lsb)
|
||||
#define HAL_TCL1_RING_BASE_MSB(hal) \
|
||||
((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->tcl1_ring_misc)
|
||||
#define HAL_TCL1_RING_TP_ADDR_LSB(hal) \
|
||||
((hal)->regs->tcl1_ring_tp_addr_lsb)
|
||||
#define HAL_TCL1_RING_TP_ADDR_MSB(hal) \
|
||||
((hal)->regs->tcl1_ring_tp_addr_msb)
|
||||
#define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX0(hal) \
|
||||
((hal)->regs->tcl1_ring_consumer_int_setup_ix0)
|
||||
#define HAL_TCL1_RING_CONSUMER_INT_SETUP_IX1(hal) \
|
||||
((hal)->regs->tcl1_ring_consumer_int_setup_ix1)
|
||||
#define HAL_TCL1_RING_MSI1_BASE_LSB(hal) \
|
||||
((hal)->regs->tcl1_ring_msi1_base_lsb)
|
||||
#define HAL_TCL1_RING_MSI1_BASE_MSB(hal) \
|
||||
((hal)->regs->tcl1_ring_msi1_base_msb)
|
||||
#define HAL_TCL1_RING_MSI1_DATA(hal) \
|
||||
((hal)->regs->tcl1_ring_msi1_data)
|
||||
#define HAL_TCL2_RING_BASE_LSB(hal) \
|
||||
((hal)->regs->tcl2_ring_base_lsb)
|
||||
#define HAL_TCL_RING_BASE_LSB(hal) \
|
||||
((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)); })
|
||||
#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->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->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->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->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->reo1_ring_producer_int_setup)
|
||||
#define HAL_REO1_RING_MSI1_BASE_LSB(hal) \
|
||||
((hal)->regs->reo1_ring_msi1_base_lsb)
|
||||
#define HAL_REO1_RING_MSI1_BASE_MSB(hal) \
|
||||
((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
|
||||
#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->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->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->sw2reo_ring_base)
|
||||
#define HAL_SW2REO1_RING_BASE_LSB(hal) \
|
||||
((hal)->regs->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->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->wbm_idle_ring_base_lsb)
|
||||
#define HAL_WBM_IDLE_LINK_RING_MISC_ADDR(hal) \
|
||||
((hal)->regs->wbm_idle_ring_misc_addr)
|
||||
#define HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(hal) \
|
||||
((hal)->regs->wbm_r0_idle_list_cntl_addr)
|
||||
#define HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(hal) \
|
||||
((hal)->regs->wbm_r0_idle_list_size_addr)
|
||||
#define HAL_WBM_SCATTERED_RING_BASE_LSB(hal) \
|
||||
((hal)->regs->wbm_scattered_ring_base_lsb)
|
||||
#define HAL_WBM_SCATTERED_RING_BASE_MSB(hal) \
|
||||
((hal)->regs->wbm_scattered_ring_base_msb)
|
||||
#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(hal) \
|
||||
((hal)->regs->wbm_scattered_desc_head_info_ix0)
|
||||
#define HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(hal) \
|
||||
((hal)->regs->wbm_scattered_desc_head_info_ix1)
|
||||
#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(hal) \
|
||||
((hal)->regs->wbm_scattered_desc_tail_info_ix0)
|
||||
#define HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(hal) \
|
||||
((hal)->regs->wbm_scattered_desc_tail_info_ix1)
|
||||
#define HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(hal) \
|
||||
((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->wbm_sw_release_ring_base_lsb)
|
||||
#define HAL_WBM_SW1_RELEASE_RING_BASE_LSB(hal) \
|
||||
((hal)->regs->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->wbm0_release_ring_base_lsb)
|
||||
|
||||
#define HAL_WBM1_RELEASE_RING_BASE_LSB(hal) \
|
||||
((hal)->regs->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)
|
||||
#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 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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid);
|
||||
#endif
|
||||
|
|
@ -1,92 +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 "core.h"
|
||||
#include "../core.h"
|
||||
|
||||
#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 */,
|
||||
|
|
@ -820,35 +741,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 +878,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 +1132,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,107 +1588,11 @@ 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;
|
||||
} __packed;
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
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)
|
||||
|
|
@ -2007,7 +1734,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;
|
||||
|
|
@ -2331,7 +2057,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)
|
||||
|
|
@ -2957,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)
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,45 @@
|
|||
/* 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 <linux/ieee80211.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#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;
|
||||
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,
|
||||
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);
|
||||
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);
|
||||
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
|
||||
|
|
@ -4,15 +4,17 @@
|
|||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
#include "hal.h"
|
||||
#include "../debug.h"
|
||||
#include "../hal.h"
|
||||
#include "../hif.h"
|
||||
#include "hal_tx.h"
|
||||
#include "hal_rx.h"
|
||||
#include "hal_desc.h"
|
||||
#include "hif.h"
|
||||
#include "hal.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 +23,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 +47,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 +97,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 +223,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 +241,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 +269,9 @@ out:
|
|||
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 +283,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 +293,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,10 +323,11 @@ 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_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;
|
||||
u32 cookie;
|
||||
|
|
@ -329,7 +336,7 @@ int ath12k_hal_desc_reo_parse_err(struct ath12k_base *ab,
|
|||
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) {
|
||||
|
|
@ -338,14 +345,15 @@ 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);
|
||||
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_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_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;
|
||||
|
|
@ -378,7 +386,7 @@ int ath12k_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;
|
||||
}
|
||||
|
||||
|
|
@ -390,7 +398,7 @@ int ath12k_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;
|
||||
}
|
||||
|
||||
|
|
@ -429,12 +437,13 @@ int ath12k_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;
|
||||
}
|
||||
|
||||
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_buffer_addr *buff_addr,
|
||||
dma_addr_t *paddr, u32 *cookie)
|
||||
{
|
||||
*paddr = ((u64)(le32_get_bits(buff_addr->info1,
|
||||
BUFFER_ADDR_INFO1_ADDR)) << 32) |
|
||||
|
|
@ -443,10 +452,10 @@ void ath12k_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;
|
||||
|
|
@ -474,11 +483,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;
|
||||
|
|
@ -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,8 +916,10 @@ 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)
|
||||
{
|
||||
struct ath12k_hal *hal = &ab->hal;
|
||||
|
||||
u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG;
|
||||
u32 val;
|
||||
|
||||
|
|
@ -904,7 +929,7 @@ void ath12k_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);
|
||||
|
|
@ -912,15 +937,15 @@ void ath12k_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,
|
||||
|
|
@ -929,19 +954,21 @@ void ath12k_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map)
|
|||
ring_hash_map);
|
||||
}
|
||||
|
||||
void ath12k_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab)
|
||||
void ath12k_wifi7_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(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);
|
||||
}
|
||||
|
|
@ -1,12 +1,16 @@
|
|||
/* 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
|
||||
#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;
|
||||
|
|
@ -17,11 +21,9 @@ struct hal_rx_wbm_rel_info {
|
|||
bool continuation;
|
||||
void *rx_desc;
|
||||
bool hw_cc_done;
|
||||
__le32 peer_metadata;
|
||||
};
|
||||
|
||||
#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,69 +41,10 @@ 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
|
||||
#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,
|
||||
|
|
@ -113,167 +56,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)
|
||||
|
|
@ -531,11 +313,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];
|
||||
|
|
@ -588,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
|
||||
|
|
@ -1044,128 +812,60 @@ 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);
|
||||
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_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_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_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_dp *dp, void *desc,
|
||||
struct hal_rx_wbm_rel_info *rel_info);
|
||||
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,
|
||||
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_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,
|
||||
u32 start_seq, enum hal_pn_type type);
|
||||
|
||||
#endif
|
||||
|
|
@ -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)
|
||||
|
|
@ -1495,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;
|
||||
|
|
@ -1530,15 +1483,9 @@ 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;
|
||||
} __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 */
|
||||
|
|
@ -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.h"
|
||||
#include "hal_tx.h"
|
||||
#include "hif.h"
|
||||
#include "../hif.h"
|
||||
#include "hal.h"
|
||||
|
||||
#define DSCP_TID_MAP_TBL_ENTRY_SIZE 64
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
@ -136,10 +136,3 @@ void ath12k_hal_tx_set_dscp_tid_map(struct ath12k_base *ab, int id)
|
|||
HAL_TCL1_RING_CMN_CTRL_REG,
|
||||
ctrl_reg_val);
|
||||
}
|
||||
|
||||
void ath12k_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);
|
||||
}
|
||||
|
|
@ -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 "../mac.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
|
||||
|
||||
/* TODO: check all these data can be managed with struct ath12k_tx_desc_info for perf */
|
||||
struct hal_tx_info {
|
||||
|
|
@ -188,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_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_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);
|
||||
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
|
||||
|
|
@ -0,0 +1,805 @@
|
|||
// 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"
|
||||
#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 */
|
||||
[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] = {},
|
||||
[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] = {},
|
||||
[HAL_PPE_RELEASE] = {},
|
||||
[HAL_TX_MONITOR_BUF] = {},
|
||||
[HAL_RXDMA_MONITOR_DST] = {},
|
||||
[HAL_TX_MONITOR_DST] = {}
|
||||
};
|
||||
|
||||
const struct ath12k_hw_regs wcn7850_regs = {
|
||||
/* SW2TCL(x) R0 ring configuration address */
|
||||
.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 */
|
||||
.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 */
|
||||
.ppe_rel_ring_base = 0x0000043c,
|
||||
|
||||
/* REO DEST ring address */
|
||||
.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 */
|
||||
.reo2_sw0_ring_base = 0x000008a4,
|
||||
|
||||
/* REO Reinject ring address */
|
||||
.sw2reo_ring_base = 0x00000304,
|
||||
.sw2reo1_ring_base = 0x0000037c,
|
||||
|
||||
/* REO cmd ring address */
|
||||
.reo_cmd_ring_base = 0x0000028c,
|
||||
|
||||
/* REO status ring address */
|
||||
.reo_status_ring_base = 0x00000a84,
|
||||
|
||||
/* 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 = 0x1e40304,
|
||||
};
|
||||
|
||||
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,
|
||||
RX_MSDU_END_INFO5_LAST_MSDU);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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_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_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_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);
|
||||
|
||||
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_hal_rx_desc_get_msdu_payload_wcn7850(struct hal_rx_desc *desc)
|
||||
{
|
||||
return &desc->u.wcn7850.msdu_payload[0];
|
||||
}
|
||||
|
||||
u32 ath12k_hal_rx_desc_get_mpdu_start_offset_wcn7850(void)
|
||||
{
|
||||
return offsetof(struct hal_rx_desc_wcn7850, mpdu_start_tag);
|
||||
}
|
||||
|
||||
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,
|
||||
RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) ==
|
||||
RX_DESC_DECRYPT_STATUS_CODE_OK);
|
||||
}
|
||||
|
||||
u32 ath12k_hal_get_rx_desc_size_wcn7850(void)
|
||||
{
|
||||
return sizeof(struct hal_rx_desc_wcn7850);
|
||||
}
|
||||
|
||||
u8 ath12k_hal_rx_desc_get_msdu_src_link_wcn7850(struct hal_rx_desc *desc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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_hal_rx_desc_get_crypto_hdr_wcn7850(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_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;
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_hal *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(hal);
|
||||
s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP;
|
||||
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(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(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(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(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(hal);
|
||||
s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP;
|
||||
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(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(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(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(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(hal) +
|
||||
HAL_CE_DST_STATUS_RING_BASE_LSB;
|
||||
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(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(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(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(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];
|
||||
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 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 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,
|
||||
.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_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,
|
||||
.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,
|
||||
.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,
|
||||
.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,
|
||||
};
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/* 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"
|
||||
#include "hal.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,
|
||||
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);
|
||||
u32 ath12k_hal_get_rx_desc_size_wcn7850(void);
|
||||
u8 ath12k_hal_rx_desc_get_msdu_src_link_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
|
||||
|
|
@ -0,0 +1,945 @@
|
|||
// 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 <linux/types.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/bitfield.h>
|
||||
|
||||
#include "../debug.h"
|
||||
#include "../core.h"
|
||||
#include "../ce.h"
|
||||
#include "ce.h"
|
||||
#include "../hw.h"
|
||||
#include "hw.h"
|
||||
#include "../mhi.h"
|
||||
#include "mhi.h"
|
||||
#include "dp_rx.h"
|
||||
#include "../peer.h"
|
||||
#include "wmi.h"
|
||||
#include "../wow.h"
|
||||
#include "../debugfs.h"
|
||||
#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,
|
||||
0xac, 0x12, 0x00, 0x03);
|
||||
|
||||
static u8 ath12k_wifi7_hw_qcn9274_mac_from_pdev_id(int pdev_idx)
|
||||
{
|
||||
return pdev_idx;
|
||||
}
|
||||
|
||||
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_wifi7_hw_mac_id_to_srng_id_qcn9274(const struct ath12k_hw_params *hw,
|
||||
int mac_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 ath12k_wifi7_hw_get_ring_selector_qcn9274(struct sk_buff *skb)
|
||||
{
|
||||
return smp_processor_id();
|
||||
}
|
||||
|
||||
static bool ath12k_wifi7_dp_srng_is_comp_ring_qcn9274(int ring_num)
|
||||
{
|
||||
if (ring_num < 3 || ring_num == 4)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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_wifi7_hw_mac_id_to_pdev_id_wcn7850(const struct ath12k_hw_params *hw,
|
||||
int mac_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_wifi7_hw_get_ring_selector_wcn7850(struct sk_buff *skb)
|
||||
{
|
||||
return skb_get_queue_mapping(skb);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ath12k_is_addba_resp_action_code(struct ieee80211_mgmt *mgmt)
|
||||
{
|
||||
if (!ieee80211_is_action(mgmt->frame_control))
|
||||
return false;
|
||||
|
||||
if (mgmt->u.action.category != WLAN_CATEGORY_BACK)
|
||||
return false;
|
||||
|
||||
if (mgmt->u.action.u.addba_resp.action_code != WLAN_ACTION_ADDBA_RESP)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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);
|
||||
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)) {
|
||||
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);
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION)
|
||||
return arvif->is_up &&
|
||||
(vif->valid_links == vif->active_links) &&
|
||||
!ieee80211_is_probe_req(fc) &&
|
||||
!ieee80211_is_auth(fc) &&
|
||||
!ieee80211_is_deauth(fc) &&
|
||||
!ath12k_is_addba_resp_action_code(mgmt);
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_AP)
|
||||
return !(ieee80211_is_probe_resp(fc) || ieee80211_is_auth(fc) ||
|
||||
ieee80211_is_assoc_resp(fc) || ieee80211_is_reassoc_resp(fc) ||
|
||||
ath12k_is_addba_resp_action_code(mgmt));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static const struct ath12k_hw_ops qcn9274_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_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_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_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_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
|
||||
#define ATH12K_TX_RING_MASK_3 0x8
|
||||
#define ATH12K_TX_RING_MASK_4 0x10
|
||||
|
||||
#define ATH12K_RX_RING_MASK_0 0x1
|
||||
#define ATH12K_RX_RING_MASK_1 0x2
|
||||
#define ATH12K_RX_RING_MASK_2 0x4
|
||||
#define ATH12K_RX_RING_MASK_3 0x8
|
||||
|
||||
#define ATH12K_RX_ERR_RING_MASK_0 0x1
|
||||
|
||||
#define ATH12K_RX_WBM_REL_RING_MASK_0 0x1
|
||||
|
||||
#define ATH12K_REO_STATUS_RING_MASK_0 0x1
|
||||
|
||||
#define ATH12K_HOST2RXDMA_RING_MASK_0 0x1
|
||||
|
||||
#define ATH12K_RX_MON_RING_MASK_0 0x1
|
||||
#define ATH12K_RX_MON_RING_MASK_1 0x2
|
||||
#define ATH12K_RX_MON_RING_MASK_2 0x4
|
||||
|
||||
#define ATH12K_TX_MON_RING_MASK_0 0x1
|
||||
#define ATH12K_TX_MON_RING_MASK_1 0x2
|
||||
|
||||
#define ATH12K_RX_MON_STATUS_RING_MASK_0 0x1
|
||||
#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_wifi7_hw_ring_mask_qcn9274 = {
|
||||
.tx = {
|
||||
ATH12K_TX_RING_MASK_0,
|
||||
ATH12K_TX_RING_MASK_1,
|
||||
ATH12K_TX_RING_MASK_2,
|
||||
ATH12K_TX_RING_MASK_3,
|
||||
},
|
||||
.rx_mon_dest = {
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
ATH12K_RX_MON_RING_MASK_0,
|
||||
ATH12K_RX_MON_RING_MASK_1,
|
||||
ATH12K_RX_MON_RING_MASK_2,
|
||||
},
|
||||
.rx = {
|
||||
0, 0, 0, 0,
|
||||
ATH12K_RX_RING_MASK_0,
|
||||
ATH12K_RX_RING_MASK_1,
|
||||
ATH12K_RX_RING_MASK_2,
|
||||
ATH12K_RX_RING_MASK_3,
|
||||
},
|
||||
.rx_err = {
|
||||
0, 0, 0,
|
||||
ATH12K_RX_ERR_RING_MASK_0,
|
||||
},
|
||||
.rx_wbm_rel = {
|
||||
0, 0, 0,
|
||||
ATH12K_RX_WBM_REL_RING_MASK_0,
|
||||
},
|
||||
.reo_status = {
|
||||
0, 0, 0,
|
||||
ATH12K_REO_STATUS_RING_MASK_0,
|
||||
},
|
||||
.host2rxdma = {
|
||||
0, 0, 0,
|
||||
ATH12K_HOST2RXDMA_RING_MASK_0,
|
||||
},
|
||||
.tx_mon_dest = {
|
||||
0, 0, 0,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ath12k_hw_ring_mask ath12k_wifi7_hw_ring_mask_ipq5332 = {
|
||||
.tx = {
|
||||
ATH12K_TX_RING_MASK_0,
|
||||
ATH12K_TX_RING_MASK_1,
|
||||
ATH12K_TX_RING_MASK_2,
|
||||
ATH12K_TX_RING_MASK_3,
|
||||
},
|
||||
.rx_mon_dest = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
ATH12K_RX_MON_RING_MASK_0,
|
||||
},
|
||||
.rx = {
|
||||
0, 0, 0, 0,
|
||||
ATH12K_RX_RING_MASK_0,
|
||||
ATH12K_RX_RING_MASK_1,
|
||||
ATH12K_RX_RING_MASK_2,
|
||||
ATH12K_RX_RING_MASK_3,
|
||||
},
|
||||
.rx_err = {
|
||||
0, 0, 0,
|
||||
ATH12K_RX_ERR_RING_MASK_0,
|
||||
},
|
||||
.rx_wbm_rel = {
|
||||
0, 0, 0,
|
||||
ATH12K_RX_WBM_REL_RING_MASK_0,
|
||||
},
|
||||
.reo_status = {
|
||||
0, 0, 0,
|
||||
ATH12K_REO_STATUS_RING_MASK_0,
|
||||
},
|
||||
.host2rxdma = {
|
||||
0, 0, 0,
|
||||
ATH12K_HOST2RXDMA_RING_MASK_0,
|
||||
},
|
||||
.tx_mon_dest = {
|
||||
ATH12K_TX_MON_RING_MASK_0,
|
||||
ATH12K_TX_MON_RING_MASK_1,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ath12k_hw_ring_mask ath12k_wifi7_hw_ring_mask_wcn7850 = {
|
||||
.tx = {
|
||||
ATH12K_TX_RING_MASK_0,
|
||||
ATH12K_TX_RING_MASK_1,
|
||||
ATH12K_TX_RING_MASK_2,
|
||||
},
|
||||
.rx_mon_dest = {
|
||||
},
|
||||
.rx_mon_status = {
|
||||
0, 0, 0, 0,
|
||||
ATH12K_RX_MON_STATUS_RING_MASK_0,
|
||||
ATH12K_RX_MON_STATUS_RING_MASK_1,
|
||||
ATH12K_RX_MON_STATUS_RING_MASK_2,
|
||||
},
|
||||
.rx = {
|
||||
0, 0, 0,
|
||||
ATH12K_RX_RING_MASK_0,
|
||||
ATH12K_RX_RING_MASK_1,
|
||||
ATH12K_RX_RING_MASK_2,
|
||||
ATH12K_RX_RING_MASK_3,
|
||||
},
|
||||
.rx_err = {
|
||||
ATH12K_RX_ERR_RING_MASK_0,
|
||||
},
|
||||
.rx_wbm_rel = {
|
||||
ATH12K_RX_WBM_REL_RING_MASK_0,
|
||||
},
|
||||
.reo_status = {
|
||||
ATH12K_REO_STATUS_RING_MASK_0,
|
||||
},
|
||||
.host2rxdma = {
|
||||
},
|
||||
.tx_mon_dest = {
|
||||
},
|
||||
};
|
||||
|
||||
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_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[] = {
|
||||
{
|
||||
.name = "qcn9274 hw1.0",
|
||||
.hw_rev = ATH12K_HW_QCN9274_HW10,
|
||||
.fw = {
|
||||
.dir = "QCN9274/hw1.0",
|
||||
.board_size = 256 * 1024,
|
||||
.cal_offset = 128 * 1024,
|
||||
.m3_loader = ath12k_m3_fw_loader_driver,
|
||||
},
|
||||
.max_radios = 1,
|
||||
.single_pdev_only = false,
|
||||
.qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9274,
|
||||
.internal_sleep_clock = false,
|
||||
|
||||
.hw_ops = &qcn9274_ops,
|
||||
.ring_mask = &ath12k_wifi7_hw_ring_mask_qcn9274,
|
||||
|
||||
.host_ce_config = ath12k_wifi7_host_ce_config_qcn9274,
|
||||
.ce_count = 16,
|
||||
.target_ce_config = ath12k_wifi7_target_ce_config_wlan_qcn9274,
|
||||
.target_ce_count = 12,
|
||||
.svc_to_ce_map =
|
||||
ath12k_wifi7_target_service_to_ce_map_wlan_qcn9274,
|
||||
.svc_to_ce_map_len = 18,
|
||||
|
||||
.rxdma1_enable = false,
|
||||
.num_rxdma_per_pdev = 1,
|
||||
.num_rxdma_dst_ring = 0,
|
||||
.rx_mac_buf_ring = false,
|
||||
.vdev_start_delay = false,
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
BIT(NL80211_IFTYPE_MESH_POINT) |
|
||||
BIT(NL80211_IFTYPE_AP_VLAN),
|
||||
.supports_monitor = false,
|
||||
|
||||
.idle_ps = false,
|
||||
.download_calib = true,
|
||||
.supports_suspend = false,
|
||||
.tcl_ring_retry = true,
|
||||
.reoq_lut_support = true,
|
||||
.supports_shadow_regs = false,
|
||||
|
||||
.num_tcl_banks = 48,
|
||||
.max_tx_ring = 4,
|
||||
|
||||
.mhi_config = &ath12k_wifi7_mhi_config_qcn9274,
|
||||
|
||||
.wmi_init = ath12k_wifi7_wmi_init_qcn9274,
|
||||
|
||||
.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
|
||||
|
||||
.rfkill_pin = 0,
|
||||
.rfkill_cfg = 0,
|
||||
.rfkill_on_level = 0,
|
||||
|
||||
.rddm_size = 0x600000,
|
||||
|
||||
.def_num_link = 0,
|
||||
.max_mlo_peer = 256,
|
||||
|
||||
.otp_board_id_register = QCN9274_QFPROM_RAW_RFA_PDET_ROW13_LSB,
|
||||
|
||||
.supports_sta_ps = false,
|
||||
|
||||
.acpi_guid = NULL,
|
||||
.supports_dynamic_smps_6ghz = true,
|
||||
|
||||
.iova_mask = 0,
|
||||
|
||||
.supports_aspm = false,
|
||||
|
||||
.ce_ie_addr = NULL,
|
||||
.ce_remap = NULL,
|
||||
.bdf_addr_offset = 0,
|
||||
|
||||
.current_cc_support = false,
|
||||
|
||||
.dp_primary_link_only = true,
|
||||
},
|
||||
{
|
||||
.name = "wcn7850 hw2.0",
|
||||
.hw_rev = ATH12K_HW_WCN7850_HW20,
|
||||
|
||||
.fw = {
|
||||
.dir = "WCN7850/hw2.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 = 48,
|
||||
.rfkill_cfg = 0,
|
||||
.rfkill_on_level = 1,
|
||||
|
||||
.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 = ATH12K_PCIE_MAX_PAYLOAD_SIZE - 1,
|
||||
|
||||
.supports_aspm = true,
|
||||
|
||||
.ce_ie_addr = NULL,
|
||||
.ce_remap = NULL,
|
||||
.bdf_addr_offset = 0,
|
||||
|
||||
.current_cc_support = true,
|
||||
|
||||
.dp_primary_link_only = false,
|
||||
},
|
||||
{
|
||||
.name = "qcn9274 hw2.0",
|
||||
.hw_rev = ATH12K_HW_QCN9274_HW20,
|
||||
.fw = {
|
||||
.dir = "QCN9274/hw2.0",
|
||||
.board_size = 256 * 1024,
|
||||
.cal_offset = 128 * 1024,
|
||||
.m3_loader = ath12k_m3_fw_loader_driver,
|
||||
},
|
||||
.max_radios = 2,
|
||||
.single_pdev_only = false,
|
||||
.qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9274,
|
||||
.internal_sleep_clock = false,
|
||||
|
||||
.hw_ops = &qcn9274_ops,
|
||||
.ring_mask = &ath12k_wifi7_hw_ring_mask_qcn9274,
|
||||
|
||||
.host_ce_config = ath12k_wifi7_host_ce_config_qcn9274,
|
||||
.ce_count = 16,
|
||||
.target_ce_config = ath12k_wifi7_target_ce_config_wlan_qcn9274,
|
||||
.target_ce_count = 12,
|
||||
.svc_to_ce_map =
|
||||
ath12k_wifi7_target_service_to_ce_map_wlan_qcn9274,
|
||||
.svc_to_ce_map_len = 18,
|
||||
|
||||
.rxdma1_enable = true,
|
||||
.num_rxdma_per_pdev = 1,
|
||||
.num_rxdma_dst_ring = 0,
|
||||
.rx_mac_buf_ring = false,
|
||||
.vdev_start_delay = false,
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
BIT(NL80211_IFTYPE_MESH_POINT) |
|
||||
BIT(NL80211_IFTYPE_AP_VLAN),
|
||||
.supports_monitor = true,
|
||||
|
||||
.idle_ps = false,
|
||||
.download_calib = true,
|
||||
.supports_suspend = false,
|
||||
.tcl_ring_retry = true,
|
||||
.reoq_lut_support = true,
|
||||
.supports_shadow_regs = false,
|
||||
|
||||
.num_tcl_banks = 48,
|
||||
.max_tx_ring = 4,
|
||||
|
||||
.mhi_config = &ath12k_wifi7_mhi_config_qcn9274,
|
||||
|
||||
.wmi_init = ath12k_wifi7_wmi_init_qcn9274,
|
||||
|
||||
.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
|
||||
|
||||
.rfkill_pin = 0,
|
||||
.rfkill_cfg = 0,
|
||||
.rfkill_on_level = 0,
|
||||
|
||||
.rddm_size = 0x600000,
|
||||
|
||||
.def_num_link = 0,
|
||||
.max_mlo_peer = 256,
|
||||
|
||||
.otp_board_id_register = QCN9274_QFPROM_RAW_RFA_PDET_ROW13_LSB,
|
||||
|
||||
.supports_sta_ps = false,
|
||||
|
||||
.acpi_guid = NULL,
|
||||
.supports_dynamic_smps_6ghz = true,
|
||||
|
||||
.iova_mask = 0,
|
||||
|
||||
.supports_aspm = false,
|
||||
|
||||
.ce_ie_addr = NULL,
|
||||
.ce_remap = NULL,
|
||||
.bdf_addr_offset = 0,
|
||||
|
||||
.current_cc_support = false,
|
||||
|
||||
.dp_primary_link_only = true,
|
||||
},
|
||||
{
|
||||
.name = "ipq5332 hw1.0",
|
||||
.hw_rev = ATH12K_HW_IPQ5332_HW10,
|
||||
.fw = {
|
||||
.dir = "IPQ5332/hw1.0",
|
||||
.board_size = 256 * 1024,
|
||||
.cal_offset = 128 * 1024,
|
||||
.m3_loader = ath12k_m3_fw_loader_remoteproc,
|
||||
},
|
||||
.max_radios = 1,
|
||||
.single_pdev_only = false,
|
||||
.qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ5332,
|
||||
.internal_sleep_clock = false,
|
||||
|
||||
.hw_ops = &qcn9274_ops,
|
||||
.ring_mask = &ath12k_wifi7_hw_ring_mask_ipq5332,
|
||||
|
||||
.host_ce_config = ath12k_wifi7_host_ce_config_ipq5332,
|
||||
.ce_count = 12,
|
||||
.target_ce_config = ath12k_wifi7_target_ce_config_wlan_ipq5332,
|
||||
.target_ce_count = 12,
|
||||
.svc_to_ce_map =
|
||||
ath12k_wifi7_target_service_to_ce_map_wlan_ipq5332,
|
||||
.svc_to_ce_map_len = 18,
|
||||
|
||||
.rxdma1_enable = false,
|
||||
.num_rxdma_per_pdev = 1,
|
||||
.num_rxdma_dst_ring = 0,
|
||||
.rx_mac_buf_ring = false,
|
||||
.vdev_start_delay = false,
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
BIT(NL80211_IFTYPE_MESH_POINT),
|
||||
.supports_monitor = false,
|
||||
|
||||
.idle_ps = false,
|
||||
.download_calib = true,
|
||||
.supports_suspend = false,
|
||||
.tcl_ring_retry = true,
|
||||
.reoq_lut_support = false,
|
||||
.supports_shadow_regs = false,
|
||||
|
||||
.num_tcl_banks = 48,
|
||||
.max_tx_ring = 4,
|
||||
|
||||
.wmi_init = &ath12k_wifi7_wmi_init_qcn9274,
|
||||
|
||||
.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
|
||||
|
||||
.rfkill_pin = 0,
|
||||
.rfkill_cfg = 0,
|
||||
.rfkill_on_level = 0,
|
||||
|
||||
.rddm_size = 0,
|
||||
|
||||
.def_num_link = 0,
|
||||
.max_mlo_peer = 256,
|
||||
|
||||
.otp_board_id_register = 0,
|
||||
|
||||
.supports_sta_ps = false,
|
||||
|
||||
.acpi_guid = NULL,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
.iova_mask = 0,
|
||||
.supports_aspm = false,
|
||||
|
||||
.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,
|
||||
},
|
||||
};
|
||||
|
||||
/* 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_wifi7_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;
|
||||
int 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_wifi7_hw_params)) {
|
||||
ath12k_err(ab, "Unsupported Wi-Fi 7 hardware version: 0x%x\n",
|
||||
ab->hw_rev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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.h"
|
||||
|
||||
static const struct mhi_channel_config ath12k_wifi7_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_wifi7_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_wifi7_mhi_config_qcn9274 = {
|
||||
.max_channels = 30,
|
||||
.timeout_ms = 10000,
|
||||
.use_bounce_buf = false,
|
||||
.buf_len = 0,
|
||||
.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_wifi7_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_wifi7_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_wifi7_mhi_config_wcn7850 = {
|
||||
.max_channels = 128,
|
||||
.timeout_ms = 2000,
|
||||
.use_bounce_buf = false,
|
||||
.buf_len = 8192,
|
||||
.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,
|
||||
};
|
||||
|
|
@ -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_wifi7_mhi_config_qcn9274;
|
||||
extern const struct mhi_controller_config ath12k_wifi7_mhi_config_wcn7850;
|
||||
#endif /* _ATH12K_WIFI7_MHI_H */
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
// 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 <linux/pci.h>
|
||||
|
||||
#include "../pci.h"
|
||||
#include "pci.h"
|
||||
#include "../core.h"
|
||||
#include "../hif.h"
|
||||
#include "../mhi.h"
|
||||
#include "hw.h"
|
||||
#include "../hal.h"
|
||||
#include "dp.h"
|
||||
#include "core.h"
|
||||
#include "hal.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_wifi7_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_wifi7_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;
|
||||
int ret;
|
||||
|
||||
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_wifi7_pci_ops_qcn9274;
|
||||
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_wifi7_pci_ops_wcn7850;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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,
|
||||
.ops.arch_init = ath12k_wifi7_arch_init,
|
||||
.ops.arch_deinit = ath12k_wifi7_arch_deinit,
|
||||
};
|
||||
|
||||
int ath12k_wifi7_pci_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ath12k_pci_register_driver(ATH12K_DEVICE_FAMILY_WIFI7,
|
||||
&ath12k_wifi7_pci_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);
|
||||
}
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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.h"
|
||||
|
||||
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 *
|
||||
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_wifi7_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;
|
||||
}
|
||||
|
|
@ -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_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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -4217,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 = {};
|
||||
|
||||
|
|
@ -4237,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);
|
||||
}
|
||||
|
|
@ -7379,8 +7283,8 @@ 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_sta *ahsta;
|
||||
struct ath12k_link_sta *arsta;
|
||||
struct ath12k *ar;
|
||||
|
||||
if (ath12k_pull_peer_sta_kickout_ev(ab, skb, &arg) != 0) {
|
||||
|
|
@ -7392,42 +7296,24 @@ 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);
|
||||
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);
|
||||
arvif = arsta->arvif;
|
||||
if (!arvif) {
|
||||
ath12k_warn(ab, "invalid vdev id in peer sta kickout ev %d",
|
||||
peer->vdev_id);
|
||||
ath12k_warn(ab, "invalid arvif in peer sta kickout ev for STA %pM",
|
||||
arg.mac_addr);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ar = arvif->ar;
|
||||
|
||||
if (peer->mlo) {
|
||||
sta = ieee80211_find_sta_by_link_addrs(ath12k_ar_to_hw(ar),
|
||||
arg.mac_addr,
|
||||
NULL, &link_id);
|
||||
if (peer->link_id != link_id) {
|
||||
ath12k_warn(ab,
|
||||
"Spurious quick kickout for MLO STA %pM with invalid link_id, peer: %d, sta: %d\n",
|
||||
arg.mac_addr, peer->link_id, link_id);
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
sta = ieee80211_find_sta_by_ifaddr(ath12k_ar_to_hw(ar),
|
||||
arg.mac_addr, NULL);
|
||||
}
|
||||
if (!sta) {
|
||||
ath12k_warn(ab, "Spurious quick kickout for %sSTA %pM\n",
|
||||
peer->mlo ? "MLO " : "", arg.mac_addr);
|
||||
goto exit;
|
||||
}
|
||||
ahsta = arsta->ahsta;
|
||||
sta = ath12k_ahsta_to_sta(ahsta);
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_WMI,
|
||||
"peer sta kickout event %pM reason: %d rssi: %d\n",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <net/mac80211.h>
|
||||
#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)
|
||||
|
|
@ -6323,10 +6322,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);
|
||||
|
|
|
|||
|
|
@ -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 <linux/delay.h>
|
||||
|
|
@ -919,6 +919,7 @@ cleanup:
|
|||
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 @@ exit:
|
|||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ath12k_wow_op_resume);
|
||||
|
||||
int ath12k_wow_init(struct ath12k *ar)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue