git: 931b526c68f5 - stable/15 - ath12k: update Atheros/QCA's ath12k driver
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 31 Mar 2026 20:28:12 UTC
The branch stable/15 has been updated by bz:
URL: https://cgit.FreeBSD.org/src/commit/?id=931b526c68f5ea054bf9d3e12b1e16d34de1e4df
commit 931b526c68f5ea054bf9d3e12b1e16d34de1e4df
Author: Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2026-03-19 23:33:40 +0000
Commit: Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2026-03-31 16:22:50 +0000
ath12k: update Atheros/QCA's ath12k driver
This version is based on
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
05f7e89ab9731565d8a62e3b5d1ec206485eeb0b ( tag: v6.19 ).
Sponsored by: The FreeBSD Foundation
(cherry picked from commit a96550206e4bde15bf615ff2127b80404a7ec41f)
---
sys/contrib/dev/athk/ath12k/Kconfig | 30 +-
sys/contrib/dev/athk/ath12k/Makefile | 10 +-
sys/contrib/dev/athk/ath12k/acpi.c | 510 +
sys/contrib/dev/athk/ath12k/acpi.h | 114 +
sys/contrib/dev/athk/ath12k/ahb.c | 1156 +++
sys/contrib/dev/athk/ath12k/ahb.h | 80 +
sys/contrib/dev/athk/ath12k/ce.c | 121 +-
sys/contrib/dev/athk/ath12k/ce.h | 27 +-
sys/contrib/dev/athk/ath12k/core.c | 1826 +++-
sys/contrib/dev/athk/ath12k/core.h | 817 +-
sys/contrib/dev/athk/ath12k/coredump.c | 54 +
sys/contrib/dev/athk/ath12k/coredump.h | 81 +
sys/contrib/dev/athk/ath12k/dbring.c | 5 +-
sys/contrib/dev/athk/ath12k/debug.c | 19 +-
sys/contrib/dev/athk/ath12k/debug.h | 17 +-
sys/contrib/dev/athk/ath12k/debugfs.c | 1515 +++
sys/contrib/dev/athk/ath12k/debugfs.h | 147 +
sys/contrib/dev/athk/ath12k/debugfs_htt_stats.c | 6178 ++++++++++++
sys/contrib/dev/athk/ath12k/debugfs_htt_stats.h | 2076 ++++
sys/contrib/dev/athk/ath12k/debugfs_sta.c | 337 +
sys/contrib/dev/athk/ath12k/debugfs_sta.h | 24 +
sys/contrib/dev/athk/ath12k/dp.c | 536 +-
sys/contrib/dev/athk/ath12k/dp.h | 276 +-
sys/contrib/dev/athk/ath12k/dp_mon.c | 2853 +++++-
sys/contrib/dev/athk/ath12k/dp_mon.h | 19 +-
sys/contrib/dev/athk/ath12k/dp_rx.c | 1970 ++--
sys/contrib/dev/athk/ath12k/dp_rx.h | 88 +-
sys/contrib/dev/athk/ath12k/dp_tx.c | 866 +-
sys/contrib/dev/athk/ath12k/dp_tx.h | 10 +-
sys/contrib/dev/athk/ath12k/fw.c | 178 +
sys/contrib/dev/athk/ath12k/fw.h | 37 +
sys/contrib/dev/athk/ath12k/hal.c | 589 +-
sys/contrib/dev/athk/ath12k/hal.h | 127 +-
sys/contrib/dev/athk/ath12k/hal_desc.h | 116 +-
sys/contrib/dev/athk/ath12k/hal_rx.c | 159 +-
sys/contrib/dev/athk/ath12k/hal_rx.h | 535 +-
sys/contrib/dev/athk/ath12k/hal_tx.h | 12 +-
sys/contrib/dev/athk/ath12k/hif.h | 45 +-
sys/contrib/dev/athk/ath12k/htc.c | 10 +-
sys/contrib/dev/athk/ath12k/hw.c | 671 +-
sys/contrib/dev/athk/ath12k/hw.h | 104 +-
sys/contrib/dev/athk/ath12k/mac.c | 11535 ++++++++++++++++++----
sys/contrib/dev/athk/ath12k/mac.h | 149 +-
sys/contrib/dev/athk/ath12k/mhi.c | 193 +-
sys/contrib/dev/athk/ath12k/mhi.h | 7 +-
sys/contrib/dev/athk/ath12k/p2p.c | 147 +
sys/contrib/dev/athk/ath12k/p2p.h | 24 +
sys/contrib/dev/athk/ath12k/pci.c | 682 +-
sys/contrib/dev/athk/ath12k/pci.h | 18 +-
sys/contrib/dev/athk/ath12k/peer.c | 244 +-
sys/contrib/dev/athk/ath12k/peer.h | 60 +-
sys/contrib/dev/athk/ath12k/qmi.c | 1207 ++-
sys/contrib/dev/athk/ath12k/qmi.h | 91 +-
sys/contrib/dev/athk/ath12k/reg.c | 666 +-
sys/contrib/dev/athk/ath12k/reg.h | 36 +-
sys/contrib/dev/athk/ath12k/rx_desc.h | 133 +-
sys/contrib/dev/athk/ath12k/testmode.c | 395 +
sys/contrib/dev/athk/ath12k/testmode.h | 40 +
sys/contrib/dev/athk/ath12k/trace.h | 41 +-
sys/contrib/dev/athk/ath12k/wmi.c | 5991 +++++++++--
sys/contrib/dev/athk/ath12k/wmi.h | 2084 +++-
sys/contrib/dev/athk/ath12k/wow.c | 1029 ++
sys/contrib/dev/athk/ath12k/wow.h | 62 +
sys/modules/ath11k/Makefile | 63 +-
64 files changed, 43310 insertions(+), 5932 deletions(-)
diff --git a/sys/contrib/dev/athk/ath12k/Kconfig b/sys/contrib/dev/athk/ath12k/Kconfig
index 4f9c514c13e7..1ea1af1b8f6c 100644
--- a/sys/contrib/dev/athk/ath12k/Kconfig
+++ b/sys/contrib/dev/athk/ath12k/Kconfig
@@ -2,11 +2,12 @@
config ATH12K
tristate "Qualcomm Technologies Wi-Fi 7 support (ath12k)"
depends on MAC80211 && HAS_DMA && PCI
- depends on CRYPTO_MICHAEL_MIC
+ select CRYPTO_MICHAEL_MIC
select QCOM_QMI_HELPERS
select MHI_BUS
select QRTR
select QRTR_MHI
+ select PCI_PWRCTRL_PWRSEQ if HAVE_PWRCTRL
help
Enable support for Qualcomm Technologies Wi-Fi 7 (IEEE
802.11be) family of chipsets, for example WCN7850 and
@@ -14,6 +15,14 @@ config ATH12K
If you choose to build a module, it'll be called ath12k.
+config ATH12K_AHB
+ bool "QTI ath12k AHB support"
+ depends on ATH12K && REMOTEPROC
+ select QCOM_MDT_LOADER
+ select QCOM_SCM
+ help
+ Enable support for Ath12k AHB bus chipsets, example IPQ5332.
+
config ATH12K_DEBUG
bool "ath12k debugging"
depends on ATH12K
@@ -24,6 +33,15 @@ config ATH12K_DEBUG
If unsure, say Y to make it easier to debug problems. But if
you want optimal performance choose N.
+config ATH12K_DEBUGFS
+ bool "QTI ath12k debugfs support"
+ depends on ATH12K && MAC80211_DEBUGFS
+ help
+ Enable ath12k debugfs support
+
+ If unsure, say Y to make it easier to debug problems. But if
+ you want optimal performance choose N.
+
config ATH12K_TRACING
bool "ath12k tracing support"
depends on ATH12K && EVENT_TRACING
@@ -32,3 +50,13 @@ config ATH12K_TRACING
If unsure, say Y to make it easier to debug problems. But if
you want optimal performance choose N.
+
+config ATH12K_COREDUMP
+ bool "ath12k coredump"
+ depends on ATH12K
+ select WANT_DEV_COREDUMP
+ help
+ Enable ath12k coredump collection
+
+ If unsure, say Y to make it easier to debug problems. But if
+ dump collection not required choose N.
diff --git a/sys/contrib/dev/athk/ath12k/Makefile b/sys/contrib/dev/athk/ath12k/Makefile
index 62c52e733b5e..d95ee525a6cd 100644
--- a/sys/contrib/dev/athk/ath12k/Makefile
+++ b/sys/contrib/dev/athk/ath12k/Makefile
@@ -19,9 +19,17 @@ ath12k-y += core.o \
hw.o \
mhi.o \
pci.o \
- dp_mon.o
+ dp_mon.o \
+ fw.o \
+ p2p.o
+ath12k-$(CONFIG_ATH12K_AHB) += ahb.o
+ath12k-$(CONFIG_ATH12K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o
+ath12k-$(CONFIG_ACPI) += acpi.o
ath12k-$(CONFIG_ATH12K_TRACING) += trace.o
+ath12k-$(CONFIG_PM) += wow.o
+ath12k-$(CONFIG_ATH12K_COREDUMP) += coredump.o
+ath12k-$(CONFIG_NL80211_TESTMODE) += testmode.o
# for tracing framework to find trace.h
CFLAGS_trace.o := -I$(src)
diff --git a/sys/contrib/dev/athk/ath12k/acpi.c b/sys/contrib/dev/athk/ath12k/acpi.c
new file mode 100644
index 000000000000..d81367ce6929
--- /dev/null
+++ b/sys/contrib/dev/athk/ath12k/acpi.c
@@ -0,0 +1,510 @@
+// 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.
+ */
+
+#include "core.h"
+#include "acpi.h"
+#include "debug.h"
+
+static int ath12k_acpi_dsm_get_data(struct ath12k_base *ab, int func)
+{
+ union acpi_object *obj;
+ acpi_handle root_handle;
+ int ret, i;
+
+ root_handle = ACPI_HANDLE(ab->dev);
+ if (!root_handle) {
+ ath12k_dbg(ab, ATH12K_DBG_BOOT, "invalid acpi handler\n");
+ return -EOPNOTSUPP;
+ }
+
+ obj = acpi_evaluate_dsm(root_handle, ab->hw_params->acpi_guid, 0, func,
+ NULL);
+
+ if (!obj) {
+ ath12k_dbg(ab, ATH12K_DBG_BOOT, "acpi_evaluate_dsm() failed\n");
+ return -ENOENT;
+ }
+
+ if (obj->type == ACPI_TYPE_INTEGER) {
+ switch (func) {
+ case ATH12K_ACPI_DSM_FUNC_SUPPORT_FUNCS:
+ ab->acpi.func_bit = obj->integer.value;
+ break;
+ case ATH12K_ACPI_DSM_FUNC_DISABLE_FLAG:
+ ab->acpi.bit_flag = obj->integer.value;
+ break;
+ }
+ } else if (obj->type == ACPI_TYPE_STRING) {
+ switch (func) {
+ case ATH12K_ACPI_DSM_FUNC_BDF_EXT:
+ if (obj->string.length <= ATH12K_ACPI_BDF_ANCHOR_STRING_LEN ||
+ obj->string.length > ATH12K_ACPI_BDF_MAX_LEN ||
+ memcmp(obj->string.pointer, ATH12K_ACPI_BDF_ANCHOR_STRING,
+ ATH12K_ACPI_BDF_ANCHOR_STRING_LEN)) {
+ ath12k_warn(ab, "invalid ACPI DSM BDF size: %d\n",
+ obj->string.length);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ memcpy(ab->acpi.bdf_string, obj->string.pointer,
+ obj->buffer.length);
+
+ break;
+ }
+ } else if (obj->type == ACPI_TYPE_BUFFER) {
+ switch (func) {
+ case ATH12K_ACPI_DSM_FUNC_SUPPORT_FUNCS:
+ if (obj->buffer.length < ATH12K_ACPI_DSM_FUNC_MIN_BITMAP_SIZE ||
+ obj->buffer.length > ATH12K_ACPI_DSM_FUNC_MAX_BITMAP_SIZE) {
+ ath12k_warn(ab, "invalid ACPI DSM func size: %d\n",
+ obj->buffer.length);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ab->acpi.func_bit = 0;
+ for (i = 0; i < obj->buffer.length; i++)
+ ab->acpi.func_bit += obj->buffer.pointer[i] << (i * 8);
+
+ break;
+ case ATH12K_ACPI_DSM_FUNC_TAS_CFG:
+ if (obj->buffer.length != ATH12K_ACPI_DSM_TAS_CFG_SIZE) {
+ ath12k_warn(ab, "invalid ACPI DSM TAS config size: %d\n",
+ obj->buffer.length);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ memcpy(&ab->acpi.tas_cfg, obj->buffer.pointer,
+ obj->buffer.length);
+
+ break;
+ case ATH12K_ACPI_DSM_FUNC_TAS_DATA:
+ if (obj->buffer.length != ATH12K_ACPI_DSM_TAS_DATA_SIZE) {
+ ath12k_warn(ab, "invalid ACPI DSM TAS data size: %d\n",
+ obj->buffer.length);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ memcpy(&ab->acpi.tas_sar_power_table, obj->buffer.pointer,
+ obj->buffer.length);
+
+ break;
+ case ATH12K_ACPI_DSM_FUNC_BIOS_SAR:
+ if (obj->buffer.length != ATH12K_ACPI_DSM_BIOS_SAR_DATA_SIZE) {
+ ath12k_warn(ab, "invalid ACPI BIOS SAR data size: %d\n",
+ obj->buffer.length);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ memcpy(&ab->acpi.bios_sar_data, obj->buffer.pointer,
+ obj->buffer.length);
+
+ break;
+ case ATH12K_ACPI_DSM_FUNC_GEO_OFFSET:
+ if (obj->buffer.length != ATH12K_ACPI_DSM_GEO_OFFSET_DATA_SIZE) {
+ ath12k_warn(ab, "invalid ACPI GEO OFFSET data size: %d\n",
+ obj->buffer.length);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ memcpy(&ab->acpi.geo_offset_data, obj->buffer.pointer,
+ obj->buffer.length);
+
+ break;
+ case ATH12K_ACPI_DSM_FUNC_INDEX_CCA:
+ if (obj->buffer.length != ATH12K_ACPI_DSM_CCA_DATA_SIZE) {
+ ath12k_warn(ab, "invalid ACPI DSM CCA data size: %d\n",
+ obj->buffer.length);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ memcpy(&ab->acpi.cca_data, obj->buffer.pointer,
+ obj->buffer.length);
+
+ break;
+ case ATH12K_ACPI_DSM_FUNC_INDEX_BAND_EDGE:
+ if (obj->buffer.length != ATH12K_ACPI_DSM_BAND_EDGE_DATA_SIZE) {
+ ath12k_warn(ab, "invalid ACPI DSM band edge data size: %d\n",
+ obj->buffer.length);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ memcpy(&ab->acpi.band_edge_power, obj->buffer.pointer,
+ obj->buffer.length);
+
+ break;
+ }
+ } else {
+ ath12k_warn(ab, "ACPI DSM method returned an unsupported object type: %d\n",
+ obj->type);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ ACPI_FREE(obj);
+ return ret;
+}
+
+static int ath12k_acpi_set_power_limit(struct ath12k_base *ab)
+{
+ const u8 *tas_sar_power_table = ab->acpi.tas_sar_power_table;
+ int ret;
+
+ if (tas_sar_power_table[0] != ATH12K_ACPI_TAS_DATA_VERSION ||
+ tas_sar_power_table[1] != ATH12K_ACPI_TAS_DATA_ENABLE) {
+ ath12k_warn(ab, "latest ACPI TAS data is invalid\n");
+ return -EINVAL;
+ }
+
+ ret = ath12k_wmi_set_bios_cmd(ab, WMI_BIOS_PARAM_TAS_DATA_TYPE,
+ tas_sar_power_table,
+ ATH12K_ACPI_DSM_TAS_DATA_SIZE);
+ if (ret) {
+ ath12k_warn(ab, "failed to send ACPI TAS data table: %d\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int ath12k_acpi_set_bios_sar_power(struct ath12k_base *ab)
+{
+ int ret;
+
+ if (ab->acpi.bios_sar_data[0] != ATH12K_ACPI_POWER_LIMIT_VERSION ||
+ ab->acpi.bios_sar_data[1] != ATH12K_ACPI_POWER_LIMIT_ENABLE_FLAG) {
+ ath12k_warn(ab, "invalid latest ACPI BIOS SAR data\n");
+ return -EINVAL;
+ }
+
+ ret = ath12k_wmi_set_bios_sar_cmd(ab, ab->acpi.bios_sar_data);
+ if (ret) {
+ ath12k_warn(ab, "failed to set ACPI BIOS SAR table: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void ath12k_acpi_dsm_notify(acpi_handle handle, u32 event, void *data)
+{
+ int ret;
+ struct ath12k_base *ab = data;
+
+ if (event == ATH12K_ACPI_NOTIFY_EVENT) {
+ ath12k_warn(ab, "unknown acpi notify %u\n", event);
+ return;
+ }
+
+ if (!ab->acpi.acpi_tas_enable) {
+ ath12k_dbg(ab, ATH12K_DBG_BOOT, "acpi_tas_enable is false\n");
+ return;
+ }
+
+ ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_TAS_DATA);
+ if (ret) {
+ ath12k_warn(ab, "failed to update ACPI TAS data table: %d\n", ret);
+ return;
+ }
+
+ ret = ath12k_acpi_set_power_limit(ab);
+ if (ret) {
+ ath12k_warn(ab, "failed to set ACPI TAS power limit data: %d", ret);
+ return;
+ }
+
+ if (!ab->acpi.acpi_bios_sar_enable)
+ return;
+
+ ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_BIOS_SAR);
+ if (ret) {
+ ath12k_warn(ab, "failed to update BIOS SAR: %d\n", ret);
+ return;
+ }
+
+ ret = ath12k_acpi_set_bios_sar_power(ab);
+ if (ret) {
+ ath12k_warn(ab, "failed to set BIOS SAR power limit: %d\n", ret);
+ return;
+ }
+}
+
+static int ath12k_acpi_set_bios_sar_params(struct ath12k_base *ab)
+{
+ int ret;
+
+ ret = ath12k_wmi_set_bios_sar_cmd(ab, ab->acpi.bios_sar_data);
+ if (ret) {
+ ath12k_warn(ab, "failed to set ACPI BIOS SAR table: %d\n", ret);
+ return ret;
+ }
+
+ ret = ath12k_wmi_set_bios_geo_cmd(ab, ab->acpi.geo_offset_data);
+ if (ret) {
+ ath12k_warn(ab, "failed to set ACPI BIOS GEO table: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ath12k_acpi_set_tas_params(struct ath12k_base *ab)
+{
+ int ret;
+
+ ret = ath12k_wmi_set_bios_cmd(ab, WMI_BIOS_PARAM_TAS_CONFIG_TYPE,
+ ab->acpi.tas_cfg,
+ ATH12K_ACPI_DSM_TAS_CFG_SIZE);
+ if (ret) {
+ ath12k_warn(ab, "failed to send ACPI TAS config table parameter: %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = ath12k_wmi_set_bios_cmd(ab, WMI_BIOS_PARAM_TAS_DATA_TYPE,
+ ab->acpi.tas_sar_power_table,
+ ATH12K_ACPI_DSM_TAS_DATA_SIZE);
+ if (ret) {
+ ath12k_warn(ab, "failed to send ACPI TAS data table parameter: %d\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+bool ath12k_acpi_get_disable_rfkill(struct ath12k_base *ab)
+{
+ return ab->acpi.acpi_disable_rfkill;
+}
+
+bool ath12k_acpi_get_disable_11be(struct ath12k_base *ab)
+{
+ return ab->acpi.acpi_disable_11be;
+}
+
+void ath12k_acpi_set_dsm_func(struct ath12k_base *ab)
+{
+ int ret;
+ u8 *buf;
+
+ if (!ab->hw_params->acpi_guid)
+ /* not supported with this hardware */
+ return;
+
+ if (ab->acpi.acpi_tas_enable) {
+ ret = ath12k_acpi_set_tas_params(ab);
+ if (ret) {
+ ath12k_warn(ab, "failed to send ACPI TAS parameters: %d\n", ret);
+ return;
+ }
+ }
+
+ if (ab->acpi.acpi_bios_sar_enable) {
+ ret = ath12k_acpi_set_bios_sar_params(ab);
+ if (ret) {
+ ath12k_warn(ab, "failed to send ACPI BIOS SAR: %d\n", ret);
+ return;
+ }
+ }
+
+ if (ab->acpi.acpi_cca_enable) {
+ buf = ab->acpi.cca_data + ATH12K_ACPI_CCA_THR_OFFSET_DATA_OFFSET;
+ ret = ath12k_wmi_set_bios_cmd(ab,
+ WMI_BIOS_PARAM_CCA_THRESHOLD_TYPE,
+ buf,
+ ATH12K_ACPI_CCA_THR_OFFSET_LEN);
+ if (ret) {
+ ath12k_warn(ab, "failed to set ACPI DSM CCA threshold: %d\n",
+ ret);
+ return;
+ }
+ }
+
+ if (ab->acpi.acpi_band_edge_enable) {
+ ret = ath12k_wmi_set_bios_cmd(ab,
+ WMI_BIOS_PARAM_TYPE_BANDEDGE,
+ ab->acpi.band_edge_power,
+ sizeof(ab->acpi.band_edge_power));
+ if (ret) {
+ ath12k_warn(ab,
+ "failed to set ACPI DSM band edge channel power: %d\n",
+ ret);
+ return;
+ }
+ }
+}
+
+int ath12k_acpi_start(struct ath12k_base *ab)
+{
+ acpi_status status;
+ int ret;
+
+ ab->acpi.acpi_tas_enable = false;
+ ab->acpi.acpi_disable_11be = false;
+ ab->acpi.acpi_disable_rfkill = false;
+ ab->acpi.acpi_bios_sar_enable = false;
+ ab->acpi.acpi_cca_enable = false;
+ ab->acpi.acpi_band_edge_enable = false;
+ ab->acpi.acpi_enable_bdf = false;
+ ab->acpi.bdf_string[0] = '\0';
+
+ if (!ab->hw_params->acpi_guid)
+ /* not supported with this hardware */
+ return 0;
+
+ ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_SUPPORT_FUNCS);
+ if (ret) {
+ ath12k_dbg(ab, ATH12K_DBG_BOOT, "failed to get ACPI DSM data: %d\n", ret);
+ return ret;
+ }
+
+ if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_DISABLE_FLAG)) {
+ ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_DISABLE_FLAG);
+ if (ret) {
+ ath12k_warn(ab, "failed to get ACPI DISABLE FLAG: %d\n", ret);
+ return ret;
+ }
+
+ if (ATH12K_ACPI_CHEK_BIT_VALID(ab->acpi,
+ ATH12K_ACPI_DSM_DISABLE_11BE_BIT))
+ ab->acpi.acpi_disable_11be = true;
+
+ if (!ATH12K_ACPI_CHEK_BIT_VALID(ab->acpi,
+ ATH12K_ACPI_DSM_DISABLE_RFKILL_BIT))
+ ab->acpi.acpi_disable_rfkill = true;
+ }
+
+ if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_BDF_EXT)) {
+ ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_BDF_EXT);
+ if (ret || ab->acpi.bdf_string[0] == '\0') {
+ ath12k_warn(ab, "failed to get ACPI BDF EXT: %d\n", ret);
+ return ret;
+ }
+
+ ab->acpi.acpi_enable_bdf = true;
+ }
+
+ if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_TAS_CFG)) {
+ ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_TAS_CFG);
+ if (ret) {
+ ath12k_warn(ab, "failed to get ACPI TAS config table: %d\n", ret);
+ return ret;
+ }
+ }
+
+ if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_TAS_DATA)) {
+ ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_TAS_DATA);
+ if (ret) {
+ ath12k_warn(ab, "failed to get ACPI TAS data table: %d\n", ret);
+ return ret;
+ }
+
+ if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_TAS_CFG) &&
+ ab->acpi.tas_sar_power_table[0] == ATH12K_ACPI_TAS_DATA_VERSION &&
+ ab->acpi.tas_sar_power_table[1] == ATH12K_ACPI_TAS_DATA_ENABLE)
+ ab->acpi.acpi_tas_enable = true;
+ }
+
+ if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_BIOS_SAR)) {
+ ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_BIOS_SAR);
+ if (ret) {
+ ath12k_warn(ab, "failed to get ACPI bios sar data: %d\n", ret);
+ return ret;
+ }
+ }
+
+ if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_GEO_OFFSET)) {
+ ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_GEO_OFFSET);
+ if (ret) {
+ ath12k_warn(ab, "failed to get ACPI geo offset data: %d\n", ret);
+ return ret;
+ }
+
+ if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_BIOS_SAR) &&
+ ab->acpi.bios_sar_data[0] == ATH12K_ACPI_POWER_LIMIT_VERSION &&
+ ab->acpi.bios_sar_data[1] == ATH12K_ACPI_POWER_LIMIT_ENABLE_FLAG &&
+ !ab->acpi.acpi_tas_enable)
+ ab->acpi.acpi_bios_sar_enable = true;
+ }
+
+ if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_CCA)) {
+ ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_INDEX_CCA);
+ if (ret) {
+ ath12k_warn(ab, "failed to get ACPI DSM CCA threshold configuration: %d\n",
+ ret);
+ return ret;
+ }
+
+ if (ab->acpi.cca_data[0] == ATH12K_ACPI_CCA_THR_VERSION &&
+ ab->acpi.cca_data[ATH12K_ACPI_CCA_THR_OFFSET_DATA_OFFSET] ==
+ ATH12K_ACPI_CCA_THR_ENABLE_FLAG)
+ ab->acpi.acpi_cca_enable = true;
+ }
+
+ if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi,
+ ATH12K_ACPI_FUNC_BIT_BAND_EDGE_CHAN_POWER)) {
+ ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_INDEX_BAND_EDGE);
+ if (ret) {
+ ath12k_warn(ab, "failed to get ACPI DSM band edge channel power: %d\n",
+ ret);
+ return ret;
+ }
+
+ if (ab->acpi.band_edge_power[0] == ATH12K_ACPI_BAND_EDGE_VERSION &&
+ ab->acpi.band_edge_power[1] == ATH12K_ACPI_BAND_EDGE_ENABLE_FLAG)
+ ab->acpi.acpi_band_edge_enable = true;
+ }
+
+ status = acpi_install_notify_handler(ACPI_HANDLE(ab->dev),
+ ACPI_DEVICE_NOTIFY,
+ ath12k_acpi_dsm_notify, ab);
+ if (ACPI_FAILURE(status)) {
+ ath12k_warn(ab, "failed to install DSM notify callback: %d\n", status);
+ return -EIO;
+ }
+
+ ab->acpi.started = true;
+
+ return 0;
+}
+
+int ath12k_acpi_check_bdf_variant_name(struct ath12k_base *ab)
+{
+ size_t max_len = sizeof(ab->qmi.target.bdf_ext);
+
+ if (!ab->acpi.acpi_enable_bdf)
+ return -ENODATA;
+
+ if (strscpy(ab->qmi.target.bdf_ext, ab->acpi.bdf_string + 4, max_len) < 0)
+ ath12k_dbg(ab, ATH12K_DBG_BOOT,
+ "acpi bdf variant longer than the buffer (variant: %s)\n",
+ ab->acpi.bdf_string);
+
+ return 0;
+}
+
+void ath12k_acpi_stop(struct ath12k_base *ab)
+{
+ if (!ab->acpi.started)
+ return;
+
+ acpi_remove_notify_handler(ACPI_HANDLE(ab->dev),
+ ACPI_DEVICE_NOTIFY,
+ ath12k_acpi_dsm_notify);
+
+ memset(&ab->acpi, 0, sizeof(ab->acpi));
+}
diff --git a/sys/contrib/dev/athk/ath12k/acpi.h b/sys/contrib/dev/athk/ath12k/acpi.h
new file mode 100644
index 000000000000..3a26fea6af1a
--- /dev/null
+++ b/sys/contrib/dev/athk/ath12k/acpi.h
@@ -0,0 +1,114 @@
+/* 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.
+ */
+#ifndef ATH12K_ACPI_H
+#define ATH12K_ACPI_H
+
+#include <linux/acpi.h>
+
+#define ATH12K_ACPI_DSM_FUNC_SUPPORT_FUNCS 0
+#define ATH12K_ACPI_DSM_FUNC_DISABLE_FLAG 2
+#define ATH12K_ACPI_DSM_FUNC_BDF_EXT 3
+#define ATH12K_ACPI_DSM_FUNC_BIOS_SAR 4
+#define ATH12K_ACPI_DSM_FUNC_GEO_OFFSET 5
+#define ATH12K_ACPI_DSM_FUNC_INDEX_CCA 6
+#define ATH12K_ACPI_DSM_FUNC_TAS_CFG 8
+#define ATH12K_ACPI_DSM_FUNC_TAS_DATA 9
+#define ATH12K_ACPI_DSM_FUNC_INDEX_BAND_EDGE 10
+
+#define ATH12K_ACPI_FUNC_BIT_DISABLE_FLAG BIT(1)
+#define ATH12K_ACPI_FUNC_BIT_BDF_EXT BIT(2)
+#define ATH12K_ACPI_FUNC_BIT_BIOS_SAR BIT(3)
+#define ATH12K_ACPI_FUNC_BIT_GEO_OFFSET BIT(4)
+#define ATH12K_ACPI_FUNC_BIT_CCA BIT(5)
+#define ATH12K_ACPI_FUNC_BIT_TAS_CFG BIT(7)
+#define ATH12K_ACPI_FUNC_BIT_TAS_DATA BIT(8)
+#define ATH12K_ACPI_FUNC_BIT_BAND_EDGE_CHAN_POWER BIT(9)
+
+#define ATH12K_ACPI_NOTIFY_EVENT 0x86
+#define ATH12K_ACPI_FUNC_BIT_VALID(_acdata, _func) (((_acdata).func_bit) & (_func))
+#define ATH12K_ACPI_CHEK_BIT_VALID(_acdata, _func) (((_acdata).bit_flag) & (_func))
+
+#define ATH12K_ACPI_TAS_DATA_VERSION 0x1
+#define ATH12K_ACPI_TAS_DATA_ENABLE 0x1
+#define ATH12K_ACPI_POWER_LIMIT_VERSION 0x1
+#define ATH12K_ACPI_POWER_LIMIT_ENABLE_FLAG 0x1
+#define ATH12K_ACPI_CCA_THR_VERSION 0x1
+#define ATH12K_ACPI_CCA_THR_ENABLE_FLAG 0x1
+#define ATH12K_ACPI_BAND_EDGE_VERSION 0x1
+#define ATH12K_ACPI_BAND_EDGE_ENABLE_FLAG 0x1
+
+#define ATH12K_ACPI_GEO_OFFSET_DATA_OFFSET 1
+#define ATH12K_ACPI_DBS_BACKOFF_DATA_OFFSET 2
+#define ATH12K_ACPI_CCA_THR_OFFSET_DATA_OFFSET 5
+#define ATH12K_ACPI_BIOS_SAR_DBS_BACKOFF_LEN 10
+#define ATH12K_ACPI_POWER_LIMIT_DATA_OFFSET 12
+#define ATH12K_ACPI_BIOS_SAR_GEO_OFFSET_LEN 18
+#define ATH12K_ACPI_BIOS_SAR_TABLE_LEN 22
+#define ATH12K_ACPI_CCA_THR_OFFSET_LEN 36
+
+#define ATH12K_ACPI_DSM_TAS_DATA_SIZE 69
+#define ATH12K_ACPI_DSM_BAND_EDGE_DATA_SIZE 100
+#define ATH12K_ACPI_DSM_TAS_CFG_SIZE 108
+
+#define ATH12K_ACPI_DSM_FUNC_MIN_BITMAP_SIZE 1
+#define ATH12K_ACPI_DSM_FUNC_MAX_BITMAP_SIZE 4
+
+#define ATH12K_ACPI_DSM_DISABLE_11BE_BIT BIT(0)
+#define ATH12K_ACPI_DSM_DISABLE_RFKILL_BIT BIT(2)
+
+#define ATH12K_ACPI_BDF_ANCHOR_STRING_LEN 3
+#define ATH12K_ACPI_BDF_ANCHOR_STRING "BDF"
+#define ATH12K_ACPI_BDF_MAX_LEN 100
+
+#define ATH12K_ACPI_DSM_GEO_OFFSET_DATA_SIZE (ATH12K_ACPI_GEO_OFFSET_DATA_OFFSET + \
+ ATH12K_ACPI_BIOS_SAR_GEO_OFFSET_LEN)
+#define ATH12K_ACPI_DSM_BIOS_SAR_DATA_SIZE (ATH12K_ACPI_POWER_LIMIT_DATA_OFFSET + \
+ ATH12K_ACPI_BIOS_SAR_TABLE_LEN)
+#define ATH12K_ACPI_DSM_CCA_DATA_SIZE (ATH12K_ACPI_CCA_THR_OFFSET_DATA_OFFSET + \
+ ATH12K_ACPI_CCA_THR_OFFSET_LEN)
+
+#ifdef CONFIG_ACPI
+
+int ath12k_acpi_start(struct ath12k_base *ab);
+void ath12k_acpi_stop(struct ath12k_base *ab);
+bool ath12k_acpi_get_disable_rfkill(struct ath12k_base *ab);
+bool ath12k_acpi_get_disable_11be(struct ath12k_base *ab);
+void ath12k_acpi_set_dsm_func(struct ath12k_base *ab);
+int ath12k_acpi_check_bdf_variant_name(struct ath12k_base *ab);
+
+#else
+
+static inline int ath12k_acpi_start(struct ath12k_base *ab)
+{
+ return 0;
+}
+
+static inline void ath12k_acpi_stop(struct ath12k_base *ab)
+{
+}
+
+static inline bool ath12k_acpi_get_disable_rfkill(struct ath12k_base *ab)
+{
+ return false;
+}
+
+static inline bool ath12k_acpi_get_disable_11be(struct ath12k_base *ab)
+{
+ return false;
+}
+
+static inline void ath12k_acpi_set_dsm_func(struct ath12k_base *ab)
+{
+}
+
+static inline int ath12k_acpi_check_bdf_variant_name(struct ath12k_base *ab)
+{
+ return 0;
+}
+
+#endif /* CONFIG_ACPI */
+
+#endif /* ATH12K_ACPI_H */
diff --git a/sys/contrib/dev/athk/ath12k/ahb.c b/sys/contrib/dev/athk/ath12k/ahb.c
new file mode 100644
index 000000000000..b30527c402f6
--- /dev/null
+++ b/sys/contrib/dev/athk/ath12k/ahb.c
@@ -0,0 +1,1156 @@
+// 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.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/remoteproc.h>
+#include <linux/soc/qcom/mdt_loader.h>
+#include <linux/soc/qcom/smem_state.h>
+#include "ahb.h"
+#include "debug.h"
+#include "hif.h"
+
+static const struct of_device_id ath12k_ahb_of_match[] = {
+ { .compatible = "qcom,ipq5332-wifi",
+ .data = (void *)ATH12K_HW_IPQ5332_HW10,
+ },
+ { }
+};
+
+MODULE_DEVICE_TABLE(of, ath12k_ahb_of_match);
+
+#define ATH12K_IRQ_CE0_OFFSET 4
+#define ATH12K_MAX_UPDS 1
+#define ATH12K_UPD_IRQ_WRD_LEN 18
+static const char ath12k_userpd_irq[][9] = {"spawn",
+ "ready",
+ "stop-ack"};
+
+static const char *irq_name[ATH12K_IRQ_NUM_MAX] = {
+ "misc-pulse1",
+ "misc-latch",
+ "sw-exception",
+ "watchdog",
+ "ce0",
+ "ce1",
+ "ce2",
+ "ce3",
+ "ce4",
+ "ce5",
+ "ce6",
+ "ce7",
+ "ce8",
+ "ce9",
+ "ce10",
+ "ce11",
+ "host2wbm-desc-feed",
+ "host2reo-re-injection",
+ "host2reo-command",
+ "host2rxdma-monitor-ring3",
+ "host2rxdma-monitor-ring2",
+ "host2rxdma-monitor-ring1",
+ "reo2ost-exception",
+ "wbm2host-rx-release",
+ "reo2host-status",
+ "reo2host-destination-ring4",
+ "reo2host-destination-ring3",
+ "reo2host-destination-ring2",
+ "reo2host-destination-ring1",
+ "rxdma2host-monitor-destination-mac3",
+ "rxdma2host-monitor-destination-mac2",
+ "rxdma2host-monitor-destination-mac1",
+ "ppdu-end-interrupts-mac3",
+ "ppdu-end-interrupts-mac2",
+ "ppdu-end-interrupts-mac1",
+ "rxdma2host-monitor-status-ring-mac3",
+ "rxdma2host-monitor-status-ring-mac2",
+ "rxdma2host-monitor-status-ring-mac1",
+ "host2rxdma-host-buf-ring-mac3",
+ "host2rxdma-host-buf-ring-mac2",
+ "host2rxdma-host-buf-ring-mac1",
+ "rxdma2host-destination-ring-mac3",
+ "rxdma2host-destination-ring-mac2",
+ "rxdma2host-destination-ring-mac1",
+ "host2tcl-input-ring4",
+ "host2tcl-input-ring3",
+ "host2tcl-input-ring2",
+ "host2tcl-input-ring1",
+ "wbm2host-tx-completions-ring4",
+ "wbm2host-tx-completions-ring3",
+ "wbm2host-tx-completions-ring2",
+ "wbm2host-tx-completions-ring1",
+ "tcl2host-status-ring",
+};
+
+enum ext_irq_num {
+ host2wbm_desc_feed = 16,
+ host2reo_re_injection,
+ host2reo_command,
+ host2rxdma_monitor_ring3,
+ host2rxdma_monitor_ring2,
+ host2rxdma_monitor_ring1,
+ reo2host_exception,
+ wbm2host_rx_release,
+ reo2host_status,
+ reo2host_destination_ring4,
+ reo2host_destination_ring3,
+ reo2host_destination_ring2,
+ reo2host_destination_ring1,
+ rxdma2host_monitor_destination_mac3,
+ rxdma2host_monitor_destination_mac2,
+ rxdma2host_monitor_destination_mac1,
+ ppdu_end_interrupts_mac3,
+ ppdu_end_interrupts_mac2,
+ ppdu_end_interrupts_mac1,
+ rxdma2host_monitor_status_ring_mac3,
+ rxdma2host_monitor_status_ring_mac2,
+ rxdma2host_monitor_status_ring_mac1,
+ host2rxdma_host_buf_ring_mac3,
+ host2rxdma_host_buf_ring_mac2,
+ host2rxdma_host_buf_ring_mac1,
+ rxdma2host_destination_ring_mac3,
+ rxdma2host_destination_ring_mac2,
+ rxdma2host_destination_ring_mac1,
+ host2tcl_input_ring4,
+ host2tcl_input_ring3,
+ host2tcl_input_ring2,
+ host2tcl_input_ring1,
+ wbm2host_tx_completions_ring4,
+ wbm2host_tx_completions_ring3,
+ wbm2host_tx_completions_ring2,
+ wbm2host_tx_completions_ring1,
+ tcl2host_status_ring,
+};
+
+static u32 ath12k_ahb_read32(struct ath12k_base *ab, u32 offset)
+{
+ if (ab->ce_remap && offset < HAL_SEQ_WCSS_CMEM_OFFSET)
+ return ioread32(ab->mem_ce + offset);
+ return ioread32(ab->mem + offset);
+}
+
+static void ath12k_ahb_write32(struct ath12k_base *ab, u32 offset,
+ u32 value)
+{
+ if (ab->ce_remap && offset < HAL_SEQ_WCSS_CMEM_OFFSET)
+ iowrite32(value, ab->mem_ce + offset);
+ else
+ iowrite32(value, ab->mem + offset);
+}
+
+static void ath12k_ahb_cancel_workqueue(struct ath12k_base *ab)
+{
+ int i;
+
+ for (i = 0; i < ab->hw_params->ce_count; i++) {
+ struct ath12k_ce_pipe *ce_pipe = &ab->ce.ce_pipe[i];
+
+ if (ath12k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
+ continue;
+
+ cancel_work_sync(&ce_pipe->intr_wq);
+ }
+}
+
+static void ath12k_ahb_ext_grp_disable(struct ath12k_ext_irq_grp *irq_grp)
+{
+ int i;
+
+ for (i = 0; i < irq_grp->num_irq; i++)
+ disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
+}
+
+static void __ath12k_ahb_ext_irq_disable(struct ath12k_base *ab)
+{
+ int i;
+
+ for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) {
*** 61938 LINES SKIPPED ***