* [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization
@ 2025-08-28 17:35 Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 01/20] wifi: ath12k: Move hal_tx and hal_rx to wifi7 directory Ripan Deuri
` (22 more replies)
0 siblings, 23 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
This patch series continues the modularization work described in the
https://lore.kernel.org/linux-wireless/20250812-ath12k-mod-v1-0-8c9b0eb9335d@quicinc.com
("wifi: ath12k: Ath12k modularization changes") series, which established
the foundation for the Next Generation (NG) ath12k driver framework.
That series introduced the foundational split of the original ath12k.ko
into two distinct modules: a common module (ath12k.ko) and an architecture-
specific module (ath12k_wifi7.ko) for Wi-Fi 7 devices as depicted below.
+-----------------+
| |
| ath12k.ko |
| (common) |
+---------------+ | |
| | +-----------------+
| ath12k.ko | ===========>
| | +------------------+
+---------------+ | |
| ath12k_wifi7.ko |
| (wifi7 family) |
| |
+------------------+
Building on that framework, this series focuses on modularizing the Data Path
(DP) of the ath12k driver, allowing the common DP to be reused across different
hardware architectures.
The patches included here support the NG framework objective by reorganizing
DP-specific files and the directory structure as outlined below.
Existing file org New file org
----------------- ------------
├── dp.c ├── dp.c
├── dp.h ├── dp.h
├── dp_rx.c ├── dp_htt.c
├── dp_rx.h ├── dp_htt.h
├── dp_tx.c ├── dp_rx.c
├── dp_tx.h ├── dp_rx.h
├── hal.c ├── dp_tx.c
├── hal_desc.h ├── dp_tx.h
├── hal.h ├── hal.c
├── hal_rx.c ├── hal.h
├── hal_rx.h ├── wifi7
├── hal_tx.c │ ├── dp.c
├── hal_tx.h │ ├── dp_rx.c
│ ├── dp_rx.h
│ ├── dp_tx.c
│ ├── dp_tx.h
│ ├── hal_desc.h
│ ├── hal_qcn9274.c
│ ├── hal_qcn9274.h
│ ├── hal_rx.c
│ ├── hal_rx.h
│ ├── hal_tx.c
│ ├── hal_tx.h
│ ├── hal_wcn7850.c
│ ├── hal_wcn7850.h
│ ├── rx_desc.h
Note: While common files are not intended to include architecture-specific
headers, a few Wi-Fi 7 headers are temporarily included in common files
across patches to simplify patch splitting. This will be resolved in a
later series.
---
Harsh Kumar Bijlani (4):
wifi: ath12k: Move HTT code in dp.h to newly introduced files
wifi: ath12k: Move HTT Rx specific code to newly introduced files
wifi: ath12k: Move HTT Tx specific code to newly introduced files
wifi: ath12k: Move HTT specific code from dp.c to newly introduced
files
Pavankumar Nandeshwar (16):
wifi: ath12k: Move hal_tx and hal_rx to wifi7 directory
wifi: ath12k: Move hal_tx.h file to wifi7 directory
wifi: ath12k: Move hal_rx.h file to wifi7 directory
wifi: ath12k: Move HAL Rx wrapper APIs to dp_rx.h
wifi: ath12k: Move Rx error related functions to wifi7 directory
wifi: ath12k: Move hal_desc.h file to wifi7 directory
wifi: ath12k: Move rx_desc.h file to wifi7 directory
wifi: ath12k: Move rxdma ring config functions to wifi7 directory
wifi: ath12k: Move rx error and defrag functions to wifi7 directory
wifi: ath12k: Move regular msdu processing functions to wifi7
directory
wifi: ath12k: Move srng processing to wifi7 directory
wifi: ath12k: Separate arch specific part of RX APIs
wifi: ath12k: Move arch specific REO functions to wifi7 directory
wifi: ath12k: Move arch specific rx tid and related functions to wifi7
directory
wifi: ath12k: Move arch specific tx APIs to wifi7 directory
wifi: ath12k: Move ath12k_dp_tx and related APIs to wifi7 directory
drivers/net/wireless/ath/ath12k/Makefile | 9 +-
drivers/net/wireless/ath/ath12k/ahb.c | 3 +-
drivers/net/wireless/ath/ath12k/core.h | 4 +-
.../wireless/ath/ath12k/debugfs_htt_stats.h | 4 +-
drivers/net/wireless/ath/ath12k/dp.c | 159 +-
drivers/net/wireless/ath/ath12k/dp.h | 1518 +-------
drivers/net/wireless/ath/ath12k/dp_htt.c | 1354 ++++++++
drivers/net/wireless/ath/ath12k/dp_htt.h | 1546 +++++++++
drivers/net/wireless/ath/ath12k/dp_mon.c | 4 +-
drivers/net/wireless/ath/ath12k/dp_rx.c | 3056 +----------------
drivers/net/wireless/ath/ath12k/dp_rx.h | 297 +-
drivers/net/wireless/ath/ath12k/dp_tx.c | 1609 +--------
drivers/net/wireless/ath/ath12k/dp_tx.h | 41 +-
drivers/net/wireless/ath/ath12k/hal.c | 8 +-
drivers/net/wireless/ath/ath12k/hal.h | 501 ++-
drivers/net/wireless/ath/ath12k/mac.c | 3 +-
drivers/net/wireless/ath/ath12k/pci.c | 3 +-
drivers/net/wireless/ath/ath12k/wifi7/dp.c | 137 +
drivers/net/wireless/ath/ath12k/wifi7/dp.h | 15 +
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 2043 +++++++++++
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 47 +
drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 908 +++++
drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h | 14 +
.../ath/ath12k/{ => wifi7}/hal_desc.h | 149 +-
.../wireless/ath/ath12k/{ => wifi7}/hal_rx.c | 8 +-
.../wireless/ath/ath12k/{ => wifi7}/hal_rx.h | 299 +-
.../ath12k/{rx_desc.h => wifi7/hal_rx_desc.h} | 48 +-
.../wireless/ath/ath12k/{ => wifi7}/hal_tx.c | 6 +-
.../wireless/ath/ath12k/{ => wifi7}/hal_tx.h | 11 +-
drivers/net/wireless/ath/ath12k/wifi7/hw.c | 4 +-
30 files changed, 6993 insertions(+), 6815 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath12k/dp_htt.c
create mode 100644 drivers/net/wireless/ath/ath12k/dp_htt.h
create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp.c
create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp.h
create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h
rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_desc.h (95%)
rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_rx.c (99%)
rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_rx.h (83%)
rename drivers/net/wireless/ath/ath12k/{rx_desc.h => wifi7/hal_rx_desc.h} (97%)
rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_tx.c (97%)
rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_tx.h (96%)
base-commit: 0e487f03c6e5d8dd5b076b8b061e50e736ab2196
--
2.34.1
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 01/20] wifi: ath12k: Move hal_tx and hal_rx to wifi7 directory
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 02/20] wifi: ath12k: Move hal_tx.h file " Ripan Deuri
` (21 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Move architecture-specific files hal_rx.c and hal_tx.c into the wifi7
directory as part of a broader effort to separate common and hardware
-specific code into distinct modules. This modularization enables reuse
of the common driver components across multiple hardware architectures.
The relocated files remain part of ath12k.ko temporarily, until the
corresponding infra for movement to the ath12k_wifi7.ko arrives in
upcoming patches.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/Makefile | 5 +++--
.../net/wireless/ath/ath12k/{ => wifi7}/hal_rx.c | 14 +++++++-------
.../net/wireless/ath/ath12k/{ => wifi7}/hal_tx.c | 10 +++++-----
3 files changed, 15 insertions(+), 14 deletions(-)
rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_rx.c (99%)
rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_tx.c (96%)
diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile
index 8dd77729f52f..b34cf83a24eb 100644
--- a/drivers/net/wireless/ath/ath12k/Makefile
+++ b/drivers/net/wireless/ath/ath12k/Makefile
@@ -2,8 +2,6 @@
obj-$(CONFIG_ATH12K) += ath12k.o
ath12k-y += core.o \
hal.o \
- hal_tx.o \
- hal_rx.o \
wmi.o \
mac.o \
reg.o \
@@ -24,6 +22,9 @@ ath12k-y += core.o \
ath12k-$(CONFIG_ATH12K_AHB) += ahb.o
+ath12k-y += wifi7/hal_tx.o \
+ wifi7/hal_rx.o \
+
obj-$(CONFIG_ATH12K) += wifi7/
ath12k-$(CONFIG_ATH12K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o
diff --git a/drivers/net/wireless/ath/ath12k/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
similarity index 99%
rename from drivers/net/wireless/ath/ath12k/hal_rx.c
rename to drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
index 48aa48c48606..a25b21740e08 100644
--- a/drivers/net/wireless/ath/ath12k/hal_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
@@ -1,15 +1,15 @@
// 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 "debug.h"
-#include "hal.h"
-#include "hal_tx.h"
-#include "hal_rx.h"
-#include "hal_desc.h"
-#include "hif.h"
+#include "../debug.h"
+#include "../hal.h"
+#include "../hif.h"
+#include "../hal_tx.h"
+#include "../hal_rx.h"
+#include "../hal_desc.h"
static void ath12k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr,
u8 owner, u8 buffer_type, u32 magic)
diff --git a/drivers/net/wireless/ath/ath12k/hal_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c
similarity index 96%
rename from drivers/net/wireless/ath/ath12k/hal_tx.c
rename to drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c
index 869e07e406fe..f58da63a1b02 100644
--- a/drivers/net/wireless/ath/ath12k/hal_tx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
-#include "hal_desc.h"
-#include "hal.h"
-#include "hal_tx.h"
-#include "hif.h"
+#include "../hal_desc.h"
+#include "../hal.h"
+#include "../hal_tx.h"
+#include "../hif.h"
#define DSCP_TID_MAP_TBL_ENTRY_SIZE 64
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 02/20] wifi: ath12k: Move hal_tx.h file to wifi7 directory
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 01/20] wifi: ath12k: Move hal_tx and hal_rx to wifi7 directory Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 03/20] wifi: ath12k: Move hal_rx.h " Ripan Deuri
` (20 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Move wifi7 architecture specific file hal_tx.h to wifi7 directory, and move
the common part from it to hal.h file which is in the common directory.
It is as part of a broader effort to separate common and hardware-specific
code into distinct modules. This modularization enables reuse of the common
driver components across multiple hardware architectures.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/dp.c | 4 ++--
drivers/net/wireless/ath/ath12k/dp_tx.h | 4 ++--
drivers/net/wireless/ath/ath12k/hal.c | 4 ++--
drivers/net/wireless/ath/ath12k/hal.h | 9 ++++++++-
drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c | 2 +-
drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c | 2 +-
.../net/wireless/ath/ath12k/{ => wifi7}/hal_tx.h | 13 +++----------
7 files changed, 19 insertions(+), 19 deletions(-)
rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_tx.h (95%)
diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c
index f893fce6d9bd..a3170e02d4c7 100644
--- a/drivers/net/wireless/ath/ath12k/dp.c
+++ b/drivers/net/wireless/ath/ath12k/dp.c
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <crypto/hash.h>
#include "core.h"
#include "dp_tx.h"
-#include "hal_tx.h"
+#include "wifi7/hal_tx.h"
#include "hif.h"
#include "debug.h"
#include "dp_rx.h"
diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.h b/drivers/net/wireless/ath/ath12k/dp_tx.h
index 10acdcf1fa8f..aa2f6397bc83 100644
--- a/drivers/net/wireless/ath/ath12k/dp_tx.h
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.h
@@ -1,14 +1,14 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022, 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef ATH12K_DP_TX_H
#define ATH12K_DP_TX_H
#include "core.h"
-#include "hal_tx.h"
+#include "wifi7/hal_tx.h"
struct ath12k_dp_htt_wbm_tx_status {
bool acked;
diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c
index 022eea9515ef..dbbdb6f3f8cf 100644
--- a/drivers/net/wireless/ath/ath12k/hal.c
+++ b/drivers/net/wireless/ath/ath12k/hal.c
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/dma-mapping.h>
-#include "hal_tx.h"
+#include "wifi7/hal_tx.h"
#include "hal_rx.h"
#include "debug.h"
#include "hal_desc.h"
diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h
index c1750b5dc03c..b3aa13ad5196 100644
--- a/drivers/net/wireless/ath/ath12k/hal.h
+++ b/drivers/net/wireless/ath/ath12k/hal.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef ATH12K_HAL_H
@@ -11,6 +11,13 @@
#include "rx_desc.h"
struct ath12k_base;
+
+#define HAL_TX_ADDRX_EN 1
+#define HAL_TX_ADDRY_EN 2
+
+#define HAL_TX_ADDR_SEARCH_DEFAULT 0
+#define HAL_TX_ADDR_SEARCH_INDEX 1
+
#define HAL_CE_REMAP_REG_BASE (ab->ce_remap_base_addr)
#define HAL_LINK_DESC_SIZE (32 << 2)
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
index a25b21740e08..93727a55fc75 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
@@ -7,7 +7,7 @@
#include "../debug.h"
#include "../hal.h"
#include "../hif.h"
-#include "../hal_tx.h"
+#include "hal_tx.h"
#include "../hal_rx.h"
#include "../hal_desc.h"
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c
index f58da63a1b02..87c1312c4f46 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c
@@ -6,7 +6,7 @@
#include "../hal_desc.h"
#include "../hal.h"
-#include "../hal_tx.h"
+#include "hal_tx.h"
#include "../hif.h"
#define DSCP_TID_MAP_TBL_ENTRY_SIZE 64
diff --git a/drivers/net/wireless/ath/ath12k/hal_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h
similarity index 95%
rename from drivers/net/wireless/ath/ath12k/hal_tx.h
rename to drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h
index eb065a79f6c6..b179320569ff 100644
--- a/drivers/net/wireless/ath/ath12k/hal_tx.h
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h
@@ -1,21 +1,14 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022, 2024-2025 Qualcomm Innovation Center, Inc.
- * All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef ATH12K_HAL_TX_H
#define ATH12K_HAL_TX_H
-#include "hal_desc.h"
-#include "core.h"
-
-#define HAL_TX_ADDRX_EN 1
-#define HAL_TX_ADDRY_EN 2
-
-#define HAL_TX_ADDR_SEARCH_DEFAULT 0
-#define HAL_TX_ADDR_SEARCH_INDEX 1
+#include "../hal_desc.h"
+#include "../core.h"
/* TODO: check all these data can be managed with struct ath12k_tx_desc_info for perf */
struct hal_tx_info {
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 03/20] wifi: ath12k: Move hal_rx.h file to wifi7 directory
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 01/20] wifi: ath12k: Move hal_tx and hal_rx to wifi7 directory Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 02/20] wifi: ath12k: Move hal_tx.h file " Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 04/20] wifi: ath12k: Move HAL Rx wrapper APIs to dp_rx.h Ripan Deuri
` (19 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Move wifi7 architecture specific file hal_rx.h to wifi7 directory, and move
the common part from it to hal.h file which is in the common directory.
It is as part of a broader effort to separate common and hardware-specific
code into distinct modules. This modularization enables reuse of the common
driver components across multiple hardware architectures.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/core.h | 4 +-
drivers/net/wireless/ath/ath12k/dp.h | 4 +-
drivers/net/wireless/ath/ath12k/dp_rx.c | 4 +-
drivers/net/wireless/ath/ath12k/hal.c | 2 +-
drivers/net/wireless/ath/ath12k/hal.h | 295 +++++++++++++++++
.../net/wireless/ath/ath12k/wifi7/hal_rx.c | 2 +-
.../wireless/ath/ath12k/{ => wifi7}/hal_rx.h | 299 +-----------------
7 files changed, 304 insertions(+), 306 deletions(-)
rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_rx.h (83%)
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index 3c4a8f834b70..b68f063283fe 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef ATH12K_CORE_H
@@ -26,7 +26,7 @@
#include "ce.h"
#include "mac.h"
#include "hw.h"
-#include "hal_rx.h"
+#include "wifi7/hal_rx.h"
#include "reg.h"
#include "dbring.h"
#include "fw.h"
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index 7baa48b86f7a..faab444744b3 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -1,14 +1,14 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef ATH12K_DP_H
#define ATH12K_DP_H
#include "hal_desc.h"
-#include "hal_rx.h"
+#include "wifi7/hal_rx.h"
#include "hw.h"
#define MAX_RXDMA_PER_PDEV 2
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index 1b1ac82871f4..4f6b71a18dc4 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/ieee80211.h>
@@ -13,7 +13,7 @@
#include "hal_desc.h"
#include "hw.h"
#include "dp_rx.h"
-#include "hal_rx.h"
+#include "wifi7/hal_rx.h"
#include "dp_tx.h"
#include "peer.h"
#include "dp_mon.h"
diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c
index dbbdb6f3f8cf..f9ce60d22cc1 100644
--- a/drivers/net/wireless/ath/ath12k/hal.c
+++ b/drivers/net/wireless/ath/ath12k/hal.c
@@ -5,7 +5,7 @@
*/
#include <linux/dma-mapping.h>
#include "wifi7/hal_tx.h"
-#include "hal_rx.h"
+#include "wifi7/hal_rx.h"
#include "debug.h"
#include "hal_desc.h"
#include "hif.h"
diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h
index b3aa13ad5196..d02d27f28cc1 100644
--- a/drivers/net/wireless/ath/ath12k/hal.h
+++ b/drivers/net/wireless/ath/ath12k/hal.h
@@ -12,12 +12,22 @@
struct ath12k_base;
+#define HAL_INVALID_PEERID 0x3fff
+#define VHT_SIG_SU_NSS_MASK 0x7
+
#define HAL_TX_ADDRX_EN 1
#define HAL_TX_ADDRY_EN 2
#define HAL_TX_ADDR_SEARCH_DEFAULT 0
#define HAL_TX_ADDR_SEARCH_INDEX 1
+#define HAL_RX_MAX_MPDU 256
+#define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP (HAL_RX_MAX_MPDU >> 5)
+
+#define EHT_MAX_USER_INFO 4
+#define HAL_RX_MON_MAX_AGGR_SIZE 128
+#define HAL_MAX_UL_MU_USERS 37
+
#define HAL_CE_REMAP_REG_BASE (ab->ce_remap_base_addr)
#define HAL_LINK_DESC_SIZE (32 << 2)
@@ -532,6 +542,64 @@ enum hal_srng_ring_id {
#define HAL_SRNG_RING_ID_MAX (HAL_SRNG_RING_ID_DMAC_CMN_ID_END + \
HAL_SRNG_NUM_PMAC_RINGS)
+enum hal_rx_su_mu_coding {
+ HAL_RX_SU_MU_CODING_BCC,
+ HAL_RX_SU_MU_CODING_LDPC,
+ HAL_RX_SU_MU_CODING_MAX,
+};
+
+enum hal_rx_gi {
+ HAL_RX_GI_0_8_US,
+ HAL_RX_GI_0_4_US,
+ HAL_RX_GI_1_6_US,
+ HAL_RX_GI_3_2_US,
+ HAL_RX_GI_MAX,
+};
+
+enum hal_rx_bw {
+ HAL_RX_BW_20MHZ,
+ HAL_RX_BW_40MHZ,
+ HAL_RX_BW_80MHZ,
+ HAL_RX_BW_160MHZ,
+ HAL_RX_BW_320MHZ,
+ HAL_RX_BW_MAX,
+};
+
+enum hal_rx_preamble {
+ HAL_RX_PREAMBLE_11A,
+ HAL_RX_PREAMBLE_11B,
+ HAL_RX_PREAMBLE_11N,
+ HAL_RX_PREAMBLE_11AC,
+ HAL_RX_PREAMBLE_11AX,
+ HAL_RX_PREAMBLE_11BA,
+ HAL_RX_PREAMBLE_11BE,
+ HAL_RX_PREAMBLE_MAX,
+};
+
+enum hal_rx_reception_type {
+ HAL_RX_RECEPTION_TYPE_SU,
+ HAL_RX_RECEPTION_TYPE_MU_MIMO,
+ HAL_RX_RECEPTION_TYPE_MU_OFDMA,
+ HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO,
+ HAL_RX_RECEPTION_TYPE_MAX,
+};
+
+enum hal_rx_legacy_rate {
+ HAL_RX_LEGACY_RATE_1_MBPS,
+ HAL_RX_LEGACY_RATE_2_MBPS,
+ HAL_RX_LEGACY_RATE_5_5_MBPS,
+ HAL_RX_LEGACY_RATE_6_MBPS,
+ HAL_RX_LEGACY_RATE_9_MBPS,
+ HAL_RX_LEGACY_RATE_11_MBPS,
+ HAL_RX_LEGACY_RATE_12_MBPS,
+ HAL_RX_LEGACY_RATE_18_MBPS,
+ HAL_RX_LEGACY_RATE_24_MBPS,
+ HAL_RX_LEGACY_RATE_36_MBPS,
+ HAL_RX_LEGACY_RATE_48_MBPS,
+ HAL_RX_LEGACY_RATE_54_MBPS,
+ HAL_RX_LEGACY_RATE_INVALID,
+};
+
enum hal_ring_type {
HAL_REO_DST,
HAL_REO_EXCEPTION,
@@ -632,6 +700,158 @@ enum hal_srng_dir {
HAL_SRNG_DIR_DST
};
+struct hal_rx_user_status {
+ u32 mcs:4,
+ nss:3,
+ ofdma_info_valid:1,
+ ul_ofdma_ru_start_index:7,
+ ul_ofdma_ru_width:7,
+ ul_ofdma_ru_size:8;
+ u32 ul_ofdma_user_v0_word0;
+ u32 ul_ofdma_user_v0_word1;
+ u32 ast_index;
+ u32 tid;
+ u16 tcp_msdu_count;
+ u16 tcp_ack_msdu_count;
+ u16 udp_msdu_count;
+ u16 other_msdu_count;
+ u16 frame_control;
+ u8 frame_control_info_valid;
+ u8 data_sequence_control_info_valid;
+ u16 first_data_seq_ctrl;
+ u32 preamble_type;
+ u16 ht_flags;
+ u16 vht_flags;
+ u16 he_flags;
+ u8 rs_flags;
+ u8 ldpc;
+ u32 mpdu_cnt_fcs_ok;
+ u32 mpdu_cnt_fcs_err;
+ u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP];
+ u32 mpdu_ok_byte_count;
+ u32 mpdu_err_byte_count;
+ bool ampdu_present;
+ u16 ampdu_id;
+};
+
+struct hal_rx_u_sig_info {
+ bool ul_dl;
+ u8 bw;
+ u8 ppdu_type_comp_mode;
+ u8 eht_sig_mcs;
+ u8 num_eht_sig_sym;
+ struct ieee80211_radiotap_eht_usig usig;
+};
+
+struct hal_rx_tlv_aggr_info {
+ bool in_progress;
+ u16 cur_len;
+ u16 tlv_tag;
+ u8 buf[HAL_RX_MON_MAX_AGGR_SIZE];
+};
+
+struct hal_rx_radiotap_eht {
+ __le32 known;
+ __le32 data[9];
+};
+
+struct hal_rx_eht_info {
+ u8 num_user_info;
+ struct hal_rx_radiotap_eht eht;
+ u32 user_info[EHT_MAX_USER_INFO];
+};
+
+struct hal_rx_mon_ppdu_info {
+ u32 ppdu_id;
+ u32 last_ppdu_id;
+ u64 ppdu_ts;
+ u32 num_mpdu_fcs_ok;
+ u32 num_mpdu_fcs_err;
+ u32 preamble_type;
+ u32 mpdu_len;
+ u16 chan_num;
+ u16 freq;
+ u16 tcp_msdu_count;
+ u16 tcp_ack_msdu_count;
+ u16 udp_msdu_count;
+ u16 other_msdu_count;
+ u16 peer_id;
+ u8 rate;
+ u8 mcs;
+ u8 nss;
+ u8 bw;
+ u8 vht_flag_values1;
+ u8 vht_flag_values2;
+ u8 vht_flag_values3[4];
+ u8 vht_flag_values4;
+ u8 vht_flag_values5;
+ u16 vht_flag_values6;
+ u8 is_stbc;
+ u8 gi;
+ u8 sgi;
+ u8 ldpc;
+ u8 beamformed;
+ u8 rssi_comb;
+ u16 tid;
+ u8 fc_valid;
+ u16 ht_flags;
+ u16 vht_flags;
+ u16 he_flags;
+ u16 he_mu_flags;
+ u8 dcm;
+ u8 ru_alloc;
+ u8 reception_type;
+ u64 tsft;
+ u64 rx_duration;
+ u16 frame_control;
+ u32 ast_index;
+ u8 rs_fcs_err;
+ u8 rs_flags;
+ u8 cck_flag;
+ u8 ofdm_flag;
+ u8 ulofdma_flag;
+ u8 frame_control_info_valid;
+ u16 he_per_user_1;
+ u16 he_per_user_2;
+ u8 he_per_user_position;
+ u8 he_per_user_known;
+ u16 he_flags1;
+ u16 he_flags2;
+ u8 he_RU[4];
+ u16 he_data1;
+ u16 he_data2;
+ u16 he_data3;
+ u16 he_data4;
+ u16 he_data5;
+ u16 he_data6;
+ u32 ppdu_len;
+ u32 prev_ppdu_id;
+ u32 device_id;
+ u16 first_data_seq_ctrl;
+ u8 monitor_direct_used;
+ u8 data_sequence_control_info_valid;
+ u8 ltf_size;
+ u8 rxpcu_filter_pass;
+ s8 rssi_chain[8][8];
+ u32 num_users;
+ u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP];
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ u8 addr4[ETH_ALEN];
+ struct hal_rx_user_status userstats[HAL_MAX_UL_MU_USERS];
+ u8 userid;
+ bool first_msdu_in_mpdu;
+ bool is_ampdu;
+ u8 medium_prot_type;
+ bool ppdu_continuation;
+ bool eht_usig;
+ struct hal_rx_u_sig_info u_sig_info;
+ bool is_eht;
+ struct hal_rx_eht_info eht_info;
+ struct hal_rx_tlv_aggr_info tlv_aggr;
+};
+
/* srng flags */
#define HAL_SRNG_FLAGS_MSI_SWAP 0x00000008
#define HAL_SRNG_FLAGS_RING_PTR_SWAP 0x00000010
@@ -1060,6 +1280,81 @@ struct ath12k_hal_tcl_to_wbm_rbm_map {
u8 rbm_id;
};
+#define RU_INVALID 0
+#define RU_26 1
+#define RU_52 2
+#define RU_106 4
+#define RU_242 9
+#define RU_484 18
+#define RU_996 37
+#define RU_2X996 74
+#define RU_3X996 111
+#define RU_4X996 148
+#define RU_52_26 (RU_52 + RU_26)
+#define RU_106_26 (RU_106 + RU_26)
+#define RU_484_242 (RU_484 + RU_242)
+#define RU_996_484 (RU_996 + RU_484)
+#define RU_996_484_242 (RU_996 + RU_484_242)
+#define RU_2X996_484 (RU_2X996 + RU_484)
+#define RU_3X996_484 (RU_3X996 + RU_484)
+
+enum ath12k_eht_ru_size {
+ ATH12K_EHT_RU_26,
+ ATH12K_EHT_RU_52,
+ ATH12K_EHT_RU_106,
+ ATH12K_EHT_RU_242,
+ ATH12K_EHT_RU_484,
+ ATH12K_EHT_RU_996,
+ ATH12K_EHT_RU_996x2,
+ ATH12K_EHT_RU_996x4,
+ ATH12K_EHT_RU_52_26,
+ ATH12K_EHT_RU_106_26,
+ ATH12K_EHT_RU_484_242,
+ ATH12K_EHT_RU_996_484,
+ ATH12K_EHT_RU_996_484_242,
+ ATH12K_EHT_RU_996x2_484,
+ ATH12K_EHT_RU_996x3,
+ ATH12K_EHT_RU_996x3_484,
+
+ /* Keep last */
+ ATH12K_EHT_RU_INVALID,
+};
+
+#define HAL_RX_RU_ALLOC_TYPE_MAX ATH12K_EHT_RU_INVALID
+
+static inline
+enum nl80211_he_ru_alloc ath12k_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones)
+{
+ enum nl80211_he_ru_alloc ret;
+
+ switch (ru_tones) {
+ case RU_52:
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_52;
+ break;
+ case RU_106:
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_106;
+ break;
+ case RU_242:
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_242;
+ break;
+ case RU_484:
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_484;
+ break;
+ case RU_996:
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_996;
+ break;
+ case RU_2X996:
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_2x996;
+ break;
+ case RU_26:
+ fallthrough;
+ default:
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_26;
+ break;
+ }
+ return ret;
+}
+
struct hal_rx_ops {
bool (*rx_desc_get_first_msdu)(struct hal_rx_desc *desc);
bool (*rx_desc_get_last_msdu)(struct hal_rx_desc *desc);
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
index 93727a55fc75..ee8e7b883c89 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
@@ -8,7 +8,7 @@
#include "../hal.h"
#include "../hif.h"
#include "hal_tx.h"
-#include "../hal_rx.h"
+#include "hal_rx.h"
#include "../hal_desc.h"
static void ath12k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr,
diff --git a/drivers/net/wireless/ath/ath12k/hal_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h
similarity index 83%
rename from drivers/net/wireless/ath/ath12k/hal_rx.h
rename to drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h
index a3ab588aae19..a4ecc65b8b5d 100644
--- a/drivers/net/wireless/ath/ath12k/hal_rx.h
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef ATH12K_HAL_RX_H
@@ -19,9 +19,6 @@ struct hal_rx_wbm_rel_info {
bool hw_cc_done;
};
-#define HAL_INVALID_PEERID 0x3fff
-#define VHT_SIG_SU_NSS_MASK 0x7
-
#define HAL_RX_MPDU_INFO_PN_GET_BYTE1(__val) \
le32_get_bits((__val), GENMASK(7, 0))
@@ -39,64 +36,6 @@ struct hal_rx_mon_status_tlv_hdr {
u8 value[];
};
-enum hal_rx_su_mu_coding {
- HAL_RX_SU_MU_CODING_BCC,
- HAL_RX_SU_MU_CODING_LDPC,
- HAL_RX_SU_MU_CODING_MAX,
-};
-
-enum hal_rx_gi {
- HAL_RX_GI_0_8_US,
- HAL_RX_GI_0_4_US,
- HAL_RX_GI_1_6_US,
- HAL_RX_GI_3_2_US,
- HAL_RX_GI_MAX,
-};
-
-enum hal_rx_bw {
- HAL_RX_BW_20MHZ,
- HAL_RX_BW_40MHZ,
- HAL_RX_BW_80MHZ,
- HAL_RX_BW_160MHZ,
- HAL_RX_BW_320MHZ,
- HAL_RX_BW_MAX,
-};
-
-enum hal_rx_preamble {
- HAL_RX_PREAMBLE_11A,
- HAL_RX_PREAMBLE_11B,
- HAL_RX_PREAMBLE_11N,
- HAL_RX_PREAMBLE_11AC,
- HAL_RX_PREAMBLE_11AX,
- HAL_RX_PREAMBLE_11BA,
- HAL_RX_PREAMBLE_11BE,
- HAL_RX_PREAMBLE_MAX,
-};
-
-enum hal_rx_reception_type {
- HAL_RX_RECEPTION_TYPE_SU,
- HAL_RX_RECEPTION_TYPE_MU_MIMO,
- HAL_RX_RECEPTION_TYPE_MU_OFDMA,
- HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO,
- HAL_RX_RECEPTION_TYPE_MAX,
-};
-
-enum hal_rx_legacy_rate {
- HAL_RX_LEGACY_RATE_1_MBPS,
- HAL_RX_LEGACY_RATE_2_MBPS,
- HAL_RX_LEGACY_RATE_5_5_MBPS,
- HAL_RX_LEGACY_RATE_6_MBPS,
- HAL_RX_LEGACY_RATE_9_MBPS,
- HAL_RX_LEGACY_RATE_11_MBPS,
- HAL_RX_LEGACY_RATE_12_MBPS,
- HAL_RX_LEGACY_RATE_18_MBPS,
- HAL_RX_LEGACY_RATE_24_MBPS,
- HAL_RX_LEGACY_RATE_36_MBPS,
- HAL_RX_LEGACY_RATE_48_MBPS,
- HAL_RX_LEGACY_RATE_54_MBPS,
- HAL_RX_LEGACY_RATE_INVALID,
-};
-
#define HAL_TLV_STATUS_PPDU_NOT_DONE 0
#define HAL_TLV_STATUS_PPDU_DONE 1
#define HAL_TLV_STATUS_BUF_DONE 2
@@ -113,167 +52,6 @@ enum hal_rx_mon_status {
HAL_RX_MON_STATUS_MSDU_END,
};
-#define HAL_RX_MAX_MPDU 1024
-#define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP (HAL_RX_MAX_MPDU >> 5)
-
-struct hal_rx_user_status {
- u32 mcs:4,
- nss:3,
- ofdma_info_valid:1,
- ul_ofdma_ru_start_index:7,
- ul_ofdma_ru_width:7,
- ul_ofdma_ru_size:8;
- u32 ul_ofdma_user_v0_word0;
- u32 ul_ofdma_user_v0_word1;
- u32 ast_index;
- u32 tid;
- u16 tcp_msdu_count;
- u16 tcp_ack_msdu_count;
- u16 udp_msdu_count;
- u16 other_msdu_count;
- u16 frame_control;
- u8 frame_control_info_valid;
- u8 data_sequence_control_info_valid;
- u16 first_data_seq_ctrl;
- u32 preamble_type;
- u16 ht_flags;
- u16 vht_flags;
- u16 he_flags;
- u8 rs_flags;
- u8 ldpc;
- u32 mpdu_cnt_fcs_ok;
- u32 mpdu_cnt_fcs_err;
- u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP];
- u32 mpdu_ok_byte_count;
- u32 mpdu_err_byte_count;
- bool ampdu_present;
- u16 ampdu_id;
-};
-
-#define HAL_MAX_UL_MU_USERS 37
-
-struct hal_rx_u_sig_info {
- bool ul_dl;
- u8 bw;
- u8 ppdu_type_comp_mode;
- u8 eht_sig_mcs;
- u8 num_eht_sig_sym;
- struct ieee80211_radiotap_eht_usig usig;
-};
-
-#define HAL_RX_MON_MAX_AGGR_SIZE 128
-
-struct hal_rx_tlv_aggr_info {
- bool in_progress;
- u16 cur_len;
- u16 tlv_tag;
- u8 buf[HAL_RX_MON_MAX_AGGR_SIZE];
-};
-
-struct hal_rx_radiotap_eht {
- __le32 known;
- __le32 data[9];
-};
-
-#define EHT_MAX_USER_INFO 4
-
-struct hal_rx_eht_info {
- u8 num_user_info;
- struct hal_rx_radiotap_eht eht;
- u32 user_info[EHT_MAX_USER_INFO];
-};
-
-struct hal_rx_mon_ppdu_info {
- u32 ppdu_id;
- u32 last_ppdu_id;
- u64 ppdu_ts;
- u32 num_mpdu_fcs_ok;
- u32 num_mpdu_fcs_err;
- u32 preamble_type;
- u32 mpdu_len;
- u16 chan_num;
- u16 freq;
- u16 tcp_msdu_count;
- u16 tcp_ack_msdu_count;
- u16 udp_msdu_count;
- u16 other_msdu_count;
- u16 peer_id;
- u8 rate;
- u8 mcs;
- u8 nss;
- u8 bw;
- u8 vht_flag_values1;
- u8 vht_flag_values2;
- u8 vht_flag_values3[4];
- u8 vht_flag_values4;
- u8 vht_flag_values5;
- u16 vht_flag_values6;
- u8 is_stbc;
- u8 gi;
- u8 sgi;
- u8 ldpc;
- u8 beamformed;
- u8 rssi_comb;
- u16 tid;
- u8 fc_valid;
- u16 ht_flags;
- u16 vht_flags;
- u16 he_flags;
- u16 he_mu_flags;
- u8 dcm;
- u8 ru_alloc;
- u8 reception_type;
- u64 tsft;
- u64 rx_duration;
- u16 frame_control;
- u32 ast_index;
- u8 rs_fcs_err;
- u8 rs_flags;
- u8 cck_flag;
- u8 ofdm_flag;
- u8 ulofdma_flag;
- u8 frame_control_info_valid;
- u16 he_per_user_1;
- u16 he_per_user_2;
- u8 he_per_user_position;
- u8 he_per_user_known;
- u16 he_flags1;
- u16 he_flags2;
- u8 he_RU[4];
- u16 he_data1;
- u16 he_data2;
- u16 he_data3;
- u16 he_data4;
- u16 he_data5;
- u16 he_data6;
- u32 ppdu_len;
- u32 prev_ppdu_id;
- u32 device_id;
- u16 first_data_seq_ctrl;
- u8 monitor_direct_used;
- u8 data_sequence_control_info_valid;
- u8 ltf_size;
- u8 rxpcu_filter_pass;
- s8 rssi_chain[8][8];
- u32 num_users;
- u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP];
- u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
- u8 addr3[ETH_ALEN];
- u8 addr4[ETH_ALEN];
- struct hal_rx_user_status userstats[HAL_MAX_UL_MU_USERS];
- u8 userid;
- bool first_msdu_in_mpdu;
- bool is_ampdu;
- u8 medium_prot_type;
- bool ppdu_continuation;
- bool eht_usig;
- struct hal_rx_u_sig_info u_sig_info;
- bool is_eht;
- struct hal_rx_eht_info eht_info;
- struct hal_rx_tlv_aggr_info tlv_aggr;
-};
-
#define HAL_RX_PPDU_START_INFO0_PPDU_ID GENMASK(15, 0)
#define HAL_RX_PPDU_START_INFO1_CHAN_NUM GENMASK(15, 0)
#define HAL_RX_PPDU_START_INFO1_CHAN_FREQ GENMASK(31, 16)
@@ -1042,81 +820,6 @@ enum hal_mon_reception_type {
#define HAL_RU_PER80(ru_per80, num_80mhz, ru_idx_per80mhz) \
(HAL_RU(ru_per80, num_80mhz, ru_idx_per80mhz))
-#define RU_INVALID 0
-#define RU_26 1
-#define RU_52 2
-#define RU_106 4
-#define RU_242 9
-#define RU_484 18
-#define RU_996 37
-#define RU_2X996 74
-#define RU_3X996 111
-#define RU_4X996 148
-#define RU_52_26 (RU_52 + RU_26)
-#define RU_106_26 (RU_106 + RU_26)
-#define RU_484_242 (RU_484 + RU_242)
-#define RU_996_484 (RU_996 + RU_484)
-#define RU_996_484_242 (RU_996 + RU_484_242)
-#define RU_2X996_484 (RU_2X996 + RU_484)
-#define RU_3X996_484 (RU_3X996 + RU_484)
-
-enum ath12k_eht_ru_size {
- ATH12K_EHT_RU_26,
- ATH12K_EHT_RU_52,
- ATH12K_EHT_RU_106,
- ATH12K_EHT_RU_242,
- ATH12K_EHT_RU_484,
- ATH12K_EHT_RU_996,
- ATH12K_EHT_RU_996x2,
- ATH12K_EHT_RU_996x4,
- ATH12K_EHT_RU_52_26,
- ATH12K_EHT_RU_106_26,
- ATH12K_EHT_RU_484_242,
- ATH12K_EHT_RU_996_484,
- ATH12K_EHT_RU_996_484_242,
- ATH12K_EHT_RU_996x2_484,
- ATH12K_EHT_RU_996x3,
- ATH12K_EHT_RU_996x3_484,
-
- /* Keep last */
- ATH12K_EHT_RU_INVALID,
-};
-
-#define HAL_RX_RU_ALLOC_TYPE_MAX ATH12K_EHT_RU_INVALID
-
-static inline
-enum nl80211_he_ru_alloc ath12k_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones)
-{
- enum nl80211_he_ru_alloc ret;
-
- switch (ru_tones) {
- case RU_52:
- ret = NL80211_RATE_INFO_HE_RU_ALLOC_52;
- break;
- case RU_106:
- ret = NL80211_RATE_INFO_HE_RU_ALLOC_106;
- break;
- case RU_242:
- ret = NL80211_RATE_INFO_HE_RU_ALLOC_242;
- break;
- case RU_484:
- ret = NL80211_RATE_INFO_HE_RU_ALLOC_484;
- break;
- case RU_996:
- ret = NL80211_RATE_INFO_HE_RU_ALLOC_996;
- break;
- case RU_2X996:
- ret = NL80211_RATE_INFO_HE_RU_ALLOC_2x996;
- break;
- case RU_26:
- fallthrough;
- default:
- ret = NL80211_RATE_INFO_HE_RU_ALLOC_26;
- break;
- }
- return ret;
-}
-
void ath12k_hal_reo_status_queue_stats(struct ath12k_base *ab,
struct hal_tlv_64_hdr *tlv,
struct hal_reo_status *status);
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 04/20] wifi: ath12k: Move HAL Rx wrapper APIs to dp_rx.h
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (2 preceding siblings ...)
2025-08-28 17:35 ` [PATCH ath12k-ng 03/20] wifi: ath12k: Move hal_rx.h " Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 05/20] wifi: ath12k: Move Rx error related functions to wifi7 directory Ripan Deuri
` (18 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Move HAL Rx APIs from dp_rx.c to dp_rx.h to facilitate the separation of
common and hardware-specific code that are dependent on these HAL Rx ops
in upcoming patches.
Move the following wrapper APIs to dp_rx.h
ath12k_dp_rx_h_enctype
ath12k_dp_rx_h_mesh_ctl_present
ath12k_dp_rx_h_seq_ctrl_valid
ath12k_dp_rx_h_fc_valid
ath12k_dp_rx_h_more_frags
ath12k_dp_rx_h_frag_no
ath12k_dp_rx_h_seq_no
ath12k_dp_rx_h_msdu_done
ath12k_dp_rx_h_l4_cksum_fail
ath12k_dp_rx_h_ip_cksum_fail
ath12k_dp_rx_h_is_decrypted
ath12k_dp_rx_h_msdu_len
ath12k_dp_rx_h_sgi
ath12k_dp_rx_h_rate_mcs
ath12k_dp_rx_h_rx_bw
ath12k_dp_rx_h_freq
ath12k_dp_rx_h_pkt_type
ath12k_dp_rx_h_nss
ath12k_dp_rx_h_tid
ath12k_dp_rx_h_peer_id
ath12k_dp_rx_h_first_msdu
ath12k_dp_rx_h_last_msdu
ath12k_dp_rx_desc_end_tlv_copy
ath12k_dp_rxdesc_set_msdu_len
ath12k_dp_rx_h_is_da_mcbc
ath12k_dp_rxdesc_mac_addr2_valid
ath12k_dp_rxdesc_get_mpdu_start_addr2
ath12k_dp_rx_desc_get_dot11_hdr
ath12k_dp_rx_desc_get_crypto_header
ath12k_dp_rx_get_msdu_src_link
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/dp_rx.c | 237 -----------------------
drivers/net/wireless/ath/ath12k/dp_rx.h | 239 +++++++++++++++++++++++-
2 files changed, 238 insertions(+), 238 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index 4f6b71a18dc4..acd20417b650 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -21,243 +21,6 @@
#define ATH12K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ)
-static enum hal_encrypt_type ath12k_dp_rx_h_enctype(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- if (!ab->hal_rx_ops->rx_desc_encrypt_valid(desc))
- return HAL_ENCRYPT_TYPE_OPEN;
-
- return ab->hal_rx_ops->rx_desc_get_encrypt_type(desc);
-}
-
-u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_get_decap_type(desc);
-}
-
-static u8 ath12k_dp_rx_h_mesh_ctl_present(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_get_mesh_ctl(desc);
-}
-
-static bool ath12k_dp_rx_h_seq_ctrl_valid(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_get_mpdu_seq_ctl_vld(desc);
-}
-
-static bool ath12k_dp_rx_h_fc_valid(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_get_mpdu_fc_valid(desc);
-}
-
-static bool ath12k_dp_rx_h_more_frags(struct ath12k_base *ab,
- struct sk_buff *skb)
-{
- struct ieee80211_hdr *hdr;
-
- hdr = (struct ieee80211_hdr *)(skb->data + ab->hal.hal_desc_sz);
- return ieee80211_has_morefrags(hdr->frame_control);
-}
-
-static u16 ath12k_dp_rx_h_frag_no(struct ath12k_base *ab,
- struct sk_buff *skb)
-{
- struct ieee80211_hdr *hdr;
-
- hdr = (struct ieee80211_hdr *)(skb->data + ab->hal.hal_desc_sz);
- return le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;
-}
-
-static u16 ath12k_dp_rx_h_seq_no(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_get_mpdu_start_seq_no(desc);
-}
-
-static bool ath12k_dp_rx_h_msdu_done(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->dp_rx_h_msdu_done(desc);
-}
-
-static bool ath12k_dp_rx_h_l4_cksum_fail(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->dp_rx_h_l4_cksum_fail(desc);
-}
-
-static bool ath12k_dp_rx_h_ip_cksum_fail(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->dp_rx_h_ip_cksum_fail(desc);
-}
-
-static bool ath12k_dp_rx_h_is_decrypted(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->dp_rx_h_is_decrypted(desc);
-}
-
-u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->dp_rx_h_mpdu_err(desc);
-}
-
-static u16 ath12k_dp_rx_h_msdu_len(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_get_msdu_len(desc);
-}
-
-static u8 ath12k_dp_rx_h_sgi(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_get_msdu_sgi(desc);
-}
-
-static u8 ath12k_dp_rx_h_rate_mcs(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_get_msdu_rate_mcs(desc);
-}
-
-static u8 ath12k_dp_rx_h_rx_bw(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_get_msdu_rx_bw(desc);
-}
-
-static u32 ath12k_dp_rx_h_freq(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_get_msdu_freq(desc);
-}
-
-static u8 ath12k_dp_rx_h_pkt_type(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_get_msdu_pkt_type(desc);
-}
-
-static u8 ath12k_dp_rx_h_nss(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return hweight8(ab->hal_rx_ops->rx_desc_get_msdu_nss(desc));
-}
-
-static u8 ath12k_dp_rx_h_tid(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_get_mpdu_tid(desc);
-}
-
-static u16 ath12k_dp_rx_h_peer_id(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_get_mpdu_peer_id(desc);
-}
-
-u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_get_l3_pad_bytes(desc);
-}
-
-static bool ath12k_dp_rx_h_first_msdu(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_get_first_msdu(desc);
-}
-
-static bool ath12k_dp_rx_h_last_msdu(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_get_last_msdu(desc);
-}
-
-static void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab,
- struct hal_rx_desc *fdesc,
- struct hal_rx_desc *ldesc)
-{
- ab->hal_rx_ops->rx_desc_copy_end_tlv(fdesc, ldesc);
-}
-
-static void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab,
- struct hal_rx_desc *desc,
- u16 len)
-{
- ab->hal_rx_ops->rx_desc_set_msdu_len(desc, len);
-}
-
-u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab,
- struct hal_rx_desc *rx_desc)
-{
- return ab->hal_rx_ops->rx_desc_get_mpdu_ppdu_id(rx_desc);
-}
-
-bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab,
- struct hal_rx_desc *rx_desc)
-{
- u32 tlv_tag;
-
- tlv_tag = ab->hal_rx_ops->rx_desc_get_mpdu_start_tag(rx_desc);
-
- return tlv_tag == HAL_RX_MPDU_START;
-}
-
-static bool ath12k_dp_rx_h_is_da_mcbc(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return (ath12k_dp_rx_h_first_msdu(ab, desc) &&
- ab->hal_rx_ops->rx_desc_is_da_mcbc(desc));
-}
-
-static bool ath12k_dp_rxdesc_mac_addr2_valid(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_mac_addr2_valid(desc);
-}
-
-static u8 *ath12k_dp_rxdesc_get_mpdu_start_addr2(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_mpdu_start_addr2(desc);
-}
-
-static void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab,
- struct hal_rx_desc *desc,
- struct ieee80211_hdr *hdr)
-{
- ab->hal_rx_ops->rx_desc_get_dot11_hdr(desc, hdr);
-}
-
-static void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab,
- struct hal_rx_desc *desc,
- u8 *crypto_hdr,
- enum hal_encrypt_type enctype)
-{
- ab->hal_rx_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype);
-}
-
-static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab,
- struct hal_rx_desc *desc)
-{
- return ab->hal_rx_ops->rx_desc_get_msdu_src_link_id(desc);
-}
-
-static void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list)
-{
- struct sk_buff *skb;
-
- while ((skb = __skb_dequeue(skb_list)))
- dev_kfree_skb_any(skb);
-}
-
static size_t ath12k_dp_list_cut_nodes(struct list_head *list,
struct list_head *head,
size_t count)
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h
index e971a314bd2d..61861c63ecbf 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef ATH12K_DP_RX_H
#define ATH12K_DP_RX_H
@@ -103,6 +103,243 @@ static inline u32 ath12k_he_gi_to_nl80211_he_gi(u8 sgi)
return ret;
}
+static inline enum hal_encrypt_type ath12k_dp_rx_h_enctype(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ if (!ab->hal_rx_ops->rx_desc_encrypt_valid(desc))
+ return HAL_ENCRYPT_TYPE_OPEN;
+
+ return ab->hal_rx_ops->rx_desc_get_encrypt_type(desc);
+}
+
+static inline u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_get_decap_type(desc);
+}
+
+static inline u8 ath12k_dp_rx_h_mesh_ctl_present(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_get_mesh_ctl(desc);
+}
+
+static inline bool ath12k_dp_rx_h_seq_ctrl_valid(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_get_mpdu_seq_ctl_vld(desc);
+}
+
+static inline bool ath12k_dp_rx_h_fc_valid(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_get_mpdu_fc_valid(desc);
+}
+
+static inline bool ath12k_dp_rx_h_more_frags(struct ath12k_base *ab,
+ struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr;
+
+ hdr = (struct ieee80211_hdr *)(skb->data + ab->hal.hal_desc_sz);
+ return ieee80211_has_morefrags(hdr->frame_control);
+}
+
+static inline u16 ath12k_dp_rx_h_frag_no(struct ath12k_base *ab,
+ struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr;
+
+ hdr = (struct ieee80211_hdr *)(skb->data + ab->hal.hal_desc_sz);
+ return le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;
+}
+
+static inline u16 ath12k_dp_rx_h_seq_no(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_get_mpdu_start_seq_no(desc);
+}
+
+static inline bool ath12k_dp_rx_h_msdu_done(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->dp_rx_h_msdu_done(desc);
+}
+
+static inline bool ath12k_dp_rx_h_l4_cksum_fail(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->dp_rx_h_l4_cksum_fail(desc);
+}
+
+static inline bool ath12k_dp_rx_h_ip_cksum_fail(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->dp_rx_h_ip_cksum_fail(desc);
+}
+
+static inline bool ath12k_dp_rx_h_is_decrypted(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->dp_rx_h_is_decrypted(desc);
+}
+
+static inline u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->dp_rx_h_mpdu_err(desc);
+}
+
+static inline u16 ath12k_dp_rx_h_msdu_len(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_get_msdu_len(desc);
+}
+
+static inline u8 ath12k_dp_rx_h_sgi(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_get_msdu_sgi(desc);
+}
+
+static inline u8 ath12k_dp_rx_h_rate_mcs(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_get_msdu_rate_mcs(desc);
+}
+
+static inline u8 ath12k_dp_rx_h_rx_bw(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_get_msdu_rx_bw(desc);
+}
+
+static inline u32 ath12k_dp_rx_h_freq(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_get_msdu_freq(desc);
+}
+
+static inline u8 ath12k_dp_rx_h_pkt_type(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_get_msdu_pkt_type(desc);
+}
+
+static inline u8 ath12k_dp_rx_h_nss(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return hweight8(ab->hal_rx_ops->rx_desc_get_msdu_nss(desc));
+}
+
+static inline u8 ath12k_dp_rx_h_tid(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_get_mpdu_tid(desc);
+}
+
+static inline u16 ath12k_dp_rx_h_peer_id(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_get_mpdu_peer_id(desc);
+}
+
+static inline u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_get_l3_pad_bytes(desc);
+}
+
+static inline bool ath12k_dp_rx_h_first_msdu(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_get_first_msdu(desc);
+}
+
+static inline bool ath12k_dp_rx_h_last_msdu(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_get_last_msdu(desc);
+}
+
+static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_base *ab,
+ struct hal_rx_desc *fdesc,
+ struct hal_rx_desc *ldesc)
+{
+ ab->hal_rx_ops->rx_desc_copy_end_tlv(fdesc, ldesc);
+}
+
+static inline void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab,
+ struct hal_rx_desc *desc,
+ u16 len)
+{
+ ab->hal_rx_ops->rx_desc_set_msdu_len(desc, len);
+}
+
+static inline u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab,
+ struct hal_rx_desc *rx_desc)
+{
+ return ab->hal_rx_ops->rx_desc_get_mpdu_ppdu_id(rx_desc);
+}
+
+static inline bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab,
+ struct hal_rx_desc *rx_desc)
+{
+ u32 tlv_tag;
+
+ tlv_tag = ab->hal_rx_ops->rx_desc_get_mpdu_start_tag(rx_desc);
+
+ return tlv_tag == HAL_RX_MPDU_START;
+}
+
+static inline bool ath12k_dp_rx_h_is_da_mcbc(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return (ath12k_dp_rx_h_first_msdu(ab, desc) &&
+ ab->hal_rx_ops->rx_desc_is_da_mcbc(desc));
+}
+
+static inline bool ath12k_dp_rxdesc_mac_addr2_valid(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_mac_addr2_valid(desc);
+}
+
+static inline u8 *ath12k_dp_rxdesc_get_mpdu_start_addr2(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_mpdu_start_addr2(desc);
+}
+
+static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_base *ab,
+ struct hal_rx_desc *desc,
+ struct ieee80211_hdr *hdr)
+{
+ ab->hal_rx_ops->rx_desc_get_dot11_hdr(desc, hdr);
+}
+
+static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_base *ab,
+ struct hal_rx_desc *desc,
+ u8 *crypto_hdr,
+ enum hal_encrypt_type enctype)
+{
+ ab->hal_rx_ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype);
+}
+
+static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_base *ab,
+ struct hal_rx_desc *desc)
+{
+ return ab->hal_rx_ops->rx_desc_get_msdu_src_link_id(desc);
+}
+
+static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list)
+{
+ struct sk_buff *skb;
+
+ while ((skb = __skb_dequeue(skb_list)))
+ dev_kfree_skb_any(skb);
+}
+
int ath12k_dp_rx_ampdu_start(struct ath12k *ar,
struct ieee80211_ampdu_params *params,
u8 link_id);
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 05/20] wifi: ath12k: Move Rx error related functions to wifi7 directory
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (3 preceding siblings ...)
2025-08-28 17:35 ` [PATCH ath12k-ng 04/20] wifi: ath12k: Move HAL Rx wrapper APIs to dp_rx.h Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 06/20] wifi: ath12k: Move hal_desc.h file " Ripan Deuri
` (17 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Move wifi7 architecture specific Rx error functions from dp_rx.c to
wifi7 directory.
The new wifi7-specific dp_rx.c file will continue to be part of ath12k.ko
temporarily until the corresponding infra for movement to the
ath12k_wifi7.ko arrives in upcoming patches.
Move following architecture specific APIs to wifi7 directory:
ath12k_dp_rx_h_tkip_mic_err
ath12k_dp_rx_h_rxdma_err
ath12k_dp_rx_h_reo_err
ath12k_dp_rx_wbm_err
ath12k_dp_rx_process_wbm_err
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/Makefile | 1 +
drivers/net/wireless/ath/ath12k/dp.c | 2 +-
drivers/net/wireless/ath/ath12k/dp_mon.c | 4 +-
drivers/net/wireless/ath/ath12k/dp_rx.c | 370 +-----------------
drivers/net/wireless/ath/ath12k/dp_rx.h | 18 +-
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 350 +++++++++++++++++
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 14 +
7 files changed, 397 insertions(+), 362 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile
index b34cf83a24eb..d7628bb7af02 100644
--- a/drivers/net/wireless/ath/ath12k/Makefile
+++ b/drivers/net/wireless/ath/ath12k/Makefile
@@ -24,6 +24,7 @@ ath12k-$(CONFIG_ATH12K_AHB) += ahb.o
ath12k-y += wifi7/hal_tx.o \
wifi7/hal_rx.o \
+ wifi7/dp_rx.o
obj-$(CONFIG_ATH12K) += wifi7/
diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c
index a3170e02d4c7..1b4fab3073b0 100644
--- a/drivers/net/wireless/ath/ath12k/dp.c
+++ b/drivers/net/wireless/ath/ath12k/dp.c
@@ -10,7 +10,7 @@
#include "wifi7/hal_tx.h"
#include "hif.h"
#include "debug.h"
-#include "dp_rx.h"
+#include "wifi7/dp_rx.h"
#include "peer.h"
#include "dp_mon.h"
diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c
index 8189e52ed007..b0a0e2a97e8f 100644
--- a/drivers/net/wireless/ath/ath12k/dp_mon.c
+++ b/drivers/net/wireless/ath/ath12k/dp_mon.c
@@ -1,12 +1,12 @@
// 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.
*/
#include "dp_mon.h"
#include "debug.h"
-#include "dp_rx.h"
+#include "wifi7/dp_rx.h"
#include "dp_tx.h"
#include "peer.h"
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index acd20417b650..453310080182 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -2033,11 +2033,11 @@ static void ath12k_dp_rx_h_undecap_eth(struct ath12k *ar,
ether_addr_copy(ieee80211_get_SA(hdr), sa);
}
-static void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu,
- struct hal_rx_desc *rx_desc,
- enum hal_encrypt_type enctype,
- struct ieee80211_rx_status *status,
- bool decrypted)
+void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu,
+ struct hal_rx_desc *rx_desc,
+ enum hal_encrypt_type enctype,
+ struct ieee80211_rx_status *status,
+ bool decrypted)
{
struct ath12k_base *ab = ar->ab;
u8 decap;
@@ -2323,9 +2323,9 @@ void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info)
ath12k_dp_rx_h_rate(ar, rx_info);
}
-static void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi,
- struct sk_buff *msdu,
- struct ath12k_dp_rx_info *rx_info)
+void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi,
+ struct sk_buff *msdu,
+ struct ath12k_dp_rx_info *rx_info)
{
struct ath12k_base *ab = ar->ab;
struct ieee80211_rx_status *rx_status;
@@ -2395,9 +2395,9 @@ static void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *nap
ieee80211_rx_napi(ath12k_ar_to_hw(ar), pubsta, msdu, napi);
}
-static bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab,
- struct hal_rx_desc *rx_desc,
- struct sk_buff *msdu)
+bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab,
+ struct hal_rx_desc *rx_desc,
+ struct sk_buff *msdu)
{
struct ieee80211_hdr *hdr;
u8 decap_type;
@@ -3584,9 +3584,9 @@ static void ath12k_dp_rx_null_q_desc_sg_drop(struct ath12k *ar,
}
}
-static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu,
- struct ath12k_dp_rx_info *rx_info,
- struct sk_buff_head *msdu_list)
+int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu,
+ struct ath12k_dp_rx_info *rx_info,
+ struct sk_buff_head *msdu_list)
{
struct ath12k_base *ab = ar->ab;
u16 msdu_len;
@@ -3654,348 +3654,6 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu,
return 0;
}
-static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu,
- struct ath12k_dp_rx_info *rx_info,
- struct sk_buff_head *msdu_list)
-{
- struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
- bool drop = false;
-
- ar->ab->device_stats.reo_error[rxcb->err_code]++;
-
- switch (rxcb->err_code) {
- case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO:
- if (ath12k_dp_rx_h_null_q_desc(ar, msdu, rx_info, msdu_list))
- drop = true;
- break;
- case HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED:
- /* TODO: Do not drop PN failed packets in the driver;
- * instead, it is good to drop such packets in mac80211
- * after incrementing the replay counters.
- */
- fallthrough;
- default:
- /* TODO: Review other errors and process them to mac80211
- * as appropriate.
- */
- drop = true;
- break;
- }
-
- return drop;
-}
-
-static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu,
- struct ath12k_dp_rx_info *rx_info)
-{
- struct ath12k_base *ab = ar->ab;
- u16 msdu_len;
- struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data;
- u8 l3pad_bytes;
- struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
- u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz;
-
- rxcb->is_first_msdu = ath12k_dp_rx_h_first_msdu(ab, desc);
- rxcb->is_last_msdu = ath12k_dp_rx_h_last_msdu(ab, desc);
-
- l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc);
- msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc);
-
- if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) {
- ath12k_dbg(ab, ATH12K_DBG_DATA,
- "invalid msdu len in tkip mic err %u\n", msdu_len);
- ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", desc,
- sizeof(*desc));
- return true;
- }
-
- skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len);
- skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes);
-
- if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu)))
- return true;
-
- ath12k_dp_rx_h_ppdu(ar, rx_info);
-
- rx_info->rx_status->flag |= (RX_FLAG_MMIC_STRIPPED | RX_FLAG_MMIC_ERROR |
- RX_FLAG_DECRYPTED);
-
- ath12k_dp_rx_h_undecap(ar, msdu, desc,
- HAL_ENCRYPT_TYPE_TKIP_MIC, rx_info->rx_status, false);
- return false;
-}
-
-static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu,
- struct ath12k_dp_rx_info *rx_info)
-{
- struct ath12k_base *ab = ar->ab;
- struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
- struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data;
- bool drop = false;
- u32 err_bitmap;
-
- ar->ab->device_stats.rxdma_error[rxcb->err_code]++;
-
- switch (rxcb->err_code) {
- case HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR:
- case HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR:
- err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc);
- if (err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) {
- ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info);
- drop = ath12k_dp_rx_h_tkip_mic_err(ar, msdu, rx_info);
- break;
- }
- fallthrough;
- default:
- /* TODO: Review other rxdma error code to check if anything is
- * worth reporting to mac80211
- */
- drop = true;
- break;
- }
-
- return drop;
-}
-
-static void ath12k_dp_rx_wbm_err(struct ath12k *ar,
- struct napi_struct *napi,
- struct sk_buff *msdu,
- struct sk_buff_head *msdu_list)
-{
- struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
- struct ieee80211_rx_status rxs = {};
- struct ath12k_dp_rx_info rx_info;
- bool drop = true;
-
- rx_info.addr2_present = false;
- rx_info.rx_status = &rxs;
-
- switch (rxcb->err_rel_src) {
- case HAL_WBM_REL_SRC_MODULE_REO:
- drop = ath12k_dp_rx_h_reo_err(ar, msdu, &rx_info, msdu_list);
- break;
- case HAL_WBM_REL_SRC_MODULE_RXDMA:
- drop = ath12k_dp_rx_h_rxdma_err(ar, msdu, &rx_info);
- break;
- default:
- /* msdu will get freed */
- break;
- }
-
- if (drop) {
- dev_kfree_skb_any(msdu);
- return;
- }
-
- rx_info.rx_status->flag |= RX_FLAG_SKIP_MONITOR;
-
- ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info);
-}
-
-int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
- struct napi_struct *napi, int budget)
-{
- struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES];
- struct ath12k_hw_group *ag = ab->ag;
- struct ath12k *ar;
- struct ath12k_dp *dp = &ab->dp;
- struct dp_rxdma_ring *rx_ring;
- struct hal_rx_wbm_rel_info err_info;
- struct hal_srng *srng;
- struct sk_buff *msdu;
- struct sk_buff_head msdu_list, scatter_msdu_list;
- struct ath12k_skb_rxcb *rxcb;
- void *rx_desc;
- int num_buffs_reaped[ATH12K_MAX_DEVICES] = {};
- int total_num_buffs_reaped = 0;
- struct ath12k_rx_desc_info *desc_info;
- struct ath12k_device_dp_stats *device_stats = &ab->device_stats;
- struct ath12k_hw_link *hw_links = ag->hw_links;
- struct ath12k_base *partner_ab;
- u8 hw_link_id, device_id;
- int ret, pdev_id;
- struct hal_rx_desc *msdu_data;
-
- __skb_queue_head_init(&msdu_list);
- __skb_queue_head_init(&scatter_msdu_list);
-
- for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++)
- INIT_LIST_HEAD(&rx_desc_used_list[device_id]);
-
- srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id];
- spin_lock_bh(&srng->lock);
-
- ath12k_hal_srng_access_begin(ab, srng);
-
- while (budget) {
- rx_desc = ath12k_hal_srng_dst_get_next_entry(ab, srng);
- if (!rx_desc)
- break;
-
- ret = ath12k_hal_wbm_desc_parse_err(ab, rx_desc, &err_info);
- if (ret) {
- ath12k_warn(ab,
- "failed to parse rx error in wbm_rel ring desc %d\n",
- ret);
- continue;
- }
-
- desc_info = err_info.rx_desc;
-
- /* retry manual desc retrieval if hw cc is not done */
- if (!desc_info) {
- desc_info = ath12k_dp_get_rx_desc(ab, err_info.cookie);
- if (!desc_info) {
- ath12k_warn(ab, "Invalid cookie in DP WBM rx error descriptor retrieval: 0x%x\n",
- err_info.cookie);
- continue;
- }
- }
-
- if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC)
- ath12k_warn(ab, "WBM RX err, Check HW CC implementation");
-
- msdu = desc_info->skb;
- desc_info->skb = NULL;
-
- device_id = desc_info->device_id;
- partner_ab = ath12k_ag_to_ab(ag, device_id);
- if (unlikely(!partner_ab)) {
- dev_kfree_skb_any(msdu);
-
- /* In any case continuation bit is set
- * in the previous record, cleanup scatter_msdu_list
- */
- ath12k_dp_clean_up_skb_list(&scatter_msdu_list);
- continue;
- }
-
- list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]);
-
- rxcb = ATH12K_SKB_RXCB(msdu);
- dma_unmap_single(partner_ab->dev, rxcb->paddr,
- msdu->len + skb_tailroom(msdu),
- DMA_FROM_DEVICE);
-
- num_buffs_reaped[device_id]++;
- total_num_buffs_reaped++;
-
- if (!err_info.continuation)
- budget--;
-
- if (err_info.push_reason !=
- HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED) {
- dev_kfree_skb_any(msdu);
- continue;
- }
-
- msdu_data = (struct hal_rx_desc *)msdu->data;
- rxcb->err_rel_src = err_info.err_rel_src;
- rxcb->err_code = err_info.err_code;
- rxcb->is_first_msdu = err_info.first_msdu;
- rxcb->is_last_msdu = err_info.last_msdu;
- rxcb->is_continuation = err_info.continuation;
- rxcb->rx_desc = msdu_data;
-
- if (err_info.continuation) {
- __skb_queue_tail(&scatter_msdu_list, msdu);
- continue;
- }
-
- hw_link_id = ath12k_dp_rx_get_msdu_src_link(partner_ab,
- msdu_data);
- if (hw_link_id >= ATH12K_GROUP_MAX_RADIO) {
- dev_kfree_skb_any(msdu);
-
- /* In any case continuation bit is set
- * in the previous record, cleanup scatter_msdu_list
- */
- ath12k_dp_clean_up_skb_list(&scatter_msdu_list);
- continue;
- }
-
- if (!skb_queue_empty(&scatter_msdu_list)) {
- struct sk_buff *msdu;
-
- skb_queue_walk(&scatter_msdu_list, msdu) {
- rxcb = ATH12K_SKB_RXCB(msdu);
- rxcb->hw_link_id = hw_link_id;
- }
-
- skb_queue_splice_tail_init(&scatter_msdu_list,
- &msdu_list);
- }
-
- rxcb = ATH12K_SKB_RXCB(msdu);
- rxcb->hw_link_id = hw_link_id;
- __skb_queue_tail(&msdu_list, msdu);
- }
-
- /* In any case continuation bit is set in the
- * last record, cleanup scatter_msdu_list
- */
- ath12k_dp_clean_up_skb_list(&scatter_msdu_list);
-
- ath12k_hal_srng_access_end(ab, srng);
-
- spin_unlock_bh(&srng->lock);
-
- if (!total_num_buffs_reaped)
- goto done;
-
- for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) {
- if (!num_buffs_reaped[device_id])
- continue;
-
- partner_ab = ath12k_ag_to_ab(ag, device_id);
- rx_ring = &partner_ab->dp.rx_refill_buf_ring;
-
- ath12k_dp_rx_bufs_replenish(ab, rx_ring,
- &rx_desc_used_list[device_id],
- num_buffs_reaped[device_id]);
- }
-
- rcu_read_lock();
- while ((msdu = __skb_dequeue(&msdu_list))) {
- rxcb = ATH12K_SKB_RXCB(msdu);
- hw_link_id = rxcb->hw_link_id;
-
- device_id = hw_links[hw_link_id].device_id;
- partner_ab = ath12k_ag_to_ab(ag, device_id);
- if (unlikely(!partner_ab)) {
- ath12k_dbg(ab, ATH12K_DBG_DATA,
- "Unable to process WBM error msdu due to invalid hw link id %d device id %d\n",
- hw_link_id, device_id);
- dev_kfree_skb_any(msdu);
- continue;
- }
-
- pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params,
- hw_links[hw_link_id].pdev_idx);
- ar = partner_ab->pdevs[pdev_id].ar;
-
- if (!ar || !rcu_dereference(ar->ab->pdevs_active[pdev_id])) {
- dev_kfree_skb_any(msdu);
- continue;
- }
-
- if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) {
- dev_kfree_skb_any(msdu);
- continue;
- }
-
- if (rxcb->err_rel_src < HAL_WBM_REL_SRC_MODULE_MAX) {
- device_id = ar->ab->device_id;
- device_stats->rx_wbm_rel_source[rxcb->err_rel_src][device_id]++;
- }
-
- ath12k_dp_rx_wbm_err(ar, napi, msdu, &msdu_list);
- }
- rcu_read_unlock();
-done:
- return total_num_buffs_reaped;
-}
-
void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab)
{
struct ath12k_dp *dp = &ab->dp;
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h
index 61861c63ecbf..1909f9070d46 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.h
@@ -340,6 +340,20 @@ static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list)
dev_kfree_skb_any(skb);
}
+void ath12k_dp_rx_h_undecap(struct ath12k *ar, struct sk_buff *msdu,
+ struct hal_rx_desc *rx_desc,
+ enum hal_encrypt_type enctype,
+ struct ieee80211_rx_status *status,
+ bool decrypted);
+void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi,
+ struct sk_buff *msdu,
+ struct ath12k_dp_rx_info *rx_info);
+bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab,
+ struct hal_rx_desc *rx_desc,
+ struct sk_buff *msdu);
+int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu,
+ struct ath12k_dp_rx_info *rx_info,
+ struct sk_buff_head *msdu_list);
int ath12k_dp_rx_ampdu_start(struct ath12k *ar,
struct ieee80211_ampdu_params *params,
u8 link_id);
@@ -367,8 +381,6 @@ int ath12k_dp_rx_pdev_alloc(struct ath12k_base *ab, int pdev_idx);
void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int pdev_idx);
void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab);
void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab);
-int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
- struct napi_struct *napi, int budget);
int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
int budget);
int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id,
@@ -390,7 +402,6 @@ u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab,
struct hal_rx_desc *desc);
u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab,
struct hal_rx_desc *desc);
-void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info);
int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab);
int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab);
@@ -411,4 +422,5 @@ int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab,
enum hal_wbm_rel_bm_act action);
bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab,
struct hal_rx_desc *rx_desc);
+void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info);
#endif /* ATH12K_DP_RX_H */
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
new file mode 100644
index 000000000000..26539a4d4b30
--- /dev/null
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
@@ -0,0 +1,350 @@
+// SPDX-License-Identifier: BSD-3-Clause-Clear
+/*
+ * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include "dp_rx.h"
+#include "../dp_tx.h"
+
+static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu,
+ struct ath12k_dp_rx_info *rx_info)
+{
+ struct ath12k_base *ab = ar->ab;
+ u16 msdu_len;
+ struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data;
+ u8 l3pad_bytes;
+ struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
+ u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz;
+
+ rxcb->is_first_msdu = ath12k_dp_rx_h_first_msdu(ab, desc);
+ rxcb->is_last_msdu = ath12k_dp_rx_h_last_msdu(ab, desc);
+
+ l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc);
+ msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc);
+
+ if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) {
+ ath12k_dbg(ab, ATH12K_DBG_DATA,
+ "invalid msdu len in tkip mic err %u\n", msdu_len);
+ ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", desc,
+ sizeof(*desc));
+ return true;
+ }
+
+ skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len);
+ skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes);
+
+ if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu)))
+ return true;
+
+ ath12k_dp_rx_h_ppdu(ar, rx_info);
+
+ rx_info->rx_status->flag |= (RX_FLAG_MMIC_STRIPPED | RX_FLAG_MMIC_ERROR |
+ RX_FLAG_DECRYPTED);
+
+ ath12k_dp_rx_h_undecap(ar, msdu, desc,
+ HAL_ENCRYPT_TYPE_TKIP_MIC, rx_info->rx_status, false);
+ return false;
+}
+
+static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu,
+ struct ath12k_dp_rx_info *rx_info)
+{
+ struct ath12k_base *ab = ar->ab;
+ struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
+ struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data;
+ bool drop = false;
+ u32 err_bitmap;
+
+ ar->ab->device_stats.rxdma_error[rxcb->err_code]++;
+
+ switch (rxcb->err_code) {
+ case HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR:
+ case HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR:
+ err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc);
+ if (err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) {
+ ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info);
+ drop = ath12k_dp_rx_h_tkip_mic_err(ar, msdu, rx_info);
+ break;
+ }
+ fallthrough;
+ default:
+ /* TODO: Review other rxdma error code to check if anything is
+ * worth reporting to mac80211
+ */
+ drop = true;
+ break;
+ }
+
+ return drop;
+}
+
+static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu,
+ struct ath12k_dp_rx_info *rx_info,
+ struct sk_buff_head *msdu_list)
+{
+ struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
+ bool drop = false;
+
+ ar->ab->device_stats.reo_error[rxcb->err_code]++;
+
+ switch (rxcb->err_code) {
+ case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO:
+ if (ath12k_dp_rx_h_null_q_desc(ar, msdu, rx_info, msdu_list))
+ drop = true;
+ break;
+ case HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED:
+ /* TODO: Do not drop PN failed packets in the driver;
+ * instead, it is good to drop such packets in mac80211
+ * after incrementing the replay counters.
+ */
+ fallthrough;
+ default:
+ /* TODO: Review other errors and process them to mac80211
+ * as appropriate.
+ */
+ drop = true;
+ break;
+ }
+
+ return drop;
+}
+
+static void ath12k_dp_rx_wbm_err(struct ath12k *ar,
+ struct napi_struct *napi,
+ struct sk_buff *msdu,
+ struct sk_buff_head *msdu_list)
+{
+ struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
+ struct ieee80211_rx_status rxs = {};
+ struct ath12k_dp_rx_info rx_info;
+ bool drop = true;
+
+ rx_info.addr2_present = false;
+ rx_info.rx_status = &rxs;
+
+ switch (rxcb->err_rel_src) {
+ case HAL_WBM_REL_SRC_MODULE_REO:
+ drop = ath12k_dp_rx_h_reo_err(ar, msdu, &rx_info, msdu_list);
+ break;
+ case HAL_WBM_REL_SRC_MODULE_RXDMA:
+ drop = ath12k_dp_rx_h_rxdma_err(ar, msdu, &rx_info);
+ break;
+ default:
+ /* msdu will get freed */
+ break;
+ }
+
+ if (drop) {
+ dev_kfree_skb_any(msdu);
+ return;
+ }
+
+ rx_info.rx_status->flag |= RX_FLAG_SKIP_MONITOR;
+
+ ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info);
+}
+
+int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
+ struct napi_struct *napi, int budget)
+{
+ struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES];
+ struct ath12k_hw_group *ag = ab->ag;
+ struct ath12k *ar;
+ struct ath12k_dp *dp = &ab->dp;
+ struct dp_rxdma_ring *rx_ring;
+ struct hal_rx_wbm_rel_info err_info;
+ struct hal_srng *srng;
+ struct sk_buff *msdu;
+ struct sk_buff_head msdu_list, scatter_msdu_list;
+ struct ath12k_skb_rxcb *rxcb;
+ void *rx_desc;
+ int num_buffs_reaped[ATH12K_MAX_DEVICES] = {};
+ int total_num_buffs_reaped = 0;
+ struct ath12k_rx_desc_info *desc_info;
+ struct ath12k_device_dp_stats *device_stats = &ab->device_stats;
+ struct ath12k_hw_link *hw_links = ag->hw_links;
+ struct ath12k_base *partner_ab;
+ u8 hw_link_id, device_id;
+ int ret, pdev_id;
+ struct hal_rx_desc *msdu_data;
+
+ __skb_queue_head_init(&msdu_list);
+ __skb_queue_head_init(&scatter_msdu_list);
+
+ for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++)
+ INIT_LIST_HEAD(&rx_desc_used_list[device_id]);
+
+ srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id];
+ spin_lock_bh(&srng->lock);
+
+ ath12k_hal_srng_access_begin(ab, srng);
+
+ while (budget) {
+ rx_desc = ath12k_hal_srng_dst_get_next_entry(ab, srng);
+ if (!rx_desc)
+ break;
+
+ ret = ath12k_hal_wbm_desc_parse_err(ab, rx_desc, &err_info);
+ if (ret) {
+ ath12k_warn(ab,
+ "failed to parse rx error in wbm_rel ring desc %d\n",
+ ret);
+ continue;
+ }
+
+ desc_info = err_info.rx_desc;
+
+ /* retry manual desc retrieval if hw cc is not done */
+ if (!desc_info) {
+ desc_info = ath12k_dp_get_rx_desc(ab, err_info.cookie);
+ if (!desc_info) {
+ ath12k_warn(ab, "Invalid cookie in DP WBM rx error descriptor retrieval: 0x%x\n",
+ err_info.cookie);
+ continue;
+ }
+ }
+
+ if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC)
+ ath12k_warn(ab, "WBM RX err, Check HW CC implementation");
+
+ msdu = desc_info->skb;
+ desc_info->skb = NULL;
+
+ device_id = desc_info->device_id;
+ partner_ab = ath12k_ag_to_ab(ag, device_id);
+ if (unlikely(!partner_ab)) {
+ dev_kfree_skb_any(msdu);
+
+ /* In any case continuation bit is set
+ * in the previous record, cleanup scatter_msdu_list
+ */
+ ath12k_dp_clean_up_skb_list(&scatter_msdu_list);
+ continue;
+ }
+
+ list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]);
+
+ rxcb = ATH12K_SKB_RXCB(msdu);
+ dma_unmap_single(partner_ab->dev, rxcb->paddr,
+ msdu->len + skb_tailroom(msdu),
+ DMA_FROM_DEVICE);
+
+ num_buffs_reaped[device_id]++;
+ total_num_buffs_reaped++;
+
+ if (!err_info.continuation)
+ budget--;
+
+ if (err_info.push_reason !=
+ HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED) {
+ dev_kfree_skb_any(msdu);
+ continue;
+ }
+
+ msdu_data = (struct hal_rx_desc *)msdu->data;
+ rxcb->err_rel_src = err_info.err_rel_src;
+ rxcb->err_code = err_info.err_code;
+ rxcb->is_first_msdu = err_info.first_msdu;
+ rxcb->is_last_msdu = err_info.last_msdu;
+ rxcb->is_continuation = err_info.continuation;
+ rxcb->rx_desc = msdu_data;
+
+ if (err_info.continuation) {
+ __skb_queue_tail(&scatter_msdu_list, msdu);
+ continue;
+ }
+
+ hw_link_id = ath12k_dp_rx_get_msdu_src_link(partner_ab,
+ msdu_data);
+ if (hw_link_id >= ATH12K_GROUP_MAX_RADIO) {
+ dev_kfree_skb_any(msdu);
+
+ /* In any case continuation bit is set
+ * in the previous record, cleanup scatter_msdu_list
+ */
+ ath12k_dp_clean_up_skb_list(&scatter_msdu_list);
+ continue;
+ }
+
+ if (!skb_queue_empty(&scatter_msdu_list)) {
+ struct sk_buff *msdu;
+
+ skb_queue_walk(&scatter_msdu_list, msdu) {
+ rxcb = ATH12K_SKB_RXCB(msdu);
+ rxcb->hw_link_id = hw_link_id;
+ }
+
+ skb_queue_splice_tail_init(&scatter_msdu_list,
+ &msdu_list);
+ }
+
+ rxcb = ATH12K_SKB_RXCB(msdu);
+ rxcb->hw_link_id = hw_link_id;
+ __skb_queue_tail(&msdu_list, msdu);
+ }
+
+ /* In any case continuation bit is set in the
+ * last record, cleanup scatter_msdu_list
+ */
+ ath12k_dp_clean_up_skb_list(&scatter_msdu_list);
+
+ ath12k_hal_srng_access_end(ab, srng);
+
+ spin_unlock_bh(&srng->lock);
+
+ if (!total_num_buffs_reaped)
+ goto done;
+
+ for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) {
+ if (!num_buffs_reaped[device_id])
+ continue;
+
+ partner_ab = ath12k_ag_to_ab(ag, device_id);
+ rx_ring = &partner_ab->dp.rx_refill_buf_ring;
+
+ ath12k_dp_rx_bufs_replenish(ab, rx_ring,
+ &rx_desc_used_list[device_id],
+ num_buffs_reaped[device_id]);
+ }
+
+ rcu_read_lock();
+ while ((msdu = __skb_dequeue(&msdu_list))) {
+ rxcb = ATH12K_SKB_RXCB(msdu);
+ hw_link_id = rxcb->hw_link_id;
+
+ device_id = hw_links[hw_link_id].device_id;
+ partner_ab = ath12k_ag_to_ab(ag, device_id);
+ if (unlikely(!partner_ab)) {
+ ath12k_dbg(ab, ATH12K_DBG_DATA,
+ "Unable to process WBM error msdu due to invalid hw link id %d device id %d\n",
+ hw_link_id, device_id);
+ dev_kfree_skb_any(msdu);
+ continue;
+ }
+
+ pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params,
+ hw_links[hw_link_id].pdev_idx);
+ ar = partner_ab->pdevs[pdev_id].ar;
+
+ if (!ar || !rcu_dereference(ar->ab->pdevs_active[pdev_id])) {
+ dev_kfree_skb_any(msdu);
+ continue;
+ }
+
+ if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) {
+ dev_kfree_skb_any(msdu);
+ continue;
+ }
+
+ if (rxcb->err_rel_src < HAL_WBM_REL_SRC_MODULE_MAX) {
+ device_id = ar->ab->device_id;
+ device_stats->rx_wbm_rel_source[rxcb->err_rel_src][device_id]++;
+ }
+
+ ath12k_dp_rx_wbm_err(ar, napi, msdu, &msdu_list);
+ }
+ rcu_read_unlock();
+done:
+ return total_num_buffs_reaped;
+}
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
new file mode 100644
index 000000000000..a6da98962345
--- /dev/null
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: BSD-3-Clause-Clear */
+/*
+ * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+#ifndef ATH12K_DP_RX_WIFI7_H
+#define ATH12K_DP_RX_WIFI7_H
+
+#include "../core.h"
+#include "../dp_rx.h"
+
+int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
+ struct napi_struct *napi, int budget);
+#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 06/20] wifi: ath12k: Move hal_desc.h file to wifi7 directory
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (4 preceding siblings ...)
2025-08-28 17:35 ` [PATCH ath12k-ng 05/20] wifi: ath12k: Move Rx error related functions to wifi7 directory Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 07/20] wifi: ath12k: Move rx_desc.h " Ripan Deuri
` (16 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Move wifi7 architecture specific file hal_desc.h to wifi7 directory,
and move the common part from it to hal.h file which is in the
common directory.
It is as part of a broader effort to separate common and hardware-specific
code into distinct modules. This modularization enables reuse of the common
driver components across multiple hardware architectures.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/dp.h | 2 +-
drivers/net/wireless/ath/ath12k/dp_rx.c | 2 +-
drivers/net/wireless/ath/ath12k/hal.c | 2 +-
drivers/net/wireless/ath/ath12k/hal.h | 149 +++++++++++++++++-
.../ath/ath12k/{ => wifi7}/hal_desc.h | 149 +-----------------
.../net/wireless/ath/ath12k/wifi7/hal_rx.c | 2 +-
.../net/wireless/ath/ath12k/wifi7/hal_tx.c | 2 +-
.../net/wireless/ath/ath12k/wifi7/hal_tx.h | 2 +-
8 files changed, 156 insertions(+), 154 deletions(-)
rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_desc.h (95%)
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index faab444744b3..6ab74d773261 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -7,7 +7,7 @@
#ifndef ATH12K_DP_H
#define ATH12K_DP_H
-#include "hal_desc.h"
+#include "wifi7/hal_desc.h"
#include "wifi7/hal_rx.h"
#include "hw.h"
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index 453310080182..3da3ed5844c7 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -10,7 +10,7 @@
#include <crypto/hash.h>
#include "core.h"
#include "debug.h"
-#include "hal_desc.h"
+#include "wifi7/hal_desc.h"
#include "hw.h"
#include "dp_rx.h"
#include "wifi7/hal_rx.h"
diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c
index f9ce60d22cc1..144c26586b79 100644
--- a/drivers/net/wireless/ath/ath12k/hal.c
+++ b/drivers/net/wireless/ath/ath12k/hal.c
@@ -7,7 +7,7 @@
#include "wifi7/hal_tx.h"
#include "wifi7/hal_rx.h"
#include "debug.h"
-#include "hal_desc.h"
+#include "wifi7/hal_desc.h"
#include "hif.h"
static const struct hal_srng_config hw_srng_config_template[] = {
diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h
index d02d27f28cc1..ec8a078f0739 100644
--- a/drivers/net/wireless/ath/ath12k/hal.h
+++ b/drivers/net/wireless/ath/ath12k/hal.h
@@ -7,11 +7,13 @@
#ifndef ATH12K_HAL_H
#define ATH12K_HAL_H
-#include "hal_desc.h"
+#include "wifi7/hal_desc.h"
#include "rx_desc.h"
struct ath12k_base;
+#define HAL_DESC_REO_NON_QOS_TID 16
+
#define HAL_INVALID_PEERID 0x3fff
#define VHT_SIG_SU_NSS_MASK 0x7
@@ -672,6 +674,128 @@ enum hal_reo_cmd_status {
HAL_REO_CMD_DRAIN = 0xff,
};
+enum hal_tcl_encap_type {
+ HAL_TCL_ENCAP_TYPE_RAW,
+ HAL_TCL_ENCAP_TYPE_NATIVE_WIFI,
+ HAL_TCL_ENCAP_TYPE_ETHERNET,
+ HAL_TCL_ENCAP_TYPE_802_3 = 3,
+ HAL_TCL_ENCAP_TYPE_MAX
+};
+
+enum hal_tcl_desc_type {
+ HAL_TCL_DESC_TYPE_BUFFER,
+ HAL_TCL_DESC_TYPE_EXT_DESC,
+ HAL_TCL_DESC_TYPE_MAX,
+};
+
+enum hal_reo_dest_ring_buffer_type {
+ HAL_REO_DEST_RING_BUFFER_TYPE_MSDU,
+ HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC,
+};
+
+enum hal_reo_dest_ring_push_reason {
+ HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED,
+ HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION,
+};
+
+enum hal_reo_entr_rxdma_push_reason {
+ HAL_REO_ENTR_RING_RXDMA_PUSH_REASON_ERR_DETECTED,
+ HAL_REO_ENTR_RING_RXDMA_PUSH_REASON_ROUTING_INSTRUCTION,
+ HAL_REO_ENTR_RING_RXDMA_PUSH_REASON_RX_FLUSH,
+};
+
+enum hal_reo_dest_ring_error_code {
+ HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO,
+ HAL_REO_DEST_RING_ERROR_CODE_DESC_INVALID,
+ HAL_REO_DEST_RING_ERROR_CODE_AMPDU_IN_NON_BA,
+ HAL_REO_DEST_RING_ERROR_CODE_NON_BA_DUPLICATE,
+ HAL_REO_DEST_RING_ERROR_CODE_BA_DUPLICATE,
+ HAL_REO_DEST_RING_ERROR_CODE_FRAME_2K_JUMP,
+ HAL_REO_DEST_RING_ERROR_CODE_BAR_2K_JUMP,
+ HAL_REO_DEST_RING_ERROR_CODE_FRAME_OOR,
+ HAL_REO_DEST_RING_ERROR_CODE_BAR_OOR,
+ HAL_REO_DEST_RING_ERROR_CODE_NO_BA_SESSION,
+ HAL_REO_DEST_RING_ERROR_CODE_FRAME_SN_EQUALS_SSN,
+ HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED,
+ HAL_REO_DEST_RING_ERROR_CODE_2K_ERR_FLAG_SET,
+ HAL_REO_DEST_RING_ERROR_CODE_PN_ERR_FLAG_SET,
+ HAL_REO_DEST_RING_ERROR_CODE_DESC_BLOCKED,
+ HAL_REO_DEST_RING_ERROR_CODE_MAX,
+};
+
+enum hal_reo_entr_rxdma_ecode {
+ HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_FCS_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_UNECRYPTED_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LEN_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LIMIT_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_WIFI_PARSE_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_PARSE_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_SA_TIMEOUT_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_DA_TIMEOUT_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_FLOW_TIMEOUT_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_FRAG_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_MULTICAST_ECHO_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_MISMATCH_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_UNAUTH_WDS_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_GRPCAST_AMSDU_WDS_ERR,
+ HAL_REO_ENTR_RING_RXDMA_ECODE_MAX,
+};
+
+enum hal_wbm_htt_tx_comp_status {
+ HAL_WBM_REL_HTT_TX_COMP_STATUS_OK,
+ HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP,
+ HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL,
+ HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ,
+ HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT,
+ HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY,
+ HAL_WBM_REL_HTT_TX_COMP_STATUS_VDEVID_MISMATCH,
+ HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX,
+};
+
+enum hal_encrypt_type {
+ HAL_ENCRYPT_TYPE_WEP_40,
+ HAL_ENCRYPT_TYPE_WEP_104,
+ HAL_ENCRYPT_TYPE_TKIP_NO_MIC,
+ HAL_ENCRYPT_TYPE_WEP_128,
+ HAL_ENCRYPT_TYPE_TKIP_MIC,
+ HAL_ENCRYPT_TYPE_WAPI,
+ HAL_ENCRYPT_TYPE_CCMP_128,
+ HAL_ENCRYPT_TYPE_OPEN,
+ HAL_ENCRYPT_TYPE_CCMP_256,
+ HAL_ENCRYPT_TYPE_GCMP_128,
+ HAL_ENCRYPT_TYPE_AES_GCMP_256,
+ HAL_ENCRYPT_TYPE_WAPI_GCM_SM4,
+};
+
+enum hal_tx_rate_stats_bw {
+ HAL_TX_RATE_STATS_BW_20,
+ HAL_TX_RATE_STATS_BW_40,
+ HAL_TX_RATE_STATS_BW_80,
+ HAL_TX_RATE_STATS_BW_160,
+};
+
+enum hal_tx_rate_stats_pkt_type {
+ HAL_TX_RATE_STATS_PKT_TYPE_11A,
+ HAL_TX_RATE_STATS_PKT_TYPE_11B,
+ HAL_TX_RATE_STATS_PKT_TYPE_11N,
+ HAL_TX_RATE_STATS_PKT_TYPE_11AC,
+ HAL_TX_RATE_STATS_PKT_TYPE_11AX,
+ HAL_TX_RATE_STATS_PKT_TYPE_11BA,
+ HAL_TX_RATE_STATS_PKT_TYPE_11BE,
+};
+
+enum hal_tx_rate_stats_sgi {
+ HAL_TX_RATE_STATS_SGI_08US,
+ HAL_TX_RATE_STATS_SGI_04US,
+ HAL_TX_RATE_STATS_SGI_16US,
+ HAL_TX_RATE_STATS_SGI_32US,
+};
+
struct hal_wbm_idle_scatter_list {
dma_addr_t paddr;
struct hal_wbm_link_desc *vaddr;
@@ -1280,6 +1404,29 @@ struct ath12k_hal_tcl_to_wbm_rbm_map {
u8 rbm_id;
};
+enum hal_wbm_rel_bm_act {
+ HAL_WBM_REL_BM_ACT_PUT_IN_IDLE,
+ HAL_WBM_REL_BM_ACT_REL_MSDU,
+};
+
+/* hal_wbm_rel_bm_act
+ *
+ * put_in_idle_list
+ * Put the buffer or descriptor back in the idle list. In case of MSDU or
+ * MDPU link descriptor, BM does not need to check to release any
+ * individual MSDU buffers.
+ *
+ * release_msdu_list
+ * This BM action can only be used in combination with desc_type being
+ * msdu_link_descriptor. Field first_msdu_index points out which MSDU
+ * pointer in the MSDU link descriptor is the first of an MPDU that is
+ * released. BM shall release all the MSDU buffers linked to this first
+ * MSDU buffer pointer. All related MSDU buffer pointer entries shall be
+ * set to value 0, which represents the 'NULL' pointer. When all MSDU
+ * buffer pointers in the MSDU link descriptor are 'NULL', the MSDU link
+ * descriptor itself shall also be released.
+ */
+
#define RU_INVALID 0
#define RU_26 1
#define RU_52 2
diff --git a/drivers/net/wireless/ath/ath12k/hal_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h
similarity index 95%
rename from drivers/net/wireless/ath/ath12k/hal_desc.h
rename to drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h
index 0173f731bfef..0e91410bdedf 100644
--- a/drivers/net/wireless/ath/ath12k/hal_desc.h
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_desc.h
@@ -1,9 +1,9 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022, 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
-#include "core.h"
+#include "../core.h"
#ifndef ATH12K_HAL_DESC_H
#define ATH12K_HAL_DESC_H
@@ -820,35 +820,6 @@ struct rx_msdu_ext_desc {
* Set to the link ID of the PMAC that received the frame
*/
-enum hal_reo_dest_ring_buffer_type {
- HAL_REO_DEST_RING_BUFFER_TYPE_MSDU,
- HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC,
-};
-
-enum hal_reo_dest_ring_push_reason {
- HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED,
- HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION,
-};
-
-enum hal_reo_dest_ring_error_code {
- HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO,
- HAL_REO_DEST_RING_ERROR_CODE_DESC_INVALID,
- HAL_REO_DEST_RING_ERROR_CODE_AMPDU_IN_NON_BA,
- HAL_REO_DEST_RING_ERROR_CODE_NON_BA_DUPLICATE,
- HAL_REO_DEST_RING_ERROR_CODE_BA_DUPLICATE,
- HAL_REO_DEST_RING_ERROR_CODE_FRAME_2K_JUMP,
- HAL_REO_DEST_RING_ERROR_CODE_BAR_2K_JUMP,
- HAL_REO_DEST_RING_ERROR_CODE_FRAME_OOR,
- HAL_REO_DEST_RING_ERROR_CODE_BAR_OOR,
- HAL_REO_DEST_RING_ERROR_CODE_NO_BA_SESSION,
- HAL_REO_DEST_RING_ERROR_CODE_FRAME_SN_EQUALS_SSN,
- HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED,
- HAL_REO_DEST_RING_ERROR_CODE_2K_ERR_FLAG_SET,
- HAL_REO_DEST_RING_ERROR_CODE_PN_ERR_FLAG_SET,
- HAL_REO_DEST_RING_ERROR_CODE_DESC_BLOCKED,
- HAL_REO_DEST_RING_ERROR_CODE_MAX,
-};
-
#define HAL_REO_DEST_RING_INFO0_BUFFER_TYPE BIT(0)
#define HAL_REO_DEST_RING_INFO0_PUSH_REASON GENMASK(2, 1)
#define HAL_REO_DEST_RING_INFO0_ERROR_CODE GENMASK(7, 3)
@@ -986,35 +957,6 @@ struct hal_reo_to_ppe_ring {
* More Segments followed
*/
-enum hal_reo_entr_rxdma_push_reason {
- HAL_REO_ENTR_RING_RXDMA_PUSH_REASON_ERR_DETECTED,
- HAL_REO_ENTR_RING_RXDMA_PUSH_REASON_ROUTING_INSTRUCTION,
- HAL_REO_ENTR_RING_RXDMA_PUSH_REASON_RX_FLUSH,
-};
-
-enum hal_reo_entr_rxdma_ecode {
- HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_FCS_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_UNECRYPTED_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LEN_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LIMIT_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_WIFI_PARSE_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_PARSE_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_SA_TIMEOUT_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_DA_TIMEOUT_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_FLOW_TIMEOUT_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_FRAG_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_MULTICAST_ECHO_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_MISMATCH_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_UNAUTH_WDS_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_GRPCAST_AMSDU_WDS_ERR,
- HAL_REO_ENTR_RING_RXDMA_ECODE_MAX,
-};
-
enum hal_rx_reo_dest_ring {
HAL_RX_REO_DEST_RING_TCL,
HAL_RX_REO_DEST_RING_SW1,
@@ -1268,46 +1210,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;
@@ -1764,30 +1666,6 @@ struct hal_ce_srng_dst_status_desc {
#define HAL_TX_RATE_STATS_INFO0_OFDMA_TX BIT(16)
#define HAL_TX_RATE_STATS_INFO0_TONES_IN_RU GENMASK(28, 17)
-enum hal_tx_rate_stats_bw {
- HAL_TX_RATE_STATS_BW_20,
- HAL_TX_RATE_STATS_BW_40,
- HAL_TX_RATE_STATS_BW_80,
- HAL_TX_RATE_STATS_BW_160,
-};
-
-enum hal_tx_rate_stats_pkt_type {
- HAL_TX_RATE_STATS_PKT_TYPE_11A,
- HAL_TX_RATE_STATS_PKT_TYPE_11B,
- HAL_TX_RATE_STATS_PKT_TYPE_11N,
- HAL_TX_RATE_STATS_PKT_TYPE_11AC,
- HAL_TX_RATE_STATS_PKT_TYPE_11AX,
- HAL_TX_RATE_STATS_PKT_TYPE_11BA,
- HAL_TX_RATE_STATS_PKT_TYPE_11BE,
-};
-
-enum hal_tx_rate_stats_sgi {
- HAL_TX_RATE_STATS_SGI_08US,
- HAL_TX_RATE_STATS_SGI_04US,
- HAL_TX_RATE_STATS_SGI_16US,
- HAL_TX_RATE_STATS_SGI_32US,
-};
-
struct hal_tx_rate_stats {
__le32 info0;
__le32 tsf;
@@ -1843,28 +1721,6 @@ enum hal_wbm_rel_desc_type {
* treat this is the same way as a link descriptor.
*/
-enum hal_wbm_rel_bm_act {
- HAL_WBM_REL_BM_ACT_PUT_IN_IDLE,
- HAL_WBM_REL_BM_ACT_REL_MSDU,
-};
-
-/* hal_wbm_rel_bm_act
- *
- * put_in_idle_list
- * Put the buffer or descriptor back in the idle list. In case of MSDU or
- * MDPU link descriptor, BM does not need to check to release any
- * individual MSDU buffers.
- *
- * release_msdu_list
- * This BM action can only be used in combination with desc_type being
- * msdu_link_descriptor. Field first_msdu_index points out which MSDU
- * pointer in the MSDU link descriptor is the first of an MPDU that is
- * released. BM shall release all the MSDU buffers linked to this first
- * MSDU buffer pointer. All related MSDU buffer pointer entries shall be
- * set to value 0, which represents the 'NULL' pointer. When all MSDU
- * buffer pointers in the MSDU link descriptor are 'NULL', the MSDU link
- * descriptor itself shall also be released.
- */
#define HAL_WBM_COMPL_RX_INFO0_REL_SRC_MODULE GENMASK(2, 0)
#define HAL_WBM_COMPL_RX_INFO0_BM_ACTION GENMASK(5, 3)
#define HAL_WBM_COMPL_RX_INFO0_DESC_TYPE GENMASK(8, 6)
@@ -2330,7 +2186,6 @@ enum hal_desc_buf_type {
#define HAL_DESC_REO_OWNED 4
#define HAL_DESC_REO_QUEUE_DESC 8
#define HAL_DESC_REO_QUEUE_EXT_DESC 9
-#define HAL_DESC_REO_NON_QOS_TID 16
#define HAL_DESC_HDR_INFO0_OWNER GENMASK(3, 0)
#define HAL_DESC_HDR_INFO0_BUF_TYPE GENMASK(7, 4)
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
index ee8e7b883c89..801dde62e4ed 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx.c
@@ -9,7 +9,7 @@
#include "../hif.h"
#include "hal_tx.h"
#include "hal_rx.h"
-#include "../hal_desc.h"
+#include "hal_desc.h"
static void ath12k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr,
u8 owner, u8 buffer_type, u32 magic)
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c
index 87c1312c4f46..3a7d3163b1a5 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.c
@@ -4,7 +4,7 @@
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
-#include "../hal_desc.h"
+#include "hal_desc.h"
#include "../hal.h"
#include "hal_tx.h"
#include "../hif.h"
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h
index b179320569ff..412fe1ba22dc 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_tx.h
@@ -7,7 +7,7 @@
#ifndef ATH12K_HAL_TX_H
#define ATH12K_HAL_TX_H
-#include "../hal_desc.h"
+#include "hal_desc.h"
#include "../core.h"
/* TODO: check all these data can be managed with struct ath12k_tx_desc_info for perf */
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 07/20] wifi: ath12k: Move rx_desc.h file to wifi7 directory
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (5 preceding siblings ...)
2025-08-28 17:35 ` [PATCH ath12k-ng 06/20] wifi: ath12k: Move hal_desc.h file " Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 08/20] wifi: ath12k: Move rxdma ring config functions " Ripan Deuri
` (15 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Move wifi7 architecture specific file rx_desc.h to wifi7 directory
and rename it to hal_rx_desc.h to match the naming convention used,
and move the common part from it to hal.h file which is in the
common directory.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/dp_rx.h | 2 +-
drivers/net/wireless/ath/ath12k/hal.h | 48 ++++++++++++++++++-
.../ath12k/{rx_desc.h => wifi7/hal_rx_desc.h} | 48 +------------------
3 files changed, 49 insertions(+), 49 deletions(-)
rename drivers/net/wireless/ath/ath12k/{rx_desc.h => wifi7/hal_rx_desc.h} (97%)
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h
index 1909f9070d46..caff92bffb84 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.h
@@ -7,7 +7,7 @@
#define ATH12K_DP_RX_H
#include "core.h"
-#include "rx_desc.h"
+#include "wifi7/hal_rx_desc.h"
#include "debug.h"
#define DP_MAX_NWIFI_HDR_LEN 30
diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h
index ec8a078f0739..c99878262a4a 100644
--- a/drivers/net/wireless/ath/ath12k/hal.h
+++ b/drivers/net/wireless/ath/ath12k/hal.h
@@ -8,7 +8,7 @@
#define ATH12K_HAL_H
#include "wifi7/hal_desc.h"
-#include "rx_desc.h"
+#include "wifi7/hal_rx_desc.h"
struct ath12k_base;
@@ -30,6 +30,11 @@ struct ath12k_base;
#define HAL_RX_MON_MAX_AGGR_SIZE 128
#define HAL_MAX_UL_MU_USERS 37
+#define MAX_USER_POS 8
+#define MAX_MU_GROUP_ID 64
+#define MAX_MU_GROUP_SHOW 16
+#define MAX_MU_GROUP_LENGTH (6 * MAX_MU_GROUP_SHOW)
+
#define HAL_CE_REMAP_REG_BASE (ab->ce_remap_base_addr)
#define HAL_LINK_DESC_SIZE (32 << 2)
@@ -824,6 +829,47 @@ enum hal_srng_dir {
HAL_SRNG_DIR_DST
};
+enum rx_msdu_start_pkt_type {
+ RX_MSDU_START_PKT_TYPE_11A,
+ RX_MSDU_START_PKT_TYPE_11B,
+ RX_MSDU_START_PKT_TYPE_11N,
+ RX_MSDU_START_PKT_TYPE_11AC,
+ RX_MSDU_START_PKT_TYPE_11AX,
+ RX_MSDU_START_PKT_TYPE_11BA,
+ RX_MSDU_START_PKT_TYPE_11BE,
+};
+
+enum rx_msdu_start_sgi {
+ RX_MSDU_START_SGI_0_8_US,
+ RX_MSDU_START_SGI_0_4_US,
+ RX_MSDU_START_SGI_1_6_US,
+ RX_MSDU_START_SGI_3_2_US,
+};
+
+enum rx_msdu_start_recv_bw {
+ RX_MSDU_START_RECV_BW_20MHZ,
+ RX_MSDU_START_RECV_BW_40MHZ,
+ RX_MSDU_START_RECV_BW_80MHZ,
+ RX_MSDU_START_RECV_BW_160MHZ,
+};
+
+enum rx_msdu_start_reception_type {
+ RX_MSDU_START_RECEPTION_TYPE_SU,
+ RX_MSDU_START_RECEPTION_TYPE_DL_MU_MIMO,
+ RX_MSDU_START_RECEPTION_TYPE_DL_MU_OFDMA,
+ RX_MSDU_START_RECEPTION_TYPE_DL_MU_OFDMA_MIMO,
+ RX_MSDU_START_RECEPTION_TYPE_UL_MU_MIMO,
+ RX_MSDU_START_RECEPTION_TYPE_UL_MU_OFDMA,
+ RX_MSDU_START_RECEPTION_TYPE_UL_MU_OFDMA_MIMO,
+};
+
+enum rx_desc_decap_type {
+ RX_DESC_DECAP_TYPE_RAW,
+ RX_DESC_DECAP_TYPE_NATIVE_WIFI,
+ RX_DESC_DECAP_TYPE_ETHERNET2_DIX,
+ RX_DESC_DECAP_TYPE_8023,
+};
+
struct hal_rx_user_status {
u32 mcs:4,
nss:3,
diff --git a/drivers/net/wireless/ath/ath12k/rx_desc.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h
similarity index 97%
rename from drivers/net/wireless/ath/ath12k/rx_desc.h
rename to drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h
index 6c600473b402..60f165a176e0 100644
--- a/drivers/net/wireless/ath/ath12k/rx_desc.h
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_rx_desc.h
@@ -1,18 +1,11 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef ATH12K_RX_DESC_H
#define ATH12K_RX_DESC_H
-enum rx_desc_decap_type {
- RX_DESC_DECAP_TYPE_RAW,
- RX_DESC_DECAP_TYPE_NATIVE_WIFI,
- RX_DESC_DECAP_TYPE_ETHERNET2_DIX,
- RX_DESC_DECAP_TYPE_8023,
-};
-
enum rx_desc_decrypt_status_code {
RX_DESC_DECRYPT_STATUS_CODE_OK,
RX_DESC_DECRYPT_STATUS_CODE_UNPROTECTED_FRAME,
@@ -631,40 +624,6 @@ struct rx_mpdu_start_qcn9274_compact {
*
*/
-enum rx_msdu_start_pkt_type {
- RX_MSDU_START_PKT_TYPE_11A,
- RX_MSDU_START_PKT_TYPE_11B,
- RX_MSDU_START_PKT_TYPE_11N,
- RX_MSDU_START_PKT_TYPE_11AC,
- RX_MSDU_START_PKT_TYPE_11AX,
- RX_MSDU_START_PKT_TYPE_11BA,
- RX_MSDU_START_PKT_TYPE_11BE,
-};
-
-enum rx_msdu_start_sgi {
- RX_MSDU_START_SGI_0_8_US,
- RX_MSDU_START_SGI_0_4_US,
- RX_MSDU_START_SGI_1_6_US,
- RX_MSDU_START_SGI_3_2_US,
-};
-
-enum rx_msdu_start_recv_bw {
- RX_MSDU_START_RECV_BW_20MHZ,
- RX_MSDU_START_RECV_BW_40MHZ,
- RX_MSDU_START_RECV_BW_80MHZ,
- RX_MSDU_START_RECV_BW_160MHZ,
-};
-
-enum rx_msdu_start_reception_type {
- RX_MSDU_START_RECEPTION_TYPE_SU,
- RX_MSDU_START_RECEPTION_TYPE_DL_MU_MIMO,
- RX_MSDU_START_RECEPTION_TYPE_DL_MU_OFDMA,
- RX_MSDU_START_RECEPTION_TYPE_DL_MU_OFDMA_MIMO,
- RX_MSDU_START_RECEPTION_TYPE_UL_MU_MIMO,
- RX_MSDU_START_RECEPTION_TYPE_UL_MU_OFDMA,
- RX_MSDU_START_RECEPTION_TYPE_UL_MU_OFDMA_MIMO,
-};
-
#define RX_MSDU_END_64_TLV_SRC_LINK_ID GENMASK(24, 22)
#define RX_MSDU_END_INFO0_RXPCU_MPDU_FITLER GENMASK(1, 0)
@@ -1536,9 +1495,4 @@ struct hal_rx_desc {
} u;
} __packed;
-#define MAX_USER_POS 8
-#define MAX_MU_GROUP_ID 64
-#define MAX_MU_GROUP_SHOW 16
-#define MAX_MU_GROUP_LENGTH (6 * MAX_MU_GROUP_SHOW)
-
#endif /* ATH12K_RX_DESC_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 08/20] wifi: ath12k: Move rxdma ring config functions to wifi7 directory
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (6 preceding siblings ...)
2025-08-28 17:35 ` [PATCH ath12k-ng 07/20] wifi: ath12k: Move rx_desc.h " Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 09/20] wifi: ath12k: Move rx error and defrag " Ripan Deuri
` (14 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Move architecture specific RxDMA functions to wifi7 directory.
The moved APIs will be a part of dp_rx.c file inside wifi7 directory.
wifi7/dp_rx.c file will continue to be part of ath12k.ko temporarily
until the corresponding infra for movement to ath12k_wifi7.ko arrives
in upcoming patches.
Architecture specific APIs:
ath12k_dp_rxdma_ring_sel_config_qcn9274
ath12k_dp_rxdma_ring_sel_config_wcn7850
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/dp_rx.c | 85 -------------------
drivers/net/wireless/ath/ath12k/dp_rx.h | 3 -
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 85 +++++++++++++++++++
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 2 +
drivers/net/wireless/ath/ath12k/wifi7/hw.c | 4 +-
5 files changed, 89 insertions(+), 90 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index 3da3ed5844c7..4f666fd077fc 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -3765,91 +3765,6 @@ void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int mac_id)
ath12k_dp_rx_pdev_srng_free(ar);
}
-int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab)
-{
- struct ath12k_dp *dp = &ab->dp;
- struct htt_rx_ring_tlv_filter tlv_filter = {};
- u32 ring_id;
- int ret;
- u32 hal_rx_desc_sz = ab->hal.hal_desc_sz;
-
- ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id;
-
- tlv_filter.rx_filter = HTT_RX_TLV_FLAGS_RXDMA_RING;
- tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR;
- tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST |
- HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST |
- HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA;
- tlv_filter.offset_valid = true;
- tlv_filter.rx_packet_offset = hal_rx_desc_sz;
-
- tlv_filter.rx_mpdu_start_offset =
- ab->hal_rx_ops->rx_desc_get_mpdu_start_offset();
- tlv_filter.rx_msdu_end_offset =
- ab->hal_rx_ops->rx_desc_get_msdu_end_offset();
-
- if (ath12k_dp_wmask_compaction_rx_tlv_supported(ab)) {
- tlv_filter.rx_mpdu_start_wmask =
- ab->hw_params->hal_ops->rxdma_ring_wmask_rx_mpdu_start();
- tlv_filter.rx_msdu_end_wmask =
- ab->hw_params->hal_ops->rxdma_ring_wmask_rx_msdu_end();
- ath12k_dbg(ab, ATH12K_DBG_DATA,
- "Configuring compact tlv masks rx_mpdu_start_wmask 0x%x rx_msdu_end_wmask 0x%x\n",
- tlv_filter.rx_mpdu_start_wmask, tlv_filter.rx_msdu_end_wmask);
- }
-
- ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, 0,
- HAL_RXDMA_BUF,
- DP_RXDMA_REFILL_RING_SIZE,
- &tlv_filter);
-
- return ret;
-}
-EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_qcn9274);
-
-int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab)
-{
- struct ath12k_dp *dp = &ab->dp;
- struct htt_rx_ring_tlv_filter tlv_filter = {};
- u32 ring_id;
- int ret = 0;
- u32 hal_rx_desc_sz = ab->hal.hal_desc_sz;
- int i;
-
- ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id;
-
- tlv_filter.rx_filter = HTT_RX_TLV_FLAGS_RXDMA_RING;
- tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR;
- tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST |
- HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST |
- HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA;
- tlv_filter.offset_valid = true;
- tlv_filter.rx_packet_offset = hal_rx_desc_sz;
-
- tlv_filter.rx_header_offset = offsetof(struct hal_rx_desc_wcn7850, pkt_hdr_tlv);
-
- tlv_filter.rx_mpdu_start_offset =
- ab->hal_rx_ops->rx_desc_get_mpdu_start_offset();
- tlv_filter.rx_msdu_end_offset =
- ab->hal_rx_ops->rx_desc_get_msdu_end_offset();
-
- /* TODO: Selectively subscribe to required qwords within msdu_end
- * and mpdu_start and setup the mask in below msg
- * and modify the rx_desc struct
- */
-
- for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
- ring_id = dp->rx_mac_buf_ring[i].ring_id;
- ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, i,
- HAL_RXDMA_BUF,
- DP_RXDMA_REFILL_RING_SIZE,
- &tlv_filter);
- }
-
- return ret;
-}
-EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_wcn7850);
-
int ath12k_dp_rx_htt_setup(struct ath12k_base *ab)
{
struct ath12k_dp *dp = &ab->dp;
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h
index caff92bffb84..542f08efe0cd 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.h
@@ -402,9 +402,6 @@ u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab,
struct hal_rx_desc *desc);
u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab,
struct hal_rx_desc *desc);
-int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab);
-int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab);
-
int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len,
int (*iter)(struct ath12k_base *ar, u16 tag, u16 len,
const void *ptr, void *data),
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
index 26539a4d4b30..a002e3839fff 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
@@ -348,3 +348,88 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
done:
return total_num_buffs_reaped;
}
+
+int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab)
+{
+ struct ath12k_dp *dp = &ab->dp;
+ struct htt_rx_ring_tlv_filter tlv_filter = {};
+ u32 ring_id;
+ int ret;
+ u32 hal_rx_desc_sz = ab->hal.hal_desc_sz;
+
+ ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id;
+
+ tlv_filter.rx_filter = HTT_RX_TLV_FLAGS_RXDMA_RING;
+ tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR;
+ tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST |
+ HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST |
+ HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA;
+ tlv_filter.offset_valid = true;
+ tlv_filter.rx_packet_offset = hal_rx_desc_sz;
+
+ tlv_filter.rx_mpdu_start_offset =
+ ab->hal_rx_ops->rx_desc_get_mpdu_start_offset();
+ tlv_filter.rx_msdu_end_offset =
+ ab->hal_rx_ops->rx_desc_get_msdu_end_offset();
+
+ if (ath12k_dp_wmask_compaction_rx_tlv_supported(ab)) {
+ tlv_filter.rx_mpdu_start_wmask =
+ ab->hw_params->hal_ops->rxdma_ring_wmask_rx_mpdu_start();
+ tlv_filter.rx_msdu_end_wmask =
+ ab->hw_params->hal_ops->rxdma_ring_wmask_rx_msdu_end();
+ ath12k_dbg(ab, ATH12K_DBG_DATA,
+ "Configuring compact tlv masks rx_mpdu_start_wmask 0x%x rx_msdu_end_wmask 0x%x\n",
+ tlv_filter.rx_mpdu_start_wmask, tlv_filter.rx_msdu_end_wmask);
+ }
+
+ ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, 0,
+ HAL_RXDMA_BUF,
+ DP_RXDMA_REFILL_RING_SIZE,
+ &tlv_filter);
+
+ return ret;
+}
+EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_qcn9274);
+
+int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab)
+{
+ struct ath12k_dp *dp = &ab->dp;
+ struct htt_rx_ring_tlv_filter tlv_filter = {};
+ u32 ring_id;
+ int ret = 0;
+ u32 hal_rx_desc_sz = ab->hal.hal_desc_sz;
+ int i;
+
+ ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id;
+
+ tlv_filter.rx_filter = HTT_RX_TLV_FLAGS_RXDMA_RING;
+ tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR;
+ tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST |
+ HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST |
+ HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA;
+ tlv_filter.offset_valid = true;
+ tlv_filter.rx_packet_offset = hal_rx_desc_sz;
+
+ tlv_filter.rx_header_offset = offsetof(struct hal_rx_desc_wcn7850, pkt_hdr_tlv);
+
+ tlv_filter.rx_mpdu_start_offset =
+ ab->hal_rx_ops->rx_desc_get_mpdu_start_offset();
+ tlv_filter.rx_msdu_end_offset =
+ ab->hal_rx_ops->rx_desc_get_msdu_end_offset();
+
+ /* TODO: Selectively subscribe to required qwords within msdu_end
+ * and mpdu_start and setup the mask in below msg
+ * and modify the rx_desc struct
+ */
+
+ for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
+ ring_id = dp->rx_mac_buf_ring[i].ring_id;
+ ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, i,
+ HAL_RXDMA_BUF,
+ DP_RXDMA_REFILL_RING_SIZE,
+ &tlv_filter);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_wcn7850);
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
index a6da98962345..154018c221da 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
@@ -11,4 +11,6 @@
int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
struct napi_struct *napi, int budget);
+int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab);
+int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab);
#endif
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
index 82b4f5b9f570..909f7311619c 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/types.h>
@@ -16,7 +16,7 @@
#include "hw.h"
#include "../mhi.h"
#include "mhi.h"
-#include "../dp_rx.h"
+#include "dp_rx.h"
#include "../peer.h"
#include "wmi.h"
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 09/20] wifi: ath12k: Move rx error and defrag functions to wifi7 directory
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (7 preceding siblings ...)
2025-08-28 17:35 ` [PATCH ath12k-ng 08/20] wifi: ath12k: Move rxdma ring config functions " Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 10/20] wifi: ath12k: Move regular msdu processing " Ripan Deuri
` (13 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Move arch specific RX error and defrag functions to wifi7 directory.
The moved APIs will be a part of dp_rx.c file inside wifi7 directory.
wifi7/dp_rx.c file will continue to be part of ath12k.ko
temporarily until the corresponding infra for movement
to ath12k_wifi7.ko arrives in upcoming patches.
Architecture specific APIs:
ath12k_dp_rx_h_defrag_validate_incr_pn
ath12k_dp_rx_h_defrag_reo_reinject
ath12k_dp_rx_h_defrag
ath12k_dp_rx_frag_h_mpdu
ath12k_dp_process_rx_err_buf
ath12k_dp_rx_process_err
ath12k_dp_rx_null_q_desc_sg_drop
ath12k_dp_rx_h_null_q_desc
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/dp_rx.c | 711 +-----------------
drivers/net/wireless/ath/ath12k/dp_rx.h | 21 +-
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 682 +++++++++++++++++
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 2 +
4 files changed, 714 insertions(+), 702 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index 4f666fd077fc..d52fec62eed7 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -19,8 +19,6 @@
#include "dp_mon.h"
#include "debugfs_htt_stats.h"
-#define ATH12K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ)
-
static size_t ath12k_dp_list_cut_nodes(struct list_head *list,
struct list_head *head,
size_t count)
@@ -653,8 +651,8 @@ int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab,
return ret;
}
-static void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid,
- bool rel_link_desc)
+void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid,
+ bool rel_link_desc)
{
struct ath12k_buffer_addr *buf_addr_info;
struct ath12k_base *ab = rx_tid->ab;
@@ -2096,10 +2094,10 @@ ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu,
return peer;
}
-static void ath12k_dp_rx_h_mpdu(struct ath12k *ar,
- struct sk_buff *msdu,
- struct hal_rx_desc *rx_desc,
- struct ath12k_dp_rx_info *rx_info)
+void ath12k_dp_rx_h_mpdu(struct ath12k *ar,
+ struct sk_buff *msdu,
+ struct hal_rx_desc *rx_desc,
+ struct ath12k_dp_rx_info *rx_info)
{
struct ath12k_base *ab = ar->ab;
struct ath12k_skb_rxcb *rxcb;
@@ -2830,8 +2828,8 @@ static int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key,
return ret;
}
-static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer,
- struct sk_buff *msdu)
+int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer,
+ struct sk_buff *msdu)
{
struct ath12k_base *ab = ar->ab;
struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data;
@@ -2894,8 +2892,8 @@ static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer
return -EINVAL;
}
-static void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu,
- enum hal_encrypt_type enctype, u32 flags)
+void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu,
+ enum hal_encrypt_type enctype, u32 flags)
{
struct ieee80211_hdr *hdr;
size_t hdr_len;
@@ -2925,222 +2923,6 @@ static void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu,
}
}
-static int ath12k_dp_rx_h_defrag(struct ath12k *ar,
- struct ath12k_peer *peer,
- struct ath12k_dp_rx_tid *rx_tid,
- struct sk_buff **defrag_skb)
-{
- struct ath12k_base *ab = ar->ab;
- struct hal_rx_desc *rx_desc;
- struct sk_buff *skb, *first_frag, *last_frag;
- struct ieee80211_hdr *hdr;
- enum hal_encrypt_type enctype;
- bool is_decrypted = false;
- int msdu_len = 0;
- int extra_space;
- u32 flags, hal_rx_desc_sz = ar->ab->hal.hal_desc_sz;
-
- first_frag = skb_peek(&rx_tid->rx_frags);
- last_frag = skb_peek_tail(&rx_tid->rx_frags);
-
- skb_queue_walk(&rx_tid->rx_frags, skb) {
- flags = 0;
- rx_desc = (struct hal_rx_desc *)skb->data;
- hdr = (struct ieee80211_hdr *)(skb->data + hal_rx_desc_sz);
-
- enctype = ath12k_dp_rx_h_enctype(ab, rx_desc);
- if (enctype != HAL_ENCRYPT_TYPE_OPEN)
- is_decrypted = ath12k_dp_rx_h_is_decrypted(ab,
- rx_desc);
-
- if (is_decrypted) {
- if (skb != first_frag)
- flags |= RX_FLAG_IV_STRIPPED;
- if (skb != last_frag)
- flags |= RX_FLAG_ICV_STRIPPED |
- RX_FLAG_MIC_STRIPPED;
- }
-
- /* RX fragments are always raw packets */
- if (skb != last_frag)
- skb_trim(skb, skb->len - FCS_LEN);
- ath12k_dp_rx_h_undecap_frag(ar, skb, enctype, flags);
-
- if (skb != first_frag)
- skb_pull(skb, hal_rx_desc_sz +
- ieee80211_hdrlen(hdr->frame_control));
- msdu_len += skb->len;
- }
-
- extra_space = msdu_len - (DP_RX_BUFFER_SIZE + skb_tailroom(first_frag));
- if (extra_space > 0 &&
- (pskb_expand_head(first_frag, 0, extra_space, GFP_ATOMIC) < 0))
- return -ENOMEM;
-
- __skb_unlink(first_frag, &rx_tid->rx_frags);
- while ((skb = __skb_dequeue(&rx_tid->rx_frags))) {
- skb_put_data(first_frag, skb->data, skb->len);
- dev_kfree_skb_any(skb);
- }
-
- hdr = (struct ieee80211_hdr *)(first_frag->data + hal_rx_desc_sz);
- hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_MOREFRAGS);
- ATH12K_SKB_RXCB(first_frag)->is_frag = 1;
-
- if (ath12k_dp_rx_h_verify_tkip_mic(ar, peer, first_frag))
- first_frag = NULL;
-
- *defrag_skb = first_frag;
- return 0;
-}
-
-static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar,
- struct ath12k_dp_rx_tid *rx_tid,
- struct sk_buff *defrag_skb)
-{
- struct ath12k_base *ab = ar->ab;
- struct ath12k_dp *dp = &ab->dp;
- struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)defrag_skb->data;
- struct hal_reo_entrance_ring *reo_ent_ring;
- struct hal_reo_dest_ring *reo_dest_ring;
- struct dp_link_desc_bank *link_desc_banks;
- struct hal_rx_msdu_link *msdu_link;
- struct hal_rx_msdu_details *msdu0;
- struct hal_srng *srng;
- dma_addr_t link_paddr, buf_paddr;
- u32 desc_bank, msdu_info, msdu_ext_info, mpdu_info;
- u32 cookie, hal_rx_desc_sz, dest_ring_info0, queue_addr_hi;
- int ret;
- struct ath12k_rx_desc_info *desc_info;
- enum hal_rx_buf_return_buf_manager idle_link_rbm = dp->idle_link_rbm;
- u8 dst_ind;
-
- hal_rx_desc_sz = ab->hal.hal_desc_sz;
- link_desc_banks = dp->link_desc_banks;
- reo_dest_ring = rx_tid->dst_ring_desc;
-
- ath12k_hal_rx_reo_ent_paddr_get(ab, &reo_dest_ring->buf_addr_info,
- &link_paddr, &cookie);
- desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK);
-
- msdu_link = (struct hal_rx_msdu_link *)(link_desc_banks[desc_bank].vaddr +
- (link_paddr - link_desc_banks[desc_bank].paddr));
- msdu0 = &msdu_link->msdu_link[0];
- msdu_ext_info = le32_to_cpu(msdu0->rx_msdu_ext_info.info0);
- dst_ind = u32_get_bits(msdu_ext_info, RX_MSDU_EXT_DESC_INFO0_REO_DEST_IND);
-
- memset(msdu0, 0, sizeof(*msdu0));
-
- msdu_info = u32_encode_bits(1, RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU) |
- u32_encode_bits(1, RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU) |
- u32_encode_bits(0, RX_MSDU_DESC_INFO0_MSDU_CONTINUATION) |
- u32_encode_bits(defrag_skb->len - hal_rx_desc_sz,
- RX_MSDU_DESC_INFO0_MSDU_LENGTH) |
- u32_encode_bits(1, RX_MSDU_DESC_INFO0_VALID_SA) |
- u32_encode_bits(1, RX_MSDU_DESC_INFO0_VALID_DA);
- msdu0->rx_msdu_info.info0 = cpu_to_le32(msdu_info);
- msdu0->rx_msdu_ext_info.info0 = cpu_to_le32(msdu_ext_info);
-
- /* change msdu len in hal rx desc */
- ath12k_dp_rxdesc_set_msdu_len(ab, rx_desc, defrag_skb->len - hal_rx_desc_sz);
-
- buf_paddr = dma_map_single(ab->dev, defrag_skb->data,
- defrag_skb->len + skb_tailroom(defrag_skb),
- DMA_TO_DEVICE);
- if (dma_mapping_error(ab->dev, buf_paddr))
- return -ENOMEM;
-
- spin_lock_bh(&dp->rx_desc_lock);
- desc_info = list_first_entry_or_null(&dp->rx_desc_free_list,
- struct ath12k_rx_desc_info,
- list);
- if (!desc_info) {
- spin_unlock_bh(&dp->rx_desc_lock);
- ath12k_warn(ab, "failed to find rx desc for reinject\n");
- ret = -ENOMEM;
- goto err_unmap_dma;
- }
-
- desc_info->skb = defrag_skb;
- desc_info->in_use = true;
-
- list_del(&desc_info->list);
- spin_unlock_bh(&dp->rx_desc_lock);
-
- ATH12K_SKB_RXCB(defrag_skb)->paddr = buf_paddr;
-
- ath12k_hal_rx_buf_addr_info_set(&msdu0->buf_addr_info, buf_paddr,
- desc_info->cookie,
- HAL_RX_BUF_RBM_SW3_BM);
-
- /* Fill mpdu details into reo entrance ring */
- srng = &ab->hal.srng_list[dp->reo_reinject_ring.ring_id];
-
- spin_lock_bh(&srng->lock);
- ath12k_hal_srng_access_begin(ab, srng);
-
- reo_ent_ring = ath12k_hal_srng_src_get_next_entry(ab, srng);
- if (!reo_ent_ring) {
- ath12k_hal_srng_access_end(ab, srng);
- spin_unlock_bh(&srng->lock);
- ret = -ENOSPC;
- goto err_free_desc;
- }
- memset(reo_ent_ring, 0, sizeof(*reo_ent_ring));
-
- ath12k_hal_rx_buf_addr_info_set(&reo_ent_ring->buf_addr_info, link_paddr,
- cookie,
- idle_link_rbm);
-
- mpdu_info = u32_encode_bits(1, RX_MPDU_DESC_INFO0_MSDU_COUNT) |
- u32_encode_bits(0, RX_MPDU_DESC_INFO0_FRAG_FLAG) |
- u32_encode_bits(1, RX_MPDU_DESC_INFO0_RAW_MPDU) |
- u32_encode_bits(1, RX_MPDU_DESC_INFO0_VALID_PN) |
- u32_encode_bits(rx_tid->tid, RX_MPDU_DESC_INFO0_TID);
-
- reo_ent_ring->rx_mpdu_info.info0 = cpu_to_le32(mpdu_info);
- reo_ent_ring->rx_mpdu_info.peer_meta_data =
- reo_dest_ring->rx_mpdu_info.peer_meta_data;
-
- if (ab->hw_params->reoq_lut_support) {
- reo_ent_ring->queue_addr_lo = reo_dest_ring->rx_mpdu_info.peer_meta_data;
- queue_addr_hi = 0;
- } else {
- reo_ent_ring->queue_addr_lo =
- cpu_to_le32(lower_32_bits(rx_tid->qbuf.paddr_aligned));
- queue_addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned);
- }
-
- reo_ent_ring->info0 = le32_encode_bits(queue_addr_hi,
- HAL_REO_ENTR_RING_INFO0_QUEUE_ADDR_HI) |
- le32_encode_bits(dst_ind,
- HAL_REO_ENTR_RING_INFO0_DEST_IND);
-
- reo_ent_ring->info1 = le32_encode_bits(rx_tid->cur_sn,
- HAL_REO_ENTR_RING_INFO1_MPDU_SEQ_NUM);
- dest_ring_info0 = le32_get_bits(reo_dest_ring->info0,
- HAL_REO_DEST_RING_INFO0_SRC_LINK_ID);
- reo_ent_ring->info2 =
- cpu_to_le32(u32_get_bits(dest_ring_info0,
- HAL_REO_ENTR_RING_INFO2_SRC_LINK_ID));
-
- ath12k_hal_srng_access_end(ab, srng);
- spin_unlock_bh(&srng->lock);
-
- return 0;
-
-err_free_desc:
- spin_lock_bh(&dp->rx_desc_lock);
- desc_info->in_use = false;
- desc_info->skb = NULL;
- list_add_tail(&desc_info->list, &dp->rx_desc_free_list);
- spin_unlock_bh(&dp->rx_desc_lock);
-err_unmap_dma:
- dma_unmap_single(ab->dev, buf_paddr, defrag_skb->len + skb_tailroom(defrag_skb),
- DMA_TO_DEVICE);
- return ret;
-}
-
static int ath12k_dp_rx_h_cmp_frags(struct ath12k_base *ab,
struct sk_buff *a, struct sk_buff *b)
{
@@ -3152,9 +2934,9 @@ static int ath12k_dp_rx_h_cmp_frags(struct ath12k_base *ab,
return frag1 - frag2;
}
-static void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab,
- struct sk_buff_head *frag_list,
- struct sk_buff *cur_frag)
+void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab,
+ struct sk_buff_head *frag_list,
+ struct sk_buff *cur_frag)
{
struct sk_buff *skb;
int cmp;
@@ -3169,7 +2951,7 @@ static void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab,
__skb_queue_tail(frag_list, cur_frag);
}
-static u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb)
+u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr;
u64 pn = 0;
@@ -3189,471 +2971,6 @@ static u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb)
return pn;
}
-static bool
-ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, struct ath12k_dp_rx_tid *rx_tid)
-{
- struct ath12k_base *ab = ar->ab;
- enum hal_encrypt_type encrypt_type;
- struct sk_buff *first_frag, *skb;
- struct hal_rx_desc *desc;
- u64 last_pn;
- u64 cur_pn;
-
- first_frag = skb_peek(&rx_tid->rx_frags);
- desc = (struct hal_rx_desc *)first_frag->data;
-
- encrypt_type = ath12k_dp_rx_h_enctype(ab, desc);
- if (encrypt_type != HAL_ENCRYPT_TYPE_CCMP_128 &&
- encrypt_type != HAL_ENCRYPT_TYPE_CCMP_256 &&
- encrypt_type != HAL_ENCRYPT_TYPE_GCMP_128 &&
- encrypt_type != HAL_ENCRYPT_TYPE_AES_GCMP_256)
- return true;
-
- last_pn = ath12k_dp_rx_h_get_pn(ar, first_frag);
- skb_queue_walk(&rx_tid->rx_frags, skb) {
- if (skb == first_frag)
- continue;
-
- cur_pn = ath12k_dp_rx_h_get_pn(ar, skb);
- if (cur_pn != last_pn + 1)
- return false;
- last_pn = cur_pn;
- }
- return true;
-}
-
-static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar,
- struct sk_buff *msdu,
- struct hal_reo_dest_ring *ring_desc)
-{
- struct ath12k_base *ab = ar->ab;
- struct hal_rx_desc *rx_desc;
- struct ath12k_peer *peer;
- struct ath12k_dp_rx_tid *rx_tid;
- struct sk_buff *defrag_skb = NULL;
- u32 peer_id;
- u16 seqno, frag_no;
- u8 tid;
- int ret = 0;
- bool more_frags;
-
- rx_desc = (struct hal_rx_desc *)msdu->data;
- peer_id = ath12k_dp_rx_h_peer_id(ab, rx_desc);
- tid = ath12k_dp_rx_h_tid(ab, rx_desc);
- seqno = ath12k_dp_rx_h_seq_no(ab, rx_desc);
- frag_no = ath12k_dp_rx_h_frag_no(ab, msdu);
- more_frags = ath12k_dp_rx_h_more_frags(ab, msdu);
-
- if (!ath12k_dp_rx_h_seq_ctrl_valid(ab, rx_desc) ||
- !ath12k_dp_rx_h_fc_valid(ab, rx_desc) ||
- tid > IEEE80211_NUM_TIDS)
- return -EINVAL;
-
- /* received unfragmented packet in reo
- * exception ring, this shouldn't happen
- * as these packets typically come from
- * reo2sw srngs.
- */
- if (WARN_ON_ONCE(!frag_no && !more_frags))
- return -EINVAL;
-
- spin_lock_bh(&ab->base_lock);
- peer = ath12k_peer_find_by_id(ab, peer_id);
- if (!peer) {
- ath12k_warn(ab, "failed to find the peer to de-fragment received fragment peer_id %d\n",
- peer_id);
- ret = -ENOENT;
- goto out_unlock;
- }
-
- if (!peer->dp_setup_done) {
- ath12k_warn(ab, "The peer %pM [%d] has uninitialized datapath\n",
- peer->addr, peer_id);
- ret = -ENOENT;
- goto out_unlock;
- }
-
- rx_tid = &peer->rx_tid[tid];
-
- if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) ||
- skb_queue_empty(&rx_tid->rx_frags)) {
- /* Flush stored fragments and start a new sequence */
- ath12k_dp_rx_frags_cleanup(rx_tid, true);
- rx_tid->cur_sn = seqno;
- }
-
- if (rx_tid->rx_frag_bitmap & BIT(frag_no)) {
- /* Fragment already present */
- ret = -EINVAL;
- goto out_unlock;
- }
-
- if ((!rx_tid->rx_frag_bitmap || frag_no > __fls(rx_tid->rx_frag_bitmap)))
- __skb_queue_tail(&rx_tid->rx_frags, msdu);
- else
- ath12k_dp_rx_h_sort_frags(ab, &rx_tid->rx_frags, msdu);
-
- rx_tid->rx_frag_bitmap |= BIT(frag_no);
- if (!more_frags)
- rx_tid->last_frag_no = frag_no;
-
- if (frag_no == 0) {
- rx_tid->dst_ring_desc = kmemdup(ring_desc,
- sizeof(*rx_tid->dst_ring_desc),
- GFP_ATOMIC);
- if (!rx_tid->dst_ring_desc) {
- ret = -ENOMEM;
- goto out_unlock;
- }
- } else {
- ath12k_dp_rx_link_desc_return(ab, &ring_desc->buf_addr_info,
- HAL_WBM_REL_BM_ACT_PUT_IN_IDLE);
- }
-
- if (!rx_tid->last_frag_no ||
- rx_tid->rx_frag_bitmap != GENMASK(rx_tid->last_frag_no, 0)) {
- mod_timer(&rx_tid->frag_timer, jiffies +
- ATH12K_DP_RX_FRAGMENT_TIMEOUT_MS);
- goto out_unlock;
- }
-
- spin_unlock_bh(&ab->base_lock);
- timer_delete_sync(&rx_tid->frag_timer);
- spin_lock_bh(&ab->base_lock);
-
- peer = ath12k_peer_find_by_id(ab, peer_id);
- if (!peer)
- goto err_frags_cleanup;
-
- if (!ath12k_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid))
- goto err_frags_cleanup;
-
- if (ath12k_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb))
- goto err_frags_cleanup;
-
- if (!defrag_skb)
- goto err_frags_cleanup;
-
- if (ath12k_dp_rx_h_defrag_reo_reinject(ar, rx_tid, defrag_skb))
- goto err_frags_cleanup;
-
- ath12k_dp_rx_frags_cleanup(rx_tid, false);
- goto out_unlock;
-
-err_frags_cleanup:
- dev_kfree_skb_any(defrag_skb);
- ath12k_dp_rx_frags_cleanup(rx_tid, true);
-out_unlock:
- spin_unlock_bh(&ab->base_lock);
- return ret;
-}
-
-static int
-ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc,
- struct list_head *used_list,
- bool drop, u32 cookie)
-{
- struct ath12k_base *ab = ar->ab;
- struct sk_buff *msdu;
- struct ath12k_skb_rxcb *rxcb;
- struct hal_rx_desc *rx_desc;
- u16 msdu_len;
- u32 hal_rx_desc_sz = ab->hal.hal_desc_sz;
- struct ath12k_rx_desc_info *desc_info;
- u64 desc_va;
-
- desc_va = ((u64)le32_to_cpu(desc->buf_va_hi) << 32 |
- le32_to_cpu(desc->buf_va_lo));
- desc_info = (struct ath12k_rx_desc_info *)((unsigned long)desc_va);
-
- /* retry manual desc retrieval */
- if (!desc_info) {
- desc_info = ath12k_dp_get_rx_desc(ab, cookie);
- if (!desc_info) {
- ath12k_warn(ab, "Invalid cookie in DP rx error descriptor retrieval: 0x%x\n",
- cookie);
- return -EINVAL;
- }
- }
-
- if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC)
- ath12k_warn(ab, " RX Exception, Check HW CC implementation");
-
- msdu = desc_info->skb;
- desc_info->skb = NULL;
-
- list_add_tail(&desc_info->list, used_list);
-
- rxcb = ATH12K_SKB_RXCB(msdu);
- dma_unmap_single(ar->ab->dev, rxcb->paddr,
- msdu->len + skb_tailroom(msdu),
- DMA_FROM_DEVICE);
-
- if (drop) {
- dev_kfree_skb_any(msdu);
- return 0;
- }
-
- rcu_read_lock();
- if (!rcu_dereference(ar->ab->pdevs_active[ar->pdev_idx])) {
- dev_kfree_skb_any(msdu);
- goto exit;
- }
-
- if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) {
- dev_kfree_skb_any(msdu);
- goto exit;
- }
-
- rx_desc = (struct hal_rx_desc *)msdu->data;
- msdu_len = ath12k_dp_rx_h_msdu_len(ar->ab, rx_desc);
- if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) {
- ath12k_warn(ar->ab, "invalid msdu leng %u", msdu_len);
- ath12k_dbg_dump(ar->ab, ATH12K_DBG_DATA, NULL, "", rx_desc,
- sizeof(*rx_desc));
- dev_kfree_skb_any(msdu);
- goto exit;
- }
-
- skb_put(msdu, hal_rx_desc_sz + msdu_len);
-
- if (ath12k_dp_rx_frag_h_mpdu(ar, msdu, desc)) {
- dev_kfree_skb_any(msdu);
- ath12k_dp_rx_link_desc_return(ar->ab, &desc->buf_addr_info,
- HAL_WBM_REL_BM_ACT_PUT_IN_IDLE);
- }
-exit:
- rcu_read_unlock();
- return 0;
-}
-
-int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
- int budget)
-{
- struct ath12k_hw_group *ag = ab->ag;
- struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES];
- u32 msdu_cookies[HAL_NUM_RX_MSDUS_PER_LINK_DESC];
- int num_buffs_reaped[ATH12K_MAX_DEVICES] = {};
- struct dp_link_desc_bank *link_desc_banks;
- enum hal_rx_buf_return_buf_manager rbm;
- struct hal_rx_msdu_link *link_desc_va;
- int tot_n_bufs_reaped, quota, ret, i;
- struct hal_reo_dest_ring *reo_desc;
- struct dp_rxdma_ring *rx_ring;
- struct dp_srng *reo_except;
- struct ath12k_hw_link *hw_links = ag->hw_links;
- struct ath12k_base *partner_ab;
- u8 hw_link_id, device_id;
- u32 desc_bank, num_msdus;
- struct hal_srng *srng;
- struct ath12k *ar;
- dma_addr_t paddr;
- bool is_frag;
- bool drop;
- int pdev_id;
-
- tot_n_bufs_reaped = 0;
- quota = budget;
-
- for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++)
- INIT_LIST_HEAD(&rx_desc_used_list[device_id]);
-
- reo_except = &ab->dp.reo_except_ring;
-
- srng = &ab->hal.srng_list[reo_except->ring_id];
-
- spin_lock_bh(&srng->lock);
-
- ath12k_hal_srng_access_begin(ab, srng);
-
- while (budget &&
- (reo_desc = ath12k_hal_srng_dst_get_next_entry(ab, srng))) {
- drop = false;
- ab->device_stats.err_ring_pkts++;
-
- ret = ath12k_hal_desc_reo_parse_err(ab, reo_desc, &paddr,
- &desc_bank);
- if (ret) {
- ath12k_warn(ab, "failed to parse error reo desc %d\n",
- ret);
- continue;
- }
-
- hw_link_id = le32_get_bits(reo_desc->info0,
- HAL_REO_DEST_RING_INFO0_SRC_LINK_ID);
- device_id = hw_links[hw_link_id].device_id;
- partner_ab = ath12k_ag_to_ab(ag, device_id);
-
- pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params,
- hw_links[hw_link_id].pdev_idx);
- ar = partner_ab->pdevs[pdev_id].ar;
-
- link_desc_banks = partner_ab->dp.link_desc_banks;
- link_desc_va = link_desc_banks[desc_bank].vaddr +
- (paddr - link_desc_banks[desc_bank].paddr);
- ath12k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies,
- &rbm);
- if (rbm != partner_ab->dp.idle_link_rbm &&
- rbm != HAL_RX_BUF_RBM_SW3_BM &&
- rbm != partner_ab->hw_params->hal_params->rx_buf_rbm) {
- ab->device_stats.invalid_rbm++;
- ath12k_warn(ab, "invalid return buffer manager %d\n", rbm);
- ath12k_dp_rx_link_desc_return(partner_ab,
- &reo_desc->buf_addr_info,
- HAL_WBM_REL_BM_ACT_REL_MSDU);
- continue;
- }
-
- is_frag = !!(le32_to_cpu(reo_desc->rx_mpdu_info.info0) &
- RX_MPDU_DESC_INFO0_FRAG_FLAG);
-
- /* Process only rx fragments with one msdu per link desc below, and drop
- * msdu's indicated due to error reasons.
- * Dynamic fragmentation not supported in Multi-link client, so drop the
- * partner device buffers.
- */
- if (!is_frag || num_msdus > 1 ||
- partner_ab->device_id != ab->device_id) {
- drop = true;
-
- /* Return the link desc back to wbm idle list */
- ath12k_dp_rx_link_desc_return(partner_ab,
- &reo_desc->buf_addr_info,
- HAL_WBM_REL_BM_ACT_PUT_IN_IDLE);
- }
-
- for (i = 0; i < num_msdus; i++) {
- if (!ath12k_dp_process_rx_err_buf(ar, reo_desc,
- &rx_desc_used_list[device_id],
- drop,
- msdu_cookies[i])) {
- num_buffs_reaped[device_id]++;
- tot_n_bufs_reaped++;
- }
- }
-
- if (tot_n_bufs_reaped >= quota) {
- tot_n_bufs_reaped = quota;
- goto exit;
- }
-
- budget = quota - tot_n_bufs_reaped;
- }
-
-exit:
- ath12k_hal_srng_access_end(ab, srng);
-
- spin_unlock_bh(&srng->lock);
-
- for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) {
- if (!num_buffs_reaped[device_id])
- continue;
-
- partner_ab = ath12k_ag_to_ab(ag, device_id);
- rx_ring = &partner_ab->dp.rx_refill_buf_ring;
-
- ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring,
- &rx_desc_used_list[device_id],
- num_buffs_reaped[device_id]);
- }
-
- return tot_n_bufs_reaped;
-}
-
-static void ath12k_dp_rx_null_q_desc_sg_drop(struct ath12k *ar,
- int msdu_len,
- struct sk_buff_head *msdu_list)
-{
- struct sk_buff *skb, *tmp;
- struct ath12k_skb_rxcb *rxcb;
- int n_buffs;
-
- n_buffs = DIV_ROUND_UP(msdu_len,
- (DP_RX_BUFFER_SIZE - ar->ab->hal.hal_desc_sz));
-
- skb_queue_walk_safe(msdu_list, skb, tmp) {
- rxcb = ATH12K_SKB_RXCB(skb);
- if (rxcb->err_rel_src == HAL_WBM_REL_SRC_MODULE_REO &&
- rxcb->err_code == HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO) {
- if (!n_buffs)
- break;
- __skb_unlink(skb, msdu_list);
- dev_kfree_skb_any(skb);
- n_buffs--;
- }
- }
-}
-
-int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu,
- struct ath12k_dp_rx_info *rx_info,
- struct sk_buff_head *msdu_list)
-{
- struct ath12k_base *ab = ar->ab;
- u16 msdu_len;
- struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data;
- u8 l3pad_bytes;
- struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
- u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz;
-
- msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc);
-
- if (!rxcb->is_frag && ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE)) {
- /* First buffer will be freed by the caller, so deduct it's length */
- msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - hal_rx_desc_sz);
- ath12k_dp_rx_null_q_desc_sg_drop(ar, msdu_len, msdu_list);
- return -EINVAL;
- }
-
- /* Even after cleaning up the sg buffers in the msdu list with above check
- * any msdu received with continuation flag needs to be dropped as invalid.
- * This protects against some random err frame with continuation flag.
- */
- if (rxcb->is_continuation)
- return -EINVAL;
-
- if (!ath12k_dp_rx_h_msdu_done(ab, desc)) {
- ath12k_warn(ar->ab,
- "msdu_done bit not set in null_q_des processing\n");
- __skb_queue_purge(msdu_list);
- return -EIO;
- }
-
- /* Handle NULL queue descriptor violations arising out a missing
- * REO queue for a given peer or a given TID. This typically
- * may happen if a packet is received on a QOS enabled TID before the
- * ADDBA negotiation for that TID, when the TID queue is setup. Or
- * it may also happen for MC/BC frames if they are not routed to the
- * non-QOS TID queue, in the absence of any other default TID queue.
- * This error can show up both in a REO destination or WBM release ring.
- */
-
- if (rxcb->is_frag) {
- skb_pull(msdu, hal_rx_desc_sz);
- } else {
- l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc);
-
- if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE)
- return -EINVAL;
-
- skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len);
- skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes);
- }
- if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu)))
- return -EINVAL;
-
- ath12k_dp_rx_h_fetch_info(ab, desc, rx_info);
- ath12k_dp_rx_h_ppdu(ar, rx_info);
- ath12k_dp_rx_h_mpdu(ar, msdu, desc, rx_info);
-
- rxcb->tid = rx_info->tid;
-
- /* Please note that caller will having the access to msdu and completing
- * rx with mac80211. Need not worry about cleaning up amsdu_list.
- */
-
- return 0;
-}
-
void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab)
{
struct ath12k_dp *dp = &ab->dp;
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h
index 542f08efe0cd..dc0b1078213c 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.h
@@ -45,6 +45,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
@@ -351,9 +353,20 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi,
bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab,
struct hal_rx_desc *rx_desc,
struct sk_buff *msdu);
-int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu,
- struct ath12k_dp_rx_info *rx_info,
- struct sk_buff_head *msdu_list);
+void ath12k_dp_rx_h_mpdu(struct ath12k *ar,
+ struct sk_buff *msdu,
+ struct hal_rx_desc *rx_desc,
+ struct ath12k_dp_rx_info *rx_info);
+u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb);
+void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab,
+ struct sk_buff_head *frag_list,
+ struct sk_buff *cur_frag);
+void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu,
+ enum hal_encrypt_type enctype, u32 flags);
+int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer,
+ struct sk_buff *msdu);
+void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid,
+ bool rel_link_desc);
int ath12k_dp_rx_ampdu_start(struct ath12k *ar,
struct ieee80211_ampdu_params *params,
u8 link_id);
@@ -381,8 +394,6 @@ int ath12k_dp_rx_pdev_alloc(struct ath12k_base *ab, int pdev_idx);
void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int pdev_idx);
void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab);
void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab);
-int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
- int budget);
int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id,
struct napi_struct *napi,
int budget);
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
index a002e3839fff..c2b108a1005b 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
@@ -6,6 +6,688 @@
#include "dp_rx.h"
#include "../dp_tx.h"
+#include "../peer.h"
+
+static bool
+ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, struct ath12k_dp_rx_tid *rx_tid)
+{
+ struct ath12k_base *ab = ar->ab;
+ enum hal_encrypt_type encrypt_type;
+ struct sk_buff *first_frag, *skb;
+ struct hal_rx_desc *desc;
+ u64 last_pn;
+ u64 cur_pn;
+
+ first_frag = skb_peek(&rx_tid->rx_frags);
+ desc = (struct hal_rx_desc *)first_frag->data;
+
+ encrypt_type = ath12k_dp_rx_h_enctype(ab, desc);
+ if (encrypt_type != HAL_ENCRYPT_TYPE_CCMP_128 &&
+ encrypt_type != HAL_ENCRYPT_TYPE_CCMP_256 &&
+ encrypt_type != HAL_ENCRYPT_TYPE_GCMP_128 &&
+ encrypt_type != HAL_ENCRYPT_TYPE_AES_GCMP_256)
+ return true;
+
+ last_pn = ath12k_dp_rx_h_get_pn(ar, first_frag);
+ skb_queue_walk(&rx_tid->rx_frags, skb) {
+ if (skb == first_frag)
+ continue;
+
+ cur_pn = ath12k_dp_rx_h_get_pn(ar, skb);
+ if (cur_pn != last_pn + 1)
+ return false;
+ last_pn = cur_pn;
+ }
+ return true;
+}
+
+static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar,
+ struct ath12k_dp_rx_tid *rx_tid,
+ struct sk_buff *defrag_skb)
+{
+ struct ath12k_base *ab = ar->ab;
+ struct ath12k_dp *dp = &ab->dp;
+ struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)defrag_skb->data;
+ struct hal_reo_entrance_ring *reo_ent_ring;
+ struct hal_reo_dest_ring *reo_dest_ring;
+ struct dp_link_desc_bank *link_desc_banks;
+ struct hal_rx_msdu_link *msdu_link;
+ struct hal_rx_msdu_details *msdu0;
+ struct hal_srng *srng;
+ dma_addr_t link_paddr, buf_paddr;
+ u32 desc_bank, msdu_info, msdu_ext_info, mpdu_info;
+ u32 cookie, hal_rx_desc_sz, dest_ring_info0, queue_addr_hi;
+ int ret;
+ struct ath12k_rx_desc_info *desc_info;
+ enum hal_rx_buf_return_buf_manager idle_link_rbm = dp->idle_link_rbm;
+ u8 dst_ind;
+
+ hal_rx_desc_sz = ab->hal.hal_desc_sz;
+ link_desc_banks = dp->link_desc_banks;
+ reo_dest_ring = rx_tid->dst_ring_desc;
+
+ ath12k_hal_rx_reo_ent_paddr_get(ab, &reo_dest_ring->buf_addr_info,
+ &link_paddr, &cookie);
+ desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK);
+
+ msdu_link = (struct hal_rx_msdu_link *)(link_desc_banks[desc_bank].vaddr +
+ (link_paddr - link_desc_banks[desc_bank].paddr));
+ msdu0 = &msdu_link->msdu_link[0];
+ msdu_ext_info = le32_to_cpu(msdu0->rx_msdu_ext_info.info0);
+ dst_ind = u32_get_bits(msdu_ext_info, RX_MSDU_EXT_DESC_INFO0_REO_DEST_IND);
+
+ memset(msdu0, 0, sizeof(*msdu0));
+
+ msdu_info = u32_encode_bits(1, RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU) |
+ u32_encode_bits(1, RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU) |
+ u32_encode_bits(0, RX_MSDU_DESC_INFO0_MSDU_CONTINUATION) |
+ u32_encode_bits(defrag_skb->len - hal_rx_desc_sz,
+ RX_MSDU_DESC_INFO0_MSDU_LENGTH) |
+ u32_encode_bits(1, RX_MSDU_DESC_INFO0_VALID_SA) |
+ u32_encode_bits(1, RX_MSDU_DESC_INFO0_VALID_DA);
+ msdu0->rx_msdu_info.info0 = cpu_to_le32(msdu_info);
+ msdu0->rx_msdu_ext_info.info0 = cpu_to_le32(msdu_ext_info);
+
+ /* change msdu len in hal rx desc */
+ ath12k_dp_rxdesc_set_msdu_len(ab, rx_desc, defrag_skb->len - hal_rx_desc_sz);
+
+ buf_paddr = dma_map_single(ab->dev, defrag_skb->data,
+ defrag_skb->len + skb_tailroom(defrag_skb),
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(ab->dev, buf_paddr))
+ return -ENOMEM;
+
+ spin_lock_bh(&dp->rx_desc_lock);
+ desc_info = list_first_entry_or_null(&dp->rx_desc_free_list,
+ struct ath12k_rx_desc_info,
+ list);
+ if (!desc_info) {
+ spin_unlock_bh(&dp->rx_desc_lock);
+ ath12k_warn(ab, "failed to find rx desc for reinject\n");
+ ret = -ENOMEM;
+ goto err_unmap_dma;
+ }
+
+ desc_info->skb = defrag_skb;
+ desc_info->in_use = true;
+
+ list_del(&desc_info->list);
+ spin_unlock_bh(&dp->rx_desc_lock);
+
+ ATH12K_SKB_RXCB(defrag_skb)->paddr = buf_paddr;
+
+ ath12k_hal_rx_buf_addr_info_set(&msdu0->buf_addr_info, buf_paddr,
+ desc_info->cookie,
+ HAL_RX_BUF_RBM_SW3_BM);
+
+ /* Fill mpdu details into reo entrance ring */
+ srng = &ab->hal.srng_list[dp->reo_reinject_ring.ring_id];
+
+ spin_lock_bh(&srng->lock);
+ ath12k_hal_srng_access_begin(ab, srng);
+
+ reo_ent_ring = ath12k_hal_srng_src_get_next_entry(ab, srng);
+ if (!reo_ent_ring) {
+ ath12k_hal_srng_access_end(ab, srng);
+ spin_unlock_bh(&srng->lock);
+ ret = -ENOSPC;
+ goto err_free_desc;
+ }
+ memset(reo_ent_ring, 0, sizeof(*reo_ent_ring));
+
+ ath12k_hal_rx_buf_addr_info_set(&reo_ent_ring->buf_addr_info, link_paddr,
+ cookie,
+ idle_link_rbm);
+
+ mpdu_info = u32_encode_bits(1, RX_MPDU_DESC_INFO0_MSDU_COUNT) |
+ u32_encode_bits(0, RX_MPDU_DESC_INFO0_FRAG_FLAG) |
+ u32_encode_bits(1, RX_MPDU_DESC_INFO0_RAW_MPDU) |
+ u32_encode_bits(1, RX_MPDU_DESC_INFO0_VALID_PN) |
+ u32_encode_bits(rx_tid->tid, RX_MPDU_DESC_INFO0_TID);
+
+ reo_ent_ring->rx_mpdu_info.info0 = cpu_to_le32(mpdu_info);
+ reo_ent_ring->rx_mpdu_info.peer_meta_data =
+ reo_dest_ring->rx_mpdu_info.peer_meta_data;
+
+ if (ab->hw_params->reoq_lut_support) {
+ reo_ent_ring->queue_addr_lo = reo_dest_ring->rx_mpdu_info.peer_meta_data;
+ queue_addr_hi = 0;
+ } else {
+ reo_ent_ring->queue_addr_lo =
+ cpu_to_le32(lower_32_bits(rx_tid->qbuf.paddr_aligned));
+ queue_addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned);
+ }
+
+ reo_ent_ring->info0 = le32_encode_bits(queue_addr_hi,
+ HAL_REO_ENTR_RING_INFO0_QUEUE_ADDR_HI) |
+ le32_encode_bits(dst_ind,
+ HAL_REO_ENTR_RING_INFO0_DEST_IND);
+
+ reo_ent_ring->info1 = le32_encode_bits(rx_tid->cur_sn,
+ HAL_REO_ENTR_RING_INFO1_MPDU_SEQ_NUM);
+ dest_ring_info0 = le32_get_bits(reo_dest_ring->info0,
+ HAL_REO_DEST_RING_INFO0_SRC_LINK_ID);
+ reo_ent_ring->info2 =
+ cpu_to_le32(u32_get_bits(dest_ring_info0,
+ HAL_REO_ENTR_RING_INFO2_SRC_LINK_ID));
+
+ ath12k_hal_srng_access_end(ab, srng);
+ spin_unlock_bh(&srng->lock);
+
+ return 0;
+
+err_free_desc:
+ spin_lock_bh(&dp->rx_desc_lock);
+ desc_info->in_use = false;
+ desc_info->skb = NULL;
+ list_add_tail(&desc_info->list, &dp->rx_desc_free_list);
+ spin_unlock_bh(&dp->rx_desc_lock);
+err_unmap_dma:
+ dma_unmap_single(ab->dev, buf_paddr, defrag_skb->len + skb_tailroom(defrag_skb),
+ DMA_TO_DEVICE);
+ return ret;
+}
+
+static int ath12k_dp_rx_h_defrag(struct ath12k *ar,
+ struct ath12k_peer *peer,
+ struct ath12k_dp_rx_tid *rx_tid,
+ struct sk_buff **defrag_skb)
+{
+ struct ath12k_base *ab = ar->ab;
+ struct hal_rx_desc *rx_desc;
+ struct sk_buff *skb, *first_frag, *last_frag;
+ struct ieee80211_hdr *hdr;
+ enum hal_encrypt_type enctype;
+ bool is_decrypted = false;
+ int msdu_len = 0;
+ int extra_space;
+ u32 flags, hal_rx_desc_sz = ar->ab->hal.hal_desc_sz;
+
+ first_frag = skb_peek(&rx_tid->rx_frags);
+ last_frag = skb_peek_tail(&rx_tid->rx_frags);
+
+ skb_queue_walk(&rx_tid->rx_frags, skb) {
+ flags = 0;
+ rx_desc = (struct hal_rx_desc *)skb->data;
+ hdr = (struct ieee80211_hdr *)(skb->data + hal_rx_desc_sz);
+
+ enctype = ath12k_dp_rx_h_enctype(ab, rx_desc);
+ if (enctype != HAL_ENCRYPT_TYPE_OPEN)
+ is_decrypted = ath12k_dp_rx_h_is_decrypted(ab,
+ rx_desc);
+
+ if (is_decrypted) {
+ if (skb != first_frag)
+ flags |= RX_FLAG_IV_STRIPPED;
+ if (skb != last_frag)
+ flags |= RX_FLAG_ICV_STRIPPED |
+ RX_FLAG_MIC_STRIPPED;
+ }
+
+ /* RX fragments are always raw packets */
+ if (skb != last_frag)
+ skb_trim(skb, skb->len - FCS_LEN);
+ ath12k_dp_rx_h_undecap_frag(ar, skb, enctype, flags);
+
+ if (skb != first_frag)
+ skb_pull(skb, hal_rx_desc_sz +
+ ieee80211_hdrlen(hdr->frame_control));
+ msdu_len += skb->len;
+ }
+
+ extra_space = msdu_len - (DP_RX_BUFFER_SIZE + skb_tailroom(first_frag));
+ if (extra_space > 0 &&
+ (pskb_expand_head(first_frag, 0, extra_space, GFP_ATOMIC) < 0))
+ return -ENOMEM;
+
+ __skb_unlink(first_frag, &rx_tid->rx_frags);
+ while ((skb = __skb_dequeue(&rx_tid->rx_frags))) {
+ skb_put_data(first_frag, skb->data, skb->len);
+ dev_kfree_skb_any(skb);
+ }
+
+ hdr = (struct ieee80211_hdr *)(first_frag->data + hal_rx_desc_sz);
+ hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_MOREFRAGS);
+ ATH12K_SKB_RXCB(first_frag)->is_frag = 1;
+
+ if (ath12k_dp_rx_h_verify_tkip_mic(ar, peer, first_frag))
+ first_frag = NULL;
+
+ *defrag_skb = first_frag;
+ return 0;
+}
+
+static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar,
+ struct sk_buff *msdu,
+ struct hal_reo_dest_ring *ring_desc)
+{
+ struct ath12k_base *ab = ar->ab;
+ struct hal_rx_desc *rx_desc;
+ struct ath12k_peer *peer;
+ struct ath12k_dp_rx_tid *rx_tid;
+ struct sk_buff *defrag_skb = NULL;
+ u32 peer_id;
+ u16 seqno, frag_no;
+ u8 tid;
+ int ret = 0;
+ bool more_frags;
+
+ rx_desc = (struct hal_rx_desc *)msdu->data;
+ peer_id = ath12k_dp_rx_h_peer_id(ab, rx_desc);
+ tid = ath12k_dp_rx_h_tid(ab, rx_desc);
+ seqno = ath12k_dp_rx_h_seq_no(ab, rx_desc);
+ frag_no = ath12k_dp_rx_h_frag_no(ab, msdu);
+ more_frags = ath12k_dp_rx_h_more_frags(ab, msdu);
+
+ if (!ath12k_dp_rx_h_seq_ctrl_valid(ab, rx_desc) ||
+ !ath12k_dp_rx_h_fc_valid(ab, rx_desc) ||
+ tid > IEEE80211_NUM_TIDS)
+ return -EINVAL;
+
+ /* received unfragmented packet in reo
+ * exception ring, this shouldn't happen
+ * as these packets typically come from
+ * reo2sw srngs.
+ */
+ if (WARN_ON_ONCE(!frag_no && !more_frags))
+ return -EINVAL;
+
+ spin_lock_bh(&ab->base_lock);
+ peer = ath12k_peer_find_by_id(ab, peer_id);
+ if (!peer) {
+ ath12k_warn(ab, "failed to find the peer to de-fragment received fragment peer_id %d\n",
+ peer_id);
+ ret = -ENOENT;
+ goto out_unlock;
+ }
+
+ if (!peer->dp_setup_done) {
+ ath12k_warn(ab, "The peer %pM [%d] has uninitialized datapath\n",
+ peer->addr, peer_id);
+ ret = -ENOENT;
+ goto out_unlock;
+ }
+
+ rx_tid = &peer->rx_tid[tid];
+
+ if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) ||
+ skb_queue_empty(&rx_tid->rx_frags)) {
+ /* Flush stored fragments and start a new sequence */
+ ath12k_dp_rx_frags_cleanup(rx_tid, true);
+ rx_tid->cur_sn = seqno;
+ }
+
+ if (rx_tid->rx_frag_bitmap & BIT(frag_no)) {
+ /* Fragment already present */
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ if ((!rx_tid->rx_frag_bitmap || frag_no > __fls(rx_tid->rx_frag_bitmap)))
+ __skb_queue_tail(&rx_tid->rx_frags, msdu);
+ else
+ ath12k_dp_rx_h_sort_frags(ab, &rx_tid->rx_frags, msdu);
+
+ rx_tid->rx_frag_bitmap |= BIT(frag_no);
+ if (!more_frags)
+ rx_tid->last_frag_no = frag_no;
+
+ if (frag_no == 0) {
+ rx_tid->dst_ring_desc = kmemdup(ring_desc,
+ sizeof(*rx_tid->dst_ring_desc),
+ GFP_ATOMIC);
+ if (!rx_tid->dst_ring_desc) {
+ ret = -ENOMEM;
+ goto out_unlock;
+ }
+ } else {
+ ath12k_dp_rx_link_desc_return(ab, &ring_desc->buf_addr_info,
+ HAL_WBM_REL_BM_ACT_PUT_IN_IDLE);
+ }
+
+ if (!rx_tid->last_frag_no ||
+ rx_tid->rx_frag_bitmap != GENMASK(rx_tid->last_frag_no, 0)) {
+ mod_timer(&rx_tid->frag_timer, jiffies +
+ ATH12K_DP_RX_FRAGMENT_TIMEOUT_MS);
+ goto out_unlock;
+ }
+
+ spin_unlock_bh(&ab->base_lock);
+ timer_delete_sync(&rx_tid->frag_timer);
+ spin_lock_bh(&ab->base_lock);
+
+ peer = ath12k_peer_find_by_id(ab, peer_id);
+ if (!peer)
+ goto err_frags_cleanup;
+
+ if (!ath12k_dp_rx_h_defrag_validate_incr_pn(ar, rx_tid))
+ goto err_frags_cleanup;
+
+ if (ath12k_dp_rx_h_defrag(ar, peer, rx_tid, &defrag_skb))
+ goto err_frags_cleanup;
+
+ if (!defrag_skb)
+ goto err_frags_cleanup;
+
+ if (ath12k_dp_rx_h_defrag_reo_reinject(ar, rx_tid, defrag_skb))
+ goto err_frags_cleanup;
+
+ ath12k_dp_rx_frags_cleanup(rx_tid, false);
+ goto out_unlock;
+
+err_frags_cleanup:
+ dev_kfree_skb_any(defrag_skb);
+ ath12k_dp_rx_frags_cleanup(rx_tid, true);
+out_unlock:
+ spin_unlock_bh(&ab->base_lock);
+ return ret;
+}
+
+static int
+ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc,
+ struct list_head *used_list,
+ bool drop, u32 cookie)
+{
+ struct ath12k_base *ab = ar->ab;
+ struct sk_buff *msdu;
+ struct ath12k_skb_rxcb *rxcb;
+ struct hal_rx_desc *rx_desc;
+ u16 msdu_len;
+ u32 hal_rx_desc_sz = ab->hal.hal_desc_sz;
+ struct ath12k_rx_desc_info *desc_info;
+ u64 desc_va;
+
+ desc_va = ((u64)le32_to_cpu(desc->buf_va_hi) << 32 |
+ le32_to_cpu(desc->buf_va_lo));
+ desc_info = (struct ath12k_rx_desc_info *)((unsigned long)desc_va);
+
+ /* retry manual desc retrieval */
+ if (!desc_info) {
+ desc_info = ath12k_dp_get_rx_desc(ab, cookie);
+ if (!desc_info) {
+ ath12k_warn(ab, "Invalid cookie in DP rx error descriptor retrieval: 0x%x\n",
+ cookie);
+ return -EINVAL;
+ }
+ }
+
+ if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC)
+ ath12k_warn(ab, " RX Exception, Check HW CC implementation");
+
+ msdu = desc_info->skb;
+ desc_info->skb = NULL;
+
+ list_add_tail(&desc_info->list, used_list);
+
+ rxcb = ATH12K_SKB_RXCB(msdu);
+ dma_unmap_single(ar->ab->dev, rxcb->paddr,
+ msdu->len + skb_tailroom(msdu),
+ DMA_FROM_DEVICE);
+
+ if (drop) {
+ dev_kfree_skb_any(msdu);
+ return 0;
+ }
+
+ rcu_read_lock();
+ if (!rcu_dereference(ar->ab->pdevs_active[ar->pdev_idx])) {
+ dev_kfree_skb_any(msdu);
+ goto exit;
+ }
+
+ if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) {
+ dev_kfree_skb_any(msdu);
+ goto exit;
+ }
+
+ rx_desc = (struct hal_rx_desc *)msdu->data;
+ msdu_len = ath12k_dp_rx_h_msdu_len(ar->ab, rx_desc);
+ if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) {
+ ath12k_warn(ar->ab, "invalid msdu leng %u", msdu_len);
+ ath12k_dbg_dump(ar->ab, ATH12K_DBG_DATA, NULL, "", rx_desc,
+ sizeof(*rx_desc));
+ dev_kfree_skb_any(msdu);
+ goto exit;
+ }
+
+ skb_put(msdu, hal_rx_desc_sz + msdu_len);
+
+ if (ath12k_dp_rx_frag_h_mpdu(ar, msdu, desc)) {
+ dev_kfree_skb_any(msdu);
+ ath12k_dp_rx_link_desc_return(ar->ab, &desc->buf_addr_info,
+ HAL_WBM_REL_BM_ACT_PUT_IN_IDLE);
+ }
+exit:
+ rcu_read_unlock();
+ return 0;
+}
+
+int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
+ int budget)
+{
+ struct ath12k_hw_group *ag = ab->ag;
+ struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES];
+ u32 msdu_cookies[HAL_NUM_RX_MSDUS_PER_LINK_DESC];
+ int num_buffs_reaped[ATH12K_MAX_DEVICES] = {};
+ struct dp_link_desc_bank *link_desc_banks;
+ enum hal_rx_buf_return_buf_manager rbm;
+ struct hal_rx_msdu_link *link_desc_va;
+ int tot_n_bufs_reaped, quota, ret, i;
+ struct hal_reo_dest_ring *reo_desc;
+ struct dp_rxdma_ring *rx_ring;
+ struct dp_srng *reo_except;
+ struct ath12k_hw_link *hw_links = ag->hw_links;
+ struct ath12k_base *partner_ab;
+ u8 hw_link_id, device_id;
+ u32 desc_bank, num_msdus;
+ struct hal_srng *srng;
+ struct ath12k *ar;
+ dma_addr_t paddr;
+ bool is_frag;
+ bool drop;
+ int pdev_id;
+
+ tot_n_bufs_reaped = 0;
+ quota = budget;
+
+ for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++)
+ INIT_LIST_HEAD(&rx_desc_used_list[device_id]);
+
+ reo_except = &ab->dp.reo_except_ring;
+
+ srng = &ab->hal.srng_list[reo_except->ring_id];
+
+ spin_lock_bh(&srng->lock);
+
+ ath12k_hal_srng_access_begin(ab, srng);
+
+ while (budget &&
+ (reo_desc = ath12k_hal_srng_dst_get_next_entry(ab, srng))) {
+ drop = false;
+ ab->device_stats.err_ring_pkts++;
+
+ ret = ath12k_hal_desc_reo_parse_err(ab, reo_desc, &paddr,
+ &desc_bank);
+ if (ret) {
+ ath12k_warn(ab, "failed to parse error reo desc %d\n",
+ ret);
+ continue;
+ }
+
+ hw_link_id = le32_get_bits(reo_desc->info0,
+ HAL_REO_DEST_RING_INFO0_SRC_LINK_ID);
+ device_id = hw_links[hw_link_id].device_id;
+ partner_ab = ath12k_ag_to_ab(ag, device_id);
+
+ pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params,
+ hw_links[hw_link_id].pdev_idx);
+ ar = partner_ab->pdevs[pdev_id].ar;
+
+ link_desc_banks = partner_ab->dp.link_desc_banks;
+ link_desc_va = link_desc_banks[desc_bank].vaddr +
+ (paddr - link_desc_banks[desc_bank].paddr);
+ ath12k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies,
+ &rbm);
+ if (rbm != partner_ab->dp.idle_link_rbm &&
+ rbm != HAL_RX_BUF_RBM_SW3_BM &&
+ rbm != partner_ab->hw_params->hal_params->rx_buf_rbm) {
+ ab->device_stats.invalid_rbm++;
+ ath12k_warn(ab, "invalid return buffer manager %d\n", rbm);
+ ath12k_dp_rx_link_desc_return(partner_ab,
+ &reo_desc->buf_addr_info,
+ HAL_WBM_REL_BM_ACT_REL_MSDU);
+ continue;
+ }
+
+ is_frag = !!(le32_to_cpu(reo_desc->rx_mpdu_info.info0) &
+ RX_MPDU_DESC_INFO0_FRAG_FLAG);
+
+ /* Process only rx fragments with one msdu per link desc below, and drop
+ * msdu's indicated due to error reasons.
+ * Dynamic fragmentation not supported in Multi-link client, so drop the
+ * partner device buffers.
+ */
+ if (!is_frag || num_msdus > 1 ||
+ partner_ab->device_id != ab->device_id) {
+ drop = true;
+
+ /* Return the link desc back to wbm idle list */
+ ath12k_dp_rx_link_desc_return(partner_ab,
+ &reo_desc->buf_addr_info,
+ HAL_WBM_REL_BM_ACT_PUT_IN_IDLE);
+ }
+
+ for (i = 0; i < num_msdus; i++) {
+ if (!ath12k_dp_process_rx_err_buf(ar, reo_desc,
+ &rx_desc_used_list[device_id],
+ drop,
+ msdu_cookies[i])) {
+ num_buffs_reaped[device_id]++;
+ tot_n_bufs_reaped++;
+ }
+ }
+
+ if (tot_n_bufs_reaped >= quota) {
+ tot_n_bufs_reaped = quota;
+ goto exit;
+ }
+
+ budget = quota - tot_n_bufs_reaped;
+ }
+
+exit:
+ ath12k_hal_srng_access_end(ab, srng);
+
+ spin_unlock_bh(&srng->lock);
+
+ for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) {
+ if (!num_buffs_reaped[device_id])
+ continue;
+
+ partner_ab = ath12k_ag_to_ab(ag, device_id);
+ rx_ring = &partner_ab->dp.rx_refill_buf_ring;
+
+ ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring,
+ &rx_desc_used_list[device_id],
+ num_buffs_reaped[device_id]);
+ }
+
+ return tot_n_bufs_reaped;
+}
+
+static void ath12k_dp_rx_null_q_desc_sg_drop(struct ath12k *ar,
+ int msdu_len,
+ struct sk_buff_head *msdu_list)
+{
+ struct sk_buff *skb, *tmp;
+ struct ath12k_skb_rxcb *rxcb;
+ int n_buffs;
+
+ n_buffs = DIV_ROUND_UP(msdu_len,
+ (DP_RX_BUFFER_SIZE - ar->ab->hal.hal_desc_sz));
+
+ skb_queue_walk_safe(msdu_list, skb, tmp) {
+ rxcb = ATH12K_SKB_RXCB(skb);
+ if (rxcb->err_rel_src == HAL_WBM_REL_SRC_MODULE_REO &&
+ rxcb->err_code == HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO) {
+ if (!n_buffs)
+ break;
+ __skb_unlink(skb, msdu_list);
+ dev_kfree_skb_any(skb);
+ n_buffs--;
+ }
+ }
+}
+
+static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu,
+ struct ath12k_dp_rx_info *rx_info,
+ struct sk_buff_head *msdu_list)
+{
+ struct ath12k_base *ab = ar->ab;
+ u16 msdu_len;
+ struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data;
+ u8 l3pad_bytes;
+ struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
+ u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz;
+
+ msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc);
+
+ if (!rxcb->is_frag && ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE)) {
+ /* First buffer will be freed by the caller, so deduct it's length */
+ msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - hal_rx_desc_sz);
+ ath12k_dp_rx_null_q_desc_sg_drop(ar, msdu_len, msdu_list);
+ return -EINVAL;
+ }
+
+ /* Even after cleaning up the sg buffers in the msdu list with above check
+ * any msdu received with continuation flag needs to be dropped as invalid.
+ * This protects against some random err frame with continuation flag.
+ */
+ if (rxcb->is_continuation)
+ return -EINVAL;
+
+ if (!ath12k_dp_rx_h_msdu_done(ab, desc)) {
+ ath12k_warn(ar->ab,
+ "msdu_done bit not set in null_q_des processing\n");
+ __skb_queue_purge(msdu_list);
+ return -EIO;
+ }
+
+ /* Handle NULL queue descriptor violations arising out a missing
+ * REO queue for a given peer or a given TID. This typically
+ * may happen if a packet is received on a QOS enabled TID before the
+ * ADDBA negotiation for that TID, when the TID queue is setup. Or
+ * it may also happen for MC/BC frames if they are not routed to the
+ * non-QOS TID queue, in the absence of any other default TID queue.
+ * This error can show up both in a REO destination or WBM release ring.
+ */
+
+ if (rxcb->is_frag) {
+ skb_pull(msdu, hal_rx_desc_sz);
+ } else {
+ l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc);
+
+ if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE)
+ return -EINVAL;
+
+ skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len);
+ skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes);
+ }
+ if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, desc, msdu)))
+ return -EINVAL;
+
+ ath12k_dp_rx_h_fetch_info(ab, desc, rx_info);
+ ath12k_dp_rx_h_ppdu(ar, rx_info);
+ ath12k_dp_rx_h_mpdu(ar, msdu, desc, rx_info);
+
+ rxcb->tid = rx_info->tid;
+
+ /* Please note that caller will having the access to msdu and completing
+ * rx with mac80211. Need not worry about cleaning up amsdu_list.
+ */
+
+ return 0;
+}
static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu,
struct ath12k_dp_rx_info *rx_info)
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
index 154018c221da..9c2114c62ba2 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
@@ -11,6 +11,8 @@
int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
struct napi_struct *napi, int budget);
+int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
+ int budget);
int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab);
int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab);
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 10/20] wifi: ath12k: Move regular msdu processing functions to wifi7 directory
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (8 preceding siblings ...)
2025-08-28 17:35 ` [PATCH ath12k-ng 09/20] wifi: ath12k: Move rx error and defrag " Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 11/20] wifi: ath12k: Move srng processing " Ripan Deuri
` (12 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Move arch specific RX MSDU processing related functions to wifi7 directory.
The moved APIs will be a part of dp_rx.c file inside wifi7 directory.
wifi7/dp_rx.c file will continue to be part of ath12k.ko temporarily
until the corresponding infra for movement to ath12k_wifi7.ko arrives
in upcoming patches.
Architecture specific APIs:
ath12k_dp_rx_msdu_coalesce
ath12k_dp_rx_h_csum_offload
ath12k_dp_rx_h_mpdu
ath12k_dp_rx_process
ath12k_dp_rx_process_received_packets
ath12k_dp_rx_h_verify_tkip_mic
ath12k_dp_rx_process_msdu
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/dp_rx.c | 543 +-----------------
drivers/net/wireless/ath/ath12k/dp_rx.h | 18 +-
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 527 +++++++++++++++++
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 3 +
4 files changed, 547 insertions(+), 544 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index d52fec62eed7..6809c50ee871 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -1664,95 +1664,8 @@ void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab,
}
EXPORT_SYMBOL(ath12k_dp_htt_htc_t2h_msg_handler);
-static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar,
- struct sk_buff_head *msdu_list,
- struct sk_buff *first, struct sk_buff *last,
- u8 l3pad_bytes, int msdu_len)
-{
- struct ath12k_base *ab = ar->ab;
- struct sk_buff *skb;
- struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(first);
- int buf_first_hdr_len, buf_first_len;
- struct hal_rx_desc *ldesc;
- int space_extra, rem_len, buf_len;
- u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz;
- bool is_continuation;
-
- /* As the msdu is spread across multiple rx buffers,
- * find the offset to the start of msdu for computing
- * the length of the msdu in the first buffer.
- */
- buf_first_hdr_len = hal_rx_desc_sz + l3pad_bytes;
- buf_first_len = DP_RX_BUFFER_SIZE - buf_first_hdr_len;
-
- if (WARN_ON_ONCE(msdu_len <= buf_first_len)) {
- skb_put(first, buf_first_hdr_len + msdu_len);
- skb_pull(first, buf_first_hdr_len);
- return 0;
- }
-
- ldesc = (struct hal_rx_desc *)last->data;
- rxcb->is_first_msdu = ath12k_dp_rx_h_first_msdu(ab, ldesc);
- rxcb->is_last_msdu = ath12k_dp_rx_h_last_msdu(ab, ldesc);
-
- /* MSDU spans over multiple buffers because the length of the MSDU
- * exceeds DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE. So assume the data
- * in the first buf is of length DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE.
- */
- skb_put(first, DP_RX_BUFFER_SIZE);
- skb_pull(first, buf_first_hdr_len);
-
- /* When an MSDU spread over multiple buffers MSDU_END
- * tlvs are valid only in the last buffer. Copy those tlvs.
- */
- ath12k_dp_rx_desc_end_tlv_copy(ab, rxcb->rx_desc, ldesc);
-
- space_extra = msdu_len - (buf_first_len + skb_tailroom(first));
- if (space_extra > 0 &&
- (pskb_expand_head(first, 0, space_extra, GFP_ATOMIC) < 0)) {
- /* Free up all buffers of the MSDU */
- while ((skb = __skb_dequeue(msdu_list)) != NULL) {
- rxcb = ATH12K_SKB_RXCB(skb);
- if (!rxcb->is_continuation) {
- dev_kfree_skb_any(skb);
- break;
- }
- dev_kfree_skb_any(skb);
- }
- return -ENOMEM;
- }
-
- rem_len = msdu_len - buf_first_len;
- while ((skb = __skb_dequeue(msdu_list)) != NULL && rem_len > 0) {
- rxcb = ATH12K_SKB_RXCB(skb);
- is_continuation = rxcb->is_continuation;
- if (is_continuation)
- buf_len = DP_RX_BUFFER_SIZE - hal_rx_desc_sz;
- else
- buf_len = rem_len;
-
- if (buf_len > (DP_RX_BUFFER_SIZE - hal_rx_desc_sz)) {
- WARN_ON_ONCE(1);
- dev_kfree_skb_any(skb);
- return -EINVAL;
- }
-
- skb_put(skb, buf_len + hal_rx_desc_sz);
- skb_pull(skb, hal_rx_desc_sz);
- skb_copy_from_linear_data(skb, skb_put(first, buf_len),
- buf_len);
- dev_kfree_skb_any(skb);
-
- rem_len -= buf_len;
- if (!is_continuation)
- break;
- }
-
- return 0;
-}
-
-static struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list,
- struct sk_buff *first)
+struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list,
+ struct sk_buff *first)
{
struct sk_buff *skb;
struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(first);
@@ -1769,13 +1682,6 @@ static struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_
return NULL;
}
-static void ath12k_dp_rx_h_csum_offload(struct sk_buff *msdu,
- struct ath12k_dp_rx_info *rx_info)
-{
- msdu->ip_summed = (rx_info->ip_csum_fail || rx_info->l4_csum_fail) ?
- CHECKSUM_NONE : CHECKSUM_UNNECESSARY;
-}
-
int ath12k_dp_rx_crypto_mic_len(struct ath12k *ar, enum hal_encrypt_type enctype)
{
switch (enctype) {
@@ -2094,84 +2000,6 @@ ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu,
return peer;
}
-void ath12k_dp_rx_h_mpdu(struct ath12k *ar,
- struct sk_buff *msdu,
- struct hal_rx_desc *rx_desc,
- struct ath12k_dp_rx_info *rx_info)
-{
- struct ath12k_base *ab = ar->ab;
- struct ath12k_skb_rxcb *rxcb;
- enum hal_encrypt_type enctype;
- bool is_decrypted = false;
- struct ieee80211_hdr *hdr;
- struct ath12k_peer *peer;
- struct ieee80211_rx_status *rx_status = rx_info->rx_status;
- u32 err_bitmap;
-
- /* PN for multicast packets will be checked in mac80211 */
- rxcb = ATH12K_SKB_RXCB(msdu);
- rxcb->is_mcbc = rx_info->is_mcbc;
-
- if (rxcb->is_mcbc)
- rxcb->peer_id = rx_info->peer_id;
-
- spin_lock_bh(&ar->ab->base_lock);
- peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu, rx_info);
- if (peer) {
- /* resetting mcbc bit because mcbc packets are unicast
- * packets only for AP as STA sends unicast packets.
- */
- rxcb->is_mcbc = rxcb->is_mcbc && !peer->ucast_ra_only;
-
- if (rxcb->is_mcbc)
- enctype = peer->sec_type_grp;
- else
- enctype = peer->sec_type;
- } else {
- enctype = HAL_ENCRYPT_TYPE_OPEN;
- }
- spin_unlock_bh(&ar->ab->base_lock);
-
- err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc);
- if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap)
- is_decrypted = ath12k_dp_rx_h_is_decrypted(ab, rx_desc);
-
- /* Clear per-MPDU flags while leaving per-PPDU flags intact */
- rx_status->flag &= ~(RX_FLAG_FAILED_FCS_CRC |
- RX_FLAG_MMIC_ERROR |
- RX_FLAG_DECRYPTED |
- RX_FLAG_IV_STRIPPED |
- RX_FLAG_MMIC_STRIPPED);
-
- if (err_bitmap & HAL_RX_MPDU_ERR_FCS)
- rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
- if (err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC)
- rx_status->flag |= RX_FLAG_MMIC_ERROR;
-
- if (is_decrypted) {
- rx_status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_MMIC_STRIPPED;
-
- if (rx_info->is_mcbc)
- rx_status->flag |= RX_FLAG_MIC_STRIPPED |
- RX_FLAG_ICV_STRIPPED;
- else
- rx_status->flag |= RX_FLAG_IV_STRIPPED |
- RX_FLAG_PN_VALIDATED;
- }
-
- ath12k_dp_rx_h_csum_offload(msdu, rx_info);
- ath12k_dp_rx_h_undecap(ar, msdu, rx_desc,
- enctype, rx_status, is_decrypted);
-
- if (!is_decrypted || rx_info->is_mcbc)
- return;
-
- if (rx_info->decap_type != DP_RX_DECAP_TYPE_ETHERNET2_DIX) {
- hdr = (void *)msdu->data;
- hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
- }
-}
-
static void ath12k_dp_rx_h_rate(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info)
{
struct ieee80211_supported_band *sband;
@@ -2416,140 +2244,9 @@ bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab,
return false;
}
-static int ath12k_dp_rx_process_msdu(struct ath12k *ar,
- struct sk_buff *msdu,
- struct sk_buff_head *msdu_list,
- struct ath12k_dp_rx_info *rx_info)
-{
- struct ath12k_base *ab = ar->ab;
- struct hal_rx_desc *rx_desc, *lrx_desc;
- struct ath12k_skb_rxcb *rxcb;
- struct sk_buff *last_buf;
- u8 l3_pad_bytes;
- u16 msdu_len;
- int ret;
- u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz;
-
- last_buf = ath12k_dp_rx_get_msdu_last_buf(msdu_list, msdu);
- if (!last_buf) {
- ath12k_warn(ab,
- "No valid Rx buffer to access MSDU_END tlv\n");
- ret = -EIO;
- goto free_out;
- }
-
- rx_desc = (struct hal_rx_desc *)msdu->data;
- lrx_desc = (struct hal_rx_desc *)last_buf->data;
- if (!ath12k_dp_rx_h_msdu_done(ab, lrx_desc)) {
- ath12k_warn(ab, "msdu_done bit in msdu_end is not set\n");
- ret = -EIO;
- goto free_out;
- }
-
- rxcb = ATH12K_SKB_RXCB(msdu);
- rxcb->rx_desc = rx_desc;
- msdu_len = ath12k_dp_rx_h_msdu_len(ab, lrx_desc);
- l3_pad_bytes = ath12k_dp_rx_h_l3pad(ab, lrx_desc);
-
- if (rxcb->is_frag) {
- skb_pull(msdu, hal_rx_desc_sz);
- } else if (!rxcb->is_continuation) {
- if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) {
- ret = -EINVAL;
- ath12k_warn(ab, "invalid msdu len %u\n", msdu_len);
- ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", rx_desc,
- sizeof(*rx_desc));
- goto free_out;
- }
- skb_put(msdu, hal_rx_desc_sz + l3_pad_bytes + msdu_len);
- skb_pull(msdu, hal_rx_desc_sz + l3_pad_bytes);
- } else {
- ret = ath12k_dp_rx_msdu_coalesce(ar, msdu_list,
- msdu, last_buf,
- l3_pad_bytes, msdu_len);
- if (ret) {
- ath12k_warn(ab,
- "failed to coalesce msdu rx buffer%d\n", ret);
- goto free_out;
- }
- }
-
- if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu))) {
- ret = -EINVAL;
- goto free_out;
- }
-
- ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info);
- ath12k_dp_rx_h_ppdu(ar, rx_info);
- ath12k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_info);
-
- rx_info->rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED;
-
- return 0;
-
-free_out:
- return ret;
-}
-
-static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab,
- struct napi_struct *napi,
- struct sk_buff_head *msdu_list,
- int ring_id)
-{
- struct ath12k_hw_group *ag = ab->ag;
- struct ieee80211_rx_status rx_status = {};
- struct ath12k_skb_rxcb *rxcb;
- struct sk_buff *msdu;
- struct ath12k *ar;
- struct ath12k_hw_link *hw_links = ag->hw_links;
- struct ath12k_base *partner_ab;
- struct ath12k_dp_rx_info rx_info;
- u8 hw_link_id, pdev_id;
- int ret;
-
- if (skb_queue_empty(msdu_list))
- return;
-
- rx_info.addr2_present = false;
- rx_info.rx_status = &rx_status;
-
- rcu_read_lock();
-
- while ((msdu = __skb_dequeue(msdu_list))) {
- rxcb = ATH12K_SKB_RXCB(msdu);
- hw_link_id = rxcb->hw_link_id;
- partner_ab = ath12k_ag_to_ab(ag,
- hw_links[hw_link_id].device_id);
- pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params,
- hw_links[hw_link_id].pdev_idx);
- ar = partner_ab->pdevs[pdev_id].ar;
- if (!rcu_dereference(partner_ab->pdevs_active[pdev_id])) {
- dev_kfree_skb_any(msdu);
- continue;
- }
-
- if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) {
- dev_kfree_skb_any(msdu);
- continue;
- }
-
- ret = ath12k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_info);
- if (ret) {
- ath12k_dbg(ab, ATH12K_DBG_DATA,
- "Unable to process msdu %d", ret);
- dev_kfree_skb_any(msdu);
- continue;
- }
-
- ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info);
- }
-
- rcu_read_unlock();
-}
-
-static u16 ath12k_dp_rx_get_peer_id(struct ath12k_base *ab,
- enum ath12k_peer_metadata_version ver,
- __le32 peer_metadata)
+u16 ath12k_dp_rx_get_peer_id(struct ath12k_base *ab,
+ enum ath12k_peer_metadata_version ver,
+ __le32 peer_metadata)
{
switch (ver) {
default:
@@ -2570,166 +2267,6 @@ static u16 ath12k_dp_rx_get_peer_id(struct ath12k_base *ab,
}
}
-int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id,
- struct napi_struct *napi, int budget)
-{
- struct ath12k_hw_group *ag = ab->ag;
- struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES];
- struct ath12k_hw_link *hw_links = ag->hw_links;
- int num_buffs_reaped[ATH12K_MAX_DEVICES] = {};
- struct ath12k_rx_desc_info *desc_info;
- struct ath12k_dp *dp = &ab->dp;
- struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;
- struct hal_reo_dest_ring *desc;
- struct ath12k_base *partner_ab;
- struct sk_buff_head msdu_list;
- struct ath12k_skb_rxcb *rxcb;
- int total_msdu_reaped = 0;
- u8 hw_link_id, device_id;
- struct hal_srng *srng;
- struct sk_buff *msdu;
- bool done = false;
- u64 desc_va;
-
- __skb_queue_head_init(&msdu_list);
-
- for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++)
- INIT_LIST_HEAD(&rx_desc_used_list[device_id]);
-
- srng = &ab->hal.srng_list[dp->reo_dst_ring[ring_id].ring_id];
-
- spin_lock_bh(&srng->lock);
-
-try_again:
- ath12k_hal_srng_access_begin(ab, srng);
-
- while ((desc = ath12k_hal_srng_dst_get_next_entry(ab, srng))) {
- struct rx_mpdu_desc *mpdu_info;
- struct rx_msdu_desc *msdu_info;
- enum hal_reo_dest_ring_push_reason push_reason;
- u32 cookie;
-
- cookie = le32_get_bits(desc->buf_addr_info.info1,
- BUFFER_ADDR_INFO1_SW_COOKIE);
-
- hw_link_id = le32_get_bits(desc->info0,
- HAL_REO_DEST_RING_INFO0_SRC_LINK_ID);
-
- desc_va = ((u64)le32_to_cpu(desc->buf_va_hi) << 32 |
- le32_to_cpu(desc->buf_va_lo));
- desc_info = (struct ath12k_rx_desc_info *)((unsigned long)desc_va);
-
- device_id = hw_links[hw_link_id].device_id;
- partner_ab = ath12k_ag_to_ab(ag, device_id);
- if (unlikely(!partner_ab)) {
- if (desc_info->skb) {
- dev_kfree_skb_any(desc_info->skb);
- desc_info->skb = NULL;
- }
-
- continue;
- }
-
- /* retry manual desc retrieval */
- if (!desc_info) {
- desc_info = ath12k_dp_get_rx_desc(partner_ab, cookie);
- if (!desc_info) {
- ath12k_warn(partner_ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n",
- cookie);
- continue;
- }
- }
-
- if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC)
- ath12k_warn(ab, "Check HW CC implementation");
-
- msdu = desc_info->skb;
- desc_info->skb = NULL;
-
- list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]);
-
- rxcb = ATH12K_SKB_RXCB(msdu);
- dma_unmap_single(partner_ab->dev, rxcb->paddr,
- msdu->len + skb_tailroom(msdu),
- DMA_FROM_DEVICE);
-
- num_buffs_reaped[device_id]++;
- ab->device_stats.reo_rx[ring_id][ab->device_id]++;
-
- push_reason = le32_get_bits(desc->info0,
- HAL_REO_DEST_RING_INFO0_PUSH_REASON);
- if (push_reason !=
- HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) {
- dev_kfree_skb_any(msdu);
- ab->device_stats.hal_reo_error[ring_id]++;
- continue;
- }
-
- msdu_info = &desc->rx_msdu_info;
- mpdu_info = &desc->rx_mpdu_info;
-
- rxcb->is_first_msdu = !!(le32_to_cpu(msdu_info->info0) &
- RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU);
- rxcb->is_last_msdu = !!(le32_to_cpu(msdu_info->info0) &
- RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU);
- rxcb->is_continuation = !!(le32_to_cpu(msdu_info->info0) &
- RX_MSDU_DESC_INFO0_MSDU_CONTINUATION);
- rxcb->hw_link_id = hw_link_id;
- rxcb->peer_id = ath12k_dp_rx_get_peer_id(ab, dp->peer_metadata_ver,
- mpdu_info->peer_meta_data);
- rxcb->tid = le32_get_bits(mpdu_info->info0,
- RX_MPDU_DESC_INFO0_TID);
-
- __skb_queue_tail(&msdu_list, msdu);
-
- if (!rxcb->is_continuation) {
- total_msdu_reaped++;
- done = true;
- } else {
- done = false;
- }
-
- if (total_msdu_reaped >= budget)
- break;
- }
-
- /* Hw might have updated the head pointer after we cached it.
- * In this case, even though there are entries in the ring we'll
- * get rx_desc NULL. Give the read another try with updated cached
- * head pointer so that we can reap complete MPDU in the current
- * rx processing.
- */
- if (!done && ath12k_hal_srng_dst_num_free(ab, srng, true)) {
- ath12k_hal_srng_access_end(ab, srng);
- goto try_again;
- }
-
- ath12k_hal_srng_access_end(ab, srng);
-
- spin_unlock_bh(&srng->lock);
-
- if (!total_msdu_reaped)
- goto exit;
-
- for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) {
- if (!num_buffs_reaped[device_id])
- continue;
-
- partner_ab = ath12k_ag_to_ab(ag, device_id);
- rx_ring = &partner_ab->dp.rx_refill_buf_ring;
-
- ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring,
- &rx_desc_used_list[device_id],
- num_buffs_reaped[device_id]);
- }
-
- ath12k_dp_rx_process_received_packets(ab, napi, &msdu_list,
- ring_id);
-
-exit:
- return total_msdu_reaped;
-}
-
static void ath12k_dp_rx_frag_timer(struct timer_list *timer)
{
struct ath12k_dp_rx_tid *rx_tid = timer_container_of(rx_tid, timer,
@@ -2787,9 +2324,9 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev
return 0;
}
-static int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key,
- struct ieee80211_hdr *hdr, u8 *data,
- size_t data_len, u8 *mic)
+int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key,
+ struct ieee80211_hdr *hdr, u8 *data,
+ size_t data_len, u8 *mic)
{
SHASH_DESC_ON_STACK(desc, tfm);
u8 mic_hdr[16] = {};
@@ -2828,70 +2365,6 @@ static int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key,
return ret;
}
-int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer,
- struct sk_buff *msdu)
-{
- struct ath12k_base *ab = ar->ab;
- struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data;
- struct ieee80211_rx_status *rxs = IEEE80211_SKB_RXCB(msdu);
- struct ieee80211_key_conf *key_conf;
- struct ieee80211_hdr *hdr;
- struct ath12k_dp_rx_info rx_info;
- u8 mic[IEEE80211_CCMP_MIC_LEN];
- int head_len, tail_len, ret;
- size_t data_len;
- u32 hdr_len, hal_rx_desc_sz = ar->ab->hal.hal_desc_sz;
- u8 *key, *data;
- u8 key_idx;
-
- if (ath12k_dp_rx_h_enctype(ab, rx_desc) != HAL_ENCRYPT_TYPE_TKIP_MIC)
- return 0;
-
- rx_info.addr2_present = false;
- rx_info.rx_status = rxs;
-
- hdr = (struct ieee80211_hdr *)(msdu->data + hal_rx_desc_sz);
- hdr_len = ieee80211_hdrlen(hdr->frame_control);
- head_len = hdr_len + hal_rx_desc_sz + IEEE80211_TKIP_IV_LEN;
- tail_len = IEEE80211_CCMP_MIC_LEN + IEEE80211_TKIP_ICV_LEN + FCS_LEN;
-
- if (!is_multicast_ether_addr(hdr->addr1))
- key_idx = peer->ucast_keyidx;
- else
- key_idx = peer->mcast_keyidx;
-
- key_conf = peer->keys[key_idx];
-
- data = msdu->data + head_len;
- data_len = msdu->len - head_len - tail_len;
- key = &key_conf->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];
-
- ret = ath12k_dp_rx_h_michael_mic(peer->tfm_mmic, key, hdr, data, data_len, mic);
- if (ret || memcmp(mic, data + data_len, IEEE80211_CCMP_MIC_LEN))
- goto mic_fail;
-
- return 0;
-
-mic_fail:
- (ATH12K_SKB_RXCB(msdu))->is_first_msdu = true;
- (ATH12K_SKB_RXCB(msdu))->is_last_msdu = true;
-
- ath12k_dp_rx_h_fetch_info(ab, rx_desc, &rx_info);
-
- rxs->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_MMIC_STRIPPED |
- RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED;
- skb_pull(msdu, hal_rx_desc_sz);
-
- if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu)))
- return -EINVAL;
-
- ath12k_dp_rx_h_ppdu(ar, &rx_info);
- ath12k_dp_rx_h_undecap(ar, msdu, rx_desc,
- HAL_ENCRYPT_TYPE_TKIP_MIC, rxs, true);
- ieee80211_rx(ath12k_ar_to_hw(ar), msdu);
- return -EINVAL;
-}
-
void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu,
enum hal_encrypt_type enctype, u32 flags)
{
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h
index dc0b1078213c..5fc9adeb49bd 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.h
@@ -6,6 +6,7 @@
#ifndef ATH12K_DP_RX_H
#define ATH12K_DP_RX_H
+#include <crypto/hash.h>
#include "core.h"
#include "wifi7/hal_rx_desc.h"
#include "debug.h"
@@ -353,20 +354,20 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi,
bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab,
struct hal_rx_desc *rx_desc,
struct sk_buff *msdu);
-void ath12k_dp_rx_h_mpdu(struct ath12k *ar,
- struct sk_buff *msdu,
- struct hal_rx_desc *rx_desc,
- struct ath12k_dp_rx_info *rx_info);
u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb);
void ath12k_dp_rx_h_sort_frags(struct ath12k_base *ab,
struct sk_buff_head *frag_list,
struct sk_buff *cur_frag);
void ath12k_dp_rx_h_undecap_frag(struct ath12k *ar, struct sk_buff *msdu,
enum hal_encrypt_type enctype, u32 flags);
-int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer,
- struct sk_buff *msdu);
void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid,
bool rel_link_desc);
+int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key,
+ struct ieee80211_hdr *hdr, u8 *data,
+ size_t data_len, u8 *mic);
+u16 ath12k_dp_rx_get_peer_id(struct ath12k_base *ab,
+ enum ath12k_peer_metadata_version ver,
+ __le32 peer_metadata);
int ath12k_dp_rx_ampdu_start(struct ath12k *ar,
struct ieee80211_ampdu_params *params,
u8 link_id);
@@ -394,9 +395,6 @@ int ath12k_dp_rx_pdev_alloc(struct ath12k_base *ab, int pdev_idx);
void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int pdev_idx);
void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab);
void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab);
-int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id,
- struct napi_struct *napi,
- int budget);
int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab,
struct dp_rxdma_ring *rx_ring,
struct list_head *used_list,
@@ -431,4 +429,6 @@ int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab,
bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab,
struct hal_rx_desc *rx_desc);
void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info);
+struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list,
+ struct sk_buff *first);
#endif /* ATH12K_DP_RX_H */
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
index c2b108a1005b..b55cfb926571 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
@@ -8,6 +8,469 @@
#include "../dp_tx.h"
#include "../peer.h"
+static void ath12k_dp_rx_h_csum_offload(struct sk_buff *msdu,
+ struct ath12k_dp_rx_info *rx_info)
+{
+ msdu->ip_summed = (rx_info->ip_csum_fail || rx_info->l4_csum_fail) ?
+ CHECKSUM_NONE : CHECKSUM_UNNECESSARY;
+}
+
+static void ath12k_dp_rx_h_mpdu(struct ath12k *ar,
+ struct sk_buff *msdu,
+ struct hal_rx_desc *rx_desc,
+ struct ath12k_dp_rx_info *rx_info)
+{
+ struct ath12k_base *ab = ar->ab;
+ struct ath12k_skb_rxcb *rxcb;
+ enum hal_encrypt_type enctype;
+ bool is_decrypted = false;
+ struct ieee80211_hdr *hdr;
+ struct ath12k_peer *peer;
+ struct ieee80211_rx_status *rx_status = rx_info->rx_status;
+ u32 err_bitmap;
+
+ /* PN for multicast packets will be checked in mac80211 */
+ rxcb = ATH12K_SKB_RXCB(msdu);
+ rxcb->is_mcbc = rx_info->is_mcbc;
+
+ if (rxcb->is_mcbc)
+ rxcb->peer_id = rx_info->peer_id;
+
+ spin_lock_bh(&ar->ab->base_lock);
+ peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu, rx_info);
+ if (peer) {
+ /* resetting mcbc bit because mcbc packets are unicast
+ * packets only for AP as STA sends unicast packets.
+ */
+ rxcb->is_mcbc = rxcb->is_mcbc && !peer->ucast_ra_only;
+
+ if (rxcb->is_mcbc)
+ enctype = peer->sec_type_grp;
+ else
+ enctype = peer->sec_type;
+ } else {
+ enctype = HAL_ENCRYPT_TYPE_OPEN;
+ }
+ spin_unlock_bh(&ar->ab->base_lock);
+
+ err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc);
+ if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap)
+ is_decrypted = ath12k_dp_rx_h_is_decrypted(ab, rx_desc);
+
+ /* Clear per-MPDU flags while leaving per-PPDU flags intact */
+ rx_status->flag &= ~(RX_FLAG_FAILED_FCS_CRC |
+ RX_FLAG_MMIC_ERROR |
+ RX_FLAG_DECRYPTED |
+ RX_FLAG_IV_STRIPPED |
+ RX_FLAG_MMIC_STRIPPED);
+
+ if (err_bitmap & HAL_RX_MPDU_ERR_FCS)
+ rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+ if (err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC)
+ rx_status->flag |= RX_FLAG_MMIC_ERROR;
+
+ if (is_decrypted) {
+ rx_status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_MMIC_STRIPPED;
+
+ if (rx_info->is_mcbc)
+ rx_status->flag |= RX_FLAG_MIC_STRIPPED |
+ RX_FLAG_ICV_STRIPPED;
+ else
+ rx_status->flag |= RX_FLAG_IV_STRIPPED |
+ RX_FLAG_PN_VALIDATED;
+ }
+
+ ath12k_dp_rx_h_csum_offload(msdu, rx_info);
+ ath12k_dp_rx_h_undecap(ar, msdu, rx_desc,
+ enctype, rx_status, is_decrypted);
+
+ if (!is_decrypted || rx_info->is_mcbc)
+ return;
+
+ if (rx_info->decap_type != DP_RX_DECAP_TYPE_ETHERNET2_DIX) {
+ hdr = (void *)msdu->data;
+ hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+ }
+}
+
+static int ath12k_dp_rx_msdu_coalesce(struct ath12k *ar,
+ struct sk_buff_head *msdu_list,
+ struct sk_buff *first, struct sk_buff *last,
+ u8 l3pad_bytes, int msdu_len)
+{
+ struct ath12k_base *ab = ar->ab;
+ struct sk_buff *skb;
+ struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(first);
+ int buf_first_hdr_len, buf_first_len;
+ struct hal_rx_desc *ldesc;
+ int space_extra, rem_len, buf_len;
+ u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz;
+ bool is_continuation;
+
+ /* As the msdu is spread across multiple rx buffers,
+ * find the offset to the start of msdu for computing
+ * the length of the msdu in the first buffer.
+ */
+ buf_first_hdr_len = hal_rx_desc_sz + l3pad_bytes;
+ buf_first_len = DP_RX_BUFFER_SIZE - buf_first_hdr_len;
+
+ if (WARN_ON_ONCE(msdu_len <= buf_first_len)) {
+ skb_put(first, buf_first_hdr_len + msdu_len);
+ skb_pull(first, buf_first_hdr_len);
+ return 0;
+ }
+
+ ldesc = (struct hal_rx_desc *)last->data;
+ rxcb->is_first_msdu = ath12k_dp_rx_h_first_msdu(ab, ldesc);
+ rxcb->is_last_msdu = ath12k_dp_rx_h_last_msdu(ab, ldesc);
+
+ /* MSDU spans over multiple buffers because the length of the MSDU
+ * exceeds DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE. So assume the data
+ * in the first buf is of length DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE.
+ */
+ skb_put(first, DP_RX_BUFFER_SIZE);
+ skb_pull(first, buf_first_hdr_len);
+
+ /* When an MSDU spread over multiple buffers MSDU_END
+ * tlvs are valid only in the last buffer. Copy those tlvs.
+ */
+ ath12k_dp_rx_desc_end_tlv_copy(ab, rxcb->rx_desc, ldesc);
+
+ space_extra = msdu_len - (buf_first_len + skb_tailroom(first));
+ if (space_extra > 0 &&
+ (pskb_expand_head(first, 0, space_extra, GFP_ATOMIC) < 0)) {
+ /* Free up all buffers of the MSDU */
+ while ((skb = __skb_dequeue(msdu_list)) != NULL) {
+ rxcb = ATH12K_SKB_RXCB(skb);
+ if (!rxcb->is_continuation) {
+ dev_kfree_skb_any(skb);
+ break;
+ }
+ dev_kfree_skb_any(skb);
+ }
+ return -ENOMEM;
+ }
+
+ rem_len = msdu_len - buf_first_len;
+ while ((skb = __skb_dequeue(msdu_list)) != NULL && rem_len > 0) {
+ rxcb = ATH12K_SKB_RXCB(skb);
+ is_continuation = rxcb->is_continuation;
+ if (is_continuation)
+ buf_len = DP_RX_BUFFER_SIZE - hal_rx_desc_sz;
+ else
+ buf_len = rem_len;
+
+ if (buf_len > (DP_RX_BUFFER_SIZE - hal_rx_desc_sz)) {
+ WARN_ON_ONCE(1);
+ dev_kfree_skb_any(skb);
+ return -EINVAL;
+ }
+
+ skb_put(skb, buf_len + hal_rx_desc_sz);
+ skb_pull(skb, hal_rx_desc_sz);
+ skb_copy_from_linear_data(skb, skb_put(first, buf_len),
+ buf_len);
+ dev_kfree_skb_any(skb);
+
+ rem_len -= buf_len;
+ if (!is_continuation)
+ break;
+ }
+
+ return 0;
+}
+
+static int ath12k_dp_rx_process_msdu(struct ath12k *ar,
+ struct sk_buff *msdu,
+ struct sk_buff_head *msdu_list,
+ struct ath12k_dp_rx_info *rx_info)
+{
+ struct ath12k_base *ab = ar->ab;
+ struct hal_rx_desc *rx_desc, *lrx_desc;
+ struct ath12k_skb_rxcb *rxcb;
+ struct sk_buff *last_buf;
+ u8 l3_pad_bytes;
+ u16 msdu_len;
+ int ret;
+ u32 hal_rx_desc_sz = ar->ab->hal.hal_desc_sz;
+
+ last_buf = ath12k_dp_rx_get_msdu_last_buf(msdu_list, msdu);
+ if (!last_buf) {
+ ath12k_warn(ab,
+ "No valid Rx buffer to access MSDU_END tlv\n");
+ ret = -EIO;
+ goto free_out;
+ }
+
+ rx_desc = (struct hal_rx_desc *)msdu->data;
+ lrx_desc = (struct hal_rx_desc *)last_buf->data;
+ if (!ath12k_dp_rx_h_msdu_done(ab, lrx_desc)) {
+ ath12k_warn(ab, "msdu_done bit in msdu_end is not set\n");
+ ret = -EIO;
+ goto free_out;
+ }
+
+ rxcb = ATH12K_SKB_RXCB(msdu);
+ rxcb->rx_desc = rx_desc;
+ msdu_len = ath12k_dp_rx_h_msdu_len(ab, lrx_desc);
+ l3_pad_bytes = ath12k_dp_rx_h_l3pad(ab, lrx_desc);
+
+ if (rxcb->is_frag) {
+ skb_pull(msdu, hal_rx_desc_sz);
+ } else if (!rxcb->is_continuation) {
+ if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) {
+ ret = -EINVAL;
+ ath12k_warn(ab, "invalid msdu len %u\n", msdu_len);
+ ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", rx_desc,
+ sizeof(*rx_desc));
+ goto free_out;
+ }
+ skb_put(msdu, hal_rx_desc_sz + l3_pad_bytes + msdu_len);
+ skb_pull(msdu, hal_rx_desc_sz + l3_pad_bytes);
+ } else {
+ ret = ath12k_dp_rx_msdu_coalesce(ar, msdu_list,
+ msdu, last_buf,
+ l3_pad_bytes, msdu_len);
+ if (ret) {
+ ath12k_warn(ab,
+ "failed to coalesce msdu rx buffer%d\n", ret);
+ goto free_out;
+ }
+ }
+
+ if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu))) {
+ ret = -EINVAL;
+ goto free_out;
+ }
+
+ ath12k_dp_rx_h_fetch_info(ab, rx_desc, rx_info);
+ ath12k_dp_rx_h_ppdu(ar, rx_info);
+ ath12k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_info);
+
+ rx_info->rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED;
+
+ return 0;
+
+free_out:
+ return ret;
+}
+
+static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab,
+ struct napi_struct *napi,
+ struct sk_buff_head *msdu_list,
+ int ring_id)
+{
+ struct ath12k_hw_group *ag = ab->ag;
+ struct ieee80211_rx_status rx_status = {};
+ struct ath12k_skb_rxcb *rxcb;
+ struct sk_buff *msdu;
+ struct ath12k *ar;
+ struct ath12k_hw_link *hw_links = ag->hw_links;
+ struct ath12k_base *partner_ab;
+ struct ath12k_dp_rx_info rx_info;
+ u8 hw_link_id, pdev_id;
+ int ret;
+
+ if (skb_queue_empty(msdu_list))
+ return;
+
+ rx_info.addr2_present = false;
+ rx_info.rx_status = &rx_status;
+
+ rcu_read_lock();
+
+ while ((msdu = __skb_dequeue(msdu_list))) {
+ rxcb = ATH12K_SKB_RXCB(msdu);
+ hw_link_id = rxcb->hw_link_id;
+ partner_ab = ath12k_ag_to_ab(ag,
+ hw_links[hw_link_id].device_id);
+ pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params,
+ hw_links[hw_link_id].pdev_idx);
+ ar = partner_ab->pdevs[pdev_id].ar;
+ if (!rcu_dereference(partner_ab->pdevs_active[pdev_id])) {
+ dev_kfree_skb_any(msdu);
+ continue;
+ }
+
+ if (test_bit(ATH12K_FLAG_CAC_RUNNING, &ar->dev_flags)) {
+ dev_kfree_skb_any(msdu);
+ continue;
+ }
+
+ ret = ath12k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_info);
+ if (ret) {
+ ath12k_dbg(ab, ATH12K_DBG_DATA,
+ "Unable to process msdu %d", ret);
+ dev_kfree_skb_any(msdu);
+ continue;
+ }
+
+ ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info);
+ }
+
+ rcu_read_unlock();
+}
+
+int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id,
+ struct napi_struct *napi, int budget)
+{
+ struct ath12k_hw_group *ag = ab->ag;
+ struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES];
+ struct ath12k_hw_link *hw_links = ag->hw_links;
+ int num_buffs_reaped[ATH12K_MAX_DEVICES] = {};
+ struct ath12k_rx_desc_info *desc_info;
+ struct ath12k_dp *dp = &ab->dp;
+ struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;
+ struct hal_reo_dest_ring *desc;
+ struct ath12k_base *partner_ab;
+ struct sk_buff_head msdu_list;
+ struct ath12k_skb_rxcb *rxcb;
+ int total_msdu_reaped = 0;
+ u8 hw_link_id, device_id;
+ struct hal_srng *srng;
+ struct sk_buff *msdu;
+ bool done = false;
+ u64 desc_va;
+
+ __skb_queue_head_init(&msdu_list);
+
+ for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++)
+ INIT_LIST_HEAD(&rx_desc_used_list[device_id]);
+
+ srng = &ab->hal.srng_list[dp->reo_dst_ring[ring_id].ring_id];
+
+ spin_lock_bh(&srng->lock);
+
+try_again:
+ ath12k_hal_srng_access_begin(ab, srng);
+
+ while ((desc = ath12k_hal_srng_dst_get_next_entry(ab, srng))) {
+ struct rx_mpdu_desc *mpdu_info;
+ struct rx_msdu_desc *msdu_info;
+ enum hal_reo_dest_ring_push_reason push_reason;
+ u32 cookie;
+
+ cookie = le32_get_bits(desc->buf_addr_info.info1,
+ BUFFER_ADDR_INFO1_SW_COOKIE);
+
+ hw_link_id = le32_get_bits(desc->info0,
+ HAL_REO_DEST_RING_INFO0_SRC_LINK_ID);
+
+ desc_va = ((u64)le32_to_cpu(desc->buf_va_hi) << 32 |
+ le32_to_cpu(desc->buf_va_lo));
+ desc_info = (struct ath12k_rx_desc_info *)((unsigned long)desc_va);
+
+ device_id = hw_links[hw_link_id].device_id;
+ partner_ab = ath12k_ag_to_ab(ag, device_id);
+ if (unlikely(!partner_ab)) {
+ if (desc_info->skb) {
+ dev_kfree_skb_any(desc_info->skb);
+ desc_info->skb = NULL;
+ }
+
+ continue;
+ }
+
+ /* retry manual desc retrieval */
+ if (!desc_info) {
+ desc_info = ath12k_dp_get_rx_desc(partner_ab, cookie);
+ if (!desc_info) {
+ ath12k_warn(partner_ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n",
+ cookie);
+ continue;
+ }
+ }
+
+ if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC)
+ ath12k_warn(ab, "Check HW CC implementation");
+
+ msdu = desc_info->skb;
+ desc_info->skb = NULL;
+
+ list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]);
+
+ rxcb = ATH12K_SKB_RXCB(msdu);
+ dma_unmap_single(partner_ab->dev, rxcb->paddr,
+ msdu->len + skb_tailroom(msdu),
+ DMA_FROM_DEVICE);
+
+ num_buffs_reaped[device_id]++;
+ ab->device_stats.reo_rx[ring_id][ab->device_id]++;
+
+ push_reason = le32_get_bits(desc->info0,
+ HAL_REO_DEST_RING_INFO0_PUSH_REASON);
+ if (push_reason !=
+ HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) {
+ dev_kfree_skb_any(msdu);
+ ab->device_stats.hal_reo_error[ring_id]++;
+ continue;
+ }
+
+ msdu_info = &desc->rx_msdu_info;
+ mpdu_info = &desc->rx_mpdu_info;
+
+ rxcb->is_first_msdu = !!(le32_to_cpu(msdu_info->info0) &
+ RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU);
+ rxcb->is_last_msdu = !!(le32_to_cpu(msdu_info->info0) &
+ RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU);
+ rxcb->is_continuation = !!(le32_to_cpu(msdu_info->info0) &
+ RX_MSDU_DESC_INFO0_MSDU_CONTINUATION);
+ rxcb->hw_link_id = hw_link_id;
+ rxcb->peer_id = ath12k_dp_rx_get_peer_id(ab, dp->peer_metadata_ver,
+ mpdu_info->peer_meta_data);
+ rxcb->tid = le32_get_bits(mpdu_info->info0,
+ RX_MPDU_DESC_INFO0_TID);
+
+ __skb_queue_tail(&msdu_list, msdu);
+
+ if (!rxcb->is_continuation) {
+ total_msdu_reaped++;
+ done = true;
+ } else {
+ done = false;
+ }
+
+ if (total_msdu_reaped >= budget)
+ break;
+ }
+
+ /* Hw might have updated the head pointer after we cached it.
+ * In this case, even though there are entries in the ring we'll
+ * get rx_desc NULL. Give the read another try with updated cached
+ * head pointer so that we can reap complete MPDU in the current
+ * rx processing.
+ */
+ if (!done && ath12k_hal_srng_dst_num_free(ab, srng, true)) {
+ ath12k_hal_srng_access_end(ab, srng);
+ goto try_again;
+ }
+
+ ath12k_hal_srng_access_end(ab, srng);
+
+ spin_unlock_bh(&srng->lock);
+
+ if (!total_msdu_reaped)
+ goto exit;
+
+ for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) {
+ if (!num_buffs_reaped[device_id])
+ continue;
+
+ partner_ab = ath12k_ag_to_ab(ag, device_id);
+ rx_ring = &partner_ab->dp.rx_refill_buf_ring;
+
+ ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring,
+ &rx_desc_used_list[device_id],
+ num_buffs_reaped[device_id]);
+ }
+
+ ath12k_dp_rx_process_received_packets(ab, napi, &msdu_list,
+ ring_id);
+
+exit:
+ return total_msdu_reaped;
+}
+
static bool
ath12k_dp_rx_h_defrag_validate_incr_pn(struct ath12k *ar, struct ath12k_dp_rx_tid *rx_tid)
{
@@ -188,6 +651,70 @@ static int ath12k_dp_rx_h_defrag_reo_reinject(struct ath12k *ar,
return ret;
}
+static int ath12k_dp_rx_h_verify_tkip_mic(struct ath12k *ar, struct ath12k_peer *peer,
+ struct sk_buff *msdu)
+{
+ struct ath12k_base *ab = ar->ab;
+ struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data;
+ struct ieee80211_rx_status *rxs = IEEE80211_SKB_RXCB(msdu);
+ struct ieee80211_key_conf *key_conf;
+ struct ieee80211_hdr *hdr;
+ struct ath12k_dp_rx_info rx_info;
+ u8 mic[IEEE80211_CCMP_MIC_LEN];
+ int head_len, tail_len, ret;
+ size_t data_len;
+ u32 hdr_len, hal_rx_desc_sz = ar->ab->hal.hal_desc_sz;
+ u8 *key, *data;
+ u8 key_idx;
+
+ if (ath12k_dp_rx_h_enctype(ab, rx_desc) != HAL_ENCRYPT_TYPE_TKIP_MIC)
+ return 0;
+
+ rx_info.addr2_present = false;
+ rx_info.rx_status = rxs;
+
+ hdr = (struct ieee80211_hdr *)(msdu->data + hal_rx_desc_sz);
+ hdr_len = ieee80211_hdrlen(hdr->frame_control);
+ head_len = hdr_len + hal_rx_desc_sz + IEEE80211_TKIP_IV_LEN;
+ tail_len = IEEE80211_CCMP_MIC_LEN + IEEE80211_TKIP_ICV_LEN + FCS_LEN;
+
+ if (!is_multicast_ether_addr(hdr->addr1))
+ key_idx = peer->ucast_keyidx;
+ else
+ key_idx = peer->mcast_keyidx;
+
+ key_conf = peer->keys[key_idx];
+
+ data = msdu->data + head_len;
+ data_len = msdu->len - head_len - tail_len;
+ key = &key_conf->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];
+
+ ret = ath12k_dp_rx_h_michael_mic(peer->tfm_mmic, key, hdr, data, data_len, mic);
+ if (ret || memcmp(mic, data + data_len, IEEE80211_CCMP_MIC_LEN))
+ goto mic_fail;
+
+ return 0;
+
+mic_fail:
+ (ATH12K_SKB_RXCB(msdu))->is_first_msdu = true;
+ (ATH12K_SKB_RXCB(msdu))->is_last_msdu = true;
+
+ ath12k_dp_rx_h_fetch_info(ab, rx_desc, &rx_info);
+
+ rxs->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_MMIC_STRIPPED |
+ RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED;
+ skb_pull(msdu, hal_rx_desc_sz);
+
+ if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(ab, rx_desc, msdu)))
+ return -EINVAL;
+
+ ath12k_dp_rx_h_ppdu(ar, &rx_info);
+ ath12k_dp_rx_h_undecap(ar, msdu, rx_desc,
+ HAL_ENCRYPT_TYPE_TKIP_MIC, rxs, true);
+ ieee80211_rx(ath12k_ar_to_hw(ar), msdu);
+ return -EINVAL;
+}
+
static int ath12k_dp_rx_h_defrag(struct ath12k *ar,
struct ath12k_peer *peer,
struct ath12k_dp_rx_tid *rx_tid,
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
index 9c2114c62ba2..fa44e454cee6 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
@@ -13,6 +13,9 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
struct napi_struct *napi, int budget);
int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
int budget);
+int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id,
+ struct napi_struct *napi,
+ int budget);
int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab);
int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab);
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 11/20] wifi: ath12k: Move srng processing to wifi7 directory
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (9 preceding siblings ...)
2025-08-28 17:35 ` [PATCH ath12k-ng 10/20] wifi: ath12k: Move regular msdu processing " Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 12/20] wifi: ath12k: Separate arch specific part of RX APIs Ripan Deuri
` (11 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Move ath12k_dp_service_srng API and ath12k_dp_rx_process_reo_status
to wifi7 directory.
As srng processing is specific to architecture (wifi7 / wifi8), the
API ath12k_dp_service_srng is being moved to wifi7 directory. The
file wifi7/dp.c can be used to define wifi7-specifi functions that are
common to both tx and rx.
The API which is invoked as part of service srng,
ath12k_dp_rx_process_reo_status is also moved to wifi7 directory, as
the implementation is specific to HW due to the usage of wifi7
specific HAL macros.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/Makefile | 3 +-
drivers/net/wireless/ath/ath12k/ahb.c | 3 +-
drivers/net/wireless/ath/ath12k/dp.c | 124 ----------------
drivers/net/wireless/ath/ath12k/dp.h | 3 -
drivers/net/wireless/ath/ath12k/dp_rx.c | 79 ----------
drivers/net/wireless/ath/ath12k/dp_rx.h | 1 -
drivers/net/wireless/ath/ath12k/pci.c | 3 +-
drivers/net/wireless/ath/ath12k/wifi7/dp.c | 136 ++++++++++++++++++
drivers/net/wireless/ath/ath12k/wifi7/dp.h | 15 ++
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 79 ++++++++++
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 1 +
11 files changed, 237 insertions(+), 210 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp.c
create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp.h
diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile
index d7628bb7af02..ed1f1dba3d3b 100644
--- a/drivers/net/wireless/ath/ath12k/Makefile
+++ b/drivers/net/wireless/ath/ath12k/Makefile
@@ -24,7 +24,8 @@ ath12k-$(CONFIG_ATH12K_AHB) += ahb.o
ath12k-y += wifi7/hal_tx.o \
wifi7/hal_rx.o \
- wifi7/dp_rx.o
+ wifi7/dp_rx.o \
+ wifi7/dp.o
obj-$(CONFIG_ATH12K) += wifi7/
diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c
index efb0ef609dcf..ed61dc7ffa68 100644
--- a/drivers/net/wireless/ath/ath12k/ahb.c
+++ b/drivers/net/wireless/ath/ath12k/ahb.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/dma-mapping.h>
@@ -15,6 +15,7 @@
#include "ahb.h"
#include "debug.h"
#include "hif.h"
+#include "wifi7/dp.h"
#define ATH12K_IRQ_CE0_OFFSET 4
#define ATH12K_MAX_UPDS 1
diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c
index 1b4fab3073b0..d0bdf058633f 100644
--- a/drivers/net/wireless/ath/ath12k/dp.c
+++ b/drivers/net/wireless/ath/ath12k/dp.c
@@ -883,130 +883,6 @@ int ath12k_dp_link_desc_setup(struct ath12k_base *ab,
return ret;
}
-int ath12k_dp_service_srng(struct ath12k_base *ab,
- struct ath12k_ext_irq_grp *irq_grp,
- int budget)
-{
- struct napi_struct *napi = &irq_grp->napi;
- int grp_id = irq_grp->grp_id;
- int work_done = 0;
- int i = 0, j;
- int tot_work_done = 0;
- enum dp_monitor_mode monitor_mode;
- u8 ring_mask;
-
- if (ab->hw_params->ring_mask->tx[grp_id]) {
- i = fls(ab->hw_params->ring_mask->tx[grp_id]) - 1;
- ath12k_dp_tx_completion_handler(ab, i);
- }
-
- if (ab->hw_params->ring_mask->rx_err[grp_id]) {
- work_done = ath12k_dp_rx_process_err(ab, napi, budget);
- budget -= work_done;
- tot_work_done += work_done;
- if (budget <= 0)
- goto done;
- }
-
- if (ab->hw_params->ring_mask->rx_wbm_rel[grp_id]) {
- work_done = ath12k_dp_rx_process_wbm_err(ab,
- napi,
- budget);
- budget -= work_done;
- tot_work_done += work_done;
-
- if (budget <= 0)
- goto done;
- }
-
- if (ab->hw_params->ring_mask->rx[grp_id]) {
- i = fls(ab->hw_params->ring_mask->rx[grp_id]) - 1;
- work_done = ath12k_dp_rx_process(ab, i, napi,
- budget);
- budget -= work_done;
- tot_work_done += work_done;
- if (budget <= 0)
- goto done;
- }
-
- if (ab->hw_params->ring_mask->rx_mon_status[grp_id]) {
- ring_mask = ab->hw_params->ring_mask->rx_mon_status[grp_id];
- for (i = 0; i < ab->num_radios; i++) {
- for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) {
- int id = i * ab->hw_params->num_rxdma_per_pdev + j;
-
- if (ring_mask & BIT(id)) {
- work_done =
- ath12k_dp_mon_process_ring(ab, id, napi, budget,
- 0);
- budget -= work_done;
- tot_work_done += work_done;
- if (budget <= 0)
- goto done;
- }
- }
- }
- }
-
- if (ab->hw_params->ring_mask->rx_mon_dest[grp_id]) {
- monitor_mode = ATH12K_DP_RX_MONITOR_MODE;
- ring_mask = ab->hw_params->ring_mask->rx_mon_dest[grp_id];
- for (i = 0; i < ab->num_radios; i++) {
- for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) {
- int id = i * ab->hw_params->num_rxdma_per_pdev + j;
-
- if (ring_mask & BIT(id)) {
- work_done =
- ath12k_dp_mon_process_ring(ab, id, napi, budget,
- monitor_mode);
- budget -= work_done;
- tot_work_done += work_done;
-
- if (budget <= 0)
- goto done;
- }
- }
- }
- }
-
- if (ab->hw_params->ring_mask->tx_mon_dest[grp_id]) {
- monitor_mode = ATH12K_DP_TX_MONITOR_MODE;
- ring_mask = ab->hw_params->ring_mask->tx_mon_dest[grp_id];
- for (i = 0; i < ab->num_radios; i++) {
- for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) {
- int id = i * ab->hw_params->num_rxdma_per_pdev + j;
-
- if (ring_mask & BIT(id)) {
- work_done =
- ath12k_dp_mon_process_ring(ab, id, napi, budget,
- monitor_mode);
- budget -= work_done;
- tot_work_done += work_done;
-
- if (budget <= 0)
- goto done;
- }
- }
- }
- }
-
- if (ab->hw_params->ring_mask->reo_status[grp_id])
- ath12k_dp_rx_process_reo_status(ab);
-
- if (ab->hw_params->ring_mask->host2rxdma[grp_id]) {
- struct ath12k_dp *dp = &ab->dp;
- struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;
- LIST_HEAD(list);
-
- ath12k_dp_rx_bufs_replenish(ab, rx_ring, &list, 0);
- }
-
- /* TODO: Implement handler for other interrupts */
-
-done:
- return tot_work_done;
-}
-
void ath12k_dp_pdev_free(struct ath12k_base *ab)
{
int i;
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index 6ab74d773261..51af354ee769 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -1936,9 +1936,6 @@ static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr)
memcpy(addr + 4, &addr_h16, ETH_ALEN - 4);
}
-int ath12k_dp_service_srng(struct ath12k_base *ab,
- struct ath12k_ext_irq_grp *irq_grp,
- int budget);
int ath12k_dp_htt_connect(struct ath12k_dp *dp);
void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif);
void ath12k_dp_free(struct ath12k_base *ab);
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index 6809c50ee871..8832ba5f5cdb 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -2444,85 +2444,6 @@ u64 ath12k_dp_rx_h_get_pn(struct ath12k *ar, struct sk_buff *skb)
return pn;
}
-void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab)
-{
- struct ath12k_dp *dp = &ab->dp;
- struct hal_tlv_64_hdr *hdr;
- struct hal_srng *srng;
- struct ath12k_dp_rx_reo_cmd *cmd, *tmp;
- bool found = false;
- u16 tag;
- struct hal_reo_status reo_status;
-
- srng = &ab->hal.srng_list[dp->reo_status_ring.ring_id];
-
- memset(&reo_status, 0, sizeof(reo_status));
-
- spin_lock_bh(&srng->lock);
-
- ath12k_hal_srng_access_begin(ab, srng);
-
- while ((hdr = ath12k_hal_srng_dst_get_next_entry(ab, srng))) {
- tag = le64_get_bits(hdr->tl, HAL_SRNG_TLV_HDR_TAG);
-
- switch (tag) {
- case HAL_REO_GET_QUEUE_STATS_STATUS:
- ath12k_hal_reo_status_queue_stats(ab, hdr,
- &reo_status);
- break;
- case HAL_REO_FLUSH_QUEUE_STATUS:
- ath12k_hal_reo_flush_queue_status(ab, hdr,
- &reo_status);
- break;
- case HAL_REO_FLUSH_CACHE_STATUS:
- ath12k_hal_reo_flush_cache_status(ab, hdr,
- &reo_status);
- break;
- case HAL_REO_UNBLOCK_CACHE_STATUS:
- ath12k_hal_reo_unblk_cache_status(ab, hdr,
- &reo_status);
- break;
- case HAL_REO_FLUSH_TIMEOUT_LIST_STATUS:
- ath12k_hal_reo_flush_timeout_list_status(ab, hdr,
- &reo_status);
- break;
- case HAL_REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS:
- ath12k_hal_reo_desc_thresh_reached_status(ab, hdr,
- &reo_status);
- break;
- case HAL_REO_UPDATE_RX_REO_QUEUE_STATUS:
- ath12k_hal_reo_update_rx_reo_queue_status(ab, hdr,
- &reo_status);
- break;
- default:
- ath12k_warn(ab, "Unknown reo status type %d\n", tag);
- continue;
- }
-
- spin_lock_bh(&dp->reo_cmd_lock);
- list_for_each_entry_safe(cmd, tmp, &dp->reo_cmd_list, list) {
- if (reo_status.uniform_hdr.cmd_num == cmd->cmd_num) {
- found = true;
- list_del(&cmd->list);
- break;
- }
- }
- spin_unlock_bh(&dp->reo_cmd_lock);
-
- if (found) {
- cmd->handler(dp, (void *)&cmd->data,
- reo_status.uniform_hdr.cmd_status);
- kfree(cmd);
- }
-
- found = false;
- }
-
- ath12k_hal_srng_access_end(ab, srng);
-
- spin_unlock_bh(&srng->lock);
-}
-
void ath12k_dp_rx_free(struct ath12k_base *ab)
{
struct ath12k_dp *dp = &ab->dp;
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h
index 5fc9adeb49bd..b3095fd46cd5 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.h
@@ -394,7 +394,6 @@ void ath12k_dp_rx_free(struct ath12k_base *ab);
int ath12k_dp_rx_pdev_alloc(struct ath12k_base *ab, int pdev_idx);
void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int pdev_idx);
void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab);
-void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab);
int ath12k_dp_rx_bufs_replenish(struct ath12k_base *ab,
struct dp_rxdma_ring *rx_ring,
struct list_head *used_list,
diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
index 72bcaab6f542..2de566444719 100644
--- a/drivers/net/wireless/ath/ath12k/pci.c
+++ b/drivers/net/wireless/ath/ath12k/pci.c
@@ -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.
*/
#include <linux/module.h>
@@ -15,6 +15,7 @@
#include "hif.h"
#include "mhi.h"
#include "debug.h"
+#include "wifi7/dp.h"
#define ATH12K_PCI_BAR_NUM 0
#define ATH12K_PCI_DMA_MASK 36
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c
new file mode 100644
index 000000000000..2e7b9bbd3d8e
--- /dev/null
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: BSD-3-Clause-Clear
+/*
+ * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+#include "../core.h"
+#include "../debug.h"
+#include "../dp_rx.h"
+#include "../dp_tx.h"
+#include "../dp_mon.h"
+#include "dp_rx.h"
+#include "dp.h"
+
+int ath12k_dp_service_srng(struct ath12k_base *ab,
+ struct ath12k_ext_irq_grp *irq_grp,
+ int budget)
+{
+ struct napi_struct *napi = &irq_grp->napi;
+ int grp_id = irq_grp->grp_id;
+ int work_done = 0;
+ int i = 0, j;
+ int tot_work_done = 0;
+ enum dp_monitor_mode monitor_mode;
+ u8 ring_mask;
+
+ if (ab->hw_params->ring_mask->tx[grp_id]) {
+ i = fls(ab->hw_params->ring_mask->tx[grp_id]) - 1;
+ ath12k_dp_tx_completion_handler(ab, i);
+ }
+
+ if (ab->hw_params->ring_mask->rx_err[grp_id]) {
+ work_done = ath12k_dp_rx_process_err(ab, napi, budget);
+ budget -= work_done;
+ tot_work_done += work_done;
+ if (budget <= 0)
+ goto done;
+ }
+
+ if (ab->hw_params->ring_mask->rx_wbm_rel[grp_id]) {
+ work_done = ath12k_dp_rx_process_wbm_err(ab,
+ napi,
+ budget);
+ budget -= work_done;
+ tot_work_done += work_done;
+
+ if (budget <= 0)
+ goto done;
+ }
+
+ if (ab->hw_params->ring_mask->rx[grp_id]) {
+ i = fls(ab->hw_params->ring_mask->rx[grp_id]) - 1;
+ work_done = ath12k_dp_rx_process(ab, i, napi,
+ budget);
+ budget -= work_done;
+ tot_work_done += work_done;
+ if (budget <= 0)
+ goto done;
+ }
+
+ if (ab->hw_params->ring_mask->rx_mon_status[grp_id]) {
+ ring_mask = ab->hw_params->ring_mask->rx_mon_status[grp_id];
+ for (i = 0; i < ab->num_radios; i++) {
+ for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) {
+ int id = i * ab->hw_params->num_rxdma_per_pdev + j;
+
+ if (ring_mask & BIT(id)) {
+ work_done =
+ ath12k_dp_mon_process_ring(ab, id, napi, budget,
+ 0);
+ budget -= work_done;
+ tot_work_done += work_done;
+ if (budget <= 0)
+ goto done;
+ }
+ }
+ }
+ }
+
+ if (ab->hw_params->ring_mask->rx_mon_dest[grp_id]) {
+ monitor_mode = ATH12K_DP_RX_MONITOR_MODE;
+ ring_mask = ab->hw_params->ring_mask->rx_mon_dest[grp_id];
+ for (i = 0; i < ab->num_radios; i++) {
+ for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) {
+ int id = i * ab->hw_params->num_rxdma_per_pdev + j;
+
+ if (ring_mask & BIT(id)) {
+ work_done =
+ ath12k_dp_mon_process_ring(ab, id, napi, budget,
+ monitor_mode);
+ budget -= work_done;
+ tot_work_done += work_done;
+
+ if (budget <= 0)
+ goto done;
+ }
+ }
+ }
+ }
+
+ if (ab->hw_params->ring_mask->tx_mon_dest[grp_id]) {
+ monitor_mode = ATH12K_DP_TX_MONITOR_MODE;
+ ring_mask = ab->hw_params->ring_mask->tx_mon_dest[grp_id];
+ for (i = 0; i < ab->num_radios; i++) {
+ for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) {
+ int id = i * ab->hw_params->num_rxdma_per_pdev + j;
+
+ if (ring_mask & BIT(id)) {
+ work_done =
+ ath12k_dp_mon_process_ring(ab, id, napi, budget,
+ monitor_mode);
+ budget -= work_done;
+ tot_work_done += work_done;
+
+ if (budget <= 0)
+ goto done;
+ }
+ }
+ }
+ }
+
+ if (ab->hw_params->ring_mask->reo_status[grp_id])
+ ath12k_dp_rx_process_reo_status(ab);
+
+ if (ab->hw_params->ring_mask->host2rxdma[grp_id]) {
+ struct ath12k_dp *dp = &ab->dp;
+ struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;
+ LIST_HEAD(list);
+
+ ath12k_dp_rx_bufs_replenish(ab, rx_ring, &list, 0);
+ }
+
+ /* TODO: Implement handler for other interrupts */
+
+done:
+ return tot_work_done;
+}
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.h b/drivers/net/wireless/ath/ath12k/wifi7/dp.h
new file mode 100644
index 000000000000..17255a5671d7
--- /dev/null
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: BSD-3-Clause-Clear */
+/*
+ * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef ATH12K_DP_WIFI7_H
+#define ATH12K_DP_WIFI7_H
+
+#include "hw.h"
+
+int ath12k_dp_service_srng(struct ath12k_base *ab,
+ struct ath12k_ext_irq_grp *irq_grp,
+ int budget);
+#endif
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
index b55cfb926571..cbc51a9a2c42 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
@@ -1642,3 +1642,82 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab)
return ret;
}
EXPORT_SYMBOL(ath12k_dp_rxdma_ring_sel_config_wcn7850);
+
+void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab)
+{
+ struct ath12k_dp *dp = &ab->dp;
+ struct hal_tlv_64_hdr *hdr;
+ struct hal_srng *srng;
+ struct ath12k_dp_rx_reo_cmd *cmd, *tmp;
+ bool found = false;
+ u16 tag;
+ struct hal_reo_status reo_status;
+
+ srng = &ab->hal.srng_list[dp->reo_status_ring.ring_id];
+
+ memset(&reo_status, 0, sizeof(reo_status));
+
+ spin_lock_bh(&srng->lock);
+
+ ath12k_hal_srng_access_begin(ab, srng);
+
+ while ((hdr = ath12k_hal_srng_dst_get_next_entry(ab, srng))) {
+ tag = le64_get_bits(hdr->tl, HAL_SRNG_TLV_HDR_TAG);
+
+ switch (tag) {
+ case HAL_REO_GET_QUEUE_STATS_STATUS:
+ ath12k_hal_reo_status_queue_stats(ab, hdr,
+ &reo_status);
+ break;
+ case HAL_REO_FLUSH_QUEUE_STATUS:
+ ath12k_hal_reo_flush_queue_status(ab, hdr,
+ &reo_status);
+ break;
+ case HAL_REO_FLUSH_CACHE_STATUS:
+ ath12k_hal_reo_flush_cache_status(ab, hdr,
+ &reo_status);
+ break;
+ case HAL_REO_UNBLOCK_CACHE_STATUS:
+ ath12k_hal_reo_unblk_cache_status(ab, hdr,
+ &reo_status);
+ break;
+ case HAL_REO_FLUSH_TIMEOUT_LIST_STATUS:
+ ath12k_hal_reo_flush_timeout_list_status(ab, hdr,
+ &reo_status);
+ break;
+ case HAL_REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS:
+ ath12k_hal_reo_desc_thresh_reached_status(ab, hdr,
+ &reo_status);
+ break;
+ case HAL_REO_UPDATE_RX_REO_QUEUE_STATUS:
+ ath12k_hal_reo_update_rx_reo_queue_status(ab, hdr,
+ &reo_status);
+ break;
+ default:
+ ath12k_warn(ab, "Unknown reo status type %d\n", tag);
+ continue;
+ }
+
+ spin_lock_bh(&dp->reo_cmd_lock);
+ list_for_each_entry_safe(cmd, tmp, &dp->reo_cmd_list, list) {
+ if (reo_status.uniform_hdr.cmd_num == cmd->cmd_num) {
+ found = true;
+ list_del(&cmd->list);
+ break;
+ }
+ }
+ spin_unlock_bh(&dp->reo_cmd_lock);
+
+ if (found) {
+ cmd->handler(dp, (void *)&cmd->data,
+ reo_status.uniform_hdr.cmd_status);
+ kfree(cmd);
+ }
+
+ found = false;
+ }
+
+ ath12k_hal_srng_access_end(ab, srng);
+
+ spin_unlock_bh(&srng->lock);
+}
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
index fa44e454cee6..63176a53c1e7 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
@@ -16,6 +16,7 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id,
struct napi_struct *napi,
int budget);
+void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab);
int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab);
int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab);
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 12/20] wifi: ath12k: Separate arch specific part of RX APIs
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (10 preceding siblings ...)
2025-08-28 17:35 ` [PATCH ath12k-ng 11/20] wifi: ath12k: Move srng processing " Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 13/20] wifi: ath12k: Move arch specific REO functions to wifi7 directory Ripan Deuri
` (10 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Below API have architecture specific HAL macros.
ath12k_dp_rx_peer_pn_replay_config
Separate architecture specific parts from these APIs to
later move them to wifi7 directory.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/dp_rx.c | 56 ++++++++++++++-----------
1 file changed, 32 insertions(+), 24 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index 8832ba5f5cdb..dd771063f591 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -958,6 +958,36 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar,
return ret;
}
+static void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd,
+ struct ath12k_dp_rx_tid *rx_tid,
+ u32 cipher, enum set_key_cmd key_cmd)
+{
+ cmd->flag = HAL_REO_CMD_FLG_NEED_STATUS;
+ cmd->upd0 = HAL_REO_CMD_UPD0_PN |
+ HAL_REO_CMD_UPD0_PN_SIZE |
+ HAL_REO_CMD_UPD0_PN_VALID |
+ HAL_REO_CMD_UPD0_PN_CHECK |
+ HAL_REO_CMD_UPD0_SVLD;
+
+ switch (cipher) {
+ case WLAN_CIPHER_SUITE_TKIP:
+ case WLAN_CIPHER_SUITE_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP_256:
+ case WLAN_CIPHER_SUITE_GCMP:
+ case WLAN_CIPHER_SUITE_GCMP_256:
+ if (key_cmd == SET_KEY) {
+ cmd->upd1 |= HAL_REO_CMD_UPD1_PN_CHECK;
+ cmd->pn_size = 48;
+ }
+ break;
+ default:
+ break;
+ }
+
+ cmd->addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned);
+ cmd->addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned);
+}
+
int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif,
const u8 *peer_addr,
enum set_key_cmd key_cmd,
@@ -978,28 +1008,6 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif,
if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
return 0;
- cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS;
- cmd.upd0 = HAL_REO_CMD_UPD0_PN |
- HAL_REO_CMD_UPD0_PN_SIZE |
- HAL_REO_CMD_UPD0_PN_VALID |
- HAL_REO_CMD_UPD0_PN_CHECK |
- HAL_REO_CMD_UPD0_SVLD;
-
- switch (key->cipher) {
- case WLAN_CIPHER_SUITE_TKIP:
- case WLAN_CIPHER_SUITE_CCMP:
- case WLAN_CIPHER_SUITE_CCMP_256:
- case WLAN_CIPHER_SUITE_GCMP:
- case WLAN_CIPHER_SUITE_GCMP_256:
- if (key_cmd == SET_KEY) {
- cmd.upd1 |= HAL_REO_CMD_UPD1_PN_CHECK;
- cmd.pn_size = 48;
- }
- break;
- default:
- break;
- }
-
spin_lock_bh(&ab->base_lock);
peer = ath12k_peer_find(ab, arvif->vdev_id, peer_addr);
@@ -1014,8 +1022,8 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif,
rx_tid = &peer->rx_tid[tid];
if (!rx_tid->active)
continue;
- cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned);
- cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned);
+
+ ath12k_dp_setup_pn_check_reo_cmd(&cmd, rx_tid, key->cipher, key_cmd);
ret = ath12k_dp_reo_cmd_send(ab, rx_tid,
HAL_REO_CMD_UPDATE_RX_QUEUE,
&cmd, NULL);
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 13/20] wifi: ath12k: Move arch specific REO functions to wifi7 directory
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (11 preceding siblings ...)
2025-08-28 17:35 ` [PATCH ath12k-ng 12/20] wifi: ath12k: Separate arch specific part of RX APIs Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 14/20] wifi: ath12k: Move arch specific rx tid and related " Ripan Deuri
` (9 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Move arch specific REO functions to wifi7 directory.
The moved APIs will be a part of dp_rx.c file inside wifi7 directory.
wifi7/dp_rx.c file will continue to be part of ath12k.ko temporarily
until the corresponding infra for movement to ath12k_wifi7.ko arrives
in upcoming patches.
Architecture specific APIs:
ath12k_dp_setup_pn_check_reo_cmd
ath12k_dp_rx_assign_reoq
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/dp_rx.c | 82 +------------------
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 80 ++++++++++++++++++
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 6 ++
3 files changed, 87 insertions(+), 81 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index dd771063f591..22d9c2d8c4e3 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -13,6 +13,7 @@
#include "wifi7/hal_desc.h"
#include "hw.h"
#include "dp_rx.h"
+#include "wifi7/dp_rx.h"
#include "wifi7/hal_rx.h"
#include "dp_tx.h"
#include "peer.h"
@@ -728,57 +729,6 @@ static int ath12k_peer_rx_tid_reo_update(struct ath12k *ar,
return 0;
}
-static int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab,
- struct ath12k_sta *ahsta,
- struct ath12k_dp_rx_tid *rx_tid,
- u16 ssn, enum hal_pn_type pn_type)
-{
- u32 ba_win_sz = rx_tid->ba_win_sz;
- struct ath12k_reoq_buf *buf;
- void *vaddr, *vaddr_aligned;
- dma_addr_t paddr_aligned;
- u8 tid = rx_tid->tid;
- u32 hw_desc_sz;
- int ret;
-
- buf = &ahsta->reoq_bufs[tid];
- if (!buf->vaddr) {
- /* TODO: Optimize the memory allocation for qos tid based on
- * the actual BA window size in REO tid update path.
- */
- if (tid == HAL_DESC_REO_NON_QOS_TID)
- hw_desc_sz = ath12k_hal_reo_qdesc_size(ba_win_sz, tid);
- else
- hw_desc_sz = ath12k_hal_reo_qdesc_size(DP_BA_WIN_SZ_MAX, tid);
-
- vaddr = kzalloc(hw_desc_sz + HAL_LINK_DESC_ALIGN - 1, GFP_ATOMIC);
- if (!vaddr)
- return -ENOMEM;
-
- vaddr_aligned = PTR_ALIGN(vaddr, HAL_LINK_DESC_ALIGN);
-
- ath12k_hal_reo_qdesc_setup(vaddr_aligned, tid, ba_win_sz,
- ssn, pn_type);
-
- paddr_aligned = dma_map_single(ab->dev, vaddr_aligned, hw_desc_sz,
- DMA_BIDIRECTIONAL);
- ret = dma_mapping_error(ab->dev, paddr_aligned);
- if (ret) {
- kfree(vaddr);
- return ret;
- }
-
- buf->vaddr = vaddr;
- buf->paddr_aligned = paddr_aligned;
- buf->size = hw_desc_sz;
- }
-
- rx_tid->qbuf = *buf;
- rx_tid->active = true;
-
- return 0;
-}
-
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)
@@ -958,36 +908,6 @@ int ath12k_dp_rx_ampdu_stop(struct ath12k *ar,
return ret;
}
-static void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd,
- struct ath12k_dp_rx_tid *rx_tid,
- u32 cipher, enum set_key_cmd key_cmd)
-{
- cmd->flag = HAL_REO_CMD_FLG_NEED_STATUS;
- cmd->upd0 = HAL_REO_CMD_UPD0_PN |
- HAL_REO_CMD_UPD0_PN_SIZE |
- HAL_REO_CMD_UPD0_PN_VALID |
- HAL_REO_CMD_UPD0_PN_CHECK |
- HAL_REO_CMD_UPD0_SVLD;
-
- switch (cipher) {
- case WLAN_CIPHER_SUITE_TKIP:
- case WLAN_CIPHER_SUITE_CCMP:
- case WLAN_CIPHER_SUITE_CCMP_256:
- case WLAN_CIPHER_SUITE_GCMP:
- case WLAN_CIPHER_SUITE_GCMP_256:
- if (key_cmd == SET_KEY) {
- cmd->upd1 |= HAL_REO_CMD_UPD1_PN_CHECK;
- cmd->pn_size = 48;
- }
- break;
- default:
- break;
- }
-
- cmd->addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned);
- cmd->addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned);
-}
-
int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif,
const u8 *peer_addr,
enum set_key_cmd key_cmd,
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
index cbc51a9a2c42..bcdfa19a2e5f 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
@@ -8,6 +8,56 @@
#include "../dp_tx.h"
#include "../peer.h"
+int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta,
+ struct ath12k_dp_rx_tid *rx_tid,
+ u16 ssn, enum hal_pn_type pn_type)
+{
+ u32 ba_win_sz = rx_tid->ba_win_sz;
+ struct ath12k_reoq_buf *buf;
+ void *vaddr, *vaddr_aligned;
+ dma_addr_t paddr_aligned;
+ u8 tid = rx_tid->tid;
+ u32 hw_desc_sz;
+ int ret;
+
+ buf = &ahsta->reoq_bufs[tid];
+ if (!buf->vaddr) {
+ /* TODO: Optimize the memory allocation for qos tid based on
+ * the actual BA window size in REO tid update path.
+ */
+ if (tid == HAL_DESC_REO_NON_QOS_TID)
+ hw_desc_sz = ath12k_hal_reo_qdesc_size(ba_win_sz, tid);
+ else
+ hw_desc_sz = ath12k_hal_reo_qdesc_size(DP_BA_WIN_SZ_MAX, tid);
+
+ vaddr = kzalloc(hw_desc_sz + HAL_LINK_DESC_ALIGN - 1, GFP_ATOMIC);
+ if (!vaddr)
+ return -ENOMEM;
+
+ vaddr_aligned = PTR_ALIGN(vaddr, HAL_LINK_DESC_ALIGN);
+
+ ath12k_hal_reo_qdesc_setup(vaddr_aligned, tid, ba_win_sz,
+ ssn, pn_type);
+
+ paddr_aligned = dma_map_single(ab->dev, vaddr_aligned, hw_desc_sz,
+ DMA_BIDIRECTIONAL);
+ ret = dma_mapping_error(ab->dev, paddr_aligned);
+ if (ret) {
+ kfree(vaddr);
+ return ret;
+ }
+
+ buf->vaddr = vaddr;
+ buf->paddr_aligned = paddr_aligned;
+ buf->size = hw_desc_sz;
+ }
+
+ rx_tid->qbuf = *buf;
+ rx_tid->active = true;
+
+ return 0;
+}
+
static void ath12k_dp_rx_h_csum_offload(struct sk_buff *msdu,
struct ath12k_dp_rx_info *rx_info)
{
@@ -1354,6 +1404,36 @@ static void ath12k_dp_rx_wbm_err(struct ath12k *ar,
ath12k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_info);
}
+void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd,
+ struct ath12k_dp_rx_tid *rx_tid,
+ u32 cipher, enum set_key_cmd key_cmd)
+{
+ cmd->flag = HAL_REO_CMD_FLG_NEED_STATUS;
+ cmd->upd0 = HAL_REO_CMD_UPD0_PN |
+ HAL_REO_CMD_UPD0_PN_SIZE |
+ HAL_REO_CMD_UPD0_PN_VALID |
+ HAL_REO_CMD_UPD0_PN_CHECK |
+ HAL_REO_CMD_UPD0_SVLD;
+
+ switch (cipher) {
+ case WLAN_CIPHER_SUITE_TKIP:
+ case WLAN_CIPHER_SUITE_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP_256:
+ case WLAN_CIPHER_SUITE_GCMP:
+ case WLAN_CIPHER_SUITE_GCMP_256:
+ if (key_cmd == SET_KEY) {
+ cmd->upd1 |= HAL_REO_CMD_UPD1_PN_CHECK;
+ cmd->pn_size = 48;
+ }
+ break;
+ default:
+ break;
+ }
+
+ cmd->addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned);
+ cmd->addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned);
+}
+
int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
struct napi_struct *napi, int budget)
{
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
index 63176a53c1e7..3589db00c906 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
@@ -19,4 +19,10 @@ int ath12k_dp_rx_process(struct ath12k_base *ab, int mac_id,
void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab);
int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab);
int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab);
+void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd,
+ struct ath12k_dp_rx_tid *rx_tid,
+ u32 cipher, enum set_key_cmd key_cmd);
+int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta,
+ struct ath12k_dp_rx_tid *rx_tid,
+ u16 ssn, enum hal_pn_type pn_type);
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 14/20] wifi: ath12k: Move arch specific rx tid and related functions to wifi7 directory
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (12 preceding siblings ...)
2025-08-28 17:35 ` [PATCH ath12k-ng 13/20] wifi: ath12k: Move arch specific REO functions to wifi7 directory Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 15/20] wifi: ath12k: Move arch specific tx APIs " Ripan Deuri
` (8 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Move arch specific Rx tid related functions to wifi7 directory.
The moved APIs will be a part of dp_rx.c file inside wifi7 directory.
wifi7/dp_rx.c file will continue to be part of ath12k.ko
temporarily until the corresponding infra for movement
to ath12k_wifi7.ko arrives in upcoming patches.
Architecture specific APIs:
ath12k_peer_rx_tid_qref_reset
ath12k_dp_reo_cache_flush
ath12k_dp_reo_cmd_send
ath12k_peer_rx_tid_reo_update
ath12k_dp_rx_link_desc_return
ath12k_dp_rx_peer_tid_delete
ath12k_peer_rx_tid_qref_setup
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/dp_rx.c | 248 +-----------------
drivers/net/wireless/ath/ath12k/dp_rx.h | 7 +-
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 240 +++++++++++++++++
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 19 ++
4 files changed, 267 insertions(+), 247 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index 22d9c2d8c4e3..d735eee9efee 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -370,8 +370,8 @@ void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab)
spin_unlock_bh(&dp->reo_cmd_lock);
}
-static void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx,
- enum hal_reo_cmd_status status)
+void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx,
+ enum hal_reo_cmd_status status)
{
struct ath12k_dp_rx_tid *rx_tid = ctx;
@@ -385,93 +385,8 @@ static void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx,
rx_tid->qbuf.vaddr = NULL;
}
-static int ath12k_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid,
- enum hal_reo_cmd_type type,
- struct ath12k_hal_reo_cmd *cmd,
- void (*cb)(struct ath12k_dp *dp, void *ctx,
- enum hal_reo_cmd_status status))
-{
- struct ath12k_dp *dp = &ab->dp;
- struct ath12k_dp_rx_reo_cmd *dp_cmd;
- struct hal_srng *cmd_ring;
- int cmd_num;
-
- cmd_ring = &ab->hal.srng_list[dp->reo_cmd_ring.ring_id];
- cmd_num = ath12k_hal_reo_cmd_send(ab, cmd_ring, type, cmd);
-
- /* cmd_num should start from 1, during failure return the error code */
- if (cmd_num < 0)
- return cmd_num;
-
- /* reo cmd ring descriptors has cmd_num starting from 1 */
- if (cmd_num == 0)
- return -EINVAL;
-
- if (!cb)
- return 0;
-
- /* Can this be optimized so that we keep the pending command list only
- * for tid delete command to free up the resource on the command status
- * indication?
- */
- dp_cmd = kzalloc(sizeof(*dp_cmd), GFP_ATOMIC);
-
- if (!dp_cmd)
- return -ENOMEM;
-
- memcpy(&dp_cmd->data, rx_tid, sizeof(*rx_tid));
- dp_cmd->cmd_num = cmd_num;
- dp_cmd->handler = cb;
-
- spin_lock_bh(&dp->reo_cmd_lock);
- list_add_tail(&dp_cmd->list, &dp->reo_cmd_list);
- spin_unlock_bh(&dp->reo_cmd_lock);
-
- return 0;
-}
-
-static void ath12k_dp_reo_cache_flush(struct ath12k_base *ab,
- struct ath12k_dp_rx_tid *rx_tid)
-{
- struct ath12k_hal_reo_cmd cmd = {};
- unsigned long tot_desc_sz, desc_sz;
- int ret;
-
- tot_desc_sz = rx_tid->qbuf.size;
- desc_sz = ath12k_hal_reo_qdesc_size(0, HAL_DESC_REO_NON_QOS_TID);
-
- while (tot_desc_sz > desc_sz) {
- tot_desc_sz -= desc_sz;
- cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned + tot_desc_sz);
- cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned);
- ret = ath12k_dp_reo_cmd_send(ab, rx_tid,
- HAL_REO_CMD_FLUSH_CACHE, &cmd,
- NULL);
- if (ret)
- ath12k_warn(ab,
- "failed to send HAL_REO_CMD_FLUSH_CACHE, tid %d (%d)\n",
- rx_tid->tid, ret);
- }
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned);
- cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned);
- cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS;
- ret = ath12k_dp_reo_cmd_send(ab, rx_tid,
- HAL_REO_CMD_FLUSH_CACHE,
- &cmd, ath12k_dp_reo_cmd_free);
- if (ret) {
- ath12k_err(ab, "failed to send HAL_REO_CMD_FLUSH_CACHE cmd, tid %d (%d)\n",
- rx_tid->tid, ret);
- dma_unmap_single(ab->dev, rx_tid->qbuf.paddr_aligned, rx_tid->qbuf.size,
- DMA_BIDIRECTIONAL);
- kfree(rx_tid->qbuf.vaddr);
- rx_tid->qbuf.vaddr = NULL;
- }
-}
-
-static void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx,
- enum hal_reo_cmd_status status)
+void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx,
+ enum hal_reo_cmd_status status)
{
struct ath12k_base *ab = dp->ab;
struct ath12k_dp_rx_tid *rx_tid = ctx;
@@ -531,127 +446,6 @@ static void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx,
rx_tid->qbuf.vaddr = NULL;
}
-static void ath12k_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid,
- dma_addr_t paddr)
-{
- struct ath12k_reo_queue_ref *qref;
- struct ath12k_dp *dp = &ab->dp;
- bool ml_peer = false;
-
- if (!ab->hw_params->reoq_lut_support)
- return;
-
- if (peer_id & ATH12K_PEER_ML_ID_VALID) {
- peer_id &= ~ATH12K_PEER_ML_ID_VALID;
- ml_peer = true;
- }
-
- if (ml_peer)
- qref = (struct ath12k_reo_queue_ref *)dp->ml_reoq_lut.vaddr +
- (peer_id * (IEEE80211_NUM_TIDS + 1) + tid);
- else
- qref = (struct ath12k_reo_queue_ref *)dp->reoq_lut.vaddr +
- (peer_id * (IEEE80211_NUM_TIDS + 1) + tid);
-
- qref->info0 = u32_encode_bits(lower_32_bits(paddr),
- BUFFER_ADDR_INFO0_ADDR);
- qref->info1 = u32_encode_bits(upper_32_bits(paddr),
- BUFFER_ADDR_INFO1_ADDR) |
- u32_encode_bits(tid, DP_REO_QREF_NUM);
- ath12k_hal_reo_shared_qaddr_cache_clear(ab);
-}
-
-static void ath12k_peer_rx_tid_qref_reset(struct ath12k_base *ab, u16 peer_id, u16 tid)
-{
- struct ath12k_reo_queue_ref *qref;
- struct ath12k_dp *dp = &ab->dp;
- bool ml_peer = false;
-
- if (!ab->hw_params->reoq_lut_support)
- return;
-
- if (peer_id & ATH12K_PEER_ML_ID_VALID) {
- peer_id &= ~ATH12K_PEER_ML_ID_VALID;
- ml_peer = true;
- }
-
- if (ml_peer)
- qref = (struct ath12k_reo_queue_ref *)dp->ml_reoq_lut.vaddr +
- (peer_id * (IEEE80211_NUM_TIDS + 1) + tid);
- else
- qref = (struct ath12k_reo_queue_ref *)dp->reoq_lut.vaddr +
- (peer_id * (IEEE80211_NUM_TIDS + 1) + tid);
-
- qref->info0 = u32_encode_bits(0, BUFFER_ADDR_INFO0_ADDR);
- qref->info1 = u32_encode_bits(0, BUFFER_ADDR_INFO1_ADDR) |
- u32_encode_bits(tid, DP_REO_QREF_NUM);
-}
-
-void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar,
- struct ath12k_peer *peer, u8 tid)
-{
- struct ath12k_hal_reo_cmd cmd = {};
- struct ath12k_dp_rx_tid *rx_tid = &peer->rx_tid[tid];
- int ret;
-
- if (!rx_tid->active)
- return;
-
- cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS;
- cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned);
- cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned);
- cmd.upd0 = HAL_REO_CMD_UPD0_VLD;
- ret = ath12k_dp_reo_cmd_send(ar->ab, rx_tid,
- HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd,
- ath12k_dp_rx_tid_del_func);
- if (ret) {
- ath12k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n",
- tid, ret);
- dma_unmap_single(ar->ab->dev, rx_tid->qbuf.paddr_aligned,
- rx_tid->qbuf.size, DMA_BIDIRECTIONAL);
- kfree(rx_tid->qbuf.vaddr);
- rx_tid->qbuf.vaddr = NULL;
- }
-
- if (peer->mlo)
- ath12k_peer_rx_tid_qref_reset(ar->ab, peer->ml_id, tid);
- else
- ath12k_peer_rx_tid_qref_reset(ar->ab, peer->peer_id, tid);
-
- rx_tid->active = false;
-}
-
-int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab,
- struct ath12k_buffer_addr *buf_addr_info,
- enum hal_wbm_rel_bm_act action)
-{
- struct hal_wbm_release_ring *desc;
- struct ath12k_dp *dp = &ab->dp;
- struct hal_srng *srng;
- int ret = 0;
-
- srng = &ab->hal.srng_list[dp->wbm_desc_rel_ring.ring_id];
-
- spin_lock_bh(&srng->lock);
-
- ath12k_hal_srng_access_begin(ab, srng);
-
- desc = ath12k_hal_srng_src_get_next_entry(ab, srng);
- if (!desc) {
- ret = -ENOBUFS;
- goto exit;
- }
-
- ath12k_hal_rx_msdu_link_desc_set(ab, desc, buf_addr_info, action);
-
-exit:
- ath12k_hal_srng_access_end(ab, srng);
-
- spin_unlock_bh(&srng->lock);
-
- return ret;
-}
-
void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid,
bool rel_link_desc)
{
@@ -695,40 +489,6 @@ void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_peer *peer)
}
}
-static int ath12k_peer_rx_tid_reo_update(struct ath12k *ar,
- struct ath12k_peer *peer,
- struct ath12k_dp_rx_tid *rx_tid,
- u32 ba_win_sz, u16 ssn,
- bool update_ssn)
-{
- struct ath12k_hal_reo_cmd cmd = {};
- int ret;
-
- cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned);
- cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned);
- cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS;
- cmd.upd0 = HAL_REO_CMD_UPD0_BA_WINDOW_SIZE;
- cmd.ba_window_size = ba_win_sz;
-
- if (update_ssn) {
- cmd.upd0 |= HAL_REO_CMD_UPD0_SSN;
- cmd.upd2 = u32_encode_bits(ssn, HAL_REO_CMD_UPD2_SSN);
- }
-
- ret = ath12k_dp_reo_cmd_send(ar->ab, rx_tid,
- HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd,
- NULL);
- if (ret) {
- ath12k_warn(ar->ab, "failed to update rx tid queue, tid %d (%d)\n",
- rx_tid->tid, ret);
- return ret;
- }
-
- rx_tid->ba_win_sz = ba_win_sz;
-
- return 0;
-}
-
int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id,
u8 tid, u32 ba_win_sz, u16 ssn,
enum hal_pn_type pn_type)
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h
index b3095fd46cd5..7bf70cef4365 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.h
@@ -422,12 +422,13 @@ u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab,
struct hal_rx_desc *rx_desc);
bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab,
struct hal_rx_desc *rx_desc);
-int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab,
- struct ath12k_buffer_addr *buf_addr_info,
- enum hal_wbm_rel_bm_act action);
bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab,
struct hal_rx_desc *rx_desc);
void ath12k_dp_rx_h_ppdu(struct ath12k *ar, struct ath12k_dp_rx_info *rx_info);
struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list,
struct sk_buff *first);
+void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx,
+ enum hal_reo_cmd_status status);
+void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx,
+ enum hal_reo_cmd_status status);
#endif /* ATH12K_DP_RX_H */
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
index bcdfa19a2e5f..d95e3c4daa5d 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
@@ -8,6 +8,246 @@
#include "../dp_tx.h"
#include "../peer.h"
+void ath12k_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid,
+ dma_addr_t paddr)
+{
+ struct ath12k_reo_queue_ref *qref;
+ struct ath12k_dp *dp = &ab->dp;
+ bool ml_peer = false;
+
+ if (!ab->hw_params->reoq_lut_support)
+ return;
+
+ if (peer_id & ATH12K_PEER_ML_ID_VALID) {
+ peer_id &= ~ATH12K_PEER_ML_ID_VALID;
+ ml_peer = true;
+ }
+
+ if (ml_peer)
+ qref = (struct ath12k_reo_queue_ref *)dp->ml_reoq_lut.vaddr +
+ (peer_id * (IEEE80211_NUM_TIDS + 1) + tid);
+ else
+ qref = (struct ath12k_reo_queue_ref *)dp->reoq_lut.vaddr +
+ (peer_id * (IEEE80211_NUM_TIDS + 1) + tid);
+
+ qref->info0 = u32_encode_bits(lower_32_bits(paddr),
+ BUFFER_ADDR_INFO0_ADDR);
+ qref->info1 = u32_encode_bits(upper_32_bits(paddr),
+ BUFFER_ADDR_INFO1_ADDR) |
+ u32_encode_bits(tid, DP_REO_QREF_NUM);
+ ath12k_hal_reo_shared_qaddr_cache_clear(ab);
+}
+
+static void ath12k_peer_rx_tid_qref_reset(struct ath12k_base *ab, u16 peer_id, u16 tid)
+{
+ struct ath12k_reo_queue_ref *qref;
+ struct ath12k_dp *dp = &ab->dp;
+ bool ml_peer = false;
+
+ if (!ab->hw_params->reoq_lut_support)
+ return;
+
+ if (peer_id & ATH12K_PEER_ML_ID_VALID) {
+ peer_id &= ~ATH12K_PEER_ML_ID_VALID;
+ ml_peer = true;
+ }
+
+ if (ml_peer)
+ qref = (struct ath12k_reo_queue_ref *)dp->ml_reoq_lut.vaddr +
+ (peer_id * (IEEE80211_NUM_TIDS + 1) + tid);
+ else
+ qref = (struct ath12k_reo_queue_ref *)dp->reoq_lut.vaddr +
+ (peer_id * (IEEE80211_NUM_TIDS + 1) + tid);
+
+ qref->info0 = u32_encode_bits(0, BUFFER_ADDR_INFO0_ADDR);
+ qref->info1 = u32_encode_bits(0, BUFFER_ADDR_INFO1_ADDR) |
+ u32_encode_bits(tid, DP_REO_QREF_NUM);
+}
+
+void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar,
+ struct ath12k_peer *peer, u8 tid)
+{
+ struct ath12k_hal_reo_cmd cmd = {};
+ struct ath12k_dp_rx_tid *rx_tid = &peer->rx_tid[tid];
+ int ret;
+
+ if (!rx_tid->active)
+ return;
+
+ cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS;
+ cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned);
+ cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned);
+ cmd.upd0 = HAL_REO_CMD_UPD0_VLD;
+ ret = ath12k_dp_reo_cmd_send(ar->ab, rx_tid,
+ HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd,
+ ath12k_dp_rx_tid_del_func);
+ if (ret) {
+ ath12k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n",
+ tid, ret);
+ dma_unmap_single(ar->ab->dev, rx_tid->qbuf.paddr_aligned,
+ rx_tid->qbuf.size, DMA_BIDIRECTIONAL);
+ kfree(rx_tid->qbuf.vaddr);
+ rx_tid->qbuf.vaddr = NULL;
+ }
+
+ if (peer->mlo)
+ ath12k_peer_rx_tid_qref_reset(ar->ab, peer->ml_id, tid);
+ else
+ ath12k_peer_rx_tid_qref_reset(ar->ab, peer->peer_id, tid);
+
+ rx_tid->active = false;
+}
+
+int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab,
+ struct ath12k_buffer_addr *buf_addr_info,
+ enum hal_wbm_rel_bm_act action)
+{
+ struct hal_wbm_release_ring *desc;
+ struct ath12k_dp *dp = &ab->dp;
+ struct hal_srng *srng;
+ int ret = 0;
+
+ srng = &ab->hal.srng_list[dp->wbm_desc_rel_ring.ring_id];
+
+ spin_lock_bh(&srng->lock);
+
+ ath12k_hal_srng_access_begin(ab, srng);
+
+ desc = ath12k_hal_srng_src_get_next_entry(ab, srng);
+ if (!desc) {
+ ret = -ENOBUFS;
+ goto exit;
+ }
+
+ ath12k_hal_rx_msdu_link_desc_set(ab, desc, buf_addr_info, action);
+
+exit:
+ ath12k_hal_srng_access_end(ab, srng);
+
+ spin_unlock_bh(&srng->lock);
+
+ return ret;
+}
+
+int ath12k_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid,
+ enum hal_reo_cmd_type type,
+ struct ath12k_hal_reo_cmd *cmd,
+ void (*cb)(struct ath12k_dp *dp, void *ctx,
+ enum hal_reo_cmd_status status))
+{
+ struct ath12k_dp *dp = &ab->dp;
+ struct ath12k_dp_rx_reo_cmd *dp_cmd;
+ struct hal_srng *cmd_ring;
+ int cmd_num;
+
+ cmd_ring = &ab->hal.srng_list[dp->reo_cmd_ring.ring_id];
+ cmd_num = ath12k_hal_reo_cmd_send(ab, cmd_ring, type, cmd);
+
+ /* cmd_num should start from 1, during failure return the error code */
+ if (cmd_num < 0)
+ return cmd_num;
+
+ /* reo cmd ring descriptors has cmd_num starting from 1 */
+ if (cmd_num == 0)
+ return -EINVAL;
+
+ if (!cb)
+ return 0;
+
+ /* Can this be optimized so that we keep the pending command list only
+ * for tid delete command to free up the resource on the command status
+ * indication?
+ */
+ dp_cmd = kzalloc(sizeof(*dp_cmd), GFP_ATOMIC);
+
+ if (!dp_cmd)
+ return -ENOMEM;
+
+ memcpy(&dp_cmd->data, rx_tid, sizeof(*rx_tid));
+ dp_cmd->cmd_num = cmd_num;
+ dp_cmd->handler = cb;
+
+ spin_lock_bh(&dp->reo_cmd_lock);
+ list_add_tail(&dp_cmd->list, &dp->reo_cmd_list);
+ spin_unlock_bh(&dp->reo_cmd_lock);
+
+ return 0;
+}
+
+int ath12k_peer_rx_tid_reo_update(struct ath12k *ar,
+ struct ath12k_peer *peer,
+ struct ath12k_dp_rx_tid *rx_tid,
+ u32 ba_win_sz, u16 ssn,
+ bool update_ssn)
+{
+ struct ath12k_hal_reo_cmd cmd = {};
+ int ret;
+
+ cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned);
+ cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned);
+ cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS;
+ cmd.upd0 = HAL_REO_CMD_UPD0_BA_WINDOW_SIZE;
+ cmd.ba_window_size = ba_win_sz;
+
+ if (update_ssn) {
+ cmd.upd0 |= HAL_REO_CMD_UPD0_SSN;
+ cmd.upd2 = u32_encode_bits(ssn, HAL_REO_CMD_UPD2_SSN);
+ }
+
+ ret = ath12k_dp_reo_cmd_send(ar->ab, rx_tid,
+ HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd,
+ NULL);
+ if (ret) {
+ ath12k_warn(ar->ab, "failed to update rx tid queue, tid %d (%d)\n",
+ rx_tid->tid, ret);
+ return ret;
+ }
+
+ rx_tid->ba_win_sz = ba_win_sz;
+
+ return 0;
+}
+
+void ath12k_dp_reo_cache_flush(struct ath12k_base *ab,
+ struct ath12k_dp_rx_tid *rx_tid)
+{
+ struct ath12k_hal_reo_cmd cmd = {};
+ unsigned long tot_desc_sz, desc_sz;
+ int ret;
+
+ tot_desc_sz = rx_tid->qbuf.size;
+ desc_sz = ath12k_hal_reo_qdesc_size(0, HAL_DESC_REO_NON_QOS_TID);
+
+ while (tot_desc_sz > desc_sz) {
+ tot_desc_sz -= desc_sz;
+ cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned + tot_desc_sz);
+ cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned);
+ ret = ath12k_dp_reo_cmd_send(ab, rx_tid,
+ HAL_REO_CMD_FLUSH_CACHE, &cmd,
+ NULL);
+ if (ret)
+ ath12k_warn(ab,
+ "failed to send HAL_REO_CMD_FLUSH_CACHE, tid %d (%d)\n",
+ rx_tid->tid, ret);
+ }
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.addr_lo = lower_32_bits(rx_tid->qbuf.paddr_aligned);
+ cmd.addr_hi = upper_32_bits(rx_tid->qbuf.paddr_aligned);
+ cmd.flag = HAL_REO_CMD_FLG_NEED_STATUS;
+ ret = ath12k_dp_reo_cmd_send(ab, rx_tid,
+ HAL_REO_CMD_FLUSH_CACHE,
+ &cmd, ath12k_dp_reo_cmd_free);
+ if (ret) {
+ ath12k_err(ab, "failed to send HAL_REO_CMD_FLUSH_CACHE cmd, tid %d (%d)\n",
+ rx_tid->tid, ret);
+ dma_unmap_single(ab->dev, rx_tid->qbuf.paddr_aligned, rx_tid->qbuf.size,
+ DMA_BIDIRECTIONAL);
+ kfree(rx_tid->qbuf.vaddr);
+ rx_tid->qbuf.vaddr = NULL;
+ }
+}
+
int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta,
struct ath12k_dp_rx_tid *rx_tid,
u16 ssn, enum hal_pn_type pn_type)
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
index 3589db00c906..45b856aaaa12 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
@@ -25,4 +25,23 @@ void ath12k_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd,
int ath12k_dp_rx_assign_reoq(struct ath12k_base *ab, struct ath12k_sta *ahsta,
struct ath12k_dp_rx_tid *rx_tid,
u16 ssn, enum hal_pn_type pn_type);
+int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab,
+ struct ath12k_buffer_addr *buf_addr_info,
+ enum hal_wbm_rel_bm_act action);
+void ath12k_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid,
+ dma_addr_t paddr);
+void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar,
+ struct ath12k_peer *peer, u8 tid);
+int ath12k_dp_reo_cmd_send(struct ath12k_base *ab, struct ath12k_dp_rx_tid *rx_tid,
+ enum hal_reo_cmd_type type,
+ struct ath12k_hal_reo_cmd *cmd,
+ void (*cb)(struct ath12k_dp *dp, void *ctx,
+ enum hal_reo_cmd_status status));
+void ath12k_dp_reo_cache_flush(struct ath12k_base *ab,
+ struct ath12k_dp_rx_tid *rx_tid);
+int ath12k_peer_rx_tid_reo_update(struct ath12k *ar,
+ struct ath12k_peer *peer,
+ struct ath12k_dp_rx_tid *rx_tid,
+ u32 ba_win_sz, u16 ssn,
+ bool update_ssn);
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 15/20] wifi: ath12k: Move arch specific tx APIs to wifi7 directory
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (13 preceding siblings ...)
2025-08-28 17:35 ` [PATCH ath12k-ng 14/20] wifi: ath12k: Move arch specific rx tid and related " Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 16/20] wifi: ath12k: Move ath12k_dp_tx and related " Ripan Deuri
` (7 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Move arch specific TX data path to wifi7 directory as part of Next
Generation (NG) Driver Framework.
Architecture specific APIs:
ath12k_dp_tx_htt_tx_complete_buf
ath12k_dp_tx_process_htt_tx_complete
ath12k_dp_tx_update_txcompl
ath12k_dp_tx_complete_msdu
ath12k_dp_tx_status_parse
ath12k_dp_tx_completion_handler
The moved APIs will be a part of dp_tx.c file inside wifi7 directory.
wifi7/dp_tx.c file will continue to be part of ath12k.ko temporarily
until the corresponding infra for movement to ath12k_wifi7.ko arrives
in upcoming patches.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/Makefile | 1 +
drivers/net/wireless/ath/ath12k/dp_tx.c | 564 +-----------------
drivers/net/wireless/ath/ath12k/dp_tx.h | 18 +-
drivers/net/wireless/ath/ath12k/mac.c | 3 +-
drivers/net/wireless/ath/ath12k/wifi7/dp.c | 1 +
drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 545 +++++++++++++++++
drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h | 11 +
7 files changed, 591 insertions(+), 552 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h
diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile
index ed1f1dba3d3b..e72b52d5af6d 100644
--- a/drivers/net/wireless/ath/ath12k/Makefile
+++ b/drivers/net/wireless/ath/ath12k/Makefile
@@ -25,6 +25,7 @@ ath12k-$(CONFIG_ATH12K_AHB) += ahb.o
ath12k-y += wifi7/hal_tx.o \
wifi7/hal_rx.o \
wifi7/dp_rx.o \
+ wifi7/dp_tx.o \
wifi7/dp.o
obj-$(CONFIG_ATH12K) += wifi7/
diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c
index abc84ca8467a..f1649744c78b 100644
--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include "core.h"
@@ -12,7 +12,7 @@
#include "peer.h"
#include "mac.h"
-static enum hal_tcl_encap_type
+enum hal_tcl_encap_type
ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb)
{
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
@@ -26,7 +26,7 @@ ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb)
return HAL_TCL_ENCAP_TYPE_NATIVE_WIFI;
}
-static void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb)
+void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (void *)skb->data;
u8 *qos_ctl;
@@ -43,7 +43,7 @@ static void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb)
hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
}
-static u8 ath12k_dp_tx_get_tid(struct sk_buff *skb)
+u8 ath12k_dp_tx_get_tid(struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (void *)skb->data;
struct ath12k_skb_cb *cb = ATH12K_SKB_CB(skb);
@@ -78,9 +78,9 @@ enum hal_encrypt_type ath12k_dp_tx_get_encrypt_type(u32 cipher)
}
}
-static void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp,
- struct ath12k_tx_desc_info *tx_desc,
- u8 pool_id)
+void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp,
+ struct ath12k_tx_desc_info *tx_desc,
+ u8 pool_id)
{
spin_lock_bh(&dp->tx_desc_lock[pool_id]);
tx_desc->skb_ext_desc = NULL;
@@ -88,8 +88,8 @@ static void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp,
spin_unlock_bh(&dp->tx_desc_lock[pool_id]);
}
-static struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp,
- u8 pool_id)
+struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp,
+ u8 pool_id)
{
struct ath12k_tx_desc_info *desc;
@@ -129,7 +129,7 @@ static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab,
#define HTT_META_DATA_ALIGNMENT 0x8
-static void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len)
+void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len)
{
struct sk_buff *tail;
void *metadata;
@@ -182,8 +182,8 @@ static void ath12k_dp_tx_move_payload(struct sk_buff *skb,
}
}
-static int ath12k_dp_tx_align_payload(struct ath12k_base *ab,
- struct sk_buff **pskb)
+int ath12k_dp_tx_align_payload(struct ath12k_base *ab,
+ struct sk_buff **pskb)
{
u32 iova_mask = ab->hw_params->iova_mask;
unsigned long offset, delta1, delta2;
@@ -539,9 +539,9 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif,
return ret;
}
-static void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab,
- struct dp_tx_ring *tx_ring,
- struct ath12k_tx_desc_params *desc_params)
+void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab,
+ struct dp_tx_ring *tx_ring,
+ struct ath12k_tx_desc_params *desc_params)
{
struct ath12k *ar;
struct sk_buff *msdu = desc_params->skb;
@@ -564,540 +564,6 @@ static void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab,
wake_up(&ar->dp.tx_empty_waitq);
}
-static void
-ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab,
- struct ath12k_tx_desc_params *desc_params,
- struct dp_tx_ring *tx_ring,
- struct ath12k_dp_htt_wbm_tx_status *ts,
- u16 peer_id)
-{
- struct ieee80211_tx_info *info;
- struct ath12k_link_vif *arvif;
- struct ath12k_skb_cb *skb_cb;
- struct ieee80211_vif *vif;
- struct ath12k_vif *ahvif;
- struct ath12k *ar;
- struct sk_buff *msdu = desc_params->skb;
- s32 noise_floor;
- struct ieee80211_tx_status status = {};
- struct ath12k_peer *peer;
-
- skb_cb = ATH12K_SKB_CB(msdu);
- info = IEEE80211_SKB_CB(msdu);
-
- ar = skb_cb->ar;
- ab->device_stats.tx_completed[tx_ring->tcl_data_ring_id]++;
-
- if (atomic_dec_and_test(&ar->dp.num_tx_pending))
- wake_up(&ar->dp.tx_empty_waitq);
-
- dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
- if (skb_cb->paddr_ext_desc) {
- dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc,
- desc_params->skb_ext_desc->len, DMA_TO_DEVICE);
- dev_kfree_skb_any(desc_params->skb_ext_desc);
- }
-
- vif = skb_cb->vif;
- if (vif) {
- ahvif = ath12k_vif_to_ahvif(vif);
- rcu_read_lock();
- arvif = rcu_dereference(ahvif->link[skb_cb->link_id]);
- if (arvif) {
- spin_lock_bh(&arvif->link_stats_lock);
- arvif->link_stats.tx_completed++;
- spin_unlock_bh(&arvif->link_stats_lock);
- }
- rcu_read_unlock();
- }
-
- memset(&info->status, 0, sizeof(info->status));
-
- if (ts->acked) {
- if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
- info->flags |= IEEE80211_TX_STAT_ACK;
- info->status.ack_signal = ts->ack_rssi;
-
- if (!test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT,
- ab->wmi_ab.svc_map)) {
- spin_lock_bh(&ar->data_lock);
- noise_floor = ath12k_pdev_get_noise_floor(ar);
- spin_unlock_bh(&ar->data_lock);
-
- info->status.ack_signal += noise_floor;
- }
-
- info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID;
- } else {
- info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
- }
- }
- rcu_read_lock();
- spin_lock_bh(&ab->base_lock);
- peer = ath12k_peer_find_by_id(ab, peer_id);
- if (!peer || !peer->sta) {
- ath12k_dbg(ab, ATH12K_DBG_DATA,
- "dp_tx: failed to find the peer with peer_id %d\n", peer_id);
- spin_unlock_bh(&ab->base_lock);
- ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu);
- goto exit;
- } else {
- status.sta = peer->sta;
- }
- spin_unlock_bh(&ab->base_lock);
-
- status.info = info;
- status.skb = msdu;
- ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status);
-exit:
- rcu_read_unlock();
-}
-
-static void
-ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc,
- struct dp_tx_ring *tx_ring,
- struct ath12k_tx_desc_params *desc_params)
-{
- struct htt_tx_wbm_completion *status_desc;
- struct ath12k_dp_htt_wbm_tx_status ts = {};
- enum hal_wbm_htt_tx_comp_status wbm_status;
- u16 peer_id;
-
- status_desc = desc;
-
- wbm_status = le32_get_bits(status_desc->info0,
- HTT_TX_WBM_COMP_INFO0_STATUS);
- ab->device_stats.fw_tx_status[wbm_status]++;
-
- switch (wbm_status) {
- case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK:
- ts.acked = (wbm_status == HAL_WBM_REL_HTT_TX_COMP_STATUS_OK);
- ts.ack_rssi = le32_get_bits(status_desc->info2,
- HTT_TX_WBM_COMP_INFO2_ACK_RSSI);
-
- peer_id = le32_get_bits(((struct hal_wbm_completion_ring_tx *)desc)->
- info3, HAL_WBM_COMPL_TX_INFO3_PEER_ID);
-
- ath12k_dp_tx_htt_tx_complete_buf(ab, desc_params, tx_ring, &ts, peer_id);
- break;
- case HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP:
- case HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL:
- case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ:
- case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT:
- case HAL_WBM_REL_HTT_TX_COMP_STATUS_VDEVID_MISMATCH:
- ath12k_dp_tx_free_txbuf(ab, tx_ring, desc_params);
- break;
- case HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY:
- /* This event is to be handled only when the driver decides to
- * use WDS offload functionality.
- */
- break;
- default:
- ath12k_warn(ab, "Unknown htt wbm tx status %d\n", wbm_status);
- break;
- }
-}
-
-static void ath12k_dp_tx_update_txcompl(struct ath12k *ar, struct hal_tx_status *ts)
-{
- struct ath12k_base *ab = ar->ab;
- struct ath12k_peer *peer;
- struct ieee80211_sta *sta;
- struct ath12k_sta *ahsta;
- struct ath12k_link_sta *arsta;
- struct rate_info txrate = {};
- u16 rate, ru_tones;
- u8 rate_idx = 0;
- int ret;
-
- spin_lock_bh(&ab->base_lock);
- peer = ath12k_peer_find_by_id(ab, ts->peer_id);
- if (!peer || !peer->sta) {
- ath12k_dbg(ab, ATH12K_DBG_DP_TX,
- "failed to find the peer by id %u\n", ts->peer_id);
- spin_unlock_bh(&ab->base_lock);
- return;
- }
- sta = peer->sta;
- ahsta = ath12k_sta_to_ahsta(sta);
- arsta = &ahsta->deflink;
-
- /* This is to prefer choose the real NSS value arsta->last_txrate.nss,
- * if it is invalid, then choose the NSS value while assoc.
- */
- if (arsta->last_txrate.nss)
- txrate.nss = arsta->last_txrate.nss;
- else
- txrate.nss = arsta->peer_nss;
- spin_unlock_bh(&ab->base_lock);
-
- switch (ts->pkt_type) {
- case HAL_TX_RATE_STATS_PKT_TYPE_11A:
- case HAL_TX_RATE_STATS_PKT_TYPE_11B:
- ret = ath12k_mac_hw_ratecode_to_legacy_rate(ts->mcs,
- ts->pkt_type,
- &rate_idx,
- &rate);
- if (ret < 0) {
- ath12k_warn(ab, "Invalid tx legacy rate %d\n", ret);
- return;
- }
-
- txrate.legacy = rate;
- break;
- case HAL_TX_RATE_STATS_PKT_TYPE_11N:
- if (ts->mcs > ATH12K_HT_MCS_MAX) {
- ath12k_warn(ab, "Invalid HT mcs index %d\n", ts->mcs);
- return;
- }
-
- if (txrate.nss != 0)
- txrate.mcs = ts->mcs + 8 * (txrate.nss - 1);
-
- txrate.flags = RATE_INFO_FLAGS_MCS;
-
- if (ts->sgi)
- txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
- break;
- case HAL_TX_RATE_STATS_PKT_TYPE_11AC:
- if (ts->mcs > ATH12K_VHT_MCS_MAX) {
- ath12k_warn(ab, "Invalid VHT mcs index %d\n", ts->mcs);
- return;
- }
-
- txrate.mcs = ts->mcs;
- txrate.flags = RATE_INFO_FLAGS_VHT_MCS;
-
- if (ts->sgi)
- txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
- break;
- case HAL_TX_RATE_STATS_PKT_TYPE_11AX:
- if (ts->mcs > ATH12K_HE_MCS_MAX) {
- ath12k_warn(ab, "Invalid HE mcs index %d\n", ts->mcs);
- return;
- }
-
- txrate.mcs = ts->mcs;
- txrate.flags = RATE_INFO_FLAGS_HE_MCS;
- txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(ts->sgi);
- break;
- case HAL_TX_RATE_STATS_PKT_TYPE_11BE:
- if (ts->mcs > ATH12K_EHT_MCS_MAX) {
- ath12k_warn(ab, "Invalid EHT mcs index %d\n", ts->mcs);
- return;
- }
-
- txrate.mcs = ts->mcs;
- txrate.flags = RATE_INFO_FLAGS_EHT_MCS;
- txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(ts->sgi);
- break;
- default:
- ath12k_warn(ab, "Invalid tx pkt type: %d\n", ts->pkt_type);
- return;
- }
-
- txrate.bw = ath12k_mac_bw_to_mac80211_bw(ts->bw);
-
- if (ts->ofdma && ts->pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11AX) {
- txrate.bw = RATE_INFO_BW_HE_RU;
- ru_tones = ath12k_mac_he_convert_tones_to_ru_tones(ts->tones);
- txrate.he_ru_alloc =
- ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones);
- }
-
- if (ts->ofdma && ts->pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11BE) {
- txrate.bw = RATE_INFO_BW_EHT_RU;
- txrate.eht_ru_alloc =
- ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(ts->tones);
- }
-
- spin_lock_bh(&ab->base_lock);
- arsta->txrate = txrate;
- spin_unlock_bh(&ab->base_lock);
-}
-
-static void ath12k_dp_tx_complete_msdu(struct ath12k *ar,
- struct ath12k_tx_desc_params *desc_params,
- struct hal_tx_status *ts,
- int ring)
-{
- struct ath12k_base *ab = ar->ab;
- struct ath12k_hw *ah = ar->ah;
- struct ieee80211_tx_info *info;
- struct ath12k_link_vif *arvif;
- struct ath12k_skb_cb *skb_cb;
- struct ieee80211_vif *vif;
- struct ath12k_vif *ahvif;
- struct sk_buff *msdu = desc_params->skb;
- s32 noise_floor;
- struct ieee80211_tx_status status = {};
- struct ieee80211_rate_status status_rate = {};
- struct ath12k_peer *peer;
- struct ath12k_link_sta *arsta;
- struct ath12k_sta *ahsta;
- struct rate_info rate;
-
- if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) {
- /* Must not happen */
- return;
- }
-
- skb_cb = ATH12K_SKB_CB(msdu);
- ab->device_stats.tx_completed[ring]++;
-
- dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
- if (skb_cb->paddr_ext_desc) {
- dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc,
- desc_params->skb_ext_desc->len, DMA_TO_DEVICE);
- dev_kfree_skb_any(desc_params->skb_ext_desc);
- }
-
- rcu_read_lock();
-
- if (!rcu_dereference(ab->pdevs_active[ar->pdev_idx])) {
- ieee80211_free_txskb(ah->hw, msdu);
- goto exit;
- }
-
- if (!skb_cb->vif) {
- ieee80211_free_txskb(ah->hw, msdu);
- goto exit;
- }
-
- vif = skb_cb->vif;
- if (vif) {
- ahvif = ath12k_vif_to_ahvif(vif);
- arvif = rcu_dereference(ahvif->link[skb_cb->link_id]);
- if (arvif) {
- spin_lock_bh(&arvif->link_stats_lock);
- arvif->link_stats.tx_completed++;
- spin_unlock_bh(&arvif->link_stats_lock);
- }
- }
-
- info = IEEE80211_SKB_CB(msdu);
- memset(&info->status, 0, sizeof(info->status));
-
- /* skip tx rate update from ieee80211_status*/
- info->status.rates[0].idx = -1;
-
- switch (ts->status) {
- case HAL_WBM_TQM_REL_REASON_FRAME_ACKED:
- if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
- info->flags |= IEEE80211_TX_STAT_ACK;
- info->status.ack_signal = ts->ack_rssi;
-
- if (!test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT,
- ab->wmi_ab.svc_map)) {
- spin_lock_bh(&ar->data_lock);
- noise_floor = ath12k_pdev_get_noise_floor(ar);
- spin_unlock_bh(&ar->data_lock);
-
- info->status.ack_signal += noise_floor;
- }
-
- info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID;
- }
- break;
- case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_TX:
- if (info->flags & IEEE80211_TX_CTL_NO_ACK) {
- info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
- break;
- }
- fallthrough;
- case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_MPDU:
- case HAL_WBM_TQM_REL_REASON_DROP_THRESHOLD:
- case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_AGED_FRAMES:
- /* The failure status is due to internal firmware tx failure
- * hence drop the frame; do not update the status of frame to
- * the upper layer
- */
- ieee80211_free_txskb(ah->hw, msdu);
- goto exit;
- default:
- ath12k_dbg(ab, ATH12K_DBG_DP_TX, "tx frame is not acked status %d\n",
- ts->status);
- break;
- }
-
- /* NOTE: Tx rate status reporting. Tx completion status does not have
- * necessary information (for example nss) to build the tx rate.
- * Might end up reporting it out-of-band from HTT stats.
- */
-
- ath12k_dp_tx_update_txcompl(ar, ts);
-
- spin_lock_bh(&ab->base_lock);
- peer = ath12k_peer_find_by_id(ab, ts->peer_id);
- if (!peer || !peer->sta) {
- ath12k_err(ab,
- "dp_tx: failed to find the peer with peer_id %d\n",
- ts->peer_id);
- spin_unlock_bh(&ab->base_lock);
- ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu);
- goto exit;
- }
- ahsta = ath12k_sta_to_ahsta(peer->sta);
- arsta = &ahsta->deflink;
-
- spin_unlock_bh(&ab->base_lock);
-
- status.sta = peer->sta;
- status.info = info;
- status.skb = msdu;
- rate = arsta->last_txrate;
-
- status_rate.rate_idx = rate;
- status_rate.try_count = 1;
-
- status.rates = &status_rate;
- status.n_rates = 1;
- ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status);
-
-exit:
- rcu_read_unlock();
-}
-
-static void ath12k_dp_tx_status_parse(struct ath12k_base *ab,
- struct hal_wbm_completion_ring_tx *desc,
- struct hal_tx_status *ts)
-{
- u32 info0 = le32_to_cpu(desc->rate_stats.info0);
-
- ts->buf_rel_source =
- le32_get_bits(desc->info0, HAL_WBM_COMPL_TX_INFO0_REL_SRC_MODULE);
- if (ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_FW &&
- ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)
- return;
-
- if (ts->buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW)
- return;
-
- ts->status = le32_get_bits(desc->info0,
- HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON);
-
- ts->ppdu_id = le32_get_bits(desc->info1,
- HAL_WBM_COMPL_TX_INFO1_TQM_STATUS_NUMBER);
-
- ts->peer_id = le32_get_bits(desc->info3, HAL_WBM_COMPL_TX_INFO3_PEER_ID);
-
- ts->ack_rssi = le32_get_bits(desc->info2,
- HAL_WBM_COMPL_TX_INFO2_ACK_FRAME_RSSI);
-
- if (info0 & HAL_TX_RATE_STATS_INFO0_VALID) {
- ts->pkt_type = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_PKT_TYPE);
- ts->mcs = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_MCS);
- ts->sgi = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_SGI);
- ts->bw = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_BW);
- ts->tones = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_TONES_IN_RU);
- ts->ofdma = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_OFDMA_TX);
- }
-}
-
-void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id)
-{
- struct ath12k *ar;
- struct ath12k_dp *dp = &ab->dp;
- int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id;
- struct hal_srng *status_ring = &ab->hal.srng_list[hal_ring_id];
- struct ath12k_tx_desc_info *tx_desc = NULL;
- struct hal_tx_status ts = {};
- struct ath12k_tx_desc_params desc_params;
- struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id];
- struct hal_wbm_release_ring *desc;
- u8 pdev_id;
- u64 desc_va;
- enum hal_wbm_rel_src_module buf_rel_source;
- enum hal_wbm_tqm_rel_reason rel_status;
-
- spin_lock_bh(&status_ring->lock);
-
- ath12k_hal_srng_access_begin(ab, status_ring);
-
- while (ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_head) !=
- tx_ring->tx_status_tail) {
- desc = ath12k_hal_srng_dst_get_next_entry(ab, status_ring);
- if (!desc)
- break;
-
- memcpy(&tx_ring->tx_status[tx_ring->tx_status_head],
- desc, sizeof(*desc));
- tx_ring->tx_status_head =
- ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_head);
- }
-
- if (ath12k_hal_srng_dst_peek(ab, status_ring) &&
- (ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_head) ==
- tx_ring->tx_status_tail)) {
- /* TODO: Process pending tx_status messages when kfifo_is_full() */
- ath12k_warn(ab, "Unable to process some of the tx_status ring desc because status_fifo is full\n");
- }
-
- ath12k_hal_srng_access_end(ab, status_ring);
-
- spin_unlock_bh(&status_ring->lock);
-
- while (ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_tail) !=
- tx_ring->tx_status_head) {
- struct hal_wbm_completion_ring_tx *tx_status;
- u32 desc_id;
-
- tx_ring->tx_status_tail =
- ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_tail);
- tx_status = &tx_ring->tx_status[tx_ring->tx_status_tail];
- ath12k_dp_tx_status_parse(ab, tx_status, &ts);
-
- if (le32_get_bits(tx_status->info0, HAL_WBM_COMPL_TX_INFO0_CC_DONE)) {
- /* HW done cookie conversion */
- desc_va = ((u64)le32_to_cpu(tx_status->buf_va_hi) << 32 |
- le32_to_cpu(tx_status->buf_va_lo));
- tx_desc = (struct ath12k_tx_desc_info *)((unsigned long)desc_va);
- } else {
- /* SW does cookie conversion to VA */
- desc_id = le32_get_bits(tx_status->buf_va_hi,
- BUFFER_ADDR_INFO1_SW_COOKIE);
-
- tx_desc = ath12k_dp_get_tx_desc(ab, desc_id);
- }
- if (!tx_desc) {
- ath12k_warn(ab, "unable to retrieve tx_desc!");
- continue;
- }
-
- desc_params.mac_id = tx_desc->mac_id;
- desc_params.skb = tx_desc->skb;
- desc_params.skb_ext_desc = tx_desc->skb_ext_desc;
-
- /* Find the HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE value */
- buf_rel_source = le32_get_bits(tx_status->info0,
- HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE);
- ab->device_stats.tx_wbm_rel_source[buf_rel_source]++;
-
- rel_status = le32_get_bits(tx_status->info0,
- HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON);
- ab->device_stats.tqm_rel_reason[rel_status]++;
-
- /* Release descriptor as soon as extracting necessary info
- * to reduce contention
- */
- ath12k_dp_tx_release_txbuf(dp, tx_desc, tx_desc->pool_id);
- if (ts.buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW) {
- ath12k_dp_tx_process_htt_tx_complete(ab, (void *)tx_status,
- tx_ring, &desc_params);
- continue;
- }
-
- pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, desc_params.mac_id);
- ar = ab->pdevs[pdev_id].ar;
-
- if (atomic_dec_and_test(&ar->dp.num_tx_pending))
- wake_up(&ar->dp.tx_empty_waitq);
-
- ath12k_dp_tx_complete_msdu(ar, &desc_params, &ts,
- tx_ring->tcl_data_ring_id);
- }
-}
-
static int
ath12k_dp_tx_get_ring_id_type(struct ath12k_base *ab,
int mac_id, u32 ring_id,
diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.h b/drivers/net/wireless/ath/ath12k/dp_tx.h
index aa2f6397bc83..67ab7b3f55ea 100644
--- a/drivers/net/wireless/ath/ath12k/dp_tx.h
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.h
@@ -19,8 +19,6 @@ int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab);
int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif,
struct sk_buff *skb, bool gsn_valid, int mcbc_gsn,
bool is_mcast);
-void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id);
-
int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask);
int
ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type,
@@ -38,4 +36,20 @@ int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id,
int tx_buf_size,
struct htt_tx_ring_tlv_filter *htt_tlv_filter);
int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset);
+
+enum hal_tcl_encap_type
+ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb);
+void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb);
+u8 ath12k_dp_tx_get_tid(struct sk_buff *skb);
+void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len);
+int ath12k_dp_tx_align_payload(struct ath12k_base *ab,
+ struct sk_buff **pskb);
+void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp,
+ struct ath12k_tx_desc_info *tx_desc,
+ u8 pool_id);
+struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp,
+ u8 pool_id);
+void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab,
+ struct dp_tx_ring *tx_ring,
+ struct ath12k_tx_desc_params *desc_params);
#endif
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index bd1ec3b2c084..996d0b425c10 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <net/mac80211.h>
@@ -14,6 +14,7 @@
#include "wmi.h"
#include "hw.h"
#include "dp_tx.h"
+#include "wifi7/dp_tx.h"
#include "dp_rx.h"
#include "testmode.h"
#include "peer.h"
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c
index 2e7b9bbd3d8e..afe791394e6b 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c
@@ -10,6 +10,7 @@
#include "../dp_mon.h"
#include "dp_rx.h"
#include "dp.h"
+#include "dp_tx.h"
int ath12k_dp_service_srng(struct ath12k_base *ab,
struct ath12k_ext_irq_grp *irq_grp,
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
new file mode 100644
index 000000000000..149e211aa225
--- /dev/null
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
@@ -0,0 +1,545 @@
+// SPDX-License-Identifier: BSD-3-Clause-Clear
+/*
+ * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include "../core.h"
+#include "../debug.h"
+#include "../dp_tx.h"
+#include "../peer.h"
+#include "dp_tx.h"
+
+static void
+ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab,
+ struct ath12k_tx_desc_params *desc_params,
+ struct dp_tx_ring *tx_ring,
+ struct ath12k_dp_htt_wbm_tx_status *ts,
+ u16 peer_id)
+{
+ struct ieee80211_tx_info *info;
+ struct ath12k_link_vif *arvif;
+ struct ath12k_skb_cb *skb_cb;
+ struct ieee80211_vif *vif;
+ struct ath12k_vif *ahvif;
+ struct ath12k *ar;
+ struct sk_buff *msdu = desc_params->skb;
+ s32 noise_floor;
+ struct ieee80211_tx_status status = {};
+ struct ath12k_peer *peer;
+
+ skb_cb = ATH12K_SKB_CB(msdu);
+ info = IEEE80211_SKB_CB(msdu);
+
+ ar = skb_cb->ar;
+ ab->device_stats.tx_completed[tx_ring->tcl_data_ring_id]++;
+
+ if (atomic_dec_and_test(&ar->dp.num_tx_pending))
+ wake_up(&ar->dp.tx_empty_waitq);
+
+ dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
+ if (skb_cb->paddr_ext_desc) {
+ dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc,
+ desc_params->skb_ext_desc->len, DMA_TO_DEVICE);
+ dev_kfree_skb_any(desc_params->skb_ext_desc);
+ }
+
+ vif = skb_cb->vif;
+ if (vif) {
+ ahvif = ath12k_vif_to_ahvif(vif);
+ rcu_read_lock();
+ arvif = rcu_dereference(ahvif->link[skb_cb->link_id]);
+ if (arvif) {
+ spin_lock_bh(&arvif->link_stats_lock);
+ arvif->link_stats.tx_completed++;
+ spin_unlock_bh(&arvif->link_stats_lock);
+ }
+ rcu_read_unlock();
+ }
+
+ memset(&info->status, 0, sizeof(info->status));
+
+ if (ts->acked) {
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ info->status.ack_signal = ts->ack_rssi;
+
+ if (!test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT,
+ ab->wmi_ab.svc_map)) {
+ spin_lock_bh(&ar->data_lock);
+ noise_floor = ath12k_pdev_get_noise_floor(ar);
+ spin_unlock_bh(&ar->data_lock);
+
+ info->status.ack_signal += noise_floor;
+ }
+
+ info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID;
+ } else {
+ info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
+ }
+ }
+ rcu_read_lock();
+ spin_lock_bh(&ab->base_lock);
+ peer = ath12k_peer_find_by_id(ab, peer_id);
+ if (!peer || !peer->sta) {
+ ath12k_dbg(ab, ATH12K_DBG_DATA,
+ "dp_tx: failed to find the peer with peer_id %d\n", peer_id);
+ spin_unlock_bh(&ab->base_lock);
+ ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu);
+ goto exit;
+ } else {
+ status.sta = peer->sta;
+ }
+ spin_unlock_bh(&ab->base_lock);
+
+ status.info = info;
+ status.skb = msdu;
+ ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status);
+exit:
+ rcu_read_unlock();
+}
+
+static void
+ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc,
+ struct dp_tx_ring *tx_ring,
+ struct ath12k_tx_desc_params *desc_params)
+{
+ struct htt_tx_wbm_completion *status_desc;
+ struct ath12k_dp_htt_wbm_tx_status ts = {};
+ enum hal_wbm_htt_tx_comp_status wbm_status;
+ u16 peer_id;
+
+ status_desc = desc;
+
+ wbm_status = le32_get_bits(status_desc->info0,
+ HTT_TX_WBM_COMP_INFO0_STATUS);
+ ab->device_stats.fw_tx_status[wbm_status]++;
+
+ switch (wbm_status) {
+ case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK:
+ ts.acked = (wbm_status == HAL_WBM_REL_HTT_TX_COMP_STATUS_OK);
+ ts.ack_rssi = le32_get_bits(status_desc->info2,
+ HTT_TX_WBM_COMP_INFO2_ACK_RSSI);
+
+ peer_id = le32_get_bits(((struct hal_wbm_completion_ring_tx *)desc)->
+ info3, HAL_WBM_COMPL_TX_INFO3_PEER_ID);
+
+ ath12k_dp_tx_htt_tx_complete_buf(ab, desc_params, tx_ring, &ts, peer_id);
+ break;
+ case HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP:
+ case HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL:
+ case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ:
+ case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT:
+ case HAL_WBM_REL_HTT_TX_COMP_STATUS_VDEVID_MISMATCH:
+ ath12k_dp_tx_free_txbuf(ab, tx_ring, desc_params);
+ break;
+ case HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY:
+ /* This event is to be handled only when the driver decides to
+ * use WDS offload functionality.
+ */
+ break;
+ default:
+ ath12k_warn(ab, "Unknown htt wbm tx status %d\n", wbm_status);
+ break;
+ }
+}
+
+static void ath12k_dp_tx_update_txcompl(struct ath12k *ar, struct hal_tx_status *ts)
+{
+ struct ath12k_base *ab = ar->ab;
+ struct ath12k_peer *peer;
+ struct ieee80211_sta *sta;
+ struct ath12k_sta *ahsta;
+ struct ath12k_link_sta *arsta;
+ struct rate_info txrate = {};
+ u16 rate, ru_tones;
+ u8 rate_idx = 0;
+ int ret;
+
+ spin_lock_bh(&ab->base_lock);
+ peer = ath12k_peer_find_by_id(ab, ts->peer_id);
+ if (!peer || !peer->sta) {
+ ath12k_dbg(ab, ATH12K_DBG_DP_TX,
+ "failed to find the peer by id %u\n", ts->peer_id);
+ spin_unlock_bh(&ab->base_lock);
+ return;
+ }
+ sta = peer->sta;
+ ahsta = ath12k_sta_to_ahsta(sta);
+ arsta = &ahsta->deflink;
+
+ /* This is to prefer choose the real NSS value arsta->last_txrate.nss,
+ * if it is invalid, then choose the NSS value while assoc.
+ */
+ if (arsta->last_txrate.nss)
+ txrate.nss = arsta->last_txrate.nss;
+ else
+ txrate.nss = arsta->peer_nss;
+ spin_unlock_bh(&ab->base_lock);
+
+ switch (ts->pkt_type) {
+ case HAL_TX_RATE_STATS_PKT_TYPE_11A:
+ case HAL_TX_RATE_STATS_PKT_TYPE_11B:
+ ret = ath12k_mac_hw_ratecode_to_legacy_rate(ts->mcs,
+ ts->pkt_type,
+ &rate_idx,
+ &rate);
+ if (ret < 0) {
+ ath12k_warn(ab, "Invalid tx legacy rate %d\n", ret);
+ return;
+ }
+
+ txrate.legacy = rate;
+ break;
+ case HAL_TX_RATE_STATS_PKT_TYPE_11N:
+ if (ts->mcs > ATH12K_HT_MCS_MAX) {
+ ath12k_warn(ab, "Invalid HT mcs index %d\n", ts->mcs);
+ return;
+ }
+
+ if (txrate.nss != 0)
+ txrate.mcs = ts->mcs + 8 * (txrate.nss - 1);
+
+ txrate.flags = RATE_INFO_FLAGS_MCS;
+
+ if (ts->sgi)
+ txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+ break;
+ case HAL_TX_RATE_STATS_PKT_TYPE_11AC:
+ if (ts->mcs > ATH12K_VHT_MCS_MAX) {
+ ath12k_warn(ab, "Invalid VHT mcs index %d\n", ts->mcs);
+ return;
+ }
+
+ txrate.mcs = ts->mcs;
+ txrate.flags = RATE_INFO_FLAGS_VHT_MCS;
+
+ if (ts->sgi)
+ txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+ break;
+ case HAL_TX_RATE_STATS_PKT_TYPE_11AX:
+ if (ts->mcs > ATH12K_HE_MCS_MAX) {
+ ath12k_warn(ab, "Invalid HE mcs index %d\n", ts->mcs);
+ return;
+ }
+
+ txrate.mcs = ts->mcs;
+ txrate.flags = RATE_INFO_FLAGS_HE_MCS;
+ txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(ts->sgi);
+ break;
+ case HAL_TX_RATE_STATS_PKT_TYPE_11BE:
+ if (ts->mcs > ATH12K_EHT_MCS_MAX) {
+ ath12k_warn(ab, "Invalid EHT mcs index %d\n", ts->mcs);
+ return;
+ }
+
+ txrate.mcs = ts->mcs;
+ txrate.flags = RATE_INFO_FLAGS_EHT_MCS;
+ txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(ts->sgi);
+ break;
+ default:
+ ath12k_warn(ab, "Invalid tx pkt type: %d\n", ts->pkt_type);
+ return;
+ }
+
+ txrate.bw = ath12k_mac_bw_to_mac80211_bw(ts->bw);
+
+ if (ts->ofdma && ts->pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11AX) {
+ txrate.bw = RATE_INFO_BW_HE_RU;
+ ru_tones = ath12k_mac_he_convert_tones_to_ru_tones(ts->tones);
+ txrate.he_ru_alloc =
+ ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones);
+ }
+
+ if (ts->ofdma && ts->pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11BE) {
+ txrate.bw = RATE_INFO_BW_EHT_RU;
+ txrate.eht_ru_alloc =
+ ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(ts->tones);
+ }
+
+ spin_lock_bh(&ab->base_lock);
+ arsta->txrate = txrate;
+ spin_unlock_bh(&ab->base_lock);
+}
+
+static void ath12k_dp_tx_complete_msdu(struct ath12k *ar,
+ struct ath12k_tx_desc_params *desc_params,
+ struct hal_tx_status *ts,
+ int ring)
+{
+ struct ath12k_base *ab = ar->ab;
+ struct ath12k_hw *ah = ar->ah;
+ struct ieee80211_tx_info *info;
+ struct ath12k_link_vif *arvif;
+ struct ath12k_skb_cb *skb_cb;
+ struct ieee80211_vif *vif;
+ struct ath12k_vif *ahvif;
+ struct sk_buff *msdu = desc_params->skb;
+ s32 noise_floor;
+ struct ieee80211_tx_status status = {};
+ struct ieee80211_rate_status status_rate = {};
+ struct ath12k_peer *peer;
+ struct ath12k_link_sta *arsta;
+ struct ath12k_sta *ahsta;
+ struct rate_info rate;
+
+ if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) {
+ /* Must not happen */
+ return;
+ }
+
+ skb_cb = ATH12K_SKB_CB(msdu);
+ ab->device_stats.tx_completed[ring]++;
+
+ dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
+ if (skb_cb->paddr_ext_desc) {
+ dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc,
+ desc_params->skb_ext_desc->len, DMA_TO_DEVICE);
+ dev_kfree_skb_any(desc_params->skb_ext_desc);
+ }
+
+ rcu_read_lock();
+
+ if (!rcu_dereference(ab->pdevs_active[ar->pdev_idx])) {
+ ieee80211_free_txskb(ah->hw, msdu);
+ goto exit;
+ }
+
+ if (!skb_cb->vif) {
+ ieee80211_free_txskb(ah->hw, msdu);
+ goto exit;
+ }
+
+ vif = skb_cb->vif;
+ if (vif) {
+ ahvif = ath12k_vif_to_ahvif(vif);
+ arvif = rcu_dereference(ahvif->link[skb_cb->link_id]);
+ if (arvif) {
+ spin_lock_bh(&arvif->link_stats_lock);
+ arvif->link_stats.tx_completed++;
+ spin_unlock_bh(&arvif->link_stats_lock);
+ }
+ }
+
+ info = IEEE80211_SKB_CB(msdu);
+ memset(&info->status, 0, sizeof(info->status));
+
+ /* skip tx rate update from ieee80211_status*/
+ info->status.rates[0].idx = -1;
+
+ switch (ts->status) {
+ case HAL_WBM_TQM_REL_REASON_FRAME_ACKED:
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ info->status.ack_signal = ts->ack_rssi;
+
+ if (!test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT,
+ ab->wmi_ab.svc_map)) {
+ spin_lock_bh(&ar->data_lock);
+ noise_floor = ath12k_pdev_get_noise_floor(ar);
+ spin_unlock_bh(&ar->data_lock);
+
+ info->status.ack_signal += noise_floor;
+ }
+
+ info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID;
+ }
+ break;
+ case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_TX:
+ if (info->flags & IEEE80211_TX_CTL_NO_ACK) {
+ info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
+ break;
+ }
+ fallthrough;
+ case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_MPDU:
+ case HAL_WBM_TQM_REL_REASON_DROP_THRESHOLD:
+ case HAL_WBM_TQM_REL_REASON_CMD_REMOVE_AGED_FRAMES:
+ /* The failure status is due to internal firmware tx failure
+ * hence drop the frame; do not update the status of frame to
+ * the upper layer
+ */
+ ieee80211_free_txskb(ah->hw, msdu);
+ goto exit;
+ default:
+ ath12k_dbg(ab, ATH12K_DBG_DP_TX, "tx frame is not acked status %d\n",
+ ts->status);
+ break;
+ }
+
+ /* NOTE: Tx rate status reporting. Tx completion status does not have
+ * necessary information (for example nss) to build the tx rate.
+ * Might end up reporting it out-of-band from HTT stats.
+ */
+
+ ath12k_dp_tx_update_txcompl(ar, ts);
+
+ spin_lock_bh(&ab->base_lock);
+ peer = ath12k_peer_find_by_id(ab, ts->peer_id);
+ if (!peer || !peer->sta) {
+ ath12k_err(ab,
+ "dp_tx: failed to find the peer with peer_id %d\n",
+ ts->peer_id);
+ spin_unlock_bh(&ab->base_lock);
+ ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu);
+ goto exit;
+ }
+ ahsta = ath12k_sta_to_ahsta(peer->sta);
+ arsta = &ahsta->deflink;
+
+ spin_unlock_bh(&ab->base_lock);
+
+ status.sta = peer->sta;
+ status.info = info;
+ status.skb = msdu;
+ rate = arsta->last_txrate;
+
+ status_rate.rate_idx = rate;
+ status_rate.try_count = 1;
+
+ status.rates = &status_rate;
+ status.n_rates = 1;
+ ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status);
+
+exit:
+ rcu_read_unlock();
+}
+
+static void ath12k_dp_tx_status_parse(struct ath12k_base *ab,
+ struct hal_wbm_completion_ring_tx *desc,
+ struct hal_tx_status *ts)
+{
+ u32 info0 = le32_to_cpu(desc->rate_stats.info0);
+
+ ts->buf_rel_source =
+ le32_get_bits(desc->info0, HAL_WBM_COMPL_TX_INFO0_REL_SRC_MODULE);
+ if (ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_FW &&
+ ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)
+ return;
+
+ if (ts->buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW)
+ return;
+
+ ts->status = le32_get_bits(desc->info0,
+ HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON);
+
+ ts->ppdu_id = le32_get_bits(desc->info1,
+ HAL_WBM_COMPL_TX_INFO1_TQM_STATUS_NUMBER);
+
+ ts->peer_id = le32_get_bits(desc->info3, HAL_WBM_COMPL_TX_INFO3_PEER_ID);
+
+ ts->ack_rssi = le32_get_bits(desc->info2,
+ HAL_WBM_COMPL_TX_INFO2_ACK_FRAME_RSSI);
+
+ if (info0 & HAL_TX_RATE_STATS_INFO0_VALID) {
+ ts->pkt_type = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_PKT_TYPE);
+ ts->mcs = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_MCS);
+ ts->sgi = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_SGI);
+ ts->bw = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_BW);
+ ts->tones = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_TONES_IN_RU);
+ ts->ofdma = u32_get_bits(info0, HAL_TX_RATE_STATS_INFO0_OFDMA_TX);
+ }
+}
+
+void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id)
+{
+ struct ath12k *ar;
+ struct ath12k_dp *dp = &ab->dp;
+ int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id;
+ struct hal_srng *status_ring = &ab->hal.srng_list[hal_ring_id];
+ struct ath12k_tx_desc_info *tx_desc = NULL;
+ struct hal_tx_status ts = {};
+ struct ath12k_tx_desc_params desc_params;
+ struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id];
+ struct hal_wbm_release_ring *desc;
+ u8 pdev_id;
+ u64 desc_va;
+ enum hal_wbm_rel_src_module buf_rel_source;
+ enum hal_wbm_tqm_rel_reason rel_status;
+
+ spin_lock_bh(&status_ring->lock);
+
+ ath12k_hal_srng_access_begin(ab, status_ring);
+
+ while (ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_head) !=
+ tx_ring->tx_status_tail) {
+ desc = ath12k_hal_srng_dst_get_next_entry(ab, status_ring);
+ if (!desc)
+ break;
+
+ memcpy(&tx_ring->tx_status[tx_ring->tx_status_head],
+ desc, sizeof(*desc));
+ tx_ring->tx_status_head =
+ ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_head);
+ }
+
+ if (ath12k_hal_srng_dst_peek(ab, status_ring) &&
+ (ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_head) ==
+ tx_ring->tx_status_tail)) {
+ /* TODO: Process pending tx_status messages when kfifo_is_full() */
+ ath12k_warn(ab, "Unable to process some of the tx_status ring desc because status_fifo is full\n");
+ }
+
+ ath12k_hal_srng_access_end(ab, status_ring);
+
+ spin_unlock_bh(&status_ring->lock);
+
+ while (ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_tail) !=
+ tx_ring->tx_status_head) {
+ struct hal_wbm_completion_ring_tx *tx_status;
+ u32 desc_id;
+
+ tx_ring->tx_status_tail =
+ ATH12K_TX_COMPL_NEXT(ab, tx_ring->tx_status_tail);
+ tx_status = &tx_ring->tx_status[tx_ring->tx_status_tail];
+ ath12k_dp_tx_status_parse(ab, tx_status, &ts);
+
+ if (le32_get_bits(tx_status->info0, HAL_WBM_COMPL_TX_INFO0_CC_DONE)) {
+ /* HW done cookie conversion */
+ desc_va = ((u64)le32_to_cpu(tx_status->buf_va_hi) << 32 |
+ le32_to_cpu(tx_status->buf_va_lo));
+ tx_desc = (struct ath12k_tx_desc_info *)((unsigned long)desc_va);
+ } else {
+ /* SW does cookie conversion to VA */
+ desc_id = le32_get_bits(tx_status->buf_va_hi,
+ BUFFER_ADDR_INFO1_SW_COOKIE);
+
+ tx_desc = ath12k_dp_get_tx_desc(ab, desc_id);
+ }
+ if (!tx_desc) {
+ ath12k_warn(ab, "unable to retrieve tx_desc!");
+ continue;
+ }
+
+ desc_params.mac_id = tx_desc->mac_id;
+ desc_params.skb = tx_desc->skb;
+ desc_params.skb_ext_desc = tx_desc->skb_ext_desc;
+
+ /* Find the HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE value */
+ buf_rel_source = le32_get_bits(tx_status->info0,
+ HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE);
+ ab->device_stats.tx_wbm_rel_source[buf_rel_source]++;
+
+ rel_status = le32_get_bits(tx_status->info0,
+ HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON);
+ ab->device_stats.tqm_rel_reason[rel_status]++;
+
+ /* Release descriptor as soon as extracting necessary info
+ * to reduce contention
+ */
+ ath12k_dp_tx_release_txbuf(dp, tx_desc, tx_desc->pool_id);
+ if (ts.buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW) {
+ ath12k_dp_tx_process_htt_tx_complete(ab, (void *)tx_status,
+ tx_ring, &desc_params);
+ continue;
+ }
+
+ pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, desc_params.mac_id);
+ ar = ab->pdevs[pdev_id].ar;
+
+ if (atomic_dec_and_test(&ar->dp.num_tx_pending))
+ wake_up(&ar->dp.tx_empty_waitq);
+
+ ath12k_dp_tx_complete_msdu(ar, &desc_params, &ts,
+ tx_ring->tcl_data_ring_id);
+ }
+}
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h
new file mode 100644
index 000000000000..4361beb99666
--- /dev/null
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: BSD-3-Clause-Clear */
+/*
+ * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef ATH12K_DP_TX_WIFI7_H
+#define ATH12K_DP_TX_WIFI7_H
+
+void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id);
+#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 16/20] wifi: ath12k: Move ath12k_dp_tx and related APIs to wifi7 directory
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (14 preceding siblings ...)
2025-08-28 17:35 ` [PATCH ath12k-ng 15/20] wifi: ath12k: Move arch specific tx APIs " Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 17/20] wifi: ath12k: Move HTT code in dp.h to newly introduced files Ripan Deuri
` (6 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Move arch specific TX data path to wifi7 directory as part of Next
Generation (NG) Driver Framework.
Architecture specific APIs:
ath12k_hal_tx_cmd_ext_desc_setup
ath12k_dp_prepare_htt_metadata
ath12k_dp_tx
The moved APIs will be a part of dp_tx.c file inside wifi7 directory.
wifi7/dp_tx.c file will continue to be part of ath12k.ko temporarily
until the corresponding infra for movement to ath12k_wifi7.ko arrives
in upcoming patches.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Pavankumar Nandeshwar <quic_pnandesh@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/dp_tx.c | 363 ------------------
drivers/net/wireless/ath/ath12k/dp_tx.h | 3 -
drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 363 ++++++++++++++++++
drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h | 3 +
4 files changed, 366 insertions(+), 366 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c
index f1649744c78b..c7b0fc22c1a7 100644
--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
@@ -109,26 +109,6 @@ struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp,
return desc;
}
-static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab,
- struct hal_tx_msdu_ext_desc *tcl_ext_cmd,
- struct hal_tx_info *ti)
-{
- tcl_ext_cmd->info0 = le32_encode_bits(ti->paddr,
- HAL_TX_MSDU_EXT_INFO0_BUF_PTR_LO);
- tcl_ext_cmd->info1 = le32_encode_bits(0x0,
- HAL_TX_MSDU_EXT_INFO1_BUF_PTR_HI) |
- le32_encode_bits(ti->data_len,
- HAL_TX_MSDU_EXT_INFO1_BUF_LEN);
-
- tcl_ext_cmd->info1 |= le32_encode_bits(1, HAL_TX_MSDU_EXT_INFO1_EXTN_OVERRIDE) |
- le32_encode_bits(ti->encap_type,
- HAL_TX_MSDU_EXT_INFO1_ENCAP_TYPE) |
- le32_encode_bits(ti->encrypt_type,
- HAL_TX_MSDU_EXT_INFO1_ENCRYPT_TYPE);
-}
-
-#define HTT_META_DATA_ALIGNMENT 0x8
-
void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len)
{
struct sk_buff *tail;
@@ -142,29 +122,6 @@ void *ath12k_dp_metadata_align_skb(struct sk_buff *skb, u8 tail_len)
return metadata;
}
-/* Preparing HTT Metadata when utilized with ext MSDU */
-static int ath12k_dp_prepare_htt_metadata(struct sk_buff *skb)
-{
- struct hal_tx_msdu_metadata *desc_ext;
- u8 htt_desc_size;
- /* Size rounded of multiple of 8 bytes */
- u8 htt_desc_size_aligned;
-
- htt_desc_size = sizeof(struct hal_tx_msdu_metadata);
- htt_desc_size_aligned = ALIGN(htt_desc_size, HTT_META_DATA_ALIGNMENT);
-
- desc_ext = ath12k_dp_metadata_align_skb(skb, htt_desc_size_aligned);
- if (!desc_ext)
- return -ENOMEM;
-
- desc_ext->info0 = le32_encode_bits(1, HAL_TX_MSDU_METADATA_INFO0_ENCRYPT_FLAG) |
- le32_encode_bits(0, HAL_TX_MSDU_METADATA_INFO0_ENCRYPT_TYPE) |
- le32_encode_bits(1,
- HAL_TX_MSDU_METADATA_INFO0_HOST_TX_DESC_POOL);
-
- return 0;
-}
-
static void ath12k_dp_tx_move_payload(struct sk_buff *skb,
unsigned long delta,
bool head)
@@ -219,326 +176,6 @@ int ath12k_dp_tx_align_payload(struct ath12k_base *ab,
return ret;
}
-int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif,
- struct sk_buff *skb, bool gsn_valid, int mcbc_gsn,
- bool is_mcast)
-{
- struct ath12k_base *ab = ar->ab;
- struct ath12k_dp *dp = &ab->dp;
- struct hal_tx_info ti = {};
- struct ath12k_tx_desc_info *tx_desc;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb);
- struct hal_tcl_data_cmd *hal_tcl_desc;
- struct hal_tx_msdu_ext_desc *msg;
- struct sk_buff *skb_ext_desc = NULL;
- struct hal_srng *tcl_ring;
- struct ieee80211_hdr *hdr = (void *)skb->data;
- struct ath12k_vif *ahvif = arvif->ahvif;
- struct dp_tx_ring *tx_ring;
- u8 pool_id;
- u8 hal_ring_id;
- int ret;
- u8 ring_selector, ring_map = 0;
- bool tcl_ring_retry;
- bool msdu_ext_desc = false;
- bool add_htt_metadata = false;
- u32 iova_mask = ab->hw_params->iova_mask;
- bool is_diff_encap = false;
- bool is_null_frame = false;
-
- if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))
- return -ESHUTDOWN;
-
- if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&
- !ieee80211_is_data(hdr->frame_control))
- return -EOPNOTSUPP;
-
- pool_id = skb_get_queue_mapping(skb) & (ATH12K_HW_MAX_QUEUES - 1);
-
- /* Let the default ring selection be based on current processor
- * number, where one of the 3 tcl rings are selected based on
- * the smp_processor_id(). In case that ring
- * is full/busy, we resort to other available rings.
- * If all rings are full, we drop the packet.
- * TODO: Add throttling logic when all rings are full
- */
- ring_selector = ab->hw_params->hw_ops->get_ring_selector(skb);
-
-tcl_ring_sel:
- tcl_ring_retry = false;
- ti.ring_id = ring_selector % ab->hw_params->max_tx_ring;
-
- ring_map |= BIT(ti.ring_id);
- ti.rbm_id = ab->hw_params->hal_ops->tcl_to_wbm_rbm_map[ti.ring_id].rbm_id;
-
- tx_ring = &dp->tx_ring[ti.ring_id];
-
- tx_desc = ath12k_dp_tx_assign_buffer(dp, pool_id);
- if (!tx_desc)
- return -ENOMEM;
-
- ti.bank_id = arvif->bank_id;
- ti.meta_data_flags = arvif->tcl_metadata;
-
- if (ahvif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW &&
- test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) {
- if (skb_cb->flags & ATH12K_SKB_CIPHER_SET) {
- ti.encrypt_type =
- ath12k_dp_tx_get_encrypt_type(skb_cb->cipher);
-
- if (ieee80211_has_protected(hdr->frame_control))
- skb_put(skb, IEEE80211_CCMP_MIC_LEN);
- } else {
- ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN;
- }
-
- msdu_ext_desc = true;
- }
-
- if (gsn_valid) {
- /* Reset and Initialize meta_data_flags with Global Sequence
- * Number (GSN) info.
- */
- ti.meta_data_flags =
- u32_encode_bits(HTT_TCL_META_DATA_TYPE_GLOBAL_SEQ_NUM,
- HTT_TCL_META_DATA_TYPE) |
- u32_encode_bits(mcbc_gsn, HTT_TCL_META_DATA_GLOBAL_SEQ_NUM);
- }
-
- ti.encap_type = ath12k_dp_tx_get_encap_type(ab, skb);
- ti.addr_search_flags = arvif->hal_addr_search_flags;
- ti.search_type = arvif->search_type;
- ti.type = HAL_TCL_DESC_TYPE_BUFFER;
- ti.pkt_offset = 0;
- ti.lmac_id = ar->lmac_id;
-
- ti.vdev_id = arvif->vdev_id;
- if (gsn_valid)
- ti.vdev_id += HTT_TX_MLO_MCAST_HOST_REINJECT_BASE_VDEV_ID;
-
- ti.bss_ast_hash = arvif->ast_hash;
- ti.bss_ast_idx = arvif->ast_idx;
- ti.dscp_tid_tbl_idx = 0;
-
- if (skb->ip_summed == CHECKSUM_PARTIAL &&
- ti.encap_type != HAL_TCL_ENCAP_TYPE_RAW) {
- ti.flags0 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_IP4_CKSUM_EN) |
- u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_UDP4_CKSUM_EN) |
- u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_UDP6_CKSUM_EN) |
- u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TCP4_CKSUM_EN) |
- u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TCP6_CKSUM_EN);
- }
-
- ti.flags1 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO3_TID_OVERWRITE);
-
- ti.tid = ath12k_dp_tx_get_tid(skb);
-
- switch (ti.encap_type) {
- case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI:
- is_null_frame = ieee80211_is_nullfunc(hdr->frame_control);
- if (ahvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) {
- if (skb->protocol == cpu_to_be16(ETH_P_PAE) || is_null_frame)
- is_diff_encap = true;
-
- /* Firmware expects msdu ext descriptor for nwifi/raw packets
- * received in ETH mode. Without this, observed tx fail for
- * Multicast packets in ETH mode.
- */
- msdu_ext_desc = true;
- } else {
- ath12k_dp_tx_encap_nwifi(skb);
- }
- break;
- case HAL_TCL_ENCAP_TYPE_RAW:
- if (!test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) {
- ret = -EINVAL;
- goto fail_remove_tx_buf;
- }
- break;
- case HAL_TCL_ENCAP_TYPE_ETHERNET:
- /* no need to encap */
- break;
- case HAL_TCL_ENCAP_TYPE_802_3:
- default:
- /* TODO: Take care of other encap modes as well */
- ret = -EINVAL;
- atomic_inc(&ab->device_stats.tx_err.misc_fail);
- goto fail_remove_tx_buf;
- }
-
- if (iova_mask &&
- (unsigned long)skb->data & iova_mask) {
- ret = ath12k_dp_tx_align_payload(ab, &skb);
- if (ret) {
- ath12k_warn(ab, "failed to align TX buffer %d\n", ret);
- /* don't bail out, give original buffer
- * a chance even unaligned.
- */
- goto map;
- }
-
- /* hdr is pointing to a wrong place after alignment,
- * so refresh it for later use.
- */
- hdr = (void *)skb->data;
- }
-map:
- ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE);
- if (dma_mapping_error(ab->dev, ti.paddr)) {
- atomic_inc(&ab->device_stats.tx_err.misc_fail);
- ath12k_warn(ab, "failed to DMA map data Tx buffer\n");
- ret = -ENOMEM;
- goto fail_remove_tx_buf;
- }
-
- if ((!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) &&
- !(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) &&
- !(skb_cb->flags & ATH12K_SKB_CIPHER_SET) &&
- ieee80211_has_protected(hdr->frame_control)) ||
- is_diff_encap) {
- /* Firmware is not expecting meta data for qos null
- * nwifi packet received in ETH encap mode.
- */
- if (is_null_frame && msdu_ext_desc)
- goto skip_htt_meta;
-
- /* Add metadata for sw encrypted vlan group traffic
- * and EAPOL nwifi packet received in ETH encap mode.
- */
- add_htt_metadata = true;
- msdu_ext_desc = true;
- ti.meta_data_flags |= HTT_TCL_META_DATA_VALID_HTT;
-skip_htt_meta:
- ti.flags0 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TO_FW);
- ti.encap_type = HAL_TCL_ENCAP_TYPE_RAW;
- ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN;
- }
-
- tx_desc->skb = skb;
- tx_desc->mac_id = ar->pdev_idx;
- ti.desc_id = tx_desc->desc_id;
- ti.data_len = skb->len;
- skb_cb->paddr = ti.paddr;
- skb_cb->vif = ahvif->vif;
- skb_cb->ar = ar;
-
- if (msdu_ext_desc) {
- skb_ext_desc = dev_alloc_skb(sizeof(struct hal_tx_msdu_ext_desc));
- if (!skb_ext_desc) {
- ret = -ENOMEM;
- goto fail_unmap_dma;
- }
-
- skb_put(skb_ext_desc, sizeof(struct hal_tx_msdu_ext_desc));
- memset(skb_ext_desc->data, 0, skb_ext_desc->len);
-
- msg = (struct hal_tx_msdu_ext_desc *)skb_ext_desc->data;
- ath12k_hal_tx_cmd_ext_desc_setup(ab, msg, &ti);
-
- if (add_htt_metadata) {
- ret = ath12k_dp_prepare_htt_metadata(skb_ext_desc);
- if (ret < 0) {
- ath12k_dbg(ab, ATH12K_DBG_DP_TX,
- "Failed to add HTT meta data, dropping packet\n");
- goto fail_free_ext_skb;
- }
- }
-
- ti.paddr = dma_map_single(ab->dev, skb_ext_desc->data,
- skb_ext_desc->len, DMA_TO_DEVICE);
- ret = dma_mapping_error(ab->dev, ti.paddr);
- if (ret)
- goto fail_free_ext_skb;
-
- ti.data_len = skb_ext_desc->len;
- ti.type = HAL_TCL_DESC_TYPE_EXT_DESC;
-
- skb_cb->paddr_ext_desc = ti.paddr;
- tx_desc->skb_ext_desc = skb_ext_desc;
- }
-
- hal_ring_id = tx_ring->tcl_data_ring.ring_id;
- tcl_ring = &ab->hal.srng_list[hal_ring_id];
-
- spin_lock_bh(&tcl_ring->lock);
-
- ath12k_hal_srng_access_begin(ab, tcl_ring);
-
- hal_tcl_desc = ath12k_hal_srng_src_get_next_entry(ab, tcl_ring);
- if (!hal_tcl_desc) {
- /* NOTE: It is highly unlikely we'll be running out of tcl_ring
- * desc because the desc is directly enqueued onto hw queue.
- */
- ath12k_hal_srng_access_end(ab, tcl_ring);
- ab->device_stats.tx_err.desc_na[ti.ring_id]++;
- spin_unlock_bh(&tcl_ring->lock);
- ret = -ENOMEM;
-
- /* Checking for available tcl descriptors in another ring in
- * case of failure due to full tcl ring now, is better than
- * checking this ring earlier for each pkt tx.
- * Restart ring selection if some rings are not checked yet.
- */
- if (ring_map != (BIT(ab->hw_params->max_tx_ring) - 1) &&
- ab->hw_params->tcl_ring_retry) {
- tcl_ring_retry = true;
- ring_selector++;
- }
-
- goto fail_unmap_dma_ext;
- }
-
- spin_lock_bh(&arvif->link_stats_lock);
- arvif->link_stats.tx_encap_type[ti.encap_type]++;
- arvif->link_stats.tx_encrypt_type[ti.encrypt_type]++;
- arvif->link_stats.tx_desc_type[ti.type]++;
-
- if (is_mcast)
- arvif->link_stats.tx_bcast_mcast++;
- else
- arvif->link_stats.tx_enqueued++;
- spin_unlock_bh(&arvif->link_stats_lock);
-
- ab->device_stats.tx_enqueued[ti.ring_id]++;
-
- ath12k_hal_tx_cmd_desc_setup(ab, hal_tcl_desc, &ti);
-
- ath12k_hal_srng_access_end(ab, tcl_ring);
-
- spin_unlock_bh(&tcl_ring->lock);
-
- ath12k_dbg_dump(ab, ATH12K_DBG_DP_TX, NULL, "dp tx msdu: ",
- skb->data, skb->len);
-
- atomic_inc(&ar->dp.num_tx_pending);
-
- return 0;
-
-fail_unmap_dma_ext:
- if (skb_cb->paddr_ext_desc)
- dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc,
- skb_ext_desc->len,
- DMA_TO_DEVICE);
-fail_free_ext_skb:
- kfree_skb(skb_ext_desc);
-
-fail_unmap_dma:
- dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE);
-
-fail_remove_tx_buf:
- ath12k_dp_tx_release_txbuf(dp, tx_desc, pool_id);
-
- spin_lock_bh(&arvif->link_stats_lock);
- arvif->link_stats.tx_dropped++;
- spin_unlock_bh(&arvif->link_stats_lock);
-
- if (tcl_ring_retry)
- goto tcl_ring_sel;
-
- return ret;
-}
-
void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab,
struct dp_tx_ring *tx_ring,
struct ath12k_tx_desc_params *desc_params)
diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.h b/drivers/net/wireless/ath/ath12k/dp_tx.h
index 67ab7b3f55ea..8405a0baf95b 100644
--- a/drivers/net/wireless/ath/ath12k/dp_tx.h
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.h
@@ -16,9 +16,6 @@ struct ath12k_dp_htt_wbm_tx_status {
};
int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab);
-int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif,
- struct sk_buff *skb, bool gsn_valid, int mcbc_gsn,
- bool is_mcast);
int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask);
int
ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type,
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
index 149e211aa225..49d219a195c5 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
@@ -10,6 +10,369 @@
#include "../peer.h"
#include "dp_tx.h"
+static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab,
+ struct hal_tx_msdu_ext_desc *tcl_ext_cmd,
+ struct hal_tx_info *ti)
+{
+ tcl_ext_cmd->info0 = le32_encode_bits(ti->paddr,
+ HAL_TX_MSDU_EXT_INFO0_BUF_PTR_LO);
+ tcl_ext_cmd->info1 = le32_encode_bits(0x0,
+ HAL_TX_MSDU_EXT_INFO1_BUF_PTR_HI) |
+ le32_encode_bits(ti->data_len,
+ HAL_TX_MSDU_EXT_INFO1_BUF_LEN);
+
+ tcl_ext_cmd->info1 |= le32_encode_bits(1, HAL_TX_MSDU_EXT_INFO1_EXTN_OVERRIDE) |
+ le32_encode_bits(ti->encap_type,
+ HAL_TX_MSDU_EXT_INFO1_ENCAP_TYPE) |
+ le32_encode_bits(ti->encrypt_type,
+ HAL_TX_MSDU_EXT_INFO1_ENCRYPT_TYPE);
+}
+
+#define HTT_META_DATA_ALIGNMENT 0x8
+
+/* Preparing HTT Metadata when utilized with ext MSDU */
+static int ath12k_dp_prepare_htt_metadata(struct sk_buff *skb)
+{
+ struct hal_tx_msdu_metadata *desc_ext;
+ u8 htt_desc_size;
+ /* Size rounded of multiple of 8 bytes */
+ u8 htt_desc_size_aligned;
+
+ htt_desc_size = sizeof(struct hal_tx_msdu_metadata);
+ htt_desc_size_aligned = ALIGN(htt_desc_size, HTT_META_DATA_ALIGNMENT);
+
+ desc_ext = ath12k_dp_metadata_align_skb(skb, htt_desc_size_aligned);
+ if (!desc_ext)
+ return -ENOMEM;
+
+ desc_ext->info0 = le32_encode_bits(1, HAL_TX_MSDU_METADATA_INFO0_ENCRYPT_FLAG) |
+ le32_encode_bits(0, HAL_TX_MSDU_METADATA_INFO0_ENCRYPT_TYPE) |
+ le32_encode_bits(1,
+ HAL_TX_MSDU_METADATA_INFO0_HOST_TX_DESC_POOL);
+
+ return 0;
+}
+
+int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif,
+ struct sk_buff *skb, bool gsn_valid, int mcbc_gsn,
+ bool is_mcast)
+{
+ struct ath12k_base *ab = ar->ab;
+ struct ath12k_dp *dp = &ab->dp;
+ struct hal_tx_info ti = {};
+ struct ath12k_tx_desc_info *tx_desc;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb);
+ struct hal_tcl_data_cmd *hal_tcl_desc;
+ struct hal_tx_msdu_ext_desc *msg;
+ struct sk_buff *skb_ext_desc = NULL;
+ struct hal_srng *tcl_ring;
+ struct ieee80211_hdr *hdr = (void *)skb->data;
+ struct ath12k_vif *ahvif = arvif->ahvif;
+ struct dp_tx_ring *tx_ring;
+ u8 pool_id;
+ u8 hal_ring_id;
+ int ret;
+ u8 ring_selector, ring_map = 0;
+ bool tcl_ring_retry;
+ bool msdu_ext_desc = false;
+ bool add_htt_metadata = false;
+ u32 iova_mask = ab->hw_params->iova_mask;
+ bool is_diff_encap = false;
+ bool is_null_frame = false;
+
+ if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))
+ return -ESHUTDOWN;
+
+ if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&
+ !ieee80211_is_data(hdr->frame_control))
+ return -EOPNOTSUPP;
+
+ pool_id = skb_get_queue_mapping(skb) & (ATH12K_HW_MAX_QUEUES - 1);
+
+ /* Let the default ring selection be based on current processor
+ * number, where one of the 3 tcl rings are selected based on
+ * the smp_processor_id(). In case that ring
+ * is full/busy, we resort to other available rings.
+ * If all rings are full, we drop the packet.
+ * TODO: Add throttling logic when all rings are full
+ */
+ ring_selector = ab->hw_params->hw_ops->get_ring_selector(skb);
+
+tcl_ring_sel:
+ tcl_ring_retry = false;
+ ti.ring_id = ring_selector % ab->hw_params->max_tx_ring;
+
+ ring_map |= BIT(ti.ring_id);
+ ti.rbm_id = ab->hw_params->hal_ops->tcl_to_wbm_rbm_map[ti.ring_id].rbm_id;
+
+ tx_ring = &dp->tx_ring[ti.ring_id];
+
+ tx_desc = ath12k_dp_tx_assign_buffer(dp, pool_id);
+ if (!tx_desc)
+ return -ENOMEM;
+
+ ti.bank_id = arvif->bank_id;
+ ti.meta_data_flags = arvif->tcl_metadata;
+
+ if (ahvif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW &&
+ test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) {
+ if (skb_cb->flags & ATH12K_SKB_CIPHER_SET) {
+ ti.encrypt_type =
+ ath12k_dp_tx_get_encrypt_type(skb_cb->cipher);
+
+ if (ieee80211_has_protected(hdr->frame_control))
+ skb_put(skb, IEEE80211_CCMP_MIC_LEN);
+ } else {
+ ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN;
+ }
+
+ msdu_ext_desc = true;
+ }
+
+ if (gsn_valid) {
+ /* Reset and Initialize meta_data_flags with Global Sequence
+ * Number (GSN) info.
+ */
+ ti.meta_data_flags =
+ u32_encode_bits(HTT_TCL_META_DATA_TYPE_GLOBAL_SEQ_NUM,
+ HTT_TCL_META_DATA_TYPE) |
+ u32_encode_bits(mcbc_gsn, HTT_TCL_META_DATA_GLOBAL_SEQ_NUM);
+ }
+
+ ti.encap_type = ath12k_dp_tx_get_encap_type(ab, skb);
+ ti.addr_search_flags = arvif->hal_addr_search_flags;
+ ti.search_type = arvif->search_type;
+ ti.type = HAL_TCL_DESC_TYPE_BUFFER;
+ ti.pkt_offset = 0;
+ ti.lmac_id = ar->lmac_id;
+
+ ti.vdev_id = arvif->vdev_id;
+ if (gsn_valid)
+ ti.vdev_id += HTT_TX_MLO_MCAST_HOST_REINJECT_BASE_VDEV_ID;
+
+ ti.bss_ast_hash = arvif->ast_hash;
+ ti.bss_ast_idx = arvif->ast_idx;
+ ti.dscp_tid_tbl_idx = 0;
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL &&
+ ti.encap_type != HAL_TCL_ENCAP_TYPE_RAW) {
+ ti.flags0 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_IP4_CKSUM_EN) |
+ u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_UDP4_CKSUM_EN) |
+ u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_UDP6_CKSUM_EN) |
+ u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TCP4_CKSUM_EN) |
+ u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TCP6_CKSUM_EN);
+ }
+
+ ti.flags1 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO3_TID_OVERWRITE);
+
+ ti.tid = ath12k_dp_tx_get_tid(skb);
+
+ switch (ti.encap_type) {
+ case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI:
+ is_null_frame = ieee80211_is_nullfunc(hdr->frame_control);
+ if (ahvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) {
+ if (skb->protocol == cpu_to_be16(ETH_P_PAE) || is_null_frame)
+ is_diff_encap = true;
+
+ /* Firmware expects msdu ext descriptor for nwifi/raw packets
+ * received in ETH mode. Without this, observed tx fail for
+ * Multicast packets in ETH mode.
+ */
+ msdu_ext_desc = true;
+ } else {
+ ath12k_dp_tx_encap_nwifi(skb);
+ }
+ break;
+ case HAL_TCL_ENCAP_TYPE_RAW:
+ if (!test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) {
+ ret = -EINVAL;
+ goto fail_remove_tx_buf;
+ }
+ break;
+ case HAL_TCL_ENCAP_TYPE_ETHERNET:
+ /* no need to encap */
+ break;
+ case HAL_TCL_ENCAP_TYPE_802_3:
+ default:
+ /* TODO: Take care of other encap modes as well */
+ ret = -EINVAL;
+ atomic_inc(&ab->device_stats.tx_err.misc_fail);
+ goto fail_remove_tx_buf;
+ }
+
+ if (iova_mask &&
+ (unsigned long)skb->data & iova_mask) {
+ ret = ath12k_dp_tx_align_payload(ab, &skb);
+ if (ret) {
+ ath12k_warn(ab, "failed to align TX buffer %d\n", ret);
+ /* don't bail out, give original buffer
+ * a chance even unaligned.
+ */
+ goto map;
+ }
+
+ /* hdr is pointing to a wrong place after alignment,
+ * so refresh it for later use.
+ */
+ hdr = (void *)skb->data;
+ }
+map:
+ ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE);
+ if (dma_mapping_error(ab->dev, ti.paddr)) {
+ atomic_inc(&ab->device_stats.tx_err.misc_fail);
+ ath12k_warn(ab, "failed to DMA map data Tx buffer\n");
+ ret = -ENOMEM;
+ goto fail_remove_tx_buf;
+ }
+
+ if ((!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) &&
+ !(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) &&
+ !(skb_cb->flags & ATH12K_SKB_CIPHER_SET) &&
+ ieee80211_has_protected(hdr->frame_control)) ||
+ is_diff_encap) {
+ /* Firmware is not expecting meta data for qos null
+ * nwifi packet received in ETH encap mode.
+ */
+ if (is_null_frame && msdu_ext_desc)
+ goto skip_htt_meta;
+
+ /* Add metadata for sw encrypted vlan group traffic
+ * and EAPOL nwifi packet received in ETH encap mode.
+ */
+ add_htt_metadata = true;
+ msdu_ext_desc = true;
+ ti.meta_data_flags |= HTT_TCL_META_DATA_VALID_HTT;
+skip_htt_meta:
+ ti.flags0 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TO_FW);
+ ti.encap_type = HAL_TCL_ENCAP_TYPE_RAW;
+ ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN;
+ }
+
+ tx_desc->skb = skb;
+ tx_desc->mac_id = ar->pdev_idx;
+ ti.desc_id = tx_desc->desc_id;
+ ti.data_len = skb->len;
+ skb_cb->paddr = ti.paddr;
+ skb_cb->vif = ahvif->vif;
+ skb_cb->ar = ar;
+
+ if (msdu_ext_desc) {
+ skb_ext_desc = dev_alloc_skb(sizeof(struct hal_tx_msdu_ext_desc));
+ if (!skb_ext_desc) {
+ ret = -ENOMEM;
+ goto fail_unmap_dma;
+ }
+
+ skb_put(skb_ext_desc, sizeof(struct hal_tx_msdu_ext_desc));
+ memset(skb_ext_desc->data, 0, skb_ext_desc->len);
+
+ msg = (struct hal_tx_msdu_ext_desc *)skb_ext_desc->data;
+ ath12k_hal_tx_cmd_ext_desc_setup(ab, msg, &ti);
+
+ if (add_htt_metadata) {
+ ret = ath12k_dp_prepare_htt_metadata(skb_ext_desc);
+ if (ret < 0) {
+ ath12k_dbg(ab, ATH12K_DBG_DP_TX,
+ "Failed to add HTT meta data, dropping packet\n");
+ goto fail_free_ext_skb;
+ }
+ }
+
+ ti.paddr = dma_map_single(ab->dev, skb_ext_desc->data,
+ skb_ext_desc->len, DMA_TO_DEVICE);
+ ret = dma_mapping_error(ab->dev, ti.paddr);
+ if (ret)
+ goto fail_free_ext_skb;
+
+ ti.data_len = skb_ext_desc->len;
+ ti.type = HAL_TCL_DESC_TYPE_EXT_DESC;
+
+ skb_cb->paddr_ext_desc = ti.paddr;
+ tx_desc->skb_ext_desc = skb_ext_desc;
+ }
+
+ hal_ring_id = tx_ring->tcl_data_ring.ring_id;
+ tcl_ring = &ab->hal.srng_list[hal_ring_id];
+
+ spin_lock_bh(&tcl_ring->lock);
+
+ ath12k_hal_srng_access_begin(ab, tcl_ring);
+
+ hal_tcl_desc = ath12k_hal_srng_src_get_next_entry(ab, tcl_ring);
+ if (!hal_tcl_desc) {
+ /* NOTE: It is highly unlikely we'll be running out of tcl_ring
+ * desc because the desc is directly enqueued onto hw queue.
+ */
+ ath12k_hal_srng_access_end(ab, tcl_ring);
+ ab->device_stats.tx_err.desc_na[ti.ring_id]++;
+ spin_unlock_bh(&tcl_ring->lock);
+ ret = -ENOMEM;
+
+ /* Checking for available tcl descriptors in another ring in
+ * case of failure due to full tcl ring now, is better than
+ * checking this ring earlier for each pkt tx.
+ * Restart ring selection if some rings are not checked yet.
+ */
+ if (ring_map != (BIT(ab->hw_params->max_tx_ring) - 1) &&
+ ab->hw_params->tcl_ring_retry) {
+ tcl_ring_retry = true;
+ ring_selector++;
+ }
+
+ goto fail_unmap_dma_ext;
+ }
+
+ spin_lock_bh(&arvif->link_stats_lock);
+ arvif->link_stats.tx_encap_type[ti.encap_type]++;
+ arvif->link_stats.tx_encrypt_type[ti.encrypt_type]++;
+ arvif->link_stats.tx_desc_type[ti.type]++;
+
+ if (is_mcast)
+ arvif->link_stats.tx_bcast_mcast++;
+ else
+ arvif->link_stats.tx_enqueued++;
+ spin_unlock_bh(&arvif->link_stats_lock);
+
+ ab->device_stats.tx_enqueued[ti.ring_id]++;
+
+ ath12k_hal_tx_cmd_desc_setup(ab, hal_tcl_desc, &ti);
+
+ ath12k_hal_srng_access_end(ab, tcl_ring);
+
+ spin_unlock_bh(&tcl_ring->lock);
+
+ ath12k_dbg_dump(ab, ATH12K_DBG_DP_TX, NULL, "dp tx msdu: ",
+ skb->data, skb->len);
+
+ atomic_inc(&ar->dp.num_tx_pending);
+
+ return 0;
+
+fail_unmap_dma_ext:
+ if (skb_cb->paddr_ext_desc)
+ dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc,
+ skb_ext_desc->len,
+ DMA_TO_DEVICE);
+fail_free_ext_skb:
+ kfree_skb(skb_ext_desc);
+
+fail_unmap_dma:
+ dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE);
+
+fail_remove_tx_buf:
+ ath12k_dp_tx_release_txbuf(dp, tx_desc, pool_id);
+
+ spin_lock_bh(&arvif->link_stats_lock);
+ arvif->link_stats.tx_dropped++;
+ spin_unlock_bh(&arvif->link_stats_lock);
+
+ if (tcl_ring_retry)
+ goto tcl_ring_sel;
+
+ return ret;
+}
+
static void
ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab,
struct ath12k_tx_desc_params *desc_params,
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h
index 4361beb99666..42faf664f8f8 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h
@@ -7,5 +7,8 @@
#ifndef ATH12K_DP_TX_WIFI7_H
#define ATH12K_DP_TX_WIFI7_H
+int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif,
+ struct sk_buff *skb, bool gsn_valid, int mcbc_gsn,
+ bool is_mcast);
void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id);
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 17/20] wifi: ath12k: Move HTT code in dp.h to newly introduced files
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (15 preceding siblings ...)
2025-08-28 17:35 ` [PATCH ath12k-ng 16/20] wifi: ath12k: Move ath12k_dp_tx and related " Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 18/20] wifi: ath12k: Move HTT Rx specific code " Ripan Deuri
` (5 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Harsh Kumar Bijlani <quic_hbijlani@quicinc.com>
WLAN Host driver interacts with the Firmware and vice versa using
Host-To-Target (HTT) interface.
HTT interface code is spread across multiple files (ex dp_tx.c,
dp_rx.c, dp.h etc) and this interface is independent of the underlying
architecture Tx and Rx.
Relocate HTT specific code from dp.h to newly introduced file dp_htt.h
for HTT interface.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Harsh Kumar Bijlani <quic_hbijlani@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
.../wireless/ath/ath12k/debugfs_htt_stats.h | 4 +-
drivers/net/wireless/ath/ath12k/dp.h | 1506 +---------------
drivers/net/wireless/ath/ath12k/dp_htt.h | 1517 +++++++++++++++++
3 files changed, 1521 insertions(+), 1506 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath12k/dp_htt.h
diff --git a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h
index 9bd3a632b002..8008658371aa 100644
--- a/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h
+++ b/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.h
@@ -1,12 +1,14 @@
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef DEBUG_HTT_STATS_H
#define DEBUG_HTT_STATS_H
+#include "dp_htt.h"
+
#define ATH12K_HTT_STATS_BUF_SIZE (1024 * 512)
#define ATH12K_HTT_STATS_COOKIE_LSB GENMASK_ULL(31, 0)
#define ATH12K_HTT_STATS_COOKIE_MSB GENMASK_ULL(63, 32)
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index 51af354ee769..45d569e19534 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -10,6 +10,7 @@
#include "wifi7/hal_desc.h"
#include "wifi7/hal_rx.h"
#include "hw.h"
+#include "dp_htt.h"
#define MAX_RXDMA_PER_PDEV 2
@@ -425,1511 +426,6 @@ struct ath12k_dp {
struct ath12k_reo_q_addr_lut ml_reoq_lut;
};
-/* HTT definitions */
-#define HTT_TAG_TCL_METADATA_VERSION 5
-
-#define HTT_TCL_META_DATA_TYPE GENMASK(1, 0)
-#define HTT_TCL_META_DATA_VALID_HTT BIT(2)
-
-/* vdev meta data */
-#define HTT_TCL_META_DATA_VDEV_ID GENMASK(10, 3)
-#define HTT_TCL_META_DATA_PDEV_ID GENMASK(12, 11)
-#define HTT_TCL_META_DATA_HOST_INSPECTED_MISSION BIT(13)
-
-/* peer meta data */
-#define HTT_TCL_META_DATA_PEER_ID GENMASK(15, 3)
-
-/* Global sequence number */
-#define HTT_TCL_META_DATA_TYPE_GLOBAL_SEQ_NUM 3
-#define HTT_TCL_META_DATA_GLOBAL_SEQ_HOST_INSPECTED BIT(2)
-#define HTT_TCL_META_DATA_GLOBAL_SEQ_NUM GENMASK(14, 3)
-#define HTT_TX_MLO_MCAST_HOST_REINJECT_BASE_VDEV_ID 128
-
-/* HTT tx completion is overlaid in wbm_release_ring */
-#define HTT_TX_WBM_COMP_INFO0_STATUS GENMASK(16, 13)
-#define HTT_TX_WBM_COMP_INFO1_REINJECT_REASON GENMASK(3, 0)
-#define HTT_TX_WBM_COMP_INFO1_EXCEPTION_FRAME BIT(4)
-
-#define HTT_TX_WBM_COMP_INFO2_ACK_RSSI GENMASK(31, 24)
-
-struct htt_tx_wbm_completion {
- __le32 rsvd0[2];
- __le32 info0;
- __le32 info1;
- __le32 info2;
- __le32 info3;
- __le32 info4;
- __le32 rsvd1;
-
-} __packed;
-
-enum htt_h2t_msg_type {
- HTT_H2T_MSG_TYPE_VERSION_REQ = 0,
- HTT_H2T_MSG_TYPE_SRING_SETUP = 0xb,
- HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG = 0xc,
- HTT_H2T_MSG_TYPE_EXT_STATS_CFG = 0x10,
- HTT_H2T_MSG_TYPE_PPDU_STATS_CFG = 0x11,
- HTT_H2T_MSG_TYPE_VDEV_TXRX_STATS_CFG = 0x1a,
- HTT_H2T_MSG_TYPE_TX_MONITOR_CFG = 0x1b,
-};
-
-#define HTT_VER_REQ_INFO_MSG_ID GENMASK(7, 0)
-#define HTT_OPTION_TCL_METADATA_VER_V1 1
-#define HTT_OPTION_TCL_METADATA_VER_V2 2
-#define HTT_OPTION_TAG GENMASK(7, 0)
-#define HTT_OPTION_LEN GENMASK(15, 8)
-#define HTT_OPTION_VALUE GENMASK(31, 16)
-#define HTT_TCL_METADATA_VER_SZ 4
-
-struct htt_ver_req_cmd {
- __le32 ver_reg_info;
- __le32 tcl_metadata_version;
-} __packed;
-
-enum htt_srng_ring_type {
- HTT_HW_TO_SW_RING,
- HTT_SW_TO_HW_RING,
- HTT_SW_TO_SW_RING,
-};
-
-enum htt_srng_ring_id {
- HTT_RXDMA_HOST_BUF_RING,
- HTT_RXDMA_MONITOR_STATUS_RING,
- HTT_RXDMA_MONITOR_BUF_RING,
- HTT_RXDMA_MONITOR_DESC_RING,
- HTT_RXDMA_MONITOR_DEST_RING,
- HTT_HOST1_TO_FW_RXBUF_RING,
- HTT_HOST2_TO_FW_RXBUF_RING,
- HTT_RXDMA_NON_MONITOR_DEST_RING,
- HTT_RXDMA_HOST_BUF_RING2,
- HTT_TX_MON_HOST2MON_BUF_RING,
- HTT_TX_MON_MON2HOST_DEST_RING,
- HTT_RX_MON_HOST2MON_BUF_RING,
- HTT_RX_MON_MON2HOST_DEST_RING,
-};
-
-/* host -> target HTT_SRING_SETUP message
- *
- * After target is booted up, Host can send SRING setup message for
- * each host facing LMAC SRING. Target setups up HW registers based
- * on setup message and confirms back to Host if response_required is set.
- * Host should wait for confirmation message before sending new SRING
- * setup message
- *
- * The message would appear as follows:
- *
- * |31 24|23 20|19|18 16|15|14 8|7 0|
- * |--------------- +-----------------+----------------+------------------|
- * | ring_type | ring_id | pdev_id | msg_type |
- * |----------------------------------------------------------------------|
- * | ring_base_addr_lo |
- * |----------------------------------------------------------------------|
- * | ring_base_addr_hi |
- * |----------------------------------------------------------------------|
- * |ring_misc_cfg_flag|ring_entry_size| ring_size |
- * |----------------------------------------------------------------------|
- * | ring_head_offset32_remote_addr_lo |
- * |----------------------------------------------------------------------|
- * | ring_head_offset32_remote_addr_hi |
- * |----------------------------------------------------------------------|
- * | ring_tail_offset32_remote_addr_lo |
- * |----------------------------------------------------------------------|
- * | ring_tail_offset32_remote_addr_hi |
- * |----------------------------------------------------------------------|
- * | ring_msi_addr_lo |
- * |----------------------------------------------------------------------|
- * | ring_msi_addr_hi |
- * |----------------------------------------------------------------------|
- * | ring_msi_data |
- * |----------------------------------------------------------------------|
- * | intr_timer_th |IM| intr_batch_counter_th |
- * |----------------------------------------------------------------------|
- * | reserved |RR|PTCF| intr_low_threshold |
- * |----------------------------------------------------------------------|
- * Where
- * IM = sw_intr_mode
- * RR = response_required
- * PTCF = prefetch_timer_cfg
- *
- * The message is interpreted as follows:
- * dword0 - b'0:7 - msg_type: This will be set to
- * HTT_H2T_MSG_TYPE_SRING_SETUP
- * b'8:15 - pdev_id:
- * 0 (for rings at SOC/UMAC level),
- * 1/2/3 mac id (for rings at LMAC level)
- * b'16:23 - ring_id: identify which ring is to setup,
- * more details can be got from enum htt_srng_ring_id
- * b'24:31 - ring_type: identify type of host rings,
- * more details can be got from enum htt_srng_ring_type
- * dword1 - b'0:31 - ring_base_addr_lo: Lower 32bits of ring base address
- * dword2 - b'0:31 - ring_base_addr_hi: Upper 32bits of ring base address
- * dword3 - b'0:15 - ring_size: size of the ring in unit of 4-bytes words
- * b'16:23 - ring_entry_size: Size of each entry in 4-byte word units
- * b'24:31 - ring_misc_cfg_flag: Valid only for HW_TO_SW_RING and
- * SW_TO_HW_RING.
- * Refer to HTT_SRING_SETUP_RING_MISC_CFG_RING defs.
- * dword4 - b'0:31 - ring_head_off32_remote_addr_lo:
- * Lower 32 bits of memory address of the remote variable
- * storing the 4-byte word offset that identifies the head
- * element within the ring.
- * (The head offset variable has type u32.)
- * Valid for HW_TO_SW and SW_TO_SW rings.
- * dword5 - b'0:31 - ring_head_off32_remote_addr_hi:
- * Upper 32 bits of memory address of the remote variable
- * storing the 4-byte word offset that identifies the head
- * element within the ring.
- * (The head offset variable has type u32.)
- * Valid for HW_TO_SW and SW_TO_SW rings.
- * dword6 - b'0:31 - ring_tail_off32_remote_addr_lo:
- * Lower 32 bits of memory address of the remote variable
- * storing the 4-byte word offset that identifies the tail
- * element within the ring.
- * (The tail offset variable has type u32.)
- * Valid for HW_TO_SW and SW_TO_SW rings.
- * dword7 - b'0:31 - ring_tail_off32_remote_addr_hi:
- * Upper 32 bits of memory address of the remote variable
- * storing the 4-byte word offset that identifies the tail
- * element within the ring.
- * (The tail offset variable has type u32.)
- * Valid for HW_TO_SW and SW_TO_SW rings.
- * dword8 - b'0:31 - ring_msi_addr_lo: Lower 32bits of MSI cfg address
- * valid only for HW_TO_SW_RING and SW_TO_HW_RING
- * dword9 - b'0:31 - ring_msi_addr_hi: Upper 32bits of MSI cfg address
- * valid only for HW_TO_SW_RING and SW_TO_HW_RING
- * dword10 - b'0:31 - ring_msi_data: MSI data
- * Refer to HTT_SRING_SETUP_RING_MSC_CFG_xxx defs
- * valid only for HW_TO_SW_RING and SW_TO_HW_RING
- * dword11 - b'0:14 - intr_batch_counter_th:
- * batch counter threshold is in units of 4-byte words.
- * HW internally maintains and increments batch count.
- * (see SRING spec for detail description).
- * When batch count reaches threshold value, an interrupt
- * is generated by HW.
- * b'15 - sw_intr_mode:
- * This configuration shall be static.
- * Only programmed at power up.
- * 0: generate pulse style sw interrupts
- * 1: generate level style sw interrupts
- * b'16:31 - intr_timer_th:
- * The timer init value when timer is idle or is
- * initialized to start downcounting.
- * In 8us units (to cover a range of 0 to 524 ms)
- * dword12 - b'0:15 - intr_low_threshold:
- * Used only by Consumer ring to generate ring_sw_int_p.
- * Ring entries low threshold water mark, that is used
- * in combination with the interrupt timer as well as
- * the clearing of the level interrupt.
- * b'16:18 - prefetch_timer_cfg:
- * Used only by Consumer ring to set timer mode to
- * support Application prefetch handling.
- * The external tail offset/pointer will be updated
- * at following intervals:
- * 3'b000: (Prefetch feature disabled; used only for debug)
- * 3'b001: 1 usec
- * 3'b010: 4 usec
- * 3'b011: 8 usec (default)
- * 3'b100: 16 usec
- * Others: Reserved
- * b'19 - response_required:
- * Host needs HTT_T2H_MSG_TYPE_SRING_SETUP_DONE as response
- * b'20:31 - reserved: reserved for future use
- */
-
-#define HTT_SRNG_SETUP_CMD_INFO0_MSG_TYPE GENMASK(7, 0)
-#define HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID GENMASK(15, 8)
-#define HTT_SRNG_SETUP_CMD_INFO0_RING_ID GENMASK(23, 16)
-#define HTT_SRNG_SETUP_CMD_INFO0_RING_TYPE GENMASK(31, 24)
-
-#define HTT_SRNG_SETUP_CMD_INFO1_RING_SIZE GENMASK(15, 0)
-#define HTT_SRNG_SETUP_CMD_INFO1_RING_ENTRY_SIZE GENMASK(23, 16)
-#define HTT_SRNG_SETUP_CMD_INFO1_RING_LOOP_CNT_DIS BIT(25)
-#define HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_MSI_SWAP BIT(27)
-#define HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_HOST_FW_SWAP BIT(28)
-#define HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_TLV_SWAP BIT(29)
-
-#define HTT_SRNG_SETUP_CMD_INTR_INFO_BATCH_COUNTER_THRESH GENMASK(14, 0)
-#define HTT_SRNG_SETUP_CMD_INTR_INFO_SW_INTR_MODE BIT(15)
-#define HTT_SRNG_SETUP_CMD_INTR_INFO_INTR_TIMER_THRESH GENMASK(31, 16)
-
-#define HTT_SRNG_SETUP_CMD_INFO2_INTR_LOW_THRESH GENMASK(15, 0)
-#define HTT_SRNG_SETUP_CMD_INFO2_PRE_FETCH_TIMER_CFG GENMASK(18, 16)
-#define HTT_SRNG_SETUP_CMD_INFO2_RESPONSE_REQUIRED BIT(19)
-
-struct htt_srng_setup_cmd {
- __le32 info0;
- __le32 ring_base_addr_lo;
- __le32 ring_base_addr_hi;
- __le32 info1;
- __le32 ring_head_off32_remote_addr_lo;
- __le32 ring_head_off32_remote_addr_hi;
- __le32 ring_tail_off32_remote_addr_lo;
- __le32 ring_tail_off32_remote_addr_hi;
- __le32 ring_msi_addr_lo;
- __le32 ring_msi_addr_hi;
- __le32 msi_data;
- __le32 intr_info;
- __le32 info2;
-} __packed;
-
-/* host -> target FW PPDU_STATS config message
- *
- * @details
- * The following field definitions describe the format of the HTT host
- * to target FW for PPDU_STATS_CFG msg.
- * The message allows the host to configure the PPDU_STATS_IND messages
- * produced by the target.
- *
- * |31 24|23 16|15 8|7 0|
- * |-----------------------------------------------------------|
- * | REQ bit mask | pdev_mask | msg type |
- * |-----------------------------------------------------------|
- * Header fields:
- * - MSG_TYPE
- * Bits 7:0
- * Purpose: identifies this is a req to configure ppdu_stats_ind from target
- * Value: 0x11
- * - PDEV_MASK
- * Bits 8:15
- * Purpose: identifies which pdevs this PPDU stats configuration applies to
- * Value: This is a overloaded field, refer to usage and interpretation of
- * PDEV in interface document.
- * Bit 8 : Reserved for SOC stats
- * Bit 9 - 15 : Indicates PDEV_MASK in DBDC
- * Indicates MACID_MASK in DBS
- * - REQ_TLV_BIT_MASK
- * Bits 16:31
- * Purpose: each set bit indicates the corresponding PPDU stats TLV type
- * needs to be included in the target's PPDU_STATS_IND messages.
- * Value: refer htt_ppdu_stats_tlv_tag_t <<<???
- *
- */
-
-struct htt_ppdu_stats_cfg_cmd {
- __le32 msg;
-} __packed;
-
-#define HTT_PPDU_STATS_CFG_MSG_TYPE GENMASK(7, 0)
-#define HTT_PPDU_STATS_CFG_SOC_STATS BIT(8)
-#define HTT_PPDU_STATS_CFG_PDEV_ID GENMASK(15, 9)
-#define HTT_PPDU_STATS_CFG_TLV_TYPE_BITMASK GENMASK(31, 16)
-
-enum htt_ppdu_stats_tag_type {
- HTT_PPDU_STATS_TAG_COMMON,
- HTT_PPDU_STATS_TAG_USR_COMMON,
- HTT_PPDU_STATS_TAG_USR_RATE,
- HTT_PPDU_STATS_TAG_USR_MPDU_ENQ_BITMAP_64,
- HTT_PPDU_STATS_TAG_USR_MPDU_ENQ_BITMAP_256,
- HTT_PPDU_STATS_TAG_SCH_CMD_STATUS,
- HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON,
- HTT_PPDU_STATS_TAG_USR_COMPLTN_BA_BITMAP_64,
- HTT_PPDU_STATS_TAG_USR_COMPLTN_BA_BITMAP_256,
- HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS,
- HTT_PPDU_STATS_TAG_USR_COMPLTN_FLUSH,
- HTT_PPDU_STATS_TAG_USR_COMMON_ARRAY,
- HTT_PPDU_STATS_TAG_INFO,
- HTT_PPDU_STATS_TAG_TX_MGMTCTRL_PAYLOAD,
-
- /* New TLV's are added above to this line */
- HTT_PPDU_STATS_TAG_MAX,
-};
-
-#define HTT_PPDU_STATS_TAG_DEFAULT (BIT(HTT_PPDU_STATS_TAG_COMMON) \
- | BIT(HTT_PPDU_STATS_TAG_USR_COMMON) \
- | BIT(HTT_PPDU_STATS_TAG_USR_RATE) \
- | BIT(HTT_PPDU_STATS_TAG_SCH_CMD_STATUS) \
- | BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON) \
- | BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS) \
- | BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_FLUSH) \
- | BIT(HTT_PPDU_STATS_TAG_USR_COMMON_ARRAY))
-
-#define HTT_PPDU_STATS_TAG_PKTLOG (BIT(HTT_PPDU_STATS_TAG_USR_MPDU_ENQ_BITMAP_64) | \
- BIT(HTT_PPDU_STATS_TAG_USR_MPDU_ENQ_BITMAP_256) | \
- BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_BA_BITMAP_64) | \
- BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_BA_BITMAP_256) | \
- BIT(HTT_PPDU_STATS_TAG_INFO) | \
- BIT(HTT_PPDU_STATS_TAG_TX_MGMTCTRL_PAYLOAD) | \
- HTT_PPDU_STATS_TAG_DEFAULT)
-
-enum htt_stats_internal_ppdu_frametype {
- HTT_STATS_PPDU_FTYPE_CTRL,
- HTT_STATS_PPDU_FTYPE_DATA,
- HTT_STATS_PPDU_FTYPE_BAR,
- HTT_STATS_PPDU_FTYPE_MAX
-};
-
-/* HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG Message
- *
- * details:
- * HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG message is sent by host to
- * configure RXDMA rings.
- * The configuration is per ring based and includes both packet subtypes
- * and PPDU/MPDU TLVs.
- *
- * The message would appear as follows:
- *
- * |31 29|28|27|26|25|24|23 16|15 8|7 0|
- * |-------+--+--+--+--+--+-----------+----------------+---------------|
- * | rsvd1 |ED|DT|OV|PS|SS| ring_id | pdev_id | msg_type |
- * |-------------------------------------------------------------------|
- * | rsvd2 | ring_buffer_size |
- * |-------------------------------------------------------------------|
- * | packet_type_enable_flags_0 |
- * |-------------------------------------------------------------------|
- * | packet_type_enable_flags_1 |
- * |-------------------------------------------------------------------|
- * | packet_type_enable_flags_2 |
- * |-------------------------------------------------------------------|
- * | packet_type_enable_flags_3 |
- * |-------------------------------------------------------------------|
- * | tlv_filter_in_flags |
- * |-------------------------------------------------------------------|
- * Where:
- * PS = pkt_swap
- * SS = status_swap
- * The message is interpreted as follows:
- * dword0 - b'0:7 - msg_type: This will be set to
- * HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG
- * b'8:15 - pdev_id:
- * 0 (for rings at SOC/UMAC level),
- * 1/2/3 mac id (for rings at LMAC level)
- * b'16:23 - ring_id : Identify the ring to configure.
- * More details can be got from enum htt_srng_ring_id
- * b'24 - status_swap: 1 is to swap status TLV
- * b'25 - pkt_swap: 1 is to swap packet TLV
- * b'26 - rx_offset_valid (OV): flag to indicate rx offsets
- * configuration fields are valid
- * b'27 - drop_thresh_valid (DT): flag to indicate if the
- * rx_drop_threshold field is valid
- * b'28 - rx_mon_global_en: Enable/Disable global register
- * configuration in Rx monitor module.
- * b'29:31 - rsvd1: reserved for future use
- * dword1 - b'0:16 - ring_buffer_size: size of buffers referenced by rx ring,
- * in byte units.
- * Valid only for HW_TO_SW_RING and SW_TO_HW_RING
- * - b'16:31 - rsvd2: Reserved for future use
- * dword2 - b'0:31 - packet_type_enable_flags_0:
- * Enable MGMT packet from 0b0000 to 0b1001
- * bits from low to high: FP, MD, MO - 3 bits
- * FP: Filter_Pass
- * MD: Monitor_Direct
- * MO: Monitor_Other
- * 10 mgmt subtypes * 3 bits -> 30 bits
- * Refer to PKT_TYPE_ENABLE_FLAG0_xxx_MGMT_xxx defs
- * dword3 - b'0:31 - packet_type_enable_flags_1:
- * Enable MGMT packet from 0b1010 to 0b1111
- * bits from low to high: FP, MD, MO - 3 bits
- * Refer to PKT_TYPE_ENABLE_FLAG1_xxx_MGMT_xxx defs
- * dword4 - b'0:31 - packet_type_enable_flags_2:
- * Enable CTRL packet from 0b0000 to 0b1001
- * bits from low to high: FP, MD, MO - 3 bits
- * Refer to PKT_TYPE_ENABLE_FLAG2_xxx_CTRL_xxx defs
- * dword5 - b'0:31 - packet_type_enable_flags_3:
- * Enable CTRL packet from 0b1010 to 0b1111,
- * MCAST_DATA, UCAST_DATA, NULL_DATA
- * bits from low to high: FP, MD, MO - 3 bits
- * Refer to PKT_TYPE_ENABLE_FLAG3_xxx_CTRL_xxx defs
- * dword6 - b'0:31 - tlv_filter_in_flags:
- * Filter in Attention/MPDU/PPDU/Header/User tlvs
- * Refer to CFG_TLV_FILTER_IN_FLAG defs
- */
-
-#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0)
-#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID GENMASK(15, 8)
-#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_RING_ID GENMASK(23, 16)
-#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_SS BIT(24)
-#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS BIT(25)
-#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_OFFSET_VALID BIT(26)
-#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_DROP_THRES_VAL BIT(27)
-#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_EN_RXMON BIT(28)
-
-#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE GENMASK(15, 0)
-#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT GENMASK(18, 16)
-#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL GENMASK(21, 19)
-#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA GENMASK(24, 22)
-
-#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_DROP_THRESHOLD GENMASK(9, 0)
-#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_MGMT_TYPE BIT(17)
-#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_CTRL_TYPE BIT(18)
-#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_DATA_TYPE BIT(19)
-
-#define HTT_RX_RING_SELECTION_CFG_CMD_INFO3_EN_TLV_PKT_OFFSET BIT(0)
-#define HTT_RX_RING_SELECTION_CFG_CMD_INFO3_PKT_TLV_OFFSET GENMASK(14, 1)
-
-#define HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET GENMASK(15, 0)
-#define HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET GENMASK(31, 16)
-#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET GENMASK(15, 0)
-#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET GENMASK(31, 16)
-#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET GENMASK(15, 0)
-#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET GENMASK(31, 16)
-#define HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET GENMASK(15, 0)
-
-#define HTT_RX_RING_SELECTION_CFG_WORD_MASK_COMPACT_SET BIT(23)
-#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_MASK GENMASK(15, 0)
-#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_MASK GENMASK(18, 16)
-#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_MASK GENMASK(16, 0)
-
-enum htt_rx_filter_tlv_flags {
- HTT_RX_FILTER_TLV_FLAGS_MPDU_START = BIT(0),
- HTT_RX_FILTER_TLV_FLAGS_MSDU_START = BIT(1),
- HTT_RX_FILTER_TLV_FLAGS_RX_PACKET = BIT(2),
- HTT_RX_FILTER_TLV_FLAGS_MSDU_END = BIT(3),
- HTT_RX_FILTER_TLV_FLAGS_MPDU_END = BIT(4),
- HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER = BIT(5),
- HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER = BIT(6),
- HTT_RX_FILTER_TLV_FLAGS_ATTENTION = BIT(7),
- HTT_RX_FILTER_TLV_FLAGS_PPDU_START = BIT(8),
- HTT_RX_FILTER_TLV_FLAGS_PPDU_END = BIT(9),
- HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS = BIT(10),
- HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT = BIT(11),
- HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE = BIT(12),
- HTT_RX_FILTER_TLV_FLAGS_PPDU_START_USER_INFO = BIT(13),
-};
-
-enum htt_rx_mgmt_pkt_filter_tlv_flags0 {
- HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ = BIT(0),
- HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ = BIT(1),
- HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ = BIT(2),
- HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP = BIT(3),
- HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP = BIT(4),
- HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP = BIT(5),
- HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ = BIT(6),
- HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ = BIT(7),
- HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ = BIT(8),
- HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP = BIT(9),
- HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP = BIT(10),
- HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP = BIT(11),
- HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ = BIT(12),
- HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ = BIT(13),
- HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ = BIT(14),
- HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP = BIT(15),
- HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP = BIT(16),
- HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP = BIT(17),
- HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV = BIT(18),
- HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV = BIT(19),
- HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV = BIT(20),
- HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7 = BIT(21),
- HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7 = BIT(22),
- HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7 = BIT(23),
- HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON = BIT(24),
- HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON = BIT(25),
- HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON = BIT(26),
- HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM = BIT(27),
- HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM = BIT(28),
- HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM = BIT(29),
-};
-
-enum htt_rx_mgmt_pkt_filter_tlv_flags1 {
- HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC = BIT(0),
- HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC = BIT(1),
- HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC = BIT(2),
- HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH = BIT(3),
- HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH = BIT(4),
- HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH = BIT(5),
- HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH = BIT(6),
- HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH = BIT(7),
- HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH = BIT(8),
- HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION = BIT(9),
- HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION = BIT(10),
- HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION = BIT(11),
- HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK = BIT(12),
- HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK = BIT(13),
- HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK = BIT(14),
- HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15 = BIT(15),
- HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15 = BIT(16),
- HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15 = BIT(17),
-};
-
-enum htt_rx_ctrl_pkt_filter_tlv_flags2 {
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 = BIT(0),
- HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 = BIT(1),
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 = BIT(2),
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 = BIT(3),
- HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 = BIT(4),
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 = BIT(5),
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER = BIT(6),
- HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER = BIT(7),
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER = BIT(8),
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 = BIT(9),
- HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 = BIT(10),
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 = BIT(11),
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL = BIT(12),
- HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL = BIT(13),
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL = BIT(14),
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP = BIT(15),
- HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP = BIT(16),
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP = BIT(17),
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT = BIT(18),
- HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT = BIT(19),
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT = BIT(20),
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER = BIT(21),
- HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER = BIT(22),
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER = BIT(23),
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR = BIT(24),
- HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BAR = BIT(25),
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BAR = BIT(26),
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BA = BIT(27),
- HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BA = BIT(28),
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BA = BIT(29),
-};
-
-enum htt_rx_ctrl_pkt_filter_tlv_flags3 {
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL = BIT(0),
- HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL = BIT(1),
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL = BIT(2),
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_RTS = BIT(3),
- HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_RTS = BIT(4),
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_RTS = BIT(5),
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CTS = BIT(6),
- HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CTS = BIT(7),
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CTS = BIT(8),
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_ACK = BIT(9),
- HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_ACK = BIT(10),
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_ACK = BIT(11),
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND = BIT(12),
- HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND = BIT(13),
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND = BIT(14),
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK = BIT(15),
- HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK = BIT(16),
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK = BIT(17),
-};
-
-enum htt_rx_data_pkt_filter_tlv_flasg3 {
- HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST = BIT(18),
- HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_MCAST = BIT(19),
- HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_MCAST = BIT(20),
- HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST = BIT(21),
- HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_UCAST = BIT(22),
- HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_UCAST = BIT(23),
- HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA = BIT(24),
- HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA = BIT(25),
- HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA = BIT(26),
-};
-
-#define HTT_RX_FP_MGMT_FILTER_FLAGS0 \
- (HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ \
- | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP \
- | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ \
- | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP \
- | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ \
- | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP \
- | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV \
- | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON \
- | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM)
-
-#define HTT_RX_MD_MGMT_FILTER_FLAGS0 \
- (HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ \
- | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP \
- | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ \
- | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP \
- | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ \
- | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP \
- | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV \
- | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON \
- | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM)
-
-#define HTT_RX_MO_MGMT_FILTER_FLAGS0 \
- (HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ \
- | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP \
- | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ \
- | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP \
- | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ \
- | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP \
- | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV \
- | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON \
- | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM)
-
-#define HTT_RX_FP_MGMT_FILTER_FLAGS1 (HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC \
- | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH \
- | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH \
- | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION \
- | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK)
-
-#define HTT_RX_MD_MGMT_FILTER_FLAGS1 (HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC \
- | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH \
- | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH \
- | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION \
- | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK)
-
-#define HTT_RX_MO_MGMT_FILTER_FLAGS1 (HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC \
- | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH \
- | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH \
- | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION \
- | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK)
-
-#define HTT_RX_FP_CTRL_FILTER_FLASG2 (HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER \
- | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR \
- | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BA)
-
-#define HTT_RX_MD_CTRL_FILTER_FLASG2 (HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER \
- | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BAR \
- | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BA)
-
-#define HTT_RX_MO_CTRL_FILTER_FLASG2 (HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER \
- | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BAR \
- | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BA)
-
-#define HTT_RX_FP_CTRL_FILTER_FLASG3 (HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL \
- | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_RTS \
- | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CTS \
- | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_ACK \
- | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND \
- | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK)
-
-#define HTT_RX_MD_CTRL_FILTER_FLASG3 (HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL \
- | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_RTS \
- | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CTS \
- | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_ACK \
- | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND \
- | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK)
-
-#define HTT_RX_MO_CTRL_FILTER_FLASG3 (HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL \
- | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_RTS \
- | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CTS \
- | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_ACK \
- | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND \
- | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK)
-
-#define HTT_RX_FP_DATA_FILTER_FLASG3 (HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST \
- | HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST \
- | HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA)
-
-#define HTT_RX_MD_DATA_FILTER_FLASG3 (HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_MCAST \
- | HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_UCAST \
- | HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA)
-
-#define HTT_RX_MO_DATA_FILTER_FLASG3 (HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_MCAST \
- | HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_UCAST \
- | HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA)
-
-#define HTT_RX_MON_FP_MGMT_FILTER_FLAGS0 \
- (HTT_RX_FP_MGMT_FILTER_FLAGS0 | \
- HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7)
-
-#define HTT_RX_MON_MO_MGMT_FILTER_FLAGS0 \
- (HTT_RX_MO_MGMT_FILTER_FLAGS0 | \
- HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7)
-
-#define HTT_RX_MON_FP_MGMT_FILTER_FLAGS1 \
- (HTT_RX_FP_MGMT_FILTER_FLAGS1 | \
- HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15)
-
-#define HTT_RX_MON_MO_MGMT_FILTER_FLAGS1 \
- (HTT_RX_MO_MGMT_FILTER_FLAGS1 | \
- HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15)
-
-#define HTT_RX_MON_FP_CTRL_FILTER_FLASG2 \
- (HTT_RX_FP_CTRL_FILTER_FLASG2 | \
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 | \
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 | \
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER | \
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 | \
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL | \
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP | \
- HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT)
-
-#define HTT_RX_MON_MO_CTRL_FILTER_FLASG2 \
- (HTT_RX_MO_CTRL_FILTER_FLASG2 | \
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 | \
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 | \
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER | \
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 | \
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL | \
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP | \
- HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT)
-
-#define HTT_RX_MON_FP_CTRL_FILTER_FLASG3 HTT_RX_FP_CTRL_FILTER_FLASG3
-
-#define HTT_RX_MON_MO_CTRL_FILTER_FLASG3 HTT_RX_MO_CTRL_FILTER_FLASG3
-
-#define HTT_RX_MON_FP_DATA_FILTER_FLASG3 HTT_RX_FP_DATA_FILTER_FLASG3
-
-#define HTT_RX_MON_MO_DATA_FILTER_FLASG3 HTT_RX_MO_DATA_FILTER_FLASG3
-
-#define HTT_RX_MON_FILTER_TLV_FLAGS \
- (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \
- HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
- HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
- HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \
- HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \
- HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE)
-
-#define HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING \
- (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \
- HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
- HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
- HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \
- HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \
- HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE)
-
-#define HTT_RX_MON_FILTER_TLV_FLAGS_MON_BUF_RING \
- (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \
- HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \
- HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \
- HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \
- HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \
- HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER | \
- HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \
- HTT_RX_FILTER_TLV_FLAGS_ATTENTION)
-
-#define HTT_RX_MON_FILTER_TLV_FLAGS_MON_DEST_RING \
- (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \
- HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \
- HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \
- HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \
- HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \
- HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER | \
- HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \
- HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
- HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
- HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \
- HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \
- HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \
- HTT_RX_FILTER_TLV_FLAGS_PPDU_START_USER_INFO)
-
-/* msdu start. mpdu end, attention, rx hdr tlv's are not subscribed */
-#define HTT_RX_TLV_FLAGS_RXDMA_RING \
- (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \
- HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \
- HTT_RX_FILTER_TLV_FLAGS_MSDU_END)
-
-#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0)
-#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID GENMASK(15, 8)
-
-struct htt_rx_ring_selection_cfg_cmd {
- __le32 info0;
- __le32 info1;
- __le32 pkt_type_en_flags0;
- __le32 pkt_type_en_flags1;
- __le32 pkt_type_en_flags2;
- __le32 pkt_type_en_flags3;
- __le32 rx_filter_tlv;
- __le32 rx_packet_offset;
- __le32 rx_mpdu_offset;
- __le32 rx_msdu_offset;
- __le32 rx_attn_offset;
- __le32 info2;
- __le32 reserved[2];
- __le32 rx_mpdu_start_end_mask;
- __le32 rx_msdu_end_word_mask;
- __le32 info3;
-} __packed;
-
-#define HTT_RX_RING_TLV_DROP_THRESHOLD_VALUE 32
-#define HTT_RX_RING_DEFAULT_DMA_LENGTH 0x7
-#define HTT_RX_RING_PKT_TLV_OFFSET 0x1
-
-struct htt_rx_ring_tlv_filter {
- u32 rx_filter; /* see htt_rx_filter_tlv_flags */
- u32 pkt_filter_flags0; /* MGMT */
- u32 pkt_filter_flags1; /* MGMT */
- u32 pkt_filter_flags2; /* CTRL */
- u32 pkt_filter_flags3; /* DATA */
- bool offset_valid;
- u16 rx_packet_offset;
- u16 rx_header_offset;
- u16 rx_mpdu_end_offset;
- u16 rx_mpdu_start_offset;
- u16 rx_msdu_end_offset;
- u16 rx_msdu_start_offset;
- u16 rx_attn_offset;
- u16 rx_mpdu_start_wmask;
- u16 rx_mpdu_end_wmask;
- u32 rx_msdu_end_wmask;
- u32 conf_len_ctrl;
- u32 conf_len_mgmt;
- u32 conf_len_data;
- u16 rx_drop_threshold;
- bool enable_log_mgmt_type;
- bool enable_log_ctrl_type;
- bool enable_log_data_type;
- bool enable_rx_tlv_offset;
- u16 rx_tlv_offset;
- bool drop_threshold_valid;
- bool rxmon_disable;
-};
-
-#define HTT_STATS_FRAME_CTRL_TYPE_MGMT 0x0
-#define HTT_STATS_FRAME_CTRL_TYPE_CTRL 0x1
-#define HTT_STATS_FRAME_CTRL_TYPE_DATA 0x2
-#define HTT_STATS_FRAME_CTRL_TYPE_RESV 0x3
-
-#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0)
-#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID GENMASK(15, 8)
-#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_RING_ID GENMASK(23, 16)
-#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_SS BIT(24)
-#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PS BIT(25)
-
-#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_RING_BUFF_SIZE GENMASK(15, 0)
-#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE GENMASK(18, 16)
-#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT GENMASK(21, 19)
-#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL GENMASK(24, 22)
-#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA GENMASK(27, 25)
-
-#define HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG GENMASK(2, 0)
-
-struct htt_tx_ring_selection_cfg_cmd {
- __le32 info0;
- __le32 info1;
- __le32 info2;
- __le32 tlv_filter_mask_in0;
- __le32 tlv_filter_mask_in1;
- __le32 tlv_filter_mask_in2;
- __le32 tlv_filter_mask_in3;
- __le32 reserved[3];
-} __packed;
-
-#define HTT_TX_RING_TLV_FILTER_MGMT_DMA_LEN GENMASK(3, 0)
-#define HTT_TX_RING_TLV_FILTER_CTRL_DMA_LEN GENMASK(7, 4)
-#define HTT_TX_RING_TLV_FILTER_DATA_DMA_LEN GENMASK(11, 8)
-
-#define HTT_TX_MON_FILTER_HYBRID_MODE \
- (HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_START_STATUS | \
- HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_END_STATUS | \
- HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START | \
- HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_END | \
- HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PPDU | \
- HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_PPDU | \
- HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_ACK_OR_BA | \
- HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_1K_BA | \
- HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PROT | \
- HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_PROT | \
- HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_RESPONSE | \
- HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO | \
- HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO_PART2)
-
-struct htt_tx_ring_tlv_filter {
- u32 tx_mon_downstream_tlv_flags;
- u32 tx_mon_upstream_tlv_flags0;
- u32 tx_mon_upstream_tlv_flags1;
- u32 tx_mon_upstream_tlv_flags2;
- bool tx_mon_mgmt_filter;
- bool tx_mon_data_filter;
- bool tx_mon_ctrl_filter;
- u16 tx_mon_pkt_dma_len;
-} __packed;
-
-enum htt_tx_mon_upstream_tlv_flags0 {
- HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_START_STATUS = BIT(1),
- HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_END_STATUS = BIT(2),
- HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START = BIT(3),
- HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_END = BIT(4),
- HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PPDU = BIT(5),
- HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_PPDU = BIT(6),
- HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_ACK_OR_BA = BIT(7),
- HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_1K_BA = BIT(8),
- HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PROT = BIT(9),
- HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_PROT = BIT(10),
- HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_RESPONSE = BIT(11),
- HTT_TX_FILTER_TLV_FLAGS0_RX_FRAME_BITMAP_ACK = BIT(12),
- HTT_TX_FILTER_TLV_FLAGS0_RX_FRAME_1K_BITMAP_ACK = BIT(13),
- HTT_TX_FILTER_TLV_FLAGS0_COEX_TX_STATUS = BIT(14),
- HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO = BIT(15),
- HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO_PART2 = BIT(16),
-};
-
-#define HTT_TX_FILTER_TLV_FLAGS2_TXPCU_PHYTX_OTHER_TRANSMIT_INFO32 BIT(11)
-
-/* HTT message target->host */
-
-enum htt_t2h_msg_type {
- HTT_T2H_MSG_TYPE_VERSION_CONF,
- HTT_T2H_MSG_TYPE_PEER_MAP = 0x3,
- HTT_T2H_MSG_TYPE_PEER_UNMAP = 0x4,
- HTT_T2H_MSG_TYPE_RX_ADDBA = 0x5,
- HTT_T2H_MSG_TYPE_PKTLOG = 0x8,
- HTT_T2H_MSG_TYPE_SEC_IND = 0xb,
- HTT_T2H_MSG_TYPE_PEER_MAP2 = 0x1e,
- HTT_T2H_MSG_TYPE_PEER_UNMAP2 = 0x1f,
- HTT_T2H_MSG_TYPE_PPDU_STATS_IND = 0x1d,
- HTT_T2H_MSG_TYPE_EXT_STATS_CONF = 0x1c,
- HTT_T2H_MSG_TYPE_BKPRESSURE_EVENT_IND = 0x24,
- HTT_T2H_MSG_TYPE_MLO_TIMESTAMP_OFFSET_IND = 0x28,
- HTT_T2H_MSG_TYPE_PEER_MAP3 = 0x2b,
- HTT_T2H_MSG_TYPE_VDEV_TXRX_STATS_PERIODIC_IND = 0x2c,
-};
-
-#define HTT_TARGET_VERSION_MAJOR 3
-
-#define HTT_T2H_MSG_TYPE GENMASK(7, 0)
-#define HTT_T2H_VERSION_CONF_MINOR GENMASK(15, 8)
-#define HTT_T2H_VERSION_CONF_MAJOR GENMASK(23, 16)
-
-struct htt_t2h_version_conf_msg {
- __le32 version;
-} __packed;
-
-#define HTT_T2H_PEER_MAP_INFO_VDEV_ID GENMASK(15, 8)
-#define HTT_T2H_PEER_MAP_INFO_PEER_ID GENMASK(31, 16)
-#define HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16 GENMASK(15, 0)
-#define HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID GENMASK(31, 16)
-#define HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL GENMASK(15, 0)
-#define HTT_T2H_PEER_MAP3_INFO2_HW_PEER_ID GENMASK(15, 0)
-#define HTT_T2H_PEER_MAP3_INFO2_AST_HASH_VAL GENMASK(31, 16)
-#define HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M BIT(16)
-#define HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_S 16
-
-struct htt_t2h_peer_map_event {
- __le32 info;
- __le32 mac_addr_l32;
- __le32 info1;
- __le32 info2;
-} __packed;
-
-#define HTT_T2H_PEER_UNMAP_INFO_VDEV_ID HTT_T2H_PEER_MAP_INFO_VDEV_ID
-#define HTT_T2H_PEER_UNMAP_INFO_PEER_ID HTT_T2H_PEER_MAP_INFO_PEER_ID
-#define HTT_T2H_PEER_UNMAP_INFO1_MAC_ADDR_H16 \
- HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16
-#define HTT_T2H_PEER_MAP_INFO1_NEXT_HOP_M HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M
-#define HTT_T2H_PEER_MAP_INFO1_NEXT_HOP_S HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_S
-
-struct htt_t2h_peer_unmap_event {
- __le32 info;
- __le32 mac_addr_l32;
- __le32 info1;
-} __packed;
-
-struct htt_resp_msg {
- union {
- struct htt_t2h_version_conf_msg version_msg;
- struct htt_t2h_peer_map_event peer_map_ev;
- struct htt_t2h_peer_unmap_event peer_unmap_ev;
- };
-} __packed;
-
-#define HTT_VDEV_GET_STATS_U64(msg_l32, msg_u32)\
- (((u64)__le32_to_cpu(msg_u32) << 32) | (__le32_to_cpu(msg_l32)))
-#define HTT_T2H_VDEV_STATS_PERIODIC_MSG_TYPE GENMASK(7, 0)
-#define HTT_T2H_VDEV_STATS_PERIODIC_PDEV_ID GENMASK(15, 8)
-#define HTT_T2H_VDEV_STATS_PERIODIC_NUM_VDEV GENMASK(23, 16)
-#define HTT_T2H_VDEV_STATS_PERIODIC_PAYLOAD_BYTES GENMASK(15, 0)
-#define HTT_VDEV_TXRX_STATS_COMMON_TLV 0
-#define HTT_VDEV_TXRX_STATS_HW_STATS_TLV 1
-
-struct htt_t2h_vdev_txrx_stats_ind {
- __le32 vdev_id;
- __le32 rx_msdu_byte_cnt_lo;
- __le32 rx_msdu_byte_cnt_hi;
- __le32 rx_msdu_cnt_lo;
- __le32 rx_msdu_cnt_hi;
- __le32 tx_msdu_byte_cnt_lo;
- __le32 tx_msdu_byte_cnt_hi;
- __le32 tx_msdu_cnt_lo;
- __le32 tx_msdu_cnt_hi;
- __le32 tx_retry_cnt_lo;
- __le32 tx_retry_cnt_hi;
- __le32 tx_retry_byte_cnt_lo;
- __le32 tx_retry_byte_cnt_hi;
- __le32 tx_drop_cnt_lo;
- __le32 tx_drop_cnt_hi;
- __le32 tx_drop_byte_cnt_lo;
- __le32 tx_drop_byte_cnt_hi;
- __le32 msdu_ttl_cnt_lo;
- __le32 msdu_ttl_cnt_hi;
- __le32 msdu_ttl_byte_cnt_lo;
- __le32 msdu_ttl_byte_cnt_hi;
-} __packed;
-
-struct htt_t2h_vdev_common_stats_tlv {
- __le32 soc_drop_count_lo;
- __le32 soc_drop_count_hi;
-} __packed;
-
-/* ppdu stats
- *
- * @details
- * The following field definitions describe the format of the HTT target
- * to host ppdu stats indication message.
- *
- *
- * |31 16|15 12|11 10|9 8|7 0 |
- * |----------------------------------------------------------------------|
- * | payload_size | rsvd |pdev_id|mac_id | msg type |
- * |----------------------------------------------------------------------|
- * | ppdu_id |
- * |----------------------------------------------------------------------|
- * | Timestamp in us |
- * |----------------------------------------------------------------------|
- * | reserved |
- * |----------------------------------------------------------------------|
- * | type-specific stats info |
- * | (see htt_ppdu_stats.h) |
- * |----------------------------------------------------------------------|
- * Header fields:
- * - MSG_TYPE
- * Bits 7:0
- * Purpose: Identifies this is a PPDU STATS indication
- * message.
- * Value: 0x1d
- * - mac_id
- * Bits 9:8
- * Purpose: mac_id of this ppdu_id
- * Value: 0-3
- * - pdev_id
- * Bits 11:10
- * Purpose: pdev_id of this ppdu_id
- * Value: 0-3
- * 0 (for rings at SOC level),
- * 1/2/3 PDEV -> 0/1/2
- * - payload_size
- * Bits 31:16
- * Purpose: total tlv size
- * Value: payload_size in bytes
- */
-
-#define HTT_T2H_PPDU_STATS_INFO_PDEV_ID GENMASK(11, 10)
-#define HTT_T2H_PPDU_STATS_INFO_PAYLOAD_SIZE GENMASK(31, 16)
-
-struct ath12k_htt_ppdu_stats_msg {
- __le32 info;
- __le32 ppdu_id;
- __le32 timestamp;
- __le32 rsvd;
- u8 data[];
-} __packed;
-
-struct htt_tlv {
- __le32 header;
- u8 value[];
-} __packed;
-
-#define HTT_TLV_TAG GENMASK(11, 0)
-#define HTT_TLV_LEN GENMASK(23, 12)
-
-enum HTT_PPDU_STATS_BW {
- HTT_PPDU_STATS_BANDWIDTH_5MHZ = 0,
- HTT_PPDU_STATS_BANDWIDTH_10MHZ = 1,
- HTT_PPDU_STATS_BANDWIDTH_20MHZ = 2,
- HTT_PPDU_STATS_BANDWIDTH_40MHZ = 3,
- HTT_PPDU_STATS_BANDWIDTH_80MHZ = 4,
- HTT_PPDU_STATS_BANDWIDTH_160MHZ = 5, /* includes 80+80 */
- HTT_PPDU_STATS_BANDWIDTH_DYN = 6,
-};
-
-#define HTT_PPDU_STATS_CMN_FLAGS_FRAME_TYPE_M GENMASK(7, 0)
-#define HTT_PPDU_STATS_CMN_FLAGS_QUEUE_TYPE_M GENMASK(15, 8)
-/* bw - HTT_PPDU_STATS_BW */
-#define HTT_PPDU_STATS_CMN_FLAGS_BW_M GENMASK(19, 16)
-
-struct htt_ppdu_stats_common {
- __le32 ppdu_id;
- __le16 sched_cmdid;
- u8 ring_id;
- u8 num_users;
- __le32 flags; /* %HTT_PPDU_STATS_COMMON_FLAGS_*/
- __le32 chain_mask;
- __le32 fes_duration_us; /* frame exchange sequence */
- __le32 ppdu_sch_eval_start_tstmp_us;
- __le32 ppdu_sch_end_tstmp_us;
- __le32 ppdu_start_tstmp_us;
- /* BIT [15 : 0] - phy mode (WLAN_PHY_MODE) with which ppdu was transmitted
- * BIT [31 : 16] - bandwidth (in MHz) with which ppdu was transmitted
- */
- __le16 phy_mode;
- __le16 bw_mhz;
-} __packed;
-
-enum htt_ppdu_stats_gi {
- HTT_PPDU_STATS_SGI_0_8_US,
- HTT_PPDU_STATS_SGI_0_4_US,
- HTT_PPDU_STATS_SGI_1_6_US,
- HTT_PPDU_STATS_SGI_3_2_US,
-};
-
-#define HTT_PPDU_STATS_USER_RATE_INFO0_USER_POS_M GENMASK(3, 0)
-#define HTT_PPDU_STATS_USER_RATE_INFO0_MU_GROUP_ID_M GENMASK(11, 4)
-
-enum HTT_PPDU_STATS_PPDU_TYPE {
- HTT_PPDU_STATS_PPDU_TYPE_SU,
- HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO,
- HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA,
- HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA,
- HTT_PPDU_STATS_PPDU_TYPE_UL_TRIG,
- HTT_PPDU_STATS_PPDU_TYPE_BURST_BCN,
- HTT_PPDU_STATS_PPDU_TYPE_UL_BSR_RESP,
- HTT_PPDU_STATS_PPDU_TYPE_UL_BSR_TRIG,
- HTT_PPDU_STATS_PPDU_TYPE_UL_RESP,
- HTT_PPDU_STATS_PPDU_TYPE_MAX
-};
-
-#define HTT_PPDU_STATS_USER_RATE_INFO1_RESP_TYPE_VALD_M BIT(0)
-#define HTT_PPDU_STATS_USER_RATE_INFO1_PPDU_TYPE_M GENMASK(5, 1)
-
-#define HTT_PPDU_STATS_USER_RATE_FLAGS_LTF_SIZE_M GENMASK(1, 0)
-#define HTT_PPDU_STATS_USER_RATE_FLAGS_STBC_M BIT(2)
-#define HTT_PPDU_STATS_USER_RATE_FLAGS_HE_RE_M BIT(3)
-#define HTT_PPDU_STATS_USER_RATE_FLAGS_TXBF_M GENMASK(7, 4)
-#define HTT_PPDU_STATS_USER_RATE_FLAGS_BW_M GENMASK(11, 8)
-#define HTT_PPDU_STATS_USER_RATE_FLAGS_NSS_M GENMASK(15, 12)
-#define HTT_PPDU_STATS_USER_RATE_FLAGS_MCS_M GENMASK(19, 16)
-#define HTT_PPDU_STATS_USER_RATE_FLAGS_PREAMBLE_M GENMASK(23, 20)
-#define HTT_PPDU_STATS_USER_RATE_FLAGS_GI_M GENMASK(27, 24)
-#define HTT_PPDU_STATS_USER_RATE_FLAGS_DCM_M BIT(28)
-#define HTT_PPDU_STATS_USER_RATE_FLAGS_LDPC_M BIT(29)
-
-#define HTT_USR_RATE_PPDU_TYPE(_val) \
- le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_INFO1_PPDU_TYPE_M)
-#define HTT_USR_RATE_PREAMBLE(_val) \
- le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_PREAMBLE_M)
-#define HTT_USR_RATE_BW(_val) \
- le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_BW_M)
-#define HTT_USR_RATE_NSS(_val) \
- le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_NSS_M)
-#define HTT_USR_RATE_MCS(_val) \
- le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_MCS_M)
-#define HTT_USR_RATE_GI(_val) \
- le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_GI_M)
-#define HTT_USR_RATE_DCM(_val) \
- le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_DCM_M)
-
-#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_LTF_SIZE_M GENMASK(1, 0)
-#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_STBC_M BIT(2)
-#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_HE_RE_M BIT(3)
-#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_TXBF_M GENMASK(7, 4)
-#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_BW_M GENMASK(11, 8)
-#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_NSS_M GENMASK(15, 12)
-#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_MCS_M GENMASK(19, 16)
-#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_PREAMBLE_M GENMASK(23, 20)
-#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_GI_M GENMASK(27, 24)
-#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_DCM_M BIT(28)
-#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_LDPC_M BIT(29)
-
-struct htt_ppdu_stats_user_rate {
- u8 tid_num;
- u8 reserved0;
- __le16 sw_peer_id;
- __le32 info0; /* %HTT_PPDU_STATS_USER_RATE_INFO0_*/
- __le16 ru_end;
- __le16 ru_start;
- __le16 resp_ru_end;
- __le16 resp_ru_start;
- __le32 info1; /* %HTT_PPDU_STATS_USER_RATE_INFO1_ */
- __le32 rate_flags; /* %HTT_PPDU_STATS_USER_RATE_FLAGS_ */
- /* Note: resp_rate_info is only valid for if resp_type is UL */
- __le32 resp_rate_flags; /* %HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_ */
-} __packed;
-
-#define HTT_PPDU_STATS_TX_INFO_FLAGS_RATECODE_M GENMASK(7, 0)
-#define HTT_PPDU_STATS_TX_INFO_FLAGS_IS_AMPDU_M BIT(8)
-#define HTT_PPDU_STATS_TX_INFO_FLAGS_BA_ACK_FAILED_M GENMASK(10, 9)
-#define HTT_PPDU_STATS_TX_INFO_FLAGS_BW_M GENMASK(13, 11)
-#define HTT_PPDU_STATS_TX_INFO_FLAGS_SGI_M BIT(14)
-#define HTT_PPDU_STATS_TX_INFO_FLAGS_PEERID_M GENMASK(31, 16)
-
-#define HTT_TX_INFO_IS_AMSDU(_flags) \
- u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_IS_AMPDU_M)
-#define HTT_TX_INFO_BA_ACK_FAILED(_flags) \
- u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_BA_ACK_FAILED_M)
-#define HTT_TX_INFO_RATECODE(_flags) \
- u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_RATECODE_M)
-#define HTT_TX_INFO_PEERID(_flags) \
- u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_PEERID_M)
-
-enum htt_ppdu_stats_usr_compln_status {
- HTT_PPDU_STATS_USER_STATUS_OK,
- HTT_PPDU_STATS_USER_STATUS_FILTERED,
- HTT_PPDU_STATS_USER_STATUS_RESP_TIMEOUT,
- HTT_PPDU_STATS_USER_STATUS_RESP_MISMATCH,
- HTT_PPDU_STATS_USER_STATUS_ABORT,
-};
-
-#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_LONG_RETRY_M GENMASK(3, 0)
-#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_SHORT_RETRY_M GENMASK(7, 4)
-#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_IS_AMPDU_M BIT(8)
-#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_RESP_TYPE_M GENMASK(12, 9)
-
-#define HTT_USR_CMPLTN_IS_AMPDU(_val) \
- le32_get_bits(_val, HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_IS_AMPDU_M)
-#define HTT_USR_CMPLTN_LONG_RETRY(_val) \
- le32_get_bits(_val, HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_LONG_RETRY_M)
-#define HTT_USR_CMPLTN_SHORT_RETRY(_val) \
- le32_get_bits(_val, HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_SHORT_RETRY_M)
-
-struct htt_ppdu_stats_usr_cmpltn_cmn {
- u8 status;
- u8 tid_num;
- __le16 sw_peer_id;
- /* RSSI value of last ack packet (units = dB above noise floor) */
- __le32 ack_rssi;
- __le16 mpdu_tried;
- __le16 mpdu_success;
- __le32 flags; /* %HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_LONG_RETRIES*/
-} __packed;
-
-#define HTT_PPDU_STATS_ACK_BA_INFO_NUM_MPDU_M GENMASK(8, 0)
-#define HTT_PPDU_STATS_ACK_BA_INFO_NUM_MSDU_M GENMASK(24, 9)
-#define HTT_PPDU_STATS_ACK_BA_INFO_TID_NUM GENMASK(31, 25)
-
-#define HTT_PPDU_STATS_NON_QOS_TID 16
-
-struct htt_ppdu_stats_usr_cmpltn_ack_ba_status {
- __le32 ppdu_id;
- __le16 sw_peer_id;
- __le16 reserved0;
- __le32 info; /* %HTT_PPDU_STATS_USR_CMPLTN_CMN_INFO_ */
- __le16 current_seq;
- __le16 start_seq;
- __le32 success_bytes;
-} __packed;
-
-struct htt_ppdu_user_stats {
- u16 peer_id;
- u16 delay_ba;
- u32 tlv_flags;
- bool is_valid_peer_id;
- struct htt_ppdu_stats_user_rate rate;
- struct htt_ppdu_stats_usr_cmpltn_cmn cmpltn_cmn;
- struct htt_ppdu_stats_usr_cmpltn_ack_ba_status ack_ba;
-};
-
-#define HTT_PPDU_STATS_MAX_USERS 8
-#define HTT_PPDU_DESC_MAX_DEPTH 16
-
-struct htt_ppdu_stats {
- struct htt_ppdu_stats_common common;
- struct htt_ppdu_user_stats user_stats[HTT_PPDU_STATS_MAX_USERS];
-};
-
-struct htt_ppdu_stats_info {
- u32 tlv_bitmap;
- u32 ppdu_id;
- u32 frame_type;
- u32 frame_ctrl;
- u32 delay_ba;
- u32 bar_num_users;
- struct htt_ppdu_stats ppdu_stats;
- struct list_head list;
-};
-
-/* @brief target -> host MLO offset indiciation message
- *
- * @details
- * The following field definitions describe the format of the HTT target
- * to host mlo offset indication message.
- *
- *
- * |31 29|28 |26|25 22|21 16|15 13|12 10 |9 8|7 0|
- * |---------------------------------------------------------------------|
- * | rsvd1 | mac_freq |chip_id |pdev_id|msgtype|
- * |---------------------------------------------------------------------|
- * | sync_timestamp_lo_us |
- * |---------------------------------------------------------------------|
- * | sync_timestamp_hi_us |
- * |---------------------------------------------------------------------|
- * | mlo_offset_lo |
- * |---------------------------------------------------------------------|
- * | mlo_offset_hi |
- * |---------------------------------------------------------------------|
- * | mlo_offset_clcks |
- * |---------------------------------------------------------------------|
- * | rsvd2 | mlo_comp_clks |mlo_comp_us |
- * |---------------------------------------------------------------------|
- * | rsvd3 |mlo_comp_timer |
- * |---------------------------------------------------------------------|
- * Header fields
- * - MSG_TYPE
- * Bits 7:0
- * Purpose: Identifies this is a MLO offset indication msg
- * - PDEV_ID
- * Bits 9:8
- * Purpose: Pdev of this MLO offset
- * - CHIP_ID
- * Bits 12:10
- * Purpose: chip_id of this MLO offset
- * - MAC_FREQ
- * Bits 28:13
- * - SYNC_TIMESTAMP_LO_US
- * Purpose: clock frequency of the mac HW block in MHz
- * Bits: 31:0
- * Purpose: lower 32 bits of the WLAN global time stamp at which
- * last sync interrupt was received
- * - SYNC_TIMESTAMP_HI_US
- * Bits: 31:0
- * Purpose: upper 32 bits of WLAN global time stamp at which
- * last sync interrupt was received
- * - MLO_OFFSET_LO
- * Bits: 31:0
- * Purpose: lower 32 bits of the MLO offset in us
- * - MLO_OFFSET_HI
- * Bits: 31:0
- * Purpose: upper 32 bits of the MLO offset in us
- * - MLO_COMP_US
- * Bits: 15:0
- * Purpose: MLO time stamp compensation applied in us
- * - MLO_COMP_CLCKS
- * Bits: 25:16
- * Purpose: MLO time stamp compensation applied in clock ticks
- * - MLO_COMP_TIMER
- * Bits: 21:0
- * Purpose: Periodic timer at which compensation is applied
- */
-
-#define HTT_T2H_MLO_OFFSET_INFO_MSG_TYPE GENMASK(7, 0)
-#define HTT_T2H_MLO_OFFSET_INFO_PDEV_ID GENMASK(9, 8)
-
-struct ath12k_htt_mlo_offset_msg {
- __le32 info;
- __le32 sync_timestamp_lo_us;
- __le32 sync_timestamp_hi_us;
- __le32 mlo_offset_hi;
- __le32 mlo_offset_lo;
- __le32 mlo_offset_clks;
- __le32 mlo_comp_clks;
- __le32 mlo_comp_timer;
-} __packed;
-
-/* @brief host -> target FW extended statistics retrieve
- *
- * @details
- * The following field definitions describe the format of the HTT host
- * to target FW extended stats retrieve message.
- * The message specifies the type of stats the host wants to retrieve.
- *
- * |31 24|23 16|15 8|7 0|
- * |-----------------------------------------------------------|
- * | reserved | stats type | pdev_mask | msg type |
- * |-----------------------------------------------------------|
- * | config param [0] |
- * |-----------------------------------------------------------|
- * | config param [1] |
- * |-----------------------------------------------------------|
- * | config param [2] |
- * |-----------------------------------------------------------|
- * | config param [3] |
- * |-----------------------------------------------------------|
- * | reserved |
- * |-----------------------------------------------------------|
- * | cookie LSBs |
- * |-----------------------------------------------------------|
- * | cookie MSBs |
- * |-----------------------------------------------------------|
- * Header fields:
- * - MSG_TYPE
- * Bits 7:0
- * Purpose: identifies this is a extended stats upload request message
- * Value: 0x10
- * - PDEV_MASK
- * Bits 8:15
- * Purpose: identifies the mask of PDEVs to retrieve stats from
- * Value: This is a overloaded field, refer to usage and interpretation of
- * PDEV in interface document.
- * Bit 8 : Reserved for SOC stats
- * Bit 9 - 15 : Indicates PDEV_MASK in DBDC
- * Indicates MACID_MASK in DBS
- * - STATS_TYPE
- * Bits 23:16
- * Purpose: identifies which FW statistics to upload
- * Value: Defined by htt_dbg_ext_stats_type (see htt_stats.h)
- * - Reserved
- * Bits 31:24
- * - CONFIG_PARAM [0]
- * Bits 31:0
- * Purpose: give an opaque configuration value to the specified stats type
- * Value: stats-type specific configuration value
- * Refer to htt_stats.h for interpretation for each stats sub_type
- * - CONFIG_PARAM [1]
- * Bits 31:0
- * Purpose: give an opaque configuration value to the specified stats type
- * Value: stats-type specific configuration value
- * Refer to htt_stats.h for interpretation for each stats sub_type
- * - CONFIG_PARAM [2]
- * Bits 31:0
- * Purpose: give an opaque configuration value to the specified stats type
- * Value: stats-type specific configuration value
- * Refer to htt_stats.h for interpretation for each stats sub_type
- * - CONFIG_PARAM [3]
- * Bits 31:0
- * Purpose: give an opaque configuration value to the specified stats type
- * Value: stats-type specific configuration value
- * Refer to htt_stats.h for interpretation for each stats sub_type
- * - Reserved [31:0] for future use.
- * - COOKIE_LSBS
- * Bits 31:0
- * Purpose: Provide a mechanism to match a target->host stats confirmation
- * message with its preceding host->target stats request message.
- * Value: LSBs of the opaque cookie specified by the host-side requestor
- * - COOKIE_MSBS
- * Bits 31:0
- * Purpose: Provide a mechanism to match a target->host stats confirmation
- * message with its preceding host->target stats request message.
- * Value: MSBs of the opaque cookie specified by the host-side requestor
- */
-
-struct htt_ext_stats_cfg_hdr {
- u8 msg_type;
- u8 pdev_mask;
- u8 stats_type;
- u8 reserved;
-} __packed;
-
-struct htt_ext_stats_cfg_cmd {
- struct htt_ext_stats_cfg_hdr hdr;
- __le32 cfg_param0;
- __le32 cfg_param1;
- __le32 cfg_param2;
- __le32 cfg_param3;
- __le32 reserved;
- __le32 cookie_lsb;
- __le32 cookie_msb;
-} __packed;
-
-/* htt stats config default params */
-#define HTT_STAT_DEFAULT_RESET_START_OFFSET 0
-#define HTT_STAT_DEFAULT_CFG0_ALL_HWQS 0xffffffff
-#define HTT_STAT_DEFAULT_CFG0_ALL_TXQS 0xffffffff
-#define HTT_STAT_DEFAULT_CFG0_ALL_CMDQS 0xffff
-#define HTT_STAT_DEFAULT_CFG0_ALL_RINGS 0xffff
-#define HTT_STAT_DEFAULT_CFG0_ACTIVE_PEERS 0xff
-#define HTT_STAT_DEFAULT_CFG0_CCA_CUMULATIVE 0x00
-#define HTT_STAT_DEFAULT_CFG0_ACTIVE_VDEVS 0x00
-
-/* HTT_DBG_EXT_STATS_PEER_INFO
- * PARAMS:
- * @config_param0:
- * [Bit0] - [0] for sw_peer_id, [1] for mac_addr based request
- * [Bit15 : Bit 1] htt_peer_stats_req_mode_t
- * [Bit31 : Bit16] sw_peer_id
- * @config_param1:
- * peer_stats_req_type_mask:32 (enum htt_peer_stats_tlv_enum)
- * 0 bit htt_peer_stats_cmn_tlv
- * 1 bit htt_peer_details_tlv
- * 2 bit htt_tx_peer_rate_stats_tlv
- * 3 bit htt_rx_peer_rate_stats_tlv
- * 4 bit htt_tx_tid_stats_tlv/htt_tx_tid_stats_v1_tlv
- * 5 bit htt_rx_tid_stats_tlv
- * 6 bit htt_msdu_flow_stats_tlv
- * @config_param2: [Bit31 : Bit0] mac_addr31to0
- * @config_param3: [Bit15 : Bit0] mac_addr47to32
- * [Bit31 : Bit16] reserved
- */
-#define HTT_STAT_PEER_INFO_MAC_ADDR BIT(0)
-#define HTT_STAT_DEFAULT_PEER_REQ_TYPE 0x7f
-
-/* Used to set different configs to the specified stats type.*/
-struct htt_ext_stats_cfg_params {
- u32 cfg0;
- u32 cfg1;
- u32 cfg2;
- u32 cfg3;
-};
-
-enum vdev_stats_offload_timer_duration {
- ATH12K_STATS_TIMER_DUR_500MS = 1,
- ATH12K_STATS_TIMER_DUR_1SEC = 2,
- ATH12K_STATS_TIMER_DUR_2SEC = 3,
-};
-
-#define ATH12K_HTT_MAC_ADDR_L32_0 GENMASK(7, 0)
-#define ATH12K_HTT_MAC_ADDR_L32_1 GENMASK(15, 8)
-#define ATH12K_HTT_MAC_ADDR_L32_2 GENMASK(23, 16)
-#define ATH12K_HTT_MAC_ADDR_L32_3 GENMASK(31, 24)
-#define ATH12K_HTT_MAC_ADDR_H16_0 GENMASK(7, 0)
-#define ATH12K_HTT_MAC_ADDR_H16_1 GENMASK(15, 8)
-
-struct htt_mac_addr {
- __le32 mac_addr_l32;
- __le32 mac_addr_h16;
-} __packed;
-
static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr)
{
memcpy(addr, &addr_l32, 4);
diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.h b/drivers/net/wireless/ath/ath12k/dp_htt.h
new file mode 100644
index 000000000000..ce9064628d34
--- /dev/null
+++ b/drivers/net/wireless/ath/ath12k/dp_htt.h
@@ -0,0 +1,1517 @@
+/* SPDX-License-Identifier: BSD-3-Clause-Clear */
+/*
+ * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef ATH12K_DP_HTT_H
+#define ATH12K_DP_HTT_H
+
+struct ath12k_dp;
+
+/* HTT definitions */
+#define HTT_TAG_TCL_METADATA_VERSION 5
+
+#define HTT_TCL_META_DATA_TYPE GENMASK(1, 0)
+#define HTT_TCL_META_DATA_VALID_HTT BIT(2)
+
+/* vdev meta data */
+#define HTT_TCL_META_DATA_VDEV_ID GENMASK(10, 3)
+#define HTT_TCL_META_DATA_PDEV_ID GENMASK(12, 11)
+#define HTT_TCL_META_DATA_HOST_INSPECTED_MISSION BIT(13)
+
+/* peer meta data */
+#define HTT_TCL_META_DATA_PEER_ID GENMASK(15, 3)
+
+/* Global sequence number */
+#define HTT_TCL_META_DATA_TYPE_GLOBAL_SEQ_NUM 3
+#define HTT_TCL_META_DATA_GLOBAL_SEQ_HOST_INSPECTED BIT(2)
+#define HTT_TCL_META_DATA_GLOBAL_SEQ_NUM GENMASK(14, 3)
+#define HTT_TX_MLO_MCAST_HOST_REINJECT_BASE_VDEV_ID 128
+
+/* HTT tx completion is overlaid in wbm_release_ring */
+#define HTT_TX_WBM_COMP_INFO0_STATUS GENMASK(16, 13)
+#define HTT_TX_WBM_COMP_INFO1_REINJECT_REASON GENMASK(3, 0)
+#define HTT_TX_WBM_COMP_INFO1_EXCEPTION_FRAME BIT(4)
+
+#define HTT_TX_WBM_COMP_INFO2_ACK_RSSI GENMASK(31, 24)
+
+struct htt_tx_wbm_completion {
+ __le32 rsvd0[2];
+ __le32 info0;
+ __le32 info1;
+ __le32 info2;
+ __le32 info3;
+ __le32 info4;
+ __le32 rsvd1;
+
+} __packed;
+
+enum htt_h2t_msg_type {
+ HTT_H2T_MSG_TYPE_VERSION_REQ = 0,
+ HTT_H2T_MSG_TYPE_SRING_SETUP = 0xb,
+ HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG = 0xc,
+ HTT_H2T_MSG_TYPE_EXT_STATS_CFG = 0x10,
+ HTT_H2T_MSG_TYPE_PPDU_STATS_CFG = 0x11,
+ HTT_H2T_MSG_TYPE_VDEV_TXRX_STATS_CFG = 0x1a,
+ HTT_H2T_MSG_TYPE_TX_MONITOR_CFG = 0x1b,
+};
+
+#define HTT_VER_REQ_INFO_MSG_ID GENMASK(7, 0)
+#define HTT_OPTION_TCL_METADATA_VER_V1 1
+#define HTT_OPTION_TCL_METADATA_VER_V2 2
+#define HTT_OPTION_TAG GENMASK(7, 0)
+#define HTT_OPTION_LEN GENMASK(15, 8)
+#define HTT_OPTION_VALUE GENMASK(31, 16)
+#define HTT_TCL_METADATA_VER_SZ 4
+
+struct htt_ver_req_cmd {
+ __le32 ver_reg_info;
+ __le32 tcl_metadata_version;
+} __packed;
+
+enum htt_srng_ring_type {
+ HTT_HW_TO_SW_RING,
+ HTT_SW_TO_HW_RING,
+ HTT_SW_TO_SW_RING,
+};
+
+enum htt_srng_ring_id {
+ HTT_RXDMA_HOST_BUF_RING,
+ HTT_RXDMA_MONITOR_STATUS_RING,
+ HTT_RXDMA_MONITOR_BUF_RING,
+ HTT_RXDMA_MONITOR_DESC_RING,
+ HTT_RXDMA_MONITOR_DEST_RING,
+ HTT_HOST1_TO_FW_RXBUF_RING,
+ HTT_HOST2_TO_FW_RXBUF_RING,
+ HTT_RXDMA_NON_MONITOR_DEST_RING,
+ HTT_RXDMA_HOST_BUF_RING2,
+ HTT_TX_MON_HOST2MON_BUF_RING,
+ HTT_TX_MON_MON2HOST_DEST_RING,
+ HTT_RX_MON_HOST2MON_BUF_RING,
+ HTT_RX_MON_MON2HOST_DEST_RING,
+};
+
+/* host -> target HTT_SRING_SETUP message
+ *
+ * After target is booted up, Host can send SRING setup message for
+ * each host facing LMAC SRING. Target setups up HW registers based
+ * on setup message and confirms back to Host if response_required is set.
+ * Host should wait for confirmation message before sending new SRING
+ * setup message
+ *
+ * The message would appear as follows:
+ *
+ * |31 24|23 20|19|18 16|15|14 8|7 0|
+ * |--------------- +-----------------+----------------+------------------|
+ * | ring_type | ring_id | pdev_id | msg_type |
+ * |----------------------------------------------------------------------|
+ * | ring_base_addr_lo |
+ * |----------------------------------------------------------------------|
+ * | ring_base_addr_hi |
+ * |----------------------------------------------------------------------|
+ * |ring_misc_cfg_flag|ring_entry_size| ring_size |
+ * |----------------------------------------------------------------------|
+ * | ring_head_offset32_remote_addr_lo |
+ * |----------------------------------------------------------------------|
+ * | ring_head_offset32_remote_addr_hi |
+ * |----------------------------------------------------------------------|
+ * | ring_tail_offset32_remote_addr_lo |
+ * |----------------------------------------------------------------------|
+ * | ring_tail_offset32_remote_addr_hi |
+ * |----------------------------------------------------------------------|
+ * | ring_msi_addr_lo |
+ * |----------------------------------------------------------------------|
+ * | ring_msi_addr_hi |
+ * |----------------------------------------------------------------------|
+ * | ring_msi_data |
+ * |----------------------------------------------------------------------|
+ * | intr_timer_th |IM| intr_batch_counter_th |
+ * |----------------------------------------------------------------------|
+ * | reserved |RR|PTCF| intr_low_threshold |
+ * |----------------------------------------------------------------------|
+ * Where
+ * IM = sw_intr_mode
+ * RR = response_required
+ * PTCF = prefetch_timer_cfg
+ *
+ * The message is interpreted as follows:
+ * dword0 - b'0:7 - msg_type: This will be set to
+ * HTT_H2T_MSG_TYPE_SRING_SETUP
+ * b'8:15 - pdev_id:
+ * 0 (for rings at SOC/UMAC level),
+ * 1/2/3 mac id (for rings at LMAC level)
+ * b'16:23 - ring_id: identify which ring is to setup,
+ * more details can be got from enum htt_srng_ring_id
+ * b'24:31 - ring_type: identify type of host rings,
+ * more details can be got from enum htt_srng_ring_type
+ * dword1 - b'0:31 - ring_base_addr_lo: Lower 32bits of ring base address
+ * dword2 - b'0:31 - ring_base_addr_hi: Upper 32bits of ring base address
+ * dword3 - b'0:15 - ring_size: size of the ring in unit of 4-bytes words
+ * b'16:23 - ring_entry_size: Size of each entry in 4-byte word units
+ * b'24:31 - ring_misc_cfg_flag: Valid only for HW_TO_SW_RING and
+ * SW_TO_HW_RING.
+ * Refer to HTT_SRING_SETUP_RING_MISC_CFG_RING defs.
+ * dword4 - b'0:31 - ring_head_off32_remote_addr_lo:
+ * Lower 32 bits of memory address of the remote variable
+ * storing the 4-byte word offset that identifies the head
+ * element within the ring.
+ * (The head offset variable has type u32.)
+ * Valid for HW_TO_SW and SW_TO_SW rings.
+ * dword5 - b'0:31 - ring_head_off32_remote_addr_hi:
+ * Upper 32 bits of memory address of the remote variable
+ * storing the 4-byte word offset that identifies the head
+ * element within the ring.
+ * (The head offset variable has type u32.)
+ * Valid for HW_TO_SW and SW_TO_SW rings.
+ * dword6 - b'0:31 - ring_tail_off32_remote_addr_lo:
+ * Lower 32 bits of memory address of the remote variable
+ * storing the 4-byte word offset that identifies the tail
+ * element within the ring.
+ * (The tail offset variable has type u32.)
+ * Valid for HW_TO_SW and SW_TO_SW rings.
+ * dword7 - b'0:31 - ring_tail_off32_remote_addr_hi:
+ * Upper 32 bits of memory address of the remote variable
+ * storing the 4-byte word offset that identifies the tail
+ * element within the ring.
+ * (The tail offset variable has type u32.)
+ * Valid for HW_TO_SW and SW_TO_SW rings.
+ * dword8 - b'0:31 - ring_msi_addr_lo: Lower 32bits of MSI cfg address
+ * valid only for HW_TO_SW_RING and SW_TO_HW_RING
+ * dword9 - b'0:31 - ring_msi_addr_hi: Upper 32bits of MSI cfg address
+ * valid only for HW_TO_SW_RING and SW_TO_HW_RING
+ * dword10 - b'0:31 - ring_msi_data: MSI data
+ * Refer to HTT_SRING_SETUP_RING_MSC_CFG_xxx defs
+ * valid only for HW_TO_SW_RING and SW_TO_HW_RING
+ * dword11 - b'0:14 - intr_batch_counter_th:
+ * batch counter threshold is in units of 4-byte words.
+ * HW internally maintains and increments batch count.
+ * (see SRING spec for detail description).
+ * When batch count reaches threshold value, an interrupt
+ * is generated by HW.
+ * b'15 - sw_intr_mode:
+ * This configuration shall be static.
+ * Only programmed at power up.
+ * 0: generate pulse style sw interrupts
+ * 1: generate level style sw interrupts
+ * b'16:31 - intr_timer_th:
+ * The timer init value when timer is idle or is
+ * initialized to start downcounting.
+ * In 8us units (to cover a range of 0 to 524 ms)
+ * dword12 - b'0:15 - intr_low_threshold:
+ * Used only by Consumer ring to generate ring_sw_int_p.
+ * Ring entries low threshold water mark, that is used
+ * in combination with the interrupt timer as well as
+ * the clearing of the level interrupt.
+ * b'16:18 - prefetch_timer_cfg:
+ * Used only by Consumer ring to set timer mode to
+ * support Application prefetch handling.
+ * The external tail offset/pointer will be updated
+ * at following intervals:
+ * 3'b000: (Prefetch feature disabled; used only for debug)
+ * 3'b001: 1 usec
+ * 3'b010: 4 usec
+ * 3'b011: 8 usec (default)
+ * 3'b100: 16 usec
+ * Others: Reserved
+ * b'19 - response_required:
+ * Host needs HTT_T2H_MSG_TYPE_SRING_SETUP_DONE as response
+ * b'20:31 - reserved: reserved for future use
+ */
+
+#define HTT_SRNG_SETUP_CMD_INFO0_MSG_TYPE GENMASK(7, 0)
+#define HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID GENMASK(15, 8)
+#define HTT_SRNG_SETUP_CMD_INFO0_RING_ID GENMASK(23, 16)
+#define HTT_SRNG_SETUP_CMD_INFO0_RING_TYPE GENMASK(31, 24)
+
+#define HTT_SRNG_SETUP_CMD_INFO1_RING_SIZE GENMASK(15, 0)
+#define HTT_SRNG_SETUP_CMD_INFO1_RING_ENTRY_SIZE GENMASK(23, 16)
+#define HTT_SRNG_SETUP_CMD_INFO1_RING_LOOP_CNT_DIS BIT(25)
+#define HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_MSI_SWAP BIT(27)
+#define HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_HOST_FW_SWAP BIT(28)
+#define HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_TLV_SWAP BIT(29)
+
+#define HTT_SRNG_SETUP_CMD_INTR_INFO_BATCH_COUNTER_THRESH GENMASK(14, 0)
+#define HTT_SRNG_SETUP_CMD_INTR_INFO_SW_INTR_MODE BIT(15)
+#define HTT_SRNG_SETUP_CMD_INTR_INFO_INTR_TIMER_THRESH GENMASK(31, 16)
+
+#define HTT_SRNG_SETUP_CMD_INFO2_INTR_LOW_THRESH GENMASK(15, 0)
+#define HTT_SRNG_SETUP_CMD_INFO2_PRE_FETCH_TIMER_CFG GENMASK(18, 16)
+#define HTT_SRNG_SETUP_CMD_INFO2_RESPONSE_REQUIRED BIT(19)
+
+struct htt_srng_setup_cmd {
+ __le32 info0;
+ __le32 ring_base_addr_lo;
+ __le32 ring_base_addr_hi;
+ __le32 info1;
+ __le32 ring_head_off32_remote_addr_lo;
+ __le32 ring_head_off32_remote_addr_hi;
+ __le32 ring_tail_off32_remote_addr_lo;
+ __le32 ring_tail_off32_remote_addr_hi;
+ __le32 ring_msi_addr_lo;
+ __le32 ring_msi_addr_hi;
+ __le32 msi_data;
+ __le32 intr_info;
+ __le32 info2;
+} __packed;
+
+/* host -> target FW PPDU_STATS config message
+ *
+ * @details
+ * The following field definitions describe the format of the HTT host
+ * to target FW for PPDU_STATS_CFG msg.
+ * The message allows the host to configure the PPDU_STATS_IND messages
+ * produced by the target.
+ *
+ * |31 24|23 16|15 8|7 0|
+ * |-----------------------------------------------------------|
+ * | REQ bit mask | pdev_mask | msg type |
+ * |-----------------------------------------------------------|
+ * Header fields:
+ * - MSG_TYPE
+ * Bits 7:0
+ * Purpose: identifies this is a req to configure ppdu_stats_ind from target
+ * Value: 0x11
+ * - PDEV_MASK
+ * Bits 8:15
+ * Purpose: identifies which pdevs this PPDU stats configuration applies to
+ * Value: This is a overloaded field, refer to usage and interpretation of
+ * PDEV in interface document.
+ * Bit 8 : Reserved for SOC stats
+ * Bit 9 - 15 : Indicates PDEV_MASK in DBDC
+ * Indicates MACID_MASK in DBS
+ * - REQ_TLV_BIT_MASK
+ * Bits 16:31
+ * Purpose: each set bit indicates the corresponding PPDU stats TLV type
+ * needs to be included in the target's PPDU_STATS_IND messages.
+ * Value: refer htt_ppdu_stats_tlv_tag_t <<<???
+ *
+ */
+
+struct htt_ppdu_stats_cfg_cmd {
+ __le32 msg;
+} __packed;
+
+#define HTT_PPDU_STATS_CFG_MSG_TYPE GENMASK(7, 0)
+#define HTT_PPDU_STATS_CFG_SOC_STATS BIT(8)
+#define HTT_PPDU_STATS_CFG_PDEV_ID GENMASK(15, 9)
+#define HTT_PPDU_STATS_CFG_TLV_TYPE_BITMASK GENMASK(31, 16)
+
+enum htt_ppdu_stats_tag_type {
+ HTT_PPDU_STATS_TAG_COMMON,
+ HTT_PPDU_STATS_TAG_USR_COMMON,
+ HTT_PPDU_STATS_TAG_USR_RATE,
+ HTT_PPDU_STATS_TAG_USR_MPDU_ENQ_BITMAP_64,
+ HTT_PPDU_STATS_TAG_USR_MPDU_ENQ_BITMAP_256,
+ HTT_PPDU_STATS_TAG_SCH_CMD_STATUS,
+ HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON,
+ HTT_PPDU_STATS_TAG_USR_COMPLTN_BA_BITMAP_64,
+ HTT_PPDU_STATS_TAG_USR_COMPLTN_BA_BITMAP_256,
+ HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS,
+ HTT_PPDU_STATS_TAG_USR_COMPLTN_FLUSH,
+ HTT_PPDU_STATS_TAG_USR_COMMON_ARRAY,
+ HTT_PPDU_STATS_TAG_INFO,
+ HTT_PPDU_STATS_TAG_TX_MGMTCTRL_PAYLOAD,
+
+ /* New TLV's are added above to this line */
+ HTT_PPDU_STATS_TAG_MAX,
+};
+
+#define HTT_PPDU_STATS_TAG_DEFAULT (BIT(HTT_PPDU_STATS_TAG_COMMON) \
+ | BIT(HTT_PPDU_STATS_TAG_USR_COMMON) \
+ | BIT(HTT_PPDU_STATS_TAG_USR_RATE) \
+ | BIT(HTT_PPDU_STATS_TAG_SCH_CMD_STATUS) \
+ | BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON) \
+ | BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS) \
+ | BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_FLUSH) \
+ | BIT(HTT_PPDU_STATS_TAG_USR_COMMON_ARRAY))
+
+#define HTT_PPDU_STATS_TAG_PKTLOG (BIT(HTT_PPDU_STATS_TAG_USR_MPDU_ENQ_BITMAP_64) | \
+ BIT(HTT_PPDU_STATS_TAG_USR_MPDU_ENQ_BITMAP_256) | \
+ BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_BA_BITMAP_64) | \
+ BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_BA_BITMAP_256) | \
+ BIT(HTT_PPDU_STATS_TAG_INFO) | \
+ BIT(HTT_PPDU_STATS_TAG_TX_MGMTCTRL_PAYLOAD) | \
+ HTT_PPDU_STATS_TAG_DEFAULT)
+
+enum htt_stats_internal_ppdu_frametype {
+ HTT_STATS_PPDU_FTYPE_CTRL,
+ HTT_STATS_PPDU_FTYPE_DATA,
+ HTT_STATS_PPDU_FTYPE_BAR,
+ HTT_STATS_PPDU_FTYPE_MAX
+};
+
+/* HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG Message
+ *
+ * details:
+ * HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG message is sent by host to
+ * configure RXDMA rings.
+ * The configuration is per ring based and includes both packet subtypes
+ * and PPDU/MPDU TLVs.
+ *
+ * The message would appear as follows:
+ *
+ * |31 29|28|27|26|25|24|23 16|15 8|7 0|
+ * |-------+--+--+--+--+--+-----------+----------------+---------------|
+ * | rsvd1 |ED|DT|OV|PS|SS| ring_id | pdev_id | msg_type |
+ * |-------------------------------------------------------------------|
+ * | rsvd2 | ring_buffer_size |
+ * |-------------------------------------------------------------------|
+ * | packet_type_enable_flags_0 |
+ * |-------------------------------------------------------------------|
+ * | packet_type_enable_flags_1 |
+ * |-------------------------------------------------------------------|
+ * | packet_type_enable_flags_2 |
+ * |-------------------------------------------------------------------|
+ * | packet_type_enable_flags_3 |
+ * |-------------------------------------------------------------------|
+ * | tlv_filter_in_flags |
+ * |-------------------------------------------------------------------|
+ * Where:
+ * PS = pkt_swap
+ * SS = status_swap
+ * The message is interpreted as follows:
+ * dword0 - b'0:7 - msg_type: This will be set to
+ * HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG
+ * b'8:15 - pdev_id:
+ * 0 (for rings at SOC/UMAC level),
+ * 1/2/3 mac id (for rings at LMAC level)
+ * b'16:23 - ring_id : Identify the ring to configure.
+ * More details can be got from enum htt_srng_ring_id
+ * b'24 - status_swap: 1 is to swap status TLV
+ * b'25 - pkt_swap: 1 is to swap packet TLV
+ * b'26 - rx_offset_valid (OV): flag to indicate rx offsets
+ * configuration fields are valid
+ * b'27 - drop_thresh_valid (DT): flag to indicate if the
+ * rx_drop_threshold field is valid
+ * b'28 - rx_mon_global_en: Enable/Disable global register
+ * configuration in Rx monitor module.
+ * b'29:31 - rsvd1: reserved for future use
+ * dword1 - b'0:16 - ring_buffer_size: size of buffers referenced by rx ring,
+ * in byte units.
+ * Valid only for HW_TO_SW_RING and SW_TO_HW_RING
+ * - b'16:31 - rsvd2: Reserved for future use
+ * dword2 - b'0:31 - packet_type_enable_flags_0:
+ * Enable MGMT packet from 0b0000 to 0b1001
+ * bits from low to high: FP, MD, MO - 3 bits
+ * FP: Filter_Pass
+ * MD: Monitor_Direct
+ * MO: Monitor_Other
+ * 10 mgmt subtypes * 3 bits -> 30 bits
+ * Refer to PKT_TYPE_ENABLE_FLAG0_xxx_MGMT_xxx defs
+ * dword3 - b'0:31 - packet_type_enable_flags_1:
+ * Enable MGMT packet from 0b1010 to 0b1111
+ * bits from low to high: FP, MD, MO - 3 bits
+ * Refer to PKT_TYPE_ENABLE_FLAG1_xxx_MGMT_xxx defs
+ * dword4 - b'0:31 - packet_type_enable_flags_2:
+ * Enable CTRL packet from 0b0000 to 0b1001
+ * bits from low to high: FP, MD, MO - 3 bits
+ * Refer to PKT_TYPE_ENABLE_FLAG2_xxx_CTRL_xxx defs
+ * dword5 - b'0:31 - packet_type_enable_flags_3:
+ * Enable CTRL packet from 0b1010 to 0b1111,
+ * MCAST_DATA, UCAST_DATA, NULL_DATA
+ * bits from low to high: FP, MD, MO - 3 bits
+ * Refer to PKT_TYPE_ENABLE_FLAG3_xxx_CTRL_xxx defs
+ * dword6 - b'0:31 - tlv_filter_in_flags:
+ * Filter in Attention/MPDU/PPDU/Header/User tlvs
+ * Refer to CFG_TLV_FILTER_IN_FLAG defs
+ */
+
+#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0)
+#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID GENMASK(15, 8)
+#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_RING_ID GENMASK(23, 16)
+#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_SS BIT(24)
+#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS BIT(25)
+#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_OFFSET_VALID BIT(26)
+#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_DROP_THRES_VAL BIT(27)
+#define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_EN_RXMON BIT(28)
+
+#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE GENMASK(15, 0)
+#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT GENMASK(18, 16)
+#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL GENMASK(21, 19)
+#define HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA GENMASK(24, 22)
+
+#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_DROP_THRESHOLD GENMASK(9, 0)
+#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_MGMT_TYPE BIT(17)
+#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_CTRL_TYPE BIT(18)
+#define HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_DATA_TYPE BIT(19)
+
+#define HTT_RX_RING_SELECTION_CFG_CMD_INFO3_EN_TLV_PKT_OFFSET BIT(0)
+#define HTT_RX_RING_SELECTION_CFG_CMD_INFO3_PKT_TLV_OFFSET GENMASK(14, 1)
+
+#define HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET GENMASK(15, 0)
+#define HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET GENMASK(31, 16)
+#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET GENMASK(15, 0)
+#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET GENMASK(31, 16)
+#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET GENMASK(15, 0)
+#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET GENMASK(31, 16)
+#define HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET GENMASK(15, 0)
+
+#define HTT_RX_RING_SELECTION_CFG_WORD_MASK_COMPACT_SET BIT(23)
+#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_MASK GENMASK(15, 0)
+#define HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_MASK GENMASK(18, 16)
+#define HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_MASK GENMASK(16, 0)
+
+enum htt_rx_filter_tlv_flags {
+ HTT_RX_FILTER_TLV_FLAGS_MPDU_START = BIT(0),
+ HTT_RX_FILTER_TLV_FLAGS_MSDU_START = BIT(1),
+ HTT_RX_FILTER_TLV_FLAGS_RX_PACKET = BIT(2),
+ HTT_RX_FILTER_TLV_FLAGS_MSDU_END = BIT(3),
+ HTT_RX_FILTER_TLV_FLAGS_MPDU_END = BIT(4),
+ HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER = BIT(5),
+ HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER = BIT(6),
+ HTT_RX_FILTER_TLV_FLAGS_ATTENTION = BIT(7),
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_START = BIT(8),
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_END = BIT(9),
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS = BIT(10),
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT = BIT(11),
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE = BIT(12),
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_START_USER_INFO = BIT(13),
+};
+
+enum htt_rx_mgmt_pkt_filter_tlv_flags0 {
+ HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ = BIT(0),
+ HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ = BIT(1),
+ HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ = BIT(2),
+ HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP = BIT(3),
+ HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP = BIT(4),
+ HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP = BIT(5),
+ HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ = BIT(6),
+ HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ = BIT(7),
+ HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ = BIT(8),
+ HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP = BIT(9),
+ HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP = BIT(10),
+ HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP = BIT(11),
+ HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ = BIT(12),
+ HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ = BIT(13),
+ HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ = BIT(14),
+ HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP = BIT(15),
+ HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP = BIT(16),
+ HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP = BIT(17),
+ HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV = BIT(18),
+ HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV = BIT(19),
+ HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV = BIT(20),
+ HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7 = BIT(21),
+ HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7 = BIT(22),
+ HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7 = BIT(23),
+ HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON = BIT(24),
+ HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON = BIT(25),
+ HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON = BIT(26),
+ HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM = BIT(27),
+ HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM = BIT(28),
+ HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM = BIT(29),
+};
+
+enum htt_rx_mgmt_pkt_filter_tlv_flags1 {
+ HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC = BIT(0),
+ HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC = BIT(1),
+ HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC = BIT(2),
+ HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH = BIT(3),
+ HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH = BIT(4),
+ HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH = BIT(5),
+ HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH = BIT(6),
+ HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH = BIT(7),
+ HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH = BIT(8),
+ HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION = BIT(9),
+ HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION = BIT(10),
+ HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION = BIT(11),
+ HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK = BIT(12),
+ HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK = BIT(13),
+ HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK = BIT(14),
+ HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15 = BIT(15),
+ HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15 = BIT(16),
+ HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15 = BIT(17),
+};
+
+enum htt_rx_ctrl_pkt_filter_tlv_flags2 {
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 = BIT(0),
+ HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 = BIT(1),
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 = BIT(2),
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 = BIT(3),
+ HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 = BIT(4),
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 = BIT(5),
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER = BIT(6),
+ HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER = BIT(7),
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER = BIT(8),
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 = BIT(9),
+ HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 = BIT(10),
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 = BIT(11),
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL = BIT(12),
+ HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL = BIT(13),
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL = BIT(14),
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP = BIT(15),
+ HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP = BIT(16),
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP = BIT(17),
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT = BIT(18),
+ HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT = BIT(19),
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT = BIT(20),
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER = BIT(21),
+ HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER = BIT(22),
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER = BIT(23),
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR = BIT(24),
+ HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BAR = BIT(25),
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BAR = BIT(26),
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BA = BIT(27),
+ HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BA = BIT(28),
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BA = BIT(29),
+};
+
+enum htt_rx_ctrl_pkt_filter_tlv_flags3 {
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL = BIT(0),
+ HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL = BIT(1),
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL = BIT(2),
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_RTS = BIT(3),
+ HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_RTS = BIT(4),
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_RTS = BIT(5),
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CTS = BIT(6),
+ HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CTS = BIT(7),
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CTS = BIT(8),
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_ACK = BIT(9),
+ HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_ACK = BIT(10),
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_ACK = BIT(11),
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND = BIT(12),
+ HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND = BIT(13),
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND = BIT(14),
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK = BIT(15),
+ HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK = BIT(16),
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK = BIT(17),
+};
+
+enum htt_rx_data_pkt_filter_tlv_flasg3 {
+ HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST = BIT(18),
+ HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_MCAST = BIT(19),
+ HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_MCAST = BIT(20),
+ HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST = BIT(21),
+ HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_UCAST = BIT(22),
+ HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_UCAST = BIT(23),
+ HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA = BIT(24),
+ HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA = BIT(25),
+ HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA = BIT(26),
+};
+
+#define HTT_RX_FP_MGMT_FILTER_FLAGS0 \
+ (HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ \
+ | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP \
+ | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ \
+ | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP \
+ | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ \
+ | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP \
+ | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV \
+ | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON \
+ | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM)
+
+#define HTT_RX_MD_MGMT_FILTER_FLAGS0 \
+ (HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ \
+ | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP \
+ | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ \
+ | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP \
+ | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ \
+ | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP \
+ | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV \
+ | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON \
+ | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM)
+
+#define HTT_RX_MO_MGMT_FILTER_FLAGS0 \
+ (HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_REQ \
+ | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ASSOC_RESP \
+ | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_REQ \
+ | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_REASSOC_RESP \
+ | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_REQ \
+ | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_RESP \
+ | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_PROBE_TIMING_ADV \
+ | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_BEACON \
+ | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_ATIM)
+
+#define HTT_RX_FP_MGMT_FILTER_FLAGS1 (HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC \
+ | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH \
+ | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH \
+ | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION \
+ | HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK)
+
+#define HTT_RX_MD_MGMT_FILTER_FLAGS1 (HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC \
+ | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH \
+ | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH \
+ | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION \
+ | HTT_RX_MD_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK)
+
+#define HTT_RX_MO_MGMT_FILTER_FLAGS1 (HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DISASSOC \
+ | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_AUTH \
+ | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_DEAUTH \
+ | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION \
+ | HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_ACTION_NOACK)
+
+#define HTT_RX_FP_CTRL_FILTER_FLASG2 (HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER \
+ | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR \
+ | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BA)
+
+#define HTT_RX_MD_CTRL_FILTER_FLASG2 (HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER \
+ | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BAR \
+ | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS2_BA)
+
+#define HTT_RX_MO_CTRL_FILTER_FLASG2 (HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_WRAPPER \
+ | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BAR \
+ | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_BA)
+
+#define HTT_RX_FP_CTRL_FILTER_FLASG3 (HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL \
+ | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_RTS \
+ | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CTS \
+ | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_ACK \
+ | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND \
+ | HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK)
+
+#define HTT_RX_MD_CTRL_FILTER_FLASG3 (HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL \
+ | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_RTS \
+ | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CTS \
+ | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_ACK \
+ | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND \
+ | HTT_RX_MD_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK)
+
+#define HTT_RX_MO_CTRL_FILTER_FLASG3 (HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_PSPOLL \
+ | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_RTS \
+ | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CTS \
+ | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_ACK \
+ | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND \
+ | HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS3_CFEND_ACK)
+
+#define HTT_RX_FP_DATA_FILTER_FLASG3 (HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST \
+ | HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST \
+ | HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA)
+
+#define HTT_RX_MD_DATA_FILTER_FLASG3 (HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_MCAST \
+ | HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_UCAST \
+ | HTT_RX_MD_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA)
+
+#define HTT_RX_MO_DATA_FILTER_FLASG3 (HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_MCAST \
+ | HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_UCAST \
+ | HTT_RX_MO_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA)
+
+#define HTT_RX_MON_FP_MGMT_FILTER_FLAGS0 \
+ (HTT_RX_FP_MGMT_FILTER_FLAGS0 | \
+ HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7)
+
+#define HTT_RX_MON_MO_MGMT_FILTER_FLAGS0 \
+ (HTT_RX_MO_MGMT_FILTER_FLAGS0 | \
+ HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS0_RESERVED_7)
+
+#define HTT_RX_MON_FP_MGMT_FILTER_FLAGS1 \
+ (HTT_RX_FP_MGMT_FILTER_FLAGS1 | \
+ HTT_RX_FP_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15)
+
+#define HTT_RX_MON_MO_MGMT_FILTER_FLAGS1 \
+ (HTT_RX_MO_MGMT_FILTER_FLAGS1 | \
+ HTT_RX_MO_MGMT_PKT_FILTER_TLV_FLAGS1_RESERVED_15)
+
+#define HTT_RX_MON_FP_CTRL_FILTER_FLASG2 \
+ (HTT_RX_FP_CTRL_FILTER_FLASG2 | \
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 | \
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 | \
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER | \
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 | \
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL | \
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP | \
+ HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT)
+
+#define HTT_RX_MON_MO_CTRL_FILTER_FLASG2 \
+ (HTT_RX_MO_CTRL_FILTER_FLASG2 | \
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_1 | \
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_2 | \
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_TRIGGER | \
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_RESERVED_4 | \
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_BF_REP_POLL | \
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_VHT_NDP | \
+ HTT_RX_MO_CTRL_PKT_FILTER_TLV_FLAGS2_CTRL_FRAME_EXT)
+
+#define HTT_RX_MON_FP_CTRL_FILTER_FLASG3 HTT_RX_FP_CTRL_FILTER_FLASG3
+
+#define HTT_RX_MON_MO_CTRL_FILTER_FLASG3 HTT_RX_MO_CTRL_FILTER_FLASG3
+
+#define HTT_RX_MON_FP_DATA_FILTER_FLASG3 HTT_RX_FP_DATA_FILTER_FLASG3
+
+#define HTT_RX_MON_MO_DATA_FILTER_FLASG3 HTT_RX_MO_DATA_FILTER_FLASG3
+
+#define HTT_RX_MON_FILTER_TLV_FLAGS \
+ (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE)
+
+#define HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING \
+ (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE)
+
+#define HTT_RX_MON_FILTER_TLV_FLAGS_MON_BUF_RING \
+ (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \
+ HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \
+ HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \
+ HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \
+ HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \
+ HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER | \
+ HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \
+ HTT_RX_FILTER_TLV_FLAGS_ATTENTION)
+
+#define HTT_RX_MON_FILTER_TLV_FLAGS_MON_DEST_RING \
+ (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \
+ HTT_RX_FILTER_TLV_FLAGS_MSDU_START | \
+ HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \
+ HTT_RX_FILTER_TLV_FLAGS_MSDU_END | \
+ HTT_RX_FILTER_TLV_FLAGS_MPDU_END | \
+ HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER | \
+ HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \
+ HTT_RX_FILTER_TLV_FLAGS_PPDU_START_USER_INFO)
+
+/* msdu start. mpdu end, attention, rx hdr tlv's are not subscribed */
+#define HTT_RX_TLV_FLAGS_RXDMA_RING \
+ (HTT_RX_FILTER_TLV_FLAGS_MPDU_START | \
+ HTT_RX_FILTER_TLV_FLAGS_RX_PACKET | \
+ HTT_RX_FILTER_TLV_FLAGS_MSDU_END)
+
+#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0)
+#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID GENMASK(15, 8)
+
+struct htt_rx_ring_selection_cfg_cmd {
+ __le32 info0;
+ __le32 info1;
+ __le32 pkt_type_en_flags0;
+ __le32 pkt_type_en_flags1;
+ __le32 pkt_type_en_flags2;
+ __le32 pkt_type_en_flags3;
+ __le32 rx_filter_tlv;
+ __le32 rx_packet_offset;
+ __le32 rx_mpdu_offset;
+ __le32 rx_msdu_offset;
+ __le32 rx_attn_offset;
+ __le32 info2;
+ __le32 reserved[2];
+ __le32 rx_mpdu_start_end_mask;
+ __le32 rx_msdu_end_word_mask;
+ __le32 info3;
+} __packed;
+
+#define HTT_RX_RING_TLV_DROP_THRESHOLD_VALUE 32
+#define HTT_RX_RING_DEFAULT_DMA_LENGTH 0x7
+#define HTT_RX_RING_PKT_TLV_OFFSET 0x1
+
+struct htt_rx_ring_tlv_filter {
+ u32 rx_filter; /* see htt_rx_filter_tlv_flags */
+ u32 pkt_filter_flags0; /* MGMT */
+ u32 pkt_filter_flags1; /* MGMT */
+ u32 pkt_filter_flags2; /* CTRL */
+ u32 pkt_filter_flags3; /* DATA */
+ bool offset_valid;
+ u16 rx_packet_offset;
+ u16 rx_header_offset;
+ u16 rx_mpdu_end_offset;
+ u16 rx_mpdu_start_offset;
+ u16 rx_msdu_end_offset;
+ u16 rx_msdu_start_offset;
+ u16 rx_attn_offset;
+ u16 rx_mpdu_start_wmask;
+ u16 rx_mpdu_end_wmask;
+ u32 rx_msdu_end_wmask;
+ u32 conf_len_ctrl;
+ u32 conf_len_mgmt;
+ u32 conf_len_data;
+ u16 rx_drop_threshold;
+ bool enable_log_mgmt_type;
+ bool enable_log_ctrl_type;
+ bool enable_log_data_type;
+ bool enable_rx_tlv_offset;
+ u16 rx_tlv_offset;
+ bool drop_threshold_valid;
+ bool rxmon_disable;
+};
+
+#define HTT_STATS_FRAME_CTRL_TYPE_MGMT 0x0
+#define HTT_STATS_FRAME_CTRL_TYPE_CTRL 0x1
+#define HTT_STATS_FRAME_CTRL_TYPE_DATA 0x2
+#define HTT_STATS_FRAME_CTRL_TYPE_RESV 0x3
+
+#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0)
+#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID GENMASK(15, 8)
+#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_RING_ID GENMASK(23, 16)
+#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_SS BIT(24)
+#define HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PS BIT(25)
+
+#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_RING_BUFF_SIZE GENMASK(15, 0)
+#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE GENMASK(18, 16)
+#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT GENMASK(21, 19)
+#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL GENMASK(24, 22)
+#define HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA GENMASK(27, 25)
+
+#define HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG GENMASK(2, 0)
+
+struct htt_tx_ring_selection_cfg_cmd {
+ __le32 info0;
+ __le32 info1;
+ __le32 info2;
+ __le32 tlv_filter_mask_in0;
+ __le32 tlv_filter_mask_in1;
+ __le32 tlv_filter_mask_in2;
+ __le32 tlv_filter_mask_in3;
+ __le32 reserved[3];
+} __packed;
+
+#define HTT_TX_RING_TLV_FILTER_MGMT_DMA_LEN GENMASK(3, 0)
+#define HTT_TX_RING_TLV_FILTER_CTRL_DMA_LEN GENMASK(7, 4)
+#define HTT_TX_RING_TLV_FILTER_DATA_DMA_LEN GENMASK(11, 8)
+
+#define HTT_TX_MON_FILTER_HYBRID_MODE \
+ (HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_START_STATUS | \
+ HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_END_STATUS | \
+ HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START | \
+ HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_END | \
+ HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PPDU | \
+ HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_PPDU | \
+ HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_ACK_OR_BA | \
+ HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_1K_BA | \
+ HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PROT | \
+ HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_PROT | \
+ HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_RESPONSE | \
+ HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO | \
+ HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO_PART2)
+
+struct htt_tx_ring_tlv_filter {
+ u32 tx_mon_downstream_tlv_flags;
+ u32 tx_mon_upstream_tlv_flags0;
+ u32 tx_mon_upstream_tlv_flags1;
+ u32 tx_mon_upstream_tlv_flags2;
+ bool tx_mon_mgmt_filter;
+ bool tx_mon_data_filter;
+ bool tx_mon_ctrl_filter;
+ u16 tx_mon_pkt_dma_len;
+} __packed;
+
+enum htt_tx_mon_upstream_tlv_flags0 {
+ HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_START_STATUS = BIT(1),
+ HTT_TX_FILTER_TLV_FLAGS0_RESPONSE_END_STATUS = BIT(2),
+ HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START = BIT(3),
+ HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_END = BIT(4),
+ HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PPDU = BIT(5),
+ HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_PPDU = BIT(6),
+ HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_ACK_OR_BA = BIT(7),
+ HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_1K_BA = BIT(8),
+ HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_START_PROT = BIT(9),
+ HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_PROT = BIT(10),
+ HTT_TX_FILTER_TLV_FLAGS0_TX_FES_STATUS_USER_RESPONSE = BIT(11),
+ HTT_TX_FILTER_TLV_FLAGS0_RX_FRAME_BITMAP_ACK = BIT(12),
+ HTT_TX_FILTER_TLV_FLAGS0_RX_FRAME_1K_BITMAP_ACK = BIT(13),
+ HTT_TX_FILTER_TLV_FLAGS0_COEX_TX_STATUS = BIT(14),
+ HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO = BIT(15),
+ HTT_TX_FILTER_TLV_FLAGS0_RECEIVED_RESPONSE_INFO_PART2 = BIT(16),
+};
+
+#define HTT_TX_FILTER_TLV_FLAGS2_TXPCU_PHYTX_OTHER_TRANSMIT_INFO32 BIT(11)
+
+/* HTT message target->host */
+
+enum htt_t2h_msg_type {
+ HTT_T2H_MSG_TYPE_VERSION_CONF,
+ HTT_T2H_MSG_TYPE_PEER_MAP = 0x3,
+ HTT_T2H_MSG_TYPE_PEER_UNMAP = 0x4,
+ HTT_T2H_MSG_TYPE_RX_ADDBA = 0x5,
+ HTT_T2H_MSG_TYPE_PKTLOG = 0x8,
+ HTT_T2H_MSG_TYPE_SEC_IND = 0xb,
+ HTT_T2H_MSG_TYPE_PEER_MAP2 = 0x1e,
+ HTT_T2H_MSG_TYPE_PEER_UNMAP2 = 0x1f,
+ HTT_T2H_MSG_TYPE_PPDU_STATS_IND = 0x1d,
+ HTT_T2H_MSG_TYPE_EXT_STATS_CONF = 0x1c,
+ HTT_T2H_MSG_TYPE_BKPRESSURE_EVENT_IND = 0x24,
+ HTT_T2H_MSG_TYPE_MLO_TIMESTAMP_OFFSET_IND = 0x28,
+ HTT_T2H_MSG_TYPE_PEER_MAP3 = 0x2b,
+ HTT_T2H_MSG_TYPE_VDEV_TXRX_STATS_PERIODIC_IND = 0x2c,
+};
+
+#define HTT_TARGET_VERSION_MAJOR 3
+
+#define HTT_T2H_MSG_TYPE GENMASK(7, 0)
+#define HTT_T2H_VERSION_CONF_MINOR GENMASK(15, 8)
+#define HTT_T2H_VERSION_CONF_MAJOR GENMASK(23, 16)
+
+struct htt_t2h_version_conf_msg {
+ __le32 version;
+} __packed;
+
+#define HTT_T2H_PEER_MAP_INFO_VDEV_ID GENMASK(15, 8)
+#define HTT_T2H_PEER_MAP_INFO_PEER_ID GENMASK(31, 16)
+#define HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16 GENMASK(15, 0)
+#define HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID GENMASK(31, 16)
+#define HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL GENMASK(15, 0)
+#define HTT_T2H_PEER_MAP3_INFO2_HW_PEER_ID GENMASK(15, 0)
+#define HTT_T2H_PEER_MAP3_INFO2_AST_HASH_VAL GENMASK(31, 16)
+#define HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M BIT(16)
+#define HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_S 16
+
+struct htt_t2h_peer_map_event {
+ __le32 info;
+ __le32 mac_addr_l32;
+ __le32 info1;
+ __le32 info2;
+} __packed;
+
+#define HTT_T2H_PEER_UNMAP_INFO_VDEV_ID HTT_T2H_PEER_MAP_INFO_VDEV_ID
+#define HTT_T2H_PEER_UNMAP_INFO_PEER_ID HTT_T2H_PEER_MAP_INFO_PEER_ID
+#define HTT_T2H_PEER_UNMAP_INFO1_MAC_ADDR_H16 \
+ HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16
+#define HTT_T2H_PEER_MAP_INFO1_NEXT_HOP_M HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M
+#define HTT_T2H_PEER_MAP_INFO1_NEXT_HOP_S HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_S
+
+struct htt_t2h_peer_unmap_event {
+ __le32 info;
+ __le32 mac_addr_l32;
+ __le32 info1;
+} __packed;
+
+struct htt_resp_msg {
+ union {
+ struct htt_t2h_version_conf_msg version_msg;
+ struct htt_t2h_peer_map_event peer_map_ev;
+ struct htt_t2h_peer_unmap_event peer_unmap_ev;
+ };
+} __packed;
+
+#define HTT_VDEV_GET_STATS_U64(msg_l32, msg_u32)\
+ (((u64)__le32_to_cpu(msg_u32) << 32) | (__le32_to_cpu(msg_l32)))
+#define HTT_T2H_VDEV_STATS_PERIODIC_MSG_TYPE GENMASK(7, 0)
+#define HTT_T2H_VDEV_STATS_PERIODIC_PDEV_ID GENMASK(15, 8)
+#define HTT_T2H_VDEV_STATS_PERIODIC_NUM_VDEV GENMASK(23, 16)
+#define HTT_T2H_VDEV_STATS_PERIODIC_PAYLOAD_BYTES GENMASK(15, 0)
+#define HTT_VDEV_TXRX_STATS_COMMON_TLV 0
+#define HTT_VDEV_TXRX_STATS_HW_STATS_TLV 1
+
+struct htt_t2h_vdev_txrx_stats_ind {
+ __le32 vdev_id;
+ __le32 rx_msdu_byte_cnt_lo;
+ __le32 rx_msdu_byte_cnt_hi;
+ __le32 rx_msdu_cnt_lo;
+ __le32 rx_msdu_cnt_hi;
+ __le32 tx_msdu_byte_cnt_lo;
+ __le32 tx_msdu_byte_cnt_hi;
+ __le32 tx_msdu_cnt_lo;
+ __le32 tx_msdu_cnt_hi;
+ __le32 tx_retry_cnt_lo;
+ __le32 tx_retry_cnt_hi;
+ __le32 tx_retry_byte_cnt_lo;
+ __le32 tx_retry_byte_cnt_hi;
+ __le32 tx_drop_cnt_lo;
+ __le32 tx_drop_cnt_hi;
+ __le32 tx_drop_byte_cnt_lo;
+ __le32 tx_drop_byte_cnt_hi;
+ __le32 msdu_ttl_cnt_lo;
+ __le32 msdu_ttl_cnt_hi;
+ __le32 msdu_ttl_byte_cnt_lo;
+ __le32 msdu_ttl_byte_cnt_hi;
+} __packed;
+
+struct htt_t2h_vdev_common_stats_tlv {
+ __le32 soc_drop_count_lo;
+ __le32 soc_drop_count_hi;
+} __packed;
+
+/* ppdu stats
+ *
+ * @details
+ * The following field definitions describe the format of the HTT target
+ * to host ppdu stats indication message.
+ *
+ *
+ * |31 16|15 12|11 10|9 8|7 0 |
+ * |----------------------------------------------------------------------|
+ * | payload_size | rsvd |pdev_id|mac_id | msg type |
+ * |----------------------------------------------------------------------|
+ * | ppdu_id |
+ * |----------------------------------------------------------------------|
+ * | Timestamp in us |
+ * |----------------------------------------------------------------------|
+ * | reserved |
+ * |----------------------------------------------------------------------|
+ * | type-specific stats info |
+ * | (see htt_ppdu_stats.h) |
+ * |----------------------------------------------------------------------|
+ * Header fields:
+ * - MSG_TYPE
+ * Bits 7:0
+ * Purpose: Identifies this is a PPDU STATS indication
+ * message.
+ * Value: 0x1d
+ * - mac_id
+ * Bits 9:8
+ * Purpose: mac_id of this ppdu_id
+ * Value: 0-3
+ * - pdev_id
+ * Bits 11:10
+ * Purpose: pdev_id of this ppdu_id
+ * Value: 0-3
+ * 0 (for rings at SOC level),
+ * 1/2/3 PDEV -> 0/1/2
+ * - payload_size
+ * Bits 31:16
+ * Purpose: total tlv size
+ * Value: payload_size in bytes
+ */
+
+#define HTT_T2H_PPDU_STATS_INFO_PDEV_ID GENMASK(11, 10)
+#define HTT_T2H_PPDU_STATS_INFO_PAYLOAD_SIZE GENMASK(31, 16)
+
+struct ath12k_htt_ppdu_stats_msg {
+ __le32 info;
+ __le32 ppdu_id;
+ __le32 timestamp;
+ __le32 rsvd;
+ u8 data[];
+} __packed;
+
+struct htt_tlv {
+ __le32 header;
+ u8 value[];
+} __packed;
+
+#define HTT_TLV_TAG GENMASK(11, 0)
+#define HTT_TLV_LEN GENMASK(23, 12)
+
+enum HTT_PPDU_STATS_BW {
+ HTT_PPDU_STATS_BANDWIDTH_5MHZ = 0,
+ HTT_PPDU_STATS_BANDWIDTH_10MHZ = 1,
+ HTT_PPDU_STATS_BANDWIDTH_20MHZ = 2,
+ HTT_PPDU_STATS_BANDWIDTH_40MHZ = 3,
+ HTT_PPDU_STATS_BANDWIDTH_80MHZ = 4,
+ HTT_PPDU_STATS_BANDWIDTH_160MHZ = 5, /* includes 80+80 */
+ HTT_PPDU_STATS_BANDWIDTH_DYN = 6,
+};
+
+#define HTT_PPDU_STATS_CMN_FLAGS_FRAME_TYPE_M GENMASK(7, 0)
+#define HTT_PPDU_STATS_CMN_FLAGS_QUEUE_TYPE_M GENMASK(15, 8)
+/* bw - HTT_PPDU_STATS_BW */
+#define HTT_PPDU_STATS_CMN_FLAGS_BW_M GENMASK(19, 16)
+
+struct htt_ppdu_stats_common {
+ __le32 ppdu_id;
+ __le16 sched_cmdid;
+ u8 ring_id;
+ u8 num_users;
+ __le32 flags; /* %HTT_PPDU_STATS_COMMON_FLAGS_*/
+ __le32 chain_mask;
+ __le32 fes_duration_us; /* frame exchange sequence */
+ __le32 ppdu_sch_eval_start_tstmp_us;
+ __le32 ppdu_sch_end_tstmp_us;
+ __le32 ppdu_start_tstmp_us;
+ /* BIT [15 : 0] - phy mode (WLAN_PHY_MODE) with which ppdu was transmitted
+ * BIT [31 : 16] - bandwidth (in MHz) with which ppdu was transmitted
+ */
+ __le16 phy_mode;
+ __le16 bw_mhz;
+} __packed;
+
+enum htt_ppdu_stats_gi {
+ HTT_PPDU_STATS_SGI_0_8_US,
+ HTT_PPDU_STATS_SGI_0_4_US,
+ HTT_PPDU_STATS_SGI_1_6_US,
+ HTT_PPDU_STATS_SGI_3_2_US,
+};
+
+#define HTT_PPDU_STATS_USER_RATE_INFO0_USER_POS_M GENMASK(3, 0)
+#define HTT_PPDU_STATS_USER_RATE_INFO0_MU_GROUP_ID_M GENMASK(11, 4)
+
+enum HTT_PPDU_STATS_PPDU_TYPE {
+ HTT_PPDU_STATS_PPDU_TYPE_SU,
+ HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO,
+ HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA,
+ HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA,
+ HTT_PPDU_STATS_PPDU_TYPE_UL_TRIG,
+ HTT_PPDU_STATS_PPDU_TYPE_BURST_BCN,
+ HTT_PPDU_STATS_PPDU_TYPE_UL_BSR_RESP,
+ HTT_PPDU_STATS_PPDU_TYPE_UL_BSR_TRIG,
+ HTT_PPDU_STATS_PPDU_TYPE_UL_RESP,
+ HTT_PPDU_STATS_PPDU_TYPE_MAX
+};
+
+#define HTT_PPDU_STATS_USER_RATE_INFO1_RESP_TYPE_VALD_M BIT(0)
+#define HTT_PPDU_STATS_USER_RATE_INFO1_PPDU_TYPE_M GENMASK(5, 1)
+
+#define HTT_PPDU_STATS_USER_RATE_FLAGS_LTF_SIZE_M GENMASK(1, 0)
+#define HTT_PPDU_STATS_USER_RATE_FLAGS_STBC_M BIT(2)
+#define HTT_PPDU_STATS_USER_RATE_FLAGS_HE_RE_M BIT(3)
+#define HTT_PPDU_STATS_USER_RATE_FLAGS_TXBF_M GENMASK(7, 4)
+#define HTT_PPDU_STATS_USER_RATE_FLAGS_BW_M GENMASK(11, 8)
+#define HTT_PPDU_STATS_USER_RATE_FLAGS_NSS_M GENMASK(15, 12)
+#define HTT_PPDU_STATS_USER_RATE_FLAGS_MCS_M GENMASK(19, 16)
+#define HTT_PPDU_STATS_USER_RATE_FLAGS_PREAMBLE_M GENMASK(23, 20)
+#define HTT_PPDU_STATS_USER_RATE_FLAGS_GI_M GENMASK(27, 24)
+#define HTT_PPDU_STATS_USER_RATE_FLAGS_DCM_M BIT(28)
+#define HTT_PPDU_STATS_USER_RATE_FLAGS_LDPC_M BIT(29)
+
+#define HTT_USR_RATE_PPDU_TYPE(_val) \
+ le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_INFO1_PPDU_TYPE_M)
+#define HTT_USR_RATE_PREAMBLE(_val) \
+ le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_PREAMBLE_M)
+#define HTT_USR_RATE_BW(_val) \
+ le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_BW_M)
+#define HTT_USR_RATE_NSS(_val) \
+ le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_NSS_M)
+#define HTT_USR_RATE_MCS(_val) \
+ le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_MCS_M)
+#define HTT_USR_RATE_GI(_val) \
+ le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_GI_M)
+#define HTT_USR_RATE_DCM(_val) \
+ le32_get_bits(_val, HTT_PPDU_STATS_USER_RATE_FLAGS_DCM_M)
+
+#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_LTF_SIZE_M GENMASK(1, 0)
+#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_STBC_M BIT(2)
+#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_HE_RE_M BIT(3)
+#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_TXBF_M GENMASK(7, 4)
+#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_BW_M GENMASK(11, 8)
+#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_NSS_M GENMASK(15, 12)
+#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_MCS_M GENMASK(19, 16)
+#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_PREAMBLE_M GENMASK(23, 20)
+#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_GI_M GENMASK(27, 24)
+#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_DCM_M BIT(28)
+#define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_LDPC_M BIT(29)
+
+struct htt_ppdu_stats_user_rate {
+ u8 tid_num;
+ u8 reserved0;
+ __le16 sw_peer_id;
+ __le32 info0; /* %HTT_PPDU_STATS_USER_RATE_INFO0_*/
+ __le16 ru_end;
+ __le16 ru_start;
+ __le16 resp_ru_end;
+ __le16 resp_ru_start;
+ __le32 info1; /* %HTT_PPDU_STATS_USER_RATE_INFO1_ */
+ __le32 rate_flags; /* %HTT_PPDU_STATS_USER_RATE_FLAGS_ */
+ /* Note: resp_rate_info is only valid for if resp_type is UL */
+ __le32 resp_rate_flags; /* %HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_ */
+} __packed;
+
+#define HTT_PPDU_STATS_TX_INFO_FLAGS_RATECODE_M GENMASK(7, 0)
+#define HTT_PPDU_STATS_TX_INFO_FLAGS_IS_AMPDU_M BIT(8)
+#define HTT_PPDU_STATS_TX_INFO_FLAGS_BA_ACK_FAILED_M GENMASK(10, 9)
+#define HTT_PPDU_STATS_TX_INFO_FLAGS_BW_M GENMASK(13, 11)
+#define HTT_PPDU_STATS_TX_INFO_FLAGS_SGI_M BIT(14)
+#define HTT_PPDU_STATS_TX_INFO_FLAGS_PEERID_M GENMASK(31, 16)
+
+#define HTT_TX_INFO_IS_AMSDU(_flags) \
+ u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_IS_AMPDU_M)
+#define HTT_TX_INFO_BA_ACK_FAILED(_flags) \
+ u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_BA_ACK_FAILED_M)
+#define HTT_TX_INFO_RATECODE(_flags) \
+ u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_RATECODE_M)
+#define HTT_TX_INFO_PEERID(_flags) \
+ u32_get_bits(_flags, HTT_PPDU_STATS_TX_INFO_FLAGS_PEERID_M)
+
+enum htt_ppdu_stats_usr_compln_status {
+ HTT_PPDU_STATS_USER_STATUS_OK,
+ HTT_PPDU_STATS_USER_STATUS_FILTERED,
+ HTT_PPDU_STATS_USER_STATUS_RESP_TIMEOUT,
+ HTT_PPDU_STATS_USER_STATUS_RESP_MISMATCH,
+ HTT_PPDU_STATS_USER_STATUS_ABORT,
+};
+
+#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_LONG_RETRY_M GENMASK(3, 0)
+#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_SHORT_RETRY_M GENMASK(7, 4)
+#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_IS_AMPDU_M BIT(8)
+#define HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_RESP_TYPE_M GENMASK(12, 9)
+
+#define HTT_USR_CMPLTN_IS_AMPDU(_val) \
+ le32_get_bits(_val, HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_IS_AMPDU_M)
+#define HTT_USR_CMPLTN_LONG_RETRY(_val) \
+ le32_get_bits(_val, HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_LONG_RETRY_M)
+#define HTT_USR_CMPLTN_SHORT_RETRY(_val) \
+ le32_get_bits(_val, HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_SHORT_RETRY_M)
+
+struct htt_ppdu_stats_usr_cmpltn_cmn {
+ u8 status;
+ u8 tid_num;
+ __le16 sw_peer_id;
+ /* RSSI value of last ack packet (units = dB above noise floor) */
+ __le32 ack_rssi;
+ __le16 mpdu_tried;
+ __le16 mpdu_success;
+ __le32 flags; /* %HTT_PPDU_STATS_USR_CMPLTN_CMN_FLAGS_LONG_RETRIES*/
+} __packed;
+
+#define HTT_PPDU_STATS_ACK_BA_INFO_NUM_MPDU_M GENMASK(8, 0)
+#define HTT_PPDU_STATS_ACK_BA_INFO_NUM_MSDU_M GENMASK(24, 9)
+#define HTT_PPDU_STATS_ACK_BA_INFO_TID_NUM GENMASK(31, 25)
+
+#define HTT_PPDU_STATS_NON_QOS_TID 16
+
+struct htt_ppdu_stats_usr_cmpltn_ack_ba_status {
+ __le32 ppdu_id;
+ __le16 sw_peer_id;
+ __le16 reserved0;
+ __le32 info; /* %HTT_PPDU_STATS_USR_CMPLTN_CMN_INFO_ */
+ __le16 current_seq;
+ __le16 start_seq;
+ __le32 success_bytes;
+} __packed;
+
+struct htt_ppdu_user_stats {
+ u16 peer_id;
+ u16 delay_ba;
+ u32 tlv_flags;
+ bool is_valid_peer_id;
+ struct htt_ppdu_stats_user_rate rate;
+ struct htt_ppdu_stats_usr_cmpltn_cmn cmpltn_cmn;
+ struct htt_ppdu_stats_usr_cmpltn_ack_ba_status ack_ba;
+};
+
+#define HTT_PPDU_STATS_MAX_USERS 8
+#define HTT_PPDU_DESC_MAX_DEPTH 16
+
+struct htt_ppdu_stats {
+ struct htt_ppdu_stats_common common;
+ struct htt_ppdu_user_stats user_stats[HTT_PPDU_STATS_MAX_USERS];
+};
+
+struct htt_ppdu_stats_info {
+ u32 tlv_bitmap;
+ u32 ppdu_id;
+ u32 frame_type;
+ u32 frame_ctrl;
+ u32 delay_ba;
+ u32 bar_num_users;
+ struct htt_ppdu_stats ppdu_stats;
+ struct list_head list;
+};
+
+/* @brief target -> host MLO offset indiciation message
+ *
+ * @details
+ * The following field definitions describe the format of the HTT target
+ * to host mlo offset indication message.
+ *
+ *
+ * |31 29|28 |26|25 22|21 16|15 13|12 10 |9 8|7 0|
+ * |---------------------------------------------------------------------|
+ * | rsvd1 | mac_freq |chip_id |pdev_id|msgtype|
+ * |---------------------------------------------------------------------|
+ * | sync_timestamp_lo_us |
+ * |---------------------------------------------------------------------|
+ * | sync_timestamp_hi_us |
+ * |---------------------------------------------------------------------|
+ * | mlo_offset_lo |
+ * |---------------------------------------------------------------------|
+ * | mlo_offset_hi |
+ * |---------------------------------------------------------------------|
+ * | mlo_offset_clcks |
+ * |---------------------------------------------------------------------|
+ * | rsvd2 | mlo_comp_clks |mlo_comp_us |
+ * |---------------------------------------------------------------------|
+ * | rsvd3 |mlo_comp_timer |
+ * |---------------------------------------------------------------------|
+ * Header fields
+ * - MSG_TYPE
+ * Bits 7:0
+ * Purpose: Identifies this is a MLO offset indication msg
+ * - PDEV_ID
+ * Bits 9:8
+ * Purpose: Pdev of this MLO offset
+ * - CHIP_ID
+ * Bits 12:10
+ * Purpose: chip_id of this MLO offset
+ * - MAC_FREQ
+ * Bits 28:13
+ * - SYNC_TIMESTAMP_LO_US
+ * Purpose: clock frequency of the mac HW block in MHz
+ * Bits: 31:0
+ * Purpose: lower 32 bits of the WLAN global time stamp at which
+ * last sync interrupt was received
+ * - SYNC_TIMESTAMP_HI_US
+ * Bits: 31:0
+ * Purpose: upper 32 bits of WLAN global time stamp at which
+ * last sync interrupt was received
+ * - MLO_OFFSET_LO
+ * Bits: 31:0
+ * Purpose: lower 32 bits of the MLO offset in us
+ * - MLO_OFFSET_HI
+ * Bits: 31:0
+ * Purpose: upper 32 bits of the MLO offset in us
+ * - MLO_COMP_US
+ * Bits: 15:0
+ * Purpose: MLO time stamp compensation applied in us
+ * - MLO_COMP_CLCKS
+ * Bits: 25:16
+ * Purpose: MLO time stamp compensation applied in clock ticks
+ * - MLO_COMP_TIMER
+ * Bits: 21:0
+ * Purpose: Periodic timer at which compensation is applied
+ */
+
+#define HTT_T2H_MLO_OFFSET_INFO_MSG_TYPE GENMASK(7, 0)
+#define HTT_T2H_MLO_OFFSET_INFO_PDEV_ID GENMASK(9, 8)
+
+struct ath12k_htt_mlo_offset_msg {
+ __le32 info;
+ __le32 sync_timestamp_lo_us;
+ __le32 sync_timestamp_hi_us;
+ __le32 mlo_offset_hi;
+ __le32 mlo_offset_lo;
+ __le32 mlo_offset_clks;
+ __le32 mlo_comp_clks;
+ __le32 mlo_comp_timer;
+} __packed;
+
+/* @brief host -> target FW extended statistics retrieve
+ *
+ * @details
+ * The following field definitions describe the format of the HTT host
+ * to target FW extended stats retrieve message.
+ * The message specifies the type of stats the host wants to retrieve.
+ *
+ * |31 24|23 16|15 8|7 0|
+ * |-----------------------------------------------------------|
+ * | reserved | stats type | pdev_mask | msg type |
+ * |-----------------------------------------------------------|
+ * | config param [0] |
+ * |-----------------------------------------------------------|
+ * | config param [1] |
+ * |-----------------------------------------------------------|
+ * | config param [2] |
+ * |-----------------------------------------------------------|
+ * | config param [3] |
+ * |-----------------------------------------------------------|
+ * | reserved |
+ * |-----------------------------------------------------------|
+ * | cookie LSBs |
+ * |-----------------------------------------------------------|
+ * | cookie MSBs |
+ * |-----------------------------------------------------------|
+ * Header fields:
+ * - MSG_TYPE
+ * Bits 7:0
+ * Purpose: identifies this is a extended stats upload request message
+ * Value: 0x10
+ * - PDEV_MASK
+ * Bits 8:15
+ * Purpose: identifies the mask of PDEVs to retrieve stats from
+ * Value: This is a overloaded field, refer to usage and interpretation of
+ * PDEV in interface document.
+ * Bit 8 : Reserved for SOC stats
+ * Bit 9 - 15 : Indicates PDEV_MASK in DBDC
+ * Indicates MACID_MASK in DBS
+ * - STATS_TYPE
+ * Bits 23:16
+ * Purpose: identifies which FW statistics to upload
+ * Value: Defined by htt_dbg_ext_stats_type (see htt_stats.h)
+ * - Reserved
+ * Bits 31:24
+ * - CONFIG_PARAM [0]
+ * Bits 31:0
+ * Purpose: give an opaque configuration value to the specified stats type
+ * Value: stats-type specific configuration value
+ * Refer to htt_stats.h for interpretation for each stats sub_type
+ * - CONFIG_PARAM [1]
+ * Bits 31:0
+ * Purpose: give an opaque configuration value to the specified stats type
+ * Value: stats-type specific configuration value
+ * Refer to htt_stats.h for interpretation for each stats sub_type
+ * - CONFIG_PARAM [2]
+ * Bits 31:0
+ * Purpose: give an opaque configuration value to the specified stats type
+ * Value: stats-type specific configuration value
+ * Refer to htt_stats.h for interpretation for each stats sub_type
+ * - CONFIG_PARAM [3]
+ * Bits 31:0
+ * Purpose: give an opaque configuration value to the specified stats type
+ * Value: stats-type specific configuration value
+ * Refer to htt_stats.h for interpretation for each stats sub_type
+ * - Reserved [31:0] for future use.
+ * - COOKIE_LSBS
+ * Bits 31:0
+ * Purpose: Provide a mechanism to match a target->host stats confirmation
+ * message with its preceding host->target stats request message.
+ * Value: LSBs of the opaque cookie specified by the host-side requestor
+ * - COOKIE_MSBS
+ * Bits 31:0
+ * Purpose: Provide a mechanism to match a target->host stats confirmation
+ * message with its preceding host->target stats request message.
+ * Value: MSBs of the opaque cookie specified by the host-side requestor
+ */
+
+struct htt_ext_stats_cfg_hdr {
+ u8 msg_type;
+ u8 pdev_mask;
+ u8 stats_type;
+ u8 reserved;
+} __packed;
+
+struct htt_ext_stats_cfg_cmd {
+ struct htt_ext_stats_cfg_hdr hdr;
+ __le32 cfg_param0;
+ __le32 cfg_param1;
+ __le32 cfg_param2;
+ __le32 cfg_param3;
+ __le32 reserved;
+ __le32 cookie_lsb;
+ __le32 cookie_msb;
+} __packed;
+
+/* htt stats config default params */
+#define HTT_STAT_DEFAULT_RESET_START_OFFSET 0
+#define HTT_STAT_DEFAULT_CFG0_ALL_HWQS 0xffffffff
+#define HTT_STAT_DEFAULT_CFG0_ALL_TXQS 0xffffffff
+#define HTT_STAT_DEFAULT_CFG0_ALL_CMDQS 0xffff
+#define HTT_STAT_DEFAULT_CFG0_ALL_RINGS 0xffff
+#define HTT_STAT_DEFAULT_CFG0_ACTIVE_PEERS 0xff
+#define HTT_STAT_DEFAULT_CFG0_CCA_CUMULATIVE 0x00
+#define HTT_STAT_DEFAULT_CFG0_ACTIVE_VDEVS 0x00
+
+/* HTT_DBG_EXT_STATS_PEER_INFO
+ * PARAMS:
+ * @config_param0:
+ * [Bit0] - [0] for sw_peer_id, [1] for mac_addr based request
+ * [Bit15 : Bit 1] htt_peer_stats_req_mode_t
+ * [Bit31 : Bit16] sw_peer_id
+ * @config_param1:
+ * peer_stats_req_type_mask:32 (enum htt_peer_stats_tlv_enum)
+ * 0 bit htt_peer_stats_cmn_tlv
+ * 1 bit htt_peer_details_tlv
+ * 2 bit htt_tx_peer_rate_stats_tlv
+ * 3 bit htt_rx_peer_rate_stats_tlv
+ * 4 bit htt_tx_tid_stats_tlv/htt_tx_tid_stats_v1_tlv
+ * 5 bit htt_rx_tid_stats_tlv
+ * 6 bit htt_msdu_flow_stats_tlv
+ * @config_param2: [Bit31 : Bit0] mac_addr31to0
+ * @config_param3: [Bit15 : Bit0] mac_addr47to32
+ * [Bit31 : Bit16] reserved
+ */
+#define HTT_STAT_PEER_INFO_MAC_ADDR BIT(0)
+#define HTT_STAT_DEFAULT_PEER_REQ_TYPE 0x7f
+
+/* Used to set different configs to the specified stats type.*/
+struct htt_ext_stats_cfg_params {
+ u32 cfg0;
+ u32 cfg1;
+ u32 cfg2;
+ u32 cfg3;
+};
+
+enum vdev_stats_offload_timer_duration {
+ ATH12K_STATS_TIMER_DUR_500MS = 1,
+ ATH12K_STATS_TIMER_DUR_1SEC = 2,
+ ATH12K_STATS_TIMER_DUR_2SEC = 3,
+};
+
+#define ATH12K_HTT_MAC_ADDR_L32_0 GENMASK(7, 0)
+#define ATH12K_HTT_MAC_ADDR_L32_1 GENMASK(15, 8)
+#define ATH12K_HTT_MAC_ADDR_L32_2 GENMASK(23, 16)
+#define ATH12K_HTT_MAC_ADDR_L32_3 GENMASK(31, 24)
+#define ATH12K_HTT_MAC_ADDR_H16_0 GENMASK(7, 0)
+#define ATH12K_HTT_MAC_ADDR_H16_1 GENMASK(15, 8)
+
+struct htt_mac_addr {
+ __le32 mac_addr_l32;
+ __le32 mac_addr_h16;
+} __packed;
+
+#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 18/20] wifi: ath12k: Move HTT Rx specific code to newly introduced files
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (16 preceding siblings ...)
2025-08-28 17:35 ` [PATCH ath12k-ng 17/20] wifi: ath12k: Move HTT code in dp.h to newly introduced files Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 19/20] wifi: ath12k: Move HTT Tx " Ripan Deuri
` (4 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Harsh Kumar Bijlani <quic_hbijlani@quicinc.com>
WLAN Host driver interacts with the Firmware and vice versa using
Host-To-Target (HTT) interface.
HTT interface code is spread across multiple files (ex dp_tx.c, dp_rx.c
etc) and this interface is independent of the underlying architecture Tx
and Rx. Relocate HTT specific code from dp_rx.c to newly introduced file
dp_htt.c for HTT interface. This new file is compiled as part of the
common module ath12k.ko.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Harsh Kumar Bijlani <quic_hbijlani@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/Makefile | 1 +
drivers/net/wireless/ath/ath12k/dp_htt.c | 644 +++++++++++++++++++++++
drivers/net/wireless/ath/ath12k/dp_htt.h | 6 +
drivers/net/wireless/ath/ath12k/dp_rx.c | 633 ----------------------
drivers/net/wireless/ath/ath12k/dp_rx.h | 6 -
5 files changed, 651 insertions(+), 639 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath12k/dp_htt.c
diff --git a/drivers/net/wireless/ath/ath12k/Makefile b/drivers/net/wireless/ath/ath12k/Makefile
index e72b52d5af6d..70d4daa48c90 100644
--- a/drivers/net/wireless/ath/ath12k/Makefile
+++ b/drivers/net/wireless/ath/ath12k/Makefile
@@ -10,6 +10,7 @@ ath12k-y += core.o \
dp.o \
dp_tx.o \
dp_rx.o \
+ dp_htt.o \
debug.o \
ce.o \
peer.o \
diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c
new file mode 100644
index 000000000000..00847d579b95
--- /dev/null
+++ b/drivers/net/wireless/ath/ath12k/dp_htt.c
@@ -0,0 +1,644 @@
+// SPDX-License-Identifier: BSD-3-Clause-Clear
+/*
+ * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include "core.h"
+#include "peer.h"
+#include "htc.h"
+#include "dp_htt.h"
+#include "debugfs_htt_stats.h"
+
+static int ath12k_get_ppdu_user_index(struct htt_ppdu_stats *ppdu_stats,
+ u16 peer_id)
+{
+ int i;
+
+ for (i = 0; i < HTT_PPDU_STATS_MAX_USERS - 1; i++) {
+ if (ppdu_stats->user_stats[i].is_valid_peer_id) {
+ if (peer_id == ppdu_stats->user_stats[i].peer_id)
+ return i;
+ } else {
+ return i;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int ath12k_htt_tlv_ppdu_stats_parse(struct ath12k_base *ab,
+ u16 tag, u16 len, const void *ptr,
+ void *data)
+{
+ const struct htt_ppdu_stats_usr_cmpltn_ack_ba_status *ba_status;
+ const struct htt_ppdu_stats_usr_cmpltn_cmn *cmplt_cmn;
+ const struct htt_ppdu_stats_user_rate *user_rate;
+ struct htt_ppdu_stats_info *ppdu_info;
+ struct htt_ppdu_user_stats *user_stats;
+ int cur_user;
+ u16 peer_id;
+
+ ppdu_info = data;
+
+ switch (tag) {
+ case HTT_PPDU_STATS_TAG_COMMON:
+ if (len < sizeof(struct htt_ppdu_stats_common)) {
+ ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n",
+ len, tag);
+ return -EINVAL;
+ }
+ memcpy(&ppdu_info->ppdu_stats.common, ptr,
+ sizeof(struct htt_ppdu_stats_common));
+ break;
+ case HTT_PPDU_STATS_TAG_USR_RATE:
+ if (len < sizeof(struct htt_ppdu_stats_user_rate)) {
+ ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n",
+ len, tag);
+ return -EINVAL;
+ }
+ user_rate = ptr;
+ peer_id = le16_to_cpu(user_rate->sw_peer_id);
+ cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats,
+ peer_id);
+ if (cur_user < 0)
+ return -EINVAL;
+ user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user];
+ user_stats->peer_id = peer_id;
+ user_stats->is_valid_peer_id = true;
+ memcpy(&user_stats->rate, ptr,
+ sizeof(struct htt_ppdu_stats_user_rate));
+ user_stats->tlv_flags |= BIT(tag);
+ break;
+ case HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON:
+ if (len < sizeof(struct htt_ppdu_stats_usr_cmpltn_cmn)) {
+ ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n",
+ len, tag);
+ return -EINVAL;
+ }
+
+ cmplt_cmn = ptr;
+ peer_id = le16_to_cpu(cmplt_cmn->sw_peer_id);
+ cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats,
+ peer_id);
+ if (cur_user < 0)
+ return -EINVAL;
+ user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user];
+ user_stats->peer_id = peer_id;
+ user_stats->is_valid_peer_id = true;
+ memcpy(&user_stats->cmpltn_cmn, ptr,
+ sizeof(struct htt_ppdu_stats_usr_cmpltn_cmn));
+ user_stats->tlv_flags |= BIT(tag);
+ break;
+ case HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS:
+ if (len <
+ sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status)) {
+ ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n",
+ len, tag);
+ return -EINVAL;
+ }
+
+ ba_status = ptr;
+ peer_id = le16_to_cpu(ba_status->sw_peer_id);
+ cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats,
+ peer_id);
+ if (cur_user < 0)
+ return -EINVAL;
+ user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user];
+ user_stats->peer_id = peer_id;
+ user_stats->is_valid_peer_id = true;
+ memcpy(&user_stats->ack_ba, ptr,
+ sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status));
+ user_stats->tlv_flags |= BIT(tag);
+ break;
+ }
+ return 0;
+}
+
+int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len,
+ int (*iter)(struct ath12k_base *ar, u16 tag, u16 len,
+ const void *ptr, void *data),
+ void *data)
+{
+ const struct htt_tlv *tlv;
+ const void *begin = ptr;
+ u16 tlv_tag, tlv_len;
+ int ret = -EINVAL;
+
+ while (len > 0) {
+ if (len < sizeof(*tlv)) {
+ ath12k_err(ab, "htt tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n",
+ ptr - begin, len, sizeof(*tlv));
+ return -EINVAL;
+ }
+ tlv = (struct htt_tlv *)ptr;
+ tlv_tag = le32_get_bits(tlv->header, HTT_TLV_TAG);
+ tlv_len = le32_get_bits(tlv->header, HTT_TLV_LEN);
+ ptr += sizeof(*tlv);
+ len -= sizeof(*tlv);
+
+ if (tlv_len > len) {
+ ath12k_err(ab, "htt tlv parse failure of tag %u at byte %zd (%zu bytes left, %u expected)\n",
+ tlv_tag, ptr - begin, len, tlv_len);
+ return -EINVAL;
+ }
+ ret = iter(ab, tlv_tag, tlv_len, ptr, data);
+ if (ret == -ENOMEM)
+ return ret;
+
+ ptr += tlv_len;
+ len -= tlv_len;
+ }
+ return 0;
+}
+
+static void
+ath12k_update_per_peer_tx_stats(struct ath12k *ar,
+ struct htt_ppdu_stats *ppdu_stats, u8 user)
+{
+ struct ath12k_base *ab = ar->ab;
+ struct ath12k_peer *peer;
+ struct ath12k_link_sta *arsta;
+ struct htt_ppdu_stats_user_rate *user_rate;
+ struct ath12k_per_peer_tx_stats *peer_stats = &ar->peer_tx_stats;
+ struct htt_ppdu_user_stats *usr_stats = &ppdu_stats->user_stats[user];
+ struct htt_ppdu_stats_common *common = &ppdu_stats->common;
+ int ret;
+ u8 flags, mcs, nss, bw, sgi, dcm, ppdu_type, rate_idx = 0;
+ u32 v, succ_bytes = 0;
+ u16 tones, rate = 0, succ_pkts = 0;
+ u32 tx_duration = 0;
+ u8 tid = HTT_PPDU_STATS_NON_QOS_TID;
+ u16 tx_retry_failed = 0, tx_retry_count = 0;
+ bool is_ampdu = false, is_ofdma;
+
+ if (!(usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_RATE)))
+ return;
+
+ if (usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON)) {
+ is_ampdu =
+ HTT_USR_CMPLTN_IS_AMPDU(usr_stats->cmpltn_cmn.flags);
+ tx_retry_failed =
+ __le16_to_cpu(usr_stats->cmpltn_cmn.mpdu_tried) -
+ __le16_to_cpu(usr_stats->cmpltn_cmn.mpdu_success);
+ tx_retry_count =
+ HTT_USR_CMPLTN_LONG_RETRY(usr_stats->cmpltn_cmn.flags) +
+ HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags);
+ }
+
+ if (usr_stats->tlv_flags &
+ BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS)) {
+ succ_bytes = le32_to_cpu(usr_stats->ack_ba.success_bytes);
+ succ_pkts = le32_get_bits(usr_stats->ack_ba.info,
+ HTT_PPDU_STATS_ACK_BA_INFO_NUM_MSDU_M);
+ tid = le32_get_bits(usr_stats->ack_ba.info,
+ HTT_PPDU_STATS_ACK_BA_INFO_TID_NUM);
+ }
+
+ if (common->fes_duration_us)
+ tx_duration = le32_to_cpu(common->fes_duration_us);
+
+ user_rate = &usr_stats->rate;
+ flags = HTT_USR_RATE_PREAMBLE(user_rate->rate_flags);
+ bw = HTT_USR_RATE_BW(user_rate->rate_flags) - 2;
+ nss = HTT_USR_RATE_NSS(user_rate->rate_flags) + 1;
+ mcs = HTT_USR_RATE_MCS(user_rate->rate_flags);
+ sgi = HTT_USR_RATE_GI(user_rate->rate_flags);
+ dcm = HTT_USR_RATE_DCM(user_rate->rate_flags);
+
+ ppdu_type = HTT_USR_RATE_PPDU_TYPE(user_rate->info1);
+ is_ofdma = (ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA) ||
+ (ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA);
+
+ /* Note: If host configured fixed rates and in some other special
+ * cases, the broadcast/management frames are sent in different rates.
+ * Firmware rate's control to be skipped for this?
+ */
+
+ if (flags == WMI_RATE_PREAMBLE_HE && mcs > ATH12K_HE_MCS_MAX) {
+ ath12k_warn(ab, "Invalid HE mcs %d peer stats", mcs);
+ return;
+ }
+
+ if (flags == WMI_RATE_PREAMBLE_VHT && mcs > ATH12K_VHT_MCS_MAX) {
+ ath12k_warn(ab, "Invalid VHT mcs %d peer stats", mcs);
+ return;
+ }
+
+ if (flags == WMI_RATE_PREAMBLE_HT && (mcs > ATH12K_HT_MCS_MAX || nss < 1)) {
+ ath12k_warn(ab, "Invalid HT mcs %d nss %d peer stats",
+ mcs, nss);
+ return;
+ }
+
+ if (flags == WMI_RATE_PREAMBLE_CCK || flags == WMI_RATE_PREAMBLE_OFDM) {
+ ret = ath12k_mac_hw_ratecode_to_legacy_rate(mcs,
+ flags,
+ &rate_idx,
+ &rate);
+ if (ret < 0)
+ return;
+ }
+
+ rcu_read_lock();
+ spin_lock_bh(&ab->base_lock);
+ peer = ath12k_peer_find_by_id(ab, usr_stats->peer_id);
+
+ if (!peer || !peer->sta) {
+ spin_unlock_bh(&ab->base_lock);
+ rcu_read_unlock();
+ return;
+ }
+
+ arsta = ath12k_peer_get_link_sta(ab, peer);
+ if (!arsta) {
+ spin_unlock_bh(&ab->base_lock);
+ rcu_read_unlock();
+ return;
+ }
+
+ memset(&arsta->txrate, 0, sizeof(arsta->txrate));
+
+ arsta->txrate.bw = ath12k_mac_bw_to_mac80211_bw(bw);
+
+ switch (flags) {
+ case WMI_RATE_PREAMBLE_OFDM:
+ arsta->txrate.legacy = rate;
+ break;
+ case WMI_RATE_PREAMBLE_CCK:
+ arsta->txrate.legacy = rate;
+ break;
+ case WMI_RATE_PREAMBLE_HT:
+ arsta->txrate.mcs = mcs + 8 * (nss - 1);
+ arsta->txrate.flags = RATE_INFO_FLAGS_MCS;
+ if (sgi)
+ arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+ break;
+ case WMI_RATE_PREAMBLE_VHT:
+ arsta->txrate.mcs = mcs;
+ arsta->txrate.flags = RATE_INFO_FLAGS_VHT_MCS;
+ if (sgi)
+ arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+ break;
+ case WMI_RATE_PREAMBLE_HE:
+ arsta->txrate.mcs = mcs;
+ arsta->txrate.flags = RATE_INFO_FLAGS_HE_MCS;
+ arsta->txrate.he_dcm = dcm;
+ arsta->txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi);
+ tones = le16_to_cpu(user_rate->ru_end) -
+ le16_to_cpu(user_rate->ru_start) + 1;
+ v = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(tones);
+ arsta->txrate.he_ru_alloc = v;
+ if (is_ofdma)
+ arsta->txrate.bw = RATE_INFO_BW_HE_RU;
+ break;
+ case WMI_RATE_PREAMBLE_EHT:
+ arsta->txrate.mcs = mcs;
+ arsta->txrate.flags = RATE_INFO_FLAGS_EHT_MCS;
+ arsta->txrate.he_dcm = dcm;
+ arsta->txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(sgi);
+ tones = le16_to_cpu(user_rate->ru_end) -
+ le16_to_cpu(user_rate->ru_start) + 1;
+ v = ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(tones);
+ arsta->txrate.eht_ru_alloc = v;
+ if (is_ofdma)
+ arsta->txrate.bw = RATE_INFO_BW_EHT_RU;
+ break;
+ }
+
+ arsta->tx_retry_failed += tx_retry_failed;
+ arsta->tx_retry_count += tx_retry_count;
+ arsta->txrate.nss = nss;
+ arsta->tx_duration += tx_duration;
+ memcpy(&arsta->last_txrate, &arsta->txrate, sizeof(struct rate_info));
+
+ /* PPDU stats reported for mgmt packet doesn't have valid tx bytes.
+ * So skip peer stats update for mgmt packets.
+ */
+ if (tid < HTT_PPDU_STATS_NON_QOS_TID) {
+ memset(peer_stats, 0, sizeof(*peer_stats));
+ peer_stats->succ_pkts = succ_pkts;
+ peer_stats->succ_bytes = succ_bytes;
+ peer_stats->is_ampdu = is_ampdu;
+ peer_stats->duration = tx_duration;
+ peer_stats->ba_fails =
+ HTT_USR_CMPLTN_LONG_RETRY(usr_stats->cmpltn_cmn.flags) +
+ HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags);
+ }
+
+ spin_unlock_bh(&ab->base_lock);
+ rcu_read_unlock();
+}
+
+static void ath12k_htt_update_ppdu_stats(struct ath12k *ar,
+ struct htt_ppdu_stats *ppdu_stats)
+{
+ u8 user;
+
+ for (user = 0; user < HTT_PPDU_STATS_MAX_USERS - 1; user++)
+ ath12k_update_per_peer_tx_stats(ar, ppdu_stats, user);
+}
+
+static
+struct htt_ppdu_stats_info *ath12k_dp_htt_get_ppdu_desc(struct ath12k *ar,
+ u32 ppdu_id)
+{
+ struct htt_ppdu_stats_info *ppdu_info;
+
+ lockdep_assert_held(&ar->data_lock);
+ if (!list_empty(&ar->ppdu_stats_info)) {
+ list_for_each_entry(ppdu_info, &ar->ppdu_stats_info, list) {
+ if (ppdu_info->ppdu_id == ppdu_id)
+ return ppdu_info;
+ }
+
+ if (ar->ppdu_stat_list_depth > HTT_PPDU_DESC_MAX_DEPTH) {
+ ppdu_info = list_first_entry(&ar->ppdu_stats_info,
+ typeof(*ppdu_info), list);
+ list_del(&ppdu_info->list);
+ ar->ppdu_stat_list_depth--;
+ ath12k_htt_update_ppdu_stats(ar, &ppdu_info->ppdu_stats);
+ kfree(ppdu_info);
+ }
+ }
+
+ ppdu_info = kzalloc(sizeof(*ppdu_info), GFP_ATOMIC);
+ if (!ppdu_info)
+ return NULL;
+
+ list_add_tail(&ppdu_info->list, &ar->ppdu_stats_info);
+ ar->ppdu_stat_list_depth++;
+
+ return ppdu_info;
+}
+
+static void ath12k_copy_to_delay_stats(struct ath12k_peer *peer,
+ struct htt_ppdu_user_stats *usr_stats)
+{
+ peer->ppdu_stats_delayba.sw_peer_id = le16_to_cpu(usr_stats->rate.sw_peer_id);
+ peer->ppdu_stats_delayba.info0 = le32_to_cpu(usr_stats->rate.info0);
+ peer->ppdu_stats_delayba.ru_end = le16_to_cpu(usr_stats->rate.ru_end);
+ peer->ppdu_stats_delayba.ru_start = le16_to_cpu(usr_stats->rate.ru_start);
+ peer->ppdu_stats_delayba.info1 = le32_to_cpu(usr_stats->rate.info1);
+ peer->ppdu_stats_delayba.rate_flags = le32_to_cpu(usr_stats->rate.rate_flags);
+ peer->ppdu_stats_delayba.resp_rate_flags =
+ le32_to_cpu(usr_stats->rate.resp_rate_flags);
+
+ peer->delayba_flag = true;
+}
+
+static void ath12k_copy_to_bar(struct ath12k_peer *peer,
+ struct htt_ppdu_user_stats *usr_stats)
+{
+ usr_stats->rate.sw_peer_id = cpu_to_le16(peer->ppdu_stats_delayba.sw_peer_id);
+ usr_stats->rate.info0 = cpu_to_le32(peer->ppdu_stats_delayba.info0);
+ usr_stats->rate.ru_end = cpu_to_le16(peer->ppdu_stats_delayba.ru_end);
+ usr_stats->rate.ru_start = cpu_to_le16(peer->ppdu_stats_delayba.ru_start);
+ usr_stats->rate.info1 = cpu_to_le32(peer->ppdu_stats_delayba.info1);
+ usr_stats->rate.rate_flags = cpu_to_le32(peer->ppdu_stats_delayba.rate_flags);
+ usr_stats->rate.resp_rate_flags =
+ cpu_to_le32(peer->ppdu_stats_delayba.resp_rate_flags);
+
+ peer->delayba_flag = false;
+}
+
+static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab,
+ struct sk_buff *skb)
+{
+ struct ath12k_htt_ppdu_stats_msg *msg;
+ struct htt_ppdu_stats_info *ppdu_info;
+ struct ath12k_peer *peer = NULL;
+ struct htt_ppdu_user_stats *usr_stats = NULL;
+ u32 peer_id = 0;
+ struct ath12k *ar;
+ int ret, i;
+ u8 pdev_id;
+ u32 ppdu_id, len;
+
+ msg = (struct ath12k_htt_ppdu_stats_msg *)skb->data;
+ len = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PAYLOAD_SIZE);
+ if (len > (skb->len - struct_size(msg, data, 0))) {
+ ath12k_warn(ab,
+ "HTT PPDU STATS event has unexpected payload size %u, should be smaller than %u\n",
+ len, skb->len);
+ return -EINVAL;
+ }
+
+ pdev_id = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PDEV_ID);
+ ppdu_id = le32_to_cpu(msg->ppdu_id);
+
+ rcu_read_lock();
+ ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id);
+ if (!ar) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ spin_lock_bh(&ar->data_lock);
+ ppdu_info = ath12k_dp_htt_get_ppdu_desc(ar, ppdu_id);
+ if (!ppdu_info) {
+ spin_unlock_bh(&ar->data_lock);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ ppdu_info->ppdu_id = ppdu_id;
+ ret = ath12k_dp_htt_tlv_iter(ab, msg->data, len,
+ ath12k_htt_tlv_ppdu_stats_parse,
+ (void *)ppdu_info);
+ if (ret) {
+ spin_unlock_bh(&ar->data_lock);
+ ath12k_warn(ab, "Failed to parse tlv %d\n", ret);
+ goto exit;
+ }
+
+ if (ppdu_info->ppdu_stats.common.num_users >= HTT_PPDU_STATS_MAX_USERS) {
+ spin_unlock_bh(&ar->data_lock);
+ ath12k_warn(ab,
+ "HTT PPDU STATS event has unexpected num_users %u, should be smaller than %u\n",
+ ppdu_info->ppdu_stats.common.num_users,
+ HTT_PPDU_STATS_MAX_USERS);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ /* back up data rate tlv for all peers */
+ if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_DATA &&
+ (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON)) &&
+ ppdu_info->delay_ba) {
+ for (i = 0; i < ppdu_info->ppdu_stats.common.num_users; i++) {
+ peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id;
+ spin_lock_bh(&ab->base_lock);
+ peer = ath12k_peer_find_by_id(ab, peer_id);
+ if (!peer) {
+ spin_unlock_bh(&ab->base_lock);
+ continue;
+ }
+
+ usr_stats = &ppdu_info->ppdu_stats.user_stats[i];
+ if (usr_stats->delay_ba)
+ ath12k_copy_to_delay_stats(peer, usr_stats);
+ spin_unlock_bh(&ab->base_lock);
+ }
+ }
+
+ /* restore all peers' data rate tlv to mu-bar tlv */
+ if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_BAR &&
+ (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON))) {
+ for (i = 0; i < ppdu_info->bar_num_users; i++) {
+ peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id;
+ spin_lock_bh(&ab->base_lock);
+ peer = ath12k_peer_find_by_id(ab, peer_id);
+ if (!peer) {
+ spin_unlock_bh(&ab->base_lock);
+ continue;
+ }
+
+ usr_stats = &ppdu_info->ppdu_stats.user_stats[i];
+ if (peer->delayba_flag)
+ ath12k_copy_to_bar(peer, usr_stats);
+ spin_unlock_bh(&ab->base_lock);
+ }
+ }
+
+ spin_unlock_bh(&ar->data_lock);
+
+exit:
+ rcu_read_unlock();
+
+ return ret;
+}
+
+static void ath12k_htt_mlo_offset_event_handler(struct ath12k_base *ab,
+ struct sk_buff *skb)
+{
+ struct ath12k_htt_mlo_offset_msg *msg;
+ struct ath12k_pdev *pdev;
+ struct ath12k *ar;
+ u8 pdev_id;
+
+ msg = (struct ath12k_htt_mlo_offset_msg *)skb->data;
+ pdev_id = u32_get_bits(__le32_to_cpu(msg->info),
+ HTT_T2H_MLO_OFFSET_INFO_PDEV_ID);
+
+ rcu_read_lock();
+ ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id);
+ if (!ar) {
+ /* It is possible that the ar is not yet active (started).
+ * The above function will only look for the active pdev
+ * and hence %NULL return is possible. Just silently
+ * discard this message
+ */
+ goto exit;
+ }
+
+ spin_lock_bh(&ar->data_lock);
+ pdev = ar->pdev;
+
+ pdev->timestamp.info = __le32_to_cpu(msg->info);
+ pdev->timestamp.sync_timestamp_lo_us = __le32_to_cpu(msg->sync_timestamp_lo_us);
+ pdev->timestamp.sync_timestamp_hi_us = __le32_to_cpu(msg->sync_timestamp_hi_us);
+ pdev->timestamp.mlo_offset_lo = __le32_to_cpu(msg->mlo_offset_lo);
+ pdev->timestamp.mlo_offset_hi = __le32_to_cpu(msg->mlo_offset_hi);
+ pdev->timestamp.mlo_offset_clks = __le32_to_cpu(msg->mlo_offset_clks);
+ pdev->timestamp.mlo_comp_clks = __le32_to_cpu(msg->mlo_comp_clks);
+ pdev->timestamp.mlo_comp_timer = __le32_to_cpu(msg->mlo_comp_timer);
+
+ spin_unlock_bh(&ar->data_lock);
+exit:
+ rcu_read_unlock();
+}
+
+void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab,
+ struct sk_buff *skb)
+{
+ struct ath12k_dp *dp = &ab->dp;
+ struct htt_resp_msg *resp = (struct htt_resp_msg *)skb->data;
+ enum htt_t2h_msg_type type;
+ u16 peer_id;
+ u8 vdev_id;
+ u8 mac_addr[ETH_ALEN];
+ u16 peer_mac_h16;
+ u16 ast_hash = 0;
+ u16 hw_peer_id;
+
+ type = le32_get_bits(resp->version_msg.version, HTT_T2H_MSG_TYPE);
+
+ ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt rx msg type :0x%0x\n", type);
+
+ switch (type) {
+ case HTT_T2H_MSG_TYPE_VERSION_CONF:
+ dp->htt_tgt_ver_major = le32_get_bits(resp->version_msg.version,
+ HTT_T2H_VERSION_CONF_MAJOR);
+ dp->htt_tgt_ver_minor = le32_get_bits(resp->version_msg.version,
+ HTT_T2H_VERSION_CONF_MINOR);
+ complete(&dp->htt_tgt_version_received);
+ break;
+ /* TODO: remove unused peer map versions after testing */
+ case HTT_T2H_MSG_TYPE_PEER_MAP:
+ vdev_id = le32_get_bits(resp->peer_map_ev.info,
+ HTT_T2H_PEER_MAP_INFO_VDEV_ID);
+ peer_id = le32_get_bits(resp->peer_map_ev.info,
+ HTT_T2H_PEER_MAP_INFO_PEER_ID);
+ peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1,
+ HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16);
+ ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32),
+ peer_mac_h16, mac_addr);
+ ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, 0, 0);
+ break;
+ case HTT_T2H_MSG_TYPE_PEER_MAP2:
+ vdev_id = le32_get_bits(resp->peer_map_ev.info,
+ HTT_T2H_PEER_MAP_INFO_VDEV_ID);
+ peer_id = le32_get_bits(resp->peer_map_ev.info,
+ HTT_T2H_PEER_MAP_INFO_PEER_ID);
+ peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1,
+ HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16);
+ ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32),
+ peer_mac_h16, mac_addr);
+ ast_hash = le32_get_bits(resp->peer_map_ev.info2,
+ HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL);
+ hw_peer_id = le32_get_bits(resp->peer_map_ev.info1,
+ HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID);
+ ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash,
+ hw_peer_id);
+ break;
+ case HTT_T2H_MSG_TYPE_PEER_MAP3:
+ vdev_id = le32_get_bits(resp->peer_map_ev.info,
+ HTT_T2H_PEER_MAP_INFO_VDEV_ID);
+ peer_id = le32_get_bits(resp->peer_map_ev.info,
+ HTT_T2H_PEER_MAP_INFO_PEER_ID);
+ peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1,
+ HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16);
+ ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32),
+ peer_mac_h16, mac_addr);
+ ast_hash = le32_get_bits(resp->peer_map_ev.info2,
+ HTT_T2H_PEER_MAP3_INFO2_AST_HASH_VAL);
+ hw_peer_id = le32_get_bits(resp->peer_map_ev.info2,
+ HTT_T2H_PEER_MAP3_INFO2_HW_PEER_ID);
+ ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash,
+ hw_peer_id);
+ break;
+ case HTT_T2H_MSG_TYPE_PEER_UNMAP:
+ case HTT_T2H_MSG_TYPE_PEER_UNMAP2:
+ peer_id = le32_get_bits(resp->peer_unmap_ev.info,
+ HTT_T2H_PEER_UNMAP_INFO_PEER_ID);
+ ath12k_peer_unmap_event(ab, peer_id);
+ break;
+ case HTT_T2H_MSG_TYPE_PPDU_STATS_IND:
+ ath12k_htt_pull_ppdu_stats(ab, skb);
+ break;
+ case HTT_T2H_MSG_TYPE_EXT_STATS_CONF:
+ ath12k_debugfs_htt_ext_stats_handler(ab, skb);
+ break;
+ case HTT_T2H_MSG_TYPE_MLO_TIMESTAMP_OFFSET_IND:
+ ath12k_htt_mlo_offset_event_handler(ab, skb);
+ break;
+ default:
+ ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt event %d not handled\n",
+ type);
+ break;
+ }
+
+ dev_kfree_skb_any(skb);
+}
+EXPORT_SYMBOL(ath12k_dp_htt_htc_t2h_msg_handler);
diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.h b/drivers/net/wireless/ath/ath12k/dp_htt.h
index ce9064628d34..9ae3a750f608 100644
--- a/drivers/net/wireless/ath/ath12k/dp_htt.h
+++ b/drivers/net/wireless/ath/ath12k/dp_htt.h
@@ -1514,4 +1514,10 @@ struct htt_mac_addr {
__le32 mac_addr_h16;
} __packed;
+int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len,
+ int (*iter)(struct ath12k_base *ar, u16 tag, u16 len,
+ const void *ptr, void *data),
+ void *data);
+void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab,
+ struct sk_buff *skb);
#endif
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index d735eee9efee..e1a2f5f54adb 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -719,639 +719,6 @@ int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif,
return ret;
}
-static int ath12k_get_ppdu_user_index(struct htt_ppdu_stats *ppdu_stats,
- u16 peer_id)
-{
- int i;
-
- for (i = 0; i < HTT_PPDU_STATS_MAX_USERS - 1; i++) {
- if (ppdu_stats->user_stats[i].is_valid_peer_id) {
- if (peer_id == ppdu_stats->user_stats[i].peer_id)
- return i;
- } else {
- return i;
- }
- }
-
- return -EINVAL;
-}
-
-static int ath12k_htt_tlv_ppdu_stats_parse(struct ath12k_base *ab,
- u16 tag, u16 len, const void *ptr,
- void *data)
-{
- const struct htt_ppdu_stats_usr_cmpltn_ack_ba_status *ba_status;
- const struct htt_ppdu_stats_usr_cmpltn_cmn *cmplt_cmn;
- const struct htt_ppdu_stats_user_rate *user_rate;
- struct htt_ppdu_stats_info *ppdu_info;
- struct htt_ppdu_user_stats *user_stats;
- int cur_user;
- u16 peer_id;
-
- ppdu_info = data;
-
- switch (tag) {
- case HTT_PPDU_STATS_TAG_COMMON:
- if (len < sizeof(struct htt_ppdu_stats_common)) {
- ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n",
- len, tag);
- return -EINVAL;
- }
- memcpy(&ppdu_info->ppdu_stats.common, ptr,
- sizeof(struct htt_ppdu_stats_common));
- break;
- case HTT_PPDU_STATS_TAG_USR_RATE:
- if (len < sizeof(struct htt_ppdu_stats_user_rate)) {
- ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n",
- len, tag);
- return -EINVAL;
- }
- user_rate = ptr;
- peer_id = le16_to_cpu(user_rate->sw_peer_id);
- cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats,
- peer_id);
- if (cur_user < 0)
- return -EINVAL;
- user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user];
- user_stats->peer_id = peer_id;
- user_stats->is_valid_peer_id = true;
- memcpy(&user_stats->rate, ptr,
- sizeof(struct htt_ppdu_stats_user_rate));
- user_stats->tlv_flags |= BIT(tag);
- break;
- case HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON:
- if (len < sizeof(struct htt_ppdu_stats_usr_cmpltn_cmn)) {
- ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n",
- len, tag);
- return -EINVAL;
- }
-
- cmplt_cmn = ptr;
- peer_id = le16_to_cpu(cmplt_cmn->sw_peer_id);
- cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats,
- peer_id);
- if (cur_user < 0)
- return -EINVAL;
- user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user];
- user_stats->peer_id = peer_id;
- user_stats->is_valid_peer_id = true;
- memcpy(&user_stats->cmpltn_cmn, ptr,
- sizeof(struct htt_ppdu_stats_usr_cmpltn_cmn));
- user_stats->tlv_flags |= BIT(tag);
- break;
- case HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS:
- if (len <
- sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status)) {
- ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n",
- len, tag);
- return -EINVAL;
- }
-
- ba_status = ptr;
- peer_id = le16_to_cpu(ba_status->sw_peer_id);
- cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats,
- peer_id);
- if (cur_user < 0)
- return -EINVAL;
- user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user];
- user_stats->peer_id = peer_id;
- user_stats->is_valid_peer_id = true;
- memcpy(&user_stats->ack_ba, ptr,
- sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status));
- user_stats->tlv_flags |= BIT(tag);
- break;
- }
- return 0;
-}
-
-int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len,
- int (*iter)(struct ath12k_base *ar, u16 tag, u16 len,
- const void *ptr, void *data),
- void *data)
-{
- const struct htt_tlv *tlv;
- const void *begin = ptr;
- u16 tlv_tag, tlv_len;
- int ret = -EINVAL;
-
- while (len > 0) {
- if (len < sizeof(*tlv)) {
- ath12k_err(ab, "htt tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n",
- ptr - begin, len, sizeof(*tlv));
- return -EINVAL;
- }
- tlv = (struct htt_tlv *)ptr;
- tlv_tag = le32_get_bits(tlv->header, HTT_TLV_TAG);
- tlv_len = le32_get_bits(tlv->header, HTT_TLV_LEN);
- ptr += sizeof(*tlv);
- len -= sizeof(*tlv);
-
- if (tlv_len > len) {
- ath12k_err(ab, "htt tlv parse failure of tag %u at byte %zd (%zu bytes left, %u expected)\n",
- tlv_tag, ptr - begin, len, tlv_len);
- return -EINVAL;
- }
- ret = iter(ab, tlv_tag, tlv_len, ptr, data);
- if (ret == -ENOMEM)
- return ret;
-
- ptr += tlv_len;
- len -= tlv_len;
- }
- return 0;
-}
-
-static void
-ath12k_update_per_peer_tx_stats(struct ath12k *ar,
- struct htt_ppdu_stats *ppdu_stats, u8 user)
-{
- struct ath12k_base *ab = ar->ab;
- struct ath12k_peer *peer;
- struct ath12k_link_sta *arsta;
- struct htt_ppdu_stats_user_rate *user_rate;
- struct ath12k_per_peer_tx_stats *peer_stats = &ar->peer_tx_stats;
- struct htt_ppdu_user_stats *usr_stats = &ppdu_stats->user_stats[user];
- struct htt_ppdu_stats_common *common = &ppdu_stats->common;
- int ret;
- u8 flags, mcs, nss, bw, sgi, dcm, ppdu_type, rate_idx = 0;
- u32 v, succ_bytes = 0;
- u16 tones, rate = 0, succ_pkts = 0;
- u32 tx_duration = 0;
- u8 tid = HTT_PPDU_STATS_NON_QOS_TID;
- u16 tx_retry_failed = 0, tx_retry_count = 0;
- bool is_ampdu = false, is_ofdma;
-
- if (!(usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_RATE)))
- return;
-
- if (usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON)) {
- is_ampdu =
- HTT_USR_CMPLTN_IS_AMPDU(usr_stats->cmpltn_cmn.flags);
- tx_retry_failed =
- __le16_to_cpu(usr_stats->cmpltn_cmn.mpdu_tried) -
- __le16_to_cpu(usr_stats->cmpltn_cmn.mpdu_success);
- tx_retry_count =
- HTT_USR_CMPLTN_LONG_RETRY(usr_stats->cmpltn_cmn.flags) +
- HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags);
- }
-
- if (usr_stats->tlv_flags &
- BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS)) {
- succ_bytes = le32_to_cpu(usr_stats->ack_ba.success_bytes);
- succ_pkts = le32_get_bits(usr_stats->ack_ba.info,
- HTT_PPDU_STATS_ACK_BA_INFO_NUM_MSDU_M);
- tid = le32_get_bits(usr_stats->ack_ba.info,
- HTT_PPDU_STATS_ACK_BA_INFO_TID_NUM);
- }
-
- if (common->fes_duration_us)
- tx_duration = le32_to_cpu(common->fes_duration_us);
-
- user_rate = &usr_stats->rate;
- flags = HTT_USR_RATE_PREAMBLE(user_rate->rate_flags);
- bw = HTT_USR_RATE_BW(user_rate->rate_flags) - 2;
- nss = HTT_USR_RATE_NSS(user_rate->rate_flags) + 1;
- mcs = HTT_USR_RATE_MCS(user_rate->rate_flags);
- sgi = HTT_USR_RATE_GI(user_rate->rate_flags);
- dcm = HTT_USR_RATE_DCM(user_rate->rate_flags);
-
- ppdu_type = HTT_USR_RATE_PPDU_TYPE(user_rate->info1);
- is_ofdma = (ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA) ||
- (ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA);
-
- /* Note: If host configured fixed rates and in some other special
- * cases, the broadcast/management frames are sent in different rates.
- * Firmware rate's control to be skipped for this?
- */
-
- if (flags == WMI_RATE_PREAMBLE_HE && mcs > ATH12K_HE_MCS_MAX) {
- ath12k_warn(ab, "Invalid HE mcs %d peer stats", mcs);
- return;
- }
-
- if (flags == WMI_RATE_PREAMBLE_VHT && mcs > ATH12K_VHT_MCS_MAX) {
- ath12k_warn(ab, "Invalid VHT mcs %d peer stats", mcs);
- return;
- }
-
- if (flags == WMI_RATE_PREAMBLE_HT && (mcs > ATH12K_HT_MCS_MAX || nss < 1)) {
- ath12k_warn(ab, "Invalid HT mcs %d nss %d peer stats",
- mcs, nss);
- return;
- }
-
- if (flags == WMI_RATE_PREAMBLE_CCK || flags == WMI_RATE_PREAMBLE_OFDM) {
- ret = ath12k_mac_hw_ratecode_to_legacy_rate(mcs,
- flags,
- &rate_idx,
- &rate);
- if (ret < 0)
- return;
- }
-
- rcu_read_lock();
- spin_lock_bh(&ab->base_lock);
- peer = ath12k_peer_find_by_id(ab, usr_stats->peer_id);
-
- if (!peer || !peer->sta) {
- spin_unlock_bh(&ab->base_lock);
- rcu_read_unlock();
- return;
- }
-
- arsta = ath12k_peer_get_link_sta(ab, peer);
- if (!arsta) {
- spin_unlock_bh(&ab->base_lock);
- rcu_read_unlock();
- return;
- }
-
- memset(&arsta->txrate, 0, sizeof(arsta->txrate));
-
- arsta->txrate.bw = ath12k_mac_bw_to_mac80211_bw(bw);
-
- switch (flags) {
- case WMI_RATE_PREAMBLE_OFDM:
- arsta->txrate.legacy = rate;
- break;
- case WMI_RATE_PREAMBLE_CCK:
- arsta->txrate.legacy = rate;
- break;
- case WMI_RATE_PREAMBLE_HT:
- arsta->txrate.mcs = mcs + 8 * (nss - 1);
- arsta->txrate.flags = RATE_INFO_FLAGS_MCS;
- if (sgi)
- arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
- break;
- case WMI_RATE_PREAMBLE_VHT:
- arsta->txrate.mcs = mcs;
- arsta->txrate.flags = RATE_INFO_FLAGS_VHT_MCS;
- if (sgi)
- arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
- break;
- case WMI_RATE_PREAMBLE_HE:
- arsta->txrate.mcs = mcs;
- arsta->txrate.flags = RATE_INFO_FLAGS_HE_MCS;
- arsta->txrate.he_dcm = dcm;
- arsta->txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi);
- tones = le16_to_cpu(user_rate->ru_end) -
- le16_to_cpu(user_rate->ru_start) + 1;
- v = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(tones);
- arsta->txrate.he_ru_alloc = v;
- if (is_ofdma)
- arsta->txrate.bw = RATE_INFO_BW_HE_RU;
- break;
- case WMI_RATE_PREAMBLE_EHT:
- arsta->txrate.mcs = mcs;
- arsta->txrate.flags = RATE_INFO_FLAGS_EHT_MCS;
- arsta->txrate.he_dcm = dcm;
- arsta->txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(sgi);
- tones = le16_to_cpu(user_rate->ru_end) -
- le16_to_cpu(user_rate->ru_start) + 1;
- v = ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(tones);
- arsta->txrate.eht_ru_alloc = v;
- if (is_ofdma)
- arsta->txrate.bw = RATE_INFO_BW_EHT_RU;
- break;
- }
-
- arsta->tx_retry_failed += tx_retry_failed;
- arsta->tx_retry_count += tx_retry_count;
- arsta->txrate.nss = nss;
- arsta->tx_duration += tx_duration;
- memcpy(&arsta->last_txrate, &arsta->txrate, sizeof(struct rate_info));
-
- /* PPDU stats reported for mgmt packet doesn't have valid tx bytes.
- * So skip peer stats update for mgmt packets.
- */
- if (tid < HTT_PPDU_STATS_NON_QOS_TID) {
- memset(peer_stats, 0, sizeof(*peer_stats));
- peer_stats->succ_pkts = succ_pkts;
- peer_stats->succ_bytes = succ_bytes;
- peer_stats->is_ampdu = is_ampdu;
- peer_stats->duration = tx_duration;
- peer_stats->ba_fails =
- HTT_USR_CMPLTN_LONG_RETRY(usr_stats->cmpltn_cmn.flags) +
- HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags);
- }
-
- spin_unlock_bh(&ab->base_lock);
- rcu_read_unlock();
-}
-
-static void ath12k_htt_update_ppdu_stats(struct ath12k *ar,
- struct htt_ppdu_stats *ppdu_stats)
-{
- u8 user;
-
- for (user = 0; user < HTT_PPDU_STATS_MAX_USERS - 1; user++)
- ath12k_update_per_peer_tx_stats(ar, ppdu_stats, user);
-}
-
-static
-struct htt_ppdu_stats_info *ath12k_dp_htt_get_ppdu_desc(struct ath12k *ar,
- u32 ppdu_id)
-{
- struct htt_ppdu_stats_info *ppdu_info;
-
- lockdep_assert_held(&ar->data_lock);
- if (!list_empty(&ar->ppdu_stats_info)) {
- list_for_each_entry(ppdu_info, &ar->ppdu_stats_info, list) {
- if (ppdu_info->ppdu_id == ppdu_id)
- return ppdu_info;
- }
-
- if (ar->ppdu_stat_list_depth > HTT_PPDU_DESC_MAX_DEPTH) {
- ppdu_info = list_first_entry(&ar->ppdu_stats_info,
- typeof(*ppdu_info), list);
- list_del(&ppdu_info->list);
- ar->ppdu_stat_list_depth--;
- ath12k_htt_update_ppdu_stats(ar, &ppdu_info->ppdu_stats);
- kfree(ppdu_info);
- }
- }
-
- ppdu_info = kzalloc(sizeof(*ppdu_info), GFP_ATOMIC);
- if (!ppdu_info)
- return NULL;
-
- list_add_tail(&ppdu_info->list, &ar->ppdu_stats_info);
- ar->ppdu_stat_list_depth++;
-
- return ppdu_info;
-}
-
-static void ath12k_copy_to_delay_stats(struct ath12k_peer *peer,
- struct htt_ppdu_user_stats *usr_stats)
-{
- peer->ppdu_stats_delayba.sw_peer_id = le16_to_cpu(usr_stats->rate.sw_peer_id);
- peer->ppdu_stats_delayba.info0 = le32_to_cpu(usr_stats->rate.info0);
- peer->ppdu_stats_delayba.ru_end = le16_to_cpu(usr_stats->rate.ru_end);
- peer->ppdu_stats_delayba.ru_start = le16_to_cpu(usr_stats->rate.ru_start);
- peer->ppdu_stats_delayba.info1 = le32_to_cpu(usr_stats->rate.info1);
- peer->ppdu_stats_delayba.rate_flags = le32_to_cpu(usr_stats->rate.rate_flags);
- peer->ppdu_stats_delayba.resp_rate_flags =
- le32_to_cpu(usr_stats->rate.resp_rate_flags);
-
- peer->delayba_flag = true;
-}
-
-static void ath12k_copy_to_bar(struct ath12k_peer *peer,
- struct htt_ppdu_user_stats *usr_stats)
-{
- usr_stats->rate.sw_peer_id = cpu_to_le16(peer->ppdu_stats_delayba.sw_peer_id);
- usr_stats->rate.info0 = cpu_to_le32(peer->ppdu_stats_delayba.info0);
- usr_stats->rate.ru_end = cpu_to_le16(peer->ppdu_stats_delayba.ru_end);
- usr_stats->rate.ru_start = cpu_to_le16(peer->ppdu_stats_delayba.ru_start);
- usr_stats->rate.info1 = cpu_to_le32(peer->ppdu_stats_delayba.info1);
- usr_stats->rate.rate_flags = cpu_to_le32(peer->ppdu_stats_delayba.rate_flags);
- usr_stats->rate.resp_rate_flags =
- cpu_to_le32(peer->ppdu_stats_delayba.resp_rate_flags);
-
- peer->delayba_flag = false;
-}
-
-static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab,
- struct sk_buff *skb)
-{
- struct ath12k_htt_ppdu_stats_msg *msg;
- struct htt_ppdu_stats_info *ppdu_info;
- struct ath12k_peer *peer = NULL;
- struct htt_ppdu_user_stats *usr_stats = NULL;
- u32 peer_id = 0;
- struct ath12k *ar;
- int ret, i;
- u8 pdev_id;
- u32 ppdu_id, len;
-
- msg = (struct ath12k_htt_ppdu_stats_msg *)skb->data;
- len = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PAYLOAD_SIZE);
- if (len > (skb->len - struct_size(msg, data, 0))) {
- ath12k_warn(ab,
- "HTT PPDU STATS event has unexpected payload size %u, should be smaller than %u\n",
- len, skb->len);
- return -EINVAL;
- }
-
- pdev_id = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PDEV_ID);
- ppdu_id = le32_to_cpu(msg->ppdu_id);
-
- rcu_read_lock();
- ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id);
- if (!ar) {
- ret = -EINVAL;
- goto exit;
- }
-
- spin_lock_bh(&ar->data_lock);
- ppdu_info = ath12k_dp_htt_get_ppdu_desc(ar, ppdu_id);
- if (!ppdu_info) {
- spin_unlock_bh(&ar->data_lock);
- ret = -EINVAL;
- goto exit;
- }
-
- ppdu_info->ppdu_id = ppdu_id;
- ret = ath12k_dp_htt_tlv_iter(ab, msg->data, len,
- ath12k_htt_tlv_ppdu_stats_parse,
- (void *)ppdu_info);
- if (ret) {
- spin_unlock_bh(&ar->data_lock);
- ath12k_warn(ab, "Failed to parse tlv %d\n", ret);
- goto exit;
- }
-
- if (ppdu_info->ppdu_stats.common.num_users >= HTT_PPDU_STATS_MAX_USERS) {
- spin_unlock_bh(&ar->data_lock);
- ath12k_warn(ab,
- "HTT PPDU STATS event has unexpected num_users %u, should be smaller than %u\n",
- ppdu_info->ppdu_stats.common.num_users,
- HTT_PPDU_STATS_MAX_USERS);
- ret = -EINVAL;
- goto exit;
- }
-
- /* back up data rate tlv for all peers */
- if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_DATA &&
- (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON)) &&
- ppdu_info->delay_ba) {
- for (i = 0; i < ppdu_info->ppdu_stats.common.num_users; i++) {
- peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id;
- spin_lock_bh(&ab->base_lock);
- peer = ath12k_peer_find_by_id(ab, peer_id);
- if (!peer) {
- spin_unlock_bh(&ab->base_lock);
- continue;
- }
-
- usr_stats = &ppdu_info->ppdu_stats.user_stats[i];
- if (usr_stats->delay_ba)
- ath12k_copy_to_delay_stats(peer, usr_stats);
- spin_unlock_bh(&ab->base_lock);
- }
- }
-
- /* restore all peers' data rate tlv to mu-bar tlv */
- if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_BAR &&
- (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON))) {
- for (i = 0; i < ppdu_info->bar_num_users; i++) {
- peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id;
- spin_lock_bh(&ab->base_lock);
- peer = ath12k_peer_find_by_id(ab, peer_id);
- if (!peer) {
- spin_unlock_bh(&ab->base_lock);
- continue;
- }
-
- usr_stats = &ppdu_info->ppdu_stats.user_stats[i];
- if (peer->delayba_flag)
- ath12k_copy_to_bar(peer, usr_stats);
- spin_unlock_bh(&ab->base_lock);
- }
- }
-
- spin_unlock_bh(&ar->data_lock);
-
-exit:
- rcu_read_unlock();
-
- return ret;
-}
-
-static void ath12k_htt_mlo_offset_event_handler(struct ath12k_base *ab,
- struct sk_buff *skb)
-{
- struct ath12k_htt_mlo_offset_msg *msg;
- struct ath12k_pdev *pdev;
- struct ath12k *ar;
- u8 pdev_id;
-
- msg = (struct ath12k_htt_mlo_offset_msg *)skb->data;
- pdev_id = u32_get_bits(__le32_to_cpu(msg->info),
- HTT_T2H_MLO_OFFSET_INFO_PDEV_ID);
-
- rcu_read_lock();
- ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id);
- if (!ar) {
- /* It is possible that the ar is not yet active (started).
- * The above function will only look for the active pdev
- * and hence %NULL return is possible. Just silently
- * discard this message
- */
- goto exit;
- }
-
- spin_lock_bh(&ar->data_lock);
- pdev = ar->pdev;
-
- pdev->timestamp.info = __le32_to_cpu(msg->info);
- pdev->timestamp.sync_timestamp_lo_us = __le32_to_cpu(msg->sync_timestamp_lo_us);
- pdev->timestamp.sync_timestamp_hi_us = __le32_to_cpu(msg->sync_timestamp_hi_us);
- pdev->timestamp.mlo_offset_lo = __le32_to_cpu(msg->mlo_offset_lo);
- pdev->timestamp.mlo_offset_hi = __le32_to_cpu(msg->mlo_offset_hi);
- pdev->timestamp.mlo_offset_clks = __le32_to_cpu(msg->mlo_offset_clks);
- pdev->timestamp.mlo_comp_clks = __le32_to_cpu(msg->mlo_comp_clks);
- pdev->timestamp.mlo_comp_timer = __le32_to_cpu(msg->mlo_comp_timer);
-
- spin_unlock_bh(&ar->data_lock);
-exit:
- rcu_read_unlock();
-}
-
-void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab,
- struct sk_buff *skb)
-{
- struct ath12k_dp *dp = &ab->dp;
- struct htt_resp_msg *resp = (struct htt_resp_msg *)skb->data;
- enum htt_t2h_msg_type type;
- u16 peer_id;
- u8 vdev_id;
- u8 mac_addr[ETH_ALEN];
- u16 peer_mac_h16;
- u16 ast_hash = 0;
- u16 hw_peer_id;
-
- type = le32_get_bits(resp->version_msg.version, HTT_T2H_MSG_TYPE);
-
- ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt rx msg type :0x%0x\n", type);
-
- switch (type) {
- case HTT_T2H_MSG_TYPE_VERSION_CONF:
- dp->htt_tgt_ver_major = le32_get_bits(resp->version_msg.version,
- HTT_T2H_VERSION_CONF_MAJOR);
- dp->htt_tgt_ver_minor = le32_get_bits(resp->version_msg.version,
- HTT_T2H_VERSION_CONF_MINOR);
- complete(&dp->htt_tgt_version_received);
- break;
- /* TODO: remove unused peer map versions after testing */
- case HTT_T2H_MSG_TYPE_PEER_MAP:
- vdev_id = le32_get_bits(resp->peer_map_ev.info,
- HTT_T2H_PEER_MAP_INFO_VDEV_ID);
- peer_id = le32_get_bits(resp->peer_map_ev.info,
- HTT_T2H_PEER_MAP_INFO_PEER_ID);
- peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1,
- HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16);
- ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32),
- peer_mac_h16, mac_addr);
- ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, 0, 0);
- break;
- case HTT_T2H_MSG_TYPE_PEER_MAP2:
- vdev_id = le32_get_bits(resp->peer_map_ev.info,
- HTT_T2H_PEER_MAP_INFO_VDEV_ID);
- peer_id = le32_get_bits(resp->peer_map_ev.info,
- HTT_T2H_PEER_MAP_INFO_PEER_ID);
- peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1,
- HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16);
- ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32),
- peer_mac_h16, mac_addr);
- ast_hash = le32_get_bits(resp->peer_map_ev.info2,
- HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL);
- hw_peer_id = le32_get_bits(resp->peer_map_ev.info1,
- HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID);
- ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash,
- hw_peer_id);
- break;
- case HTT_T2H_MSG_TYPE_PEER_MAP3:
- vdev_id = le32_get_bits(resp->peer_map_ev.info,
- HTT_T2H_PEER_MAP_INFO_VDEV_ID);
- peer_id = le32_get_bits(resp->peer_map_ev.info,
- HTT_T2H_PEER_MAP_INFO_PEER_ID);
- peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1,
- HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16);
- ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32),
- peer_mac_h16, mac_addr);
- ast_hash = le32_get_bits(resp->peer_map_ev.info2,
- HTT_T2H_PEER_MAP3_INFO2_AST_HASH_VAL);
- hw_peer_id = le32_get_bits(resp->peer_map_ev.info2,
- HTT_T2H_PEER_MAP3_INFO2_HW_PEER_ID);
- ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash,
- hw_peer_id);
- break;
- case HTT_T2H_MSG_TYPE_PEER_UNMAP:
- case HTT_T2H_MSG_TYPE_PEER_UNMAP2:
- peer_id = le32_get_bits(resp->peer_unmap_ev.info,
- HTT_T2H_PEER_UNMAP_INFO_PEER_ID);
- ath12k_peer_unmap_event(ab, peer_id);
- break;
- case HTT_T2H_MSG_TYPE_PPDU_STATS_IND:
- ath12k_htt_pull_ppdu_stats(ab, skb);
- break;
- case HTT_T2H_MSG_TYPE_EXT_STATS_CONF:
- ath12k_debugfs_htt_ext_stats_handler(ab, skb);
- break;
- case HTT_T2H_MSG_TYPE_MLO_TIMESTAMP_OFFSET_IND:
- ath12k_htt_mlo_offset_event_handler(ab, skb);
- break;
- default:
- ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt event %d not handled\n",
- type);
- break;
- }
-
- dev_kfree_skb_any(skb);
-}
-EXPORT_SYMBOL(ath12k_dp_htt_htc_t2h_msg_handler);
-
struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list,
struct sk_buff *first)
{
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h
index 7bf70cef4365..6f56a56db097 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.h
@@ -384,8 +384,6 @@ void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar,
int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id,
u8 tid, u32 ba_win_sz, u16 ssn,
enum hal_pn_type pn_type);
-void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab,
- struct sk_buff *skb);
int ath12k_dp_rx_pdev_reo_setup(struct ath12k_base *ab);
void ath12k_dp_rx_pdev_reo_cleanup(struct ath12k_base *ab);
int ath12k_dp_rx_htt_setup(struct ath12k_base *ab);
@@ -410,10 +408,6 @@ u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab,
struct hal_rx_desc *desc);
u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab,
struct hal_rx_desc *desc);
-int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len,
- int (*iter)(struct ath12k_base *ar, u16 tag, u16 len,
- const void *ptr, void *data),
- void *data);
void ath12k_dp_rx_h_fetch_info(struct ath12k_base *ab, struct hal_rx_desc *rx_desc,
struct ath12k_dp_rx_info *rx_info);
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 19/20] wifi: ath12k: Move HTT Tx specific code to newly introduced files
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (17 preceding siblings ...)
2025-08-28 17:35 ` [PATCH ath12k-ng 18/20] wifi: ath12k: Move HTT Rx specific code " Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 20/20] wifi: ath12k: Move HTT specific code from dp.c " Ripan Deuri
` (3 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Harsh Kumar Bijlani <quic_hbijlani@quicinc.com>
WLAN Host driver interacts with the Firmware and vice versa using
Host-To-Target (HTT) interface.
Relocate HTT specific code from dp_tx.c to dp_htt.c introduced for
HTT interface. These code is compiled as part of the common module
ath12k.ko.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Harsh Kumar Bijlani <quic_hbijlani@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/dp.h | 2 -
drivers/net/wireless/ath/ath12k/dp_htt.c | 683 +++++++++++++++++++++++
drivers/net/wireless/ath/ath12k/dp_htt.h | 24 +-
drivers/net/wireless/ath/ath12k/dp_tx.c | 682 ----------------------
drivers/net/wireless/ath/ath12k/dp_tx.h | 18 -
5 files changed, 705 insertions(+), 704 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index 45d569e19534..ad93e63e3344 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -441,8 +441,6 @@ void ath12k_dp_partner_cc_init(struct ath12k_base *ab);
int ath12k_dp_pdev_alloc(struct ath12k_base *ab);
void ath12k_dp_pdev_pre_alloc(struct ath12k *ar);
void ath12k_dp_pdev_free(struct ath12k_base *ab);
-int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id,
- int mac_id, enum hal_ring_type ring_type);
int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr);
void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr);
void ath12k_dp_srng_cleanup(struct ath12k_base *ab, struct dp_srng *ring);
diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c
index 00847d579b95..45aa8ae86a14 100644
--- a/drivers/net/wireless/ath/ath12k/dp_htt.c
+++ b/drivers/net/wireless/ath/ath12k/dp_htt.c
@@ -9,6 +9,7 @@
#include "htc.h"
#include "dp_htt.h"
#include "debugfs_htt_stats.h"
+#include "debugfs.h"
static int ath12k_get_ppdu_user_index(struct htt_ppdu_stats *ppdu_stats,
u16 peer_id)
@@ -642,3 +643,685 @@ void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab,
dev_kfree_skb_any(skb);
}
EXPORT_SYMBOL(ath12k_dp_htt_htc_t2h_msg_handler);
+
+static int
+ath12k_dp_tx_get_ring_id_type(struct ath12k_base *ab,
+ int mac_id, u32 ring_id,
+ enum hal_ring_type ring_type,
+ enum htt_srng_ring_type *htt_ring_type,
+ enum htt_srng_ring_id *htt_ring_id)
+{
+ int ret = 0;
+
+ switch (ring_type) {
+ case HAL_RXDMA_BUF:
+ /* for some targets, host fills rx buffer to fw and fw fills to
+ * rxbuf ring for each rxdma
+ */
+ if (!ab->hw_params->rx_mac_buf_ring) {
+ if (!(ring_id == HAL_SRNG_SW2RXDMA_BUF0 ||
+ ring_id == HAL_SRNG_SW2RXDMA_BUF1)) {
+ ret = -EINVAL;
+ }
+ *htt_ring_id = HTT_RXDMA_HOST_BUF_RING;
+ *htt_ring_type = HTT_SW_TO_HW_RING;
+ } else {
+ if (ring_id == HAL_SRNG_SW2RXDMA_BUF0) {
+ *htt_ring_id = HTT_HOST1_TO_FW_RXBUF_RING;
+ *htt_ring_type = HTT_SW_TO_SW_RING;
+ } else {
+ *htt_ring_id = HTT_RXDMA_HOST_BUF_RING;
+ *htt_ring_type = HTT_SW_TO_HW_RING;
+ }
+ }
+ break;
+ case HAL_RXDMA_DST:
+ *htt_ring_id = HTT_RXDMA_NON_MONITOR_DEST_RING;
+ *htt_ring_type = HTT_HW_TO_SW_RING;
+ break;
+ case HAL_RXDMA_MONITOR_BUF:
+ *htt_ring_id = HTT_RX_MON_HOST2MON_BUF_RING;
+ *htt_ring_type = HTT_SW_TO_HW_RING;
+ break;
+ case HAL_RXDMA_MONITOR_STATUS:
+ *htt_ring_id = HTT_RXDMA_MONITOR_STATUS_RING;
+ *htt_ring_type = HTT_SW_TO_HW_RING;
+ break;
+ case HAL_RXDMA_MONITOR_DST:
+ *htt_ring_id = HTT_RX_MON_MON2HOST_DEST_RING;
+ *htt_ring_type = HTT_HW_TO_SW_RING;
+ break;
+ case HAL_RXDMA_MONITOR_DESC:
+ *htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING;
+ *htt_ring_type = HTT_SW_TO_HW_RING;
+ break;
+ default:
+ ath12k_warn(ab, "Unsupported ring type in DP :%d\n", ring_type);
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id,
+ int mac_id, enum hal_ring_type ring_type)
+{
+ struct htt_srng_setup_cmd *cmd;
+ struct hal_srng *srng = &ab->hal.srng_list[ring_id];
+ struct hal_srng_params params;
+ struct sk_buff *skb;
+ u32 ring_entry_sz;
+ int len = sizeof(*cmd);
+ dma_addr_t hp_addr, tp_addr;
+ enum htt_srng_ring_type htt_ring_type;
+ enum htt_srng_ring_id htt_ring_id;
+ int ret;
+
+ skb = ath12k_htc_alloc_skb(ab, len);
+ if (!skb)
+ return -ENOMEM;
+
+ memset(¶ms, 0, sizeof(params));
+ ath12k_hal_srng_get_params(ab, srng, ¶ms);
+
+ hp_addr = ath12k_hal_srng_get_hp_addr(ab, srng);
+ tp_addr = ath12k_hal_srng_get_tp_addr(ab, srng);
+
+ ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id,
+ ring_type, &htt_ring_type,
+ &htt_ring_id);
+ if (ret)
+ goto err_free;
+
+ skb_put(skb, len);
+ cmd = (struct htt_srng_setup_cmd *)skb->data;
+ cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_SRING_SETUP,
+ HTT_SRNG_SETUP_CMD_INFO0_MSG_TYPE);
+ if (htt_ring_type == HTT_SW_TO_HW_RING ||
+ htt_ring_type == HTT_HW_TO_SW_RING)
+ cmd->info0 |= le32_encode_bits(DP_SW2HW_MACID(mac_id),
+ HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID);
+ else
+ cmd->info0 |= le32_encode_bits(mac_id,
+ HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID);
+ cmd->info0 |= le32_encode_bits(htt_ring_type,
+ HTT_SRNG_SETUP_CMD_INFO0_RING_TYPE);
+ cmd->info0 |= le32_encode_bits(htt_ring_id,
+ HTT_SRNG_SETUP_CMD_INFO0_RING_ID);
+
+ cmd->ring_base_addr_lo = cpu_to_le32(params.ring_base_paddr &
+ HAL_ADDR_LSB_REG_MASK);
+
+ cmd->ring_base_addr_hi = cpu_to_le32((u64)params.ring_base_paddr >>
+ HAL_ADDR_MSB_REG_SHIFT);
+
+ ret = ath12k_hal_srng_get_entrysize(ab, ring_type);
+ if (ret < 0)
+ goto err_free;
+
+ ring_entry_sz = ret;
+
+ ring_entry_sz >>= 2;
+ cmd->info1 = le32_encode_bits(ring_entry_sz,
+ HTT_SRNG_SETUP_CMD_INFO1_RING_ENTRY_SIZE);
+ cmd->info1 |= le32_encode_bits(params.num_entries * ring_entry_sz,
+ HTT_SRNG_SETUP_CMD_INFO1_RING_SIZE);
+ cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP),
+ HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_MSI_SWAP);
+ cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP),
+ HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_TLV_SWAP);
+ cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_RING_PTR_SWAP),
+ HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_HOST_FW_SWAP);
+ if (htt_ring_type == HTT_SW_TO_HW_RING)
+ cmd->info1 |= cpu_to_le32(HTT_SRNG_SETUP_CMD_INFO1_RING_LOOP_CNT_DIS);
+
+ cmd->ring_head_off32_remote_addr_lo = cpu_to_le32(lower_32_bits(hp_addr));
+ cmd->ring_head_off32_remote_addr_hi = cpu_to_le32(upper_32_bits(hp_addr));
+
+ cmd->ring_tail_off32_remote_addr_lo = cpu_to_le32(lower_32_bits(tp_addr));
+ cmd->ring_tail_off32_remote_addr_hi = cpu_to_le32(upper_32_bits(tp_addr));
+
+ cmd->ring_msi_addr_lo = cpu_to_le32(lower_32_bits(params.msi_addr));
+ cmd->ring_msi_addr_hi = cpu_to_le32(upper_32_bits(params.msi_addr));
+ cmd->msi_data = cpu_to_le32(params.msi_data);
+
+ cmd->intr_info =
+ le32_encode_bits(params.intr_batch_cntr_thres_entries * ring_entry_sz,
+ HTT_SRNG_SETUP_CMD_INTR_INFO_BATCH_COUNTER_THRESH);
+ cmd->intr_info |=
+ le32_encode_bits(params.intr_timer_thres_us >> 3,
+ HTT_SRNG_SETUP_CMD_INTR_INFO_INTR_TIMER_THRESH);
+
+ cmd->info2 = 0;
+ if (params.flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) {
+ cmd->info2 = le32_encode_bits(params.low_threshold,
+ HTT_SRNG_SETUP_CMD_INFO2_INTR_LOW_THRESH);
+ }
+
+ ath12k_dbg(ab, ATH12K_DBG_HAL,
+ "%s msi_addr_lo:0x%x, msi_addr_hi:0x%x, msi_data:0x%x\n",
+ __func__, cmd->ring_msi_addr_lo, cmd->ring_msi_addr_hi,
+ cmd->msi_data);
+
+ ath12k_dbg(ab, ATH12K_DBG_HAL,
+ "ring_id:%d, ring_type:%d, intr_info:0x%x, flags:0x%x\n",
+ ring_id, ring_type, cmd->intr_info, cmd->info2);
+
+ ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb);
+ if (ret)
+ goto err_free;
+
+ return 0;
+
+err_free:
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+
+#define HTT_TARGET_VERSION_TIMEOUT_HZ (3 * HZ)
+
+int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab)
+{
+ struct ath12k_dp *dp = &ab->dp;
+ struct sk_buff *skb;
+ struct htt_ver_req_cmd *cmd;
+ int len = sizeof(*cmd);
+ u32 metadata_version;
+ int ret;
+
+ init_completion(&dp->htt_tgt_version_received);
+
+ skb = ath12k_htc_alloc_skb(ab, len);
+ if (!skb)
+ return -ENOMEM;
+
+ skb_put(skb, len);
+ cmd = (struct htt_ver_req_cmd *)skb->data;
+ cmd->ver_reg_info = le32_encode_bits(HTT_H2T_MSG_TYPE_VERSION_REQ,
+ HTT_OPTION_TAG);
+ metadata_version = ath12k_ftm_mode ? HTT_OPTION_TCL_METADATA_VER_V1 :
+ HTT_OPTION_TCL_METADATA_VER_V2;
+
+ cmd->tcl_metadata_version = le32_encode_bits(HTT_TAG_TCL_METADATA_VERSION,
+ HTT_OPTION_TAG) |
+ le32_encode_bits(HTT_TCL_METADATA_VER_SZ,
+ HTT_OPTION_LEN) |
+ le32_encode_bits(metadata_version,
+ HTT_OPTION_VALUE);
+
+ ret = ath12k_htc_send(&ab->htc, dp->eid, skb);
+ if (ret) {
+ dev_kfree_skb_any(skb);
+ return ret;
+ }
+
+ ret = wait_for_completion_timeout(&dp->htt_tgt_version_received,
+ HTT_TARGET_VERSION_TIMEOUT_HZ);
+ if (ret == 0) {
+ ath12k_warn(ab, "htt target version request timed out\n");
+ return -ETIMEDOUT;
+ }
+
+ if (dp->htt_tgt_ver_major != HTT_TARGET_VERSION_MAJOR) {
+ ath12k_err(ab, "unsupported htt major version %d supported version is %d\n",
+ dp->htt_tgt_ver_major, HTT_TARGET_VERSION_MAJOR);
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask)
+{
+ struct ath12k_base *ab = ar->ab;
+ struct ath12k_dp *dp = &ab->dp;
+ struct sk_buff *skb;
+ struct htt_ppdu_stats_cfg_cmd *cmd;
+ int len = sizeof(*cmd);
+ u8 pdev_mask;
+ int ret;
+ int i;
+
+ for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
+ skb = ath12k_htc_alloc_skb(ab, len);
+ if (!skb)
+ return -ENOMEM;
+
+ skb_put(skb, len);
+ cmd = (struct htt_ppdu_stats_cfg_cmd *)skb->data;
+ cmd->msg = le32_encode_bits(HTT_H2T_MSG_TYPE_PPDU_STATS_CFG,
+ HTT_PPDU_STATS_CFG_MSG_TYPE);
+
+ pdev_mask = 1 << (i + ar->pdev_idx);
+ cmd->msg |= le32_encode_bits(pdev_mask, HTT_PPDU_STATS_CFG_PDEV_ID);
+ cmd->msg |= le32_encode_bits(mask, HTT_PPDU_STATS_CFG_TLV_TYPE_BITMASK);
+
+ ret = ath12k_htc_send(&ab->htc, dp->eid, skb);
+ if (ret) {
+ dev_kfree_skb_any(skb);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id,
+ int mac_id, enum hal_ring_type ring_type,
+ int rx_buf_size,
+ struct htt_rx_ring_tlv_filter *tlv_filter)
+{
+ struct htt_rx_ring_selection_cfg_cmd *cmd;
+ struct hal_srng *srng = &ab->hal.srng_list[ring_id];
+ struct hal_srng_params params;
+ struct sk_buff *skb;
+ int len = sizeof(*cmd);
+ enum htt_srng_ring_type htt_ring_type;
+ enum htt_srng_ring_id htt_ring_id;
+ int ret;
+
+ skb = ath12k_htc_alloc_skb(ab, len);
+ if (!skb)
+ return -ENOMEM;
+
+ memset(¶ms, 0, sizeof(params));
+ ath12k_hal_srng_get_params(ab, srng, ¶ms);
+
+ ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id,
+ ring_type, &htt_ring_type,
+ &htt_ring_id);
+ if (ret)
+ goto err_free;
+
+ skb_put(skb, len);
+ cmd = (struct htt_rx_ring_selection_cfg_cmd *)skb->data;
+ cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG,
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE);
+ if (htt_ring_type == HTT_SW_TO_HW_RING ||
+ htt_ring_type == HTT_HW_TO_SW_RING)
+ cmd->info0 |=
+ le32_encode_bits(DP_SW2HW_MACID(mac_id),
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID);
+ else
+ cmd->info0 |=
+ le32_encode_bits(mac_id,
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID);
+ cmd->info0 |= le32_encode_bits(htt_ring_id,
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO0_RING_ID);
+ cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP),
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO0_SS);
+ cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP),
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS);
+ cmd->info0 |= le32_encode_bits(tlv_filter->offset_valid,
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO0_OFFSET_VALID);
+ cmd->info0 |=
+ le32_encode_bits(tlv_filter->drop_threshold_valid,
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO0_DROP_THRES_VAL);
+ cmd->info0 |= le32_encode_bits(!tlv_filter->rxmon_disable,
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO0_EN_RXMON);
+
+ cmd->info1 = le32_encode_bits(rx_buf_size,
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE);
+ cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_mgmt,
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT);
+ cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_ctrl,
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL);
+ cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_data,
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA);
+ cmd->pkt_type_en_flags0 = cpu_to_le32(tlv_filter->pkt_filter_flags0);
+ cmd->pkt_type_en_flags1 = cpu_to_le32(tlv_filter->pkt_filter_flags1);
+ cmd->pkt_type_en_flags2 = cpu_to_le32(tlv_filter->pkt_filter_flags2);
+ cmd->pkt_type_en_flags3 = cpu_to_le32(tlv_filter->pkt_filter_flags3);
+ cmd->rx_filter_tlv = cpu_to_le32(tlv_filter->rx_filter);
+
+ cmd->info2 = le32_encode_bits(tlv_filter->rx_drop_threshold,
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO2_DROP_THRESHOLD);
+ cmd->info2 |=
+ le32_encode_bits(tlv_filter->enable_log_mgmt_type,
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_MGMT_TYPE);
+ cmd->info2 |=
+ le32_encode_bits(tlv_filter->enable_log_ctrl_type,
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_CTRL_TYPE);
+ cmd->info2 |=
+ le32_encode_bits(tlv_filter->enable_log_data_type,
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_DATA_TYPE);
+
+ cmd->info3 =
+ le32_encode_bits(tlv_filter->enable_rx_tlv_offset,
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO3_EN_TLV_PKT_OFFSET);
+ cmd->info3 |=
+ le32_encode_bits(tlv_filter->rx_tlv_offset,
+ HTT_RX_RING_SELECTION_CFG_CMD_INFO3_PKT_TLV_OFFSET);
+
+ if (tlv_filter->offset_valid) {
+ cmd->rx_packet_offset =
+ le32_encode_bits(tlv_filter->rx_packet_offset,
+ HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET);
+
+ cmd->rx_packet_offset |=
+ le32_encode_bits(tlv_filter->rx_header_offset,
+ HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET);
+
+ cmd->rx_mpdu_offset =
+ le32_encode_bits(tlv_filter->rx_mpdu_end_offset,
+ HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET);
+
+ cmd->rx_mpdu_offset |=
+ le32_encode_bits(tlv_filter->rx_mpdu_start_offset,
+ HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET);
+
+ cmd->rx_msdu_offset =
+ le32_encode_bits(tlv_filter->rx_msdu_end_offset,
+ HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET);
+
+ cmd->rx_msdu_offset |=
+ le32_encode_bits(tlv_filter->rx_msdu_start_offset,
+ HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET);
+
+ cmd->rx_attn_offset =
+ le32_encode_bits(tlv_filter->rx_attn_offset,
+ HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET);
+ }
+
+ if (tlv_filter->rx_mpdu_start_wmask > 0 &&
+ tlv_filter->rx_msdu_end_wmask > 0) {
+ cmd->info2 |=
+ le32_encode_bits(true,
+ HTT_RX_RING_SELECTION_CFG_WORD_MASK_COMPACT_SET);
+ cmd->rx_mpdu_start_end_mask =
+ le32_encode_bits(tlv_filter->rx_mpdu_start_wmask,
+ HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_MASK);
+ /* mpdu_end is not used for any hardwares so far
+ * please assign it in future if any chip is
+ * using through hal ops
+ */
+ cmd->rx_mpdu_start_end_mask |=
+ le32_encode_bits(tlv_filter->rx_mpdu_end_wmask,
+ HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_MASK);
+ cmd->rx_msdu_end_word_mask =
+ le32_encode_bits(tlv_filter->rx_msdu_end_wmask,
+ HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_MASK);
+ }
+
+ ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb);
+ if (ret)
+ goto err_free;
+
+ return 0;
+
+err_free:
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+
+int
+ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type,
+ struct htt_ext_stats_cfg_params *cfg_params,
+ u64 cookie)
+{
+ struct ath12k_base *ab = ar->ab;
+ struct ath12k_dp *dp = &ab->dp;
+ struct sk_buff *skb;
+ struct htt_ext_stats_cfg_cmd *cmd;
+ int len = sizeof(*cmd);
+ int ret;
+ u32 pdev_id;
+
+ skb = ath12k_htc_alloc_skb(ab, len);
+ if (!skb)
+ return -ENOMEM;
+
+ skb_put(skb, len);
+
+ cmd = (struct htt_ext_stats_cfg_cmd *)skb->data;
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_EXT_STATS_CFG;
+
+ pdev_id = ath12k_mac_get_target_pdev_id(ar);
+ cmd->hdr.pdev_mask = 1 << pdev_id;
+
+ cmd->hdr.stats_type = type;
+ cmd->cfg_param0 = cpu_to_le32(cfg_params->cfg0);
+ cmd->cfg_param1 = cpu_to_le32(cfg_params->cfg1);
+ cmd->cfg_param2 = cpu_to_le32(cfg_params->cfg2);
+ cmd->cfg_param3 = cpu_to_le32(cfg_params->cfg3);
+ cmd->cookie_lsb = cpu_to_le32(lower_32_bits(cookie));
+ cmd->cookie_msb = cpu_to_le32(upper_32_bits(cookie));
+
+ ret = ath12k_htc_send(&ab->htc, dp->eid, skb);
+ if (ret) {
+ ath12k_warn(ab, "failed to send htt type stats request: %d",
+ ret);
+ dev_kfree_skb_any(skb);
+ return ret;
+ }
+
+ return 0;
+}
+
+int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset)
+{
+ struct ath12k_base *ab = ar->ab;
+ int ret;
+
+ ret = ath12k_dp_tx_htt_rx_monitor_mode_ring_config(ar, reset);
+ if (ret) {
+ ath12k_err(ab, "failed to setup rx monitor filter %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset)
+{
+ struct ath12k_base *ab = ar->ab;
+ struct htt_rx_ring_tlv_filter tlv_filter = {};
+ int ret, ring_id, i;
+
+ tlv_filter.offset_valid = false;
+
+ if (!reset) {
+ tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_DEST_RING;
+
+ tlv_filter.drop_threshold_valid = true;
+ tlv_filter.rx_drop_threshold = HTT_RX_RING_TLV_DROP_THRESHOLD_VALUE;
+
+ tlv_filter.enable_log_mgmt_type = true;
+ tlv_filter.enable_log_ctrl_type = true;
+ tlv_filter.enable_log_data_type = true;
+
+ tlv_filter.conf_len_ctrl = HTT_RX_RING_DEFAULT_DMA_LENGTH;
+ tlv_filter.conf_len_mgmt = HTT_RX_RING_DEFAULT_DMA_LENGTH;
+ tlv_filter.conf_len_data = HTT_RX_RING_DEFAULT_DMA_LENGTH;
+
+ tlv_filter.enable_rx_tlv_offset = true;
+ tlv_filter.rx_tlv_offset = HTT_RX_RING_PKT_TLV_OFFSET;
+
+ tlv_filter.pkt_filter_flags0 =
+ HTT_RX_MON_FP_MGMT_FILTER_FLAGS0 |
+ HTT_RX_MON_MO_MGMT_FILTER_FLAGS0;
+ tlv_filter.pkt_filter_flags1 =
+ HTT_RX_MON_FP_MGMT_FILTER_FLAGS1 |
+ HTT_RX_MON_MO_MGMT_FILTER_FLAGS1;
+ tlv_filter.pkt_filter_flags2 =
+ HTT_RX_MON_FP_CTRL_FILTER_FLASG2 |
+ HTT_RX_MON_MO_CTRL_FILTER_FLASG2;
+ tlv_filter.pkt_filter_flags3 =
+ HTT_RX_MON_FP_CTRL_FILTER_FLASG3 |
+ HTT_RX_MON_MO_CTRL_FILTER_FLASG3 |
+ HTT_RX_MON_FP_DATA_FILTER_FLASG3 |
+ HTT_RX_MON_MO_DATA_FILTER_FLASG3;
+ } else {
+ tlv_filter = ath12k_mac_mon_status_filter_default;
+
+ if (ath12k_debugfs_is_extd_rx_stats_enabled(ar))
+ tlv_filter.rx_filter = ath12k_debugfs_rx_filter(ar);
+ }
+
+ if (ab->hw_params->rxdma1_enable) {
+ for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
+ ring_id = ar->dp.rxdma_mon_dst_ring[i].ring_id;
+ ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id,
+ ar->dp.mac_id + i,
+ HAL_RXDMA_MONITOR_DST,
+ DP_RXDMA_REFILL_RING_SIZE,
+ &tlv_filter);
+ if (ret) {
+ ath12k_err(ab,
+ "failed to setup filter for monitor buf %d\n",
+ ret);
+ return ret;
+ }
+ }
+ return 0;
+ }
+
+ if (!reset) {
+ for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
+ ring_id = ab->dp.rx_mac_buf_ring[i].ring_id;
+ ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id,
+ i,
+ HAL_RXDMA_BUF,
+ DP_RXDMA_REFILL_RING_SIZE,
+ &tlv_filter);
+ if (ret) {
+ ath12k_err(ab,
+ "failed to setup filter for mon rx buf %d\n",
+ ret);
+ return ret;
+ }
+ }
+ }
+
+ for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
+ ring_id = ab->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
+ if (!reset) {
+ tlv_filter.rx_filter =
+ HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING;
+ }
+
+ ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id,
+ i,
+ HAL_RXDMA_MONITOR_STATUS,
+ RX_MON_STATUS_BUF_SIZE,
+ &tlv_filter);
+ if (ret) {
+ ath12k_err(ab,
+ "failed to setup filter for mon status buf %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id,
+ int mac_id, enum hal_ring_type ring_type,
+ int tx_buf_size,
+ struct htt_tx_ring_tlv_filter *htt_tlv_filter)
+{
+ struct htt_tx_ring_selection_cfg_cmd *cmd;
+ struct hal_srng *srng = &ab->hal.srng_list[ring_id];
+ struct hal_srng_params params;
+ struct sk_buff *skb;
+ int len = sizeof(*cmd);
+ enum htt_srng_ring_type htt_ring_type;
+ enum htt_srng_ring_id htt_ring_id;
+ int ret;
+
+ skb = ath12k_htc_alloc_skb(ab, len);
+ if (!skb)
+ return -ENOMEM;
+
+ memset(¶ms, 0, sizeof(params));
+ ath12k_hal_srng_get_params(ab, srng, ¶ms);
+
+ ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id,
+ ring_type, &htt_ring_type,
+ &htt_ring_id);
+
+ if (ret)
+ goto err_free;
+
+ skb_put(skb, len);
+ cmd = (struct htt_tx_ring_selection_cfg_cmd *)skb->data;
+ cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_TX_MONITOR_CFG,
+ HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE);
+ if (htt_ring_type == HTT_SW_TO_HW_RING ||
+ htt_ring_type == HTT_HW_TO_SW_RING)
+ cmd->info0 |=
+ le32_encode_bits(DP_SW2HW_MACID(mac_id),
+ HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID);
+ else
+ cmd->info0 |=
+ le32_encode_bits(mac_id,
+ HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID);
+ cmd->info0 |= le32_encode_bits(htt_ring_id,
+ HTT_TX_RING_SELECTION_CFG_CMD_INFO0_RING_ID);
+ cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP),
+ HTT_TX_RING_SELECTION_CFG_CMD_INFO0_SS);
+ cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP),
+ HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PS);
+
+ cmd->info1 |=
+ le32_encode_bits(tx_buf_size,
+ HTT_TX_RING_SELECTION_CFG_CMD_INFO1_RING_BUFF_SIZE);
+
+ if (htt_tlv_filter->tx_mon_mgmt_filter) {
+ cmd->info1 |=
+ le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_MGMT,
+ HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE);
+ cmd->info1 |=
+ le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len,
+ HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT);
+ cmd->info2 |=
+ le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_MGMT,
+ HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG);
+ }
+
+ if (htt_tlv_filter->tx_mon_data_filter) {
+ cmd->info1 |=
+ le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_CTRL,
+ HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE);
+ cmd->info1 |=
+ le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len,
+ HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL);
+ cmd->info2 |=
+ le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_CTRL,
+ HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG);
+ }
+
+ if (htt_tlv_filter->tx_mon_ctrl_filter) {
+ cmd->info1 |=
+ le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_DATA,
+ HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE);
+ cmd->info1 |=
+ le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len,
+ HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA);
+ cmd->info2 |=
+ le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_DATA,
+ HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG);
+ }
+
+ cmd->tlv_filter_mask_in0 =
+ cpu_to_le32(htt_tlv_filter->tx_mon_downstream_tlv_flags);
+ cmd->tlv_filter_mask_in1 =
+ cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags0);
+ cmd->tlv_filter_mask_in2 =
+ cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags1);
+ cmd->tlv_filter_mask_in3 =
+ cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags2);
+
+ ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb);
+ if (ret)
+ goto err_free;
+
+ return 0;
+
+err_free:
+ dev_kfree_skb_any(skb);
+ return ret;
+}
diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.h b/drivers/net/wireless/ath/ath12k/dp_htt.h
index 9ae3a750f608..b13af1c69253 100644
--- a/drivers/net/wireless/ath/ath12k/dp_htt.h
+++ b/drivers/net/wireless/ath/ath12k/dp_htt.h
@@ -1514,10 +1514,30 @@ struct htt_mac_addr {
__le32 mac_addr_h16;
} __packed;
+int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id,
+ int mac_id, enum hal_ring_type ring_type);
+
+void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab,
+ struct sk_buff *skb);
int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len,
int (*iter)(struct ath12k_base *ar, u16 tag, u16 len,
const void *ptr, void *data),
void *data);
-void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab,
- struct sk_buff *skb);
+int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab);
+int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask);
+int
+ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type,
+ struct htt_ext_stats_cfg_params *cfg_params,
+ u64 cookie);
+int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset);
+
+int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id,
+ int mac_id, enum hal_ring_type ring_type,
+ int rx_buf_size,
+ struct htt_rx_ring_tlv_filter *tlv_filter);
+int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id,
+ int mac_id, enum hal_ring_type ring_type,
+ int tx_buf_size,
+ struct htt_tx_ring_tlv_filter *htt_tlv_filter);
+int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset);
#endif
diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c
index c7b0fc22c1a7..8d5e10781377 100644
--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
@@ -200,685 +200,3 @@ void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab,
if (atomic_dec_and_test(&ar->dp.num_tx_pending))
wake_up(&ar->dp.tx_empty_waitq);
}
-
-static int
-ath12k_dp_tx_get_ring_id_type(struct ath12k_base *ab,
- int mac_id, u32 ring_id,
- enum hal_ring_type ring_type,
- enum htt_srng_ring_type *htt_ring_type,
- enum htt_srng_ring_id *htt_ring_id)
-{
- int ret = 0;
-
- switch (ring_type) {
- case HAL_RXDMA_BUF:
- /* for some targets, host fills rx buffer to fw and fw fills to
- * rxbuf ring for each rxdma
- */
- if (!ab->hw_params->rx_mac_buf_ring) {
- if (!(ring_id == HAL_SRNG_SW2RXDMA_BUF0 ||
- ring_id == HAL_SRNG_SW2RXDMA_BUF1)) {
- ret = -EINVAL;
- }
- *htt_ring_id = HTT_RXDMA_HOST_BUF_RING;
- *htt_ring_type = HTT_SW_TO_HW_RING;
- } else {
- if (ring_id == HAL_SRNG_SW2RXDMA_BUF0) {
- *htt_ring_id = HTT_HOST1_TO_FW_RXBUF_RING;
- *htt_ring_type = HTT_SW_TO_SW_RING;
- } else {
- *htt_ring_id = HTT_RXDMA_HOST_BUF_RING;
- *htt_ring_type = HTT_SW_TO_HW_RING;
- }
- }
- break;
- case HAL_RXDMA_DST:
- *htt_ring_id = HTT_RXDMA_NON_MONITOR_DEST_RING;
- *htt_ring_type = HTT_HW_TO_SW_RING;
- break;
- case HAL_RXDMA_MONITOR_BUF:
- *htt_ring_id = HTT_RX_MON_HOST2MON_BUF_RING;
- *htt_ring_type = HTT_SW_TO_HW_RING;
- break;
- case HAL_RXDMA_MONITOR_STATUS:
- *htt_ring_id = HTT_RXDMA_MONITOR_STATUS_RING;
- *htt_ring_type = HTT_SW_TO_HW_RING;
- break;
- case HAL_RXDMA_MONITOR_DST:
- *htt_ring_id = HTT_RX_MON_MON2HOST_DEST_RING;
- *htt_ring_type = HTT_HW_TO_SW_RING;
- break;
- case HAL_RXDMA_MONITOR_DESC:
- *htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING;
- *htt_ring_type = HTT_SW_TO_HW_RING;
- break;
- default:
- ath12k_warn(ab, "Unsupported ring type in DP :%d\n", ring_type);
- ret = -EINVAL;
- }
- return ret;
-}
-
-int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id,
- int mac_id, enum hal_ring_type ring_type)
-{
- struct htt_srng_setup_cmd *cmd;
- struct hal_srng *srng = &ab->hal.srng_list[ring_id];
- struct hal_srng_params params;
- struct sk_buff *skb;
- u32 ring_entry_sz;
- int len = sizeof(*cmd);
- dma_addr_t hp_addr, tp_addr;
- enum htt_srng_ring_type htt_ring_type;
- enum htt_srng_ring_id htt_ring_id;
- int ret;
-
- skb = ath12k_htc_alloc_skb(ab, len);
- if (!skb)
- return -ENOMEM;
-
- memset(¶ms, 0, sizeof(params));
- ath12k_hal_srng_get_params(ab, srng, ¶ms);
-
- hp_addr = ath12k_hal_srng_get_hp_addr(ab, srng);
- tp_addr = ath12k_hal_srng_get_tp_addr(ab, srng);
-
- ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id,
- ring_type, &htt_ring_type,
- &htt_ring_id);
- if (ret)
- goto err_free;
-
- skb_put(skb, len);
- cmd = (struct htt_srng_setup_cmd *)skb->data;
- cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_SRING_SETUP,
- HTT_SRNG_SETUP_CMD_INFO0_MSG_TYPE);
- if (htt_ring_type == HTT_SW_TO_HW_RING ||
- htt_ring_type == HTT_HW_TO_SW_RING)
- cmd->info0 |= le32_encode_bits(DP_SW2HW_MACID(mac_id),
- HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID);
- else
- cmd->info0 |= le32_encode_bits(mac_id,
- HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID);
- cmd->info0 |= le32_encode_bits(htt_ring_type,
- HTT_SRNG_SETUP_CMD_INFO0_RING_TYPE);
- cmd->info0 |= le32_encode_bits(htt_ring_id,
- HTT_SRNG_SETUP_CMD_INFO0_RING_ID);
-
- cmd->ring_base_addr_lo = cpu_to_le32(params.ring_base_paddr &
- HAL_ADDR_LSB_REG_MASK);
-
- cmd->ring_base_addr_hi = cpu_to_le32((u64)params.ring_base_paddr >>
- HAL_ADDR_MSB_REG_SHIFT);
-
- ret = ath12k_hal_srng_get_entrysize(ab, ring_type);
- if (ret < 0)
- goto err_free;
-
- ring_entry_sz = ret;
-
- ring_entry_sz >>= 2;
- cmd->info1 = le32_encode_bits(ring_entry_sz,
- HTT_SRNG_SETUP_CMD_INFO1_RING_ENTRY_SIZE);
- cmd->info1 |= le32_encode_bits(params.num_entries * ring_entry_sz,
- HTT_SRNG_SETUP_CMD_INFO1_RING_SIZE);
- cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP),
- HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_MSI_SWAP);
- cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP),
- HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_TLV_SWAP);
- cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_RING_PTR_SWAP),
- HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_HOST_FW_SWAP);
- if (htt_ring_type == HTT_SW_TO_HW_RING)
- cmd->info1 |= cpu_to_le32(HTT_SRNG_SETUP_CMD_INFO1_RING_LOOP_CNT_DIS);
-
- cmd->ring_head_off32_remote_addr_lo = cpu_to_le32(lower_32_bits(hp_addr));
- cmd->ring_head_off32_remote_addr_hi = cpu_to_le32(upper_32_bits(hp_addr));
-
- cmd->ring_tail_off32_remote_addr_lo = cpu_to_le32(lower_32_bits(tp_addr));
- cmd->ring_tail_off32_remote_addr_hi = cpu_to_le32(upper_32_bits(tp_addr));
-
- cmd->ring_msi_addr_lo = cpu_to_le32(lower_32_bits(params.msi_addr));
- cmd->ring_msi_addr_hi = cpu_to_le32(upper_32_bits(params.msi_addr));
- cmd->msi_data = cpu_to_le32(params.msi_data);
-
- cmd->intr_info =
- le32_encode_bits(params.intr_batch_cntr_thres_entries * ring_entry_sz,
- HTT_SRNG_SETUP_CMD_INTR_INFO_BATCH_COUNTER_THRESH);
- cmd->intr_info |=
- le32_encode_bits(params.intr_timer_thres_us >> 3,
- HTT_SRNG_SETUP_CMD_INTR_INFO_INTR_TIMER_THRESH);
-
- cmd->info2 = 0;
- if (params.flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) {
- cmd->info2 = le32_encode_bits(params.low_threshold,
- HTT_SRNG_SETUP_CMD_INFO2_INTR_LOW_THRESH);
- }
-
- ath12k_dbg(ab, ATH12K_DBG_HAL,
- "%s msi_addr_lo:0x%x, msi_addr_hi:0x%x, msi_data:0x%x\n",
- __func__, cmd->ring_msi_addr_lo, cmd->ring_msi_addr_hi,
- cmd->msi_data);
-
- ath12k_dbg(ab, ATH12K_DBG_HAL,
- "ring_id:%d, ring_type:%d, intr_info:0x%x, flags:0x%x\n",
- ring_id, ring_type, cmd->intr_info, cmd->info2);
-
- ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb);
- if (ret)
- goto err_free;
-
- return 0;
-
-err_free:
- dev_kfree_skb_any(skb);
-
- return ret;
-}
-
-#define HTT_TARGET_VERSION_TIMEOUT_HZ (3 * HZ)
-
-int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab)
-{
- struct ath12k_dp *dp = &ab->dp;
- struct sk_buff *skb;
- struct htt_ver_req_cmd *cmd;
- int len = sizeof(*cmd);
- u32 metadata_version;
- int ret;
-
- init_completion(&dp->htt_tgt_version_received);
-
- skb = ath12k_htc_alloc_skb(ab, len);
- if (!skb)
- return -ENOMEM;
-
- skb_put(skb, len);
- cmd = (struct htt_ver_req_cmd *)skb->data;
- cmd->ver_reg_info = le32_encode_bits(HTT_H2T_MSG_TYPE_VERSION_REQ,
- HTT_OPTION_TAG);
- metadata_version = ath12k_ftm_mode ? HTT_OPTION_TCL_METADATA_VER_V1 :
- HTT_OPTION_TCL_METADATA_VER_V2;
-
- cmd->tcl_metadata_version = le32_encode_bits(HTT_TAG_TCL_METADATA_VERSION,
- HTT_OPTION_TAG) |
- le32_encode_bits(HTT_TCL_METADATA_VER_SZ,
- HTT_OPTION_LEN) |
- le32_encode_bits(metadata_version,
- HTT_OPTION_VALUE);
-
- ret = ath12k_htc_send(&ab->htc, dp->eid, skb);
- if (ret) {
- dev_kfree_skb_any(skb);
- return ret;
- }
-
- ret = wait_for_completion_timeout(&dp->htt_tgt_version_received,
- HTT_TARGET_VERSION_TIMEOUT_HZ);
- if (ret == 0) {
- ath12k_warn(ab, "htt target version request timed out\n");
- return -ETIMEDOUT;
- }
-
- if (dp->htt_tgt_ver_major != HTT_TARGET_VERSION_MAJOR) {
- ath12k_err(ab, "unsupported htt major version %d supported version is %d\n",
- dp->htt_tgt_ver_major, HTT_TARGET_VERSION_MAJOR);
- return -EOPNOTSUPP;
- }
-
- return 0;
-}
-
-int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask)
-{
- struct ath12k_base *ab = ar->ab;
- struct ath12k_dp *dp = &ab->dp;
- struct sk_buff *skb;
- struct htt_ppdu_stats_cfg_cmd *cmd;
- int len = sizeof(*cmd);
- u8 pdev_mask;
- int ret;
- int i;
-
- for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
- skb = ath12k_htc_alloc_skb(ab, len);
- if (!skb)
- return -ENOMEM;
-
- skb_put(skb, len);
- cmd = (struct htt_ppdu_stats_cfg_cmd *)skb->data;
- cmd->msg = le32_encode_bits(HTT_H2T_MSG_TYPE_PPDU_STATS_CFG,
- HTT_PPDU_STATS_CFG_MSG_TYPE);
-
- pdev_mask = 1 << (i + ar->pdev_idx);
- cmd->msg |= le32_encode_bits(pdev_mask, HTT_PPDU_STATS_CFG_PDEV_ID);
- cmd->msg |= le32_encode_bits(mask, HTT_PPDU_STATS_CFG_TLV_TYPE_BITMASK);
-
- ret = ath12k_htc_send(&ab->htc, dp->eid, skb);
- if (ret) {
- dev_kfree_skb_any(skb);
- return ret;
- }
- }
-
- return 0;
-}
-
-int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id,
- int mac_id, enum hal_ring_type ring_type,
- int rx_buf_size,
- struct htt_rx_ring_tlv_filter *tlv_filter)
-{
- struct htt_rx_ring_selection_cfg_cmd *cmd;
- struct hal_srng *srng = &ab->hal.srng_list[ring_id];
- struct hal_srng_params params;
- struct sk_buff *skb;
- int len = sizeof(*cmd);
- enum htt_srng_ring_type htt_ring_type;
- enum htt_srng_ring_id htt_ring_id;
- int ret;
-
- skb = ath12k_htc_alloc_skb(ab, len);
- if (!skb)
- return -ENOMEM;
-
- memset(¶ms, 0, sizeof(params));
- ath12k_hal_srng_get_params(ab, srng, ¶ms);
-
- ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id,
- ring_type, &htt_ring_type,
- &htt_ring_id);
- if (ret)
- goto err_free;
-
- skb_put(skb, len);
- cmd = (struct htt_rx_ring_selection_cfg_cmd *)skb->data;
- cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG,
- HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE);
- if (htt_ring_type == HTT_SW_TO_HW_RING ||
- htt_ring_type == HTT_HW_TO_SW_RING)
- cmd->info0 |=
- le32_encode_bits(DP_SW2HW_MACID(mac_id),
- HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID);
- else
- cmd->info0 |=
- le32_encode_bits(mac_id,
- HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID);
- cmd->info0 |= le32_encode_bits(htt_ring_id,
- HTT_RX_RING_SELECTION_CFG_CMD_INFO0_RING_ID);
- cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP),
- HTT_RX_RING_SELECTION_CFG_CMD_INFO0_SS);
- cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP),
- HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS);
- cmd->info0 |= le32_encode_bits(tlv_filter->offset_valid,
- HTT_RX_RING_SELECTION_CFG_CMD_INFO0_OFFSET_VALID);
- cmd->info0 |=
- le32_encode_bits(tlv_filter->drop_threshold_valid,
- HTT_RX_RING_SELECTION_CFG_CMD_INFO0_DROP_THRES_VAL);
- cmd->info0 |= le32_encode_bits(!tlv_filter->rxmon_disable,
- HTT_RX_RING_SELECTION_CFG_CMD_INFO0_EN_RXMON);
-
- cmd->info1 = le32_encode_bits(rx_buf_size,
- HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE);
- cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_mgmt,
- HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT);
- cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_ctrl,
- HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL);
- cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_data,
- HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA);
- cmd->pkt_type_en_flags0 = cpu_to_le32(tlv_filter->pkt_filter_flags0);
- cmd->pkt_type_en_flags1 = cpu_to_le32(tlv_filter->pkt_filter_flags1);
- cmd->pkt_type_en_flags2 = cpu_to_le32(tlv_filter->pkt_filter_flags2);
- cmd->pkt_type_en_flags3 = cpu_to_le32(tlv_filter->pkt_filter_flags3);
- cmd->rx_filter_tlv = cpu_to_le32(tlv_filter->rx_filter);
-
- cmd->info2 = le32_encode_bits(tlv_filter->rx_drop_threshold,
- HTT_RX_RING_SELECTION_CFG_CMD_INFO2_DROP_THRESHOLD);
- cmd->info2 |=
- le32_encode_bits(tlv_filter->enable_log_mgmt_type,
- HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_MGMT_TYPE);
- cmd->info2 |=
- le32_encode_bits(tlv_filter->enable_log_ctrl_type,
- HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_CTRL_TYPE);
- cmd->info2 |=
- le32_encode_bits(tlv_filter->enable_log_data_type,
- HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_DATA_TYPE);
-
- cmd->info3 =
- le32_encode_bits(tlv_filter->enable_rx_tlv_offset,
- HTT_RX_RING_SELECTION_CFG_CMD_INFO3_EN_TLV_PKT_OFFSET);
- cmd->info3 |=
- le32_encode_bits(tlv_filter->rx_tlv_offset,
- HTT_RX_RING_SELECTION_CFG_CMD_INFO3_PKT_TLV_OFFSET);
-
- if (tlv_filter->offset_valid) {
- cmd->rx_packet_offset =
- le32_encode_bits(tlv_filter->rx_packet_offset,
- HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET);
-
- cmd->rx_packet_offset |=
- le32_encode_bits(tlv_filter->rx_header_offset,
- HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET);
-
- cmd->rx_mpdu_offset =
- le32_encode_bits(tlv_filter->rx_mpdu_end_offset,
- HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET);
-
- cmd->rx_mpdu_offset |=
- le32_encode_bits(tlv_filter->rx_mpdu_start_offset,
- HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET);
-
- cmd->rx_msdu_offset =
- le32_encode_bits(tlv_filter->rx_msdu_end_offset,
- HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET);
-
- cmd->rx_msdu_offset |=
- le32_encode_bits(tlv_filter->rx_msdu_start_offset,
- HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET);
-
- cmd->rx_attn_offset =
- le32_encode_bits(tlv_filter->rx_attn_offset,
- HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET);
- }
-
- if (tlv_filter->rx_mpdu_start_wmask > 0 &&
- tlv_filter->rx_msdu_end_wmask > 0) {
- cmd->info2 |=
- le32_encode_bits(true,
- HTT_RX_RING_SELECTION_CFG_WORD_MASK_COMPACT_SET);
- cmd->rx_mpdu_start_end_mask =
- le32_encode_bits(tlv_filter->rx_mpdu_start_wmask,
- HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_MASK);
- /* mpdu_end is not used for any hardwares so far
- * please assign it in future if any chip is
- * using through hal ops
- */
- cmd->rx_mpdu_start_end_mask |=
- le32_encode_bits(tlv_filter->rx_mpdu_end_wmask,
- HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_MASK);
- cmd->rx_msdu_end_word_mask =
- le32_encode_bits(tlv_filter->rx_msdu_end_wmask,
- HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_MASK);
- }
-
- ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb);
- if (ret)
- goto err_free;
-
- return 0;
-
-err_free:
- dev_kfree_skb_any(skb);
-
- return ret;
-}
-
-int
-ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type,
- struct htt_ext_stats_cfg_params *cfg_params,
- u64 cookie)
-{
- struct ath12k_base *ab = ar->ab;
- struct ath12k_dp *dp = &ab->dp;
- struct sk_buff *skb;
- struct htt_ext_stats_cfg_cmd *cmd;
- int len = sizeof(*cmd);
- int ret;
- u32 pdev_id;
-
- skb = ath12k_htc_alloc_skb(ab, len);
- if (!skb)
- return -ENOMEM;
-
- skb_put(skb, len);
-
- cmd = (struct htt_ext_stats_cfg_cmd *)skb->data;
- memset(cmd, 0, sizeof(*cmd));
- cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_EXT_STATS_CFG;
-
- pdev_id = ath12k_mac_get_target_pdev_id(ar);
- cmd->hdr.pdev_mask = 1 << pdev_id;
-
- cmd->hdr.stats_type = type;
- cmd->cfg_param0 = cpu_to_le32(cfg_params->cfg0);
- cmd->cfg_param1 = cpu_to_le32(cfg_params->cfg1);
- cmd->cfg_param2 = cpu_to_le32(cfg_params->cfg2);
- cmd->cfg_param3 = cpu_to_le32(cfg_params->cfg3);
- cmd->cookie_lsb = cpu_to_le32(lower_32_bits(cookie));
- cmd->cookie_msb = cpu_to_le32(upper_32_bits(cookie));
-
- ret = ath12k_htc_send(&ab->htc, dp->eid, skb);
- if (ret) {
- ath12k_warn(ab, "failed to send htt type stats request: %d",
- ret);
- dev_kfree_skb_any(skb);
- return ret;
- }
-
- return 0;
-}
-
-int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset)
-{
- struct ath12k_base *ab = ar->ab;
- int ret;
-
- ret = ath12k_dp_tx_htt_rx_monitor_mode_ring_config(ar, reset);
- if (ret) {
- ath12k_err(ab, "failed to setup rx monitor filter %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset)
-{
- struct ath12k_base *ab = ar->ab;
- struct htt_rx_ring_tlv_filter tlv_filter = {};
- int ret, ring_id, i;
-
- tlv_filter.offset_valid = false;
-
- if (!reset) {
- tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_DEST_RING;
-
- tlv_filter.drop_threshold_valid = true;
- tlv_filter.rx_drop_threshold = HTT_RX_RING_TLV_DROP_THRESHOLD_VALUE;
-
- tlv_filter.enable_log_mgmt_type = true;
- tlv_filter.enable_log_ctrl_type = true;
- tlv_filter.enable_log_data_type = true;
-
- tlv_filter.conf_len_ctrl = HTT_RX_RING_DEFAULT_DMA_LENGTH;
- tlv_filter.conf_len_mgmt = HTT_RX_RING_DEFAULT_DMA_LENGTH;
- tlv_filter.conf_len_data = HTT_RX_RING_DEFAULT_DMA_LENGTH;
-
- tlv_filter.enable_rx_tlv_offset = true;
- tlv_filter.rx_tlv_offset = HTT_RX_RING_PKT_TLV_OFFSET;
-
- tlv_filter.pkt_filter_flags0 =
- HTT_RX_MON_FP_MGMT_FILTER_FLAGS0 |
- HTT_RX_MON_MO_MGMT_FILTER_FLAGS0;
- tlv_filter.pkt_filter_flags1 =
- HTT_RX_MON_FP_MGMT_FILTER_FLAGS1 |
- HTT_RX_MON_MO_MGMT_FILTER_FLAGS1;
- tlv_filter.pkt_filter_flags2 =
- HTT_RX_MON_FP_CTRL_FILTER_FLASG2 |
- HTT_RX_MON_MO_CTRL_FILTER_FLASG2;
- tlv_filter.pkt_filter_flags3 =
- HTT_RX_MON_FP_CTRL_FILTER_FLASG3 |
- HTT_RX_MON_MO_CTRL_FILTER_FLASG3 |
- HTT_RX_MON_FP_DATA_FILTER_FLASG3 |
- HTT_RX_MON_MO_DATA_FILTER_FLASG3;
- } else {
- tlv_filter = ath12k_mac_mon_status_filter_default;
-
- if (ath12k_debugfs_is_extd_rx_stats_enabled(ar))
- tlv_filter.rx_filter = ath12k_debugfs_rx_filter(ar);
- }
-
- if (ab->hw_params->rxdma1_enable) {
- for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
- ring_id = ar->dp.rxdma_mon_dst_ring[i].ring_id;
- ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id,
- ar->dp.mac_id + i,
- HAL_RXDMA_MONITOR_DST,
- DP_RXDMA_REFILL_RING_SIZE,
- &tlv_filter);
- if (ret) {
- ath12k_err(ab,
- "failed to setup filter for monitor buf %d\n",
- ret);
- return ret;
- }
- }
- return 0;
- }
-
- if (!reset) {
- for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
- ring_id = ab->dp.rx_mac_buf_ring[i].ring_id;
- ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id,
- i,
- HAL_RXDMA_BUF,
- DP_RXDMA_REFILL_RING_SIZE,
- &tlv_filter);
- if (ret) {
- ath12k_err(ab,
- "failed to setup filter for mon rx buf %d\n",
- ret);
- return ret;
- }
- }
- }
-
- for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
- ring_id = ab->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
- if (!reset) {
- tlv_filter.rx_filter =
- HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING;
- }
-
- ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id,
- i,
- HAL_RXDMA_MONITOR_STATUS,
- RX_MON_STATUS_BUF_SIZE,
- &tlv_filter);
- if (ret) {
- ath12k_err(ab,
- "failed to setup filter for mon status buf %d\n",
- ret);
- return ret;
- }
- }
-
- return 0;
-}
-
-int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id,
- int mac_id, enum hal_ring_type ring_type,
- int tx_buf_size,
- struct htt_tx_ring_tlv_filter *htt_tlv_filter)
-{
- struct htt_tx_ring_selection_cfg_cmd *cmd;
- struct hal_srng *srng = &ab->hal.srng_list[ring_id];
- struct hal_srng_params params;
- struct sk_buff *skb;
- int len = sizeof(*cmd);
- enum htt_srng_ring_type htt_ring_type;
- enum htt_srng_ring_id htt_ring_id;
- int ret;
-
- skb = ath12k_htc_alloc_skb(ab, len);
- if (!skb)
- return -ENOMEM;
-
- memset(¶ms, 0, sizeof(params));
- ath12k_hal_srng_get_params(ab, srng, ¶ms);
-
- ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id,
- ring_type, &htt_ring_type,
- &htt_ring_id);
-
- if (ret)
- goto err_free;
-
- skb_put(skb, len);
- cmd = (struct htt_tx_ring_selection_cfg_cmd *)skb->data;
- cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_TX_MONITOR_CFG,
- HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE);
- if (htt_ring_type == HTT_SW_TO_HW_RING ||
- htt_ring_type == HTT_HW_TO_SW_RING)
- cmd->info0 |=
- le32_encode_bits(DP_SW2HW_MACID(mac_id),
- HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID);
- else
- cmd->info0 |=
- le32_encode_bits(mac_id,
- HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID);
- cmd->info0 |= le32_encode_bits(htt_ring_id,
- HTT_TX_RING_SELECTION_CFG_CMD_INFO0_RING_ID);
- cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP),
- HTT_TX_RING_SELECTION_CFG_CMD_INFO0_SS);
- cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP),
- HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PS);
-
- cmd->info1 |=
- le32_encode_bits(tx_buf_size,
- HTT_TX_RING_SELECTION_CFG_CMD_INFO1_RING_BUFF_SIZE);
-
- if (htt_tlv_filter->tx_mon_mgmt_filter) {
- cmd->info1 |=
- le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_MGMT,
- HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE);
- cmd->info1 |=
- le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len,
- HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT);
- cmd->info2 |=
- le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_MGMT,
- HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG);
- }
-
- if (htt_tlv_filter->tx_mon_data_filter) {
- cmd->info1 |=
- le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_CTRL,
- HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE);
- cmd->info1 |=
- le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len,
- HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL);
- cmd->info2 |=
- le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_CTRL,
- HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG);
- }
-
- if (htt_tlv_filter->tx_mon_ctrl_filter) {
- cmd->info1 |=
- le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_DATA,
- HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE);
- cmd->info1 |=
- le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len,
- HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA);
- cmd->info2 |=
- le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_DATA,
- HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG);
- }
-
- cmd->tlv_filter_mask_in0 =
- cpu_to_le32(htt_tlv_filter->tx_mon_downstream_tlv_flags);
- cmd->tlv_filter_mask_in1 =
- cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags0);
- cmd->tlv_filter_mask_in2 =
- cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags1);
- cmd->tlv_filter_mask_in3 =
- cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags2);
-
- ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb);
- if (ret)
- goto err_free;
-
- return 0;
-
-err_free:
- dev_kfree_skb_any(skb);
- return ret;
-}
diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.h b/drivers/net/wireless/ath/ath12k/dp_tx.h
index 8405a0baf95b..5b8fe280c32a 100644
--- a/drivers/net/wireless/ath/ath12k/dp_tx.h
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.h
@@ -15,25 +15,7 @@ struct ath12k_dp_htt_wbm_tx_status {
s8 ack_rssi;
};
-int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab);
-int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask);
-int
-ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type,
- struct htt_ext_stats_cfg_params *cfg_params,
- u64 cookie);
-int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset);
-
-int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id,
- int mac_id, enum hal_ring_type ring_type,
- int rx_buf_size,
- struct htt_rx_ring_tlv_filter *tlv_filter);
void ath12k_dp_tx_put_bank_profile(struct ath12k_dp *dp, u8 bank_id);
-int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id,
- int mac_id, enum hal_ring_type ring_type,
- int tx_buf_size,
- struct htt_tx_ring_tlv_filter *htt_tlv_filter);
-int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset);
-
enum hal_tcl_encap_type
ath12k_dp_tx_get_encap_type(struct ath12k_base *ab, struct sk_buff *skb);
void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb);
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH ath12k-ng 20/20] wifi: ath12k: Move HTT specific code from dp.c to newly introduced files
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (18 preceding siblings ...)
2025-08-28 17:35 ` [PATCH ath12k-ng 19/20] wifi: ath12k: Move HTT Tx " Ripan Deuri
@ 2025-08-28 17:35 ` Ripan Deuri
2025-09-01 5:23 ` [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Baochen Qiang
` (2 subsequent siblings)
22 siblings, 0 replies; 24+ messages in thread
From: Ripan Deuri @ 2025-08-28 17:35 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
From: Harsh Kumar Bijlani <quic_hbijlani@quicinc.com>
WLAN Host driver interacts with the Firmware and vice versa using
Host-To-Target (HTT) interface.
Relocate HTT specific code from dp.c to newly introduced file dp_htt.c
for HTT interface.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Harsh Kumar Bijlani <quic_hbijlani@quicinc.com>
Signed-off-by: Ripan Deuri <quic_rdeuri@quicinc.com>
---
drivers/net/wireless/ath/ath12k/dp.c | 29 ----------------------
drivers/net/wireless/ath/ath12k/dp.h | 1 -
drivers/net/wireless/ath/ath12k/dp_htt.c | 31 ++++++++++++++++++++++--
drivers/net/wireless/ath/ath12k/dp_htt.h | 3 +++
4 files changed, 32 insertions(+), 32 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c
index d0bdf058633f..8909415df2e2 100644
--- a/drivers/net/wireless/ath/ath12k/dp.c
+++ b/drivers/net/wireless/ath/ath12k/dp.c
@@ -19,12 +19,6 @@ enum ath12k_dp_desc_type {
ATH12K_DP_RX_DESC,
};
-static void ath12k_dp_htt_htc_tx_complete(struct ath12k_base *ab,
- struct sk_buff *skb)
-{
- dev_kfree_skb_any(skb);
-}
-
void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr)
{
struct ath12k_base *ab = ar->ab;
@@ -957,29 +951,6 @@ int ath12k_dp_pdev_alloc(struct ath12k_base *ab)
return ret;
}
-int ath12k_dp_htt_connect(struct ath12k_dp *dp)
-{
- struct ath12k_htc_svc_conn_req conn_req = {};
- struct ath12k_htc_svc_conn_resp conn_resp = {};
- int status;
-
- conn_req.ep_ops.ep_tx_complete = ath12k_dp_htt_htc_tx_complete;
- conn_req.ep_ops.ep_rx_complete = ath12k_dp_htt_htc_t2h_msg_handler;
-
- /* connect to control service */
- conn_req.service_id = ATH12K_HTC_SVC_ID_HTT_DATA_MSG;
-
- status = ath12k_htc_connect_service(&dp->ab->htc, &conn_req,
- &conn_resp);
-
- if (status)
- return status;
-
- dp->eid = conn_resp.eid;
-
- return 0;
-}
-
static void ath12k_dp_update_vdev_search(struct ath12k_link_vif *arvif)
{
switch (arvif->ahvif->vdev_type) {
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index ad93e63e3344..18a3287945b7 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -432,7 +432,6 @@ static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr)
memcpy(addr + 4, &addr_h16, ETH_ALEN - 4);
}
-int ath12k_dp_htt_connect(struct ath12k_dp *dp);
void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif);
void ath12k_dp_free(struct ath12k_base *ab);
int ath12k_dp_alloc(struct ath12k_base *ab);
diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c
index 45aa8ae86a14..6ab5b2d8aac9 100644
--- a/drivers/net/wireless/ath/ath12k/dp_htt.c
+++ b/drivers/net/wireless/ath/ath12k/dp_htt.c
@@ -11,6 +11,35 @@
#include "debugfs_htt_stats.h"
#include "debugfs.h"
+static void ath12k_dp_htt_htc_tx_complete(struct ath12k_base *ab,
+ struct sk_buff *skb)
+{
+ dev_kfree_skb_any(skb);
+}
+
+int ath12k_dp_htt_connect(struct ath12k_dp *dp)
+{
+ struct ath12k_htc_svc_conn_req conn_req = {};
+ struct ath12k_htc_svc_conn_resp conn_resp = {};
+ int status;
+
+ conn_req.ep_ops.ep_tx_complete = ath12k_dp_htt_htc_tx_complete;
+ conn_req.ep_ops.ep_rx_complete = ath12k_dp_htt_htc_t2h_msg_handler;
+
+ /* connect to control service */
+ conn_req.service_id = ATH12K_HTC_SVC_ID_HTT_DATA_MSG;
+
+ status = ath12k_htc_connect_service(&dp->ab->htc, &conn_req,
+ &conn_resp);
+
+ if (status)
+ return status;
+
+ dp->eid = conn_resp.eid;
+
+ return 0;
+}
+
static int ath12k_get_ppdu_user_index(struct htt_ppdu_stats *ppdu_stats,
u16 peer_id)
{
@@ -818,8 +847,6 @@ int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id,
return ret;
}
-#define HTT_TARGET_VERSION_TIMEOUT_HZ (3 * HZ)
-
int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab)
{
struct ath12k_dp *dp = &ab->dp;
diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.h b/drivers/net/wireless/ath/ath12k/dp_htt.h
index b13af1c69253..6020e632f74e 100644
--- a/drivers/net/wireless/ath/ath12k/dp_htt.h
+++ b/drivers/net/wireless/ath/ath12k/dp_htt.h
@@ -36,6 +36,8 @@ struct ath12k_dp;
#define HTT_TX_WBM_COMP_INFO2_ACK_RSSI GENMASK(31, 24)
+#define HTT_TARGET_VERSION_TIMEOUT_HZ (3 * HZ)
+
struct htt_tx_wbm_completion {
__le32 rsvd0[2];
__le32 info0;
@@ -1514,6 +1516,7 @@ struct htt_mac_addr {
__le32 mac_addr_h16;
} __packed;
+int ath12k_dp_htt_connect(struct ath12k_dp *dp);
int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id,
int mac_id, enum hal_ring_type ring_type);
--
2.34.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (19 preceding siblings ...)
2025-08-28 17:35 ` [PATCH ath12k-ng 20/20] wifi: ath12k: Move HTT specific code from dp.c " Ripan Deuri
@ 2025-09-01 5:23 ` Baochen Qiang
2025-09-01 17:49 ` Vasanthakumar Thiagarajan
2025-09-03 17:14 ` Jeff Johnson
22 siblings, 0 replies; 24+ messages in thread
From: Baochen Qiang @ 2025-09-01 5:23 UTC (permalink / raw)
To: Ripan Deuri, ath12k; +Cc: linux-wireless
On 8/29/2025 1:35 AM, Ripan Deuri wrote:
> This patch series continues the modularization work described in the
> https://lore.kernel.org/linux-wireless/20250812-ath12k-mod-v1-0-8c9b0eb9335d@quicinc.com
> ("wifi: ath12k: Ath12k modularization changes") series, which established
> the foundation for the Next Generation (NG) ath12k driver framework.
> That series introduced the foundational split of the original ath12k.ko
> into two distinct modules: a common module (ath12k.ko) and an architecture-
> specific module (ath12k_wifi7.ko) for Wi-Fi 7 devices as depicted below.
>
> +-----------------+
> | |
> | ath12k.ko |
> | (common) |
> +---------------+ | |
> | | +-----------------+
> | ath12k.ko | ===========>
> | | +------------------+
> +---------------+ | |
> | ath12k_wifi7.ko |
> | (wifi7 family) |
> | |
> +------------------+
>
> Building on that framework, this series focuses on modularizing the Data Path
> (DP) of the ath12k driver, allowing the common DP to be reused across different
> hardware architectures.
>
> The patches included here support the NG framework objective by reorganizing
> DP-specific files and the directory structure as outlined below.
>
> Existing file org New file org
> ----------------- ------------
> ├── dp.c ├── dp.c
> ├── dp.h ├── dp.h
> ├── dp_rx.c ├── dp_htt.c
> ├── dp_rx.h ├── dp_htt.h
> ├── dp_tx.c ├── dp_rx.c
> ├── dp_tx.h ├── dp_rx.h
> ├── hal.c ├── dp_tx.c
> ├── hal_desc.h ├── dp_tx.h
> ├── hal.h ├── hal.c
> ├── hal_rx.c ├── hal.h
> ├── hal_rx.h ├── wifi7
> ├── hal_tx.c │ ├── dp.c
> ├── hal_tx.h │ ├── dp_rx.c
> │ ├── dp_rx.h
> │ ├── dp_tx.c
> │ ├── dp_tx.h
> │ ├── hal_desc.h
> │ ├── hal_qcn9274.c
> │ ├── hal_qcn9274.h
> │ ├── hal_rx.c
> │ ├── hal_rx.h
> │ ├── hal_tx.c
> │ ├── hal_tx.h
> │ ├── hal_wcn7850.c
> │ ├── hal_wcn7850.h
> │ ├── rx_desc.h
>
>
> Note: While common files are not intended to include architecture-specific
> headers, a few Wi-Fi 7 headers are temporarily included in common files
> across patches to simplify patch splitting. This will be resolved in a
> later series.
>
> ---
> Harsh Kumar Bijlani (4):
> wifi: ath12k: Move HTT code in dp.h to newly introduced files
> wifi: ath12k: Move HTT Rx specific code to newly introduced files
> wifi: ath12k: Move HTT Tx specific code to newly introduced files
> wifi: ath12k: Move HTT specific code from dp.c to newly introduced
> files
>
> Pavankumar Nandeshwar (16):
> wifi: ath12k: Move hal_tx and hal_rx to wifi7 directory
> wifi: ath12k: Move hal_tx.h file to wifi7 directory
> wifi: ath12k: Move hal_rx.h file to wifi7 directory
> wifi: ath12k: Move HAL Rx wrapper APIs to dp_rx.h
> wifi: ath12k: Move Rx error related functions to wifi7 directory
> wifi: ath12k: Move hal_desc.h file to wifi7 directory
> wifi: ath12k: Move rx_desc.h file to wifi7 directory
> wifi: ath12k: Move rxdma ring config functions to wifi7 directory
> wifi: ath12k: Move rx error and defrag functions to wifi7 directory
> wifi: ath12k: Move regular msdu processing functions to wifi7
> directory
> wifi: ath12k: Move srng processing to wifi7 directory
> wifi: ath12k: Separate arch specific part of RX APIs
> wifi: ath12k: Move arch specific REO functions to wifi7 directory
> wifi: ath12k: Move arch specific rx tid and related functions to wifi7
> directory
> wifi: ath12k: Move arch specific tx APIs to wifi7 directory
> wifi: ath12k: Move ath12k_dp_tx and related APIs to wifi7 directory
>
> drivers/net/wireless/ath/ath12k/Makefile | 9 +-
> drivers/net/wireless/ath/ath12k/ahb.c | 3 +-
> drivers/net/wireless/ath/ath12k/core.h | 4 +-
> .../wireless/ath/ath12k/debugfs_htt_stats.h | 4 +-
> drivers/net/wireless/ath/ath12k/dp.c | 159 +-
> drivers/net/wireless/ath/ath12k/dp.h | 1518 +-------
> drivers/net/wireless/ath/ath12k/dp_htt.c | 1354 ++++++++
> drivers/net/wireless/ath/ath12k/dp_htt.h | 1546 +++++++++
> drivers/net/wireless/ath/ath12k/dp_mon.c | 4 +-
> drivers/net/wireless/ath/ath12k/dp_rx.c | 3056 +----------------
> drivers/net/wireless/ath/ath12k/dp_rx.h | 297 +-
> drivers/net/wireless/ath/ath12k/dp_tx.c | 1609 +--------
> drivers/net/wireless/ath/ath12k/dp_tx.h | 41 +-
> drivers/net/wireless/ath/ath12k/hal.c | 8 +-
> drivers/net/wireless/ath/ath12k/hal.h | 501 ++-
> drivers/net/wireless/ath/ath12k/mac.c | 3 +-
> drivers/net/wireless/ath/ath12k/pci.c | 3 +-
> drivers/net/wireless/ath/ath12k/wifi7/dp.c | 137 +
> drivers/net/wireless/ath/ath12k/wifi7/dp.h | 15 +
> drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 2043 +++++++++++
> drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 47 +
> drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 908 +++++
> drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h | 14 +
> .../ath/ath12k/{ => wifi7}/hal_desc.h | 149 +-
> .../wireless/ath/ath12k/{ => wifi7}/hal_rx.c | 8 +-
> .../wireless/ath/ath12k/{ => wifi7}/hal_rx.h | 299 +-
> .../ath12k/{rx_desc.h => wifi7/hal_rx_desc.h} | 48 +-
> .../wireless/ath/ath12k/{ => wifi7}/hal_tx.c | 6 +-
> .../wireless/ath/ath12k/{ => wifi7}/hal_tx.h | 11 +-
> drivers/net/wireless/ath/ath12k/wifi7/hw.c | 4 +-
> 30 files changed, 6993 insertions(+), 6815 deletions(-)
> create mode 100644 drivers/net/wireless/ath/ath12k/dp_htt.c
> create mode 100644 drivers/net/wireless/ath/ath12k/dp_htt.h
> create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp.c
> create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp.h
> create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
> create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
> create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
> create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h
> rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_desc.h (95%)
> rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_rx.c (99%)
> rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_rx.h (83%)
> rename drivers/net/wireless/ath/ath12k/{rx_desc.h => wifi7/hal_rx_desc.h} (97%)
> rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_tx.c (97%)
> rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_tx.h (96%)
>
>
> base-commit: 0e487f03c6e5d8dd5b076b8b061e50e736ab2196
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (20 preceding siblings ...)
2025-09-01 5:23 ` [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Baochen Qiang
@ 2025-09-01 17:49 ` Vasanthakumar Thiagarajan
2025-09-03 17:14 ` Jeff Johnson
22 siblings, 0 replies; 24+ messages in thread
From: Vasanthakumar Thiagarajan @ 2025-09-01 17:49 UTC (permalink / raw)
To: Ripan Deuri, ath12k; +Cc: linux-wireless
On 8/28/2025 11:05 PM, Ripan Deuri wrote:
> This patch series continues the modularization work described in the
> https://lore.kernel.org/linux-wireless/20250812-ath12k-mod-v1-0-8c9b0eb9335d@quicinc.com
> ("wifi: ath12k: Ath12k modularization changes") series, which established
> the foundation for the Next Generation (NG) ath12k driver framework.
> That series introduced the foundational split of the original ath12k.ko
> into two distinct modules: a common module (ath12k.ko) and an architecture-
> specific module (ath12k_wifi7.ko) for Wi-Fi 7 devices as depicted below.
>
> +-----------------+
> | |
> | ath12k.ko |
> | (common) |
> +---------------+ | |
> | | +-----------------+
> | ath12k.ko | ===========>
> | | +------------------+
> +---------------+ | |
> | ath12k_wifi7.ko |
> | (wifi7 family) |
> | |
> +------------------+
>
> Building on that framework, this series focuses on modularizing the Data Path
> (DP) of the ath12k driver, allowing the common DP to be reused across different
> hardware architectures.
>
> The patches included here support the NG framework objective by reorganizing
> DP-specific files and the directory structure as outlined below.
>
> Existing file org New file org
> ----------------- ------------
> ├── dp.c ├── dp.c
> ├── dp.h ├── dp.h
> ├── dp_rx.c ├── dp_htt.c
> ├── dp_rx.h ├── dp_htt.h
> ├── dp_tx.c ├── dp_rx.c
> ├── dp_tx.h ├── dp_rx.h
> ├── hal.c ├── dp_tx.c
> ├── hal_desc.h ├── dp_tx.h
> ├── hal.h ├── hal.c
> ├── hal_rx.c ├── hal.h
> ├── hal_rx.h ├── wifi7
> ├── hal_tx.c │ ├── dp.c
> ├── hal_tx.h │ ├── dp_rx.c
> │ ├── dp_rx.h
> │ ├── dp_tx.c
> │ ├── dp_tx.h
> │ ├── hal_desc.h
> │ ├── hal_qcn9274.c
> │ ├── hal_qcn9274.h
> │ ├── hal_rx.c
> │ ├── hal_rx.h
> │ ├── hal_tx.c
> │ ├── hal_tx.h
> │ ├── hal_wcn7850.c
> │ ├── hal_wcn7850.h
> │ ├── rx_desc.h
>
>
> Note: While common files are not intended to include architecture-specific
> headers, a few Wi-Fi 7 headers are temporarily included in common files
> across patches to simplify patch splitting. This will be resolved in a
> later series.
>
> ---
> Harsh Kumar Bijlani (4):
> wifi: ath12k: Move HTT code in dp.h to newly introduced files
> wifi: ath12k: Move HTT Rx specific code to newly introduced files
> wifi: ath12k: Move HTT Tx specific code to newly introduced files
> wifi: ath12k: Move HTT specific code from dp.c to newly introduced
> files
>
> Pavankumar Nandeshwar (16):
> wifi: ath12k: Move hal_tx and hal_rx to wifi7 directory
> wifi: ath12k: Move hal_tx.h file to wifi7 directory
> wifi: ath12k: Move hal_rx.h file to wifi7 directory
> wifi: ath12k: Move HAL Rx wrapper APIs to dp_rx.h
> wifi: ath12k: Move Rx error related functions to wifi7 directory
> wifi: ath12k: Move hal_desc.h file to wifi7 directory
> wifi: ath12k: Move rx_desc.h file to wifi7 directory
> wifi: ath12k: Move rxdma ring config functions to wifi7 directory
> wifi: ath12k: Move rx error and defrag functions to wifi7 directory
> wifi: ath12k: Move regular msdu processing functions to wifi7
> directory
> wifi: ath12k: Move srng processing to wifi7 directory
> wifi: ath12k: Separate arch specific part of RX APIs
> wifi: ath12k: Move arch specific REO functions to wifi7 directory
> wifi: ath12k: Move arch specific rx tid and related functions to wifi7
> directory
> wifi: ath12k: Move arch specific tx APIs to wifi7 directory
> wifi: ath12k: Move ath12k_dp_tx and related APIs to wifi7 directory
>
> drivers/net/wireless/ath/ath12k/Makefile | 9 +-
> drivers/net/wireless/ath/ath12k/ahb.c | 3 +-
> drivers/net/wireless/ath/ath12k/core.h | 4 +-
> .../wireless/ath/ath12k/debugfs_htt_stats.h | 4 +-
> drivers/net/wireless/ath/ath12k/dp.c | 159 +-
> drivers/net/wireless/ath/ath12k/dp.h | 1518 +-------
> drivers/net/wireless/ath/ath12k/dp_htt.c | 1354 ++++++++
> drivers/net/wireless/ath/ath12k/dp_htt.h | 1546 +++++++++
> drivers/net/wireless/ath/ath12k/dp_mon.c | 4 +-
> drivers/net/wireless/ath/ath12k/dp_rx.c | 3056 +----------------
> drivers/net/wireless/ath/ath12k/dp_rx.h | 297 +-
> drivers/net/wireless/ath/ath12k/dp_tx.c | 1609 +--------
> drivers/net/wireless/ath/ath12k/dp_tx.h | 41 +-
> drivers/net/wireless/ath/ath12k/hal.c | 8 +-
> drivers/net/wireless/ath/ath12k/hal.h | 501 ++-
> drivers/net/wireless/ath/ath12k/mac.c | 3 +-
> drivers/net/wireless/ath/ath12k/pci.c | 3 +-
> drivers/net/wireless/ath/ath12k/wifi7/dp.c | 137 +
> drivers/net/wireless/ath/ath12k/wifi7/dp.h | 15 +
> drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 2043 +++++++++++
> drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 47 +
> drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c | 908 +++++
> drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h | 14 +
> .../ath/ath12k/{ => wifi7}/hal_desc.h | 149 +-
> .../wireless/ath/ath12k/{ => wifi7}/hal_rx.c | 8 +-
> .../wireless/ath/ath12k/{ => wifi7}/hal_rx.h | 299 +-
> .../ath12k/{rx_desc.h => wifi7/hal_rx_desc.h} | 48 +-
> .../wireless/ath/ath12k/{ => wifi7}/hal_tx.c | 6 +-
> .../wireless/ath/ath12k/{ => wifi7}/hal_tx.h | 11 +-
> drivers/net/wireless/ath/ath12k/wifi7/hw.c | 4 +-
> 30 files changed, 6993 insertions(+), 6815 deletions(-)
> create mode 100644 drivers/net/wireless/ath/ath12k/dp_htt.c
> create mode 100644 drivers/net/wireless/ath/ath12k/dp_htt.h
> create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp.c
> create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp.h
> create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
> create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
> create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_tx.c
> create mode 100644 drivers/net/wireless/ath/ath12k/wifi7/dp_tx.h
> rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_desc.h (95%)
> rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_rx.c (99%)
> rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_rx.h (83%)
> rename drivers/net/wireless/ath/ath12k/{rx_desc.h => wifi7/hal_rx_desc.h} (97%)
> rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_tx.c (97%)
> rename drivers/net/wireless/ath/ath12k/{ => wifi7}/hal_tx.h (96%)
>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
` (21 preceding siblings ...)
2025-09-01 17:49 ` Vasanthakumar Thiagarajan
@ 2025-09-03 17:14 ` Jeff Johnson
22 siblings, 0 replies; 24+ messages in thread
From: Jeff Johnson @ 2025-09-03 17:14 UTC (permalink / raw)
To: ath12k, Ripan Deuri; +Cc: linux-wireless
On Thu, 28 Aug 2025 23:05:33 +0530, Ripan Deuri wrote:
> This patch series continues the modularization work described in the
> https://lore.kernel.org/linux-wireless/20250812-ath12k-mod-v1-0-8c9b0eb9335d@quicinc.com
> ("wifi: ath12k: Ath12k modularization changes") series, which established
> the foundation for the Next Generation (NG) ath12k driver framework.
> That series introduced the foundational split of the original ath12k.ko
> into two distinct modules: a common module (ath12k.ko) and an architecture-
> specific module (ath12k_wifi7.ko) for Wi-Fi 7 devices as depicted below.
>
> [...]
Applied, thanks!
[01/20] wifi: ath12k: Move hal_tx and hal_rx to wifi7 directory
commit: dc722ea9ee13369b1d4687160206e6bde2e8c2e2
[02/20] wifi: ath12k: Move hal_tx.h file to wifi7 directory
commit: 020225bbf4fb2fb23553ac9c65c8f50bb4d2fe74
[03/20] wifi: ath12k: Move hal_rx.h file to wifi7 directory
commit: 4f57d71862a7edef67de6c2072127dc1c8960a24
[04/20] wifi: ath12k: Move HAL Rx wrapper APIs to dp_rx.h
commit: 2ec00a7747cb78b0c310ba1c8bc9893e53101569
[05/20] wifi: ath12k: Move Rx error related functions to wifi7 directory
commit: 1a6a4b6c9f0ea0740c86dda8b981b6d818433fe0
[06/20] wifi: ath12k: Move hal_desc.h file to wifi7 directory
commit: 87a230ec2bfa15506b885e7ab958bf45b0036e8d
[07/20] wifi: ath12k: Move rx_desc.h file to wifi7 directory
commit: 8658abc7139fc72d94959335becbabcd2b3c95a3
[08/20] wifi: ath12k: Move rxdma ring config functions to wifi7 directory
commit: 8dc72a6f603e81050ebb3d8b4b2fc5fde0d9dd93
[09/20] wifi: ath12k: Move rx error and defrag functions to wifi7 directory
commit: 6b4954d3f0000cc687f263a151ec2c7ad38e00a8
[10/20] wifi: ath12k: Move regular msdu processing functions to wifi7 directory
commit: a7cfbb18d411b186ff67f62215e53e125ccc93d6
[11/20] wifi: ath12k: Move srng processing to wifi7 directory
commit: 5d2df2aa84303a187b82ca048ae28709bef85f77
[12/20] wifi: ath12k: Separate arch specific part of RX APIs
commit: eb2120ae6ab5790527f3b3066410543c1b7a5ab4
[13/20] wifi: ath12k: Move arch specific REO functions to wifi7 directory
commit: 6c7ceff2bed9d69007d23883f12a1406e149a060
[14/20] wifi: ath12k: Move arch specific rx tid and related functions to wifi7 directory
commit: 52c555680bae89a5169810f1f12a06241c93ecb7
[15/20] wifi: ath12k: Move arch specific tx APIs to wifi7 directory
commit: 8527d81ee622f509df11e4444c7d0901ac542174
[16/20] wifi: ath12k: Move ath12k_dp_tx and related APIs to wifi7 directory
commit: a45d0e81b2429c26db6b1ee0d43ff62b12d41d1f
[17/20] wifi: ath12k: Move HTT code in dp.h to newly introduced files
commit: d3ade00eb6d27dda5ba0026f5602f03b99df5a96
[18/20] wifi: ath12k: Move HTT Rx specific code to newly introduced files
commit: 71a3f92c512e1605a2ffdae94e4d4e3a6a63b90f
[19/20] wifi: ath12k: Move HTT Tx specific code to newly introduced files
commit: 611297ee9faf6a28b1d553c41c4677052629cf6c
[20/20] wifi: ath12k: Move HTT specific code from dp.c to newly introduced files
commit: d637c58a29475d646f8decfbbc1d27fae999a449
Best regards,
--
Jeff Johnson <jeff.johnson@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2025-09-03 17:14 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-28 17:35 [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 01/20] wifi: ath12k: Move hal_tx and hal_rx to wifi7 directory Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 02/20] wifi: ath12k: Move hal_tx.h file " Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 03/20] wifi: ath12k: Move hal_rx.h " Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 04/20] wifi: ath12k: Move HAL Rx wrapper APIs to dp_rx.h Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 05/20] wifi: ath12k: Move Rx error related functions to wifi7 directory Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 06/20] wifi: ath12k: Move hal_desc.h file " Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 07/20] wifi: ath12k: Move rx_desc.h " Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 08/20] wifi: ath12k: Move rxdma ring config functions " Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 09/20] wifi: ath12k: Move rx error and defrag " Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 10/20] wifi: ath12k: Move regular msdu processing " Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 11/20] wifi: ath12k: Move srng processing " Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 12/20] wifi: ath12k: Separate arch specific part of RX APIs Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 13/20] wifi: ath12k: Move arch specific REO functions to wifi7 directory Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 14/20] wifi: ath12k: Move arch specific rx tid and related " Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 15/20] wifi: ath12k: Move arch specific tx APIs " Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 16/20] wifi: ath12k: Move ath12k_dp_tx and related " Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 17/20] wifi: ath12k: Move HTT code in dp.h to newly introduced files Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 18/20] wifi: ath12k: Move HTT Rx specific code " Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 19/20] wifi: ath12k: Move HTT Tx " Ripan Deuri
2025-08-28 17:35 ` [PATCH ath12k-ng 20/20] wifi: ath12k: Move HTT specific code from dp.c " Ripan Deuri
2025-09-01 5:23 ` [PATCH ath12k-ng 00/20] wifi: ath12k: ath12k file re-organization Baochen Qiang
2025-09-01 17:49 ` Vasanthakumar Thiagarajan
2025-09-03 17:14 ` Jeff Johnson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).